Compare commits
1590 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0e93a4d60f | |||
| 07052301c3 | |||
| 59ae7c2a84 | |||
| 9846a7f090 | |||
| 81d2e45981 | |||
| 56788d24dd | |||
| 05f337cc5f | |||
| 6e0246e439 | |||
| 6385bf7185 | |||
| 53a810db85 | |||
| 62903322fc | |||
| dc63f8d03e | |||
| 8ebc88c4d9 | |||
| aa8c2e48bd | |||
| d626d3e470 | |||
| 64c63e6cbb | |||
| 621d9afe46 | |||
| 8bd76ea422 | |||
| f909dd7612 | |||
| e9bc93157c | |||
| 063bc73658 | |||
| 6190487787 | |||
| 158f3cb65f | |||
| e2f570a23a | |||
| 46e6e31b52 | |||
| 1afd70b2ac | |||
| bc6a100181 | |||
| c2b23ae47b | |||
| 6f94958749 | |||
| 897fa24950 | |||
| cd1ea5d656 | |||
| 06748958c5 | |||
| 2536c32b3e | |||
| bd1f93687d | |||
| 5ec6beffd6 | |||
| ed6a79d869 | |||
| b5cae06cd4 | |||
| a17fcb7b53 | |||
| 39a631bbe6 | |||
| a383e8db65 | |||
| e7e67de957 | |||
| 43fd59ea14 | |||
| bf088b3423 | |||
| b944b6c678 | |||
| e535262042 | |||
| dd48008c77 | |||
| 4eb5e15641 | |||
| 0e18d41b3b | |||
| fbd941aa94 | |||
| 9c40410a22 | |||
| 096cbd68a9 | |||
| e426c25127 | |||
| 3982f34f2c | |||
| 20b4684483 | |||
| c1c0d58867 | |||
| a3ba7fb4a7 | |||
| ab1b3440f2 | |||
| e2f5bc4700 | |||
| b264f0f0f4 | |||
| eef19f3eaa | |||
| fab7a109e2 | |||
| 58d75e5b3b | |||
| 81d57c26db | |||
| c4cf048ba7 | |||
| 94a87681a6 | |||
| 7fb9c3d85c | |||
| ce261c444d | |||
| cb09ed7ecb | |||
| c61ab3b6af | |||
| a4328b8f04 | |||
| dbd0d6062c | |||
| cee781ba9e | |||
| ba583fc1ec | |||
| f7503b9e66 | |||
| f58259c790 | |||
| bbb5b1aeaa | |||
| e9672d50de | |||
| d4d468ad37 | |||
| c572230139 | |||
| 64792d5d0b | |||
| 8c3185f763 | |||
| 690a7660ca | |||
| 3b938296a8 | |||
| 0325c08ea7 | |||
| 68dbc90489 | |||
| 9c55e9c0f7 | |||
| 61eed5acf7 | |||
| 5a7b40f684 | |||
| d5f343427d | |||
| 901dd449d6 | |||
| 3b94f1111a | |||
| 959e46857d | |||
| ff7eba4d78 | |||
| 94f638e915 | |||
| 425f43d8f3 | |||
| 08ca102966 | |||
| d76f87a94f | |||
| 7d8cede29c | |||
| 2ccfd7509d | |||
| 44659da943 | |||
| 6ab0935e93 | |||
| 582d4d91a0 | |||
| fca567dee4 | |||
| 3e3ae23846 | |||
| 5d850ce66e | |||
| 077f41dc19 | |||
| c32a9ec8cd | |||
| 9afbbd3834 | |||
| 3cc5c930cb | |||
| 601cd4ebd7 | |||
| 04019ee089 | |||
| d0c227d966 | |||
| 4ad2527e2e | |||
| 8a8a4a843d | |||
| 398e230331 | |||
| 65a2e5fe0e | |||
| 6c00930560 | |||
| 1a7f4d16c5 | |||
| 5934fe5d94 | |||
| d5e0549053 | |||
| de21347f57 | |||
| 5923607efe | |||
| 98c7487e6f | |||
| bb3ca655f7 | |||
| 29c374090b | |||
| 46055853d5 | |||
| 4cb35863d0 | |||
| a55516bfa4 | |||
| ec27b03b55 | |||
| 5e1ad59a07 | |||
| 07740e4f85 | |||
| 407faffcaf | |||
| 455d145b38 | |||
| 1c43ecde9c | |||
| b16c535b11 | |||
| 1119cfaf3f | |||
| 1d919f4c09 | |||
| 2debdc6b36 | |||
| 0bcda53a17 | |||
| 060ed3e43e | |||
| e1dea25400 | |||
| 451e2115fb | |||
| 9118464db9 | |||
| 20779888d0 | |||
| b494a7a518 | |||
| 26605cb7da | |||
| c0b6790784 | |||
| 5a68444794 | |||
| a058f40d19 | |||
| c9275385f8 | |||
| 0e96ba879d | |||
| d69c38ed33 | |||
| 10aee1921d | |||
| a77c773d85 | |||
| 6b966ac672 | |||
| 6683493bfe | |||
| 407cd995c7 | |||
| 7cad9118a7 | |||
| 2c23f4d946 | |||
| 2c6ad02fe8 | |||
| e1d1889bab | |||
| aba7ba077d | |||
| c3e9985a8c | |||
| edb3ed1ebb | |||
| 10369c9c5b | |||
| aeb4bd9ce5 | |||
| 42dc4cad26 | |||
| 8fbc973901 | |||
| 6a77e4cc89 | |||
| 9d597e5f0f | |||
| df0dcdcd82 | |||
| d236997758 | |||
| c14ee7225b | |||
| fc11c6512d | |||
| f64afbb455 | |||
| 355efd43c7 | |||
| c43b904d33 | |||
| 600bbd40ab | |||
| 1087d15324 | |||
| f446045c73 | |||
| d6436ff003 | |||
| d1a54306ea | |||
| 832c5b2f31 | |||
| 47c2387cf2 | |||
| 1407c22310 | |||
| 9ad1d1bbd5 | |||
| 7fe85994a6 | |||
| 0c25e4fdbf | |||
| 181b342dd4 | |||
| 9be4ad6dc9 | |||
| c5621562b2 | |||
| 34c0bd4cc7 | |||
| 4f6d0ff06d | |||
| a498087d87 | |||
| 65eebc1dc1 | |||
| 6a7f561589 | |||
| c01d42c269 | |||
| 4a5eefa65e | |||
| 8b6405ce85 | |||
| 087c82f2af | |||
| af8857f356 | |||
| 9add7352b4 | |||
| 894909f8bc | |||
| c1816feb13 | |||
| f7ad66498e | |||
| f0d42c3de0 | |||
| cf247b1cd2 | |||
| fbe18b35ff | |||
| 18a538ee7f | |||
| 83b7d9e66c | |||
| 699304bf04 | |||
| b8451e289e | |||
| 58d1d16f52 | |||
| 85ec42a6da | |||
| 0dcb01f5b0 | |||
| 65fde56506 | |||
| f72dda83d8 | |||
| d0beaac3e7 | |||
| 4720633c09 | |||
| 0cbf8dddf9 | |||
| 3983b7a590 | |||
| 21ae339623 | |||
| 4431b5bb02 | |||
| 31869bb435 | |||
| 3f842963f8 | |||
| 57e207d552 | |||
| a18e55c721 | |||
| f5553c87a3 | |||
| 0046f85241 | |||
| 429719b771 | |||
| ef597bbbd0 | |||
| 42f012ebb3 | |||
| 58cd93fd1d | |||
| d9794f1afd | |||
| 0e59339dff | |||
| 04ee3d1b45 | |||
| 0f5ef8a9cd | |||
| 8b0328b440 | |||
| b8b5df0f05 | |||
| fdd8054931 | |||
| fddfe2944a | |||
| 4da015a61e | |||
| b127df2bcf | |||
| a07107a0a4 | |||
| 2a78d7be39 | |||
| 52b20d0b14 | |||
| 74e12d5754 | |||
| 1f619d3788 | |||
| 2ae3f04143 | |||
| b12c56b9f7 | |||
| 59a47661a4 | |||
| c0e733fe65 | |||
| 16ad6fa4bb | |||
| 4398ce111c | |||
| 52f87775e4 | |||
| 6f37d406a9 | |||
| 4945b93ba5 | |||
| 361108bf87 | |||
| 2fde99f6f1 | |||
| 7c66bf1a3a | |||
| 997dbc1d6a | |||
| 6ab41ced9f | |||
| cef179fb17 | |||
| aac5cc99b8 | |||
| 2451a17e4f | |||
| 411db8a7aa | |||
| 13f3ab9e8d | |||
| 1c58794888 | |||
| 8dfe7ccdbd | |||
| f262d1a4a5 | |||
| e99bd28163 | |||
| 52e09d71ba | |||
| a36ee478a9 | |||
| 1c616dab4c | |||
| b8d435b455 | |||
| fe0c1c6bde | |||
| c2ff6d5028 | |||
| f089cc2af2 | |||
| fc54986465 | |||
| 51b9ca7c4d | |||
| e97b405e2c | |||
| b71ad710d6 | |||
| 48b54c3496 | |||
| 362b69f088 | |||
| c211a14454 | |||
| 6fe8629801 | |||
| 198a6cd63a | |||
| 6d638bd292 | |||
| 2ecb5ae389 | |||
| 6a1f28e57b | |||
| 7e3bd15bc8 | |||
| 3e41567353 | |||
| ac556e3797 | |||
| c27d3c82d8 | |||
| cffccd03e4 | |||
| 29903b3c3f | |||
| 9827731219 | |||
| af1bf994ec | |||
| 453b4cc48a | |||
| d2b7b16b46 | |||
| 26b85b5008 | |||
| 8e641dd622 | |||
| 815a6f0eeb | |||
| f39b778d66 | |||
| 97b04370db | |||
| f50bd3e783 | |||
| dc47097ac8 | |||
| 5c16582936 | |||
| 51f5316ac1 | |||
| 42a6a49bd6 | |||
| e2eef31dbd | |||
| 1ce6d0ec1f | |||
| f70996764e | |||
| 373ee66017 | |||
| e9465902bb | |||
| 282bdb24b4 | |||
| 75faea4326 | |||
| 656ff52256 | |||
| 7d8b34d478 | |||
| 51cd8f8ca5 | |||
| 3f34186fec | |||
| 88b8207d9e | |||
| 0990ae9330 | |||
| 46e6b10569 | |||
| a4e6bba980 | |||
| c6d3480f5d | |||
| 1952f448c5 | |||
| 74b57ece6c | |||
| 3c36dff587 | |||
| 3c2c558e23 | |||
| 622e5c7d9c | |||
| ffb76c3545 | |||
| 0176d8cbaa | |||
| 86ff0b039d | |||
| a7fa132804 | |||
| 49a9771cf5 | |||
| 0fbffac83f | |||
| aa9c8b7f8e | |||
| 593aa35503 | |||
| 936369ef5f | |||
| a9fcd45d83 | |||
| b5ebbaa5bf | |||
| f9fad8717d | |||
| 56e0fe9da5 | |||
| 17f822bd40 | |||
| b5840c4c7d | |||
| ea4c8536a4 | |||
| a9ca21c97c | |||
| e0645492c5 | |||
| f1bf386c43 | |||
| f433674a58 | |||
| dbbb455677 | |||
| cb06574d5b | |||
| a8c9711106 | |||
| 601812d71e | |||
| aab2bf6809 | |||
| a41ae1f4c7 | |||
| 56c978bf95 | |||
| 004c7f7b3f | |||
| d54f175dbb | |||
| 64a8d691e3 | |||
| 6a981ddfd6 | |||
| dfa9ca5415 | |||
| 945b367213 | |||
| 5e6aee4443 | |||
| 0a9a9d16c0 | |||
| 03c4d102a3 | |||
| e2a1ed12de | |||
| dba840d8fb | |||
| f5dc8313df | |||
| 0ecdc62ccb | |||
| 228c683a96 | |||
| 23fa78eced | |||
| 3a6c37d98e | |||
| e58b3abfeb | |||
| 82d93b8766 | |||
| 29dc93d1cd | |||
| 902ec3ccc2 | |||
| 8f50e29c85 | |||
| 5338f3b513 | |||
| 65e89b9f8a | |||
| 95449ba282 | |||
| 0b7ccd3524 | |||
| 1f4465fda8 | |||
| 145fcd4eef | |||
| 45e317821b | |||
| 319b9fbb7b | |||
| f80b5bd83d | |||
| cba6700b95 | |||
| 2cbc7b553e | |||
| fd0584f517 | |||
| 52aff1bfd3 | |||
| 42ad0d11ba | |||
| be88a9db22 | |||
| 9e8e8439c7 | |||
| 3978521f56 | |||
| 40bb96dbec | |||
| 7ee4f7c57b | |||
| 3d2d030f2b | |||
| ec3f14a25d | |||
| 9b1424d7f8 | |||
| 92b7afea55 | |||
| 9fa231c541 | |||
| c967c71d16 | |||
| 4ba39c2626 | |||
| 4bc822b746 | |||
| 83f9848c42 | |||
| cf9faae277 | |||
| b60e4cc9a3 | |||
| 72cc2e8c11 | |||
| e9e9c9e143 | |||
| 77464d6be4 | |||
| 369c4ab13d | |||
| 3e16e2fd1d | |||
| 73306a9b52 | |||
| 75beaae841 | |||
| a0a125af85 | |||
| 65f3fe2b8c | |||
| 9bc66d2797 | |||
| 6f8c094cf7 | |||
| 9604cd3be1 | |||
| e7cda6bee1 | |||
| 9ac7d1f1c9 | |||
| fc78375323 | |||
| 93dc135075 | |||
| 923c0f5342 | |||
| 16a5f6929a | |||
| 866a718532 | |||
| 3f1f634826 | |||
| 386f08f476 | |||
| 9fd87f072c | |||
| fe5b9f808b | |||
| 876a50f509 | |||
| 71c46bf1af | |||
| fb28188272 | |||
| 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.
|
||||
+20
-19
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -350,7 +350,7 @@
|
||||
p.id as prefid
|
||||
FROM {$CFG->prefix}user u
|
||||
JOIN {$CFG->prefix}user_preferences p ON u.id=p.userid
|
||||
WHERE p.name='create_password' AND p.value=1 AND u.email !='' ");
|
||||
WHERE p.name='create_password' AND p.value='1' AND u.email !='' ");
|
||||
|
||||
foreach ($newusers as $newuserid => $newuser) {
|
||||
$newuser->emailstop = 0; // send email regardless
|
||||
@@ -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
|
||||
|
||||
+32
-13
@@ -80,7 +80,6 @@
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="mysql416required" />
|
||||
</FEEDBACK>
|
||||
<BYPASS function="bypass_mysql416_reqs" message="mysql416bypassed" />
|
||||
</VENDOR>
|
||||
<VENDOR name="postgres" version="7.4" />
|
||||
<VENDOR name="mssql" version="9.0" />
|
||||
@@ -140,7 +139,6 @@
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="mysql416required" />
|
||||
</FEEDBACK>
|
||||
<BYPASS function="bypass_mysql416_reqs" message="mysql416bypassed" />
|
||||
</VENDOR>
|
||||
<VENDOR name="postgres" version="8.0" />
|
||||
<VENDOR name="mssql" version="9.0" />
|
||||
@@ -200,7 +198,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 +212,19 @@
|
||||
</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.2" />
|
||||
<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 +267,35 @@
|
||||
<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_EXTENSION name="simplexml" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="simplexmlrequired" />
|
||||
</FEEDBACK>
|
||||
</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();
|
||||
?>
|
||||
|
||||
@@ -85,9 +85,21 @@
|
||||
$mnet_request->set_method('enrol/mnet/enrol.php/course_enrolments');
|
||||
$mnet_request->add_param($course->remoteid, 'int');
|
||||
$mnet_request->send($mnet_peer);
|
||||
$all_enrolled_users = $mnet_request->response;
|
||||
|
||||
$raw_all_enrolled_users = $mnet_request->response;
|
||||
unset($mnet_request);
|
||||
|
||||
$all_enrolled_users = array();
|
||||
if (!empty($raw_all_enrolled_users)) {
|
||||
// Try to repair keying of remote users array, numeric usernames get lost in the fracas
|
||||
foreach ($raw_all_enrolled_users as $username => $userdetails) {
|
||||
if (empty($userdetails['username']) || !is_numeric($username)) {
|
||||
//Not able to repair, or no need to repair
|
||||
$all_enrolled_users[$username] = $userdetails;
|
||||
} else {
|
||||
$all_enrolled_users[$userdetails['username']] = $userdetails;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$select = '';
|
||||
$all_enrolled_usernames = '';
|
||||
|
||||
@@ -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) {
|
||||
|
||||
+2
-8
@@ -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");
|
||||
@@ -48,13 +42,13 @@
|
||||
|
||||
echo "<form id=\"mform1\" class=\"mform\" action=\"http://moodle.org/register/\" method=\"post\">\n";
|
||||
echo '<fieldset id="registration">';
|
||||
echo '<legend>Registration Information</legend>';
|
||||
echo '<legend>'.get_string("registrationinfotitle").'</legend>';
|
||||
|
||||
echo "<!-- The following hidden variables are to help prevent fake entries being sent. -->\n";
|
||||
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;
|
||||
|
||||
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,11 @@ 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));
|
||||
$temp->add(new admin_setting_configcheckbox('enablesafebrowserintegration', get_string('enablesafebrowserintegration', 'admin'), get_string('configenablesafebrowserintegration', '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);
|
||||
|
||||
|
||||
@@ -61,6 +65,7 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
|
||||
$temp->add(new admin_setting_configcheckbox('loginhttps', get_string('loginhttps', 'admin'), get_string('configloginhttps', 'admin'), 0));
|
||||
$temp->add(new admin_setting_configcheckbox('cookiesecure', get_string('cookiesecure', 'admin'), get_string('configcookiesecure', 'admin'), 0));
|
||||
$temp->add(new admin_setting_configcheckbox('cookiehttponly', get_string('cookiehttponly', 'admin'), get_string('configcookiehttponly', 'admin'), 0));
|
||||
$temp->add(new admin_setting_configcheckbox('regenloginsession', get_string('regenloginsession', 'admin'), get_string('configregenloginsession', 'admin'), 0));
|
||||
$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
|
||||
|
||||
@@ -61,7 +61,7 @@ $overwritepicture = optional_param('overwritepicture', 0, PARAM_BOOL);
|
||||
admin_externalpage_print_header();
|
||||
print_heading_with_help($struploadpictures, 'uploadpictures');
|
||||
|
||||
$mform = new admin_uploadpicture_form();
|
||||
$mform = new admin_uploadpicture_form(null, $userfields);
|
||||
if ($formdata = $mform->get_data()) {
|
||||
if (!array_key_exists($userfield, $userfields)) {
|
||||
notify(get_string('uploadpicture_baduserfield','admin'));
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
class admin_uploadpicture_form extends moodleform {
|
||||
function definition (){
|
||||
global $CFG, $USER;
|
||||
global $userfields;
|
||||
|
||||
$mform =& $this->_form;
|
||||
|
||||
@@ -14,11 +13,11 @@
|
||||
|
||||
$mform->addElement('file', 'userpicturesfile', get_string('file'), 'size="40"');
|
||||
$mform->addRule('userpicturesfile', null, 'required');
|
||||
|
||||
$choices = $userfields;
|
||||
|
||||
$choices =& $this->_customdata;
|
||||
$mform->addElement('select', 'userfield', get_string('uploadpicture_userfield', 'admin'), $choices);
|
||||
$mform->setType('userfield', PARAM_INT);
|
||||
|
||||
|
||||
$choices = array( 0 => get_string('no'), 1 => get_string('yes') );
|
||||
$mform->addElement('select', 'overwritepicture', get_string('uploadpicture_overwrite', 'admin'), $choices);
|
||||
$mform->setType('overwritepicture', PARAM_INT);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -208,6 +208,10 @@ class check_bigints extends XMLDBAction {
|
||||
$o.=' </ul>';
|
||||
}
|
||||
$o.=' </li>';
|
||||
/// Give the script some more time (resetting to current if exists)
|
||||
if ($currenttl = @ini_get('max_execution_time')) {
|
||||
@ini_set('max_execution_time',$currenttl);
|
||||
}
|
||||
}
|
||||
$o.=' </ul>';
|
||||
}
|
||||
|
||||
@@ -213,6 +213,10 @@ class check_indexes extends XMLDBAction {
|
||||
$o.=' </ul>';
|
||||
}
|
||||
$o.=' </li>';
|
||||
/// Give the script some more time (resetting to current if exists)
|
||||
if ($currenttl = @ini_get('max_execution_time')) {
|
||||
@ini_set('max_execution_time',$currenttl);
|
||||
}
|
||||
}
|
||||
$o.=' </ul>';
|
||||
}
|
||||
|
||||
@@ -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() && (trim(moodle_strtolower(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
|
||||
*/
|
||||
|
||||
+119
-28
@@ -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;
|
||||
@@ -222,7 +222,7 @@ class auth_plugin_ldap extends auth_plugin_base {
|
||||
}
|
||||
$ldapval = NULL;
|
||||
foreach ($values as $value) {
|
||||
if ($value == 'dn') {
|
||||
if ((moodle_strtolower($value) == 'dn') || (moodle_strtolower($value) == 'distinguishedname')) {
|
||||
$result[$key] = $user_dn;
|
||||
}
|
||||
if (!array_key_exists($value, $user_entry[0])) {
|
||||
@@ -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,58 @@ 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
|
||||
&&!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");
|
||||
// HTTPS is potentially required
|
||||
httpsrequired();
|
||||
|
||||
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)) {
|
||||
|
||||
// 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 +1917,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 +2081,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,12 +2115,13 @@ 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote control characters in texts used in ldap filters - see rfc2254.txt
|
||||
* Quote control characters in texts used in ldap filters - see RFC 4515/2254
|
||||
*
|
||||
* @param string
|
||||
*/
|
||||
@@ -2051,14 +2133,23 @@ class auth_plugin_ldap extends auth_plugin_base {
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote control characters in quoted "texts" used in ldap
|
||||
* The order of the special characters in these arrays _IS IMPORTANT_.
|
||||
* Make sure '\\5C' (and '\\') are the first elements of the arrays.
|
||||
* Otherwise we'll double replace '\' with '\5C' which is Bad(tm)
|
||||
*/
|
||||
var $LDAP_DN_QUOTED_SPECIAL_CHARS = array('\\5c','\\20','\\22','\\23','\\2b','\\2c','\\3b','\\3c','\\3d','\\3e','\\00');
|
||||
var $LDAP_DN_SPECIAL_CHARS = array('\\', ' ', '"', '#', '+', ',', ';', '<', '=', '>', "\0");
|
||||
|
||||
/**
|
||||
* Quote control characters in distinguished names used in ldap - See RFC 4514/2253
|
||||
*
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function ldap_addslashes($text) {
|
||||
$text = str_replace('\\', '\\\\', $text);
|
||||
$text = str_replace(array('"', "\0"),
|
||||
array('\\"', '\\00'), $text);
|
||||
$text = str_replace ($this->LDAP_DN_SPECIAL_CHARS,
|
||||
$this->LDAP_DN_QUOTED_SPECIAL_CHARS,
|
||||
$text);
|
||||
return $text;
|
||||
}
|
||||
|
||||
|
||||
+14
-1
@@ -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') );
|
||||
|
||||
@@ -90,7 +92,7 @@ if (!function_exists('ldap_connect')) { // Is php4-ldap really there?
|
||||
<td align="right"><label for="menuversion"><?php print_string('auth_ldap_version_key','auth') ?></label></td>
|
||||
<td>
|
||||
<?php
|
||||
$varsions = array();
|
||||
$versions = array();
|
||||
$versions[2] = '2';
|
||||
$versions[3] = '3';
|
||||
choose_from_menu($versions, 'version', $config->version, '');
|
||||
@@ -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>
|
||||
|
||||
+141
-12
@@ -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,14 @@ 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
|
||||
- 4. 2009: Added another requirement for logout regarding the call back script
|
||||
- 6. 2009: Changed handler URL when integrated Discovery Service is used
|
||||
- 10. 2009: Fixed HTML entity preservation in Shibboleth settings
|
||||
|
||||
Moodle Configuration with Dual login
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -28,28 +36,41 @@ Moodle Configuration with Dual login
|
||||
For Apache you have to define a rule like the following in the Apache config:
|
||||
|
||||
--
|
||||
<Location ~ "/auth/shibboleth/index.php">
|
||||
<Directory /path/to/moodle/auth/shibboleth/index.php>
|
||||
AuthType shibboleth
|
||||
ShibRequireSession On
|
||||
require valid-user
|
||||
</Location>
|
||||
</Directory>
|
||||
--
|
||||
|
||||
To restrict access to Moodle, replace the access rule 'require valid-user'
|
||||
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,22 +93,32 @@ 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
|
||||
in step 1 only the index.php script in
|
||||
moodle/auth/shibboleth/ is protected but *not* the other
|
||||
scripts and especially not the login.php script.
|
||||
|
||||
If you were using the integrated WAYF alread with Shibboleth 1.3, it could
|
||||
be that the integrated WAYF is not working anymore after you updated Moodle.
|
||||
The reason is that the implicitly set default SessionInitiator changed in
|
||||
Moodle as well as in Shibboleth. For Shibboleth 1.3 one therefore has to
|
||||
add /Shibboleth.sso as third parameter whereas this is /Shibboleth.sso/DS
|
||||
for Shibboleth 2.x.
|
||||
|
||||
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 +230,104 @@ 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" />
|
||||
--
|
||||
|
||||
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
|
||||
- /moodle/auth/shibboleth/logout.php *must not* be protected by Shibboleth!
|
||||
In case all of Moodle is protected with Shibboleth, you have to add something
|
||||
like this to your Apache configuration after all the other require rules
|
||||
|
||||
--
|
||||
<Directory /path/to/moodle/auth/shibboleth/logout.php>
|
||||
AuthType shibboleth
|
||||
ShibRequireSession Off
|
||||
require shibboleth
|
||||
</Directory>
|
||||
--
|
||||
When using IIS, the same can be achieved by something like:
|
||||
--
|
||||
<Path name="auth/shibboleth/logout.php" requireSession="false" >
|
||||
--
|
||||
in the shibboleth2.xml RequestMap.
|
||||
|
||||
|
||||
Limitations:
|
||||
Single Logout is only supported when SAML2 is used at the SP and the IdP.
|
||||
As of October 2009, the Shibboleth Identity Provider 2.1.4 does not yet support
|
||||
Single Logout (SLO). Therefore, the single logout feature cannot be used yet
|
||||
in a Shibboleth only setup but there may be other SAML2 products that could
|
||||
be used as Identity Provider, e.g. SimpleSAML PHP.
|
||||
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. On the other hand, the easiest and safest way to log out
|
||||
still is to tell users to quit their web browsers :)
|
||||
|
||||
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';
|
||||
}
|
||||
|
||||
|
||||
+34
-12
@@ -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;
|
||||
echo htmlentities($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,23 +78,45 @@ 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)){
|
||||
echo $config->login_name;
|
||||
echo htmlentities($config->login_name);
|
||||
} else {
|
||||
echo 'Shibboleth Login';
|
||||
}
|
||||
?>" />
|
||||
</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">
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
}
|
||||
|
||||
redirect($urltogo);
|
||||
|
||||
}
|
||||
|
||||
$pluginconfig = get_config('auth/shibboleth');
|
||||
@@ -87,7 +88,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");
|
||||
|
||||
@@ -57,11 +56,20 @@ httpsrequired();
|
||||
$selectedIdP = $_POST['idp'];
|
||||
set_saml_cookie($selectedIdP);
|
||||
|
||||
// Redirect to SessionInitiator with providerId as argument
|
||||
// Redirect to SessionInitiator with entityID as argument
|
||||
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'));
|
||||
// For Shibbolet 1.x Service Providers
|
||||
header('Location: '.$IdPs[$selectedIdP][1].'?providerId='. urlencode($selectedIdP) .'&target='. urlencode($CFG->wwwroot.'/auth/shibboleth/index.php'));
|
||||
|
||||
// For Shibbolet 2.x Service Providers
|
||||
// header('Location: '.$IdPs[$selectedIdP][1].'?entityID='. urlencode($selectedIdP) .'&target='. urlencode($CFG->wwwroot.'/auth/shibboleth/index.php'));
|
||||
|
||||
} else {
|
||||
// For Shibbolet 1.x Service Providers
|
||||
header('Location: /Shibboleth.sso?providerId='. urlencode($selectedIdP) .'&target='. urlencode($CFG->wwwroot.'/auth/shibboleth/index.php'));
|
||||
|
||||
// For Shibboleth 2.x Service Providers
|
||||
// header('Location: /Shibboleth.sso/DS?entityID='. urlencode($selectedIdP) .'&target='. urlencode($CFG->wwwroot.'/auth/shibboleth/index.php'));
|
||||
}
|
||||
} elseif (isset($_POST['idp']) && !isset($IdPs[$_POST['idp']])) {
|
||||
$errormsg = get_string('auth_shibboleth_errormsg', 'auth');
|
||||
|
||||
@@ -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}|\/)*))?(?<![,.;])/u';
|
||||
} 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;
|
||||
}
|
||||
|
||||
@@ -427,7 +427,7 @@
|
||||
</SUMMARY>
|
||||
<ALLTEXT></ALLTEXT>
|
||||
<POPUP></POPUP>
|
||||
<OPTIONS>frame</OPTIONS>
|
||||
<OPTIONS></OPTIONS>
|
||||
<TIMEMODIFIED>1094240775</TIMEMODIFIED>
|
||||
</MOD>
|
||||
</xsl:template>
|
||||
@@ -512,7 +512,7 @@
|
||||
<xsl:value-of select="DESCRIPTION/TEXT"/>
|
||||
</ALLTEXT>
|
||||
<POPUP></POPUP>
|
||||
<OPTIONS>frame</OPTIONS>
|
||||
<OPTIONS></OPTIONS>
|
||||
<TIMEMODIFIED>1094240775</TIMEMODIFIED>
|
||||
</MOD>
|
||||
</xsl:template>
|
||||
|
||||
@@ -445,7 +445,7 @@
|
||||
</SUMMARY>
|
||||
<ALLTEXT></ALLTEXT>
|
||||
<POPUP></POPUP>
|
||||
<OPTIONS>frame</OPTIONS>
|
||||
<OPTIONS></OPTIONS>
|
||||
<TIMEMODIFIED>1094240775</TIMEMODIFIED>
|
||||
</MOD>
|
||||
</xsl:template>
|
||||
@@ -503,7 +503,7 @@
|
||||
<xsl:value-of select="DESCRIPTION/TEXT"/>
|
||||
</ALLTEXT>
|
||||
<POPUP></POPUP>
|
||||
<OPTIONS>frame</OPTIONS>
|
||||
<OPTIONS></OPTIONS>
|
||||
<TIMEMODIFIED>1094240775</TIMEMODIFIED>
|
||||
</MOD>
|
||||
</xsl:template>
|
||||
|
||||
@@ -74,9 +74,10 @@ 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");
|
||||
rename_hexfiles($subdir);
|
||||
}
|
||||
|
||||
chdir($startdir);
|
||||
@@ -89,4 +90,34 @@ function blackboard_convert($dir){
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
/**
|
||||
* grabs all files in the directory, checks if the filenames start with a ! or @
|
||||
* then checks to see if the name is a hex - if so, it translates/renames correctly.
|
||||
*
|
||||
* @param string $subdir - the directory to parse.
|
||||
*
|
||||
*/
|
||||
function rename_hexfiles($subdir) {
|
||||
//this bit of code grabs all files in the directory, and if they start with ! or @, performs the name conversion
|
||||
if ($handle = opendir("course_files/$subdir")) {
|
||||
while ($file = readdir($handle)) {
|
||||
if ($file == '..' or $file == '.') { //don't bother processing these!
|
||||
continue;
|
||||
}
|
||||
if(substr($file,0,1)=="!" || substr($file,0,1)=="@"){
|
||||
$outputfilename = "";
|
||||
$filebase = substr($file,1,strrpos($file,".")-1);
|
||||
if (ctype_xdigit($filebase)) { //check if this name is a hex - if not, don't bother to rename
|
||||
$filenamesplit = str_split($filebase,2);
|
||||
foreach($filenamesplit as $hexvalue){
|
||||
$outputfilename .= chr(hexdec($hexvalue));
|
||||
}
|
||||
$outputfilename .= strrchr($file,".");
|
||||
rename("course_files/$subdir/$file","course_files/$subdir/$outputfilename");
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir($handle);
|
||||
}
|
||||
}
|
||||
?>
|
||||
Executable
+714
@@ -0,0 +1,714 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
/**
|
||||
* @package moodlecore
|
||||
* @subpackage backup-imscc
|
||||
* @copyright 2009 Mauro Rondinelli (mauro.rondinelli [AT] uvcms.com)
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') or die('Direct access to this script is forbidden.');
|
||||
|
||||
require_once($CFG->dirroot . '/backup/cc/entities.class.php');
|
||||
require_once($CFG->dirroot . '/backup/cc/entity.label.class.php');
|
||||
require_once($CFG->dirroot . '/backup/cc/entity.resource.class.php');
|
||||
require_once($CFG->dirroot . '/backup/cc/entity.forum.class.php');
|
||||
require_once($CFG->dirroot . '/backup/cc/entity.quiz.class.php');
|
||||
|
||||
class cc2moodle {
|
||||
|
||||
public static $instances = array();
|
||||
public static $manifest;
|
||||
public static $path_to_manifest_folder;
|
||||
|
||||
public static $namespaces = array('imscc' => 'http://www.imsglobal.org/xsd/imscc/imscp_v1p1',
|
||||
'lomimscc' => 'http://ltsc.ieee.org/xsd/imscc/LOM',
|
||||
'lom' => 'http://ltsc.ieee.org/xsd/LOM',
|
||||
'voc' => 'http://ltsc.ieee.org/xsd/LOM/vocab',
|
||||
'xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
|
||||
'cc' => 'http://www.imsglobal.org/xsd/imsccauth_v1p0');
|
||||
|
||||
function __construct ($path_to_manifest) {
|
||||
|
||||
self::$manifest = new DOMDocument();
|
||||
|
||||
self::$path_to_manifest_folder = dirname($path_to_manifest);
|
||||
|
||||
self::log_action('Proccess start');
|
||||
self::log_action('Load the manifest file: ' . $path_to_manifest);
|
||||
|
||||
if (!self::$manifest->load($path_to_manifest)) {
|
||||
self::log_action('Cannot load the manifest file: ' . $path_to_manifest, true);
|
||||
}
|
||||
}
|
||||
|
||||
public function is_auth () {
|
||||
|
||||
$xpath = self::newx_path(self::$manifest, self::$namespaces);
|
||||
|
||||
$count_auth = $xpath->evaluate('count(/imscc:manifest/cc:authorizations)');
|
||||
|
||||
if ($count_auth > 0) {
|
||||
$response = true;
|
||||
} else {
|
||||
$response = false;
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
private function get_metadata ($section, $key) {
|
||||
|
||||
$xpath = self::newx_path(self::$manifest, self::$namespaces);
|
||||
|
||||
$metadata = $xpath->query('/imscc:manifest/imscc:metadata/lomimscc:lom/lomimscc:' . $section . '/lomimscc:' . $key . '/lomimscc:string');
|
||||
$value = !empty($metadata->item(0)->nodeValue) ? $metadata->item(0)->nodeValue : '';
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
public function generate_moodle_xml () {
|
||||
|
||||
global $CFG;
|
||||
|
||||
mkdir(self::$path_to_manifest_folder . DIRECTORY_SEPARATOR . 'course_files');
|
||||
|
||||
$sheet_base = self::loadsheet(SHEET_BASE);
|
||||
|
||||
// MOODLE_BACKUP / INFO / DETAILS / MOD
|
||||
$node_info_details_mod = $this->create_code_info_details_mod();
|
||||
|
||||
// MOODLE_BACKUP / BLOCKS / BLOCK
|
||||
$node_course_blocks_block = $this->create_node_course_blocks_block();
|
||||
|
||||
// MOODLE_BACKUP / COURSES / SECTIONS / SECTION
|
||||
$node_course_sections_section = $this->create_node_course_sections_section();
|
||||
|
||||
// MOODLE_BACKUP / COURSES / QUESTION_CATEGORIES
|
||||
$node_course_question_categories = $this->create_node_question_categories();
|
||||
|
||||
// MOODLE_BACKUP / COURSES / MODULES / MOD
|
||||
$node_course_modules_mod = $this->create_node_course_modules_mod();
|
||||
|
||||
// MOODLE_BACKUP / COURSE / HEADER
|
||||
$node_course_header = $this->create_node_course_header();
|
||||
|
||||
// GENERAL INFO
|
||||
$filename = optional_param('file', 'not_available.zip');
|
||||
$filename = basename($filename);
|
||||
|
||||
$www_root = $CFG->wwwroot;
|
||||
|
||||
$find_tags = array('[#zip_filename#]',
|
||||
'[#www_root#]',
|
||||
'[#node_course_header#]',
|
||||
'[#node_info_details_mod#]',
|
||||
'[#node_course_blocks_block#]',
|
||||
'[#node_course_sections_section#]',
|
||||
'[#node_course_question_categories#]',
|
||||
'[#node_course_modules#]');
|
||||
|
||||
$replace_values = array($filename,
|
||||
$www_root,
|
||||
$node_course_header,
|
||||
$node_info_details_mod,
|
||||
$node_course_blocks_block,
|
||||
$node_course_sections_section,
|
||||
$node_course_question_categories,
|
||||
$node_course_modules_mod);
|
||||
|
||||
$result_xml = str_replace($find_tags, $replace_values, $sheet_base);
|
||||
|
||||
// COPY RESOURSE FILES
|
||||
$entities = new entities();
|
||||
|
||||
$entities->move_all_files();
|
||||
|
||||
if (array_key_exists("index", self::$instances)) {
|
||||
|
||||
if (!file_put_contents(self::$path_to_manifest_folder . DIRECTORY_SEPARATOR . 'moodle.xml', $result_xml)) {
|
||||
self::log_action('Cannot save the moodle manifest file: ' . self::$path_to_tmp_folder . DIRECTORY_SEPARATOR . 'moodle.xml', true);
|
||||
} else {
|
||||
$status = true;
|
||||
}
|
||||
|
||||
} else {
|
||||
$status = false;
|
||||
notify('The course is empty');
|
||||
self::log_action('The course is empty', false);
|
||||
}
|
||||
|
||||
return $status;
|
||||
|
||||
}
|
||||
|
||||
private function get_sections_numbers ($instances) {
|
||||
|
||||
$count = 0;
|
||||
|
||||
if (array_key_exists("index", $instances)) {
|
||||
foreach ($instances["index"] as $instance) {
|
||||
if ($instance["deep"] == ROOT_DEEP) {
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $count;
|
||||
}
|
||||
|
||||
private function create_node_course_header () {
|
||||
|
||||
$node_course_header = '';
|
||||
$sheet_course_header = self::loadsheet(SHEET_COURSE_HEADER);
|
||||
|
||||
$course_title = $this->get_metadata('general', 'title');
|
||||
$section_count = $this->get_sections_numbers(self::$instances) - 1;
|
||||
|
||||
if ($section_count == -1) {
|
||||
$section_count = 0;
|
||||
}
|
||||
|
||||
if (empty($course_title)) {
|
||||
$this->log_action('The course title not found', true);
|
||||
}
|
||||
|
||||
$course_short_name = $this->create_course_code($course_title);
|
||||
|
||||
$find_tags = array('[#course_name#]',
|
||||
'[#course_short_name#]',
|
||||
'[#date_now#]',
|
||||
'[#section_count#]');
|
||||
|
||||
$replace_values = array($course_title,
|
||||
$course_short_name,
|
||||
time(),
|
||||
$section_count);
|
||||
|
||||
$node_course_header = str_replace($find_tags, $replace_values, $sheet_course_header);
|
||||
|
||||
return $node_course_header;
|
||||
}
|
||||
|
||||
private function create_node_question_categories () {
|
||||
|
||||
$quiz = new quiz();
|
||||
|
||||
self::log_action('Creating node: QUESTION_CATEGORIES');
|
||||
|
||||
$node_course_question_categories = $quiz->generate_node_question_categories();
|
||||
|
||||
return $node_course_question_categories;
|
||||
}
|
||||
|
||||
private function create_node_course_modules_mod () {
|
||||
|
||||
$labels = new label();
|
||||
$resources = new resource();
|
||||
$forums = new forum();
|
||||
$quiz = new quiz();
|
||||
|
||||
self::log_action('Creating node: COURSE/MODULES/MOD');
|
||||
|
||||
// LABELS
|
||||
$node_course_modules_mod_label = $labels->generate_node();
|
||||
|
||||
// RESOURCES (WEB CONTENT AND WEB LINK)
|
||||
$node_course_modules_mod_resource = $resources->generate_node();
|
||||
|
||||
// FORUMS
|
||||
$node_course_modules_mod_forum = $forums->generate_node();
|
||||
|
||||
// QUIZ
|
||||
$node_course_modules_mod_quiz = $quiz->generate_node_course_modules_mod();
|
||||
$node_course_modules = $node_course_modules_mod_label . $node_course_modules_mod_resource . $node_course_modules_mod_forum . $node_course_modules_mod_quiz;
|
||||
|
||||
return $node_course_modules;
|
||||
}
|
||||
|
||||
|
||||
private function create_node_course_sections_section () {
|
||||
|
||||
self::log_action('Creating node: COURSE/SECTIONS/SECTION');
|
||||
|
||||
$node_course_sections_section = '';
|
||||
$sheet_course_sections_section = self::loadsheet(SHEET_COURSE_SECTIONS_SECTION);
|
||||
|
||||
$topics = $this->get_nodes_by_criteria('deep', ROOT_DEEP);
|
||||
|
||||
$i = 0;
|
||||
|
||||
if (!empty($topics)) {
|
||||
|
||||
foreach ($topics as $topic) {
|
||||
|
||||
$i++;
|
||||
$node_node_course_sections_section_mods_mod = $this->create_node_course_sections_section_mods_mod($topic['index']);
|
||||
|
||||
if ($topic['moodle_type'] == MOODLE_TYPE_LABEL) {
|
||||
|
||||
$find_tags = array('[#section_id#]',
|
||||
'[#section_number#]',
|
||||
'[#section_summary#]',
|
||||
'[#node_course_sections_section_mods_mod#]');
|
||||
|
||||
$replace_values = array($i,
|
||||
$i - 1,
|
||||
$topic['title'],
|
||||
$node_node_course_sections_section_mods_mod);
|
||||
|
||||
} else {
|
||||
|
||||
$find_tags = array('[#section_id#]',
|
||||
'[#section_number#]',
|
||||
'[#section_summary#]',
|
||||
'[#node_course_sections_section_mods_mod#]');
|
||||
|
||||
$replace_values = array($i,
|
||||
$i - 1,
|
||||
'',
|
||||
$node_node_course_sections_section_mods_mod);
|
||||
|
||||
}
|
||||
|
||||
$node_course_sections_section .= str_replace($find_tags, $replace_values, $sheet_course_sections_section);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $node_course_sections_section;
|
||||
}
|
||||
|
||||
private function create_node_course_blocks_block () {
|
||||
|
||||
global $CFG;
|
||||
|
||||
self::log_action('Creating node: COURSE/BLOCKS/BLOCK');
|
||||
|
||||
$sheet_course_blocks_block = self::loadsheet(SHEET_COURSE_BLOCKS_BLOCK);
|
||||
$node_course_blocks_block = '';
|
||||
|
||||
$format_config = $CFG->dirroot . '/course/format/weeks/config.php';
|
||||
|
||||
if (@is_file($format_config) && is_readable($format_config)) {
|
||||
require ($format_config);
|
||||
}
|
||||
|
||||
if (!empty($format['defaultblocks'])) {
|
||||
$blocknames = $format['defaultblocks'];
|
||||
} else {
|
||||
if (!empty($CFG->defaultblocks)) {
|
||||
$blocknames = $CFG->defaultblocks;
|
||||
} else {
|
||||
$blocknames = 'participants,activity_modules,search_forums,admin,course_list:news_items,calendar_upcoming,recent_activity';
|
||||
}
|
||||
}
|
||||
|
||||
$blocknames = explode(':', $blocknames);
|
||||
$blocks_left = explode(',', $blocknames[0]);
|
||||
$blocks_right = explode(',', $blocknames[1]);
|
||||
|
||||
$find_tags = array('[#block_id#]',
|
||||
'[#block_name#]',
|
||||
'[#block_position#]',
|
||||
'[#block_weight#]');
|
||||
|
||||
$i = 0;
|
||||
$weight = 0;
|
||||
|
||||
foreach ($blocks_left as $block) {
|
||||
$i++;
|
||||
$weight++;
|
||||
|
||||
$replace_values = array($i,
|
||||
$block,
|
||||
'l',
|
||||
$weight);
|
||||
|
||||
$node_course_blocks_block .= str_replace($find_tags, $replace_values, $sheet_course_blocks_block);
|
||||
}
|
||||
|
||||
$weight = 0;
|
||||
|
||||
foreach ($blocks_right as $block) {
|
||||
|
||||
$i++;
|
||||
$weight ++;
|
||||
|
||||
$replace_values = array($i,
|
||||
$block,
|
||||
'r',
|
||||
$weight);
|
||||
|
||||
$node_course_blocks_block .= str_replace($find_tags, $replace_values, $sheet_course_blocks_block);
|
||||
}
|
||||
|
||||
return $node_course_blocks_block;
|
||||
|
||||
}
|
||||
|
||||
private function create_node_course_sections_section_mods_mod ($root_parent) {
|
||||
|
||||
$sheet_course_sections_section_mods_mod = self::loadsheet(SHEET_COURSE_SECTIONS_SECTION_MODS_MOD);
|
||||
$childs = $this->get_nodes_by_criteria('root_parent', $root_parent);
|
||||
|
||||
if ($childs) {
|
||||
|
||||
$node_course_sections_section_mods_mod = '';
|
||||
|
||||
foreach ($childs as $child) {
|
||||
|
||||
if ($child['moodle_type'] == MOODLE_TYPE_LABEL) {
|
||||
if ($child['index'] == $child['root_parent']) {
|
||||
$is_summary = true;
|
||||
} else {
|
||||
$is_summary = false;
|
||||
}
|
||||
} else {
|
||||
$is_summary = false;
|
||||
}
|
||||
|
||||
if (!$is_summary) {
|
||||
|
||||
$indent = $child['deep'] - ROOT_DEEP;
|
||||
|
||||
if ($indent > 0) {
|
||||
$indent = $indent - 1;
|
||||
}
|
||||
|
||||
$find_tags = array('[#mod_id#]',
|
||||
'[#mod_instance_id#]',
|
||||
'[#mod_type#]',
|
||||
'[#date_now#]',
|
||||
'[#mod_indent#]');
|
||||
|
||||
$replace_values = array($child['index'],
|
||||
$child['instance'],
|
||||
$child['moodle_type'],
|
||||
time(),
|
||||
$indent);
|
||||
|
||||
$node_course_sections_section_mods_mod .= str_replace($find_tags, $replace_values, $sheet_course_sections_section_mods_mod);
|
||||
}
|
||||
}
|
||||
|
||||
$response = $node_course_sections_section_mods_mod;
|
||||
|
||||
} else {
|
||||
$response = '';
|
||||
}
|
||||
|
||||
return $response;
|
||||
|
||||
}
|
||||
|
||||
public function get_nodes_by_criteria ($key, $value) {
|
||||
|
||||
$response = array();
|
||||
|
||||
if (array_key_exists('index', self::$instances)) {
|
||||
foreach (self::$instances['index'] as $item) {
|
||||
if ($item[$key] == $value) {
|
||||
$response[] = $item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
private function create_code_info_details_mod () {
|
||||
|
||||
self::log_action('Creating node: INFO/DETAILS/MOD');
|
||||
|
||||
$xpath = self::newx_path(self::$manifest, self::$namespaces);
|
||||
|
||||
$items = $xpath->query('/imscc:manifest/imscc:organizations/imscc:organization/imscc:item | /imscc:manifest/imscc:resources/imscc:resource[@type="' . CC_TYPE_QUESTION_BANK . '"]');
|
||||
|
||||
$this->create_instances($items);
|
||||
|
||||
$count_quiz = $this->count_instances(MOODLE_TYPE_QUIZ);
|
||||
$count_forum = $this->count_instances(MOODLE_TYPE_FORUM);
|
||||
$count_resource = $this->count_instances(MOODLE_TYPE_RESOURCE);
|
||||
$count_label = $this->count_instances(MOODLE_TYPE_LABEL);
|
||||
|
||||
$sheet_info_details_mod_instances_instance = self::loadsheet(SHEET_INFO_DETAILS_MOD_INSTANCE);
|
||||
|
||||
if ($count_resource > 0) {
|
||||
$resource_instance = $this->create_mod_info_details_mod_instances_instance($sheet_info_details_mod_instances_instance, $count_resource, self::$instances['instances'][MOODLE_TYPE_RESOURCE]);
|
||||
}
|
||||
if ($count_quiz > 0) {
|
||||
$quiz_instance = $this->create_mod_info_details_mod_instances_instance($sheet_info_details_mod_instances_instance, $count_quiz, self::$instances['instances'][MOODLE_TYPE_QUIZ]);
|
||||
}
|
||||
if ($count_forum > 0) {
|
||||
$forum_instance = $this->create_mod_info_details_mod_instances_instance($sheet_info_details_mod_instances_instance, $count_forum, self::$instances['instances'][MOODLE_TYPE_FORUM]);
|
||||
}
|
||||
if ($count_label > 0) {
|
||||
$label_instance = $this->create_mod_info_details_mod_instances_instance($sheet_info_details_mod_instances_instance, $count_label, self::$instances['instances'][MOODLE_TYPE_LABEL]);
|
||||
}
|
||||
|
||||
$resource_mod = $count_resource ? $this->create_mod_info_details_mod(MOODLE_TYPE_RESOURCE, $resource_instance) : '';
|
||||
$quiz_mod = $count_quiz ? $this->create_mod_info_details_mod(MOODLE_TYPE_QUIZ, $quiz_instance) : '';
|
||||
$forum_mod = $count_forum ? $this->create_mod_info_details_mod(MOODLE_TYPE_FORUM, $forum_instance) : '';
|
||||
$label_mod = $count_label ? $this->create_mod_info_details_mod(MOODLE_TYPE_LABEL, $label_instance) : '';
|
||||
|
||||
return $label_mod . $resource_mod . $quiz_mod . $forum_mod;
|
||||
|
||||
}
|
||||
|
||||
private function create_mod_info_details_mod ($mod_type, $node_info_details_mod_instances_instance) {
|
||||
|
||||
$sheet_info_details_mod = self::loadsheet(SHEET_INFO_DETAILS_MOD);
|
||||
|
||||
$find_tags = array('[#mod_type#]' ,'[#node_info_details_mod_instances_instance#]');
|
||||
$replace_values = array($mod_type , $node_info_details_mod_instances_instance);
|
||||
|
||||
return str_replace($find_tags, $replace_values, $sheet_info_details_mod);
|
||||
}
|
||||
|
||||
private function create_mod_info_details_mod_instances_instance ($sheet, $instances_quantity, $instances) {
|
||||
|
||||
$instance = '';
|
||||
|
||||
$find_tags = array('[#mod_instance_id#]',
|
||||
'[#mod_name#]',
|
||||
'[#mod_user_info#]');
|
||||
|
||||
for ($i = 1; $i <= $instances_quantity; $i++) {
|
||||
|
||||
$user_info = ($instances[$i - 1]['common_cartriedge_type'] == CC_TYPE_FORUM) ? 'true' : 'false';
|
||||
|
||||
$replace_values = array($instances[$i - 1]['instance'],
|
||||
$instances[$i - 1]['title'],
|
||||
$user_info);
|
||||
|
||||
$instance .= str_replace($find_tags, $replace_values, $sheet);
|
||||
}
|
||||
|
||||
return $instance;
|
||||
|
||||
}
|
||||
|
||||
private function create_instances ($items, $level = 0, &$array_index = 0, $index_root = 0) {
|
||||
|
||||
$level++;
|
||||
$i = 1;
|
||||
|
||||
if ($items) {
|
||||
|
||||
$xpath = self::newx_path(self::$manifest, self::$namespaces);
|
||||
|
||||
foreach ($items as $item) {
|
||||
|
||||
$array_index++;
|
||||
|
||||
if ($item->nodeName == "item") {
|
||||
|
||||
$identifierref = $xpath->query('@identifierref', $item);
|
||||
$identifierref = !empty($identifierref->item(0)->nodeValue) ? $identifierref->item(0)->nodeValue : '';
|
||||
|
||||
$title = $xpath->query('imscc:title', $item);
|
||||
$title = !empty($title->item(0)->nodeValue) ? $title->item(0)->nodeValue : '';
|
||||
|
||||
$cc_type = $this->get_item_cc_type($identifierref);
|
||||
$moodle_type = $this->convert_to_moodle_type($cc_type);
|
||||
|
||||
}
|
||||
elseif ($item->nodeName == "resource") {
|
||||
|
||||
$identifierref = $xpath->query('@identifier', $item);
|
||||
$identifierref = !empty($identifierref->item(0)->nodeValue) ? $identifierref->item(0)->nodeValue : '';
|
||||
|
||||
$cc_type = $this->get_item_cc_type($identifierref);
|
||||
$moodle_type = $this->convert_to_moodle_type($cc_type);
|
||||
|
||||
$title = 'Quiz Bank ' . ($this->count_instances($moodle_type) + 1);
|
||||
|
||||
}
|
||||
|
||||
if ($level == ROOT_DEEP) {
|
||||
$index_root = $array_index;
|
||||
}
|
||||
|
||||
self::$instances['index'][$array_index]['common_cartriedge_type'] = $cc_type;
|
||||
self::$instances['index'][$array_index]['moodle_type'] = $moodle_type;
|
||||
self::$instances['index'][$array_index]['title'] = $title ? $title : '';
|
||||
self::$instances['index'][$array_index]['root_parent'] = $index_root;
|
||||
self::$instances['index'][$array_index]['index'] = $array_index;
|
||||
self::$instances['index'][$array_index]['deep'] = $level;
|
||||
self::$instances['index'][$array_index]['instance'] = $this->count_instances($moodle_type);
|
||||
self::$instances['index'][$array_index]['resource_indentifier'] = $identifierref;
|
||||
|
||||
self::$instances['instances'][$moodle_type][] = array('title' => $title,
|
||||
'instance' => self::$instances['index'][$array_index]['instance'],
|
||||
'common_cartriedge_type' => $cc_type , 'resource_indentifier' => $identifierref);
|
||||
|
||||
$more_items = $xpath->query('imscc:item', $item);
|
||||
|
||||
if ($more_items->length > 0) {
|
||||
$this->create_instances($more_items, $level, $array_index, $index_root);
|
||||
}
|
||||
|
||||
$i++;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function count_instances ($type) {
|
||||
|
||||
$quantity = 0;
|
||||
|
||||
if (array_key_exists('index', self::$instances)) {
|
||||
if (self::$instances['index'] && $type) {
|
||||
|
||||
foreach (self::$instances['index'] as $instance) {
|
||||
if (!empty($instance['moodle_type'])) {
|
||||
$types[] = $instance['moodle_type'];
|
||||
}
|
||||
}
|
||||
|
||||
$quantity_instances = array_count_values($types);
|
||||
$quantity = array_key_exists($type, $quantity_instances) ? $quantity_instances[$type] : 0;
|
||||
}
|
||||
}
|
||||
|
||||
return $quantity;
|
||||
}
|
||||
|
||||
public function convert_to_moodle_type ($cc_type) {
|
||||
|
||||
if ($cc_type == CC_TYPE_FORUM) {
|
||||
$type = MOODLE_TYPE_FORUM;
|
||||
}
|
||||
if ($cc_type == CC_TYPE_QUIZ) {
|
||||
$type = MOODLE_TYPE_QUIZ;
|
||||
}
|
||||
if ($cc_type == CC_TYPE_WEBLINK) {
|
||||
$type = MOODLE_TYPE_RESOURCE;
|
||||
}
|
||||
if ($cc_type == CC_TYPE_WEBCONTENT) {
|
||||
$type = MOODLE_TYPE_RESOURCE;
|
||||
}
|
||||
if ($cc_type == CC_TYPE_ASSOCIATED_CONTENT) {
|
||||
$type = MOODLE_TYPE_RESOURCE;
|
||||
}
|
||||
if ($cc_type == CC_TYPE_QUESTION_BANK) {
|
||||
$type = MOODLE_TYPE_QUESTION_BANK;
|
||||
}
|
||||
if ($cc_type == CC_TYPE_EMPTY) {
|
||||
$type = MOODLE_TYPE_LABEL;
|
||||
}
|
||||
|
||||
$type = empty($type) ? TYPE_UNKNOWN : $type;
|
||||
|
||||
return $type;
|
||||
}
|
||||
|
||||
public function get_item_cc_type ($identifier) {
|
||||
|
||||
$xpath = self::newx_path(self::$manifest, self::$namespaces);
|
||||
|
||||
$nodes = $xpath->query('/imscc:manifest/imscc:resources/imscc:resource[@identifier="' . $identifier . '"]/@type');
|
||||
|
||||
if ($nodes && !empty($nodes->item(0)->nodeValue)) {
|
||||
return $nodes->item(0)->nodeValue;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
public static function newx_path (DOMDocument $manifest, $namespaces = '') {
|
||||
|
||||
$xpath = new DOMXPath($manifest);
|
||||
|
||||
if (!empty($namespaces)) {
|
||||
foreach ($namespaces as $prefix => $ns) {
|
||||
if (!$xpath->registerNamespace($prefix, $ns)) {
|
||||
self::log_action('Cannot register the namespace: ' . $prefix . ':' . $ns, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $xpath;
|
||||
}
|
||||
|
||||
public static function loadsheet ($file) {
|
||||
|
||||
$content = (is_readable($file) && ($content = file_get_contents($file))) ? $content : false;
|
||||
|
||||
self::log_action('Loading sheet: ' . $file);
|
||||
|
||||
if (!$content) {
|
||||
self::log_action('Cannot load the xml sheet: ' . $file, true);
|
||||
}
|
||||
|
||||
self::log_action('Load OK!');
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
public static function log_action ($text, $critical_error = false) {
|
||||
|
||||
$filename = cc2moodle::$path_to_manifest_folder . DIRECTORY_SEPARATOR . 'cc2moodle.log';
|
||||
$full_message = strtoupper(date("j/n/Y g:i:s a")) . " - " . $text . "\r";
|
||||
|
||||
file_put_contents($filename, $full_message, FILE_APPEND);
|
||||
|
||||
if ($critical_error) {
|
||||
self::critical_error($text);
|
||||
}
|
||||
}
|
||||
|
||||
private function critical_error ($text) {
|
||||
|
||||
$path_to_log = cc2moodle::$path_to_manifest_folder . '/cc2moodle.log';
|
||||
|
||||
echo '
|
||||
|
||||
<p>
|
||||
<hr />A critical error has been found!
|
||||
|
||||
<p>' . $text . '</p>
|
||||
|
||||
|
||||
<p>
|
||||
The process has been stopped. Please see the <a href="' . $path_to_log . '">log file</a> for more information.</p>
|
||||
|
||||
<p>Log: ' . $path_to_log . '</p>
|
||||
|
||||
<hr />
|
||||
|
||||
</p>
|
||||
';
|
||||
|
||||
die();
|
||||
}
|
||||
|
||||
private function create_course_code ($title) {
|
||||
|
||||
$code = '';
|
||||
$words = explode(' ', $title);
|
||||
|
||||
foreach ($words as $word) {
|
||||
$code .= $word[0];
|
||||
}
|
||||
|
||||
$code = strtoupper($code . '-1');
|
||||
return $code;
|
||||
}
|
||||
}
|
||||
?>
|
||||
Executable
+270
@@ -0,0 +1,270 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
/**
|
||||
* @package moodlecore
|
||||
* @subpackage backup-imscc
|
||||
* @copyright 2009 Mauro Rondinelli (mauro.rondinelli [AT] uvcms.com)
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') or die('Direct access to this script is forbidden.');
|
||||
|
||||
class entities {
|
||||
|
||||
public function load_xml_resource ($path_to_file) {
|
||||
|
||||
$resource = new DOMDocument();
|
||||
|
||||
cc2moodle::log_action('Load the XML resource file: ' . $path_to_file);
|
||||
|
||||
if (!$resource->load($path_to_file)) {
|
||||
cc2moodle::log_action('Cannot load the XML resource file: ' . $path_to_file, true);
|
||||
}
|
||||
|
||||
return $resource;
|
||||
}
|
||||
|
||||
public function update_sources ($html, $root_path = '') {
|
||||
|
||||
$document = new DOMDocument();
|
||||
|
||||
@$document->loadHTML($html);
|
||||
|
||||
$tags = array('img' => 'src' , 'a' => 'href');
|
||||
|
||||
foreach ($tags as $tag => $attribute) {
|
||||
|
||||
$elements = $document->getElementsByTagName($tag);
|
||||
|
||||
foreach ($elements as $element) {
|
||||
|
||||
$attribute_value = $element->getAttribute($attribute);
|
||||
$protocol = parse_url($attribute_value, PHP_URL_SCHEME);
|
||||
|
||||
if (empty($protocol)) {
|
||||
$attribute_value = str_replace("\$IMS-CC-FILEBASE\$", "", $attribute_value);
|
||||
$attribute_value = $this->full_path($root_path . "/" . $attribute_value, "/");
|
||||
$attribute_value = "\$@FILEPHP@\$" . "/" . $attribute_value;
|
||||
}
|
||||
|
||||
$element->setAttribute($attribute, $attribute_value);
|
||||
}
|
||||
}
|
||||
|
||||
$html = $this->clear_doctype($document->saveHTML());
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
public function full_path ($path, $dir_sep = DIRECTORY_SEPARATOR) {
|
||||
|
||||
$token = '$IMS-CC-FILEBASE$';
|
||||
$path = str_replace($token, '', $path);
|
||||
|
||||
if (is_string($path) && ($path != '')) {
|
||||
$dir_sep;
|
||||
$dot_dir = '.';
|
||||
$up_dir = '..';
|
||||
$length = strlen($path);
|
||||
$rtemp = trim($path);
|
||||
$start = strrpos($path, $dir_sep);
|
||||
$can_continue = ($start !== false);
|
||||
$result = $can_continue ? '' : $path;
|
||||
$rcount = 0;
|
||||
|
||||
while ($can_continue) {
|
||||
|
||||
$dir_part = ($start !== false) ? substr($rtemp, $start + 1, $length - $start) : $rtemp;
|
||||
$can_continue = ($dir_part !== false);
|
||||
|
||||
if ($can_continue) {
|
||||
if ($dir_part != $dot_dir) {
|
||||
if ($dir_part == $up_dir) {
|
||||
$rcount++;
|
||||
} else {
|
||||
if ($rcount > 0) {
|
||||
$rcount --;
|
||||
} else {
|
||||
$result = ($result == '') ? $dir_part : $dir_part . $dir_sep . $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
$rtemp = substr($path, 0, $start);
|
||||
$start = strrpos($rtemp, $dir_sep);
|
||||
$can_continue = (($start !== false) || (strlen($rtemp) > 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
public function include_titles ($html) {
|
||||
|
||||
$document = new DOMDocument();
|
||||
@$document->loadHTML($html);
|
||||
|
||||
$images = $document->getElementsByTagName('img');
|
||||
|
||||
foreach ($images as $image) {
|
||||
|
||||
$src = $image->getAttribute('src');
|
||||
$alt = $image->getAttribute('alt');
|
||||
$title = $image->getAttribute('title');
|
||||
|
||||
$filename = pathinfo($src);
|
||||
$filename = $filename['filename'];
|
||||
|
||||
$alt = empty($alt) ? $filename : $alt;
|
||||
$title = empty($title) ? $filename : $title;
|
||||
|
||||
$image->setAttribute('alt', $alt);
|
||||
$image->setAttribute('title', $title);
|
||||
}
|
||||
|
||||
$html = $this->clear_doctype($document->saveHTML());
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
public function get_external_xml ($identifier) {
|
||||
|
||||
$response = '';
|
||||
|
||||
$xpath = cc2moodle::newx_path(cc2moodle::$manifest, cc2moodle::$namespaces);
|
||||
|
||||
$files = $xpath->query('/imscc:manifest/imscc:resources/imscc:resource[@identifier="' . $identifier . '"]/imscc:file/@href');
|
||||
|
||||
if (empty($files)) {
|
||||
$response = '';
|
||||
} else {
|
||||
$response = $files->item(0)->nodeValue;
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function move_files ($files, $destination_folder) {
|
||||
|
||||
if (!empty($files)) {
|
||||
|
||||
foreach ($files as $file) {
|
||||
|
||||
$source = cc2moodle::$path_to_manifest_folder . DIRECTORY_SEPARATOR . $file->nodeValue;
|
||||
$destination = $destination_folder . DIRECTORY_SEPARATOR . $file->nodeValue;
|
||||
|
||||
$destination_directory = dirname($destination);
|
||||
|
||||
cc2moodle::log_action('Copy the file: ' . $source . ' to ' . $destination);
|
||||
|
||||
//echo 'Copy the file: ' . $source . ' to ' . $destination . '<br>';
|
||||
|
||||
if (!file_exists($destination_directory)) {
|
||||
mkdir($destination_directory, 0777, true);
|
||||
}
|
||||
|
||||
$copy_success = @copy($source, $destination);
|
||||
|
||||
if (!$copy_success) {
|
||||
notify('WARNING: Cannot copy the file ' . $source . ' to ' . $destination);
|
||||
cc2moodle::log_action('Cannot copy the file ' . $source . ' to ' . $destination, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function get_all_files () {
|
||||
|
||||
$all_files = array();
|
||||
|
||||
$xpath = cc2moodle::newx_path(cc2moodle::$manifest, cc2moodle::$namespaces);
|
||||
|
||||
$types = array('associatedcontent/imscc_xmlv1p0/learning-application-resource',
|
||||
'webcontent',
|
||||
);
|
||||
|
||||
foreach ($types as $type) {
|
||||
|
||||
$files = $xpath->query('/imscc:manifest/imscc:resources/imscc:resource[@type="' . $type . '"]/imscc:file/@href');
|
||||
|
||||
if (!empty($files)) {
|
||||
foreach ($files as $file) {
|
||||
$all_files[] = $file;
|
||||
}
|
||||
}
|
||||
|
||||
unset($files);
|
||||
}
|
||||
|
||||
$all_files = empty($all_files) ? '' : $all_files;
|
||||
|
||||
return $all_files;
|
||||
}
|
||||
|
||||
public function move_all_files() {
|
||||
|
||||
$files = $this->get_all_files();
|
||||
|
||||
if (!empty($files)) {
|
||||
$this->move_files($files, cc2moodle::$path_to_manifest_folder . DIRECTORY_SEPARATOR . 'course_files', true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function clear_doctype ($html) {
|
||||
|
||||
return preg_replace('/^<!DOCTYPE.+?>/',
|
||||
'',
|
||||
str_replace(array('<html>' , '</html>' , '<body>' , '</body>'),
|
||||
array('' , '' , '' , ''),
|
||||
$html));
|
||||
}
|
||||
|
||||
public function generate_random_string ($length = 6) {
|
||||
|
||||
$response = '';
|
||||
$source = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
|
||||
if ($length > 0) {
|
||||
|
||||
$response = '';
|
||||
$source = str_split($source, 1);
|
||||
|
||||
for ($i = 1; $i <= $length; $i++) {
|
||||
mt_srand((double) microtime() * 1000000);
|
||||
$num = mt_rand(1, count($source));
|
||||
$response .= $source[$num - 1];
|
||||
}
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function truncate_text ($text, $max, $remove_html) {
|
||||
|
||||
if ($max > 10) {
|
||||
$text = substr($text, 0, ($max - 6)) . ' [...]';
|
||||
} else {
|
||||
$text = substr($text, 0, $max);
|
||||
}
|
||||
|
||||
$text = $remove_html ? strip_tags($text) : $text;
|
||||
|
||||
return $text;
|
||||
}
|
||||
}
|
||||
?>
|
||||
Executable
+128
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
/**
|
||||
* @package moodlecore
|
||||
* @subpackage backup-imscc
|
||||
* @copyright 2009 Mauro Rondinelli (mauro.rondinelli [AT] uvcms.com)
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') or die('Direct access to this script is forbidden.');
|
||||
|
||||
class forum extends entities {
|
||||
|
||||
public function generate_node () {
|
||||
|
||||
cc2moodle::log_action('Creating Forum mods');
|
||||
|
||||
$response = '';
|
||||
|
||||
if (!empty(cc2moodle::$instances['instances'][MOODLE_TYPE_FORUM])) {
|
||||
foreach (cc2moodle::$instances['instances'][MOODLE_TYPE_FORUM] as $instance) {
|
||||
$response .= $this->create_node_course_modules_mod_forum($instance);
|
||||
}
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
private function create_node_course_modules_mod_forum ($instance) {
|
||||
|
||||
$sheet_mod_forum = cc2moodle::loadsheet(SHEET_COURSE_SECTIONS_SECTION_MODS_MOD_FORUM);
|
||||
|
||||
$topic_data = $this->get_topic_data($instance);
|
||||
|
||||
if (!empty($topic_data)) {
|
||||
|
||||
$find_tags = array('[#mod_instance#]',
|
||||
'[#mod_forum_title#]',
|
||||
'[#mod_forum_intro#]',
|
||||
'[#date_now#]');
|
||||
|
||||
$replace_values = array($instance['instance'],
|
||||
$instance['title'] . ' - ' . $topic_data['title'],
|
||||
$topic_data['description'],
|
||||
time());
|
||||
|
||||
return str_replace($find_tags, $replace_values, $sheet_mod_forum);
|
||||
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
public function get_topic_data ($instance) {
|
||||
|
||||
$topic_data = '';
|
||||
|
||||
$namespaces = array('dt' => 'http://www.imsglobal.org/xsd/imsdt_v1p0');
|
||||
|
||||
$topic_file = $this->get_external_xml($instance['resource_indentifier']);
|
||||
|
||||
if (!empty($topic_file)) {
|
||||
|
||||
$topic = $this->load_xml_resource(cc2moodle::$path_to_manifest_folder . DIRECTORY_SEPARATOR . $topic_file);
|
||||
|
||||
if (!empty($topic)) {
|
||||
|
||||
$xpath = cc2moodle::newx_path($topic, $namespaces);
|
||||
|
||||
$topic_title = $xpath->query('/dt:topic/title');
|
||||
$topic_title = !empty($topic_title->item(0)->nodeValue) ? $topic_title->item(0)->nodeValue : '';
|
||||
|
||||
$topic_text = $xpath->query('/dt:topic/text');
|
||||
$topic_text = !empty($topic_text->item(0)->nodeValue) ? $this->update_sources($topic_text->item(0)->nodeValue, dirname($topic_file)) : '';
|
||||
$topic_text = !empty($topic_text) ? str_replace("%24", "\$", $this->include_titles($topic_text)) : '';
|
||||
|
||||
if (!empty($topic_title)) {
|
||||
$topic_data['title'] = $topic_title;
|
||||
$topic_data['description'] = $topic_text;
|
||||
}
|
||||
}
|
||||
|
||||
$topic_attachments = $xpath->query('/dt:topic/attachments/attachment/@href');
|
||||
|
||||
if ($topic_attachments->length > 0) {
|
||||
|
||||
$attachment_html = '';
|
||||
|
||||
foreach ($topic_attachments as $file) {
|
||||
$attachment_html .= $this->generate_attachment_html($file->nodeValue);
|
||||
}
|
||||
|
||||
$topic_data['description'] = !empty($attachment_html) ? $topic_text . '<p>Attachments:</p>' . $attachment_html : $topic_text;
|
||||
}
|
||||
}
|
||||
|
||||
return $topic_data;
|
||||
}
|
||||
|
||||
private function generate_attachment_html ($filename) {
|
||||
|
||||
$images_extensions = array('gif' , 'jpeg' , 'jpg' , 'jif' , 'jfif' , 'png' , 'bmp');
|
||||
|
||||
$fileinfo = pathinfo($filename);
|
||||
|
||||
if (in_array($fileinfo['extension'], $images_extensions)) {
|
||||
return '<img src="$@FILEPHP@$/' . $filename . '" title="' . $fileinfo['basename'] . '" alt="' . $fileinfo['basename'] . '" /><br />';
|
||||
} else {
|
||||
return '<a href="$@FILEPHP@$/' . $filename . '" title="' . $fileinfo['basename'] . '" alt="' . $fileinfo['basename'] . '">' . $fileinfo['basename'] . '</a><br />';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
||||
?>
|
||||
Executable
+59
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
/**
|
||||
* @package moodlecore
|
||||
* @subpackage backup-imscc
|
||||
* @copyright 2009 Mauro Rondinelli (mauro.rondinelli [AT] uvcms.com)
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') or die('Direct access to this script is forbidden.');
|
||||
|
||||
class label extends entities {
|
||||
|
||||
public function generate_node () {
|
||||
|
||||
cc2moodle::log_action('Creating Labels mods');
|
||||
|
||||
$response = '';
|
||||
|
||||
$sheet_mod_label = cc2moodle::loadsheet(SHEET_COURSE_SECTIONS_SECTION_MODS_MOD_LABEL);
|
||||
|
||||
if (!empty(cc2moodle::$instances['instances'][MOODLE_TYPE_LABEL])) {
|
||||
foreach (cc2moodle::$instances['instances'][MOODLE_TYPE_LABEL] as $instance) {
|
||||
$response .= $this->create_node_course_modules_mod_label($sheet_mod_label, $instance);
|
||||
}
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
private function create_node_course_modules_mod_label ($sheet_mod_label, $instance) {
|
||||
|
||||
$find_tags = array('[#mod_instance#]',
|
||||
'[#mod_name#]',
|
||||
'[#mod_content#]',
|
||||
'[#date_now#]');
|
||||
|
||||
$replace_values = array($instance['instance'],
|
||||
$instance['title'],
|
||||
$instance['title'],
|
||||
time());
|
||||
|
||||
return str_replace($find_tags, $replace_values, $sheet_mod_label);
|
||||
}
|
||||
}
|
||||
?>
|
||||
Executable
+958
@@ -0,0 +1,958 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
/**
|
||||
* @package moodlecore
|
||||
* @subpackage backup-imscc
|
||||
* @copyright 2009 Mauro Rondinelli (mauro.rondinelli [AT] uvcms.com)
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') or die('Direct access to this script is forbidden.');
|
||||
|
||||
class quiz extends entities {
|
||||
|
||||
private $namespaces = array('xmlns' => 'http://www.imsglobal.org/xsd/ims_qtiasiv1p2');
|
||||
|
||||
public function generate_node_question_categories () {
|
||||
|
||||
$instances = $this->generate_instances();
|
||||
|
||||
$node_course_question_categories = $this->create_node_course_question_categories($instances);
|
||||
$node_course_question_categories = empty($node_course_question_categories) ? '' : $node_course_question_categories;
|
||||
|
||||
return $node_course_question_categories;
|
||||
|
||||
}
|
||||
|
||||
public function generate_node_course_modules_mod () {
|
||||
|
||||
cc2moodle::log_action('Creating Quiz mods');
|
||||
|
||||
$node_course_modules_mod = '';
|
||||
$instances = $this->generate_instances();
|
||||
|
||||
if (!empty($instances)) {
|
||||
foreach ($instances as $instance) {
|
||||
if ($instance['is_question_bank'] == 0) {
|
||||
$node_course_modules_mod .= $this->create_node_course_modules_mod($instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $node_course_modules_mod;
|
||||
|
||||
}
|
||||
|
||||
private function create_node_course_modules_mod_quiz_feedback () {
|
||||
|
||||
$sheet_question_mod_feedback = cc2moodle::loadsheet(SHEET_COURSE_SECTIONS_SECTION_MODS_MOD_QUIZ_FEEDBACK);
|
||||
|
||||
return $sheet_question_mod_feedback;
|
||||
}
|
||||
|
||||
private function generate_instances () {
|
||||
|
||||
$last_instance_id = 0;
|
||||
$last_question_id = 0;
|
||||
$last_answer_id = 0;
|
||||
|
||||
$instances = '';
|
||||
|
||||
$types = array(MOODLE_TYPE_QUIZ, MOODLE_TYPE_QUESTION_BANK);
|
||||
|
||||
foreach ($types as $type) {
|
||||
|
||||
if (!empty(cc2moodle::$instances['instances'][$type])) {
|
||||
|
||||
foreach (cc2moodle::$instances['instances'][$type] as $instance) {
|
||||
|
||||
if ($type == MOODLE_TYPE_QUIZ) {
|
||||
$is_question_bank = 0;
|
||||
} else {
|
||||
$is_question_bank = 1;
|
||||
}
|
||||
|
||||
$assessment_file = $this->get_external_xml($instance['resource_indentifier']);
|
||||
|
||||
if (!empty($assessment_file)) {
|
||||
|
||||
$assessment = $this->load_xml_resource(cc2moodle::$path_to_manifest_folder . DIRECTORY_SEPARATOR . $assessment_file);
|
||||
|
||||
if (!empty($assessment)) {
|
||||
|
||||
$replace_values = array('unlimited' => 0);
|
||||
|
||||
$questions = $this->get_questions($assessment, $last_question_id, $last_answer_id, dirname($assessment_file), $is_question_bank);
|
||||
$question_count = count($questions);
|
||||
|
||||
if ($question_count > 1) {
|
||||
|
||||
$last_instance_id++;
|
||||
|
||||
$instances[$instance['resource_indentifier']]['questions'] = $questions;
|
||||
$instances[$instance['resource_indentifier']]['id'] = $last_instance_id;
|
||||
$instances[$instance['resource_indentifier']]['title'] = $instance['title'];
|
||||
$instances[$instance['resource_indentifier']]['is_question_bank'] = $is_question_bank;
|
||||
$instances[$instance['resource_indentifier']]['options']['timelimit'] = $this->get_global_config($assessment, 'qmd_timelimit', 0);
|
||||
$instances[$instance['resource_indentifier']]['options']['max_attempts'] = $this->get_global_config($assessment, 'cc_maxattempts', 0, $replace_values);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $instances;
|
||||
}
|
||||
|
||||
|
||||
private function create_node_course_modules_mod ($instance) {
|
||||
|
||||
$sheet_question_mod = cc2moodle::loadsheet(SHEET_COURSE_SECTIONS_SECTION_MODS_MOD_QUIZ);
|
||||
|
||||
$node_course_modules_quiz_question_instances = $this->create_node_course_modules_mod_quiz_question_instances($instance);
|
||||
$node_course_modules_quiz_feedback = $this->create_node_course_modules_mod_quiz_feedback($instance);
|
||||
|
||||
$questions_strings = $this->get_questions_string($instance);
|
||||
$quiz_stamp = 'localhost+' . time() . '+' . $this->generate_random_string(6);
|
||||
|
||||
$find_tags = array('[#mod_id#]',
|
||||
'[#mod_name#]',
|
||||
'[#mod_intro#]',
|
||||
'[#mod_stamp#]',
|
||||
'[#question_string#]',
|
||||
'[#date_now#]',
|
||||
'[#mod_max_attempts#]',
|
||||
'[#mod_timelimit#]',
|
||||
'[#node_question_instance#]',
|
||||
'[#node_questions_feedback#]');
|
||||
|
||||
$replace_values = array($instance['id'],
|
||||
$instance['title'],
|
||||
$instance['title'],
|
||||
$quiz_stamp,
|
||||
$questions_strings,
|
||||
time(),
|
||||
$instance['options']['max_attempts'],
|
||||
$instance['options']['timelimit'],
|
||||
$node_course_modules_quiz_question_instances,
|
||||
$node_course_modules_quiz_feedback);
|
||||
|
||||
$node_question_mod = str_replace($find_tags, $replace_values, $sheet_question_mod);
|
||||
|
||||
return $node_question_mod;
|
||||
}
|
||||
|
||||
private function get_global_config ($assessment, $option, $default_value, $replace_values = '') {
|
||||
|
||||
$xpath = cc2moodle::newx_path($assessment, $this->namespaces);
|
||||
$metadata = $xpath->query('/xmlns:questestinterop/xmlns:assessment/xmlns:qtimetadata/xmlns:qtimetadatafield');
|
||||
|
||||
foreach ($metadata as $field) {
|
||||
$field_label = $xpath->query('xmlns:fieldlabel', $field);
|
||||
$field_label = !empty($field_label->item(0)->nodeValue) ? $field_label->item(0)->nodeValue : '';
|
||||
|
||||
if (strtolower($field_label) == strtolower($option)) {
|
||||
$field_entry = $xpath->query('xmlns:fieldentry', $field);
|
||||
$response = !empty($field_entry->item(0)->nodeValue) ? $field_entry->item(0)->nodeValue : '';
|
||||
}
|
||||
}
|
||||
|
||||
$response = !empty($response) ? trim($response) : '';
|
||||
|
||||
if (!empty($replace_values)) {
|
||||
foreach ($replace_values as $key => $value) {
|
||||
$response = ($key == $response) ? $value : $response;
|
||||
}
|
||||
}
|
||||
|
||||
$response = empty($response) ? $default_value : $response;
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
private function create_node_course_modules_mod_quiz_question_instances ($instance) {
|
||||
|
||||
$node_course_module_mod_quiz_questions_instances = '';
|
||||
$sheet_question_mod_instance = cc2moodle::loadsheet(SHEET_COURSE_SECTIONS_SECTION_MODS_MOD_QUIZ_QUESTION_INSTANCE);
|
||||
|
||||
$find_tags = array('[#question_id#]' , '[#instance_id#]');
|
||||
|
||||
if (!empty($instance['questions'])) {
|
||||
|
||||
foreach ($instance['questions'] as $question) {
|
||||
$replace_values = array($question['id'] , $question['id']);
|
||||
$node_course_module_mod_quiz_questions_instances .= str_replace($find_tags, $replace_values, $sheet_question_mod_instance);
|
||||
}
|
||||
|
||||
$node_course_module_mod_quiz_questions_instances = str_replace($find_tags, $replace_values, $node_course_module_mod_quiz_questions_instances);
|
||||
}
|
||||
|
||||
return $node_course_module_mod_quiz_questions_instances;
|
||||
}
|
||||
|
||||
private function get_questions_string ($instance) {
|
||||
|
||||
$questions_string = '';
|
||||
|
||||
if (!empty($instance['questions'])) {
|
||||
foreach ($instance['questions'] as $question) {
|
||||
$questions_string .= $question['id'] . ',';
|
||||
}
|
||||
}
|
||||
|
||||
$questions_string = !empty($questions_string) ? substr($questions_string, 0, strlen($questions_string) - 1) : '';
|
||||
|
||||
return $questions_string;
|
||||
}
|
||||
|
||||
private function create_node_course_question_categories ($instances) {
|
||||
|
||||
$sheet_question_categories = cc2moodle::loadsheet(SHEET_COURSE_QUESTION_CATEGORIES);
|
||||
|
||||
if (!empty($instances)) {
|
||||
|
||||
$node_course_question_categories_question_category = '';
|
||||
|
||||
foreach ($instances as $instance) {
|
||||
$node_course_question_categories_question_category .= $this->create_node_course_question_categories_question_category($instance);
|
||||
}
|
||||
|
||||
$find_tags = array('[#node_course_question_categories_question_category#]');
|
||||
$replace_values = array($node_course_question_categories_question_category);
|
||||
|
||||
$node_course_question_categories = str_replace($find_tags, $replace_values, $sheet_question_categories);
|
||||
}
|
||||
|
||||
$node_course_question_categories = empty($node_course_question_categories) ? '' : $node_course_question_categories;
|
||||
|
||||
return $node_course_question_categories;
|
||||
}
|
||||
|
||||
private function create_node_course_question_categories_question_category ($instance) {
|
||||
|
||||
$sheet_question_categories_quetion_category = cc2moodle::loadsheet(SHEET_COURSE_QUESTION_CATEGORIES_QUESTION_CATEGORY);
|
||||
|
||||
$find_tags = array('[#quiz_id#]',
|
||||
'[#quiz_name#]',
|
||||
'[#quiz_stamp#]',
|
||||
'[#node_course_question_categories_question_category_questions#]');
|
||||
|
||||
$node_course_question_categories_questions = $this->create_node_course_question_categories_question_category_question($instance);
|
||||
$node_course_question_categories_questions = empty($node_course_question_categories_questions) ? '' : $node_course_question_categories_questions;
|
||||
|
||||
$quiz_stamp = 'localhost+' . time() . '+' . $this->generate_random_string(6);
|
||||
|
||||
$replace_values = array($instance['id'],
|
||||
$instance['title'],
|
||||
$quiz_stamp,
|
||||
$node_course_question_categories_questions);
|
||||
|
||||
$node_question_categories = str_replace($find_tags, $replace_values, $sheet_question_categories_quetion_category);
|
||||
|
||||
return $node_question_categories;
|
||||
}
|
||||
|
||||
private function create_node_course_question_categories_question_category_question ($instance) {
|
||||
|
||||
global $USER;
|
||||
|
||||
$node_course_question_categories_question = '';
|
||||
|
||||
$find_tags = array('[#question_id#]',
|
||||
'[#question_title#]',
|
||||
'[#question_text#]',
|
||||
'[#question_type#]',
|
||||
'[#question_general_feedback#]',
|
||||
'[#date_now#]',
|
||||
'[#question_type_nodes#]',
|
||||
'[#question_stamp#]',
|
||||
'[#question_version#]',
|
||||
'[#logged_user#]');
|
||||
|
||||
$sheet_question_categories_question = cc2moodle::loadsheet(SHEET_COURSE_QUESTION_CATEGORIES_QUESTION_CATEGORY_QUESTION);
|
||||
|
||||
$questions = $instance['questions'];
|
||||
|
||||
if (!empty($questions)) {
|
||||
|
||||
foreach ($questions as $question) {
|
||||
|
||||
$quiz_stamp = 'localhost+' . time() . '+' . $this->generate_random_string(6);
|
||||
$quiz_version = 'localhost+' . time() . '+' . $this->generate_random_string(6);
|
||||
|
||||
$question_moodle_type = $question['moodle_type'];
|
||||
$question_cc_type = $question['cc_type'];
|
||||
|
||||
$question_type_node = '';
|
||||
|
||||
$question_type_node = ($question_moodle_type == MOODLE_QUIZ_MULTIPLE_CHOICE) ? $this->create_node_course_question_categories_question_category_question_multiple_choice($question) : $question_type_node;
|
||||
$question_type_node = ($question_moodle_type == MOODLE_QUIZ_TRUE_FALSE) ? $this->create_node_course_question_categories_question_category_question_true_false($question) : $question_type_node;
|
||||
$question_type_node = ($question_moodle_type == MOODLE_QUIZ_ESSAY) ? $this->create_node_course_question_categories_question_category_question_eesay($question) : $question_type_node;
|
||||
$question_type_node = ($question_moodle_type == MOODLE_QUIZ_SHORTANSWER) ? $this->create_node_course_question_categories_question_category_question_shortanswer($question) : $question_type_node;
|
||||
|
||||
$replace_values = array($question['id'],
|
||||
$this->truncate_text($question['title'], 255, true),
|
||||
$question['title'],
|
||||
$question_moodle_type,
|
||||
$question['feedback'],
|
||||
time(),
|
||||
$question_type_node,
|
||||
$quiz_stamp,
|
||||
$quiz_version,
|
||||
$USER->id);
|
||||
|
||||
$node_course_question_categories_question .= str_replace($find_tags, $replace_values, $sheet_question_categories_question);
|
||||
}
|
||||
}
|
||||
|
||||
$node_course_question_categories_question = empty($node_course_question_categories_question) ? '' : $node_course_question_categories_question;
|
||||
|
||||
return $node_course_question_categories_question;
|
||||
}
|
||||
|
||||
private function get_questions ($assessment, &$last_question_id, &$last_answer_id, $root_path, $is_question_bank) {
|
||||
|
||||
$questions = array();
|
||||
|
||||
$xpath = cc2moodle::newx_path($assessment, $this->namespaces);
|
||||
|
||||
if (!$is_question_bank) {
|
||||
$questions_items = $xpath->query('/xmlns:questestinterop/xmlns:assessment/xmlns:section/xmlns:item');
|
||||
} else {
|
||||
$questions_items = $xpath->query('/xmlns:questestinterop/xmlns:objectbank/xmlns:item');
|
||||
}
|
||||
|
||||
foreach ($questions_items as $question_item) {
|
||||
|
||||
$count_questions = $xpath->evaluate('count(xmlns:presentation/xmlns:flow/xmlns:material/xmlns:mattext)', $question_item);
|
||||
|
||||
if ($count_questions == 0) {
|
||||
$question_title = $xpath->query('xmlns:presentation/xmlns:material/xmlns:mattext', $question_item);
|
||||
} else {
|
||||
$question_title = $xpath->query('xmlns:presentation/xmlns:flow/xmlns:material/xmlns:mattext', $question_item);
|
||||
}
|
||||
|
||||
$question_title = !empty($question_title->item(0)->nodeValue) ? $question_title->item(0)->nodeValue : '';
|
||||
|
||||
$question_identifier = $xpath->query('@ident', $question_item);
|
||||
$question_identifier = !empty($question_identifier->item(0)->nodeValue) ? $question_identifier->item(0)->nodeValue : '';
|
||||
|
||||
if (!empty($question_identifier)) {
|
||||
|
||||
$question_type = $this->get_question_type($question_identifier, $assessment);
|
||||
|
||||
if (!empty($question_type['moodle'])) {
|
||||
|
||||
$last_question_id++;
|
||||
|
||||
$questions[$question_identifier]['id'] = $last_question_id;
|
||||
|
||||
$question_title = $this->update_sources($question_title, $root_path);
|
||||
$question_title = !empty($question_title) ? str_replace("%24", "\$", $this->include_titles($question_title)) : '';
|
||||
|
||||
$questions[$question_identifier]['title'] = $question_title;
|
||||
$questions[$question_identifier]['identifier'] = $question_identifier;
|
||||
$questions[$question_identifier]['moodle_type'] = $question_type['moodle'];
|
||||
$questions[$question_identifier]['cc_type'] = $question_type['cc'];
|
||||
$questions[$question_identifier]['feedback'] = $this->get_general_feedback($assessment, $question_identifier);
|
||||
$questions[$question_identifier]['answers'] = $this->get_answers($question_identifier, $assessment, $last_answer_id);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$questions = !empty($questions) ? $questions : '';
|
||||
|
||||
return $questions;
|
||||
}
|
||||
|
||||
private function str_replace_once ($search, $replace, $subject) {
|
||||
|
||||
$first_char = strpos($subject, $search);
|
||||
|
||||
if ($first_char !== false) {
|
||||
|
||||
$before_str = substr($subject, 0, $first_char);
|
||||
$after_str = substr($subject, $first_char + strlen($search));
|
||||
|
||||
return $before_str . $replace . $after_str;
|
||||
|
||||
} else {
|
||||
return $subject;
|
||||
}
|
||||
}
|
||||
|
||||
private function get_general_feedback ($assessment, $question_identifier) {
|
||||
|
||||
$xpath = cc2moodle::newx_path($assessment, $this->namespaces);
|
||||
|
||||
$respconditions = $xpath->query('//xmlns:item[@ident="' . $question_identifier . '"]/xmlns:resprocessing/xmlns:respcondition');
|
||||
|
||||
if (!empty($respconditions)) {
|
||||
|
||||
foreach ($respconditions as $respcondition) {
|
||||
|
||||
$continue = $respcondition->getAttributeNode('continue');
|
||||
$continue = !empty($continue->nodeValue) ? strtolower($continue->nodeValue) : '';
|
||||
|
||||
if ($continue == 'yes') {
|
||||
|
||||
$display_feedback = $xpath->query('xmlns:displayfeedback', $respcondition);
|
||||
|
||||
if (!empty($display_feedback)) {
|
||||
foreach ($display_feedback as $feedback) {
|
||||
|
||||
$feedback_identifier = $feedback->getAttributeNode('linkrefid');
|
||||
$feedback_identifier = !empty($feedback_identifier->nodeValue) ? $feedback_identifier->nodeValue : '';
|
||||
|
||||
if (!empty($feedback_identifier)) {
|
||||
$feedbacks_identifiers[] = $feedback_identifier;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$feedback = '';
|
||||
$feedbacks_identifiers = empty($feedbacks_identifiers) ? '' : $feedbacks_identifiers;
|
||||
|
||||
if (!empty($feedbacks_identifiers)) {
|
||||
foreach ($feedbacks_identifiers as $feedback_identifier) {
|
||||
$feedbacks = $xpath->query('//xmlns:item[@ident="' . $question_identifier . '"]/xmlns:itemfeedback[@ident="' . $feedback_identifier . '"]/xmlns:flow_mat/xmlns:material/xmlns:mattext');
|
||||
$feedback .= !empty($feedbacks->item(0)->nodeValue) ? $feedbacks->item(0)->nodeValue . ' ' : '';
|
||||
}
|
||||
}
|
||||
|
||||
return $feedback;
|
||||
}
|
||||
|
||||
private function get_feedback ($assessment, $identifier, $item_identifier, $question_type) {
|
||||
|
||||
$xpath = cc2moodle::newx_path($assessment, $this->namespaces);
|
||||
|
||||
$resource_processing = $xpath->query('//xmlns:item[@ident="' . $item_identifier . '"]/xmlns:resprocessing/xmlns:respcondition');
|
||||
|
||||
if (!empty($resource_processing)) {
|
||||
|
||||
foreach ($resource_processing as $response) {
|
||||
|
||||
$varequal = $xpath->query('xmlns:conditionvar/xmlns:varequal', $response);
|
||||
$varequal = !empty($varequal->item(0)->nodeValue) ? $varequal->item(0)->nodeValue : '';
|
||||
|
||||
if (strtolower($varequal) == strtolower($identifier) || ($question_type == CC_QUIZ_ESSAY)) {
|
||||
|
||||
$display_feedback = $xpath->query('xmlns:displayfeedback', $response);
|
||||
|
||||
if (!empty($display_feedback)) {
|
||||
foreach ($display_feedback as $feedback) {
|
||||
|
||||
$feedback_identifier = $feedback->getAttributeNode('linkrefid');
|
||||
$feedback_identifier = !empty($feedback_identifier->nodeValue) ? $feedback_identifier->nodeValue : '';
|
||||
|
||||
if (!empty($feedback_identifier)) {
|
||||
$feedbacks_identifiers[] = $feedback_identifier;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$feedback = '';
|
||||
$feedbacks_identifiers = empty($feedbacks_identifiers) ? '' : $feedbacks_identifiers;
|
||||
|
||||
if (!empty($feedbacks_identifiers)) {
|
||||
foreach ($feedbacks_identifiers as $feedback_identifier) {
|
||||
$feedbacks = $xpath->query('//xmlns:item[@ident="' . $item_identifier . '"]/xmlns:itemfeedback[@ident="' . $feedback_identifier . '"]/xmlns:flow_mat/xmlns:material/xmlns:mattext');
|
||||
$feedback .= !empty($feedbacks->item(0)->nodeValue) ? $feedbacks->item(0)->nodeValue . ' ' : '';
|
||||
}
|
||||
}
|
||||
|
||||
return $feedback;
|
||||
}
|
||||
|
||||
private function get_answers_fib ($question_identifier, $identifier, $assessment, &$last_answer_id) {
|
||||
|
||||
$xpath = cc2moodle::newx_path($assessment, $this->namespaces);
|
||||
|
||||
$answers_fib = array();
|
||||
|
||||
$response_items = $xpath->query('//xmlns:item[@ident="' . $question_identifier . '"]/xmlns:resprocessing/xmlns:respcondition');
|
||||
|
||||
foreach ($response_items as $response_item) {
|
||||
|
||||
$setvar = $xpath->query('xmlns:setvar', $response_item);
|
||||
$setvar = is_object($setvar->item(0)) ? $setvar->item(0)->nodeValue : '';
|
||||
|
||||
if ($setvar != '') {
|
||||
|
||||
$last_answer_id++;
|
||||
|
||||
$answer_title = $xpath->query('xmlns:conditionvar/xmlns:varequal[@respident="' . $identifier . '"]', $response_item);
|
||||
$answer_title = !empty($answer_title->item(0)->nodeValue) ? $answer_title->item(0)->nodeValue : '';
|
||||
|
||||
$case = $xpath->query('xmlns:conditionvar/xmlns:varequal/@case', $response_item);
|
||||
$case = is_object($case->item(0)) ? $case->item(0)->nodeValue : 'no'
|
||||
;
|
||||
$case = strtolower($case) == 'yes' ? 1 :
|
||||
0;
|
||||
|
||||
$display_feedback = $xpath->query('xmlns:displayfeedback', $response_item);
|
||||
|
||||
unset($feedbacks_identifiers);
|
||||
|
||||
if (!empty($display_feedback)) {
|
||||
|
||||
foreach ($display_feedback as $feedback) {
|
||||
|
||||
$feedback_identifier = $feedback->getAttributeNode('linkrefid');
|
||||
$feedback_identifier = !empty($feedback_identifier->nodeValue) ? $feedback_identifier->nodeValue : '';
|
||||
|
||||
if (!empty($feedback_identifier)) {
|
||||
$feedbacks_identifiers[] = $feedback_identifier;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$feedback = '';
|
||||
$feedbacks_identifiers = empty($feedbacks_identifiers) ? '' : $feedbacks_identifiers;
|
||||
|
||||
if (!empty($feedbacks_identifiers)) {
|
||||
foreach ($feedbacks_identifiers as $feedback_identifier) {
|
||||
$feedbacks = $xpath->query('//xmlns:item[@ident="' . $question_identifier . '"]/xmlns:itemfeedback[@ident="' . $feedback_identifier . '"]/xmlns:flow_mat/xmlns:material/xmlns:mattext');
|
||||
$feedback .= !empty($feedbacks->item(0)->nodeValue) ? $feedbacks->item(0)->nodeValue . ' ' : '';
|
||||
}
|
||||
}
|
||||
|
||||
$answers_fib[] = array('id' => $last_answer_id,
|
||||
'title' => $answer_title,
|
||||
'score' => $setvar,
|
||||
'feedback' => $feedback,
|
||||
'case' => $case);
|
||||
}
|
||||
}
|
||||
|
||||
$answers_fib = empty($answers_fib) ? '' : $answers_fib;
|
||||
|
||||
return $answers_fib;
|
||||
}
|
||||
|
||||
private function get_answers_pattern_match ($question_identifier, $identifier, $assessment, &$last_answer_id) {
|
||||
|
||||
$xpath = cc2moodle::newx_path($assessment, $this->namespaces);
|
||||
|
||||
$answers_fib = array();
|
||||
|
||||
$response_items = $xpath->query('//xmlns:item[@ident="' . $question_identifier . '"]/xmlns:resprocessing/xmlns:respcondition');
|
||||
|
||||
foreach ($response_items as $response_item) {
|
||||
|
||||
$setvar = $xpath->query('xmlns:setvar', $response_item);
|
||||
$setvar = is_object($setvar->item(0)) ? $setvar->item(0)->nodeValue : '';
|
||||
|
||||
if ($setvar != '') {
|
||||
|
||||
$last_answer_id++;
|
||||
|
||||
$answer_title = $xpath->query('xmlns:conditionvar/xmlns:varequal[@respident="' . $identifier . '"]', $response_item);
|
||||
$answer_title = !empty($answer_title->item(0)->nodeValue) ? $answer_title->item(0)->nodeValue : '';
|
||||
|
||||
if (empty($answer_title)) {
|
||||
$answer_title = $xpath->query('xmlns:conditionvar/xmlns:varsubstring[@respident="' . $identifier . '"]', $response_item);
|
||||
$answer_title = !empty($answer_title->item(0)->nodeValue) ? '*' . $answer_title->item(0)->nodeValue . '*' : '';
|
||||
}
|
||||
|
||||
if (empty($answer_title)) {
|
||||
$answer_title = '*';
|
||||
}
|
||||
|
||||
$case = $xpath->query('xmlns:conditionvar/xmlns:varequal/@case', $response_item);
|
||||
$case = is_object($case->item(0)) ? $case->item(0)->nodeValue : 'no'
|
||||
;
|
||||
$case = strtolower($case) == 'yes' ? 1 :
|
||||
0;
|
||||
|
||||
$display_feedback = $xpath->query('xmlns:displayfeedback', $response_item);
|
||||
|
||||
unset($feedbacks_identifiers);
|
||||
|
||||
if (!empty($display_feedback)) {
|
||||
|
||||
foreach ($display_feedback as $feedback) {
|
||||
|
||||
$feedback_identifier = $feedback->getAttributeNode('linkrefid');
|
||||
$feedback_identifier = !empty($feedback_identifier->nodeValue) ? $feedback_identifier->nodeValue : '';
|
||||
|
||||
if (!empty($feedback_identifier)) {
|
||||
$feedbacks_identifiers[] = $feedback_identifier;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$feedback = '';
|
||||
$feedbacks_identifiers = empty($feedbacks_identifiers) ? '' : $feedbacks_identifiers;
|
||||
|
||||
if (!empty($feedbacks_identifiers)) {
|
||||
foreach ($feedbacks_identifiers as $feedback_identifier) {
|
||||
$feedbacks = $xpath->query('//xmlns:item[@ident="' . $question_identifier . '"]/xmlns:itemfeedback[@ident="' . $feedback_identifier . '"]/xmlns:flow_mat/xmlns:material/xmlns:mattext');
|
||||
$feedback .= !empty($feedbacks->item(0)->nodeValue) ? $feedbacks->item(0)->nodeValue . ' ' : '';
|
||||
}
|
||||
}
|
||||
|
||||
$answers_fib[] = array('id' => $last_answer_id,
|
||||
'title' => $answer_title,
|
||||
'score' => $setvar,
|
||||
'feedback' => $feedback,
|
||||
'case' => $case);
|
||||
}
|
||||
}
|
||||
|
||||
$answers_fib = empty($answers_fib) ? '' : $answers_fib;
|
||||
|
||||
return $answers_fib;
|
||||
}
|
||||
|
||||
|
||||
private function get_answers ($identifier, $assessment, &$last_answer_id) {
|
||||
|
||||
$xpath = cc2moodle::newx_path($assessment, $this->namespaces);
|
||||
|
||||
$answers = array();
|
||||
|
||||
$question_cc_type = $this->get_question_type($identifier, $assessment);
|
||||
$question_cc_type = $question_cc_type['cc'];
|
||||
|
||||
if ($question_cc_type == CC_QUIZ_MULTIPLE_CHOICE || $question_cc_type == CC_QUIZ_MULTIPLE_RESPONSE || $question_cc_type == CC_QUIZ_TRUE_FALSE) {
|
||||
|
||||
$query_answers = '//xmlns:item[@ident="' . $identifier . '"]/xmlns:presentation/xmlns:response_lid/xmlns:render_choice/xmlns:response_label';
|
||||
$query_answers_with_flow = '//xmlns:item[@ident="' . $identifier . '"]/xmlns:presentation/xmlns:flow/xmlns:response_lid/xmlns:render_choice/xmlns:response_label';
|
||||
|
||||
$query_indentifer = '@ident';
|
||||
$query_title = 'xmlns:material/xmlns:mattext';
|
||||
}
|
||||
|
||||
if ($question_cc_type == CC_QUIZ_ESSAY) {
|
||||
|
||||
$query_answers = '//xmlns:item[@ident="' . $identifier . '"]/xmlns:presentation/xmlns:response_str';
|
||||
$query_answers_with_flow = '//xmlns:item[@ident="' . $identifier . '"]/xmlns:presentation/xmlns:flow/xmlns:response_str';
|
||||
|
||||
$query_indentifer = '@ident';
|
||||
$query_title = 'xmlns:render_fib';
|
||||
}
|
||||
|
||||
if ($question_cc_type == CC_QUIZ_FIB || $question_cc_type == CC_QUIZ_PATTERN_MACHT) {
|
||||
|
||||
$xpath_query = '//xmlns:item[@ident="' . $identifier . '"]/xmlns:presentation/xmlns:response_str/@ident';
|
||||
$xpath_query_with_flow = '//xmlns:item[@ident="' . $identifier . '"]/xmlns:presentation/xmlns:flow/xmlns:response_str/@ident';
|
||||
|
||||
$count_response = $xpath->evaluate('count(' . $xpath_query_with_flow . ')');
|
||||
|
||||
if ($count_response == 0) {
|
||||
$answer_identifier = $xpath->query($xpath_query);
|
||||
} else {
|
||||
$answer_identifier = $xpath->query($xpath_query_with_flow);
|
||||
}
|
||||
|
||||
$answer_identifier = !empty($answer_identifier->item(0)->nodeValue) ? $answer_identifier->item(0)->nodeValue : '';
|
||||
|
||||
if ($question_cc_type == CC_QUIZ_FIB) {
|
||||
$answers = $this->get_answers_fib ($identifier, $answer_identifier, $assessment, $last_answer_id);
|
||||
} else {
|
||||
$answers = $this->get_answers_pattern_match ($identifier, $answer_identifier, $assessment, $last_answer_id);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
$count_response = $xpath->evaluate('count(' . $query_answers_with_flow . ')');
|
||||
|
||||
if ($count_response == 0) {
|
||||
$response_items = $xpath->query($query_answers);
|
||||
} else {
|
||||
$response_items = $xpath->query($query_answers_with_flow);
|
||||
}
|
||||
|
||||
if (!empty($response_items)) {
|
||||
|
||||
foreach ($response_items as $response_item) {
|
||||
|
||||
$last_answer_id++;
|
||||
|
||||
$answer_identifier = $xpath->query($query_indentifer, $response_item);
|
||||
$answer_identifier = !empty($answer_identifier->item(0)->nodeValue) ? $answer_identifier->item(0)->nodeValue : '';
|
||||
|
||||
$answer_title = $xpath->query($query_title, $response_item);
|
||||
$answer_title = !empty($answer_title->item(0)->nodeValue) ? $answer_title->item(0)->nodeValue : '';
|
||||
|
||||
$answer_feedback = $this->get_feedback($assessment, $answer_identifier, $identifier, $question_cc_type);
|
||||
|
||||
$answer_score = $this->get_score($assessment, $answer_identifier, $identifier);
|
||||
|
||||
$answers[] = array('id' => $last_answer_id,
|
||||
'title' => $answer_title,
|
||||
'score' => $answer_score,
|
||||
'identifier' => $answer_identifier,
|
||||
'feedback' => $answer_feedback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$answers = empty($answers) ? '' : $answers;
|
||||
|
||||
return $answers;
|
||||
|
||||
}
|
||||
|
||||
private function get_score ($assessment, $identifier, $question_identifier) {
|
||||
|
||||
$xpath = cc2moodle::newx_path($assessment, $this->namespaces);
|
||||
|
||||
$resource_processing = $xpath->query('//xmlns:item[@ident="' . $question_identifier . '"]/xmlns:resprocessing/xmlns:respcondition');
|
||||
|
||||
if (!empty($resource_processing)) {
|
||||
|
||||
foreach ($resource_processing as $response) {
|
||||
|
||||
$question_cc_type = $this->get_question_type($question_identifier, $assessment);
|
||||
$question_cc_type = $question_cc_type['cc'];
|
||||
|
||||
$varequal = $xpath->query('xmlns:conditionvar/xmlns:varequal', $response);
|
||||
$varequal = !empty($varequal->item(0)->nodeValue) ? $varequal->item(0)->nodeValue : '';
|
||||
|
||||
if (strtolower($varequal) == strtolower($identifier)) {
|
||||
$score = $xpath->query('xmlns:setvar', $response);
|
||||
$score = !empty($score->item(0)->nodeValue) ? $score->item(0)->nodeValue : '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$score = empty($score) ? 0 : $score;
|
||||
|
||||
return $score;
|
||||
}
|
||||
|
||||
private function create_node_course_question_categories_question_category_question_multiple_choice ($question) {
|
||||
|
||||
$node_course_question_categories_question_answer = '';
|
||||
$sheet_question_categories_question = cc2moodle::loadsheet(SHEET_COURSE_QUESTION_CATEGORIES_QUESTION_CATEGORY_QUESTION_MULTIPLE_CHOICE);
|
||||
|
||||
if (!empty($question['answers'])) {
|
||||
foreach ($question['answers'] as $answer) {
|
||||
$node_course_question_categories_question_answer .= $this->create_node_course_question_categories_question_category_question_answer($answer);
|
||||
}
|
||||
}
|
||||
|
||||
$answer_string = $this->get_answers_string($question['answers']);
|
||||
|
||||
$is_single = ($question['cc_type'] == CC_QUIZ_MULTIPLE_CHOICE) ? 1 : 0;
|
||||
|
||||
$find_tags = array('[#node_course_question_categories_question_category_question_answer#]',
|
||||
'[#answer_string#]',
|
||||
'[#is_single#]');
|
||||
|
||||
$replace_values = array($node_course_question_categories_question_answer,
|
||||
$answer_string,
|
||||
$is_single);
|
||||
|
||||
$node_question_categories_question = str_replace($find_tags, $replace_values, $sheet_question_categories_question);
|
||||
|
||||
return $node_question_categories_question;
|
||||
}
|
||||
|
||||
private function create_node_course_question_categories_question_category_question_eesay ($question) {
|
||||
|
||||
$node_course_question_categories_question_answer = '';
|
||||
|
||||
$sheet_question_categories_question = cc2moodle::loadsheet(SHEET_COURSE_QUESTION_CATEGORIES_QUESTION_CATEGORY_QUESTION_EESAY);
|
||||
|
||||
if (!empty($question['answers'])) {
|
||||
foreach ($question['answers'] as $answer) {
|
||||
$node_course_question_categories_question_answer .= $this->create_node_course_question_categories_question_category_question_answer($answer);
|
||||
}
|
||||
}
|
||||
|
||||
$find_tags = array('[#node_course_question_categories_question_category_question_answer#]');
|
||||
$replace_values = array($node_course_question_categories_question_answer);
|
||||
|
||||
$node_question_categories_question = str_replace($find_tags, $replace_values, $sheet_question_categories_question);
|
||||
|
||||
return $node_question_categories_question;
|
||||
}
|
||||
|
||||
private function create_node_course_question_categories_question_category_question_shortanswer ($question) { //, &$fib_questions) {
|
||||
|
||||
$sheet_question_categories_question = cc2moodle::loadsheet(SHEET_COURSE_QUESTION_CATEGORIES_QUESTION_CATEGORY_QUESTION_SHORTANSWER);
|
||||
$node_course_question_categories_question_answer = '';
|
||||
|
||||
if (!empty($question['answers'])) {
|
||||
foreach ($question['answers'] as $answer) {
|
||||
$node_course_question_categories_question_answer .= $this->create_node_course_question_categories_question_category_question_answer($answer);
|
||||
}
|
||||
}
|
||||
|
||||
$answers_string = $this->get_answers_string($question['answers']);
|
||||
|
||||
$use_case = 0;
|
||||
|
||||
foreach ($question['answers'] as $answer) {
|
||||
|
||||
if ($answer['case'] == 1) {
|
||||
$use_case = 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$find_tags = array('[#answers_string#]',
|
||||
'[#use_case#]',
|
||||
'[#node_course_question_categories_question_category_question_answer#]');
|
||||
|
||||
$replace_values = array($answers_string,
|
||||
$use_case,
|
||||
$node_course_question_categories_question_answer);
|
||||
|
||||
|
||||
|
||||
$node_question_categories_question = str_replace($find_tags, $replace_values, $sheet_question_categories_question);
|
||||
|
||||
return $node_question_categories_question;
|
||||
|
||||
}
|
||||
|
||||
private function create_node_course_question_categories_question_category_question_true_false ($question) {
|
||||
|
||||
$node_course_question_categories_question_answer = '';
|
||||
|
||||
$sheet_question_categories_question = cc2moodle::loadsheet(SHEET_COURSE_QUESTION_CATEGORIES_QUESTION_CATEGORY_QUESTION_TRUE_FALSE);
|
||||
|
||||
$max_score = 0;
|
||||
$true_answer_id = 0;
|
||||
$false_answer_id = 0;
|
||||
|
||||
if (!empty($question['answers'])) {
|
||||
|
||||
foreach ($question['answers'] as $answer) {
|
||||
if ($answer['score'] > $max_score) {
|
||||
$max_score = $answer['score'];
|
||||
$true_answer_id = $answer['id'];
|
||||
}
|
||||
|
||||
$node_course_question_categories_question_answer .= $this->create_node_course_question_categories_question_category_question_answer($answer);
|
||||
}
|
||||
|
||||
foreach ($question['answers'] as $answer) {
|
||||
|
||||
if ($answer['id'] != $true_answer_id) {
|
||||
$max_score = $answer['score'];
|
||||
$false_answer_id = $answer['id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$find_tags = array('[#node_course_question_categories_question_category_question_answer#]',
|
||||
'[#true_answer_id#]',
|
||||
'[#false_answer_id#]');
|
||||
|
||||
$replace_values = array($node_course_question_categories_question_answer,
|
||||
$true_answer_id,
|
||||
$false_answer_id);
|
||||
|
||||
$node_question_categories_question = str_replace($find_tags, $replace_values, $sheet_question_categories_question);
|
||||
|
||||
return $node_question_categories_question;
|
||||
}
|
||||
|
||||
private function get_answers_string ($answers) {
|
||||
|
||||
$answer_string = '';
|
||||
|
||||
if (!empty($answers)) {
|
||||
foreach ($answers as $answer) {
|
||||
$answer_string .= $answer['id'] . ',';
|
||||
}
|
||||
}
|
||||
|
||||
$answer_string = !empty($answer_string) ? substr($answer_string, 0, strlen($answer_string) - 1) : '';
|
||||
|
||||
return $answer_string;
|
||||
|
||||
}
|
||||
|
||||
private function create_node_course_question_categories_question_category_question_answer ($answer) {
|
||||
|
||||
$sheet_question_categories_question_answer = cc2moodle::loadsheet(SHEET_COURSE_QUESTION_CATEGORIES_QUESTION_CATEGORY_QUESTION_ANSWER);
|
||||
|
||||
$find_tags = array('[#answer_id#]',
|
||||
'[#answer_text#]',
|
||||
'[#answer_score#]',
|
||||
'[#answer_feedback#]');
|
||||
|
||||
$replace_values = array($answer['id'],
|
||||
$answer['title'],
|
||||
$answer['score'],
|
||||
$answer['feedback']);
|
||||
|
||||
$node_question_categories_question_answer = str_replace($find_tags, $replace_values, $sheet_question_categories_question_answer);
|
||||
|
||||
return $node_question_categories_question_answer;
|
||||
}
|
||||
|
||||
private function get_question_type ($identifier, $assessment) {
|
||||
|
||||
$xpath = cc2moodle::newx_path($assessment, $this->namespaces);
|
||||
|
||||
$metadata = $xpath->query('//xmlns:item[@ident="' . $identifier . '"]/xmlns:itemmetadata/xmlns:qtimetadata/xmlns:qtimetadatafield');
|
||||
|
||||
foreach ($metadata as $field) {
|
||||
|
||||
$field_label = $xpath->query('xmlns:fieldlabel', $field);
|
||||
$field_label = !empty($field_label->item(0)->nodeValue) ? $field_label->item(0)->nodeValue : '';
|
||||
|
||||
if ($field_label == 'cc_profile') {
|
||||
$field_entry = $xpath->query('xmlns:fieldentry', $field);
|
||||
$type = !empty($field_entry->item(0)->nodeValue) ? $field_entry->item(0)->nodeValue : '';
|
||||
}
|
||||
}
|
||||
|
||||
$return_type = array();
|
||||
|
||||
$return_type['moodle'] = '';
|
||||
$return_type['cc'] = $type;
|
||||
|
||||
if ($type == CC_QUIZ_MULTIPLE_CHOICE) {
|
||||
$return_type['moodle'] = MOODLE_QUIZ_MULTIPLE_CHOICE;
|
||||
}
|
||||
if ($type == CC_QUIZ_MULTIPLE_RESPONSE) {
|
||||
$return_type['moodle'] = MOODLE_QUIZ_MULTIPLE_CHOICE;
|
||||
}
|
||||
if ($type == CC_QUIZ_TRUE_FALSE) {
|
||||
$return_type['moodle'] = MOODLE_QUIZ_TRUE_FALSE;
|
||||
}
|
||||
if ($type == CC_QUIZ_ESSAY) {
|
||||
$return_type['moodle'] = MOODLE_QUIZ_ESSAY;
|
||||
}
|
||||
if ($type == CC_QUIZ_FIB) {
|
||||
$return_type['moodle'] = MOODLE_QUIZ_SHORTANSWER;
|
||||
}
|
||||
if ($type == CC_QUIZ_PATTERN_MACHT) {
|
||||
$return_type['moodle'] = MOODLE_QUIZ_SHORTANSWER;
|
||||
}
|
||||
|
||||
return $return_type;
|
||||
|
||||
}
|
||||
}
|
||||
?>
|
||||
Executable
+104
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
/**
|
||||
* @package moodlecore
|
||||
* @subpackage backup-imscc
|
||||
* @copyright 2009 Mauro Rondinelli (mauro.rondinelli [AT] uvcms.com)
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') or die('Direct access to this script is forbidden.');
|
||||
|
||||
class resource extends entities {
|
||||
|
||||
private $namespaces = array('wl' => 'http://www.imsglobal.org/xsd/imswl_v1p0');
|
||||
|
||||
public function generate_node () {
|
||||
|
||||
cc2moodle::log_action('Creating Resource mods');
|
||||
|
||||
$response = '';
|
||||
$sheet_mod_resource = cc2moodle::loadsheet(SHEET_COURSE_SECTIONS_SECTION_MODS_MOD_RESOURCE);
|
||||
|
||||
if (!empty(cc2moodle::$instances['instances'][MOODLE_TYPE_RESOURCE])) {
|
||||
foreach (cc2moodle::$instances['instances'][MOODLE_TYPE_RESOURCE] as $instance) {
|
||||
$response .= $this->create_node_course_modules_mod_resource($sheet_mod_resource, $instance);
|
||||
}
|
||||
}
|
||||
|
||||
return $response;
|
||||
|
||||
}
|
||||
|
||||
private function create_node_course_modules_mod_resource ($sheet_mod_resource, $instance) {
|
||||
|
||||
$link = '';
|
||||
$xpath = cc2moodle::newx_path(CC2Moodle::$manifest, CC2Moodle::$namespaces);
|
||||
|
||||
if ($instance['common_cartriedge_type'] == CC_TYPE_WEBCONTENT || $instance['common_cartriedge_type'] == CC_TYPE_ASSOCIATED_CONTENT) {
|
||||
$resource = $xpath->query('/imscc:manifest/imscc:resources/imscc:resource[@identifier="' . $instance['resource_indentifier'] . '"]/@href');
|
||||
$resource = !empty($resource->item(0)->nodeValue) ? $resource->item(0)->nodeValue : '';
|
||||
|
||||
if (empty($resource)) {
|
||||
|
||||
unset($resource);
|
||||
|
||||
$resource = $xpath->query('/imscc:manifest/imscc:resources/imscc:resource[@identifier="' . $instance['resource_indentifier'] . '"]/imscc:file/@href');
|
||||
$resource = !empty($resource->item(0)->nodeValue) ? $resource->item(0)->nodeValue : '';
|
||||
|
||||
}
|
||||
|
||||
if (!empty($resource)) {
|
||||
$link = $resource;
|
||||
}
|
||||
}
|
||||
|
||||
if ($instance['common_cartriedge_type'] == CC_TYPE_WEBLINK) {
|
||||
|
||||
$external_resource = $xpath->query('/imscc:manifest/imscc:resources/imscc:resource[@identifier="' . $instance['resource_indentifier'] . '"]/imscc:file/@href')->item(0)->nodeValue;
|
||||
|
||||
if ($external_resource) {
|
||||
|
||||
$resource = $this->load_xml_resource(cc2moodle::$path_to_manifest_folder . DIRECTORY_SEPARATOR . $external_resource);
|
||||
|
||||
if (!empty($resource)) {
|
||||
$xpath = cc2moodle::newx_path($resource, $this->namespaces);
|
||||
$resource = $xpath->query('/wl:webLink/url/@href');
|
||||
$link = $resource->item(0)->nodeValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$find_tags = array('[#mod_instance#]',
|
||||
'[#mod_name#]',
|
||||
'[#mod_type#]',
|
||||
'[#mod_reference#]',
|
||||
'[#mod_summary#]',
|
||||
'[#mod_alltext#]',
|
||||
'[#date_now#]');
|
||||
|
||||
$replace_values = array($instance['instance'],
|
||||
$instance['title'],
|
||||
'file',
|
||||
$link,
|
||||
'',
|
||||
'',
|
||||
time());
|
||||
|
||||
return str_replace($find_tags, $replace_values, $sheet_mod_resource);
|
||||
}
|
||||
}
|
||||
?>
|
||||
Executable
+96
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
/**
|
||||
* @package moodlecore
|
||||
* @subpackage backup-imscc
|
||||
* @copyright 2009 Mauro Rondinelli (mauro.rondinelli [AT] uvcms.com)
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') or die('Direct access to this script is forbidden.');
|
||||
|
||||
// GENERAL PARAMETERS ************************************************************************************************* //
|
||||
define('ROOT_DEEP', 2);
|
||||
|
||||
// PACKAGES FORMATS *************************************************************************************************** //
|
||||
define('FORMAT_UNKNOWN', 'NA');
|
||||
define('FORMAT_COMMON_CARTRIDGE', 'CC');
|
||||
define('FORMAT_BLACK_BOARD', 'BB');
|
||||
|
||||
// FORMATS NAMESPACES ************************************************************************************************* //
|
||||
define('NS_COMMON_CARTRIDGE', 'http://www.imsglobal.org/xsd/imscc/imscp_v1p1');
|
||||
define('NS_BLACK_BOARD', 'http://www.blackboard.com/content-packaging');
|
||||
|
||||
// SHEET FILES ******************************************************************************************************** //
|
||||
define('SHEET_BASE', 'cc/sheets/base.xml');
|
||||
define('SHEET_INFO_DETAILS_MOD', 'cc/sheets/info_details_mod.xml');
|
||||
define('SHEET_INFO_DETAILS_MOD_INSTANCE', 'cc/sheets/info_details_mod_instance.xml');
|
||||
define('SHEET_COURSE_BLOCKS_BLOCK', 'cc/sheets/course_blocks_block.xml');
|
||||
define('SHEET_COURSE_HEADER', 'cc/sheets/course_header.xml');
|
||||
define('SHEET_COURSE_SECTIONS_SECTION', 'cc/sheets/course_sections_section.xml');
|
||||
define('SHEET_COURSE_SECTIONS_SECTION_MODS_MOD', 'cc/sheets/course_sections_section_mods_mod.xml');
|
||||
define('SHEET_COURSE_SECTIONS_SECTION_MODS_MOD_FORUM', 'cc/sheets/course_modules_mod_forum.xml');
|
||||
define('SHEET_COURSE_SECTIONS_SECTION_MODS_MOD_LABEL', 'cc/sheets/course_modules_mod_label.xml');
|
||||
define('SHEET_COURSE_SECTIONS_SECTION_MODS_MOD_RESOURCE', 'cc/sheets/course_modules_mod_resource.xml');
|
||||
define('SHEET_COURSE_SECTIONS_SECTION_MODS_MOD_QUIZ', 'cc/sheets/course_modules_mod_quiz.xml');
|
||||
define('SHEET_COURSE_SECTIONS_SECTION_MODS_MOD_QUIZ_QUESTION_INSTANCE', 'cc/sheets/course_modules_mod_quiz_question_instance.xml');
|
||||
define('SHEET_COURSE_SECTIONS_SECTION_MODS_MOD_QUIZ_FEEDBACK', 'cc/sheets/course_modules_mod_quiz_feedback.xml');
|
||||
define('SHEET_COURSE_QUESTION_CATEGORIES', 'cc/sheets/course_question_categories.xml');
|
||||
define('SHEET_COURSE_QUESTION_CATEGORIES_QUESTION_CATEGORY', 'cc/sheets/course_question_categories_question_category.xml');
|
||||
define('SHEET_COURSE_QUESTION_CATEGORIES_QUESTION_CATEGORY_QUESTION', 'cc/sheets/course_question_categories_question_category_question.xml');
|
||||
define('SHEET_COURSE_QUESTION_CATEGORIES_QUESTION_CATEGORY_QUESTION_MULTIPLE_CHOICE', 'cc/sheets/course_question_categories_question_category_question_multiple_choice.xml');
|
||||
define('SHEET_COURSE_QUESTION_CATEGORIES_QUESTION_CATEGORY_QUESTION_TRUE_FALSE', 'cc/sheets/course_question_categories_question_category_question_true_false.xml');
|
||||
define('SHEET_COURSE_QUESTION_CATEGORIES_QUESTION_CATEGORY_QUESTION_EESAY', 'cc/sheets/course_question_categories_question_category_question_eesay.xml');
|
||||
define('SHEET_COURSE_QUESTION_CATEGORIES_QUESTION_CATEGORY_QUESTION_SHORTANSWER', 'cc/sheets/course_question_categories_question_category_question_shortanswer.xml');
|
||||
define('SHEET_COURSE_QUESTION_CATEGORIES_QUESTION_CATEGORY_QUESTION_ANSWER', 'cc/sheets/course_question_categories_question_category_question_answer.xml');
|
||||
|
||||
// CC RESOURCES TYPE ************************************************************************************************** //
|
||||
define('CC_TYPE_FORUM', 'imsdt_xmlv1p0');
|
||||
define('CC_TYPE_QUIZ', 'imsqti_xmlv1p2/imscc_xmlv1p0/assessment');
|
||||
define('CC_TYPE_QUESTION_BANK', 'imsqti_xmlv1p2/imscc_xmlv1p0/question-bank');
|
||||
define('CC_TYPE_WEBLINK', 'imswl_xmlv1p0');
|
||||
define('CC_TYPE_WEBCONTENT', 'webcontent');
|
||||
define('CC_TYPE_ASSOCIATED_CONTENT', 'associatedcontent/imscc_xmlv1p0/learning-application-resource');
|
||||
define('CC_TYPE_EMPTY', '');
|
||||
|
||||
// MOODLE RESOURCES TYPE ********************************************************************************************** //
|
||||
define('MOODLE_TYPE_FORUM', 'forum');
|
||||
define('MOODLE_TYPE_QUIZ', 'quiz');
|
||||
define('MOODLE_TYPE_QUESTION_BANK', 'question_bank');
|
||||
define('MOODLE_TYPE_RESOURCE', 'resource');
|
||||
define('MOODLE_TYPE_LABEL', 'label');
|
||||
|
||||
// UNKNOWN TYPE ******************************************************************************************************* //
|
||||
define('TYPE_UNKNOWN', '[UNKNOWN]');
|
||||
|
||||
// CC QUESTIONS TYPES ************************************************************************************************* //
|
||||
define('CC_QUIZ_MULTIPLE_CHOICE', 'cc.multiple_choice.v0p1');
|
||||
define('CC_QUIZ_TRUE_FALSE', 'cc.true_false.v0p1');
|
||||
define('CC_QUIZ_FIB', 'cc.fib.v0p1');
|
||||
define('CC_QUIZ_MULTIPLE_RESPONSE', 'cc.multiple_response.v0p1');
|
||||
define('CC_QUIZ_PATTERN_MACHT', 'cc.pattern_match.v0p1');
|
||||
define('CC_QUIZ_ESSAY', 'cc.essay.v0p1');
|
||||
|
||||
//MOODLE QUESTIONS TYPES ********************************************************************************************** //
|
||||
define('MOODLE_QUIZ_MULTIPLE_CHOICE', 'multichoice');
|
||||
define('MOODLE_QUIZ_TRUE_FALSE', 'truefalse');
|
||||
define('MOODLE_QUIZ_MULTIANSWER', 'multianswer');
|
||||
define('MOODLE_QUIZ_MULTIPLE_RESPONSE', 'multichoice');
|
||||
define('MOODLE_QUIZ_MACHT', 'match');
|
||||
define('MOODLE_QUIZ_ESSAY', 'essay');
|
||||
define('MOODLE_QUIZ_SHORTANSWER', 'shortanswer');
|
||||
|
||||
?>
|
||||
Executable
+142
@@ -0,0 +1,142 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
/**
|
||||
* @package moodlecore
|
||||
* @subpackage backup-imscc
|
||||
* @copyright 2009 Mauro Rondinelli (mauro.rondinelli [AT] uvcms.com)
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
defined('MOODLE_INTERNAL') or die('Direct access to this script is forbidden.');
|
||||
|
||||
require_once($CFG->dirroot . '/backup/cc/includes/constants.php');
|
||||
require_once($CFG->dirroot . '/backup/cc/cc2moodle.php');
|
||||
|
||||
function cc_convert ($dir) {
|
||||
|
||||
$manifest_file = $dir . DIRECTORY_SEPARATOR . 'imsmanifest.xml';
|
||||
$moodle_file = $dir . DIRECTORY_SEPARATOR . 'moodle.xml';
|
||||
$schema_file = 'cc' . DIRECTORY_SEPARATOR . '' . DIRECTORY_SEPARATOR . 'schemas' . DIRECTORY_SEPARATOR . 'cclibxml2validator.xsd';
|
||||
|
||||
if (is_readable($manifest_file) && !is_readable($moodle_file)) {
|
||||
|
||||
$is_cc = detect_cc_format($manifest_file);
|
||||
|
||||
if ($is_cc) {
|
||||
|
||||
$detected_requirements = detect_requirements();
|
||||
|
||||
if (!$detected_requirements["php5"]) {
|
||||
notify(get_string('cc_import_req_php5', 'imscc'));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$detected_requirements["dom"]) {
|
||||
notify(get_string('cc_import_req_dom', 'imscc'));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$detected_requirements["libxml"]) {
|
||||
notify(get_string('cc_import_req_libxml', 'imscc'));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$detected_requirements["libxmlminversion"]) {
|
||||
notify(get_string('cc_import_req_libxmlminversion', 'imscc'));
|
||||
return false;
|
||||
}
|
||||
if (!$detected_requirements["xsl"]) {
|
||||
notify(get_string('cc_import_req_xsl', 'imscc'));
|
||||
return false;
|
||||
}
|
||||
|
||||
echo get_string('cc2moodle_checking_schema', 'imscc') . '<br />';
|
||||
|
||||
$cc_manifest = new DOMDocument();
|
||||
|
||||
if ($cc_manifest->load($manifest_file)) {
|
||||
if ($cc_manifest->schemaValidate($schema_file)) {
|
||||
|
||||
echo get_string('cc2moodle_valid_schema', 'imscc') . '<br />';
|
||||
|
||||
$cc2moodle = new cc2moodle($manifest_file);
|
||||
|
||||
if (!$cc2moodle->is_auth()) {
|
||||
return $cc2moodle->generate_moodle_xml();
|
||||
} else {
|
||||
notify(get_string('cc2moodle_req_auth', 'imscc'));
|
||||
return false;
|
||||
}
|
||||
|
||||
} else {
|
||||
notify(get_string('cc2moodle_invalid_schema', 'imscc'));
|
||||
return false;
|
||||
}
|
||||
|
||||
} else {
|
||||
notify(get_string('cc2moodle_manifest_dont_load', 'imscc'));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function detect_requirements () {
|
||||
|
||||
if (floor(phpversion()) >= 5) {
|
||||
$detected["php5"] = true;
|
||||
} else {
|
||||
$detected["php5"] = false;
|
||||
}
|
||||
|
||||
$detected["xsl"] = extension_loaded('xsl');
|
||||
$detected['dom'] = extension_loaded('dom');
|
||||
$detected['libxml'] = extension_loaded('libxml');
|
||||
$detected['libxmlminversion'] = extension_loaded('libxml') && version_compare(LIBXML_DOTTED_VERSION, '2.6.30', '>=');
|
||||
|
||||
return $detected;
|
||||
|
||||
}
|
||||
|
||||
function detect_cc_format ($xml_file) {
|
||||
|
||||
$inpos = 0;
|
||||
$xml_snippet = file_get_contents($xml_file, 0, NULL, 0, 500);
|
||||
|
||||
if (!empty($xml_snippet)) {
|
||||
|
||||
$xml_snippet = strtolower($xml_snippet);
|
||||
$xml_snippet = preg_replace('/\s*/m', '', $xml_snippet);
|
||||
$xml_snippet = str_replace("'", '', $xml_snippet);
|
||||
$xml_snippet = str_replace('"', '', $xml_snippet);
|
||||
|
||||
$search_string = "xmlns=" . NS_COMMON_CARTRIDGE;
|
||||
|
||||
$inpos = strpos($xml_snippet, $search_string);
|
||||
|
||||
if ($inpos) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
Executable
+19
@@ -0,0 +1,19 @@
|
||||
<?xml version = "1.0" encoding = "UTF-8"?>
|
||||
<xs:schema xmlns ="http://dummy.libxml2.validator"
|
||||
targetNamespace ="http://dummy.libxml2.validator"
|
||||
xmlns:xs ="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:imscp ="http://www.imsglobal.org/xsd/imscc/imscp_v1p1"
|
||||
xmlns:imslom ="http://ltsc.ieee.org/xsd/imscc/LOM"
|
||||
xmlns:lom ="http://ltsc.ieee.org/xsd/LOM"
|
||||
xmlns:cc ="http://www.imsglobal.org/xsd/imsccauth_v1p0"
|
||||
version="1.0"
|
||||
elementFormDefault ="qualified"
|
||||
attributeFormDefault="unqualified"
|
||||
>
|
||||
|
||||
<xs:import namespace ="http://www.imsglobal.org/xsd/imscc/imscp_v1p1" schemaLocation = "imscp_v1p2_localised.xsd" />
|
||||
<xs:import namespace ="http://ltsc.ieee.org/xsd/imscc/LOM" schemaLocation = "domainProfile_1/lomLoose_localised.xsd" />
|
||||
<xs:import namespace ="http://ltsc.ieee.org/xsd/LOM" schemaLocation = "domainProfile_2/lomLoose_localised.xsd" />
|
||||
<xs:import namespace ="http://www.imsglobal.org/xsd/imsccauth_v1p0" schemaLocation = "domainProfile_0/imsccauth_v1p0_localised.xsd" />
|
||||
</xs:schema>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user