Compare commits
912 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d97b3d4c81 | |||
| 3d9c67b089 | |||
| 845f0cf71e | |||
| f808005051 | |||
| ca0c65427d | |||
| 20460bd637 | |||
| 33647345e4 | |||
| 5ef6ac5a35 | |||
| d0b09c8d76 | |||
| 2efd5adc61 | |||
| c12a862c95 | |||
| 69a3c19fcb | |||
| 834b9a8e18 | |||
| 4a029f6843 | |||
| 7d8050dd38 | |||
| 3c9d2b1040 | |||
| f1a4d829e3 | |||
| 01408d619b | |||
| e4e7a097f6 | |||
| 510efb7455 | |||
| 3a5cfc1f59 | |||
| 4fc53e7a24 | |||
| d869267c7a | |||
| 31d15bc64e | |||
| 0297d3e3ac | |||
| f38e287c16 | |||
| bbeab900d6 | |||
| c92c1e2b4a | |||
| 4cb7ae6fa2 | |||
| 7d0b6bea51 | |||
| a5df2ffa52 | |||
| 77552e5f5b | |||
| 57411a05d8 | |||
| bc1d0d15da | |||
| 8dc2647f0f | |||
| 222bb751c9 | |||
| 0a274ff84e | |||
| bc22230af9 | |||
| 05b5af2721 | |||
| 62c8fe2d9c | |||
| 8ffc5f3410 | |||
| c48a174fc4 | |||
| cd25907728 | |||
| 372b792a25 | |||
| a1be99096e | |||
| 968b596138 | |||
| 1bd5e7f579 | |||
| cd20424b89 | |||
| 8c46d78dba | |||
| 92730c8eb9 | |||
| cda239e63e | |||
| a476c985a8 | |||
| 2e01123bf4 | |||
| 388a23e9d3 | |||
| a6f8c022f6 | |||
| 063ae6b180 | |||
| d933ddac17 | |||
| 29f88b5783 | |||
| 1e09fe76f2 | |||
| 6dec102c62 | |||
| 44df7437f9 | |||
| f7423fa240 | |||
| 76c684dc65 | |||
| 16067645b4 | |||
| ac01be5ffe | |||
| e56209d815 | |||
| e37906c31e | |||
| 25f201c259 | |||
| 3fecbbe510 | |||
| e28a53bcb0 | |||
| 70d6b77c14 | |||
| 58f4420d0f | |||
| c287b85806 | |||
| 82c38e0c45 | |||
| 5d1b9e7b00 | |||
| 9047653ffe | |||
| 5401e6b923 | |||
| 484a08cc15 | |||
| a57c6830ea | |||
| 1491aca61d | |||
| 0fd01700f4 | |||
| 6e7aa92bc6 | |||
| dacb0f0a94 | |||
| fd95e9c70d | |||
| bec5339281 | |||
| 354fd0dba7 | |||
| a4001824d9 | |||
| 6abc42a404 | |||
| 9f1b6babf0 | |||
| 306561a926 | |||
| e9024a1443 | |||
| 2d4f5d18d0 | |||
| e0b61ea590 | |||
| d830d4601d | |||
| 328b4a73fb | |||
| 3fc6d79de2 | |||
| c14bbcf890 | |||
| b67fda1e31 | |||
| 4b1de0b64b | |||
| b421c1cd70 | |||
| 7f438e833e | |||
| c9db0e876b | |||
| 6639edc34f | |||
| 56342d4eb1 | |||
| b512fdd040 | |||
| 12f8cb4e56 | |||
| 35b5a7fcd9 | |||
| 56f496f26d | |||
| 0169a60751 | |||
| 6238007754 | |||
| c9a1658c50 | |||
| 6c0ec8dd4c | |||
| 5bd06806e2 | |||
| 80b5eb78dd | |||
| bfea54fdb6 | |||
| 50f5630dd6 | |||
| 2eac5e6aa0 | |||
| c98e007a88 | |||
| f0df8853df | |||
| 7d82cbc6bb | |||
| dc08c1fd79 | |||
| 42462c057a | |||
| 586869780f | |||
| d5344f23e4 | |||
| ee73ad1ef6 | |||
| c86fca01c7 | |||
| ce0bb6e843 | |||
| 2311226b42 | |||
| d854b87af0 | |||
| 1ae503de34 | |||
| 23a605d65c | |||
| e0a473a0b4 | |||
| 5937ca9c69 | |||
| 5d1cc5707e | |||
| deb17cad7b | |||
| 114f5f134b | |||
| 6bb1094932 | |||
| f7e66c022e | |||
| dfb103a7c1 | |||
| f80a695b4c | |||
| 63a1a289e9 | |||
| 5052caed58 | |||
| 144720047a | |||
| 8dc237213b | |||
| eddae29cdf | |||
| cc58798dc3 | |||
| 4ed2d20325 | |||
| bbe790a42e | |||
| ff6c283651 | |||
| 3789c23fd1 | |||
| f609364544 | |||
| ad23f18a40 | |||
| 6e3bce00b8 | |||
| 4bc5ddb074 | |||
| d94f588b67 | |||
| dc844c1eae | |||
| 2f416e9f87 | |||
| 19e286bbe4 | |||
| 93afe952d9 | |||
| 92b0b88db1 | |||
| 0a02b7cb02 | |||
| 5948df3878 | |||
| 634d36641e | |||
| 07111d3af6 | |||
| 651ad2d035 | |||
| dcf9108490 | |||
| f256bf9169 | |||
| e068c3f054 | |||
| 71869bc4d3 | |||
| 8df8ca11a2 | |||
| f67e31c195 | |||
| 53d2f810ea | |||
| a784fee34c | |||
| a30a81e3a0 | |||
| 49dbcbd998 | |||
| 35c61094e8 | |||
| c0eeb8c461 | |||
| 4840ec1193 | |||
| 4565c9b575 | |||
| b9114ec746 | |||
| f01974e9d7 | |||
| 0a15d762b8 | |||
| 37b3541eab | |||
| 28e7877645 | |||
| 01bacdae55 | |||
| 02c3b88fcd | |||
| f186db050c | |||
| f825607286 | |||
| 800d62c56d | |||
| 546aae396b | |||
| 68b5a23a4a | |||
| 20d094cb7c | |||
| 6b6f4abe3e | |||
| c52508979e | |||
| 547e685ce3 | |||
| a4cbeb7d02 | |||
| 03b4d4fc20 | |||
| c49bb9d425 | |||
| daa42c3ade | |||
| 95e68d8982 | |||
| 07054b65a8 | |||
| 557bdeba78 | |||
| 6db1bfacee | |||
| c32962f318 | |||
| b08fc23a6c | |||
| a386305756 | |||
| 225913650f | |||
| a24459d354 | |||
| 692fbff031 | |||
| be8769b841 | |||
| 83ca070484 | |||
| 38ad80c54e | |||
| 024a976c26 | |||
| 158a5fe613 | |||
| 9e1680299a | |||
| ff1cbbe51f | |||
| 5dfd5066c0 | |||
| 9184cc647c | |||
| a48022f059 | |||
| 2941895cda | |||
| 222ada1726 | |||
| 9ff251a882 | |||
| 48d8bf0c0b | |||
| 800204438c | |||
| 97dd32edd6 | |||
| 41fc0ff97e | |||
| 440f668464 | |||
| 8b91709968 | |||
| a9362990ef | |||
| 17bf9bbdaf | |||
| 3ecd9378e9 | |||
| a0b2c28080 | |||
| bddf27de35 | |||
| 77f6265af4 | |||
| 406a0efd37 | |||
| eb7715d16f | |||
| 4db8407d3e | |||
| 61da84e414 | |||
| 73e281cdc4 | |||
| a034f66e0b | |||
| 99a895b7c3 | |||
| 1452f1e1d3 | |||
| d59b91c6a8 | |||
| 85380c6b61 | |||
| 9aff357438 | |||
| e567d6eda3 | |||
| a51a17c846 | |||
| 5dbd593d3a | |||
| 484d8abc22 | |||
| 6e036a74b0 | |||
| 38dfee06dd | |||
| 475362630b | |||
| b643f44415 | |||
| 314d105c16 | |||
| 61ba63d516 | |||
| 16e85de11f | |||
| b46e8a7b32 | |||
| 0766509ab0 | |||
| 56a067e7c1 | |||
| c7f7b18ade | |||
| 3328dc32a7 | |||
| 783e695e00 | |||
| de60fc23ae | |||
| 04576de946 | |||
| 0c5c778ae7 | |||
| 4d2eab6932 | |||
| 7f81a8388a | |||
| 76dad4b0a2 | |||
| 8b65d0cdff | |||
| 857919df34 | |||
| 0b1455e93b | |||
| fba7a51461 | |||
| 7fa00f860e | |||
| 3ce4502093 | |||
| 5739b1b6b9 | |||
| 7097828ac7 | |||
| 438995ddc1 | |||
| 53c59fae82 | |||
| eb0a4127d4 | |||
| 8eaea8e878 | |||
| cb23ec3e1c | |||
| f4f44fb59d | |||
| 850a632505 | |||
| cc52eadad9 | |||
| 0b1c48f422 | |||
| d64639a987 | |||
| 50aff07c9f | |||
| 87568b0cfa | |||
| dea510bfe0 | |||
| 4fb283dea5 | |||
| b2a2dfe8ae | |||
| 62bdb2b8ec | |||
| bce722a96d | |||
| 7266f8301e | |||
| e102b4c4d9 | |||
| 4abf4d9ada | |||
| 477cad6875 | |||
| 7ce4f46db6 | |||
| 471da1eca2 | |||
| efc68f119d | |||
| b18af92a44 | |||
| 0e88a593fd | |||
| 9125eef5b4 | |||
| d2c16cde78 | |||
| 787aa4333a | |||
| a8ee2c885d | |||
| 14a0b42eec | |||
| a6a982d798 | |||
| a09f722564 | |||
| a2c926a184 | |||
| df64a2ca06 | |||
| c490457a71 | |||
| 06b13fb79f | |||
| 260c6b548c | |||
| e50cd7c14f | |||
| 66427af8b7 | |||
| 54472938c1 | |||
| 873fcd7abf | |||
| 5ea1c8027c | |||
| 6b36cd591e | |||
| c896607100 | |||
| f0944e4f7a | |||
| c82a5b3692 | |||
| a6d32ec56e | |||
| 40565791ff | |||
| 650071c3c3 | |||
| 52db4dbd91 | |||
| 1823daac03 | |||
| 7a6ba516c8 | |||
| 6ca319debc | |||
| 351fed869c | |||
| dd0af0fad5 | |||
| 6d27533ac0 | |||
| d04d763594 | |||
| 6f17dd18c8 | |||
| 560d38c251 | |||
| 1ab7bb3c6f | |||
| 2410893797 | |||
| 6c735bd4bb | |||
| 51089c2079 | |||
| 70cfad6550 | |||
| 93d9e77b73 | |||
| 9026f8aa42 | |||
| 36fd5a2e74 | |||
| 86ebfb0bb5 | |||
| a6a46d4fc3 | |||
| f64c024648 | |||
| 8d42058734 | |||
| 06ad488970 | |||
| cca7714daf | |||
| 7080a26ecc | |||
| 56b8a5c80c | |||
| 0a43324230 | |||
| b14945cc2f | |||
| c25eb5d673 | |||
| 4741ff9810 | |||
| 5dc2d2eb4e | |||
| 3bb2f388bb | |||
| 611c47c861 | |||
| 29e70c0ffa | |||
| a8615c22c8 | |||
| 5d14c00774 | |||
| 60a26ddf42 | |||
| db57772b2f | |||
| e7a4135526 | |||
| 5e86ebcd3b | |||
| 0682e95c72 | |||
| a4112f7906 | |||
| 2cc9af244b | |||
| 6ad63c6a2b | |||
| 4ff024c5ab | |||
| 0c92dc487f | |||
| 3277a55bd5 | |||
| 6f55d77ab1 | |||
| 22fcbd1f22 | |||
| b1f4f5bae8 | |||
| 15ba94e132 | |||
| 76996862ed | |||
| a900614082 | |||
| af56a3c5b8 | |||
| 76c73a9895 | |||
| c063da3610 | |||
| a027928b32 | |||
| 8fefce40e2 | |||
| 23cd87285b | |||
| 58a10b8e47 | |||
| 288f92e8bd | |||
| 87fa90f7a5 | |||
| 9a5b9c76fc | |||
| 70a52304db | |||
| e271dc1e96 | |||
| c8b4b14574 | |||
| 925c6bba13 | |||
| 60f89a0364 | |||
| 4b3f09c081 | |||
| f47289bc99 | |||
| 8d6b7362e2 | |||
| 78ede65849 | |||
| a52191b36b | |||
| 166c123bc3 | |||
| 01707afd17 | |||
| b3995066ad | |||
| 2332e18b87 | |||
| 587d575de1 | |||
| d5df4d045f | |||
| 5ed3f867eb | |||
| 80e7dc9740 | |||
| d25ef0fbde | |||
| 3468942807 | |||
| 65b930fcbd | |||
| 0e1df382a5 | |||
| db80cf54a6 | |||
| be82fa5053 | |||
| 7fa20a8f2e | |||
| 87935201fe | |||
| bf60b24c82 | |||
| bed63ca74f | |||
| bf209aea14 | |||
| 27802334e2 | |||
| 4d51f843be | |||
| a40195b455 | |||
| f94c215231 | |||
| 3bfe6aa877 | |||
| 5d09708b25 | |||
| 10bf1500da | |||
| 091fc5259b | |||
| 3286622534 | |||
| fd6d42de20 | |||
| 8275f30231 | |||
| 6d425afa4f | |||
| e4e7acde8b | |||
| a80a00aa08 | |||
| 18b2d9d2f9 | |||
| c577e1af6a | |||
| b704533f0a | |||
| 117ee3a064 | |||
| c0abaa9fdf | |||
| ca86656416 | |||
| 22fa1056d7 | |||
| 628462b78d | |||
| 6944c07406 | |||
| 74e7fab22e | |||
| 6b6d2633b0 | |||
| b0f5eb7d36 | |||
| 162c33d75e | |||
| 641eab45e0 | |||
| 18ff1708e4 | |||
| 39396934da | |||
| a6a883df2d | |||
| 3e5db201a5 | |||
| 5a8f2ba046 | |||
| 3c63c2c900 | |||
| 96c7474eb0 | |||
| 20e102773f | |||
| 36719a497f | |||
| 1d1d4952b0 | |||
| faef5d14c7 | |||
| 61358a918d | |||
| 1a6dac81ed | |||
| df443f4d83 | |||
| 5677aedfd3 | |||
| 20f2e2ec6a | |||
| 6309e63d41 | |||
| fb0a1132c9 | |||
| 3b5f57029b | |||
| 859d6e470e | |||
| 8e114d80fb | |||
| f41a364e27 | |||
| 33cd0e15f1 | |||
| a6c941f063 | |||
| d0090576e1 | |||
| 2feef8ec73 | |||
| ca7c500826 | |||
| ec4dc1d0c2 | |||
| c10119a059 | |||
| 54405a604f | |||
| 00a3d0bdcf | |||
| 5b647d65f2 | |||
| 4d9adf0f60 | |||
| 59dd3269fb | |||
| 70ddb4e2c6 | |||
| d55eb769e4 | |||
| 08610c078f | |||
| 1f3f47fe97 | |||
| 15ccd59dc1 | |||
| f8f27a5013 | |||
| 42d5dcb5c3 | |||
| da3aaf3a63 | |||
| 3ab644e94e | |||
| 1d188cb1d3 | |||
| d5dd5bd085 | |||
| cb61fdd961 | |||
| 4c2746d752 | |||
| 9e065db83d | |||
| aa720a52ed | |||
| 963681fdc0 | |||
| de7454d413 | |||
| c327cc5c77 | |||
| bc77304aa5 | |||
| 7b30d1e84a | |||
| 4ffe9d1bd3 | |||
| be932909b5 | |||
| 665db4c894 | |||
| 960c5cce5c | |||
| e2baf7ed8a | |||
| 0ef9c59d09 | |||
| c3d1a15532 | |||
| e65317c3f3 | |||
| 32f27a6c69 | |||
| d3ea8cbc07 | |||
| 73f2ca5411 | |||
| 7b30789ce7 | |||
| 0de2b00a8a | |||
| f71446f628 | |||
| 26933d15b0 | |||
| f769b21680 | |||
| 0c6c844cb8 | |||
| 2940d926a5 | |||
| 4e65da4a2f | |||
| 229072cc77 | |||
| 79b58bee2b | |||
| 4b13200c2f | |||
| f70eede993 | |||
| 1414b0a7d4 | |||
| f80cf7dcf1 | |||
| c8393f44df | |||
| 63453ea129 | |||
| 974ccb5121 | |||
| 9604b3e9d8 | |||
| 3516f2b3ef | |||
| 2622aa2f9d | |||
| 31bbc4db30 | |||
| a52a2d3b26 | |||
| d4bb5da618 | |||
| 591eb7449f | |||
| a46efc23a3 | |||
| 4784153309 | |||
| d780b39188 | |||
| 9cb7b278af | |||
| 114ebc3742 | |||
| 6a01418aa1 | |||
| ce87f75cf6 | |||
| a5289915ca | |||
| 2381a9327f | |||
| 934a6d94ef | |||
| a24477c30a | |||
| cdfcaa4876 | |||
| 994ad03eb4 | |||
| e8047b8876 | |||
| ce9eec227b | |||
| 1e9de38a74 | |||
| 1db782af87 | |||
| 6e120bba12 | |||
| cad2583872 | |||
| 60d47c2170 | |||
| 572eca5748 | |||
| 03f2be3e3d | |||
| 6b6487eeed | |||
| 63265e4709 | |||
| 140b58502c | |||
| dfa680442c | |||
| 81df060697 | |||
| ac0f173e2e | |||
| 70d41bafa1 | |||
| 418a05d706 | |||
| 0761304d2f | |||
| 6b1ca71974 | |||
| 7f7b3c1b5b | |||
| 1abbe2a268 | |||
| 2086e272e8 | |||
| f2cd45004b | |||
| efee20c43b | |||
| 6ab7e0d283 | |||
| da3ca5041f | |||
| 841db8ec77 | |||
| 5d35d7b884 | |||
| ac70fb827a | |||
| 21b17fe49c | |||
| c4c0518d90 | |||
| bad5905952 | |||
| 7817f82c15 | |||
| cabf0dbd40 | |||
| ec6f81207a | |||
| 4cae8e7a30 | |||
| cd326efb57 | |||
| ab430ba5fd | |||
| 4c395d5b09 | |||
| 39f2c0f711 | |||
| 3e1089a7f1 | |||
| 02dae40716 | |||
| 408beb96d6 | |||
| c4e2c3ba9b | |||
| 48db5765ac | |||
| 4d59af4afa | |||
| f9758178c6 | |||
| 695ecfc67d | |||
| e02155048a | |||
| 0177319237 | |||
| e5f8c4d2e3 | |||
| edbb4f6e53 | |||
| 07b51eebf3 | |||
| 5240013d21 | |||
| ee687f8919 | |||
| 4c2336663a | |||
| a0984c46a1 | |||
| 4077d3e696 | |||
| d9e423dc82 | |||
| c58421208c | |||
| f361d3e20f | |||
| b238a8658f | |||
| 4513906883 | |||
| 1052567d7e | |||
| 1f43996636 | |||
| 0d18a2c74d | |||
| 3302964844 | |||
| 70d71d3af7 | |||
| 0b841c0c72 | |||
| bc66f3d7b2 | |||
| f3008d2a08 | |||
| 7de2aa1a95 | |||
| 69b2e68d27 | |||
| b7327c6c19 | |||
| f06196976a | |||
| 44f9a36089 | |||
| d92624e11f | |||
| 2264a0454c | |||
| 0944647413 | |||
| 8917f657a1 | |||
| b8b43072c2 | |||
| a85c16aea5 | |||
| aade13141c | |||
| 41d53f9bd5 | |||
| 0d3baf5f8e | |||
| 793d034c4a | |||
| 92236e4345 | |||
| c14c042aca | |||
| 45b9bcd9a0 | |||
| f45a62e469 | |||
| 650d4000cb | |||
| a411fd9ad7 | |||
| 9c35910821 | |||
| 47e5ed8e30 | |||
| b2e6bee53e | |||
| e217f4914a | |||
| 1ba350d146 | |||
| ec921c9d7b | |||
| ec3be4584c | |||
| e8f73b9edd | |||
| e9716eda2f | |||
| df8d12b685 | |||
| 1c529d9897 | |||
| 4ac2ded44b | |||
| f11ab3b3ed | |||
| 471b5b73a3 | |||
| ebc7b73150 | |||
| a06ed7e888 | |||
| 92a25cff43 | |||
| e5549f4f16 | |||
| 0d4fda7843 | |||
| f083859e96 | |||
| 29d83deae9 | |||
| 2217e2fea9 | |||
| 68927e83e5 | |||
| 819020ac57 | |||
| 1e5a066247 | |||
| 24a7fc2f07 | |||
| 03f0b4fc14 | |||
| 8c1261bd97 | |||
| 17af025b52 | |||
| ac56855bbc | |||
| 6f6ef56253 | |||
| 79d202c36d | |||
| 962aca6ad6 | |||
| 7473e54a3d | |||
| 105370c407 | |||
| 869ffde772 | |||
| 73d2934ba5 | |||
| 74a51dd48a | |||
| 9005a3bb96 | |||
| 6fccd1fe35 | |||
| ea78dbdf50 | |||
| db3cdb6d25 | |||
| ccc297f01a | |||
| 8dd7e73294 | |||
| f2087a7fcb | |||
| b1fe9348db | |||
| c3183cb6fe | |||
| d47064c4b2 | |||
| 66a28fbaa4 | |||
| d5d7d57d6d | |||
| db3bcaba14 | |||
| 145467fadf | |||
| 07021369d7 | |||
| 836172f366 | |||
| 2c3d0c3b6f | |||
| 1388dece19 | |||
| 41ec284720 | |||
| 62e799ac84 | |||
| 2945fe403b | |||
| 6af9a4e21c | |||
| 86c5e56baf | |||
| bde99c5a4b | |||
| abde041907 | |||
| bba453b9ed | |||
| 8abf3701a6 | |||
| d607b840b8 | |||
| c65d2ccb13 | |||
| 9149eaae18 | |||
| b35e24e254 | |||
| 8a0c8192c8 | |||
| f5f86a68ac | |||
| 57b1d3ea85 | |||
| 9611df0f92 | |||
| 74c19577c9 | |||
| c7231d5235 | |||
| 3cf111c8d3 | |||
| e0518a0940 | |||
| b000642c03 | |||
| aae5800486 | |||
| 9ef2475cdd | |||
| 8513fdd0ba | |||
| 19da0bad13 | |||
| ff64873ece | |||
| 7bd6de4822 | |||
| eb127e0b21 | |||
| 9797983c6f | |||
| 6767a5d631 | |||
| 1507697d9f | |||
| daf7e2a478 | |||
| 771e49de0c | |||
| c19896ff95 | |||
| 68494c8ef2 | |||
| 0a44e7d8cc | |||
| 345f365555 | |||
| 8079f3343f | |||
| 005f7c8b24 | |||
| a6f084c9c5 | |||
| 0e7a5b346f | |||
| 8640c059d8 | |||
| a3f65f8b5b | |||
| 88cece4bd7 | |||
| ddfebd633e | |||
| ac4baac8b9 | |||
| a0ef20cfe4 | |||
| e819a58b6e | |||
| 2adbbcac0a | |||
| 4e5e185f80 | |||
| 68cbd0599d | |||
| 2134746dea | |||
| 4d56fe7d60 | |||
| 1c4bc77d44 | |||
| bc91b91ab1 | |||
| 9887a4cbae | |||
| 7d8fb1962e | |||
| 07fbf4515c | |||
| e81e12cd79 | |||
| f318ef32bc | |||
| 696f3dcc83 | |||
| 804a5f59ce | |||
| 3f45d8fece | |||
| dfe989c826 | |||
| ed6277f9f7 | |||
| 48db0e02cd | |||
| 6ace0f59ae | |||
| fbf528eb95 | |||
| 220ea7cd09 | |||
| 7f1c642112 | |||
| 6530c22a11 | |||
| ab37a1c815 | |||
| 75b13bba36 | |||
| 2cebc825e9 | |||
| ffe7dd3769 | |||
| f41205a84c | |||
| 3046ae85cc | |||
| 536892fd4c | |||
| 2cae0d3b15 | |||
| bdb1cab348 | |||
| d08bcc4ded | |||
| 2f1473ac6d | |||
| 899f21fc26 | |||
| c60a3ef656 | |||
| 8262d6133a | |||
| e662941230 | |||
| 89feea07d3 | |||
| 9c2784ca30 | |||
| e18b4b0918 | |||
| 14d8971cd6 | |||
| 7c8149d6af | |||
| 096a908dbe | |||
| 68dfa89fea | |||
| e64751fb8a | |||
| 490c5cabb4 | |||
| 4269cac414 | |||
| cd319f3f2f | |||
| da14ce45dd | |||
| 818f90abd3 | |||
| 8ab3584274 | |||
| 13ce9a38a2 | |||
| d5699018b0 | |||
| fbb8579c1a | |||
| f248c81e5a | |||
| 7d05696b12 | |||
| 716c7536cb | |||
| 4cdf94a602 | |||
| c9f2b241e0 | |||
| 8dbe8449e0 | |||
| 4841169211 | |||
| 3fe4b72c34 | |||
| 3c1e7a0759 | |||
| 98ad5c6191 | |||
| 0872bf3175 | |||
| 6e8ca8a6ce | |||
| e2de9c6b6d | |||
| 59b25acd22 | |||
| af145cdac1 | |||
| bf68d558af | |||
| f3d159dea1 | |||
| 3af4f54efb | |||
| 6698b06b11 | |||
| 545d2c9290 | |||
| 7cac3f6fe9 | |||
| db198f615a | |||
| bbf7cf2c44 | |||
| 0f62dd32c7 | |||
| 67e82ebe0b | |||
| ac16eaa936 | |||
| bfe6b3cdd1 | |||
| f1bf39c2f8 | |||
| 6064114c32 | |||
| e0d74e610a | |||
| 8948d04695 | |||
| 9993c6bcc0 | |||
| 1da82165ef | |||
| cf139e224e | |||
| f8bce590ba | |||
| 715eb9438c | |||
| 9c461eae4e | |||
| fe6a3c0531 | |||
| 793c80165d | |||
| a4f457e111 | |||
| 4110561f3e | |||
| b1549e4127 | |||
| 724513e5d8 | |||
| c14fbe69f5 | |||
| 8b4e2418f6 | |||
| 8568798f76 | |||
| 66533b249e | |||
| e5baddebcd | |||
| 0efd3318b2 | |||
| 16acfc55f4 | |||
| 31328e3ede | |||
| c83c1ee838 | |||
| 95f83b70b0 | |||
| 53253aea3a | |||
| c244cd14b7 | |||
| a1b7cd7090 | |||
| e4ffce07cf | |||
| 6b4ce43d1d | |||
| 107ab59c29 | |||
| 4cd0bc7ece | |||
| 42952482c9 | |||
| 3804a59fb6 | |||
| 174faea612 | |||
| dec56ff204 | |||
| c6d3f0d107 | |||
| 8f36db0be5 | |||
| f554e04a27 | |||
| 20c532caf8 | |||
| a1b0938c16 | |||
| 3e1da76d54 | |||
| e3dcc260fb | |||
| ae50bef5e6 | |||
| 1b1e4d2670 | |||
| c31a650aad | |||
| 76943b900c | |||
| c05a3e254c | |||
| 63385ff2b5 | |||
| 42d7bc64f5 | |||
| f0aa5b7e3b | |||
| 40e33b6e75 | |||
| e06768b331 | |||
| ab58f3ee49 | |||
| 6a30312beb | |||
| 8c4dbdfd56 | |||
| e9b0443000 | |||
| fab5233096 | |||
| 2748bf5900 | |||
| 2adf914723 | |||
| 96a2e4086f | |||
| a2d94f3d20 | |||
| 33784bd64b | |||
| 4e5efb5c0c | |||
| 5cb434f62b | |||
| 6117291e6b | |||
| 4e342f5397 | |||
| 6b85e6affd | |||
| e71116f768 | |||
| a0172a28fc | |||
| 60020ccaa9 | |||
| 3987e19c3f | |||
| 2068b31847 | |||
| 9a5f3f7672 | |||
| 75aa0f73db | |||
| 2efce29560 | |||
| a4c6ffd85f | |||
| 184169cd76 | |||
| 55d5b4168e | |||
| 6ccff3ba5d | |||
| 44f23c7ec1 | |||
| 492b025f5f | |||
| 7f98e36008 | |||
| f53c016704 |
@@ -35,9 +35,6 @@ env:
|
||||
# Run unit tests on Postgres
|
||||
- DB=pgsql PHPUNIT=true INSTALL=false CITEST=false
|
||||
|
||||
# Perform an upgrade test too.
|
||||
- DB=pgsql PHPUNIT=false INSTALL=true CITEST=false UPGRADE=true
|
||||
|
||||
matrix:
|
||||
# Enable fast finish.
|
||||
# This will fail the build if a single job fails (except those in allow_failures).
|
||||
@@ -56,10 +53,6 @@ matrix:
|
||||
- env: DB=mysqli PHPUNIT=true INSTALL=false CITEST=false
|
||||
php: 5.4
|
||||
|
||||
# Moodle 2.7 is not compatible with PHP 7 for the upgrade test.
|
||||
- env: DB=pgsql PHPUNIT=false INSTALL=true CITEST=false UPGRADE=true
|
||||
php: 7.0
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.composer/cache
|
||||
@@ -163,7 +156,7 @@ script:
|
||||
# We need the official upstream for comparison
|
||||
git remote add upstream https://github.com/moodle/moodle.git;
|
||||
|
||||
git fetch upstream master;
|
||||
git fetch upstream MOODLE_30_STABLE;
|
||||
export GIT_PREVIOUS_COMMIT="`git merge-base FETCH_HEAD $TRAVIS_COMMIT`";
|
||||
export GIT_COMMIT="$TRAVIS_COMMIT";
|
||||
export UPSTREAM_FETCH_HEAD=`git rev-parse FETCH_HEAD`
|
||||
@@ -180,39 +173,3 @@ script:
|
||||
then
|
||||
bash local/ci/php_lint/php_lint.sh;
|
||||
fi
|
||||
|
||||
########################################################################
|
||||
# Upgrade test
|
||||
########################################################################
|
||||
- >
|
||||
if [ "$UPGRADE" = 'true' ];
|
||||
then
|
||||
# We need the official upstream.
|
||||
git remote add upstream https://github.com/moodle/moodle.git;
|
||||
|
||||
# Checkout 27 STABLE branch.
|
||||
git fetch upstream MOODLE_27_STABLE;
|
||||
git checkout MOODLE_27_STABLE;
|
||||
|
||||
# Perform the upgrade
|
||||
php admin/cli/install_database.php --agree-license --adminpass=Password --adminemail=admin@example.com --fullname="Upgrade test" --shortname=Upgrade;
|
||||
|
||||
# Return to the previous commit
|
||||
git checkout -;
|
||||
|
||||
# Perform the upgrade
|
||||
php admin/cli/upgrade.php --non-interactive --allow-unstable ;
|
||||
|
||||
# The local_ci repository can be used to check upgrade savepoints.
|
||||
git clone https://github.com/moodlehq/moodle-local_ci.git local/ci ;
|
||||
|
||||
cp local/ci/check_upgrade_savepoints/check_upgrade_savepoints.php ./check_upgrade_savepoints.php
|
||||
result=`php check_upgrade_savepoints.php`;
|
||||
# Check if there are problems
|
||||
count=`echo "$result" | grep -P "ERROR|WARN" | wc -l` ;
|
||||
if (($count > 0));
|
||||
then
|
||||
echo "$result"
|
||||
exit 1 ;
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
CONTRIBUTING TO MOODLE
|
||||
======================
|
||||
|
||||
Moodle is made by people like you. We are members of a big worldwide community
|
||||
of developers, designers, teachers, testers, translators and other users. We
|
||||
work in universities, schools, companies and other places. You are very welcome
|
||||
to join us and contribute to the project.
|
||||
|
||||
See <https://docs.moodle.org/dev/Contributing_to_Moodle> for the many ways you
|
||||
can help, not only with coding.
|
||||
|
||||
Moodle is open to community contributions to core, though all code must go
|
||||
through peer-review, automated behaviour testing, continuous integration and
|
||||
human post-integration checks.
|
||||
|
||||
Pull requests
|
||||
-------------
|
||||
|
||||
Please do not open pull requests via Github. The repository there is just a
|
||||
mirror of the official repository at <https://git.moodle.org>. Issues are
|
||||
reported and patches provided via <https://tracker.moodle.org>. See below for
|
||||
more information.
|
||||
|
||||
Moodle core bug fixes and new features
|
||||
--------------------------------------
|
||||
|
||||
During the years of intensive development, a mature process of including
|
||||
submitted patches has evolved.
|
||||
|
||||
* Every bug fix or new feature must have a tracker issue.
|
||||
* You publish the branch implementing the fix or new feature in your public
|
||||
clone of the moodle.git repository (typically on Github).
|
||||
* Your patch is peer-reviewed, discussed, integrated, tested and then released
|
||||
as a part of moodle.git.
|
||||
* New features are developed on the master branch. Bug fixes are also
|
||||
backported to currently supported maintenance (stable) branches.
|
||||
|
||||
For further details, see <https://docs.moodle.org/dev/Process>.
|
||||
|
||||
Moodle plugins
|
||||
--------------
|
||||
|
||||
Moodle has a framework for additional plugins to extend its functionality. We
|
||||
have a Moodle plugins directory <https://moodle.org/plugins/> where you can
|
||||
register and maintain your plugin. Plugins hosted in the plugins directory can
|
||||
be easily installed and updated via the Moodle administration interface.
|
||||
|
||||
* You are expected to have a public source code repository with your plugin
|
||||
code.
|
||||
* After registering your plugin in the plugins directory it is reviewed before
|
||||
being published.
|
||||
* You are expected to continuously release updated versions of the plugin via
|
||||
the plugins directory. We do not pull from your code repository; you must do
|
||||
it explicitly.
|
||||
|
||||
For further details, see <https://docs.moodle.org/dev/Plugin_contribution>.
|
||||
@@ -1,20 +0,0 @@
|
||||
MOODLE INSTALLATION
|
||||
===================
|
||||
|
||||
Here is a short summary of the installation process (which can take just a few
|
||||
minutes):
|
||||
|
||||
1. Move the Moodle files into your web directory.
|
||||
|
||||
2. Create a single database for Moodle to store all its tables in (or choose an
|
||||
existing database).
|
||||
|
||||
3. Visit your Moodle site with a browser. You should be taken to the
|
||||
install.php script, which will lead you through creating a config.php file
|
||||
and then setting up Moodle, creating an admin account etc.
|
||||
|
||||
4. Set up a cron task to call the file admin/cron.php every minute.
|
||||
|
||||
For more information, see <https://docs.moodle.org/en/Installing_Moodle>.
|
||||
|
||||
Good luck and have fun!
|
||||
@@ -1,7 +0,0 @@
|
||||
*** PLEASE DO NOT OPEN PULL REQUESTS VIA GITHUB ***
|
||||
|
||||
The moodle.git repository at Github is just a mirror of the official repository. We do not accept pull requests at Github.
|
||||
|
||||
See CONTRIBUTING.txt guidelines for how to contribute patches for Moodle. Thank you.
|
||||
|
||||
--
|
||||
@@ -1,28 +1,29 @@
|
||||
.-..-.
|
||||
_____ | || |
|
||||
/____/-.---_ .---. .---. .-.| || | .---.
|
||||
| | _ _ |/ _ \/ _ \/ _ || |/ __ \
|
||||
* | | | | | || |_| || |_| || |_| || || |___/
|
||||
|_| |_| |_|\_____/\_____/\_____||_|\_____)
|
||||
QUICK INSTALL
|
||||
=============
|
||||
|
||||
Moodle - the world's open source learning platform
|
||||
For the impatient, here is a basic outline of the
|
||||
installation process, which normally takes me only
|
||||
a few minutes:
|
||||
|
||||
Moodle <https://moodle.org> is a learning platform designed to provide
|
||||
educators, administrators and learners with a single robust, secure and
|
||||
integrated system to create personalised learning environments.
|
||||
1) Move the Moodle files into your web directory.
|
||||
|
||||
You can download Moodle <https://download.moodle.org> and run it on your own
|
||||
web server, ask one of our Moodle Partners <https://moodle.com/partners/> to
|
||||
assist you, or have a MoodleCloud site <https://moodle.com/cloud/> set up for
|
||||
you.
|
||||
2) Create a single database for Moodle to store all
|
||||
its tables in (or choose an existing database).
|
||||
|
||||
Moodle is widely used around the world by universities, schools, companies and
|
||||
all manner of organisations and individuals.
|
||||
3) Visit your Moodle site with a browser, you should
|
||||
be taken to the install.php script, which will lead
|
||||
you through creating a config.php file and then
|
||||
setting up Moodle, creating an admin account etc.
|
||||
|
||||
Moodle is provided freely as open source software, under the GNU General Public
|
||||
License <https://docs.moodle.org/dev/License>.
|
||||
4) Set up a cron task to call the file admin/cron.php
|
||||
every five minutes or so.
|
||||
|
||||
Moodle is written in PHP and JavaScript and uses an SQL database for storing
|
||||
the data.
|
||||
|
||||
See <https://docs.moodle.org> for details of Moodle's many features.
|
||||
For more information, see the INSTALL DOCUMENTATION:
|
||||
|
||||
http://docs.moodle.org/en/Installing_Moodle
|
||||
|
||||
|
||||
Good luck and have fun!
|
||||
Martin Dougiamas, Lead Developer
|
||||
|
||||
|
||||
@@ -1,48 +1,34 @@
|
||||
MOODLE TRADEMARKS POLICY
|
||||
========================
|
||||
------------------------
|
||||
Moodle Trademark License
|
||||
------------------------
|
||||
|
||||
The word "Moodle" is trademarked in many countries around the world. The word
|
||||
was originally an acronym: Modular Object-Oriented Dynamic Learning
|
||||
Environment. The trademark is owned by Martin Dougiamas, Founder and Director
|
||||
of Moodle.
|
||||
The name Moodle™ is a registered trademark of the Moodle Trust.
|
||||
|
||||
The law obligates trademark owners to police their marks and prevent the use of
|
||||
confusingly similar names by third parties. Through this policy we’d like to
|
||||
make it clear how Moodle-related projects, organisations, and people can use
|
||||
the Moodle trademark. We’d also like to be clear about how use of the word is
|
||||
restricted when used to promote commercial Moodle services. We do this to
|
||||
protect the very business model that allows us to continue developing Moodle
|
||||
for you.
|
||||
A key part of the business model that allows us to produce and
|
||||
distribute Moodle as completely Free open source software is that
|
||||
we restrict the commercial use of the Moodle trademark to those
|
||||
who have contracted to support Moodle development (Moodle Partners).
|
||||
|
||||
Allowed uses
|
||||
------------
|
||||
If you are intending to use the name (and/or logo) to advertise
|
||||
generic Moodle™ services (eg Moodle Hosting, Moodle Support,
|
||||
Moodle Certification, Moodle Training, Moodle Consulting,
|
||||
Moodle Customisation, Moodle Courseware Development, Moodle
|
||||
Theme design, Moodle Integrations, Moodle Installations, etc)
|
||||
or as the name of a software package, then you must seek
|
||||
direct permission in writing from the Moodle Trust via the
|
||||
moodle.com helpdesk, in accordance with normal trademark
|
||||
restrictions.
|
||||
|
||||
The following uses don’t require any permission at all:
|
||||
There are no restrictions on how you use the name in other
|
||||
contexts (for example, if you use Moodle just to provide
|
||||
courses then you can use the name freely to refer to it.)
|
||||
|
||||
* Referring to the software or the Moodle project.
|
||||
* Describing your own Moodle implementation (including within corporate
|
||||
settings).
|
||||
* Describing a Moodle-based community hub.
|
||||
* Describing some software you’ve made that integrates with Moodle
|
||||
(eg a Moodle integration feature on another system).
|
||||
If you aren't sure of a particular case, please ask us via
|
||||
http://moodle.com/helpdesk: we'll be happy to either provide
|
||||
you with official permission in writing or help you fix
|
||||
your wording.
|
||||
|
||||
Restricted uses
|
||||
---------------
|
||||
|
||||
The following uses are generally prohibited without explicit and direct
|
||||
permission being granted to you by Moodle Pty Ltd. We do this to protect the
|
||||
Moodle project from software and sites which could confuse people. Please
|
||||
contact us to ask for permission in writing.
|
||||
|
||||
* You can’t use "Moodle" in the name of your software (including Mobile apps)
|
||||
* You can’t use "Moodle" in your company name
|
||||
* You can’t use "Moodle" in your domain name
|
||||
* You can’t use "Moodle" in advertising-related keywords (such as Adsense)
|
||||
* You can’t use "Moodle" to describe services around Moodle (such as hosting,
|
||||
training, support, consulting, course creation services, theme development,
|
||||
customisation, installation, integration and certification). This applies
|
||||
even if you do not charge for the services. Note that usually only Moodle
|
||||
Partners have this permission.
|
||||
|
||||
For information about the Moodle Partner Certification Mark as well as for how
|
||||
to contact us, please see <https://moodle.com/trademarks/>.
|
||||
Martin Dougiamas
|
||||
Executive Director
|
||||
Moodle Trust
|
||||
http://moodle.com
|
||||
|
||||
@@ -1,106 +0,0 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Allows admin to configure antiviruses.
|
||||
*
|
||||
* @package core_antivirus
|
||||
* @copyright 2015 Ruslan Kabalin, Lancaster University.
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
require_once('../config.php');
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
require_once($CFG->libdir.'/tablelib.php');
|
||||
|
||||
$action = required_param('action', PARAM_ALPHANUMEXT);
|
||||
$antivirus = required_param('antivirus', PARAM_PLUGIN);
|
||||
$confirm = optional_param('confirm', 0, PARAM_BOOL);
|
||||
|
||||
$PAGE->set_url('/admin/antiviruses.php', array('action' => $action, 'antivirus' => $antivirus));
|
||||
$PAGE->set_context(context_system::instance());
|
||||
|
||||
require_login();
|
||||
require_capability('moodle/site:config', context_system::instance());
|
||||
|
||||
$returnurl = "$CFG->wwwroot/$CFG->admin/settings.php?section=manageantiviruses";
|
||||
|
||||
// Get currently installed and enabled antivirus plugins.
|
||||
$availableantiviruses = \core\antivirus\manager::get_available();
|
||||
if (!empty($antivirus) and empty($availableantiviruses[$antivirus])) {
|
||||
redirect ($returnurl);
|
||||
}
|
||||
|
||||
$activeantiviruses = explode(',', $CFG->antiviruses);
|
||||
foreach ($activeantiviruses as $key => $active) {
|
||||
if (empty($availableantiviruses[$active])) {
|
||||
unset($activeantiviruses[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!confirm_sesskey()) {
|
||||
redirect($returnurl);
|
||||
}
|
||||
|
||||
switch ($action) {
|
||||
case 'disable':
|
||||
// Remove from enabled list.
|
||||
$key = array_search($antivirus, $activeantiviruses);
|
||||
unset($activeantiviruses[$key]);
|
||||
break;
|
||||
|
||||
case 'enable':
|
||||
// Add to enabled list.
|
||||
if (!in_array($antivirus, $activeantiviruses)) {
|
||||
$activeantiviruses[] = $antivirus;
|
||||
$activeantiviruses = array_unique($activeantiviruses);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'down':
|
||||
$key = array_search($antivirus, $activeantiviruses);
|
||||
// Check auth plugin is valid.
|
||||
if ($key !== false) {
|
||||
// Move down the list.
|
||||
if ($key < (count($activeantiviruses) - 1)) {
|
||||
$fsave = $activeantiviruses[$key];
|
||||
$activeantiviruses[$key] = $activeantiviruses[$key + 1];
|
||||
$activeantiviruses[$key + 1] = $fsave;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'up':
|
||||
$key = array_search($antivirus, $activeantiviruses);
|
||||
// Check auth is valid.
|
||||
if ($key !== false) {
|
||||
// Move up the list.
|
||||
if ($key >= 1) {
|
||||
$fsave = $activeantiviruses[$key];
|
||||
$activeantiviruses[$key] = $activeantiviruses[$key - 1];
|
||||
$activeantiviruses[$key - 1] = $fsave;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
set_config('antiviruses', implode(',', $activeantiviruses));
|
||||
core_plugin_manager::reset_caches();
|
||||
|
||||
redirect ($returnurl);
|
||||
@@ -45,23 +45,17 @@ require_once($CFG->libdir.'/clilib.php'); // cli only functions
|
||||
require_once($CFG->libdir.'/environmentlib.php');
|
||||
|
||||
// now get cli options
|
||||
$lang = isset($SESSION->lang) ? $SESSION->lang : $CFG->lang;
|
||||
list($options, $unrecognized) = cli_get_params(
|
||||
array(
|
||||
'non-interactive' => false,
|
||||
'allow-unstable' => false,
|
||||
'help' => false,
|
||||
'lang' => $lang
|
||||
'help' => false
|
||||
),
|
||||
array(
|
||||
'h' => 'help'
|
||||
)
|
||||
);
|
||||
|
||||
if ($options['lang']) {
|
||||
$SESSION->lang = $options['lang'];
|
||||
}
|
||||
|
||||
$interactive = empty($options['non-interactive']);
|
||||
|
||||
if ($unrecognized) {
|
||||
@@ -80,10 +74,6 @@ Options:
|
||||
--non-interactive No interactive questions or confirmations
|
||||
--allow-unstable Upgrade even if the version is not marked as stable yet,
|
||||
required in non-interactive mode.
|
||||
--lang=CODE Set preferred language for CLI output. Defaults to the
|
||||
site language if not set. Defaults to 'en' if the lang
|
||||
parameter is invalid or if the language pack is not
|
||||
installed.
|
||||
-h, --help Print out this help
|
||||
|
||||
Example:
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Lets users manage data formats
|
||||
*
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
* @copyright 2016 Brendan Heywood (brendan@catalyst-au.net)
|
||||
* @package core
|
||||
* @subpackage dataformat
|
||||
*/
|
||||
|
||||
require_once('../config.php');
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
|
||||
$action = required_param('action', PARAM_ALPHANUMEXT);
|
||||
$name = required_param('name', PARAM_PLUGIN);
|
||||
|
||||
$syscontext = context_system::instance();
|
||||
$PAGE->set_url('/admin/dataformats.php');
|
||||
$PAGE->set_context($syscontext);
|
||||
|
||||
require_login();
|
||||
require_capability('moodle/site:config', $syscontext);
|
||||
require_sesskey();
|
||||
|
||||
$return = new moodle_url('/admin/settings.php', array('section' => 'managedataformats'));
|
||||
|
||||
$plugins = core_plugin_manager::instance()->get_plugins_of_type('dataformat');
|
||||
$sortorder = array_flip(array_keys($plugins));
|
||||
|
||||
if (!isset($plugins[$name])) {
|
||||
print_error('courseformatnotfound', 'error', $return, $name);
|
||||
}
|
||||
|
||||
switch ($action) {
|
||||
case 'disable':
|
||||
if ($plugins[$name]->is_enabled()) {
|
||||
set_config('disabled', 1, 'dataformat_'. $name);
|
||||
core_plugin_manager::reset_caches();
|
||||
}
|
||||
break;
|
||||
case 'enable':
|
||||
if (!$plugins[$name]->is_enabled()) {
|
||||
unset_config('disabled', 'dataformat_'. $name);
|
||||
core_plugin_manager::reset_caches();
|
||||
}
|
||||
break;
|
||||
case 'up':
|
||||
if ($sortorder[$name]) {
|
||||
$currentindex = $sortorder[$name];
|
||||
$seq = array_keys($plugins);
|
||||
$seq[$currentindex] = $seq[$currentindex - 1];
|
||||
$seq[$currentindex - 1] = $name;
|
||||
set_config('dataformat_plugins_sortorder', implode(',', $seq));
|
||||
}
|
||||
break;
|
||||
case 'down':
|
||||
if ($sortorder[$name] < count($sortorder) - 1) {
|
||||
$currentindex = $sortorder[$name];
|
||||
$seq = array_keys($plugins);
|
||||
$seq[$currentindex] = $seq[$currentindex + 1];
|
||||
$seq[$currentindex + 1] = $name;
|
||||
set_config('dataformat_plugins_sortorder', implode(',', $seq));
|
||||
}
|
||||
break;
|
||||
}
|
||||
redirect($return);
|
||||
|
||||
@@ -843,8 +843,6 @@ $buggyiconvnomb = (!function_exists('mb_convert_encoding') and @iconv('UTF-8', '
|
||||
$registered = $DB->count_records('registration_hubs', array('huburl' => HUB_MOODLEORGHUBURL, 'confirmed' => 1));
|
||||
// Check if there are any cache warnings.
|
||||
$cachewarnings = cache_helper::warnings();
|
||||
// Check if there are events 1 API handlers.
|
||||
$eventshandlers = $DB->get_records_sql('SELECT DISTINCT component FROM {events_handlers}');
|
||||
|
||||
admin_externalpage_setup('adminnotifications');
|
||||
|
||||
@@ -852,4 +850,4 @@ $output = $PAGE->get_renderer('core', 'admin');
|
||||
|
||||
echo $output->admin_notifications_page($maturity, $insecuredataroot, $errorsdisplayed, $cronoverdue, $dbproblems,
|
||||
$maintenancemode, $availableupdates, $availableupdatesfetch, $buggyiconvnomb,
|
||||
$registered, $cachewarnings, $eventshandlers);
|
||||
$registered, $cachewarnings);
|
||||
|
||||
@@ -275,19 +275,17 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
* @param array|null $availableupdates array of \core\update\info objects or null
|
||||
* @param int|null $availableupdatesfetch timestamp of the most recent updates fetch or null (unknown)
|
||||
* @param string[] $cachewarnings An array containing warnings from the Cache API.
|
||||
* @param array $eventshandlers Events 1 API handlers.
|
||||
*
|
||||
* @return string HTML to output.
|
||||
*/
|
||||
public function admin_notifications_page($maturity, $insecuredataroot, $errorsdisplayed,
|
||||
$cronoverdue, $dbproblems, $maintenancemode, $availableupdates, $availableupdatesfetch,
|
||||
$buggyiconvnomb, $registered, array $cachewarnings = array(), $eventshandlers = 0) {
|
||||
$buggyiconvnomb, $registered, array $cachewarnings = array()) {
|
||||
global $CFG;
|
||||
$output = '';
|
||||
|
||||
$output .= $this->header();
|
||||
$output .= $this->maturity_info($maturity);
|
||||
$output .= $this->legacy_log_store_writing_error();
|
||||
$output .= empty($CFG->disableupdatenotifications) ? $this->available_updates($availableupdates, $availableupdatesfetch) : '';
|
||||
$output .= $this->insecure_dataroot_warning($insecuredataroot);
|
||||
$output .= $this->display_errors_warning($errorsdisplayed);
|
||||
@@ -296,7 +294,6 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
$output .= $this->db_problems($dbproblems);
|
||||
$output .= $this->maintenance_mode_warning($maintenancemode);
|
||||
$output .= $this->cache_warnings($cachewarnings);
|
||||
$output .= $this->events_handlers($eventshandlers);
|
||||
$output .= $this->registration_warning($registered);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -597,23 +594,6 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
return join("\n", array_map(array($this, 'warning'), $cachewarnings));
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders events 1 API handlers warning.
|
||||
*
|
||||
* @param array $eventshandlers
|
||||
* @return string
|
||||
*/
|
||||
public function events_handlers($eventshandlers) {
|
||||
if ($eventshandlers) {
|
||||
$components = '';
|
||||
foreach ($eventshandlers as $eventhandler) {
|
||||
$components .= $eventhandler->component . ', ';
|
||||
}
|
||||
$components = rtrim($components, ', ');
|
||||
return $this->warning(get_string('eventshandlersinuse', 'admin', $components));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render an appropriate message if the site in in maintenance mode.
|
||||
* @param bool $maintenancemode
|
||||
@@ -1955,19 +1935,4 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if writing to the deprecated legacy log store is enabled.
|
||||
*
|
||||
* @return string An error message if writing to the legacy log store is enabled.
|
||||
*/
|
||||
protected function legacy_log_store_writing_error() {
|
||||
$enabled = get_config('logstore_legacy', 'loglegacy');
|
||||
$plugins = explode(',', get_config('tool_log', 'enabled_stores'));
|
||||
$enabled = $enabled && in_array('logstore_legacy', $plugins);
|
||||
|
||||
if ($enabled) {
|
||||
return $this->warning(get_string('legacylogginginuse'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ abstract class core_role_capability_table_with_risks extends core_role_capabilit
|
||||
protected $allpermissions; // We don't need perms ourselves, but all our subclasses do.
|
||||
protected $strperms; // Language string cache.
|
||||
protected $risksurl; // URL in moodledocs about risks.
|
||||
protected $riskicons = array(); // Cache to avoid regenerating the HTML for each risk icon.
|
||||
/** @var array The capabilities to highlight as default/inherited. */
|
||||
protected $parentpermissions;
|
||||
protected $displaypermissions;
|
||||
@@ -182,12 +183,12 @@ abstract class core_role_capability_table_with_risks extends core_role_capabilit
|
||||
*/
|
||||
public function get_risk_icon($type) {
|
||||
global $OUTPUT;
|
||||
|
||||
$iconurl = $OUTPUT->pix_url('i/' . str_replace('risk', 'risk_', $type));
|
||||
$text = '<img src="' . $iconurl . '" alt="' . get_string($type . 'short', 'admin') . '" />';
|
||||
$action = new popup_action('click', $this->risksurl, 'docspopup');
|
||||
$riskicon = $OUTPUT->action_link($this->risksurl, $text, $action, array('title'=>get_string($type, 'admin')));
|
||||
|
||||
return $riskicon;
|
||||
if (!isset($this->riskicons[$type])) {
|
||||
$iconurl = $OUTPUT->pix_url('i/' . str_replace('risk', 'risk_', $type));
|
||||
$text = '<img src="' . $iconurl . '" alt="' . get_string($type . 'short', 'admin') . '" />';
|
||||
$action = new popup_action('click', $this->risksurl, 'docspopup');
|
||||
$this->riskicons[$type] = $OUTPUT->action_link($this->risksurl, $text, $action, array('title'=>get_string($type, 'admin')));
|
||||
}
|
||||
return $this->riskicons[$type];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,15 +20,13 @@ $focus = '';
|
||||
// now we'll deal with the case that the admin has submitted the form with changed settings
|
||||
if ($data = data_submitted() and confirm_sesskey()) {
|
||||
if (admin_write_settings($data)) {
|
||||
redirect($PAGE->url, get_string('changessaved'), null, \core\output\notification::NOTIFY_SUCCESS);
|
||||
$statusmsg = get_string('changessaved');
|
||||
}
|
||||
|
||||
if (!empty($adminroot->errors)) {
|
||||
$errormsg = get_string('errorwithsettings', 'admin');
|
||||
$firsterror = reset($adminroot->errors);
|
||||
$focus = $firsterror->id;
|
||||
} else {
|
||||
redirect($PAGE->url);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ $errormsg = '';
|
||||
|
||||
if ($data = data_submitted() and confirm_sesskey()) {
|
||||
if (admin_write_settings($data)) {
|
||||
redirect($PAGE->url, get_string('changessaved'), null, \core\output\notification::NOTIFY_SUCCESS);
|
||||
$statusmsg = get_string('changessaved');
|
||||
}
|
||||
|
||||
if (empty($adminroot->errors)) {
|
||||
@@ -48,7 +48,6 @@ if ($data = data_submitted() and confirm_sesskey()) {
|
||||
case 'site': redirect("$CFG->wwwroot/");
|
||||
case 'admin': redirect("$CFG->wwwroot/$CFG->admin/");
|
||||
}
|
||||
redirect($PAGE->url);
|
||||
} else {
|
||||
$errormsg = get_string('errorwithsettings', 'admin');
|
||||
$firsterror = reset($adminroot->errors);
|
||||
@@ -77,7 +76,7 @@ if (empty($SITE->fullname)) {
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------
|
||||
|
||||
echo '<form action="' . $PAGE->url . '" method="post" id="adminsettings">';
|
||||
echo '<form action="settings.php" method="post" id="adminsettings">';
|
||||
echo '<div class="settingsform clearfix">';
|
||||
echo html_writer::input_hidden_params($PAGE->url);
|
||||
echo '<input type="hidden" name="sesskey" value="'.sesskey().'" />';
|
||||
@@ -121,7 +120,7 @@ if (empty($SITE->fullname)) {
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------
|
||||
|
||||
echo '<form action="' . $PAGE->url . '" method="post" id="adminsettings">';
|
||||
echo '<form action="settings.php" method="post" id="adminsettings">';
|
||||
echo '<div class="settingsform clearfix">';
|
||||
echo html_writer::input_hidden_params($PAGE->url);
|
||||
echo '<input type="hidden" name="sesskey" value="'.sesskey().'" />';
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* File.
|
||||
*
|
||||
* @package core_competency
|
||||
* @copyright 2016 Frédéric Massart - FMCorz.net
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
// Save processing when the user will not be able to access anything.
|
||||
if (has_capability('moodle/site:config', $systemcontext)) {
|
||||
|
||||
$parentname = 'competencies';
|
||||
|
||||
// Settings page.
|
||||
$settings = new admin_settingpage('competencysettings', new lang_string('competenciessettings', 'core_competency'),
|
||||
'moodle/site:config', false);
|
||||
$ADMIN->add($parentname, $settings);
|
||||
|
||||
// Load the full tree of settings.
|
||||
if ($ADMIN->fulltree) {
|
||||
$setting = new admin_setting_configcheckbox('core_competency/enabled',
|
||||
new lang_string('enablecompetencies', 'core_competency'),
|
||||
new lang_string('enablecompetencies_desc', 'core_competency'), 1);
|
||||
$settings->add($setting);
|
||||
|
||||
$setting = new admin_setting_configcheckbox('core_competency/pushcourseratingstouserplans',
|
||||
new lang_string('pushcourseratingstouserplans', 'core_competency'),
|
||||
new lang_string('pushcourseratingstouserplans_desc', 'core_competency'), 1);
|
||||
$settings->add($setting);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -138,16 +138,6 @@ if ($hassiteconfig) {
|
||||
$plugin->load_settings($ADMIN, 'editorsettings', $hassiteconfig);
|
||||
}
|
||||
|
||||
// Antivirus plugins.
|
||||
$ADMIN->add('modules', new admin_category('antivirussettings', new lang_string('antiviruses', 'antivirus')));
|
||||
$temp = new admin_settingpage('manageantiviruses', new lang_string('antivirussettings', 'antivirus'));
|
||||
$temp->add(new admin_setting_manageantiviruses());
|
||||
$ADMIN->add('antivirussettings', $temp);
|
||||
foreach (core_plugin_manager::instance()->get_plugins_of_type('antivirus') as $plugin) {
|
||||
/* @var \core\plugininfo\antivirus $plugin */
|
||||
$plugin->load_settings($ADMIN, 'antivirussettings', $hassiteconfig);
|
||||
}
|
||||
|
||||
/// License types
|
||||
$ADMIN->add('modules', new admin_category('licensesettings', new lang_string('licenses')));
|
||||
$temp = new admin_settingpage('managelicenses', new lang_string('managelicenses', 'admin'));
|
||||
@@ -187,11 +177,6 @@ if ($hassiteconfig) {
|
||||
$plugin->load_settings($ADMIN, 'filtersettings', $hassiteconfig);
|
||||
}
|
||||
|
||||
// Data format settings.
|
||||
$ADMIN->add('modules', new admin_category('dataformatsettings', new lang_string('dataformats')));
|
||||
$temp = new admin_settingpage('managedataformats', new lang_string('managedataformats'));
|
||||
$temp->add(new admin_setting_managedataformats());
|
||||
$ADMIN->add('dataformatsettings', $temp);
|
||||
|
||||
//== Portfolio settings ==
|
||||
require_once($CFG->libdir. '/portfoliolib.php');
|
||||
@@ -472,49 +457,6 @@ foreach ($pages as $page) {
|
||||
$ADMIN->add('reportplugins', $page);
|
||||
}
|
||||
|
||||
if ($hassiteconfig) {
|
||||
// Global Search engine plugins.
|
||||
$ADMIN->add('modules', new admin_category('searchplugins', new lang_string('search', 'admin')));
|
||||
$temp = new admin_settingpage('manageglobalsearch', new lang_string('globalsearchmanage', 'admin'));
|
||||
|
||||
$pages = array();
|
||||
$engines = array();
|
||||
foreach (core_component::get_plugin_list('search') as $engine => $plugindir) {
|
||||
$engines[$engine] = new lang_string('pluginname', 'search_' . $engine);
|
||||
$settingspath = "$plugindir/settings.php";
|
||||
if (file_exists($settingspath)) {
|
||||
$settings = new admin_settingpage('search' . $engine,
|
||||
new lang_string('pluginname', 'search_' . $engine), 'moodle/site:config');
|
||||
include($settingspath);
|
||||
if ($settings) {
|
||||
$pages[] = $settings;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Setup status.
|
||||
$temp->add(new admin_setting_searchsetupinfo());
|
||||
|
||||
// Search engine selection.
|
||||
$temp->add(new admin_setting_heading('searchengineheading', new lang_string('searchengine', 'admin'), ''));
|
||||
$temp->add(new admin_setting_configselect('searchengine',
|
||||
new lang_string('selectsearchengine', 'admin'), '', 'solr', $engines));
|
||||
|
||||
// Enable search areas.
|
||||
$temp->add(new admin_setting_heading('searchareasheading', new lang_string('availablesearchareas', 'admin'), ''));
|
||||
$searchareas = \core_search\manager::get_search_areas_list();
|
||||
foreach ($searchareas as $areaid => $searcharea) {
|
||||
list($componentname, $varname) = $searcharea->get_config_var_name();
|
||||
$temp->add(new admin_setting_configcheckbox($componentname . '/' . $varname . '_enabled', $searcharea->get_visible_name(true),
|
||||
'', 1, 1, 0));
|
||||
}
|
||||
$ADMIN->add('searchplugins', $temp);
|
||||
|
||||
foreach ($pages as $page) {
|
||||
$ADMIN->add('searchplugins', $page);
|
||||
}
|
||||
}
|
||||
|
||||
/// Add all admin tools
|
||||
if ($hassiteconfig) {
|
||||
$ADMIN->add('modules', new admin_category('tools', new lang_string('tools', 'admin')));
|
||||
@@ -547,9 +489,10 @@ if ($hassiteconfig) {
|
||||
// Add Calendar type settings.
|
||||
if ($hassiteconfig) {
|
||||
$ADMIN->add('modules', new admin_category('calendartype', new lang_string('calendartypes', 'calendar')));
|
||||
foreach (core_plugin_manager::instance()->get_plugins_of_type('calendartype') as $plugin) {
|
||||
/** @var \core\plugininfo\calendartype $plugin */
|
||||
$plugin->load_settings($ADMIN, 'calendartype', $hassiteconfig);
|
||||
foreach (core_component::get_plugin_list_with_file('calendartype', 'settings.php') as $plugin => $settingspath) {
|
||||
$settings = new admin_settingpage('calendartype_' . $plugin . '_settings', new lang_string('pluginname', 'calendartype_' . $plugin), 'moodle/site:config');
|
||||
include($settingspath);
|
||||
$ADMIN->add('calendartype', $settings);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -127,4 +127,19 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
|
||||
}
|
||||
$temp->add(new admin_setting_configselect('notifyloginthreshold', new lang_string('notifyloginthreshold', 'admin'), new lang_string('confignotifyloginthreshold', 'admin'), '10', $options));
|
||||
$ADMIN->add('security', $temp);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// "antivirus" settingpage
|
||||
$temp = new admin_settingpage('antivirus', new lang_string('antivirus', 'admin'));
|
||||
$temp->add(new admin_setting_configcheckbox('runclamonupload', new lang_string('runclamavonupload', 'admin'), new lang_string('configrunclamavonupload', 'admin'), 0));
|
||||
$temp->add(new admin_setting_configexecutable('pathtoclam', new lang_string('pathtoclam', 'admin'), new lang_string('configpathtoclam', 'admin'), ''));
|
||||
$temp->add(new admin_setting_configdirectory('quarantinedir', new lang_string('quarantinedir', 'admin'), new lang_string('configquarantinedir', 'admin'), ''));
|
||||
$temp->add(new admin_setting_configselect('clamfailureonupload', new lang_string('clamfailureonupload', 'admin'), new lang_string('configclamfailureonupload', 'admin'), 'donothing', array('donothing' => new lang_string('configclamdonothing', 'admin'),
|
||||
'actlikevirus' => new lang_string('configclamactlikevirus', 'admin'))));
|
||||
$ADMIN->add('security', $temp);
|
||||
|
||||
} // end of speedup
|
||||
|
||||
@@ -12,7 +12,6 @@ $temp->add(new admin_setting_configexecutable('pathtodu', new lang_string('patht
|
||||
$temp->add(new admin_setting_configexecutable('aspellpath', new lang_string('aspellpath', 'admin'), new lang_string('edhelpaspellpath'), ''));
|
||||
$temp->add(new admin_setting_configexecutable('pathtodot', new lang_string('pathtodot', 'admin'), new lang_string('pathtodot_help', 'admin'), ''));
|
||||
$temp->add(new admin_setting_configexecutable('pathtogs', new lang_string('pathtogs', 'admin'), new lang_string('pathtogs_help', 'admin'), '/usr/bin/gs'));
|
||||
$temp->add(new admin_setting_configexecutable('pathtounoconv', new lang_string('pathtounoconv', 'admin'), new lang_string('pathtounoconv_help', 'admin'), '/usr/bin/unoconv'));
|
||||
$ADMIN->add('server', $temp);
|
||||
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
|
||||
// Conditional activities: completion and availability
|
||||
$optionalsubsystems->add(new admin_setting_configcheckbox('enablecompletion',
|
||||
new lang_string('enablecompletion','completion'),
|
||||
new lang_string('configenablecompletion', 'completion'), 1));
|
||||
new lang_string('configenablecompletion','completion'), 0));
|
||||
|
||||
$options = array(
|
||||
1 => get_string('completionactivitydefault', 'completion'),
|
||||
@@ -45,13 +45,10 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
|
||||
|
||||
$optionalsubsystems->add($checkbox = new admin_setting_configcheckbox('enableavailability',
|
||||
new lang_string('enableavailability', 'availability'),
|
||||
new lang_string('enableavailability_desc', 'availability'), 1));
|
||||
new lang_string('enableavailability_desc', 'availability'), 0));
|
||||
$checkbox->set_affects_modinfo(true);
|
||||
|
||||
$optionalsubsystems->add(new admin_setting_configcheckbox('enableplagiarism', new lang_string('enableplagiarism','plagiarism'), new lang_string('configenableplagiarism','plagiarism'), 0));
|
||||
|
||||
$optionalsubsystems->add(new admin_setting_configcheckbox('enablebadges', new lang_string('enablebadges', 'badges'), new lang_string('configenablebadges', 'badges'), 1));
|
||||
|
||||
$optionalsubsystems->add(new admin_setting_configcheckbox('enableglobalsearch', new lang_string('enableglobalsearch', 'admin'),
|
||||
new lang_string('enableglobalsearch_desc', 'admin'), 0, 1, 0));
|
||||
}
|
||||
|
||||
@@ -30,7 +30,6 @@ if ($hassiteconfig) {
|
||||
$ADMIN->add('root', new admin_category('users', new lang_string('users','admin')));
|
||||
$ADMIN->add('root', new admin_category('courses', new lang_string('courses','admin')));
|
||||
$ADMIN->add('root', new admin_category('grades', new lang_string('grades')));
|
||||
$ADMIN->add('root', new admin_category('competencies', new lang_string('competencies', 'core_competency')));
|
||||
$ADMIN->add('root', new admin_category('badges', new lang_string('badges'), empty($CFG->enablebadges)));
|
||||
$ADMIN->add('root', new admin_category('location', new lang_string('location','admin')));
|
||||
$ADMIN->add('root', new admin_category('language', new lang_string('language')));
|
||||
|
||||
@@ -28,7 +28,8 @@
|
||||
require_once(__DIR__ . '/../../../lib/behat/behat_base.php');
|
||||
require_once(__DIR__ . '/../../../lib/behat/behat_field_manager.php');
|
||||
|
||||
use Behat\Gherkin\Node\TableNode as TableNode,
|
||||
use Behat\Behat\Context\Step\Given as Given,
|
||||
Behat\Gherkin\Node\TableNode as TableNode,
|
||||
Behat\Mink\Exception\ElementNotFoundException as ElementNotFoundException;
|
||||
|
||||
/**
|
||||
@@ -74,7 +75,7 @@ class behat_admin extends behat_base {
|
||||
$exception = new ElementNotFoundException($this->getSession(), '"' . $label . '" administration setting ');
|
||||
|
||||
// The argument should be converted to an xpath literal.
|
||||
$label = behat_context_helper::escape($label);
|
||||
$label = $this->getSession()->getSelectorsHandler()->xpathLiteral($label);
|
||||
|
||||
// Single element settings.
|
||||
try {
|
||||
|
||||
@@ -8,8 +8,6 @@ Feature: Manage availability conditions
|
||||
Scenario: Display list of availability conditions
|
||||
# Check the report doesn't show when not enabled.
|
||||
Given I log in as "admin"
|
||||
And the following config values are set as admin:
|
||||
| enableavailability | 0 |
|
||||
And I expand "Site administration" node
|
||||
When I expand "Plugins" node
|
||||
Then I should not see "Availability restrictions"
|
||||
@@ -30,6 +28,8 @@ Feature: Manage availability conditions
|
||||
Given the following "courses" exist:
|
||||
| fullname | shortname | format |
|
||||
| Course 1 | C1 | topics |
|
||||
And the following config values are set as admin:
|
||||
| enableavailability | 1 |
|
||||
And I log in as "admin"
|
||||
And I am on site homepage
|
||||
When I navigate to "Manage restrictions" node in "Site administration > Plugins > Availability restrictions"
|
||||
|
||||
@@ -120,14 +120,10 @@ $tags = '';
|
||||
|
||||
if ($options['profile']) {
|
||||
$profile = $options['profile'];
|
||||
|
||||
// If profile passed is not set, then exit.
|
||||
if (!isset($CFG->behat_config[$profile]) && !isset($CFG->behat_profiles[$profile]) &&
|
||||
!(isset($options['replace']) && (strpos($options['profile'], $options['replace']) >= 0 ))) {
|
||||
if (!isset($CFG->behat_config[$profile]) && !isset($CFG->behat_profiles[$profile])) {
|
||||
echo "Invalid profile passed: " . $profile . PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$extraopts[] = '--profile="' . $profile . '"';
|
||||
// By default, profile tags will be used.
|
||||
if (!empty($CFG->behat_config[$profile]['filters']['tags'])) {
|
||||
|
||||
@@ -173,10 +173,6 @@ if ($options['install']) {
|
||||
|
||||
// This is only displayed once for parallel install.
|
||||
if (empty($options['run'])) {
|
||||
// Notify user that 2.5 profile has been converted to 3.5.
|
||||
if (behat_config_manager::$autoprofileconversion) {
|
||||
mtrace("2.5 behat profile detected, automatically converted to current 3.x format");
|
||||
}
|
||||
|
||||
$runtestscommand = behat_command::get_behat_command(true, !empty($options['run']));
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ Feature: Forms manipulation
|
||||
When I set the field "First name" to "Field value"
|
||||
And I set the field "Select a country" to "Japan"
|
||||
And I set the field "Unmask" to "1"
|
||||
And I expand all fieldsets
|
||||
Then the field "First name" matches value "Field value"
|
||||
And the "Select a country" select box should contain "Japan"
|
||||
And the field "Unmask" matches value "1"
|
||||
|
||||
@@ -142,10 +142,11 @@ class tool_behat_manager_testcase extends advanced_testcase {
|
||||
// YAML decides when is is necessary to wrap strings between single quotes, so not controlled
|
||||
// values like paths should not be asserted including the key name as they would depend on the
|
||||
// directories values.
|
||||
$this->assertContains($CFG->dirroot, $contents);
|
||||
$this->assertContains($CFG->dirroot . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR . 'behat' . DIRECTORY_SEPARATOR . 'features', $contents);
|
||||
|
||||
// Not quoted strings.
|
||||
$this->assertContains('micarro: /me/lo/robaron', $contents);
|
||||
$this->assertContains('class: behat_init_context', $contents);
|
||||
|
||||
// YAML uses single quotes to wrap URL strings.
|
||||
$this->assertContains("base_url: '" . $CFG->behat_wwwroot . "'", $contents);
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
.path-admin-tool-capability .comparisontable tbody th span {display:block;color:#666;font-size:80%;}
|
||||
.path-admin-tool-capability .comparisontable tbody td {border:1px solid #DFDFDF;}
|
||||
|
||||
.path-admin-tool-capability .comparisontable .inherit {color:#666}
|
||||
.path-admin-tool-capability .comparisontable .allow {background-color:#006600;font-weight:bold;color:white;}
|
||||
.path-admin-tool-capability .comparisontable .prevent {background-color:#ad6704;font-weight:bold;color:white;}
|
||||
.path-admin-tool-capability .comparisontable .prohibit {background-color:#880000;font-weight:bold;color:white;}
|
||||
.path-admin-tool-capability .comparisontable .inherit {color:#666;}
|
||||
.path-admin-tool-capability .comparisontable .allow {color:#006600;font-weight:bold;}
|
||||
.path-admin-tool-capability .comparisontable .prevent {color:#ad6704;font-weight:bold;}
|
||||
.path-admin-tool-capability .comparisontable .prohibit {color:#880000;font-weight:bold;}
|
||||
@@ -1,228 +0,0 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Class exposing the api for the cohortroles tool.
|
||||
*
|
||||
* @package tool_cohortroles
|
||||
* @copyright 2015 Damyon Wiese
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
namespace tool_cohortroles;
|
||||
|
||||
use stdClass;
|
||||
use context_system;
|
||||
use core_competency\invalid_persistent_exception;
|
||||
|
||||
/**
|
||||
* Class for doing things with cohort roles.
|
||||
*
|
||||
* @copyright 2015 Damyon Wiese
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class api {
|
||||
|
||||
/**
|
||||
* Create a cohort role assignment from a record containing all the data for the class.
|
||||
*
|
||||
* Requires moodle/role:manage capability at the system context.
|
||||
*
|
||||
* @param stdClass $record Record containing all the data for an instance of the class.
|
||||
* @return competency
|
||||
*/
|
||||
public static function create_cohort_role_assignment(stdClass $record) {
|
||||
$cohortroleassignment = new cohort_role_assignment(0, $record);
|
||||
$context = context_system::instance();
|
||||
|
||||
// First we do a permissions check.
|
||||
require_capability('moodle/role:manage', $context);
|
||||
|
||||
// Validate before we check for existing records.
|
||||
if (!$cohortroleassignment->is_valid()) {
|
||||
throw new invalid_persistent_exception($cohortroleassignment->get_errors());
|
||||
}
|
||||
|
||||
$existing = cohort_role_assignment::get_record((array) $record);
|
||||
if (!empty($existing)) {
|
||||
return false;
|
||||
} else {
|
||||
// OK - all set.
|
||||
$cohortroleassignment->create();
|
||||
}
|
||||
return $cohortroleassignment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a cohort role assignment by id.
|
||||
*
|
||||
* Requires moodle/role:manage capability at the system context.
|
||||
*
|
||||
* @param int $id The record to delete. This will also remove this role from the user for all users in the system.
|
||||
* @return boolean
|
||||
*/
|
||||
public static function delete_cohort_role_assignment($id) {
|
||||
$cohortroleassignment = new cohort_role_assignment($id);
|
||||
$context = context_system::instance();
|
||||
|
||||
// First we do a permissions check.
|
||||
require_capability('moodle/role:manage', $context);
|
||||
|
||||
// OK - all set.
|
||||
return $cohortroleassignment->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a search based on the provided filters and return a paginated list of records.
|
||||
*
|
||||
* Requires moodle/role:manage capability at the system context.
|
||||
*
|
||||
* @param string $sort The column to sort on
|
||||
* @param string $order ('ASC' or 'DESC')
|
||||
* @param int $skip Number of records to skip (pagination)
|
||||
* @param int $limit Max of records to return (pagination)
|
||||
* @return array of cohort_role_assignment
|
||||
*/
|
||||
public static function list_cohort_role_assignments($sort = '', $order = 'ASC', $skip = 0, $limit = 0) {
|
||||
$context = context_system::instance();
|
||||
|
||||
// First we do a permissions check.
|
||||
require_capability('moodle/role:manage', $context);
|
||||
|
||||
// OK - all set.
|
||||
return cohort_role_assignment::get_records(array(), $sort, $order, $skip, $limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a search based on the provided filters and return a paginated list of records.
|
||||
*
|
||||
* Requires moodle/role:manage capability at system context.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function count_cohort_role_assignments() {
|
||||
$context = context_system::instance();
|
||||
|
||||
// First we do a permissions check.
|
||||
require_capability('moodle/role:manage', $context);
|
||||
|
||||
// OK - all set.
|
||||
return cohort_role_assignment::count_records();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sync all roles - adding and deleting role assignments as required.
|
||||
*
|
||||
* Slow. Should only be called from a background task.
|
||||
*
|
||||
* Requires moodle/role:manage capability at the system context.
|
||||
*
|
||||
* @return array('rolesadded' => array of (useridassignedto, useridassignedover, roleid),
|
||||
* 'rolesremoved' => array of (useridassignedto, useridassignedover, roleid))
|
||||
*/
|
||||
public static function sync_all_cohort_roles() {
|
||||
global $DB;
|
||||
|
||||
$context = context_system::instance();
|
||||
|
||||
// First we do a permissions check.
|
||||
require_capability('moodle/role:manage', $context);
|
||||
|
||||
// Ok ready to go.
|
||||
$rolesadded = array();
|
||||
$rolesremoved = array();
|
||||
|
||||
// Get all cohort role assignments and group them by user and role.
|
||||
$all = cohort_role_assignment::get_records(array(), 'userid, roleid');
|
||||
// We build an better structure to loop on.
|
||||
$info = array();
|
||||
foreach ($all as $cra) {
|
||||
if (!isset($info[$cra->get_userid()])) {
|
||||
$info[$cra->get_userid()] = array();
|
||||
}
|
||||
if (!isset($info[$cra->get_userid()][$cra->get_roleid()])) {
|
||||
$info[$cra->get_userid()][$cra->get_roleid()] = array();
|
||||
}
|
||||
array_push($info[$cra->get_userid()][$cra->get_roleid()], $cra->get_cohortid());
|
||||
}
|
||||
// Then for each user+role combo - find user context in the cohort without a role assigned.
|
||||
|
||||
foreach ($info as $userid => $roles) {
|
||||
foreach ($roles as $roleid => $cohorts) {
|
||||
list($cohortsql, $params) = $DB->get_in_or_equal($cohorts, SQL_PARAMS_NAMED);
|
||||
|
||||
$params['usercontext'] = CONTEXT_USER;
|
||||
$params['roleid'] = $roleid;
|
||||
$params['userid'] = $userid;
|
||||
|
||||
$sql = 'SELECT u.id AS userid, ra.id, ctx.id AS contextid
|
||||
FROM {user} u
|
||||
JOIN {cohort_members} cm ON u.id = cm.userid
|
||||
JOIN {context} ctx ON u.id = ctx.instanceid AND ctx.contextlevel = :usercontext
|
||||
LEFT JOIN {role_assignments} ra ON ra.contextid = ctx.id
|
||||
AND ra.roleid = :roleid
|
||||
AND ra.userid = :userid
|
||||
WHERE cm.cohortid ' . $cohortsql . '
|
||||
AND ra.id IS NULL';
|
||||
|
||||
$toadd = $DB->get_records_sql($sql, $params);
|
||||
|
||||
foreach ($toadd as $add) {
|
||||
role_assign($roleid, $userid, $add->contextid, 'tool_cohortroles');
|
||||
$rolesadded[] = array(
|
||||
'useridassignedto' => $userid,
|
||||
'useridassignedover' => $add->userid,
|
||||
'roleid' => $roleid
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// And for each user+role combo - find user context not in the cohort with a role assigned.
|
||||
// If the role was assigned by this component, unassign the role.
|
||||
foreach ($info as $userid => $roles) {
|
||||
foreach ($roles as $roleid => $cohorts) {
|
||||
// Now we are looking for entries NOT in the cohort.
|
||||
list($cohortsql, $params) = $DB->get_in_or_equal($cohorts, SQL_PARAMS_NAMED);
|
||||
|
||||
$params['usercontext'] = CONTEXT_USER;
|
||||
$params['roleid'] = $roleid;
|
||||
$params['userid'] = $userid;
|
||||
$params['component'] = 'tool_cohortroles';
|
||||
|
||||
$sql = 'SELECT u.id as userid, ra.id, ctx.id AS contextid
|
||||
FROM {user} u
|
||||
JOIN {context} ctx ON u.id = ctx.instanceid AND ctx.contextlevel = :usercontext
|
||||
JOIN {role_assignments} ra ON ra.contextid = ctx.id AND ra.roleid = :roleid AND ra.userid = :userid
|
||||
LEFT JOIN {cohort_members} cm ON u.id = cm.userid
|
||||
AND cm.cohortid ' . $cohortsql . '
|
||||
WHERE ra.component = :component AND cm.cohortid IS NULL';
|
||||
|
||||
$toremove = $DB->get_records_sql($sql, $params);
|
||||
foreach ($toremove as $remove) {
|
||||
role_unassign($roleid, $userid, $remove->contextid, 'tool_cohortroles');
|
||||
$rolesremoved[] = array(
|
||||
'useridassignedto' => $userid,
|
||||
'useridassignedover' => $remove->userid,
|
||||
'roleid' => $roleid
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array('rolesadded' => $rolesadded, 'rolesremoved' => $rolesremoved);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Class for cohort_role_assignment persistence.
|
||||
*
|
||||
* @package tool_cohortroles
|
||||
* @copyright 2015 Damyon Wiese
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
namespace tool_cohortroles;
|
||||
|
||||
use lang_string;
|
||||
use core_competency\persistent;
|
||||
|
||||
/**
|
||||
* Class for loading/storing cohort_role_assignments from the DB.
|
||||
*
|
||||
* @copyright 2015 Damyon Wiese
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class cohort_role_assignment extends persistent {
|
||||
|
||||
/** Table name for user_competency persistency */
|
||||
const TABLE = 'tool_cohortroles';
|
||||
|
||||
/**
|
||||
* Return the definition of the properties of this model.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected static function define_properties() {
|
||||
return array(
|
||||
'userid' => array(
|
||||
'type' => PARAM_INT,
|
||||
),
|
||||
'roleid' => array(
|
||||
'type' => PARAM_INT,
|
||||
),
|
||||
'cohortid' => array(
|
||||
'type' => PARAM_INT,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the user ID.
|
||||
*
|
||||
* @param int $value The value.
|
||||
* @return true|lang_string
|
||||
*/
|
||||
protected function validate_userid($value) {
|
||||
global $DB;
|
||||
|
||||
if (!$DB->record_exists('user', array('id' => $value))) {
|
||||
return new lang_string('invaliduserid', 'error');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the role ID.
|
||||
*
|
||||
* @param int $value The value.
|
||||
* @return true|lang_string
|
||||
*/
|
||||
protected function validate_roleid($value) {
|
||||
global $DB;
|
||||
|
||||
if (!$DB->record_exists('role', array('id' => $value))) {
|
||||
return new lang_string('invalidroleid', 'error');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the cohort ID.
|
||||
*
|
||||
* @param int $value The value.
|
||||
* @return true|lang_string
|
||||
*/
|
||||
protected function validate_cohortid($value) {
|
||||
global $DB;
|
||||
|
||||
if (!$DB->record_exists('cohort', array('id' => $value))) {
|
||||
return new lang_string('invalidcohortid', 'error');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Assign role to cohort form.
|
||||
*
|
||||
* @package tool_cohortroles
|
||||
* @copyright 2015 Damyon Wiese
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace tool_cohortroles\form;
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
use moodleform;
|
||||
use context_system;
|
||||
|
||||
require_once($CFG->libdir . '/formslib.php');
|
||||
|
||||
/**
|
||||
* Assign role to cohort form.
|
||||
*
|
||||
* @package tool_cohortroles
|
||||
* @copyright 2015 Damyon Wiese
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class assign_role_cohort extends moodleform {
|
||||
|
||||
/**
|
||||
* Form definition.
|
||||
*/
|
||||
public function definition() {
|
||||
global $PAGE;
|
||||
|
||||
$mform = $this->_form;
|
||||
$roles = get_roles_for_contextlevels(CONTEXT_USER);
|
||||
|
||||
if (empty($roles)) {
|
||||
$output = $PAGE->get_renderer('tool_cohortroles');
|
||||
$warning = $output->notify_problem(get_string('noassignableroles', 'tool_cohortroles'));
|
||||
$mform->addElement('html', $warning);
|
||||
return;
|
||||
}
|
||||
|
||||
$options = array(
|
||||
'ajax' => 'tool_lp/form-user-selector',
|
||||
'multiple' => true
|
||||
);
|
||||
$mform->addElement('autocomplete', 'userids', get_string('selectusers', 'tool_cohortroles'), array(), $options);
|
||||
$mform->addRule('userids', null, 'required');
|
||||
|
||||
$names = role_get_names();
|
||||
$options = array();
|
||||
foreach ($roles as $idx => $roleid) {
|
||||
$options[$roleid] = $names[$roleid]->localname;
|
||||
}
|
||||
|
||||
$mform->addElement('select', 'roleid', get_string('selectrole', 'tool_cohortroles'), $options);
|
||||
$mform->addRule('roleid', null, 'required');
|
||||
|
||||
$context = context_system::instance();
|
||||
$options = array(
|
||||
'ajax' => 'tool_lp/form-cohort-selector',
|
||||
'multiple' => true,
|
||||
'data-contextid' => $context->id,
|
||||
'data-includes' => 'all'
|
||||
);
|
||||
$mform->addElement('autocomplete', 'cohortids', get_string('selectcohorts', 'tool_cohortroles'), array(), $options);
|
||||
$mform->addRule('cohortids', null, 'required');
|
||||
$mform->addElement('submit', 'submit', get_string('assign', 'tool_cohortroles'));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,231 +0,0 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Cohort role assignments table
|
||||
*
|
||||
* @package tool_cohortroles
|
||||
* @copyright 2015 Damyon Wiese
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace tool_cohortroles\output;
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
require_once($CFG->libdir . '/tablelib.php');
|
||||
|
||||
use context_helper;
|
||||
use context_system;
|
||||
use html_writer;
|
||||
use moodle_url;
|
||||
use table_sql;
|
||||
|
||||
/**
|
||||
* Cohort role assignments table.
|
||||
*
|
||||
* @package tool_cohortroles
|
||||
* @copyright 2015 Damyon Wiese
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class cohort_role_assignments_table extends table_sql {
|
||||
|
||||
/**
|
||||
* Sets up the table.
|
||||
*
|
||||
* @param string $uniqueid Unique id of table.
|
||||
* @param moodle_url $url The base URL.
|
||||
*/
|
||||
public function __construct($uniqueid, $url) {
|
||||
global $CFG;
|
||||
parent::__construct($uniqueid);
|
||||
$context = context_system::instance();
|
||||
|
||||
$this->context = $context;
|
||||
|
||||
$this->rolenames = role_get_names();
|
||||
|
||||
// This object should not be used without the right permissions.
|
||||
require_capability('moodle/role:manage', $context);
|
||||
|
||||
$this->useridfield = 'userid';
|
||||
|
||||
// Define columns in the table.
|
||||
$this->define_table_columns();
|
||||
|
||||
$this->define_baseurl($url);
|
||||
// Define configs.
|
||||
$this->define_table_configs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Role name column.
|
||||
*
|
||||
* @param array $data Row data.
|
||||
* @return string
|
||||
*/
|
||||
protected function col_rolename($data) {
|
||||
return $this->rolenames[$data->roleid]->localname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cohort name column.
|
||||
*
|
||||
* @param array $data Row data.
|
||||
* @return string
|
||||
*/
|
||||
protected function col_cohortname($data) {
|
||||
global $OUTPUT;
|
||||
|
||||
$record = (object) array(
|
||||
'id' => $data->cohortid,
|
||||
'idnumber' => $data->cohortidnumber,
|
||||
'description' => $data->cohortdescription,
|
||||
'visible' => $data->cohortvisible,
|
||||
'name' => $data->cohortname
|
||||
);
|
||||
$context = context_helper::instance_by_id($data->cohortcontextid);
|
||||
|
||||
$exporter = new \tool_lp\external\cohort_summary_exporter($record, array('context' => $context));
|
||||
$cohort = $exporter->export($OUTPUT);
|
||||
|
||||
$html = $OUTPUT->render_from_template('tool_cohortroles/cohort-in-list', $cohort);
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Actions column.
|
||||
*
|
||||
* @param array $data Row data.
|
||||
* @return string
|
||||
*/
|
||||
protected function col_actions($data) {
|
||||
global $OUTPUT;
|
||||
|
||||
$action = new \confirm_action(get_string('removecohortroleassignmentconfirm', 'tool_cohortroles'));
|
||||
$url = new moodle_url($this->baseurl);
|
||||
$url->params(array('removecohortroleassignment' => $data->id, 'sesskey' => sesskey()));
|
||||
$pix = new \pix_icon('t/delete', get_string('removecohortroleassignment', 'tool_cohortroles'));
|
||||
return $OUTPUT->action_link($url, '', $action, null, $pix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the headers for the table.
|
||||
*/
|
||||
protected function define_table_columns() {
|
||||
$extrafields = get_extra_user_fields($this->context);
|
||||
|
||||
// Define headers and columns.
|
||||
$cols = array(
|
||||
'cohortname' => get_string('cohort', 'cohort'),
|
||||
'rolename' => get_string('role'),
|
||||
'fullname' => get_string('name'),
|
||||
);
|
||||
|
||||
// Add headers for extra user fields.
|
||||
foreach ($extrafields as $field) {
|
||||
if (get_string_manager()->string_exists($field, 'moodle')) {
|
||||
$cols[$field] = get_string($field);
|
||||
} else {
|
||||
$cols[$field] = $field;
|
||||
}
|
||||
}
|
||||
|
||||
// Add remaining headers.
|
||||
$cols = array_merge($cols, array('actions' => get_string('actions')));
|
||||
|
||||
$this->define_columns(array_keys($cols));
|
||||
$this->define_headers(array_values($cols));
|
||||
}
|
||||
|
||||
/**
|
||||
* Define table configs.
|
||||
*/
|
||||
protected function define_table_configs() {
|
||||
$this->collapsible(false);
|
||||
$this->sortable(true, 'lastname', SORT_ASC);
|
||||
$this->pageable(true);
|
||||
$this->no_sorting('actions');
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the SQL query.
|
||||
*
|
||||
* @param bool $count When true, return the count SQL.
|
||||
* @return array containing sql to use and an array of params.
|
||||
*/
|
||||
protected function get_sql_and_params($count = false) {
|
||||
$fields = 'uca.id, uca.cohortid, uca.userid, uca.roleid, ';
|
||||
$fields .= 'c.name as cohortname, c.idnumber as cohortidnumber, c.contextid as cohortcontextid, ';
|
||||
$fields .= 'c.visible as cohortvisible, c.description as cohortdescription, ';
|
||||
|
||||
// Add extra user fields that we need for the graded user.
|
||||
$extrafields = get_extra_user_fields($this->context);
|
||||
foreach ($extrafields as $field) {
|
||||
$fields .= 'u.' . $field . ', ';
|
||||
}
|
||||
$fields .= get_all_user_name_fields(true, 'u');
|
||||
|
||||
if ($count) {
|
||||
$select = "COUNT(1)";
|
||||
} else {
|
||||
$select = "$fields";
|
||||
}
|
||||
|
||||
$sql = "SELECT $select
|
||||
FROM {tool_cohortroles} uca
|
||||
JOIN {user} u ON u.id = uca.userid
|
||||
JOIN {cohort} c ON c.id = uca.cohortid";
|
||||
$params = array();
|
||||
|
||||
// Add order by if needed.
|
||||
if (!$count && $sqlsort = $this->get_sql_sort()) {
|
||||
$sql .= " ORDER BY " . $sqlsort;
|
||||
}
|
||||
|
||||
return array($sql, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the default implementation to set a decent heading level.
|
||||
*/
|
||||
public function print_nothing_to_display() {
|
||||
global $OUTPUT;
|
||||
echo $this->render_reset_button();
|
||||
$this->print_initials_bar();
|
||||
echo $OUTPUT->heading(get_string('nothingtodisplay'), 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query the DB.
|
||||
*
|
||||
* @param int $pagesize size of page for paginated displayed table.
|
||||
* @param bool $useinitialsbar do you want to use the initials bar.
|
||||
*/
|
||||
public function query_db($pagesize, $useinitialsbar = true) {
|
||||
global $DB;
|
||||
|
||||
list($countsql, $countparams) = $this->get_sql_and_params(true);
|
||||
list($sql, $params) = $this->get_sql_and_params();
|
||||
$total = $DB->count_records_sql($countsql, $countparams);
|
||||
$this->pagesize($pagesize, $total);
|
||||
$this->rawdata = $DB->get_records_sql($sql, $params, $this->get_page_start(), $this->get_page_size());
|
||||
|
||||
// Set initial bars.
|
||||
if ($useinitialsbar) {
|
||||
$this->initialbars($total > $pagesize);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Renderer class for cohort roles
|
||||
*
|
||||
* @package tool_cohortroles
|
||||
* @copyright 2016 Issam Taboubi <issam.taboubi@umontreal.ca>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace tool_cohortroles\output;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
use plugin_renderer_base;
|
||||
use renderable;
|
||||
|
||||
/**
|
||||
* Renderer class for cohort roles
|
||||
*
|
||||
* @package tool_cohortroles
|
||||
* @copyright 2016 Issam Taboubi <issam.taboubi@umontreal.ca>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class renderer extends plugin_renderer_base {
|
||||
|
||||
/**
|
||||
* Output a nofication.
|
||||
*
|
||||
* @param string $message the message to print out
|
||||
* @return string HTML fragment.
|
||||
* @see \core\output\notification
|
||||
*/
|
||||
public function notify_message($message) {
|
||||
$n = new \core\output\notification($message, \core\output\notification::NOTIFY_INFO);
|
||||
return $this->render($n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Output an error notification.
|
||||
*
|
||||
* @param string $message the message to print out
|
||||
* @return string HTML fragment.
|
||||
* @see \core\output\notification
|
||||
*/
|
||||
public function notify_problem($message) {
|
||||
$n = new \core\output\notification($message, \core\output\notification::NOTIFY_ERROR);
|
||||
return $this->render($n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Output a success notification.
|
||||
*
|
||||
* @param string $message the message to print out
|
||||
* @return string HTML fragment.
|
||||
* @see \core\output\notification
|
||||
*/
|
||||
public function notify_success($message) {
|
||||
$n = new \core\output\notification($message, \core\output\notification::NOTIFY_SUCCESS);
|
||||
return $this->render($n);
|
||||
}
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Scheduled task for syncing cohort roles.
|
||||
*
|
||||
* @package tool_cohortroles
|
||||
* @copyright 2015 Damyon Wiese
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
namespace tool_cohortroles\task;
|
||||
|
||||
use core\task\scheduled_task;
|
||||
use tool_cohortroles\api;
|
||||
|
||||
/**
|
||||
* Scheduled task for syncing cohort roles.
|
||||
*
|
||||
* @copyright 2015 Damyon Wiese
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class cohort_role_sync extends scheduled_task {
|
||||
|
||||
/**
|
||||
* Get name.
|
||||
* @return string
|
||||
*/
|
||||
public function get_name() {
|
||||
// Shown in admin screens.
|
||||
return get_string('taskname', 'tool_cohortroles');
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute.
|
||||
*/
|
||||
public function execute() {
|
||||
mtrace('Sync cohort roles...');
|
||||
$result = api::sync_all_cohort_roles();
|
||||
|
||||
mtrace('Added ' . count($result['rolesadded']));
|
||||
mtrace('Removed ' . count($result['rolesremoved']));
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<XMLDB PATH="admin/tool/cohortroles/db" VERSION="20151201" COMMENT="XMLDB file for Moodle admin/tool/cohortroles"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="../../../../lib/xmldb/xmldb.xsd"
|
||||
>
|
||||
<TABLES>
|
||||
<TABLE NAME="tool_cohortroles" COMMENT="Mapping of users to cohort role assignments.">
|
||||
<FIELDS>
|
||||
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
|
||||
<FIELD NAME="cohortid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="The cohort to sync"/>
|
||||
<FIELD NAME="roleid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="The role to assign"/>
|
||||
<FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="The user to sync"/>
|
||||
<FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="The time this record was created"/>
|
||||
<FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="The time this record was modified."/>
|
||||
<FIELD NAME="usermodified" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false" COMMENT="Who last modified this record?"/>
|
||||
</FIELDS>
|
||||
<KEYS>
|
||||
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
|
||||
</KEYS>
|
||||
<INDEXES>
|
||||
<INDEX NAME="cohortuserrole" UNIQUE="true" FIELDS="cohortid, roleid, userid"/>
|
||||
</INDEXES>
|
||||
</TABLE>
|
||||
</TABLES>
|
||||
</XMLDB>
|
||||
@@ -1,37 +0,0 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Tasks definitions.
|
||||
*
|
||||
* @package tool_cohortroles
|
||||
* @copyright 2015 Damyon Wiese
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$tasks = array(
|
||||
array(
|
||||
'classname' => 'tool_cohortroles\task\cohort_role_sync',
|
||||
'blocking' => 0,
|
||||
'minute' => 'R',
|
||||
'hour' => '*',
|
||||
'day' => '*',
|
||||
'dayofweek' => '*',
|
||||
'month' => '*'
|
||||
),
|
||||
);
|
||||
@@ -1,98 +0,0 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Assign roles for a user.
|
||||
*
|
||||
* @package tool_cohortroles
|
||||
* @copyright 2015 Damyon Wiese
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
require_once(dirname(__FILE__) . '/../../../config.php');
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
require_once($CFG->libdir.'/tablelib.php');
|
||||
|
||||
$removeid = optional_param('removecohortroleassignment', 0, PARAM_INT);
|
||||
|
||||
admin_externalpage_setup('toolcohortroles');
|
||||
$context = context_system::instance();
|
||||
|
||||
$pageurl = new moodle_url('/admin/tool/cohortroles/index.php');
|
||||
|
||||
$output = $PAGE->get_renderer('tool_cohortroles');
|
||||
|
||||
echo $output->header();
|
||||
$title = get_string('assignroletocohort', 'tool_cohortroles');
|
||||
echo $output->heading($title);
|
||||
|
||||
$form = new tool_cohortroles\form\assign_role_cohort();
|
||||
|
||||
if ($removeid) {
|
||||
require_sesskey();
|
||||
|
||||
$result = \tool_cohortroles\api::delete_cohort_role_assignment($removeid);
|
||||
if ($result) {
|
||||
$notification = get_string('cohortroleassignmentremoved', 'tool_cohortroles');
|
||||
echo $output->notify_success($notification);
|
||||
} else {
|
||||
$notification = get_string('cohortroleassignmentnotremoved', 'tool_cohortroles');
|
||||
echo $output->notify_problem($notification);
|
||||
}
|
||||
echo $output->continue_button(new moodle_url($pageurl));
|
||||
} else if ($data = $form->get_data()) {
|
||||
require_sesskey();
|
||||
// We must create them all or none.
|
||||
$saved = 0;
|
||||
// Loop through userids and cohortids only if both of them are not empty.
|
||||
if (!empty($data->userids) && !empty($data->cohortids)) {
|
||||
foreach ($data->userids as $userid) {
|
||||
foreach ($data->cohortids as $cohortid) {
|
||||
$params = (object) array('userid' => $userid, 'cohortid' => $cohortid, 'roleid' => $data->roleid);
|
||||
$result = \tool_cohortroles\api::create_cohort_role_assignment($params);
|
||||
if ($result) {
|
||||
$saved++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($saved == 0) {
|
||||
$notification = get_string('nocohortroleassignmentssaved', 'tool_cohortroles');
|
||||
echo $output->notify_problem($notification);
|
||||
} else if ($saved == 1) {
|
||||
$notification = get_string('onecohortroleassignmentsaved', 'tool_cohortroles');
|
||||
echo $output->notify_success($notification);
|
||||
} else {
|
||||
$notification = get_string('acohortroleassignmentssaved', 'tool_cohortroles', $saved);
|
||||
echo $output->notify_success($notification);
|
||||
}
|
||||
|
||||
echo $output->continue_button(new moodle_url($pageurl));
|
||||
} else {
|
||||
$form->display();
|
||||
|
||||
$title = get_string('existingcohortroles', 'tool_cohortroles');
|
||||
echo $output->heading($title);
|
||||
$url = new moodle_url('/admin/tool/cohortroles/index.php');
|
||||
$table = new tool_cohortroles\output\cohort_role_assignments_table(uniqid(), $url);
|
||||
echo $table->out(50, true);
|
||||
|
||||
echo $output->spacer();
|
||||
echo $output->notify_message(get_string('backgroundsync', 'tool_cohortroles'));
|
||||
}
|
||||
|
||||
echo $output->footer();
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Strings for component 'tool_userroles', language 'en'
|
||||
*
|
||||
* @package tool_cohortroles
|
||||
* @copyright 2015 Damyon Wiese
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
$string['acohortroleassignmentssaved'] = '{$a} cohort role assignments were saved.';
|
||||
$string['assign'] = 'Assign';
|
||||
$string['assignroletocohort'] = 'Assign role to users in the context of all members of these cohorts';
|
||||
$string['backgroundsync'] = 'Note: Roles assigned on this page will not take affect immediately, the changes to role assignments will be made by a background task.';
|
||||
$string['cohortroleassignmentremoved'] = 'The cohort role assignment was removed.';
|
||||
$string['cohortroleassignmentnotremoved'] = 'The cohort role assignment was not removed.';
|
||||
$string['cohortroles'] = 'Cohort roles';
|
||||
$string['existingcohortroles'] = 'Existing cohort role assignments';
|
||||
$string['managecohortroles'] = 'Assign user roles for entire cohort';
|
||||
$string['noassignableroles'] = 'No roles can be assigned at a user context level. <a href="../../roles/manage.php">Manage roles</a>';
|
||||
$string['nocohortroleassignmentssaved'] = 'No cohort role assignments were saved.';
|
||||
$string['onecohortroleassignmentsaved'] = 'One cohort role assignment was saved.';
|
||||
$string['pluginname'] = 'Cohort roles management';
|
||||
$string['removecohortroleassignment'] = 'Remove cohort role assignment';
|
||||
$string['removecohortroleassignmentconfirm'] = 'Are you sure you want to remove this cohort role assignment? This role will be removed for this user in all other user contexts.';
|
||||
$string['selectcohorts'] = 'Select cohorts';
|
||||
$string['selectrole'] = 'Select role';
|
||||
$string['selectusers'] = 'Select users to assign role';
|
||||
$string['taskname'] = 'Sync cohort role assignments';
|
||||
$string['thisuserroles'] = 'Roles assigned relative to this user';
|
||||
@@ -1,42 +0,0 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Link to user roles management.
|
||||
*
|
||||
* @package tool_cohortroles
|
||||
* @copyright 2015 Damyon Wiese
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die;
|
||||
|
||||
// This tool's required capabilities.
|
||||
$capabilities = [
|
||||
'moodle/cohort:view',
|
||||
'moodle/role:manage'
|
||||
];
|
||||
|
||||
// Check if the user has all of the required capabilities.
|
||||
$context = context_system::instance();
|
||||
$hasaccess = has_all_capabilities($capabilities, $context);
|
||||
|
||||
// Add this admin page only if the user has all of the required capabilities.
|
||||
if ($hasaccess) {
|
||||
$str = get_string('managecohortroles', 'tool_cohortroles');
|
||||
$url = new moodle_url('/admin/tool/cohortroles/index.php');
|
||||
$ADMIN->add('roles', new admin_externalpage('toolcohortroles', $str, $url, $capabilities));
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
{{!
|
||||
This file is part of Moodle - http://moodle.org/
|
||||
|
||||
Moodle is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Moodle is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
}}
|
||||
{{!
|
||||
@template tool_cohortroles/cohort-in-list
|
||||
|
||||
Moodle template for displaying a cohort in a list.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* none
|
||||
|
||||
Context variables required for this template:
|
||||
* id cohort id field
|
||||
* name cohort name field
|
||||
* idnumber cohort idnumber field
|
||||
* description cohort description field
|
||||
* visible cohort visible field
|
||||
|
||||
Example context (json):
|
||||
{ "id": "1",
|
||||
"name": "Cohort 1",
|
||||
"visible": true,
|
||||
"idnumber": "014",
|
||||
"description": "Some users"
|
||||
}
|
||||
}}
|
||||
{{> tool_lp/form-cohort-selector-suggestion }}
|
||||
@@ -1,243 +0,0 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* API tests.
|
||||
*
|
||||
* @package tool_cohortroles
|
||||
* @copyright 2015 Damyon Wiese
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
use tool_cohortroles\api;
|
||||
|
||||
/**
|
||||
* API tests.
|
||||
*
|
||||
* @package tool_cohortroles
|
||||
* @copyright 2015 Damyon Wiese
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class tool_cohortroles_api_testcase extends advanced_testcase {
|
||||
/** @var stdClass $cohort */
|
||||
protected $cohort = null;
|
||||
|
||||
/** @var stdClass $userassignto */
|
||||
protected $userassignto = null;
|
||||
|
||||
/** @var stdClass $userassignover */
|
||||
protected $userassignover = null;
|
||||
|
||||
/** @var stdClass $role */
|
||||
protected $role = null;
|
||||
|
||||
/**
|
||||
* Setup function- we will create a course and add an assign instance to it.
|
||||
*/
|
||||
protected function setUp() {
|
||||
global $DB;
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
// Create some users.
|
||||
$this->cohort = $this->getDataGenerator()->create_cohort();
|
||||
$this->userassignto = $this->getDataGenerator()->create_user();
|
||||
$this->userassignover = $this->getDataGenerator()->create_user();
|
||||
$this->roleid = create_role('Sausage Roll', 'sausageroll', 'mmmm');
|
||||
cohort_add_member($this->cohort->id, $this->userassignover->id);
|
||||
}
|
||||
|
||||
|
||||
public function test_create_cohort_role_assignment_without_permission() {
|
||||
$this->setExpectedException('required_capability_exception');
|
||||
$this->setUser($this->userassignto);
|
||||
$params = (object) array(
|
||||
'userid' => $this->userassignto->id,
|
||||
'roleid' => $this->roleid,
|
||||
'cohortid' => $this->cohort->id
|
||||
);
|
||||
api::create_cohort_role_assignment($params);
|
||||
}
|
||||
|
||||
public function test_create_cohort_role_assignment_with_invalid_data() {
|
||||
$this->setExpectedException('core_competency\invalid_persistent_exception');
|
||||
$this->setAdminUser();
|
||||
$params = (object) array(
|
||||
'userid' => $this->userassignto->id,
|
||||
'roleid' => -8,
|
||||
'cohortid' => $this->cohort->id
|
||||
);
|
||||
api::create_cohort_role_assignment($params);
|
||||
}
|
||||
|
||||
public function test_create_cohort_role_assignment() {
|
||||
$this->setAdminUser();
|
||||
$params = (object) array(
|
||||
'userid' => $this->userassignto->id,
|
||||
'roleid' => $this->roleid,
|
||||
'cohortid' => $this->cohort->id
|
||||
);
|
||||
$result = api::create_cohort_role_assignment($params);
|
||||
$this->assertNotEmpty($result->get_id());
|
||||
$this->assertEquals($result->get_userid(), $this->userassignto->id);
|
||||
$this->assertEquals($result->get_roleid(), $this->roleid);
|
||||
$this->assertEquals($result->get_cohortid(), $this->cohort->id);
|
||||
}
|
||||
|
||||
public function test_delete_cohort_role_assignment_without_permission() {
|
||||
$this->setAdminUser();
|
||||
$params = (object) array(
|
||||
'userid' => $this->userassignto->id,
|
||||
'roleid' => $this->roleid,
|
||||
'cohortid' => $this->cohort->id
|
||||
);
|
||||
$result = api::create_cohort_role_assignment($params);
|
||||
$this->setExpectedException('required_capability_exception');
|
||||
$this->setUser($this->userassignto);
|
||||
api::delete_cohort_role_assignment($result->get_id());
|
||||
}
|
||||
|
||||
public function test_delete_cohort_role_assignment_with_invalid_data() {
|
||||
$this->setAdminUser();
|
||||
$params = (object) array(
|
||||
'userid' => $this->userassignto->id,
|
||||
'roleid' => $this->roleid,
|
||||
'cohortid' => $this->cohort->id
|
||||
);
|
||||
$result = api::create_cohort_role_assignment($params);
|
||||
$this->setExpectedException('dml_missing_record_exception');
|
||||
api::delete_cohort_role_assignment($result->get_id() + 1);
|
||||
}
|
||||
|
||||
public function test_delete_cohort_role_assignment() {
|
||||
$this->setAdminUser();
|
||||
$params = (object) array(
|
||||
'userid' => $this->userassignto->id,
|
||||
'roleid' => $this->roleid,
|
||||
'cohortid' => $this->cohort->id
|
||||
);
|
||||
$result = api::create_cohort_role_assignment($params);
|
||||
$worked = api::delete_cohort_role_assignment($result->get_id());
|
||||
$this->assertTrue($worked);
|
||||
}
|
||||
|
||||
public function test_list_cohort_role_assignments() {
|
||||
$this->setAdminUser();
|
||||
$params = (object) array(
|
||||
'userid' => $this->userassignto->id,
|
||||
'roleid' => $this->roleid,
|
||||
'cohortid' => $this->cohort->id
|
||||
);
|
||||
$result = api::create_cohort_role_assignment($params);
|
||||
|
||||
$list = api::list_cohort_role_assignments();
|
||||
$list[0]->is_valid();
|
||||
$this->assertEquals($list[0], $result);
|
||||
}
|
||||
|
||||
public function test_count_cohort_role_assignments() {
|
||||
$this->setAdminUser();
|
||||
$params = (object) array(
|
||||
'userid' => $this->userassignto->id,
|
||||
'roleid' => $this->roleid,
|
||||
'cohortid' => $this->cohort->id
|
||||
);
|
||||
$result = api::create_cohort_role_assignment($params);
|
||||
|
||||
$count = api::count_cohort_role_assignments();
|
||||
$this->assertEquals($count, 1);
|
||||
}
|
||||
|
||||
public function test_sync_all_cohort_roles() {
|
||||
$this->setAdminUser();
|
||||
$params = (object) array(
|
||||
'userid' => $this->userassignto->id,
|
||||
'roleid' => $this->roleid,
|
||||
'cohortid' => $this->cohort->id
|
||||
);
|
||||
$result = api::create_cohort_role_assignment($params);
|
||||
|
||||
// Verify roles are assigned when users enter the cohort.
|
||||
$sync = api::sync_all_cohort_roles();
|
||||
|
||||
$rolesadded = array(array(
|
||||
'useridassignedto' => $this->userassignto->id,
|
||||
'useridassignedover' => $this->userassignover->id,
|
||||
'roleid' => $this->roleid
|
||||
));
|
||||
$rolesremoved = array();
|
||||
$expected = array('rolesadded' => $rolesadded,
|
||||
'rolesremoved' => $rolesremoved);
|
||||
$this->assertEquals($sync, $expected);
|
||||
|
||||
// Verify roles are removed when users leave the cohort.
|
||||
cohort_remove_member($this->cohort->id, $this->userassignover->id);
|
||||
$sync = api::sync_all_cohort_roles();
|
||||
|
||||
$rolesadded = array();
|
||||
$rolesremoved = array(array(
|
||||
'useridassignedto' => $this->userassignto->id,
|
||||
'useridassignedover' => $this->userassignover->id,
|
||||
'roleid' => $this->roleid
|
||||
));
|
||||
$expected = array('rolesadded' => $rolesadded,
|
||||
'rolesremoved' => $rolesremoved);
|
||||
$this->assertEquals($sync, $expected);
|
||||
|
||||
// Verify roles assigned by any other component are not removed.
|
||||
$usercontext = context_user::instance($this->userassignover->id);
|
||||
role_assign($this->roleid, $this->userassignto->id, $usercontext->id);
|
||||
$sync = api::sync_all_cohort_roles();
|
||||
|
||||
$rolesadded = array();
|
||||
$rolesremoved = array();
|
||||
$expected = array('rolesadded' => $rolesadded,
|
||||
'rolesremoved' => $rolesremoved);
|
||||
$this->assertEquals($sync, $expected);
|
||||
|
||||
// Remove manual role assignment.
|
||||
role_unassign($this->roleid, $this->userassignto->id, $usercontext->id);
|
||||
// Add someone to the cohort again...
|
||||
cohort_add_member($this->cohort->id, $this->userassignover->id);
|
||||
$sync = api::sync_all_cohort_roles();
|
||||
$rolesadded = array(array(
|
||||
'useridassignedto' => $this->userassignto->id,
|
||||
'useridassignedover' => $this->userassignover->id,
|
||||
'roleid' => $this->roleid
|
||||
));
|
||||
$rolesremoved = array();
|
||||
$expected = array('rolesadded' => $rolesadded,
|
||||
'rolesremoved' => $rolesremoved);
|
||||
$this->assertEquals($sync, $expected);
|
||||
|
||||
// Verify no fatal errors when a cohort is deleted.
|
||||
cohort_delete_cohort($this->cohort);
|
||||
$sync = api::sync_all_cohort_roles();
|
||||
|
||||
$rolesadded = array();
|
||||
$rolesremoved = array(array(
|
||||
'useridassignedto' => $this->userassignto->id,
|
||||
'useridassignedover' => $this->userassignover->id,
|
||||
'roleid' => $this->roleid
|
||||
));
|
||||
$expected = array('rolesadded' => $rolesadded,
|
||||
'rolesremoved' => $rolesremoved);
|
||||
$this->assertEquals($sync, $expected);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Plugin version info
|
||||
*
|
||||
* @package tool_cohortroles
|
||||
* @copyright 2015 Damyon Wiese
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
|
||||
$plugin->version = 2015111018; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2014110400; // Requires this Moodle version.
|
||||
$plugin->component = 'tool_cohortroles'; // Full name of the plugin (used for diagnostics).
|
||||
|
||||
$plugin->dependencies = array(
|
||||
'tool_lp' => ANY_VERSION
|
||||
);
|
||||
@@ -24,10 +24,29 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
function xmldb_tool_customlang_upgrade($oldversion) {
|
||||
global $CFG;
|
||||
global $CFG, $DB, $OUTPUT;
|
||||
|
||||
$dbman = $DB->get_manager();
|
||||
|
||||
|
||||
// Moodle v2.3.0 release upgrade line
|
||||
// Put any upgrade step following this
|
||||
|
||||
|
||||
// Moodle v2.4.0 release upgrade line
|
||||
// Put any upgrade step following this
|
||||
|
||||
|
||||
// Moodle v2.5.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
|
||||
// Moodle v2.6.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Moodle v2.7.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Moodle v2.8.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
|
Before Width: | Height: | Size: 67 B After Width: | Height: | Size: 67 B |
|
Before Width: | Height: | Size: 67 B After Width: | Height: | Size: 67 B |
|
Before Width: | Height: | Size: 207 B After Width: | Height: | Size: 266 B |
@@ -1,3 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 15.1.0, SVG Export Plug-In -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
|
||||
<!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
|
||||
]><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" preserveAspectRatio="xMinYMid meet" overflow="visible"><path d="M16 9v6c0 .5-.5 1-1 1H1c-.5 0-1-.5-1-1V9c0-.5.5-1 1-1h1c.5 0 1 .5 1 1v4h10V9c0-.5.5-1 1-1h1c.5 0 1 .5 1 1zm-3.6-3.9l-.7-.7c-.4-.4-1-.4-1.4 0l-.8.8V1c0-.5-.4-1-1-1h-1c-.5 0-1 .5-1 1v4.2l-.8-.8c-.4-.4-1-.4-1.4 0l-.7.7c-.4.4-.4 1 0 1.4l3.7 3.7c.2.2.5.3.7.3.3 0 .5-.1.7-.3l3.7-3.7c.4-.3.4-1 0-1.4z" fill="#999"/></svg>
|
||||
]>
|
||||
<svg version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
|
||||
x="0px" y="0px" width="16px" height="16px" viewBox="0 0 16 16" style="overflow:visible;enable-background:new 0 0 16 16;"
|
||||
xml:space="preserve" preserveAspectRatio="xMinYMid meet">
|
||||
<defs>
|
||||
</defs>
|
||||
<path style="fill:#999999;" d="M16,9v6c0,0.5-0.5,1-1,1h-1H2H1c-0.5,0-1-0.5-1-1V9c0-0.5,0.5-1,1-1h1c0.5,0,1,0.5,1,1v4h10V9
|
||||
c0-0.5,0.5-1,1-1h1C15.5,8,16,8.5,16,9z M12.4,5.1l-0.7-0.7c-0.4-0.4-1-0.4-1.4,0L9.5,5.2V1c0-0.5-0.4-1-1-1h-1c-0.5,0-1,0.5-1,1
|
||||
v4.2L5.7,4.4C5.3,4,4.7,4,4.3,4.4L3.6,5.1c-0.4,0.4-0.4,1,0,1.4l3.7,3.7c0.2,0.2,0.5,0.3,0.7,0.3c0.3,0,0.5-0.1,0.7-0.3l3.7-3.7
|
||||
C12.8,6.2,12.8,5.5,12.4,5.1z"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 618 B After Width: | Height: | Size: 1.0 KiB |
@@ -13,10 +13,10 @@ Feature: Manage language packs
|
||||
Scenario: Install language pack
|
||||
Given I log in as "admin"
|
||||
And I navigate to "Language packs" node in "Site administration > Language"
|
||||
When I set the field "Available language packs" to "en_ar"
|
||||
When I set the field "Available language packs" to "English - Pirate (en_ar)"
|
||||
And I press "Install selected language pack(s)"
|
||||
Then I should see "Language pack 'en_ar' was successfully installed"
|
||||
And the "Installed language packs" select box should contain "en_ar"
|
||||
And the "Installed language packs" select box should contain "English - Pirate (en_ar)"
|
||||
And I navigate to "Live logs" node in "Site administration > Reports"
|
||||
And I should see "The language pack 'en_ar' was installed."
|
||||
And I log out
|
||||
@@ -35,14 +35,14 @@ Feature: Manage language packs
|
||||
Scenario: Try to uninstall language pack
|
||||
Given I log in as "admin"
|
||||
And I navigate to "Language packs" node in "Site administration > Language"
|
||||
And I set the field "Available language packs" to "en_ar"
|
||||
And I set the field "Available language packs" to "English - Pirate (en_ar)"
|
||||
And I press "Install selected language pack(s)"
|
||||
When I set the field "Installed language packs" to "en_ar"
|
||||
When I set the field "Installed language packs" to "English - Pirate (en_ar)"
|
||||
And I press "Uninstall selected language pack(s)"
|
||||
And I press "Continue"
|
||||
Then I should see "Language pack 'en_ar' was uninstalled"
|
||||
And the "Installed language packs" select box should not contain "en_ar"
|
||||
And the "Available language packs" select box should contain "en_ar"
|
||||
And the "Installed language packs" select box should not contain "English - Pirate (en_ar)"
|
||||
And the "Available language packs" select box should contain "English - Pirate (en_ar)"
|
||||
And I navigate to "Live logs" node in "Site administration > Reports"
|
||||
And I should see "The language pack 'en_ar' was removed."
|
||||
And I should see "Language pack uninstalled"
|
||||
@@ -51,7 +51,7 @@ Feature: Manage language packs
|
||||
Scenario: Try to uninstall English language pack
|
||||
Given I log in as "admin"
|
||||
And I navigate to "Language packs" node in "Site administration > Language"
|
||||
When I set the field "Installed language packs" to "en"
|
||||
When I set the field "Installed language packs" to "English (en)"
|
||||
And I press "Uninstall selected language pack(s)"
|
||||
Then I should see "The English language pack cannot be uninstalled."
|
||||
And I navigate to "Live logs" node in "Site administration > Reports"
|
||||
|
||||
@@ -106,6 +106,38 @@ class manager implements \core\log\manager {
|
||||
if (empty($interface) || ($reader instanceof $interface)) {
|
||||
$return[$plugin] = $reader;
|
||||
}
|
||||
// TODO MDL-49291 These conditions should be removed as part of the 2nd stage deprecation.
|
||||
if ($reader instanceof \core\log\sql_internal_reader) {
|
||||
debugging('\core\log\sql_internal_reader has been deprecated in favour of \core\log\sql_internal_table_reader.' .
|
||||
' Update ' . get_class($reader) . ' to use the new interface.', DEBUG_DEVELOPER);
|
||||
} else if ($reader instanceof \core\log\sql_select_reader) {
|
||||
debugging('\core\log\sql_select_reader has been deprecated in favour of \core\log\sql_reader. Update ' .
|
||||
get_class($reader) . ' to use the new interface.', DEBUG_DEVELOPER);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO MDL-49291 This section below (until the final return) should be removed as part of the 2nd stage deprecation.
|
||||
$isselectreader = (ltrim($interface, '\\') === 'core\log\sql_select_reader');
|
||||
$isinternalreader = (ltrim($interface, '\\') === 'core\log\sql_internal_reader');
|
||||
if ($isselectreader || $isinternalreader) {
|
||||
|
||||
if ($isselectreader) {
|
||||
$alternative = '\core\log\sql_reader';
|
||||
} else {
|
||||
$alternative = '\core\log\sql_internal_table_reader';
|
||||
}
|
||||
|
||||
if (count($return) === 0) {
|
||||
// If there are no classes implementing the provided interface and the provided interface is one of
|
||||
// the deprecated ones, we return the non-deprecated alternatives. It should be safe as the new interface
|
||||
// is adding a new method but not changing the existing ones.
|
||||
debugging($interface . ' has been deprecated in favour of ' . $alternative . '. Returning ' . $alternative .
|
||||
' instances instead. Please call get_readers() using the new interface.', DEBUG_DEVELOPER);
|
||||
$return = $this->get_readers($alternative);
|
||||
} else {
|
||||
debugging($interface . ' has been deprecated in favour of ' . $alternative .
|
||||
'. Please call get_readers() using the new interface.', DEBUG_DEVELOPER);
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
|
||||
@@ -31,7 +31,20 @@ defined('MOODLE_INTERNAL') || die();
|
||||
* @return bool always true
|
||||
*/
|
||||
function xmldb_tool_log_upgrade($oldversion) {
|
||||
global $CFG;
|
||||
global $CFG, $DB, $OUTPUT;
|
||||
|
||||
$dbman = $DB->get_manager();
|
||||
|
||||
if ($oldversion < 2014040600) {
|
||||
// Reset logging defaults in dev branches,
|
||||
// in production upgrade the install.php is executed instead.
|
||||
require_once(__DIR__ . '/install.php');
|
||||
xmldb_tool_log_install();
|
||||
upgrade_plugin_savepoint(true, 2014040600, 'tool', 'log');
|
||||
}
|
||||
|
||||
// Moodle v2.7.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Moodle v2.8.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
@@ -22,10 +22,19 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
function xmldb_logstore_database_upgrade($oldversion) {
|
||||
global $CFG;
|
||||
|
||||
if ($oldversion < 2014041700) {
|
||||
// Clean up old config.
|
||||
unset_config('excludelevels', 'logstore_database');
|
||||
unset_config('excludeactions', 'logstore_database');
|
||||
|
||||
// Savepoint reached.
|
||||
upgrade_plugin_savepoint(true, 2014041700, 'logstore', 'database');
|
||||
}
|
||||
|
||||
// Moodle v2.7.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Moodle v2.8.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
@@ -182,8 +182,6 @@ class store implements \tool_log\log\store, \core\log\sql_reader {
|
||||
|
||||
/**
|
||||
* Legacy add_to_log() code.
|
||||
* @deprecated since Moodle 3.1 MDL-45104 - Please use supported log stores such as "standard" or "external" instead.
|
||||
* @todo MDL-52805 This will be removed in Moodle 3.3
|
||||
*
|
||||
* @param int $courseid The course id
|
||||
* @param string $module The module name e.g. forum, journal, resource, course, user etc
|
||||
|
||||
@@ -22,13 +22,98 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
function xmldb_logstore_standard_upgrade($oldversion) {
|
||||
global $CFG, $DB;
|
||||
|
||||
$dbman = $DB->get_manager();
|
||||
|
||||
if ($oldversion < 2014032000) {
|
||||
|
||||
// Define field anonymous to be added to logstore_standard_log.
|
||||
$table = new xmldb_table('logstore_standard_log');
|
||||
$field = new xmldb_field('anonymous', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0', 'relateduserid');
|
||||
|
||||
// Conditionally launch add field anonymous.
|
||||
if (!$dbman->field_exists($table, $field)) {
|
||||
$dbman->add_field($table, $field);
|
||||
}
|
||||
|
||||
// Standard savepoint reached.
|
||||
upgrade_plugin_savepoint(true, 2014032000, 'logstore', 'standard');
|
||||
}
|
||||
|
||||
if ($oldversion < 2014041500) {
|
||||
|
||||
// Define index contextid-component (not unique) to be dropped form logstore_standard_log.
|
||||
$table = new xmldb_table('logstore_standard_log');
|
||||
$index = new xmldb_index('contextid-component', XMLDB_INDEX_NOTUNIQUE, array('contextid', 'component'));
|
||||
|
||||
// Conditionally launch drop index contextid-component.
|
||||
if ($dbman->index_exists($table, $index)) {
|
||||
$dbman->drop_index($table, $index);
|
||||
}
|
||||
|
||||
// Define index courseid (not unique) to be dropped form logstore_standard_log.
|
||||
$table = new xmldb_table('logstore_standard_log');
|
||||
$index = new xmldb_index('courseid', XMLDB_INDEX_NOTUNIQUE, array('courseid'));
|
||||
|
||||
// Conditionally launch drop index courseid.
|
||||
if ($dbman->index_exists($table, $index)) {
|
||||
$dbman->drop_index($table, $index);
|
||||
}
|
||||
|
||||
// Define index eventname (not unique) to be dropped form logstore_standard_log.
|
||||
$table = new xmldb_table('logstore_standard_log');
|
||||
$index = new xmldb_index('eventname', XMLDB_INDEX_NOTUNIQUE, array('eventname'));
|
||||
|
||||
// Conditionally launch drop index eventname.
|
||||
if ($dbman->index_exists($table, $index)) {
|
||||
$dbman->drop_index($table, $index);
|
||||
}
|
||||
|
||||
// Define index crud (not unique) to be dropped form logstore_standard_log.
|
||||
$table = new xmldb_table('logstore_standard_log');
|
||||
$index = new xmldb_index('crud', XMLDB_INDEX_NOTUNIQUE, array('crud'));
|
||||
|
||||
// Conditionally launch drop index crud.
|
||||
if ($dbman->index_exists($table, $index)) {
|
||||
$dbman->drop_index($table, $index);
|
||||
}
|
||||
|
||||
// Define index edulevel (not unique) to be dropped form logstore_standard_log.
|
||||
$table = new xmldb_table('logstore_standard_log');
|
||||
$index = new xmldb_index('edulevel', XMLDB_INDEX_NOTUNIQUE, array('edulevel'));
|
||||
|
||||
// Conditionally launch drop index edulevel.
|
||||
if ($dbman->index_exists($table, $index)) {
|
||||
$dbman->drop_index($table, $index);
|
||||
}
|
||||
|
||||
// Define index course-time (not unique) to be added to logstore_standard_log.
|
||||
$table = new xmldb_table('logstore_standard_log');
|
||||
$index = new xmldb_index('course-time', XMLDB_INDEX_NOTUNIQUE, array('courseid', 'anonymous', 'timecreated'));
|
||||
|
||||
// Conditionally launch add index course-time.
|
||||
if (!$dbman->index_exists($table, $index)) {
|
||||
$dbman->add_index($table, $index);
|
||||
}
|
||||
|
||||
// Define index user-module (not unique) to be added to logstore_standard_log.
|
||||
$table = new xmldb_table('logstore_standard_log');
|
||||
$index = new xmldb_index('user-module', XMLDB_INDEX_NOTUNIQUE, array('userid', 'contextlevel', 'contextinstanceid', 'crud', 'edulevel', 'timecreated'));
|
||||
|
||||
// Conditionally launch add index user-module.
|
||||
if (!$dbman->index_exists($table, $index)) {
|
||||
$dbman->add_index($table, $index);
|
||||
}
|
||||
|
||||
// Standard savepoint reached.
|
||||
upgrade_plugin_savepoint(true, 2014041500, 'logstore', 'standard');
|
||||
}
|
||||
|
||||
// Moodle v2.7.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Moodle v2.8.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
@@ -38,7 +123,7 @@ function xmldb_logstore_standard_upgrade($oldversion) {
|
||||
// Moodle v3.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
if ($oldversion < 2016041200) {
|
||||
if ($oldversion < 2015111601) {
|
||||
// This could take a long time. Unfortunately, no way to know how long, and no way to do progress, so setting for 1 hour.
|
||||
upgrade_set_timeout(3600);
|
||||
|
||||
@@ -50,7 +135,7 @@ function xmldb_logstore_standard_upgrade($oldversion) {
|
||||
$dbman->add_key($table, $key);
|
||||
|
||||
// Standard savepoint reached.
|
||||
upgrade_plugin_savepoint(true, 2016041200, 'logstore', 'standard');
|
||||
upgrade_plugin_savepoint(true, 2015111601, 'logstore', 'standard');
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2016041200; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->version = 2015111601; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2015111000; // Requires this Moodle version.
|
||||
$plugin->component = 'logstore_standard'; // Full name of the plugin (used for diagnostics).
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
define(["jquery","core/notification","core/ajax","core/templates","tool_lp/dialogue","tool_lp/event_base"],function(a,b,c,d,e,f){var g=function(a,b,c,d,e){var g=this;f.prototype.constructor.apply(this,[]),g._title=a,g._message=b,g._actions=c,g._confirm=d,g._cancel=e,g._selectedValue=null,g._reset()};return g.prototype=Object.create(f.prototype),g.prototype._selectedValue=null,g.prototype._popup=null,g.prototype._title=null,g.prototype._message=null,g.prototype._actions=null,g.prototype._confirm=null,g.prototype._cancel=null,g.prototype._afterRender=function(){var b=this;b._find('[data-action="action-selector-confirm"]').attr("disabled","disabled"),b._find('[data-region="action-selector-radio-buttons"]').change(function(){b._selectedValue=a("input[type='radio']:checked").val(),b._find('[data-action="action-selector-confirm"]').removeAttr("disabled"),b._refresh.bind(b)}.bind(b)),b._find('[data-action="action-selector-cancel"]').click(function(a){a.preventDefault(),b.close()}.bind(b)),b._find('[data-action="action-selector-confirm"]').click(function(a){a.preventDefault(),b._selectedValue.length&&(b._trigger("save",{action:b._selectedValue}),b.close())}.bind(b))},g.prototype.close=function(){var a=this;a._popup.close(),a._reset()},g.prototype.display=function(){var a=this;return a._render().then(function(b){a._popup=new e(a._title,b,a._afterRender.bind(a))}.bind(a)).fail(b.exception)},g.prototype._find=function(b){return a(this._popup.getContent()).find(b)},g.prototype._refresh=function(){var a=this;return a._render().then(function(b){a._find('[data-region="action-selector"]').replaceWith(b),a._afterRender()}.bind(a))},g.prototype._render=function(){var a=this,b=[];for(var c in a._actions)b.push(a._actions[c]);var e={message:a._message,choices:b,confirm:a._confirm,cancel:a._cancel};return d.render("tool_lp/action_selector",e)},g.prototype._reset=function(){this._popup=null,this._selectedValue=""},g});
|
||||
@@ -1 +0,0 @@
|
||||
define(["jquery","core/str"],function(a,b){var c=0,d=1,e=2,f=3;return{NONE:c,EVIDENCE:d,COMPLETE:e,RECOMMEND:f,getAll:function(){var a=this;return b.get_strings([{key:"competencyoutcome_none",component:"tool_lp"},{key:"competencyoutcome_evidence",component:"tool_lp"},{key:"competencyoutcome_recommend",component:"tool_lp"},{key:"competencyoutcome_complete",component:"tool_lp"}]).then(function(b){var c={};return c[a.NONE]={code:a.NONE,name:b[0]},c[a.EVIDENCE]={code:a.EVIDENCE,name:b[1]},c[a.RECOMMEND]={code:a.RECOMMEND,name:b[2]},c[a.COMPLETE]={code:a.COMPLETE,name:b[3]},c})},getString:function(b){var c=this,d=c.getAll();return d.then(function(c){return"undefined"==typeof c[b]?a.Deferred().reject().promise():c[b].name})}}});
|
||||
@@ -1 +0,0 @@
|
||||
define(["jquery"],function(a){var b=function(b,c,d,e,f){this._baseUrl=c,this._userId=d+"",this._competencyId=e+"",this._planId=f,this._ignoreFirstCompetency=!0,a(b).on("change",this._competencyChanged.bind(this))};return b.prototype._competencyChanged=function(b){if(this._ignoreFirstCompetency)return void(this._ignoreFirstCompetency=!1);var c=a(b.target).val(),d="?userid="+this._userId+"&planid="+this._planId+"&competencyid="+c;document.location=this._baseUrl+d},b.prototype._competencyId=null,b.prototype._userId=null,b.prototype._planId=null,b.prototype._baseUrl=null,b.prototype._ignoreFirstCompetency=null,b});
|
||||
@@ -1 +0,0 @@
|
||||
define(["jquery"],function(a){var b=function(b){this._eventNode=a("<div>"),this._ready=a.Deferred(),this._tree=b};return b.prototype._competency=null,b.prototype._eventNode=null,b.prototype._ready=null,b.prototype._tree=null,b.prototype.canConfig=function(){return this._tree.hasChildren(this._competency.id)},b.prototype.getConfig=function(){return null},b.prototype.getType=function(){throw new Error("Not implemented")},b.prototype.init=function(){return this._load()},b.prototype.injectTemplate=function(){return a.Deferred().reject().promise()},b.prototype.isValid=function(){return!1},b.prototype._load=function(){return a.when()},b.prototype.on=function(a,b){this._eventNode.on(a,b)},b.prototype.setTargetCompetency=function(a){this._competency=a},b.prototype._trigger=function(a,b){this._eventNode.trigger(a,[b])},b.prototype._triggerChange=function(){this._trigger("change",this)},b});
|
||||
@@ -1 +0,0 @@
|
||||
define(["jquery","core/str","tool_lp/competency_rule"],function(a,b,c){var d=function(){c.apply(this,arguments)};return d.prototype=Object.create(c.prototype),d.prototype.getType=function(){return"core_competency\\competency_rule_all"},d.prototype.isValid=function(){return!0},d});
|
||||
@@ -1 +0,0 @@
|
||||
define(["jquery","core/str","core/templates","tool_lp/competency_rule"],function(a,b,c,d){var e=function(){d.apply(this,arguments)};return e.prototype=Object.create(d.prototype),e.prototype._container=null,e.prototype._templateLoaded=!1,e.prototype.getConfig=function(){return JSON.stringify({base:{points:this._getRequiredPoints()},competencies:this._getCompetenciesConfig()})},e.prototype._getCompetenciesConfig=function(){var b=[];return this._container.find("[data-competency]").each(function(){var c=a(this),d=c.data("competency"),e=parseInt(c.find('[name="points"]').val(),10),f=c.find('[name="required"]').prop("checked");b.push({id:d,points:e,required:f?1:0})}),b},e.prototype._getRequiredPoints=function(){return parseInt(this._container.find('[name="requiredpoints"]').val()||1,10)},e.prototype.getType=function(){return"core_competency\\competency_rule_points"},e.prototype.injectTemplate=function(b){var d,e=this,f=this._tree.getChildren(this._competency.id),g={base:{points:2},competencies:[]};if(this._templateLoaded=!1,e._competency.ruletype==e.getType())try{g=JSON.parse(e._competency.ruleconfig)}catch(h){}return d={requiredpoints:g&&g.base?g.base.points:2,competency:e._competency,children:[]},a.each(f,function(b,c){var e={id:c.id,shortname:c.shortname,required:!1,points:0};g&&a.each(g.competencies,function(a,b){b.id==e.id&&(e.required=b.required?!0:!1,e.points=b.points)}),d.children.push(e)}),c.render("tool_lp/competency_rule_points",d).then(function(a){e._container=b,b.html(a),b.find("input").change(function(){e._triggerChange()}),e._templateLoaded=!0,e._triggerChange()})},e.prototype.isValid=function(){if(!this._templateLoaded)return!1;var b=this._getRequiredPoints(),c=0,d=!0;return a.each(this._getCompetenciesConfig(),function(a,b){b.points<0&&(d=!1),c+=b.points}),d=d&&c>=b},e});
|
||||
@@ -1 +0,0 @@
|
||||
define(["jquery","core/notification","core/ajax","core/templates","core/str","tool_lp/dialogue"],function(a,b,c,d,e,f){var g,h=function(){};return h.prototype.triggerCompetencyViewedEvent=function(a){c.call([{methodname:"core_competency_competency_viewed",args:{id:a}}])},h.prototype.showDialogue=function(a,c){var e=this.getCompetencyDataPromise(a,c),g=this;e.done(function(c){d.render("tool_lp/competency_summary",c).done(function(b){g.triggerCompetencyViewedEvent(a),new f(c.competency.shortname,b)}).fail(b.exception)}).fail(b.exception)},h.prototype.showDialogueFromData=function(a){var c=this;d.render("tool_lp/competency_summary",a).done(function(b){c.triggerCompetencyViewedEvent(a.id),new f(a.shortname,b,c.enhanceDialogue)}).fail(b.exception)},h.prototype.clickEventHandler=function(b){var c=b.data.compdialogue,d=a(b.currentTarget),e=d.data("id"),f=!d.data("excluderelated"),g=d.data("includecourses");c.showDialogue(e,{includerelated:f,includecourses:g}),b.preventDefault()},h.prototype.getCompetencyDataPromise=function(a,d){var e=c.call([{methodname:"tool_lp_data_for_competency_summary",args:{competencyid:a,includerelated:d.includerelated||!1,includecourses:d.includecourses||!1}}]);return e[0].then(function(a){return a}).fail(b.exception)},{init:function(){"undefined"==typeof g&&(g=new h,a("body").delegate('[data-action="competency-dialogue"]',"click",{compdialogue:g},g.clickEventHandler.bind(g)))}}});
|
||||
@@ -1 +0,0 @@
|
||||
define(["jquery","core/notification","core/ajax","core/templates","core/str","tool_lp/tree","tool_lp/competencypicker"],function(a,b,c,d,e,f,g){var h=function(a,b,c){g.prototype.constructor.apply(this,[1,!1,"self",c]),this._userId=a,this._plans=[],b&&(this._planId=b,this._singlePlan=!0)};return h.prototype=Object.create(g.prototype),h.prototype._plans=null,h.prototype._planId=null,h.prototype._singlePlan=!1,h.prototype._userId=null,h.prototype._afterRender=function(){var b=this;g.prototype._afterRender.apply(b,arguments),b._singlePlan||b._find('[data-action="chooseplan"]').change(function(c){b._planId=a(c.target).val(),b._loadCompetencies().then(b._refresh.bind(b))}.bind(b))},h.prototype._fetchCompetencies=function(a,d){var e=this;return c.call([{methodname:"core_competency_list_plan_competencies",args:{id:a}}])[0].done(function(a){var b,c,f=[];for(b=0;b<a.length;b++)c=a[b].competency,c.shortname.toLowerCase().indexOf(d.toLowerCase())<0||(c.children=[],c.haschildren=0,f.push(c));e._competencies=f}).fail(b.exception)},h.prototype._getPlan=function(b){var c;return a.each(this._plans,function(a,d){return d.id==b?(c=d,!1):void 0}),c},h.prototype._loadCompetencies=function(){return this._fetchCompetencies(this._planId,this._searchText)},h.prototype._loadPlans=function(){var d,e=this;return e._plans.length>0?a.when():(d=e._singlePlan?c.call([{methodname:"core_competency_read_plan",args:{id:this._planId}}])[0].then(function(a){return[a]}):c.call([{methodname:"core_competency_list_user_plans",args:{userid:e._userId}}])[0],d.done(function(a){e._plans=a}).fail(b.exception))},h.prototype._preRender=function(){var b=this;return b._loadPlans().then(function(){return!b._planId&&b._plans.length>0&&(b._planId=b._plans[0].id),b._planId?b._loadCompetencies():(b._plans=[],a.when())}.bind(b))},h.prototype._render=function(){var b=this;return b._preRender().then(function(){b._singlePlan||a.each(b._plans,function(a,c){c.id==b._planId?c.selected=!0:c.selected=!1});var c={competencies:b._competencies,plan:b._getPlan(b._planId),plans:b._plans,search:b._searchText,singlePlan:b._singlePlan};return d.render("tool_lp/competency_picker_user_plans",c)}.bind(b))},h});
|
||||
@@ -1 +0,0 @@
|
||||
define(["jquery","core/notification","core/templates","tool_lp/dialogue","tool_lp/competency_outcomes","core/str"],function(a,b,c,d,e,f){var g=function(b,c){this._eventNode=a("<div></div>"),this._tree=b,this._rulesModules=c,this._setUp()};return g.prototype._competency=null,g.prototype._eventNode=null,g.prototype._outcomesOption=null,g.prototype._popup=null,g.prototype._ready=null,g.prototype._rules=null,g.prototype._rulesModules=null,g.prototype._tree=null,g.prototype._afterChange=function(){this._isValid()?this._find('[data-action="save"]').prop("disabled",!1):this._find('[data-action="save"]').prop("disabled",!0)},g.prototype._afterRuleConfigChange=function(a,b){b==this._getRule()&&this._afterChange()},g.prototype._afterRender=function(){var a=this;a._find('[name="outcome"]').on("change",function(){a._switchedOutcome()}).trigger("change"),a._find('[name="rule"]').on("change",function(){a._switchedRule()}).trigger("change"),a._find('[data-action="save"]').on("click",function(){a._trigger("save",a._getConfig()),a.close()}),a._find('[data-action="cancel"]').on("click",function(){a.close()})},g.prototype.canBeConfigured=function(){var b=!1;return a.each(this._rules,function(a,c){return c.canConfig()?(b=!0,!1):void 0}),b},g.prototype.close=function(){this._popup.close(),this._popup=null},g.prototype.display=function(){var a=this;if(a._competency)return a._render().then(function(b){return f.get_string("competencyrule","tool_lp").then(function(c){a._popup=new d(c,b,a._afterRender.bind(a))})}).fail(b.exception)},g.prototype._find=function(b){return a(this._popup.getContent()).find(b)},g.prototype._getApplicableOutcomesOptions=function(){var b=this,c=[];return a.each(b._outcomesOption,function(a,d){c.push({code:d.code,name:d.name,selected:d.code==b._competency.ruleoutcome?!0:!1})}),c},g.prototype._getApplicableRulesOptions=function(){var b=this,c=[];return a.each(b._rules,function(a,d){d.canConfig()&&c.push({name:b._getRuleName(d.getType()),type:d.getType(),selected:d.getType()==b._competency.ruletype?!0:!1})}),c},g.prototype._getConfig=function(){var a=this._getRule();return{ruletype:a?a.getType():null,ruleconfig:a?a.getConfig():null,ruleoutcome:this._getOutcome()}},g.prototype._getOutcome=function(){return this._find('[name="outcome"]').val()},g.prototype._getRule=function(){var b,c=this._find('[name="rule"]').val();return a.each(this._rules,function(a,d){return d.getType()==c?(b=d,!1):void 0}),b},g.prototype._getRuleName=function(b){var c,d=this;return a.each(d._rulesModules,function(a,d){return d.type==b?(c=d.name,!1):void 0}),c},g.prototype._initOutcomes=function(){var a=this;return e.getAll().then(function(b){a._outcomesOption=b})},g.prototype._initRules=function(){var b=this,c=[];return a.each(b._rules,function(d,e){var f=e.init().then(function(){e.setTargetCompetency(b._competency),e.on("change",b._afterRuleConfigChange.bind(b))},function(){return b._rules.splice(d,1),a.when()});c.push(f)}),a.when.apply(a.when,c)},g.prototype._isValid=function(){var a=this._getOutcome(),b=this._getRule();return a==e.NONE?!0:b?b.isValid():!1},g.prototype.on=function(a,b){this._eventNode.on(a,b)},g.prototype._preRender=function(){return this.ready()},g.prototype.ready=function(){return this._ready.promise()},g.prototype._render=function(){var a=this;return this._preRender().then(function(){var b;a.canBeConfigured()?(b={},b.outcomes=a._getApplicableOutcomesOptions(),b.rules=a._getApplicableRulesOptions()):b=!1;var d={competencyshortname:a._competency.shortname,config:b};return c.render("tool_lp/competency_rule_config",d)})},g.prototype.setTargetCompetencyId=function(b){var c=this;c._competency=c._tree.getCompetency(b),a.each(c._rules,function(a,b){b.setTargetCompetency(c._competency)})},g.prototype._setUp=function(){var b=this,c=[],d=[];b._ready=a.Deferred(),b._rules=[],a.each(b._rulesModules,function(a,b){d.push(b.amd)}),require(d,function(){a.each(arguments,function(a,c){var d=new c(b._tree);b._rules.push(d)}),c.push(b._initRules()),c.push(b._initOutcomes()),a.when.apply(a.when,c).always(function(){b._ready.resolve()})})},g.prototype._switchedOutcome=function(){var a=this,b=a._getOutcome();return b==e.NONE?(a._find('[data-region="rule-type"]').hide().find('[name="rule"]').val(-1),a._find('[data-region="rule-config"]').empty().hide(),void a._afterChange()):(a._find('[data-region="rule-type"]').show(),a._find('[data-region="rule-config"]').show(),void a._afterChange())},g.prototype._switchedRule=function(){var a=this,b=a._find('[data-region="rule-config"]'),c=a._getRule();return c?void c.injectTemplate(b).then(function(){b.show()},function(){b.empty().hide()}).always(function(){a._afterChange()}):(b.empty().hide(),void a._afterChange())},g.prototype._trigger=function(a,b){this._eventNode.trigger(a,[b])},g});
|
||||
@@ -1 +0,0 @@
|
||||
define(["core/ajax","core/notification","core/templates","tool_lp/tree","tool_lp/competency_outcomes","jquery"],function(a,b,c,d,e,f){var g={},h=0,i="",j="",k="",l=!1,m=function(a,b){var c=0,d=!1;for(a.haschildren=!1,a.children=[],c=0;c<b.length;c++)d=b[c],d.parentid==a.id&&(a.haschildren=!0,a.children.push(d),m(d,b))},n=function(b){var e=f.Deferred();return c.render("tool_lp/loading",{}).done(function(n,o){c.replaceNodeContents(f(j),n,o);var p=a.call([{methodname:"core_competency_search_competencies",args:{searchtext:b,competencyframeworkid:h}}]);p[0].done(function(a){g={};var b=0;for(b=0;b<a.length;b++)g[a[b].id]=a[b];var h=[],n=!1;for(b=0;b<a.length;b++)n=a[b],0===parseInt(n.parentid,10)&&(h.push(n),m(n,a));var o={shortname:i,canmanage:l,competencies:h};c.render("tool_lp/competencies_tree_root",o).done(function(a,b){c.replaceNodeContents(f(j),f(a).html(),b);var h=new d(j,!1);if(k){var i=f(j).find("[data-id="+k+"]");i.length&&(h.selectItem(i),h.updateFocus(i))}e.resolve(g)}).fail(e.reject)}).fail(e.reject)}),e.promise()},o=function(a,b){var c=b.selected;k=c.attr("data-id")};return{init:function(a,c,d,e,f){h=a,i=c,l=f,j=e,n(d).fail(b.exception),this.on("selectionchanged",o)},on:function(a,b){f(j).on(a,b)},getChildren:function(a){var b=[];return f.each(g,function(c,d){d.parentid==a&&b.push(d)}),b},getCompetencyFrameworkId:function(){return h},getCompetency:function(a){return g[a]},getCompetencyLevel:function(a){var b=this.getCompetency(a),c=b.path.replace(/^\/|\/$/g,"").split("/").length;return c},hasChildren:function(a){return this.getChildren(a).length>0},hasRule:function(a){var b=this.getCompetency(a);return b?b.ruleoutcome!=e.OUTCOME_NONE&&b.ruletype:!1},reloadCompetencies:function(){return n("").fail(b.exception)},listCompetencies:function(){return g}}});
|
||||
@@ -1 +0,0 @@
|
||||
define(["jquery","core/notification","tool_lp/dialogue","core/str","core/ajax","core/templates"],function(a,b,c,d,e,f){var g=function(b){a(b).on("click",this.configureSettings.bind(this))};return g.prototype._dialogue=null,g.prototype.configureSettings=function(e){var g=a(e.target).closest("a").data("courseid"),h=a(e.target).closest("a").data("pushratingstouserplans"),i={courseid:g,settings:{pushratingstouserplans:h}};e.preventDefault(),f.render("tool_lp/course_competency_settings",i).done(function(a){d.get_string("configurecoursecompetencysettings","tool_lp").done(function(b){this._dialogue=new c(b,a,this.addListeners.bind(this))}.bind(this)).fail(b.exception)}.bind(this)).fail(b.exception)},g.prototype.addListeners=function(){var a=this._find('[data-action="save"]');a.on("click",this.saveSettings.bind(this));var b=this._find('[data-action="cancel"]');b.on("click",this.cancelChanges.bind(this))},g.prototype.cancelChanges=function(a){a.preventDefault(),this._dialogue.close()},g.prototype._find=function(b){return a('[data-region="coursecompetencysettings"]').find(b)},g.prototype.saveSettings=function(a){a.preventDefault();var c=this._find('input[name="pushratingstouserplans"]:checked').val(),d=this._find('input[name="courseid"]').val(),f={pushratingstouserplans:c};e.call([{methodname:"core_competency_update_course_competency_settings",args:{courseid:d,settings:f}}])[0].done(function(){this.refreshCourseCompetenciesPage()}.bind(this)).fail(b.exception)},g.prototype.refreshCourseCompetenciesPage=function(){var c=this._find('input[name="courseid"]').val();e.call([{methodname:"tool_lp_data_for_course_competencies_page",args:{courseid:c}}])[0].done(function(c){f.render("tool_lp/course_competencies_page",c).done(function(b,c){a('[data-region="coursecompetenciespage"]').replaceWith(b),f.runTemplateJS(c),this._dialogue.close()}.bind(this)).fail(b.exception)}.bind(this)).fail(b.exception)},g});
|
||||
@@ -1 +0,0 @@
|
||||
define(["core/yui"],function(a){var b=function(b,c,d,e,f){this.yuiDialogue=null;var g=this;"undefined"==typeof f&&(f=!1),a.use("moodle-core-notification","timers",function(){var h="480px";f&&(h="800px"),g.yuiDialogue=new M.core.dialogue({headerContent:b,bodyContent:c,draggable:!0,visible:!1,center:!0,modal:!0,width:h}),g.yuiDialogue.after("visibleChange",function(b){b.newVal?"undefined"!=typeof d&&a.soon(function(){d(g),g.yuiDialogue.centerDialogue()}):"undefined"!=typeof e&&a.soon(function(){e(g)})}),g.yuiDialogue.show()})};return b.prototype.close=function(){this.yuiDialogue.hide(),this.yuiDialogue.destroy()},b.prototype.getContent=function(){return this.yuiDialogue.bodyNode.getDOMNode()},b});
|
||||
@@ -1 +0,0 @@
|
||||
define(["core/str","core/yui"],function(a,b){var c=function(a){var b=a.drag.get("node"),c=a.drop.get("node");this.callback(b.getDOMNode(),c.getDOMNode())};return{dragdrop:function(d,e,f,g,h,i,j,k){a.get_strings([{key:"emptydragdropregion",component:"moodle"},{key:"movecontent",component:"moodle"},{key:"tocontent",component:"moodle"}]).done(function(){b.use("moodle-tool_lp-dragdrop-reorder",function(){var a={callback:k};M.tool_lp.dragdrop_reorder({group:d,dragHandleText:e,sameNodeText:f,parentNodeText:g,sameNodeClass:h,parentNodeClass:i,dragHandleInsertClass:j,callback:b.bind(c,a)})})})}}});
|
||||
@@ -1 +0,0 @@
|
||||
define(["jquery"],function(a){var b=function(){this._eventNode=a("<div></div>")};return b.prototype._eventNode=null,b.prototype.on=function(a,b){this._eventNode.on(a,b)},b.prototype._trigger=function(a,b){this._eventNode.trigger(a,[b])},b});
|
||||
@@ -1 +0,0 @@
|
||||
define(["jquery","core/notification","core/ajax","core/str","core/log"],function(a,b,c,d,e){var f={},g=function(g,h){"undefined"==typeof f[g]&&(f[g]=a("body").delegate(g,"click",function(f){var g=a(f.currentTarget).parents(h);if(!g.length||g.length>1)return void e.error("None or too many evidence container were found.");var i=g.data("id");return i?(f.preventDefault(),f.stopPropagation(),void d.get_strings([{key:"confirm",component:"moodle"},{key:"areyousure",component:"moodle"},{key:"delete",component:"moodle"},{key:"cancel",component:"moodle"}]).done(function(a){b.confirm(a[0],a[1],a[2],a[3],function(){var a=c.call([{methodname:"core_competency_delete_evidence",args:{id:i}}]);a[0].then(function(){g.remove()}).fail(b.exception)})}).fail(b.exception)):void e.error("Evidence ID was not found.")}))};return{register:g}});
|
||||
@@ -1 +0,0 @@
|
||||
define(["jquery","core/ajax","core/templates"],function(a,b,c){return{processResults:function(b,c){var d=[];return a.each(c,function(a,b){d.push({value:b.id,label:b._label})}),d},transport:function(d,e,f,g){var h,i=parseInt(a(d).data("contextid"),10),j=a(d).data("includes");h=b.call([{methodname:"tool_lp_search_cohorts",args:{query:e,context:{contextid:i},includes:j}}]),h[0].then(function(b){var d=[],e=0;return a.each(b.cohorts,function(a,b){d.push(c.render("tool_lp/form-cohort-selector-suggestion",b))}),a.when.apply(a.when,d).then(function(){var c=arguments;a.each(b.cohorts,function(a,b){b._label=c[e],e++}),f(b.cohorts)})},g)}}});
|
||||
@@ -1 +0,0 @@
|
||||
define(["jquery","core/ajax","core/templates"],function(a,b,c){return{processResults:function(b,c){var d=[];return a.each(c,function(a,b){d.push({value:b.id,label:b._label})}),d},transport:function(d,e,f,g){var h,i=a(d).data("capability");"undefined"==typeof i&&(i=""),h=b.call([{methodname:"tool_lp_search_users",args:{query:e,capability:i}}]),h[0].then(function(b){var d=[],e=0;return a.each(b.users,function(b,e){var f=e,g=[];a.each(["idnumber","email","phone1","phone2","department","institution"],function(a,b){"undefined"!=typeof e[b]&&""!==e[b]&&(f.hasidentity=!0,g.push(e[b]))}),f.identity=g.join(", "),d.push(c.render("tool_lp/form-user-selector-suggestion",f))}),a.when.apply(a.when,d).then(function(){var c=arguments;a.each(b.users,function(a,b){b._label=c[e],e++}),f(b.users)})},g)}}});
|
||||
@@ -1 +0,0 @@
|
||||
define(["jquery","core/templates","core/ajax","core/notification","core/str"],function(a,b,c,d,e){var f=0,g=0,h=function(c,d){a('[data-region="managecompetencies"]').replaceWith(c),b.runTemplateJS(d)},i=function(a){b.render("tool_lp/manage_competency_frameworks_page",a).done(h).fail(d.exception)},j=function(b){b.preventDefault(),g=a(this).attr("data-frameworkid");var e=c.call([{methodname:"core_competency_duplicate_competency_framework",args:{id:g}},{methodname:"tool_lp_data_for_competency_frameworks_manage_page",args:{pagecontext:{contextid:f}}}]);e[1].done(i).fail(d.exception)},k=function(){var a=c.call([{methodname:"core_competency_delete_competency_framework",args:{id:g}},{methodname:"tool_lp_data_for_competency_frameworks_manage_page",args:{pagecontext:{contextid:f}}}]);a[0].done(function(a){if(a===!1){var b=c.call([{methodname:"core_competency_read_competency_framework",args:{id:g}}]);b[0].done(function(a){e.get_strings([{key:"frameworkcannotbedeleted",component:"tool_lp",param:a.shortname},{key:"cancel",component:"moodle"}]).done(function(a){d.alert(null,a[0])}).fail(d.exception)})}}).fail(d.exception),a[1].done(i).fail(d.exception)},l=function(b){b.preventDefault();var f=a(this).attr("data-frameworkid");g=f;var h=c.call([{methodname:"core_competency_read_competency_framework",args:{id:g}}]);h[0].done(function(a){e.get_strings([{key:"confirm",component:"moodle"},{key:"deletecompetencyframework",component:"tool_lp",param:a.shortname},{key:"delete",component:"moodle"},{key:"cancel",component:"moodle"}]).done(function(a){d.confirm(a[0],a[1],a[2],a[3],k)}).fail(d.exception)}).fail(d.exception)};return{deleteHandler:l,duplicateHandler:j,init:function(a){f=a}}});
|
||||
@@ -1 +0,0 @@
|
||||
define(["jquery","core/ajax","core/notification"],function(a,b,c){return{list:function(d,e){var f,g={context:{contextid:d}};return a.extend(g,"undefined"==typeof e?{}:e),f=b.call([{methodname:"core_competency_list_competency_frameworks",args:g}])[0],f.fail(c.exception)},processResults:function(b,c){var d=[];return a.each(c,function(a,b){d.push({value:b.id,label:b.shortname+" "+b.idnumber})}),d},transport:function(b,c,d){var e=a(b),f=e.data("contextid"),g=e.data("onlyvisible");if(!f)throw new Error("The attribute data-contextid is required on "+b);this.list(f,{query:c,onlyvisible:g}).then(d)}}});
|
||||
@@ -1 +0,0 @@
|
||||
define(["jquery","core/notification","core/templates","tool_lp/dialogue","tool_lp/event_base","core/str"],function(a,b,c,d,e,f){var g=function(a){e.prototype.constructor.apply(this,[]),this._ratingOptions=a};return g.prototype=Object.create(e.prototype),g.prototype._popup=null,g.prototype._ratingOptions=null,g.prototype._afterRender=function(){var b=this._find('[data-action="rate"]'),c=this._find('[name="rating"]'),d=this._find('[name="comment"]');this._find('[data-action="cancel"]').click(function(a){a.preventDefault(),this._trigger("cancelled"),this.close()}.bind(this)),c.change(function(){var c=a(this);c.val()?b.prop("disabled",!1):b.prop("disabled",!0)}).change(),b.click(function(a){a.preventDefault();var b=c.val();b&&(this._trigger("rated",{rating:b,note:d.val()}),this.close())}.bind(this))},g.prototype.close=function(){this._popup.close(),this._popup=null},g.prototype.display=function(){return this._render().then(function(a){return f.get_string("rate","tool_lp").then(function(b){this._popup=new d(b,a,this._afterRender.bind(this))}.bind(this))}.bind(this)).fail(b.exception)},g.prototype._find=function(b){return a(this._popup.getContent()).find(b)},g.prototype._render=function(){var a={cangrade:this._canGrade,ratings:this._ratingOptions};return c.render("tool_lp/competency_grader",a)},g});
|
||||
@@ -1 +0,0 @@
|
||||
define(["jquery","core/notification","core/ajax","core/log","tool_lp/grade_dialogue","tool_lp/event_base","tool_lp/scalevalues"],function(a,b,c,d,e,f,g){var h=function(b,c,d,e,g,h,i){f.prototype.constructor.apply(this,[]);var j=a(b);if(!j.length)throw new Error("Could not find the trigger");this._scaleId=c,this._competencyId=d,this._userId=e,this._planId=g,this._courseId=h,this._chooseStr=i,this._setUp(),j.click(function(a){a.preventDefault(),this._dialogue.display()}.bind(this)),this._planId?(this._methodName="core_competency_grade_competency_in_plan",this._args={competencyid:this._competencyId,planid:this._planId}):this._courseId?(this._methodName="core_competency_grade_competency_in_course",this._args={competencyid:this._competencyId,courseid:this._courseId,userid:this._userId}):(this._methodName="core_competency_grade_competency",this._args={userid:this._userId,competencyid:this._competencyId})};return h.prototype=Object.create(f.prototype),h.prototype._setUp=function(){var a=[],d=this,f=g.get_values(d._scaleId);f.done(function(f){a.push({value:"",name:d._chooseStr});for(var g=0;g<f.length;g++){var h=f[g];a.push({value:h.id,name:h.name})}d._dialogue=new e(a),d._dialogue.on("rated",function(a,e){var f=d._args;f.grade=e.rating,f.note=e.note,c.call([{methodname:d._methodName,args:f,done:function(a){d._trigger("competencyupdated",{args:f,evidence:a})}.bind(d),fail:b.exception}])}.bind(d))}).fail(b.exception)},h.prototype._scaleId=null,h.prototype._competencyId=null,h.prototype._userId=null,h.prototype._planId=null,h.prototype._courseId=null,h.prototype._chooseStr=null,h.prototype._dialogue=null,h});
|
||||
@@ -1 +0,0 @@
|
||||
define(["jquery","core/ajax","core/str","tool_lp/competencypicker","core/templates","core/notification"],function(a,b,c,d,e,f){var g=function(a,b,c,d,e){this.buttonSelector=a,this.inputHiddenSelector=b,this.staticElementSelector=c,this.frameworkId=d,this.pageContextId=e,this.registerEvents()};return g.prototype.buttonSelector=null,g.prototype.inputHiddenSelector=null,g.prototype.staticElementSelector=null,g.prototype.frameworkId=null,g.prototype.pageContextId=null,g.prototype.setParent=function(d){var e=this;0!==d.competencyId?b.call([{methodname:"core_competency_read_competency",args:{id:d.competencyId}}])[0].done(function(b){a(e.staticElementSelector).html(b.shortname),a(e.inputHiddenSelector).val(b.id)}).fail(f.exception):c.get_string("competencyframeworkroot","tool_lp").then(function(b){a(e.staticElementSelector).html(b),a(e.inputHiddenSelector).val(d.competencyId)}).fail(f.exception)},g.prototype.registerEvents=function(){var b=this;a(b.buttonSelector).on("click",function(a){a.preventDefault();var c=new d(b.pageContextId,b.frameworkId,"self",!1);c._render=function(){var a=this;return a._preRender().then(function(){var b={competencies:a._competencies,framework:a._getFramework(a._frameworkId),frameworks:a._frameworks,search:a._searchText,singleFramework:a._singleFramework};return e.render("tool_lp/competency_picker_competencyform",b)}.bind(a))},c.on("save",function(a,c){b.setParent(c)}.bind(b)),c.display()})},{init:function(a,b,c,d,e){new g(a,b,c,d,e)}}});
|
||||
@@ -1 +0,0 @@
|
||||
define(["jquery","core/notification","core/templates","core/ajax","tool_lp/dialogue","tool_lp/scalevalues"],function(a,b,c,d,e,f){var g=function(b,c,d){this.selectSelector=b,this.inputSelector=c,this.triggerSelector=d,this.originalscaleid=a(b).val(),a(b).on("change",this.scaleChangeHandler.bind(this)).change(),a(d).click(this.showConfig.bind(this))};return g.prototype.selectSelector=null,g.prototype.inputSelector=null,g.prototype.triggerSelector=null,g.prototype.scalevalues=null,g.prototype.originalscaleid=0,g.prototype.scaleid=0,g.prototype.popup=null,g.prototype.showConfig=function(){var d=this;if(this.scaleid=a(this.selectSelector).val(),!(this.scaleid<=0)){var f=a(this.selectSelector).find("option:selected").text();this.getScaleValues(this.scaleid).done(function(){var a={scalename:f,scales:d.scalevalues};c.render("tool_lp/scale_configuration_page",a).done(function(a){new e(f,a,d.initScaleConfig.bind(d))}).fail(b.exception)}).fail(b.exception)}},g.prototype.retrieveOriginalScaleConfig=function(){var b=a(this.inputSelector).val();if(""!==b){var c=a.parseJSON(b),d=c.shift();if(d.scaleid===this.originalscaleid)return c}return""},g.prototype.initScaleConfig=function(b){this.popup=b;var c=a(b.getContent());if(this.originalscaleid===this.scaleid){var d=this.retrieveOriginalScaleConfig();""!==d&&d.forEach(function(a){1===a.scaledefault&&c.find('[data-field="tool_lp_scale_default_'+a.id+'"]').attr("checked",!0),1===a.proficient&&c.find('[data-field="tool_lp_scale_proficient_'+a.id+'"]').attr("checked",!0)})}c.on("click",'[data-action="close"]',function(){this.setScaleConfig(),b.close()}.bind(this)),c.on("click",'[data-action="cancel"]',function(){b.close()}.bind(this))},g.prototype.setScaleConfig=function(){var b=a(this.popup.getContent()),c=[{scaleid:this.scaleid}];this.scalevalues.forEach(function(a){var d=0,e=0;b.find('[data-field="tool_lp_scale_default_'+a.id+'"]').is(":checked")&&(d=1),b.find('[data-field="tool_lp_scale_proficient_'+a.id+'"]').is(":checked")&&(e=1),(d||e)&&c.push({id:a.id,scaledefault:d,proficient:e})});var d=JSON.stringify(c);a(this.inputSelector).val(d),this.originalscaleid=this.scaleid},g.prototype.getScaleValues=function(a){return f.get_values(a).then(function(a){return this.scalevalues=a,a}.bind(this))},g.prototype.scaleChangeHandler=function(b){a(b.target).val()<=0?a(this.triggerSelector).prop("disabled",!0):a(this.triggerSelector).prop("disabled",!1)},{init:function(a,b,c){return new g(a,b,c)}}});
|
||||
@@ -1 +0,0 @@
|
||||
define(["jquery","core/ajax"],function(a,b){var c=[];return{get_values:function(d){var e=a.Deferred();return"undefined"==typeof c[d]?b.call([{methodname:"core_competency_get_scale_values",args:{scaleid:d},done:function(a){c[d]=a,e.resolve(a)},fail:e.reject}]):e.resolve(c[d]),e.promise()}}});
|
||||
@@ -1 +0,0 @@
|
||||
define(["jquery","core/templates","core/ajax","core/notification","core/str","tool_lp/actionselector"],function(a,b,c,d,e,f){var g=0,h=0,i=!0,j=function(c,d){a('[data-region="managetemplates"]').replaceWith(c),b.runTemplateJS(d)},k=function(a){b.render("tool_lp/manage_templates_page",a).done(j).fail(d.exception)},l=function(){var a=c.call([{methodname:"core_competency_delete_template",args:{id:h,deleteplans:i}},{methodname:"tool_lp_data_for_templates_manage_page",args:{pagecontext:{contextid:g}}}]);a[1].done(k).fail(d.exception)},m=function(b){b.preventDefault(),h=a(this).attr("data-templateid");var e=c.call([{methodname:"core_competency_duplicate_template",args:{id:h}},{methodname:"tool_lp_data_for_templates_manage_page",args:{pagecontext:{contextid:g}}}]);e[1].done(k).fail(d.exception)},n=function(b){b.preventDefault();var g=a(this).attr("data-templateid");h=g,i=!0;var j=c.call([{methodname:"core_competency_read_template",args:{id:h}},{methodname:"core_competency_template_has_related_data",args:{id:h}}]);j[0].done(function(a){j[1].done(function(b){b?e.get_strings([{key:"deletetemplate",component:"tool_lp",param:a.shortname},{key:"deletetemplatewithplans",component:"tool_lp"},{key:"deleteplans",component:"tool_lp"},{key:"unlinkplanstemplate",component:"tool_lp"},{key:"confirm",component:"moodle"},{key:"cancel",component:"moodle"}]).done(function(a){var b=[{text:a[2],value:"delete"},{text:a[3],value:"unlink"}],c=new f(a[0],a[1],b,a[4],a[5]);c.display(),c.on("save",function(a,b){"delete"!=b.action&&(i=!1),l()})}).fail(d.exception):e.get_strings([{key:"confirm",component:"moodle"},{key:"deletetemplate",component:"tool_lp",param:a.shortname},{key:"delete",component:"moodle"},{key:"cancel",component:"moodle"}]).done(function(a){d.confirm(a[0],a[1],a[2],a[3],l)}).fail(d.exception)}).fail(d.exception)}).fail(d.exception)};return{deleteHandler:n,duplicateHandler:m,init:function(a){g=a}}});
|
||||
@@ -1 +0,0 @@
|
||||
define(["jquery"],function(a){var b=function(b,c,d,e,f,g){this._baseUrl=d,this._userId=e+"",this._competencyId=f+"",this._courseId=g,this._ignoreFirstUser=!0,this._ignoreFirstCompetency=!0,a(b).on("change",this._userChanged.bind(this)),a(c).on("change",this._competencyChanged.bind(this))};return b.prototype._userChanged=function(b){if(this._ignoreFirstUser)return void(this._ignoreFirstUser=!1);var c=a(b.target).val(),d="?userid="+c+"&courseid="+this._courseId+"&competencyid="+this._competencyId;document.location=this._baseUrl+d},b.prototype._competencyChanged=function(b){if(this._ignoreFirstCompetency)return void(this._ignoreFirstCompetency=!1);var c=a(b.target).val(),d="?userid="+this._userId+"&courseid="+this._courseId+"&competencyid="+c;document.location=this._baseUrl+d},b.prototype._competencyId=null,b.prototype._userId=null,b.prototype._courseId=null,b.prototype._baseUrl=null,b.prototype._ignoreFirstUser=null,b.prototype._ignoreFirstCompetency=null,b});
|
||||
@@ -1 +0,0 @@
|
||||
define(["jquery","core/notification","core/ajax","core/templates"],function(a,b,c,d){var e=function(a,b,c,d,e,f){this._rootElement=a,this._competencyId=b,this._userId=c,this._planId=d,this._courseId=e,this._valid=!0,this._displayuser="undefined"!=typeof f?f:!1,this._planId?(this._methodName="tool_lp_data_for_user_competency_summary_in_plan",this._args={competencyid:this._competencyId,planid:this._planId},this._templateName="tool_lp/user_competency_summary_in_plan"):this._courseId?(this._methodName="tool_lp_data_for_user_competency_summary_in_course",this._args={userid:this._userId,competencyid:this._competencyId,courseid:this._courseId},this._templateName="tool_lp/user_competency_summary_in_course"):(this._methodName="tool_lp_data_for_user_competency_summary",this._args={userid:this._userId,competencyid:this._competencyId},this._templateName="tool_lp/user_competency_summary")};return e.prototype.reload=function(){var a=this,e=[];this._valid&&(e=c.call([{methodname:this._methodName,args:this._args}]),e[0].done(function(c){a._displayuser&&(c.displayuser=!0),d.render(a._templateName,c).done(function(b,c){d.replaceNode(a._rootElement,b,c)}).fail(b.exception)}).fail(b.exception))},e.prototype._rootElement=null,e.prototype._courseId=null,e.prototype._valid=null,e.prototype._planId=null,e.prototype._competencyId=null,e.prototype._userId=null,e.prototype._methodName=null,e.prototype._args=null,e.prototype._templateName=null,e.prototype._displayuser=!1,e});
|
||||
@@ -1 +0,0 @@
|
||||
define(["jquery","core/notification","core/str","core/ajax","core/templates","tool_lp/dialogue"],function(a,b,c,d,e,f){var g=function(b,c,d){this._regionSelector=b,this._userCompetencySelector=c,this._planId=d,a(this._regionSelector).on("click",this._userCompetencySelector,this._handleClick.bind(this))};return g.prototype._handleClick=function(c){c.preventDefault();var e=a(c.target).closest("tr"),f=a(e).data("competencyid"),g=a(e).data("userid"),h=this._planId,i=d.call([{methodname:"tool_lp_data_for_user_competency_summary_in_plan",args:{competencyid:f,planid:h},done:this._contextLoaded.bind(this),fail:b.exception}]);i[0].then(function(a){var c="core_competency_user_competency_viewed_in_plan";a.plan.iscompleted&&(c="core_competency_user_competency_plan_viewed"),d.call([{methodname:c,args:{competencyid:f,userid:g,planid:h},fail:b.exception}])})},g.prototype._contextLoaded=function(a){var d=this;e.render("tool_lp/user_competency_summary_in_plan",a).done(function(a,g){c.get_string("usercompetencysummary","report_competency").done(function(b){new f(b,a,e.runTemplateJS.bind(e,g),d._refresh.bind(d),!0)}).fail(b.exception)}).fail(b.exception)},g.prototype._refresh=function(){var a=this._planId;d.call([{methodname:"tool_lp_data_for_plan_page",args:{planid:a},done:this._pageContextLoaded.bind(this),fail:b.exception}])},g.prototype._pageContextLoaded=function(a){var c=this;e.render("tool_lp/plan_page",a).done(function(a,b){e.replaceNode(c._regionSelector,a,b)}).fail(b.exception)},g.prototype._regionSelector=null,g.prototype._userCompetencySelector=null,g.prototype._planId=null,g});
|
||||
@@ -1 +0,0 @@
|
||||
define(["jquery","core/templates","core/ajax","core/notification","core/str","tool_lp/menubar","tool_lp/event_base"],function(a,b,c,d,e,f,g){var h=function(){g.prototype.constructor.apply(this,[])};return h.prototype=Object.create(g.prototype),h.prototype._nodeSelector='[data-node="user-competency"]',h.prototype._cancelReviewRequest=function(a){var b={methodname:"core_competency_user_competency_cancel_review_request",args:{userid:a.userid,competencyid:a.competencyid}};c.call([b])[0].then(function(){this._trigger("review-request-cancelled",a),this._trigger("status-changed",a)}.bind(this),function(){this._trigger("error-occured",a)}.bind(this))},h.prototype.cancelReviewRequest=function(a){this._cancelReviewRequest(a)},h.prototype._cancelReviewRequestHandler=function(b){b.preventDefault();var c=this._findUserCompetencyData(a(b.target));this.cancelReviewRequest(c)},h.prototype._requestReview=function(a){var b={methodname:"core_competency_user_competency_request_review",args:{userid:a.userid,competencyid:a.competencyid}};c.call([b])[0].then(function(){this._trigger("review-requested",a),this._trigger("status-changed",a)}.bind(this),function(){this._trigger("error-occured",a)}.bind(this))},h.prototype.requestReview=function(a){this._requestReview(a)},h.prototype._requestReviewHandler=function(b){b.preventDefault();var c=this._findUserCompetencyData(a(b.target));this.requestReview(c)},h.prototype._startReview=function(a){var b={methodname:"core_competency_user_competency_start_review",args:{userid:a.userid,competencyid:a.competencyid}};c.call([b])[0].then(function(){this._trigger("review-started",a),this._trigger("status-changed",a)}.bind(this),function(){this._trigger("error-occured",a)}.bind(this))},h.prototype.startReview=function(a){this._startReview(a)},h.prototype._startReviewHandler=function(b){b.preventDefault();var c=this._findUserCompetencyData(a(b.target));this.startReview(c)},h.prototype._stopReview=function(a){var b={methodname:"core_competency_user_competency_stop_review",args:{userid:a.userid,competencyid:a.competencyid}};c.call([b])[0].then(function(){this._trigger("review-stopped",a),this._trigger("status-changed",a)}.bind(this),function(){this._trigger("error-occured",a)}.bind(this))},h.prototype.stopReview=function(a){this._stopReview(a)},h.prototype._stopReviewHandler=function(b){b.preventDefault();var c=this._findUserCompetencyData(a(b.target));this.stopReview(c)},h.prototype.enhanceMenubar=function(a){f.enhance(a,{'[data-action="request-review"]':this._requestReviewHandler.bind(this),'[data-action="cancel-review-request"]':this._cancelReviewRequestHandler.bind(this)})},h.prototype._findUserCompetencyData=function(a){var b,c=a.parents(this._nodeSelector);if(1!=c.length)throw new Error("The evidence node was not located.");if(b=c.data(),"undefined"==typeof b||"undefined"==typeof b.userid||"undefined"==typeof b.competencyid)throw new Error("User competency data could not be found.");return b},h.prototype.enhanceMenubar=function(a){f.enhance(a,{'[data-action="request-review"]':this._requestReviewHandler.bind(this),'[data-action="cancel-review-request"]':this._cancelReviewRequestHandler.bind(this),'[data-action="start-review"]':this._startReviewHandler.bind(this),'[data-action="stop-review"]':this._stopReviewHandler.bind(this)})},h.prototype.registerEvents=function(b){var c=a(b);c.find('[data-action="request-review"]').click(this._requestReviewHandler.bind(this)),c.find('[data-action="cancel-review-request"]').click(this._cancelReviewRequestHandler.bind(this)),c.find('[data-action="start-review"]').click(this._startReviewHandler.bind(this)),c.find('[data-action="stop-review"]').click(this._stopReviewHandler.bind(this))},h});
|
||||
@@ -1,193 +0,0 @@
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Action selector.
|
||||
*
|
||||
* To handle 'save' events use: actionselector.on('save')
|
||||
* This will receive the information to display in popup.
|
||||
* The actions have the format [{'text': sometext, 'value' : somevalue}].
|
||||
*
|
||||
* @package tool_lp
|
||||
* @copyright 2016 Serge Gauthier - <serge.gauthier.2@umontreal.ca>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
define(['jquery',
|
||||
'core/notification',
|
||||
'core/ajax',
|
||||
'core/templates',
|
||||
'tool_lp/dialogue',
|
||||
'tool_lp/event_base'],
|
||||
function($, Notification, Ajax, Templates, Dialogue, EventBase) {
|
||||
|
||||
/**
|
||||
* Action selector class.
|
||||
* @param {String} title The title of popup.
|
||||
* @param {String} message The message to display.
|
||||
* @param {object} actions The actions that can be selected.
|
||||
* @param {String} confirm Text for confirm button.
|
||||
* @param {String} cancel Text for cancel button.
|
||||
*/
|
||||
var ActionSelector = function(title, message, actions, confirm, cancel) {
|
||||
var self = this;
|
||||
|
||||
EventBase.prototype.constructor.apply(this, []);
|
||||
self._title = title;
|
||||
self._message = message;
|
||||
self._actions = actions;
|
||||
self._confirm = confirm;
|
||||
self._cancel = cancel;
|
||||
self._selectedValue = null;
|
||||
self._reset();
|
||||
};
|
||||
|
||||
ActionSelector.prototype = Object.create(EventBase.prototype);
|
||||
|
||||
/** @type {String} The value that was selected. */
|
||||
ActionSelector.prototype._selectedValue = null;
|
||||
/** @type {Dialogue} The reference to the dialogue. */
|
||||
ActionSelector.prototype._popup = null;
|
||||
/** @type {String} The title of popup. */
|
||||
ActionSelector.prototype._title = null;
|
||||
/** @type {String} The message in popup. */
|
||||
ActionSelector.prototype._message = null;
|
||||
/** @type {object} The information for radion buttons. */
|
||||
ActionSelector.prototype._actions = null;
|
||||
/** @type {String} The text for confirm button. */
|
||||
ActionSelector.prototype._confirm = null;
|
||||
/** @type {String} The text for cancel button. */
|
||||
ActionSelector.prototype._cancel = null;
|
||||
|
||||
/**
|
||||
* Hook to executed after the view is rendered.
|
||||
*
|
||||
* @method _afterRender
|
||||
*/
|
||||
ActionSelector.prototype._afterRender = function() {
|
||||
var self = this;
|
||||
|
||||
// Confirm button is disabled until a choice is done.
|
||||
self._find('[data-action="action-selector-confirm"]').attr('disabled', 'disabled');
|
||||
|
||||
// Add listener for radio buttons change.
|
||||
self._find('[data-region="action-selector-radio-buttons"]').change(function() {
|
||||
self._selectedValue = $("input[type='radio']:checked").val();
|
||||
self._find('[data-action="action-selector-confirm"]').removeAttr('disabled');
|
||||
self._refresh.bind(self);
|
||||
}.bind(self));
|
||||
|
||||
// Add listener for cancel.
|
||||
self._find('[data-action="action-selector-cancel"]').click(function(e) {
|
||||
e.preventDefault();
|
||||
self.close();
|
||||
}.bind(self));
|
||||
|
||||
// Add listener for confirm.
|
||||
self._find('[data-action="action-selector-confirm"]').click(function(e) {
|
||||
e.preventDefault();
|
||||
if (!self._selectedValue.length) {
|
||||
return;
|
||||
}
|
||||
self._trigger('save', { action: self._selectedValue });
|
||||
self.close();
|
||||
}.bind(self));
|
||||
};
|
||||
|
||||
/**
|
||||
* Close the dialogue.
|
||||
*
|
||||
* @method close
|
||||
*/
|
||||
ActionSelector.prototype.close = function() {
|
||||
var self = this;
|
||||
self._popup.close();
|
||||
self._reset();
|
||||
};
|
||||
|
||||
/**
|
||||
* Opens the action selector.
|
||||
*
|
||||
* @method display
|
||||
* @return {Promise}
|
||||
*/
|
||||
ActionSelector.prototype.display = function() {
|
||||
var self = this;
|
||||
return self._render().then(function(html) {
|
||||
self._popup = new Dialogue(
|
||||
self._title,
|
||||
html,
|
||||
self._afterRender.bind(self)
|
||||
);
|
||||
}.bind(self)).fail(Notification.exception);
|
||||
};
|
||||
|
||||
/**
|
||||
* Find a node in the dialogue.
|
||||
*
|
||||
* @param {String} selector
|
||||
* @method _find
|
||||
*/
|
||||
ActionSelector.prototype._find = function(selector) {
|
||||
return $(this._popup.getContent()).find(selector);
|
||||
};
|
||||
|
||||
/**
|
||||
* Refresh the view.
|
||||
*
|
||||
* @method _refresh
|
||||
* @return {Promise}
|
||||
*/
|
||||
ActionSelector.prototype._refresh = function() {
|
||||
var self = this;
|
||||
return self._render().then(function(html) {
|
||||
self._find('[data-region="action-selector"]').replaceWith(html);
|
||||
self._afterRender();
|
||||
}.bind(self));
|
||||
};
|
||||
|
||||
/**
|
||||
* Render the dialogue.
|
||||
*
|
||||
* @method _render
|
||||
* @return {Promise}
|
||||
*/
|
||||
ActionSelector.prototype._render = function() {
|
||||
var self = this;
|
||||
var choices = [];
|
||||
for (var i in self._actions) {
|
||||
choices.push(self._actions[i]);
|
||||
}
|
||||
var content = {'message': self._message, 'choices' : choices,
|
||||
'confirm' : self._confirm, 'cancel' : self._cancel};
|
||||
|
||||
return Templates.render('tool_lp/action_selector', content);
|
||||
};
|
||||
|
||||
/**
|
||||
* Reset the dialogue properties.
|
||||
*
|
||||
* This does not reset everything, just enough to reset the UI.
|
||||
*
|
||||
* @method _reset
|
||||
*/
|
||||
ActionSelector.prototype._reset = function() {
|
||||
this._popup = null;
|
||||
this._selectedValue = '';
|
||||
};
|
||||
|
||||
return /** @alias module:tool_lp/actionselector */ ActionSelector;
|
||||
|
||||
});
|
||||
@@ -1,338 +0,0 @@
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Handle add/remove competency links.
|
||||
*
|
||||
* @module tool_lp/competencies
|
||||
* @package tool_lp
|
||||
* @copyright 2015 Damyon Wiese <damyon@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
define(['jquery',
|
||||
'core/notification',
|
||||
'core/ajax',
|
||||
'core/templates',
|
||||
'core/str',
|
||||
'tool_lp/competencypicker',
|
||||
'tool_lp/dragdrop-reorder'],
|
||||
function($, notification, ajax, templates, str, Picker, dragdrop) {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {Number} itemid
|
||||
* @param {String} itemtype
|
||||
*/
|
||||
var competencies = function(itemid, itemtype, pagectxid) {
|
||||
this.itemid = itemid;
|
||||
this.itemtype = itemtype;
|
||||
this.pageContextId = pagectxid;
|
||||
this.pickerInstance = null;
|
||||
|
||||
$('[data-region="actions"] button').prop('disabled', false);
|
||||
this.registerEvents();
|
||||
this.registerDragDrop();
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialise the drag/drop code.
|
||||
* @method registerDragDrop
|
||||
*/
|
||||
competencies.prototype.registerDragDrop = function() {
|
||||
var localthis = this;
|
||||
// Init this module.
|
||||
str.get_string('movecompetency', 'tool_lp').done(
|
||||
function(movestring) {
|
||||
dragdrop.dragdrop('movecompetency',
|
||||
movestring,
|
||||
{ identifier: 'movecompetency', component: 'tool_lp'},
|
||||
{ identifier: 'movecompetencyafter', component: 'tool_lp'},
|
||||
'drag-samenode',
|
||||
'drag-parentnode',
|
||||
'drag-handlecontainer',
|
||||
function(drag, drop) {
|
||||
localthis.handleDrop.call(localthis, drag, drop);
|
||||
});
|
||||
}
|
||||
).fail(notification.exception);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle a drop from a drag/drop operation.
|
||||
*
|
||||
* @method handleDrop
|
||||
* @param {DOMNode} drag The dragged node.
|
||||
* @param {DOMNode} drop The dropped on node.
|
||||
*/
|
||||
competencies.prototype.handleDrop = function(drag, drop) {
|
||||
var fromid = $(drag).data('id');
|
||||
var toid = $(drop).data('id');
|
||||
var localthis = this;
|
||||
var requests = [];
|
||||
|
||||
if (localthis.itemtype == 'course') {
|
||||
requests = ajax.call([
|
||||
{
|
||||
methodname: 'core_competency_reorder_course_competency',
|
||||
args: { courseid: localthis.itemid, competencyidfrom: fromid, competencyidto: toid }
|
||||
}
|
||||
]);
|
||||
} else if (localthis.itemtype == 'template') {
|
||||
requests = ajax.call([
|
||||
{
|
||||
methodname: 'core_competency_reorder_template_competency',
|
||||
args: { templateid: localthis.itemid, competencyidfrom: fromid, competencyidto: toid }
|
||||
}
|
||||
]);
|
||||
} else if (localthis.itemtype == 'plan') {
|
||||
requests = ajax.call([
|
||||
{
|
||||
methodname: 'core_competency_reorder_plan_competency',
|
||||
args: { planid: localthis.itemid, competencyidfrom: fromid, competencyidto: toid }
|
||||
}
|
||||
]);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
requests[0].fail(notification.exception);
|
||||
};
|
||||
|
||||
/**
|
||||
* Pick a competency
|
||||
*
|
||||
* @method pickCompetency
|
||||
*/
|
||||
competencies.prototype.pickCompetency = function() {
|
||||
var self = this;
|
||||
var requests;
|
||||
var pagerender;
|
||||
var pageregion;
|
||||
var pageContextIncludes;
|
||||
|
||||
if (!self.pickerInstance) {
|
||||
if (self.itemtype === 'template' || self.itemtype === 'course') {
|
||||
pageContextIncludes = 'parents';
|
||||
}
|
||||
self.pickerInstance = new Picker(self.pageContextId, false, pageContextIncludes);
|
||||
self.pickerInstance.on('save', function(e, data) {
|
||||
var compIds = data.competencyIds;
|
||||
|
||||
if (self.itemtype === "course") {
|
||||
requests = [];
|
||||
|
||||
$.each(compIds, function(index, compId) {
|
||||
requests.push({
|
||||
methodname: 'core_competency_add_competency_to_course',
|
||||
args: { courseid: self.itemid, competencyid: compId }
|
||||
});
|
||||
});
|
||||
requests.push({
|
||||
methodname: 'tool_lp_data_for_course_competencies_page',
|
||||
args: { courseid: self.itemid }
|
||||
});
|
||||
|
||||
pagerender = 'tool_lp/course_competencies_page';
|
||||
pageregion = 'coursecompetenciespage';
|
||||
|
||||
} else if (self.itemtype === "template") {
|
||||
requests = [];
|
||||
|
||||
$.each(compIds, function(index, compId) {
|
||||
requests.push({
|
||||
methodname: 'core_competency_add_competency_to_template',
|
||||
args: { templateid: self.itemid, competencyid: compId }
|
||||
});
|
||||
});
|
||||
requests.push({
|
||||
methodname: 'tool_lp_data_for_template_competencies_page',
|
||||
args: { templateid: self.itemid, pagecontext: { contextid: self.pageContextId }}
|
||||
});
|
||||
pagerender = 'tool_lp/template_competencies_page';
|
||||
pageregion = 'templatecompetenciespage';
|
||||
} else if (self.itemtype === "plan") {
|
||||
requests = [];
|
||||
|
||||
$.each(compIds, function(index, compId) {
|
||||
requests.push({
|
||||
methodname: 'core_competency_add_competency_to_plan',
|
||||
args: { planid: self.itemid, competencyid: compId }
|
||||
});
|
||||
});
|
||||
requests.push({
|
||||
methodname: 'tool_lp_data_for_plan_page',
|
||||
args: { planid: self.itemid}
|
||||
});
|
||||
pagerender = 'tool_lp/plan_page';
|
||||
pageregion = 'plan-page';
|
||||
}
|
||||
|
||||
ajax.call(requests)[requests.length - 1].then(function(context) {
|
||||
return templates.render(pagerender, context).done(function(html, js) {
|
||||
$('[data-region="' + pageregion + '"]').replaceWith(html);
|
||||
templates.runTemplateJS(js);
|
||||
});
|
||||
}, notification.exception);
|
||||
});
|
||||
}
|
||||
|
||||
self.pickerInstance.display();
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete the link between competency and course, template or plan. Reload the page.
|
||||
*
|
||||
* @method doDelete
|
||||
* @param {int} deleteid The id of record to delete.
|
||||
*/
|
||||
competencies.prototype.doDelete = function(deleteid) {
|
||||
var localthis = this;
|
||||
var requests = [],
|
||||
pagerender = '',
|
||||
pageregion = '';
|
||||
|
||||
// Delete the link and reload the page template.
|
||||
if (localthis.itemtype == 'course') {
|
||||
requests = ajax.call([
|
||||
{ methodname: 'core_competency_remove_competency_from_course',
|
||||
args: { courseid: localthis.itemid, competencyid: deleteid } },
|
||||
{ methodname: 'tool_lp_data_for_course_competencies_page',
|
||||
args: { courseid: localthis.itemid } }
|
||||
]);
|
||||
pagerender = 'tool_lp/course_competencies_page';
|
||||
pageregion = 'coursecompetenciespage';
|
||||
} else if (localthis.itemtype == 'template') {
|
||||
requests = ajax.call([
|
||||
{ methodname: 'core_competency_remove_competency_from_template',
|
||||
args: { templateid: localthis.itemid, competencyid: deleteid } },
|
||||
{ methodname: 'tool_lp_data_for_template_competencies_page',
|
||||
args: { templateid: localthis.itemid, pagecontext: { contextid: localthis.pageContextId } } }
|
||||
]);
|
||||
pagerender = 'tool_lp/template_competencies_page';
|
||||
pageregion = 'templatecompetenciespage';
|
||||
} else if (localthis.itemtype == 'plan') {
|
||||
requests = ajax.call([
|
||||
{ methodname: 'core_competency_remove_competency_from_plan',
|
||||
args: { planid: localthis.itemid, competencyid: deleteid } },
|
||||
{ methodname: 'tool_lp_data_for_plan_page',
|
||||
args: { planid: localthis.itemid } }
|
||||
]);
|
||||
pagerender = 'tool_lp/plan_page';
|
||||
pageregion = 'plan-page';
|
||||
}
|
||||
|
||||
requests[1].done(function(context) {
|
||||
templates.render(pagerender, context).done(function(html, js) {
|
||||
$('[data-region="' + pageregion + '"]').replaceWith(html);
|
||||
templates.runTemplateJS(js);
|
||||
}).fail(notification.exception);
|
||||
}).fail(notification.exception);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Show a confirm dialogue before deleting a competency.
|
||||
*
|
||||
* @method deleteHandler
|
||||
* @param {int} deleteid The id of record to delete.
|
||||
*/
|
||||
competencies.prototype.deleteHandler = function(deleteid) {
|
||||
var localthis = this;
|
||||
var requests = [];
|
||||
var message;
|
||||
|
||||
if (localthis.itemtype == 'course') {
|
||||
message = 'unlinkcompetencycourse';
|
||||
} else if (localthis.itemtype == 'template') {
|
||||
message = 'unlinkcompetencytemplate';
|
||||
} else if (localthis.itemtype == 'plan') {
|
||||
message = 'unlinkcompetencyplan';
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
requests = ajax.call([{
|
||||
methodname: 'core_competency_read_competency',
|
||||
args: { id: deleteid }
|
||||
}]);
|
||||
|
||||
requests[0].done(function(competency) {
|
||||
str.get_strings([
|
||||
{ key: 'confirm', component: 'moodle' },
|
||||
{ key: message, component: 'tool_lp', param: competency.shortname },
|
||||
{ key: 'confirm', component: 'moodle' },
|
||||
{ key: 'cancel', component: 'moodle' }
|
||||
]).done(function (strings) {
|
||||
notification.confirm(
|
||||
strings[0], // Confirm.
|
||||
strings[1], // Unlink the competency X from the course?
|
||||
strings[2], // Confirm.
|
||||
strings[3], // Cancel.
|
||||
function() {
|
||||
localthis.doDelete(deleteid);
|
||||
}
|
||||
);
|
||||
}).fail(notification.exception);
|
||||
}).fail(notification.exception);
|
||||
};
|
||||
|
||||
/**
|
||||
* Register the javascript event handlers for this page.
|
||||
*
|
||||
* @method registerEvents
|
||||
*/
|
||||
competencies.prototype.registerEvents = function() {
|
||||
var localthis = this;
|
||||
|
||||
if (localthis.itemtype == 'course') {
|
||||
// Course completion rule handling.
|
||||
$('[data-region="coursecompetenciespage"]').on('change', 'select[data-field="ruleoutcome"]', function(e){
|
||||
var requests = [];
|
||||
var pagerender = 'tool_lp/course_competencies_page';
|
||||
var pageregion = 'coursecompetenciespage';
|
||||
var coursecompetencyid = $(e.target).data('id');
|
||||
var ruleoutcome = $(e.target).val();
|
||||
requests = ajax.call([
|
||||
{ methodname: 'core_competency_set_course_competency_ruleoutcome',
|
||||
args: { coursecompetencyid: coursecompetencyid, ruleoutcome: ruleoutcome } },
|
||||
{ methodname: 'tool_lp_data_for_course_competencies_page',
|
||||
args: { courseid: localthis.itemid } }
|
||||
]);
|
||||
|
||||
requests[1].done(function(context) {
|
||||
templates.render(pagerender, context).done(function(html, js) {
|
||||
$('[data-region="' + pageregion + '"]').replaceWith(html);
|
||||
templates.runTemplateJS(js);
|
||||
}).fail(notification.exception);
|
||||
}).fail(notification.exception);
|
||||
});
|
||||
}
|
||||
|
||||
$('[data-region="actions"] button').click(function(e) {
|
||||
e.preventDefault();
|
||||
localthis.pickCompetency();
|
||||
});
|
||||
$('[data-action="delete-competency-link"]').click(function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
var deleteid = $(e.target).closest('[data-id]').data('id');
|
||||
localthis.deleteHandler(deleteid);
|
||||
});
|
||||
};
|
||||
|
||||
return /** @alias module:tool_lp/competencies */ competencies;
|
||||
});
|
||||
@@ -1,83 +0,0 @@
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Competency rule config.
|
||||
*
|
||||
* @package tool_lp
|
||||
* @copyright 2015 Frédéric Massart - FMCorz.net
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
define(['jquery',
|
||||
'core/str'],
|
||||
function($, Str) {
|
||||
|
||||
var OUTCOME_NONE = 0,
|
||||
OUTCOME_EVIDENCE = 1,
|
||||
OUTCOME_COMPLETE = 2,
|
||||
OUTCOME_RECOMMEND = 3;
|
||||
|
||||
return /** @alias module:tool_lp/competency_outcomes */ {
|
||||
|
||||
NONE: OUTCOME_NONE,
|
||||
EVIDENCE: OUTCOME_EVIDENCE,
|
||||
COMPLETE: OUTCOME_COMPLETE,
|
||||
RECOMMEND: OUTCOME_RECOMMEND,
|
||||
|
||||
/**
|
||||
* Get all the outcomes.
|
||||
*
|
||||
* @return {Object} Indexed by outcome code, contains code and name.
|
||||
* @method getAll
|
||||
*/
|
||||
getAll: function() {
|
||||
var self = this;
|
||||
return Str.get_strings([
|
||||
{ key: 'competencyoutcome_none', component: 'tool_lp' },
|
||||
{ key: 'competencyoutcome_evidence', component: 'tool_lp' },
|
||||
{ key: 'competencyoutcome_recommend', component: 'tool_lp' },
|
||||
{ key: 'competencyoutcome_complete', component: 'tool_lp' },
|
||||
]).then(function(strings) {
|
||||
var outcomes = {};
|
||||
outcomes[self.NONE] = { code: self.NONE, name: strings[0] };
|
||||
outcomes[self.EVIDENCE] = { code: self.EVIDENCE, name: strings[1] };
|
||||
outcomes[self.RECOMMEND] = { code: self.RECOMMEND, name: strings[2] };
|
||||
outcomes[self.COMPLETE] = { code: self.COMPLETE, name: strings[3] };
|
||||
return outcomes;
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the string for an outcome.
|
||||
*
|
||||
* @param {Number} id The outcome code.
|
||||
* @return {Promise Resolved with the string.
|
||||
* @method getString
|
||||
*/
|
||||
getString: function(id) {
|
||||
var self = this,
|
||||
all = self.getAll();
|
||||
|
||||
return all.then(function(outcomes) {
|
||||
if (typeof outcomes[id] === 'undefined') {
|
||||
return $.Deferred().reject().promise();
|
||||
}
|
||||
return outcomes[id].name;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
});
|
||||
@@ -1,74 +0,0 @@
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Event click on selecting competency in the competency autocomplete.
|
||||
*
|
||||
* @package tool_lp
|
||||
* @copyright 2016 Issam Taboubi <issam.taboubi@umontreal.ca>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
define(['jquery'], function($) {
|
||||
|
||||
/**
|
||||
* CompetencyPlanNavigation
|
||||
*
|
||||
* @param {String} The selector of the competency element.
|
||||
* @param {String} The base url for the page (no params).
|
||||
* @param {Number} The user id
|
||||
* @param {Number} The competency id
|
||||
* @param {Number} The plan id
|
||||
*/
|
||||
var CompetencyPlanNavigation = function(competencySelector, baseUrl, userId, competencyId, planId) {
|
||||
this._baseUrl = baseUrl;
|
||||
this._userId = userId + '';
|
||||
this._competencyId = competencyId + '';
|
||||
this._planId = planId;
|
||||
this._ignoreFirstCompetency = true;
|
||||
|
||||
$(competencySelector).on('change', this._competencyChanged.bind(this));
|
||||
};
|
||||
|
||||
/**
|
||||
* The competency was changed in the select list.
|
||||
*
|
||||
* @method _competencyChanged
|
||||
* @param {Event} e
|
||||
*/
|
||||
CompetencyPlanNavigation.prototype._competencyChanged = function(e) {
|
||||
if (this._ignoreFirstCompetency) {
|
||||
this._ignoreFirstCompetency = false;
|
||||
return;
|
||||
}
|
||||
var newCompetencyId = $(e.target).val();
|
||||
var queryStr = '?userid=' + this._userId + '&planid=' + this._planId + '&competencyid=' + newCompetencyId;
|
||||
document.location = this._baseUrl + queryStr;
|
||||
};
|
||||
|
||||
/** @type {Number} The id of the competency. */
|
||||
CompetencyPlanNavigation.prototype._competencyId = null;
|
||||
/** @type {Number} The id of the user. */
|
||||
CompetencyPlanNavigation.prototype._userId = null;
|
||||
/** @type {Number} The id of the plan. */
|
||||
CompetencyPlanNavigation.prototype._planId = null;
|
||||
/** @type {String} Plugin base url. */
|
||||
CompetencyPlanNavigation.prototype._baseUrl = null;
|
||||
/** @type {Boolean} Ignore the first change event for competencies. */
|
||||
CompetencyPlanNavigation.prototype._ignoreFirstCompetency = null;
|
||||
|
||||
return /** @alias module:tool_lp/competency_plan_navigation */ CompetencyPlanNavigation;
|
||||
|
||||
});
|
||||
@@ -1,175 +0,0 @@
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Competency rule base module.
|
||||
*
|
||||
* @package tool_lp
|
||||
* @copyright 2015 Frédéric Massart - FMCorz.net
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
define(['jquery'], function($) {
|
||||
|
||||
/**
|
||||
* Competency rule abstract class.
|
||||
*
|
||||
* Any competency rule should extend this object. The event 'change' should be
|
||||
* triggered on the instance when the configuration has changed. This will allow
|
||||
* the components using the rule to gather the config, or check its validity.
|
||||
*
|
||||
* this._triggerChange();
|
||||
*
|
||||
* @param {Tree} tree The competency tree.
|
||||
*/
|
||||
var Rule = function(tree) {
|
||||
this._eventNode = $('<div>');
|
||||
this._ready = $.Deferred();
|
||||
this._tree = tree;
|
||||
};
|
||||
|
||||
/** @type {Object} The current competency. */
|
||||
Rule.prototype._competency = null;
|
||||
/** @type {Node} The node we attach the events to. */
|
||||
Rule.prototype._eventNode = null;
|
||||
/** @type {Promise} Resolved when the object is ready. */
|
||||
Rule.prototype._ready = null;
|
||||
/** @type {Tree} The competency tree. */
|
||||
Rule.prototype._tree = null;
|
||||
|
||||
/**
|
||||
* Whether or not the current competency can be configured using this rule.
|
||||
*
|
||||
* @return {Boolean}
|
||||
* @method canConfig
|
||||
*/
|
||||
Rule.prototype.canConfig = function() {
|
||||
return this._tree.hasChildren(this._competency.id);
|
||||
};
|
||||
|
||||
/**
|
||||
* The config established by this rule.
|
||||
*
|
||||
* To override in subclasses when relevant.
|
||||
*
|
||||
* @return {String|null}
|
||||
* @method getConfig
|
||||
*/
|
||||
Rule.prototype.getConfig = function() {
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the type of the module.
|
||||
*
|
||||
* @return {String}
|
||||
* @method getType
|
||||
*/
|
||||
Rule.prototype.getType = function() {
|
||||
throw new Error('Not implemented');
|
||||
};
|
||||
|
||||
/**
|
||||
* The init process.
|
||||
*
|
||||
* Do not override this, instead override _load.
|
||||
*
|
||||
* @return {Promise} Revoled when the plugin is initialised.
|
||||
* @method init
|
||||
*/
|
||||
Rule.prototype.init = function() {
|
||||
return this._load();
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback to inject the template.
|
||||
*
|
||||
* @param {Node} container Node to inject in.
|
||||
* @return {Promise} Resolved when done.
|
||||
* @method injectTemplate
|
||||
*/
|
||||
Rule.prototype.injectTemplate = function() {
|
||||
return $.Deferred().reject().promise();
|
||||
};
|
||||
|
||||
/**
|
||||
* Whether or not the current config is valid.
|
||||
*
|
||||
* Plugins should override this.
|
||||
*
|
||||
* @return {Boolean}
|
||||
* @method _isValid
|
||||
*/
|
||||
Rule.prototype.isValid = function() {
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Load the class.
|
||||
*
|
||||
* @return {Promise}
|
||||
* @method _load
|
||||
* @protected
|
||||
*/
|
||||
Rule.prototype._load = function() {
|
||||
return $.when();
|
||||
};
|
||||
|
||||
/**
|
||||
* Register an event listener.
|
||||
*
|
||||
* @param {String} type The event type.
|
||||
* @param {Function} handler The event listener.
|
||||
* @method on
|
||||
*/
|
||||
Rule.prototype.on = function(type, handler) {
|
||||
this._eventNode.on(type, handler);
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the current competency.
|
||||
*
|
||||
* @param {Competency} competency
|
||||
* @method setTargetCompetency
|
||||
*/
|
||||
Rule.prototype.setTargetCompetency = function(competency) {
|
||||
this._competency = competency;
|
||||
};
|
||||
|
||||
/**
|
||||
* Trigger an event.
|
||||
*
|
||||
* @param {String} type The type of event.
|
||||
* @param {Object} The data to pass to the listeners.
|
||||
* @method _trigger
|
||||
* @protected
|
||||
*/
|
||||
Rule.prototype._trigger = function(type, data) {
|
||||
this._eventNode.trigger(type, [data]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Trigger the change event.
|
||||
*
|
||||
* @method _triggerChange
|
||||
* @protected
|
||||
*/
|
||||
Rule.prototype._triggerChange = function() {
|
||||
this._trigger('change', this);
|
||||
};
|
||||
|
||||
return /** @alias module:tool_lp/competency_rule */ Rule;
|
||||
|
||||
});
|
||||
@@ -1,60 +0,0 @@
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Competency rule all module.
|
||||
*
|
||||
* @package tool_lp
|
||||
* @copyright 2015 Frédéric Massart - FMCorz.net
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
define(['jquery',
|
||||
'core/str',
|
||||
'tool_lp/competency_rule',
|
||||
],
|
||||
function($, Str, RuleBase) {
|
||||
|
||||
/**
|
||||
* Competency rule all class.
|
||||
*/
|
||||
var Rule = function() {
|
||||
RuleBase.apply(this, arguments);
|
||||
};
|
||||
Rule.prototype = Object.create(RuleBase.prototype);
|
||||
|
||||
/**
|
||||
* Return the type of the module.
|
||||
*
|
||||
* @return {String}
|
||||
* @method getType
|
||||
*/
|
||||
Rule.prototype.getType = function() {
|
||||
return 'core_competency\\competency_rule_all';
|
||||
};
|
||||
|
||||
/**
|
||||
* Whether or not the current config is valid.
|
||||
*
|
||||
* @return {Boolean}
|
||||
* @method isValid
|
||||
*/
|
||||
Rule.prototype.isValid = function() {
|
||||
return true;
|
||||
};
|
||||
|
||||
return /** @alias module:tool_lp/competency_rule_all */ Rule;
|
||||
|
||||
});
|
||||
@@ -1,199 +0,0 @@
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Competency rule points module.
|
||||
*
|
||||
* @package tool_lp
|
||||
* @copyright 2015 Frédéric Massart - FMCorz.net
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
define(['jquery',
|
||||
'core/str',
|
||||
'core/templates',
|
||||
'tool_lp/competency_rule',
|
||||
],
|
||||
function($, Str, Templates, RuleBase) {
|
||||
|
||||
/**
|
||||
* Competency rule points class.
|
||||
*/
|
||||
var Rule = function() {
|
||||
RuleBase.apply(this, arguments);
|
||||
};
|
||||
Rule.prototype = Object.create(RuleBase.prototype);
|
||||
|
||||
/** @type {Node} Reference to the container in which the template was included. */
|
||||
Rule.prototype._container = null;
|
||||
/** @type {Boolean} Whether or not the template was included. */
|
||||
Rule.prototype._templateLoaded = false;
|
||||
|
||||
/**
|
||||
* The config established by this rule.
|
||||
*
|
||||
* @return {String}
|
||||
* @method getConfig
|
||||
*/
|
||||
Rule.prototype.getConfig = function() {
|
||||
return JSON.stringify({
|
||||
base: {
|
||||
points: this._getRequiredPoints(),
|
||||
},
|
||||
competencies: this._getCompetenciesConfig()
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Gathers the input provided by the user for competencies.
|
||||
*
|
||||
* @return {Array} Containing id, points and required.
|
||||
* @method _getCompetenciesConfig
|
||||
* @protected
|
||||
*/
|
||||
Rule.prototype._getCompetenciesConfig = function() {
|
||||
var competencies = [];
|
||||
|
||||
this._container.find('[data-competency]').each(function() {
|
||||
var node = $(this),
|
||||
id = node.data('competency'),
|
||||
points = parseInt(node.find('[name="points"]').val(), 10),
|
||||
required = node.find('[name="required"]').prop('checked');
|
||||
|
||||
competencies.push({
|
||||
id: id,
|
||||
points: points,
|
||||
required: required ? 1 : 0
|
||||
});
|
||||
});
|
||||
|
||||
return competencies;
|
||||
};
|
||||
|
||||
/**
|
||||
* Fetches the required points set by the user.
|
||||
*
|
||||
* @return {Number}
|
||||
* @method _getRequiredPoints
|
||||
* @protected
|
||||
*/
|
||||
Rule.prototype._getRequiredPoints = function() {
|
||||
return parseInt(this._container.find('[name="requiredpoints"]').val() || 1, 10);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the type of the module.
|
||||
*
|
||||
* @return {String}
|
||||
* @method getType
|
||||
*/
|
||||
Rule.prototype.getType = function() {
|
||||
return 'core_competency\\competency_rule_points';
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback to inject the template.
|
||||
*
|
||||
* @param {Node} container Node to inject in.
|
||||
* @return {Promise} Resolved when done.
|
||||
* @method injectTemplate
|
||||
*/
|
||||
Rule.prototype.injectTemplate = function(container) {
|
||||
var self = this,
|
||||
children = this._tree.getChildren(this._competency.id),
|
||||
context,
|
||||
config = {
|
||||
base: { points: 2 },
|
||||
competencies: []
|
||||
};
|
||||
|
||||
this._templateLoaded = false;
|
||||
|
||||
// Only pre-load the configuration when the competency is using this rule.
|
||||
if (self._competency.ruletype == self.getType()) {
|
||||
try {
|
||||
config = JSON.parse(self._competency.ruleconfig);
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
|
||||
context = {
|
||||
requiredpoints: (config && config.base) ? config.base.points : 2,
|
||||
competency: self._competency,
|
||||
children: []
|
||||
};
|
||||
|
||||
$.each(children, function(index, child) {
|
||||
var competency = {
|
||||
id: child.id,
|
||||
shortname: child.shortname,
|
||||
required: false,
|
||||
points: 0
|
||||
};
|
||||
|
||||
if (config) {
|
||||
$.each(config.competencies, function(index, comp) {
|
||||
if (comp.id == competency.id) {
|
||||
competency.required = comp.required ? true : false;
|
||||
competency.points = comp.points;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
context.children.push(competency);
|
||||
});
|
||||
|
||||
return Templates.render('tool_lp/competency_rule_points', context).then(function(html) {
|
||||
self._container = container;
|
||||
container.html(html);
|
||||
container.find('input').change(function() {
|
||||
self._triggerChange();
|
||||
});
|
||||
|
||||
// We're done, let's trigger a change.
|
||||
self._templateLoaded = true;
|
||||
self._triggerChange();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Whether or not the current config is valid.
|
||||
*
|
||||
* @return {Boolean}
|
||||
* @method isValid
|
||||
*/
|
||||
Rule.prototype.isValid = function() {
|
||||
if (!this._templateLoaded) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var required = this._getRequiredPoints(),
|
||||
max = 0,
|
||||
valid = true;
|
||||
|
||||
$.each(this._getCompetenciesConfig(), function(index, competency) {
|
||||
if (competency.points < 0) {
|
||||
valid = false;
|
||||
}
|
||||
max += competency.points;
|
||||
});
|
||||
|
||||
valid = valid && max >= required;
|
||||
return valid;
|
||||
};
|
||||
|
||||
return /** @alias module:tool_lp/competency_rule_all */ Rule;
|
||||
|
||||
});
|
||||
@@ -1,843 +0,0 @@
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Handle selection changes and actions on the competency tree.
|
||||
*
|
||||
* @module tool_lp/competencyactions
|
||||
* @package tool_lp
|
||||
* @copyright 2015 Damyon Wiese <damyon@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
define(['jquery',
|
||||
'core/url',
|
||||
'core/templates',
|
||||
'core/notification',
|
||||
'core/str',
|
||||
'core/ajax',
|
||||
'tool_lp/dragdrop-reorder',
|
||||
'tool_lp/tree',
|
||||
'tool_lp/dialogue',
|
||||
'tool_lp/menubar',
|
||||
'tool_lp/competencypicker',
|
||||
'tool_lp/competency_outcomes',
|
||||
'tool_lp/competencyruleconfig'],
|
||||
function($, url, templates, notification, str, ajax, dragdrop, Ariatree, Dialogue, menubar, Picker, Outcomes, RuleConfig) {
|
||||
|
||||
// Private variables and functions.
|
||||
/** @var {Object} treeModel - This is an object representing the nodes in the tree. */
|
||||
var treeModel = null;
|
||||
/** @var {Node} moveSource - The start of a drag operation */
|
||||
var moveSource = null;
|
||||
/** @var {Node} moveTarget - The end of a drag operation */
|
||||
var moveTarget = null;
|
||||
/** @var {Number} pageContextId The page context ID. */
|
||||
var pageContextId;
|
||||
/** @type {Object} Picker instance. */
|
||||
var pickerInstance;
|
||||
/** @type {Object} Rule config instance. */
|
||||
var ruleConfigInstance;
|
||||
/** @type {Object} The competency we're picking a relation to. */
|
||||
var relatedTarget;
|
||||
/** @type {Object} Taxonomy constants indexed per level. */
|
||||
var taxonomiesConstants;
|
||||
/** @type {Array} The rules modules. Values are object containing type, namd and amd. */
|
||||
var rulesModules;
|
||||
/** @type {Number} the selected competency ID. */
|
||||
var selectedCompetencyId = null;
|
||||
|
||||
/**
|
||||
* Respond to choosing the "Add" menu item for the selected node in the tree.
|
||||
* @method addHandler
|
||||
*/
|
||||
var addHandler = function() {
|
||||
var parent = $('[data-region="competencyactions"]').data('competency');
|
||||
|
||||
var params = {
|
||||
competencyframeworkid : treeModel.getCompetencyFrameworkId(),
|
||||
pagecontextid: pageContextId
|
||||
};
|
||||
|
||||
if (parent !== null) {
|
||||
// We are adding at a sub node.
|
||||
params.parentid = parent.id;
|
||||
}
|
||||
|
||||
var relocate = function() {
|
||||
var queryparams = $.param(params);
|
||||
window.location = url.relativeUrl('/admin/tool/lp/editcompetency.php?' + queryparams);
|
||||
};
|
||||
|
||||
if (parent !== null && treeModel.hasRule(parent.id)) {
|
||||
str.get_strings([
|
||||
{ key: 'confirm', component: 'moodle' },
|
||||
{ key: 'addingcompetencywillresetparentrule', component: 'tool_lp', param: parent.shortname },
|
||||
{ key: 'yes', component: 'core' },
|
||||
{ key: 'no', component: 'core' }
|
||||
]).done(function (strings) {
|
||||
notification.confirm(
|
||||
strings[0],
|
||||
strings[1],
|
||||
strings[2],
|
||||
strings[3],
|
||||
relocate
|
||||
);
|
||||
}).fail(notification.exception);
|
||||
} else {
|
||||
relocate();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* A source and destination has been chosen - so time to complete a move.
|
||||
* @method doMove
|
||||
*/
|
||||
var doMove = function() {
|
||||
var frameworkid = $('[data-region="filtercompetencies"]').data('frameworkid');
|
||||
var requests = ajax.call([{
|
||||
methodname: 'core_competency_set_parent_competency',
|
||||
args: { competencyid: moveSource, parentid: moveTarget }
|
||||
}, {
|
||||
methodname: 'tool_lp_data_for_competencies_manage_page',
|
||||
args: { competencyframeworkid: frameworkid,
|
||||
search: $('[data-region="filtercompetencies"] input').val() }
|
||||
}]);
|
||||
requests[1].done(reloadPage).fail(notification.exception);
|
||||
};
|
||||
|
||||
/**
|
||||
* Confirms a competency move.
|
||||
*
|
||||
* @method confirmMove
|
||||
*/
|
||||
var confirmMove = function() {
|
||||
moveTarget = typeof moveTarget === "undefined" ? 0 : moveTarget;
|
||||
if (moveTarget == moveSource) {
|
||||
// No move to do.
|
||||
return;
|
||||
}
|
||||
|
||||
var targetComp = treeModel.getCompetency(moveTarget) || {},
|
||||
sourceComp = treeModel.getCompetency(moveSource) || {},
|
||||
confirmMessage = 'movecompetencywillresetrules',
|
||||
showConfirm = false;
|
||||
|
||||
// We shouldn't be moving the competency to the same parent.
|
||||
if (sourceComp.parentid == moveTarget) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If we are moving to a child of self.
|
||||
if (targetComp.path && targetComp.path.indexOf('/' + sourceComp.id + '/') >= 0) {
|
||||
confirmMessage = 'movecompetencytochildofselfwillresetrules';
|
||||
|
||||
// Show a confirmation if self has rules, as they'll disappear.
|
||||
showConfirm = showConfirm || treeModel.hasRule(sourceComp.id);
|
||||
}
|
||||
|
||||
// Show a confirmation if the current parent, or the destination have rules.
|
||||
showConfirm = showConfirm || (treeModel.hasRule(targetComp.id) || treeModel.hasRule(sourceComp.parentid));
|
||||
|
||||
// Show confirm, and/or do the things.
|
||||
if (showConfirm) {
|
||||
str.get_strings([
|
||||
{ key: 'confirm', component: 'moodle' },
|
||||
{ key: confirmMessage, component: 'tool_lp' },
|
||||
{ key: 'yes', component: 'moodle' },
|
||||
{ key: 'no', component: 'moodle' }
|
||||
]).done(function (strings) {
|
||||
notification.confirm(
|
||||
strings[0], // Confirm.
|
||||
strings[1], // Delete competency X?
|
||||
strings[2], // Delete.
|
||||
strings[3], // Cancel.
|
||||
doMove
|
||||
);
|
||||
}).fail(notification.exception);
|
||||
|
||||
} else {
|
||||
doMove();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* A move competency popup was opened - initialise the aria tree in it.
|
||||
* @method initMovePopup
|
||||
* @param {dialogue} popup The tool_lp/dialogue that was created.
|
||||
*/
|
||||
var initMovePopup = function(popup) {
|
||||
var body = $(popup.getContent());
|
||||
var treeRoot = body.find('[data-enhance=movetree]');
|
||||
var tree = new Ariatree(treeRoot, false);
|
||||
tree.on('selectionchanged', function(evt, params) {
|
||||
var target = params.selected;
|
||||
moveTarget = $(target).data('id');
|
||||
});
|
||||
treeRoot.show();
|
||||
|
||||
body.on('click', '[data-action="move"]', function() { popup.close(); confirmMove(); });
|
||||
body.on('click', '[data-action="cancel"]', function() { popup.close(); });
|
||||
};
|
||||
|
||||
/**
|
||||
* Turn a flat list of competencies into a tree structure (recursive).
|
||||
* @method addCompetencyChildren
|
||||
* @param {Object} parent The current parent node in the tree
|
||||
* @param {Object[]} competencies The flat list of competencies
|
||||
*/
|
||||
var addCompetencyChildren = function(parent, competencies) {
|
||||
var i;
|
||||
|
||||
for (i = 0; i < competencies.length; i++) {
|
||||
if (competencies[i].parentid == parent.id) {
|
||||
parent.haschildren = true;
|
||||
competencies[i].children = [];
|
||||
competencies[i].haschildren = false;
|
||||
parent.children[parent.children.length] = competencies[i];
|
||||
addCompetencyChildren(competencies[i], competencies);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* A node was chosen and "Move" was selected from the menu. Open a popup to select the target.
|
||||
* @method moveHandler
|
||||
*/
|
||||
var moveHandler = function(e) {
|
||||
e.preventDefault();
|
||||
var competency = $('[data-region="competencyactions"]').data('competency');
|
||||
|
||||
// Remember what we are moving.
|
||||
moveSource = competency.id;
|
||||
|
||||
// Load data for the template.
|
||||
var requests = ajax.call([
|
||||
{
|
||||
methodname: 'core_competency_search_competencies',
|
||||
args: {
|
||||
competencyframeworkid: competency.competencyframeworkid,
|
||||
searchtext: ''
|
||||
}
|
||||
},{
|
||||
methodname: 'core_competency_read_competency_framework',
|
||||
args: {
|
||||
id: competency.competencyframeworkid
|
||||
}
|
||||
}
|
||||
]);
|
||||
|
||||
// When all data has arrived, continue.
|
||||
$.when.apply(null, requests).done(function(competencies, framework) {
|
||||
|
||||
// Expand the list of competencies into a tree.
|
||||
var i, competenciestree = [];
|
||||
for (i = 0; i < competencies.length; i++) {
|
||||
var onecompetency = competencies[i];
|
||||
if (onecompetency.parentid == "0") {
|
||||
onecompetency.children = [];
|
||||
onecompetency.haschildren = 0;
|
||||
competenciestree[competenciestree.length] = onecompetency;
|
||||
addCompetencyChildren(onecompetency, competencies);
|
||||
}
|
||||
}
|
||||
|
||||
str.get_strings([
|
||||
{ key: 'movecompetency', component: 'tool_lp', param: competency.shortname },
|
||||
{ key: 'move', component: 'tool_lp' },
|
||||
{ key: 'cancel', component: 'moodle' }
|
||||
]).done(function (strings) {
|
||||
|
||||
var context = {
|
||||
framework: framework,
|
||||
competencies: competenciestree
|
||||
};
|
||||
|
||||
templates.render('tool_lp/competencies_move_tree', context)
|
||||
.done(function(tree) {
|
||||
new Dialogue(
|
||||
strings[0], // Move competency x.
|
||||
tree, // The move tree.
|
||||
initMovePopup
|
||||
);
|
||||
|
||||
}).fail(notification.exception);
|
||||
|
||||
}).fail(notification.exception);
|
||||
|
||||
}).fail(notification.exception);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Edit the selected competency.
|
||||
* @method editHandler
|
||||
*/
|
||||
var editHandler = function() {
|
||||
var competency = $('[data-region="competencyactions"]').data('competency');
|
||||
|
||||
var params = {
|
||||
competencyframeworkid : treeModel.getCompetencyFrameworkId(),
|
||||
id : competency.id,
|
||||
parentid: competency.parentid,
|
||||
pagecontextid: pageContextId
|
||||
};
|
||||
|
||||
var queryparams = $.param(params);
|
||||
window.location = url.relativeUrl('/admin/tool/lp/editcompetency.php?' + queryparams);
|
||||
};
|
||||
|
||||
/**
|
||||
* Re-render the page with the latest data.
|
||||
* @method reloadPage
|
||||
*/
|
||||
var reloadPage = function(context) {
|
||||
templates.render('tool_lp/manage_competencies_page', context)
|
||||
.done(function(newhtml, newjs) {
|
||||
$('[data-region="managecompetencies"]').replaceWith(newhtml);
|
||||
templates.runTemplateJS(newjs);
|
||||
})
|
||||
.fail(notification.exception);
|
||||
};
|
||||
|
||||
/**
|
||||
* Perform a search and render the page with the new search results.
|
||||
* @method updateSearchHandler
|
||||
*/
|
||||
var updateSearchHandler = function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
var frameworkid = $('[data-region="filtercompetencies"]').data('frameworkid');
|
||||
|
||||
var requests = ajax.call([{
|
||||
methodname: 'tool_lp_data_for_competencies_manage_page',
|
||||
args: { competencyframeworkid: frameworkid,
|
||||
search: $('[data-region="filtercompetencies"] input').val() }
|
||||
}]);
|
||||
requests[0].done(reloadPage).fail(notification.exception);
|
||||
};
|
||||
|
||||
/**
|
||||
* Move a competency "up". This only affects the sort order within the same branch of the tree.
|
||||
* @method moveUpHandler
|
||||
*/
|
||||
var moveUpHandler = function() {
|
||||
// We are chaining ajax requests here.
|
||||
var competency = $('[data-region="competencyactions"]').data('competency');
|
||||
var requests = ajax.call([{
|
||||
methodname: 'core_competency_move_up_competency',
|
||||
args: { id: competency.id }
|
||||
}, {
|
||||
methodname: 'tool_lp_data_for_competencies_manage_page',
|
||||
args: { competencyframeworkid: competency.competencyframeworkid,
|
||||
search: $('[data-region="filtercompetencies"] input').val() }
|
||||
}]);
|
||||
requests[1].done(reloadPage).fail(notification.exception);
|
||||
};
|
||||
|
||||
/**
|
||||
* Move a competency "down". This only affects the sort order within the same branch of the tree.
|
||||
* @method moveDownHandler
|
||||
*/
|
||||
var moveDownHandler = function() {
|
||||
// We are chaining ajax requests here.
|
||||
var competency = $('[data-region="competencyactions"]').data('competency');
|
||||
var requests = ajax.call([{
|
||||
methodname: 'core_competency_move_down_competency',
|
||||
args: { id: competency.id }
|
||||
}, {
|
||||
methodname: 'tool_lp_data_for_competencies_manage_page',
|
||||
args: { competencyframeworkid: competency.competencyframeworkid,
|
||||
search: $('[data-region="filtercompetencies"] input').val() }
|
||||
}]);
|
||||
requests[1].done(reloadPage).fail(notification.exception);
|
||||
};
|
||||
|
||||
/**
|
||||
* Open a dialogue to show all the courses using the selected competency.
|
||||
* @method seeCoursesHandler
|
||||
*/
|
||||
var seeCoursesHandler = function() {
|
||||
var competency = $('[data-region="competencyactions"]').data('competency');
|
||||
|
||||
var requests = ajax.call([{
|
||||
methodname: 'tool_lp_list_courses_using_competency',
|
||||
args: { id: competency.id }
|
||||
}]);
|
||||
|
||||
requests[0].done(function(courses) {
|
||||
var context = {
|
||||
courses: courses
|
||||
};
|
||||
templates.render('tool_lp/linked_courses_summary', context).done(function(html) {
|
||||
str.get_string('linkedcourses', 'tool_lp').done(function (linkedcourses) {
|
||||
new Dialogue(
|
||||
linkedcourses, // Title.
|
||||
html, // The linked courses.
|
||||
initMovePopup
|
||||
);
|
||||
}).fail(notification.exception);
|
||||
}).fail(notification.exception);
|
||||
}).fail(notification.exception);
|
||||
};
|
||||
|
||||
/**
|
||||
* Open a competencies popup to relate competencies.
|
||||
*
|
||||
* @method relateCompetenciesHandler
|
||||
*/
|
||||
var relateCompetenciesHandler = function() {
|
||||
relatedTarget = $('[data-region="competencyactions"]').data('competency');
|
||||
|
||||
if (!pickerInstance) {
|
||||
pickerInstance = new Picker(pageContextId, relatedTarget.competencyframeworkid);
|
||||
pickerInstance.on('save', function(e, data) {
|
||||
var compIds = data.competencyIds;
|
||||
|
||||
var calls = [];
|
||||
$.each(compIds, function(index, value) {
|
||||
calls.push({
|
||||
methodname: 'core_competency_add_related_competency',
|
||||
args: { competencyid: value, relatedcompetencyid: relatedTarget.id }
|
||||
});
|
||||
});
|
||||
|
||||
calls.push( {
|
||||
methodname: 'tool_lp_data_for_related_competencies_section',
|
||||
args: { competencyid: relatedTarget.id }
|
||||
});
|
||||
|
||||
var promises = ajax.call(calls);
|
||||
|
||||
promises[calls.length - 1].then(function(context) {
|
||||
return templates.render('tool_lp/related_competencies', context).done(function(html, js) {
|
||||
$('[data-region="relatedcompetencies"]').replaceWith(html);
|
||||
templates.runTemplateJS(js);
|
||||
updatedRelatedCompetencies();
|
||||
});
|
||||
}, notification.exception);
|
||||
});
|
||||
}
|
||||
|
||||
pickerInstance.setDisallowedCompetencyIDs([relatedTarget.id]);
|
||||
pickerInstance.display();
|
||||
};
|
||||
|
||||
var ruleConfigHandler = function(e) {
|
||||
e.preventDefault();
|
||||
relatedTarget = $('[data-region="competencyactions"]').data('competency');
|
||||
ruleConfigInstance.setTargetCompetencyId(relatedTarget.id);
|
||||
ruleConfigInstance.display();
|
||||
};
|
||||
|
||||
var ruleConfigSaveHandler = function(e, config) {
|
||||
var update = {
|
||||
id: relatedTarget.id,
|
||||
shortname: relatedTarget.shortname,
|
||||
idnumber: relatedTarget.idnumber,
|
||||
description: relatedTarget.description,
|
||||
descriptionformat: relatedTarget.descriptionformat,
|
||||
ruletype: config.ruletype,
|
||||
ruleoutcome: config.ruleoutcome,
|
||||
ruleconfig: config.ruleconfig
|
||||
};
|
||||
var promise = ajax.call([{
|
||||
methodname: 'core_competency_update_competency',
|
||||
args: { competency: update }
|
||||
}]);
|
||||
promise[0].then(function(result) {
|
||||
if (result) {
|
||||
relatedTarget.ruletype = config.ruletype;
|
||||
relatedTarget.ruleoutcome = config.ruleoutcome;
|
||||
relatedTarget.ruleconfig = config.ruleconfig;
|
||||
renderCompetencySummary(relatedTarget);
|
||||
}
|
||||
}, notification.exception);
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete a competency.
|
||||
* @method doDelete
|
||||
*/
|
||||
var doDelete = function() {
|
||||
// We are chaining ajax requests here.
|
||||
var competency = $('[data-region="competencyactions"]').data('competency');
|
||||
var requests = ajax.call([{
|
||||
methodname: 'core_competency_delete_competency',
|
||||
args: { id: competency.id }
|
||||
}, {
|
||||
methodname: 'tool_lp_data_for_competencies_manage_page',
|
||||
args: { competencyframeworkid: competency.competencyframeworkid,
|
||||
search: $('[data-region="filtercompetencies"] input').val() }
|
||||
}]);
|
||||
requests[0].done(function(success) {
|
||||
if (success === false) {
|
||||
str.get_strings([
|
||||
{ key: 'competencycannotbedeleted', component: 'tool_lp', param: competency.shortname },
|
||||
{ key: 'cancel', component: 'moodle' }
|
||||
]).done(function (strings) {
|
||||
notification.alert(
|
||||
null,
|
||||
strings[0]
|
||||
);
|
||||
}).fail(notification.exception);
|
||||
}
|
||||
}).fail(notification.exception);
|
||||
requests[1].done(reloadPage).fail(notification.exception);
|
||||
};
|
||||
|
||||
/**
|
||||
* Show a confirm dialogue before deleting a competency.
|
||||
* @method deleteCompetencyHandler
|
||||
*/
|
||||
var deleteCompetencyHandler = function() {
|
||||
var competency = $('[data-region="competencyactions"]').data('competency'),
|
||||
confirmMessage = 'deletecompetency';
|
||||
|
||||
if (treeModel.hasRule(competency.parentid)) {
|
||||
confirmMessage = 'deletecompetencyparenthasrule';
|
||||
}
|
||||
|
||||
str.get_strings([
|
||||
{ key: 'confirm', component: 'moodle' },
|
||||
{ key: confirmMessage, component: 'tool_lp', param: competency.shortname },
|
||||
{ key: 'delete', component: 'moodle' },
|
||||
{ key: 'cancel', component: 'moodle' }
|
||||
]).done(function (strings) {
|
||||
notification.confirm(
|
||||
strings[0], // Confirm.
|
||||
strings[1], // Delete competency X?
|
||||
strings[2], // Delete.
|
||||
strings[3], // Cancel.
|
||||
doDelete
|
||||
);
|
||||
}).fail(notification.exception);
|
||||
};
|
||||
|
||||
/**
|
||||
* HTML5 implementation of drag/drop (there is an accesible alternative in the menus).
|
||||
* @method dragStart
|
||||
*/
|
||||
var dragStart = function(e) {
|
||||
e.originalEvent.dataTransfer.setData('text', $(e.target).parent().data('id'));
|
||||
};
|
||||
|
||||
/**
|
||||
* HTML5 implementation of drag/drop (there is an accesible alternative in the menus).
|
||||
* @method allowDrop
|
||||
*/
|
||||
var allowDrop = function(e) {
|
||||
e.originalEvent.dataTransfer.dropEffect = 'move';
|
||||
e.preventDefault();
|
||||
};
|
||||
|
||||
/**
|
||||
* HTML5 implementation of drag/drop (there is an accesible alternative in the menus).
|
||||
* @method dragEnter
|
||||
*/
|
||||
var dragEnter = function(e) {
|
||||
e.preventDefault();
|
||||
$(this).addClass('currentdragtarget');
|
||||
};
|
||||
|
||||
/**
|
||||
* HTML5 implementation of drag/drop (there is an accesible alternative in the menus).
|
||||
* @method dragLeave
|
||||
*/
|
||||
var dragLeave = function(e) {
|
||||
e.preventDefault();
|
||||
$(this).removeClass('currentdragtarget');
|
||||
};
|
||||
|
||||
/**
|
||||
* HTML5 implementation of drag/drop (there is an accesible alternative in the menus).
|
||||
* @method dropOver
|
||||
*/
|
||||
var dropOver = function(e) {
|
||||
e.preventDefault();
|
||||
moveSource = e.originalEvent.dataTransfer.getData('text');
|
||||
moveTarget = $(e.target).parent().data('id');
|
||||
$(this).removeClass('currentdragtarget');
|
||||
|
||||
confirmMove();
|
||||
};
|
||||
|
||||
/**
|
||||
* Deletes a related competency without confirmation.
|
||||
*
|
||||
* @param {Event} e The event that triggered the action.
|
||||
* @method deleteRelatedHandler
|
||||
*/
|
||||
var deleteRelatedHandler = function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
var relatedid = this.id.substr(11);
|
||||
var competency = $('[data-region="competencyactions"]').data('competency');
|
||||
var removeRelated = ajax.call([
|
||||
{ methodname: 'core_competency_remove_related_competency',
|
||||
args: { relatedcompetencyid: relatedid, competencyid: competency.id } },
|
||||
{ methodname: 'tool_lp_data_for_related_competencies_section',
|
||||
args: { competencyid: competency.id } }
|
||||
]);
|
||||
|
||||
removeRelated[1].done(function(context) {
|
||||
templates.render('tool_lp/related_competencies', context).done(function(html) {
|
||||
$('[data-region="relatedcompetencies"]').replaceWith(html);
|
||||
updatedRelatedCompetencies();
|
||||
}.bind(this)).fail(notification.exception);
|
||||
}.bind(this)).fail(notification.exception);
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates the competencies list (with relations) and add listeners.
|
||||
*
|
||||
* @method updatedRelatedCompetencies
|
||||
*/
|
||||
var updatedRelatedCompetencies = function() {
|
||||
|
||||
// Listeners to newly loaded related competencies.
|
||||
$('[data-action="deleterelation"]').on('click', deleteRelatedHandler);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Log the competency viewed event.
|
||||
*
|
||||
* @param {Object} The competency.
|
||||
* @method triggerCompetencyViewedEvent
|
||||
*/
|
||||
var triggerCompetencyViewedEvent = function(competency) {
|
||||
if (competency.id !== selectedCompetencyId) {
|
||||
// Set the selected competency id.
|
||||
selectedCompetencyId = competency.id;
|
||||
ajax.call([{
|
||||
methodname: 'core_competency_competency_viewed',
|
||||
args: { id: competency.id }
|
||||
}]);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the taxonomy constant for a level.
|
||||
*
|
||||
* @param {Number} level The level.
|
||||
* @return {String}
|
||||
* @function getTaxonomyAtLevel
|
||||
*/
|
||||
var getTaxonomyAtLevel = function(level) {
|
||||
var constant = taxonomiesConstants[level];
|
||||
if (!constant) {
|
||||
constant = 'competency';
|
||||
}
|
||||
return constant;
|
||||
};
|
||||
|
||||
/**
|
||||
* Render the competency summary.
|
||||
*
|
||||
* @param {Object} competency The competency.
|
||||
*/
|
||||
var renderCompetencySummary = function(competency) {
|
||||
var promise = $.Deferred().resolve().promise(),
|
||||
context = {};
|
||||
|
||||
context.competency = competency;
|
||||
context.showdeleterelatedaction = true;
|
||||
context.showrelatedcompetencies = true;
|
||||
context.showrule = false;
|
||||
|
||||
if (competency.ruleoutcome != Outcomes.NONE) {
|
||||
// Get the outcome and rule name.
|
||||
promise = Outcomes.getString(competency.ruleoutcome).then(function(str) {
|
||||
var name;
|
||||
$.each(rulesModules, function(index, modInfo) {
|
||||
if (modInfo.type == competency.ruletype) {
|
||||
name = modInfo.name;
|
||||
}
|
||||
});
|
||||
return [str, name];
|
||||
});
|
||||
}
|
||||
|
||||
promise.then(function(strs) {
|
||||
if (typeof strs !== 'undefined') {
|
||||
context.showrule = true;
|
||||
context.rule = {
|
||||
outcome: strs[0],
|
||||
type: strs[1]
|
||||
};
|
||||
}
|
||||
}).then(function() {
|
||||
return templates.render('tool_lp/competency_summary', context).then(function(html) {
|
||||
$('[data-region="competencyinfo"]').html(html);
|
||||
$('[data-action="deleterelation"]').on('click', deleteRelatedHandler);
|
||||
});
|
||||
}).then(function() {
|
||||
return templates.render('tool_lp/loading', {});
|
||||
}).then(function(html, js) {
|
||||
templates.replaceNodeContents('[data-region="relatedcompetencies"]', html, js);
|
||||
}).done(function() {
|
||||
ajax.call([{
|
||||
methodname: 'tool_lp_data_for_related_competencies_section',
|
||||
args: { competencyid: competency.id },
|
||||
done: function(context) {
|
||||
return templates.render('tool_lp/related_competencies', context).done(function(html, js) {
|
||||
$('[data-region="relatedcompetencies"]').replaceWith(html);
|
||||
templates.runTemplateJS(js);
|
||||
updatedRelatedCompetencies();
|
||||
});
|
||||
}
|
||||
}]);
|
||||
}).fail(notification.exception);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the string "Add <taxonomy>".
|
||||
*
|
||||
* @param {Number} level The level.
|
||||
* @return {String}
|
||||
* @function strAddTaxonomy
|
||||
*/
|
||||
var strAddTaxonomy = function(level) {
|
||||
return str.get_string('taxonomy_add_' + getTaxonomyAtLevel(level), 'tool_lp');
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the string "Selected <taxonomy>".
|
||||
*
|
||||
* @param {Number} level The level.
|
||||
* @return {String}
|
||||
* @function strSelectedTaxonomy
|
||||
*/
|
||||
var strSelectedTaxonomy = function(level) {
|
||||
return str.get_string('taxonomy_selected_' + getTaxonomyAtLevel(level), 'tool_lp');
|
||||
};
|
||||
|
||||
/**
|
||||
* Handler when a node in the aria tree is selected.
|
||||
* @method selectionChanged
|
||||
* @param {Event} evt The event that triggered the selection change.
|
||||
* @param {Object} params The parameters for the event. Contains a list of selected nodes.
|
||||
*/
|
||||
var selectionChanged = function(evt, params) {
|
||||
var node = params.selected,
|
||||
id = $(node).data('id'),
|
||||
btn = $('[data-region="competencyactions"] [data-action="add"]'),
|
||||
actionMenu = $('[data-region="competencyactionsmenu"]'),
|
||||
selectedTitle = $('[data-region="selected-competency"]'),
|
||||
level = 0,
|
||||
sublevel = 1;
|
||||
|
||||
menubar.closeAll();
|
||||
|
||||
if (typeof id === "undefined") {
|
||||
// Assume this is the root of the tree.
|
||||
// Here we are only getting the text from the top of the tree, to do it we clone the tree,
|
||||
// remove all children and then call text on the result.
|
||||
$('[data-region="competencyinfo"]').html(node.clone().children().remove().end().text());
|
||||
$('[data-region="competencyactions"]').data('competency', null);
|
||||
actionMenu.hide();
|
||||
|
||||
} else {
|
||||
var competency = treeModel.getCompetency(id);
|
||||
|
||||
level = treeModel.getCompetencyLevel(id);
|
||||
sublevel = level + 1;
|
||||
|
||||
actionMenu.show();
|
||||
$('[data-region="competencyactions"]').data('competency', competency);
|
||||
renderCompetencySummary(competency);
|
||||
// Log Competency viewed event.
|
||||
triggerCompetencyViewedEvent(competency);
|
||||
}
|
||||
|
||||
strSelectedTaxonomy(level).then(function(str) {
|
||||
selectedTitle.text(str);
|
||||
});
|
||||
|
||||
strAddTaxonomy(sublevel).then(function(str) {
|
||||
btn.show()
|
||||
.find('[data-region="term"]')
|
||||
.text(str);
|
||||
});
|
||||
|
||||
// We handled this event so consume it.
|
||||
evt.preventDefault();
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the string "Selected <taxonomy>".
|
||||
*
|
||||
* @function parseTaxonomies
|
||||
* @param {String} Comma separated list of taxonomies.
|
||||
* @return {Array} of level => taxonomystr
|
||||
*/
|
||||
var parseTaxonomies = function(taxonomiesstr) {
|
||||
var all = taxonomiesstr.split(',');
|
||||
all.unshift("");
|
||||
delete all[0];
|
||||
|
||||
// Note we don't need to fill holes, because other functions check for empty anyway.
|
||||
return all;
|
||||
};
|
||||
|
||||
return {
|
||||
/**
|
||||
* Initialise this page (attach event handlers etc).
|
||||
*
|
||||
* @method init
|
||||
* @param {Object} model The tree model provides some useful functions for loading and searching competencies.
|
||||
* @param {Number} pagectxid The page context ID.
|
||||
* @param {Object} taxonomies Constants indexed by level.
|
||||
* @param {Object} rulesMods The modules of the rules.
|
||||
*/
|
||||
init: function(model, pagectxid, taxonomies, rulesMods) {
|
||||
treeModel = model;
|
||||
pageContextId = pagectxid;
|
||||
taxonomiesConstants = parseTaxonomies(taxonomies);
|
||||
rulesModules = rulesMods;
|
||||
|
||||
$('[data-region="competencyactions"] [data-action="add"]').on('click', addHandler);
|
||||
|
||||
menubar.enhance('.competencyactionsmenu', {
|
||||
'[data-action="edit"]': editHandler,
|
||||
'[data-action="delete"]': deleteCompetencyHandler,
|
||||
'[data-action="move"]': moveHandler,
|
||||
'[data-action="moveup"]': moveUpHandler,
|
||||
'[data-action="movedown"]': moveDownHandler,
|
||||
'[data-action="linkedcourses"]': seeCoursesHandler,
|
||||
'[data-action="relatedcompetencies"]': relateCompetenciesHandler.bind(this),
|
||||
'[data-action="competencyrules"]': ruleConfigHandler.bind(this)
|
||||
});
|
||||
$('[data-region="competencyactionsmenu"]').hide();
|
||||
$('[data-region="competencyactions"] [data-action="add"]').hide();
|
||||
|
||||
$('[data-region="filtercompetencies"]').on('submit', updateSearchHandler);
|
||||
// Simple html5 drag drop because we already added an accessible alternative.
|
||||
var top = $('[data-region="managecompetencies"] [data-enhance="tree"]');
|
||||
top.on('dragstart', 'li>span', dragStart)
|
||||
.on('dragover', 'li>span', allowDrop)
|
||||
.on('dragenter', 'li>span', dragEnter)
|
||||
.on('dragleave', 'li>span', dragLeave)
|
||||
.on('drop', 'li>span', dropOver);
|
||||
|
||||
model.on('selectionchanged', selectionChanged);
|
||||
|
||||
// Prepare the configuration tool.
|
||||
ruleConfigInstance = new RuleConfig(treeModel, rulesModules);
|
||||
ruleConfigInstance.on('save', ruleConfigSaveHandler.bind(this));
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -1,177 +0,0 @@
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Display Competency in dialogue box.
|
||||
*
|
||||
* @module tool_lp/Competencydialogue
|
||||
* @package tool_lp
|
||||
* @copyright 2015 Issam Taboubi <issam.taboubi@umontreal.ca>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
define(['jquery',
|
||||
'core/notification',
|
||||
'core/ajax',
|
||||
'core/templates',
|
||||
'core/str',
|
||||
'tool_lp/dialogue'],
|
||||
function($, notification, ajax, templates, str, Dialogue) {
|
||||
|
||||
/**
|
||||
* The main instance we'll be working with.
|
||||
*
|
||||
* @type {Competencydialogue}
|
||||
*/
|
||||
var instance;
|
||||
|
||||
/**
|
||||
* Constructor for CompetencyDialogue.
|
||||
*
|
||||
* @param {Object} options
|
||||
*
|
||||
*/
|
||||
var Competencydialogue = function() {
|
||||
};
|
||||
|
||||
/**
|
||||
* Log the competency viewed event.
|
||||
*
|
||||
* @param {Number} The competency ID.
|
||||
* @method triggerCompetencyViewedEvent
|
||||
*/
|
||||
Competencydialogue.prototype.triggerCompetencyViewedEvent = function(competencyId) {
|
||||
ajax.call([{
|
||||
methodname: 'core_competency_competency_viewed',
|
||||
args: { id: competencyId }
|
||||
}]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Display a dialogue box by competencyid.
|
||||
*
|
||||
* @param {Number} competencyid The competency ID.
|
||||
* @param {Object} options The options.
|
||||
* @method showDialogue
|
||||
*/
|
||||
Competencydialogue.prototype.showDialogue = function(competencyid, options) {
|
||||
|
||||
var datapromise = this.getCompetencyDataPromise(competencyid, options);
|
||||
var localthis = this;
|
||||
datapromise.done(function(data) {
|
||||
// Inner Html in the dialogue content.
|
||||
templates.render('tool_lp/competency_summary', data)
|
||||
.done(function(html) {
|
||||
// Log competency viewed event.
|
||||
localthis.triggerCompetencyViewedEvent(competencyid);
|
||||
|
||||
// Show the dialogue.
|
||||
new Dialogue(
|
||||
data.competency.shortname,
|
||||
html
|
||||
);
|
||||
}).fail(notification.exception);
|
||||
}).fail(notification.exception);
|
||||
};
|
||||
|
||||
/**
|
||||
* Display a dialogue box from data.
|
||||
*
|
||||
* @param {Object} dataSource data to be used to display dialogue box
|
||||
* @method showDialogueFromData
|
||||
*/
|
||||
Competencydialogue.prototype.showDialogueFromData = function(dataSource) {
|
||||
|
||||
var localthis = this;
|
||||
// Inner Html in the dialogue content.
|
||||
templates.render('tool_lp/competency_summary', dataSource)
|
||||
.done(function(html) {
|
||||
// Log competency viewed event.
|
||||
localthis.triggerCompetencyViewedEvent(dataSource.id);
|
||||
|
||||
// Show the dialogue.
|
||||
new Dialogue(
|
||||
dataSource.shortname,
|
||||
html,
|
||||
localthis.enhanceDialogue
|
||||
);
|
||||
}).fail(notification.exception);
|
||||
};
|
||||
|
||||
/**
|
||||
* The action on the click event.
|
||||
*
|
||||
* @param {Event} event click
|
||||
* @method clickEventHandler
|
||||
*/
|
||||
Competencydialogue.prototype.clickEventHandler = function(e) {
|
||||
|
||||
var compdialogue = e.data.compdialogue;
|
||||
var currentTarget = $(e.currentTarget);
|
||||
var competencyid = currentTarget.data('id');
|
||||
var includerelated = !(currentTarget.data('excluderelated'));
|
||||
var includecourses = currentTarget.data('includecourses');
|
||||
|
||||
// Show the dialogue box.
|
||||
compdialogue.showDialogue(competencyid, {
|
||||
includerelated: includerelated,
|
||||
includecourses: includecourses
|
||||
});
|
||||
e.preventDefault();
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a promise on data competency.
|
||||
*
|
||||
* @param {Number} competencyid
|
||||
* @return {Promise} return promise on data request
|
||||
* @method getCompetencyDataPromise
|
||||
*/
|
||||
Competencydialogue.prototype.getCompetencyDataPromise = function(competencyid, options) {
|
||||
|
||||
var requests = ajax.call([
|
||||
{ methodname: 'tool_lp_data_for_competency_summary',
|
||||
args: { competencyid: competencyid,
|
||||
includerelated: options.includerelated || false,
|
||||
includecourses: options.includecourses || false
|
||||
}
|
||||
}
|
||||
]);
|
||||
|
||||
return requests[0].then(function(context) {
|
||||
return context;
|
||||
}).fail(notification.exception);
|
||||
};
|
||||
|
||||
return /** @alias module:tool_lp/competencydialogue */ {
|
||||
|
||||
/**
|
||||
* Initialise the competency dialogue module.
|
||||
*
|
||||
* Only the first call matters.
|
||||
*
|
||||
* @return {Void}
|
||||
*/
|
||||
init: function() {
|
||||
if (typeof instance !== 'undefined') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Instantiate the one instance and delegate event on the body.
|
||||
instance = new Competencydialogue();
|
||||
$('body').delegate('[data-action="competency-dialogue"]', 'click', { compdialogue: instance },
|
||||
instance.clickEventHandler.bind(instance));
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -1,460 +0,0 @@
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Competency picker.
|
||||
*
|
||||
* To handle 'save' events use: picker.on('save')
|
||||
* This will receive a object with either a single 'competencyId', or an array in 'competencyIds'
|
||||
* depending on the value of multiSelect.
|
||||
*
|
||||
* @package tool_lp
|
||||
* @copyright 2015 Frédéric Massart - FMCorz.net
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
define(['jquery',
|
||||
'core/notification',
|
||||
'core/ajax',
|
||||
'core/templates',
|
||||
'tool_lp/dialogue',
|
||||
'core/str',
|
||||
'tool_lp/tree'],
|
||||
function($, Notification, Ajax, Templates, Dialogue, Str, Tree) {
|
||||
|
||||
/**
|
||||
* Competency picker class.
|
||||
* @param {Number} pageContextId The page context ID.
|
||||
* @param {Number|false} singleFramework The ID of the framework when limited to one.
|
||||
* @param {String} pageContextIncludes One of 'children', 'parents', 'self'.
|
||||
* @param {Boolean} multiSelect Support multi-select in the tree.
|
||||
*/
|
||||
var Picker = function(pageContextId, singleFramework, pageContextIncludes, multiSelect) {
|
||||
var self = this;
|
||||
self._eventNode = $('<div></div>');
|
||||
self._frameworks = [];
|
||||
self._reset();
|
||||
|
||||
self._pageContextId = pageContextId;
|
||||
self._pageContextIncludes = pageContextIncludes || 'children';
|
||||
self._multiSelect = (typeof multiSelect === 'undefined' || multiSelect === true);
|
||||
if (singleFramework) {
|
||||
self._frameworkId = singleFramework;
|
||||
self._singleFramework = true;
|
||||
}
|
||||
};
|
||||
|
||||
/** @type {Array} The competencies fetched. */
|
||||
Picker.prototype._competencies = null;
|
||||
/** @type {Array} The competencies that cannot be picked. */
|
||||
Picker.prototype._disallowedCompetencyIDs = null;
|
||||
/** @type {Node} The node we attach the events to. */
|
||||
Picker.prototype._eventNode = null;
|
||||
/** @type {Array} The list of frameworks fetched. */
|
||||
Picker.prototype._frameworks = null;
|
||||
/** @type {Number} The current framework ID. */
|
||||
Picker.prototype._frameworkId = null;
|
||||
/** @type {Number} The page context ID. */
|
||||
Picker.prototype._pageContextId = null;
|
||||
/** @type {Number} Relevant contexts inclusion. */
|
||||
Picker.prototype._pageContextIncludes = null;
|
||||
/** @type {Dialogue} The reference to the dialogue. */
|
||||
Picker.prototype._popup = null;
|
||||
/** @type {String} The string we filter the competencies with. */
|
||||
Picker.prototype._searchText = '';
|
||||
/** @type {Object} The competency that was selected. */
|
||||
Picker.prototype._selectedCompetencies = null;
|
||||
/** @type {Boolean} Whether we can browse frameworks or not. */
|
||||
Picker.prototype._singleFramework = false;
|
||||
/** @type {Boolean} Do we allow multi select? */
|
||||
Picker.prototype._multiSelect = true;
|
||||
/** @type {Boolean} Do we allow to display hidden framework? */
|
||||
Picker.prototype._onlyVisible = true;
|
||||
|
||||
/**
|
||||
* Hook to executed after the view is rendered.
|
||||
*
|
||||
* @method _afterRender
|
||||
*/
|
||||
Picker.prototype._afterRender = function() {
|
||||
var self = this;
|
||||
|
||||
// Initialise the tree.
|
||||
var tree = new Tree(self._find('[data-enhance=linktree]'), self._multiSelect);
|
||||
|
||||
// To prevent jiggling we only show the tree after it is enhanced.
|
||||
self._find('[data-enhance=linktree]').show();
|
||||
|
||||
tree.on('selectionchanged', function(evt, params) {
|
||||
var selected = params.selected;
|
||||
evt.preventDefault();
|
||||
var validIds = [];
|
||||
$.each(selected, function(index, item) {
|
||||
var compId = $(item).data('id'),
|
||||
valid = true;
|
||||
|
||||
if (typeof compId === 'undefined') {
|
||||
// Do not allow picking nodes with no id.
|
||||
valid = false;
|
||||
} else {
|
||||
$.each(self._disallowedCompetencyIDs, function(i, id) {
|
||||
if (id == compId) {
|
||||
valid = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (valid) {
|
||||
validIds.push(compId);
|
||||
}
|
||||
}.bind(self));
|
||||
|
||||
self._selectedCompetencies = validIds;
|
||||
|
||||
// TODO Implement disabling of nodes in the tree module somehow.
|
||||
if (!self._selectedCompetencies.length) {
|
||||
self._find('[data-region="competencylinktree"] [data-action="add"]').attr('disabled', 'disabled');
|
||||
} else {
|
||||
self._find('[data-region="competencylinktree"] [data-action="add"]').removeAttr('disabled');
|
||||
}
|
||||
}.bind(self));
|
||||
|
||||
// Add listener for framework change.
|
||||
if (!self._singleFramework) {
|
||||
self._find('[data-action="chooseframework"]').change(function(e) {
|
||||
self._frameworkId = $(e.target).val();
|
||||
self._loadCompetencies().then(self._refresh.bind(self));
|
||||
}.bind(self));
|
||||
}
|
||||
|
||||
// Add listener for search.
|
||||
self._find('[data-region="filtercompetencies"] button').click(function(e) {
|
||||
e.preventDefault();
|
||||
$(e.target).attr('disabled', 'disabled');
|
||||
self._searchText = self._find('[data-region="filtercompetencies"] input').val() || '';
|
||||
return self._refresh().always(function() {
|
||||
$(e.target).removeAttr('disabled');
|
||||
});
|
||||
}.bind(self));
|
||||
|
||||
// Add listener for cancel.
|
||||
self._find('[data-region="competencylinktree"] [data-action="cancel"]').click(function(e) {
|
||||
e.preventDefault();
|
||||
self.close();
|
||||
}.bind(self));
|
||||
|
||||
// Add listener for add.
|
||||
self._find('[data-region="competencylinktree"] [data-action="add"]').click(function(e) {
|
||||
e.preventDefault();
|
||||
if (!self._selectedCompetencies.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (self._multiSelect) {
|
||||
self._trigger('save', { competencyIds: self._selectedCompetencies });
|
||||
} else {
|
||||
// We checked above that the array has at least one value.
|
||||
self._trigger('save', { competencyId: self._selectedCompetencies[0] });
|
||||
}
|
||||
|
||||
self.close();
|
||||
}.bind(self));
|
||||
|
||||
// The list of selected competencies will be modified while looping (because of the listeners above).
|
||||
var currentItems = self._selectedCompetencies.slice(0);
|
||||
|
||||
$.each(currentItems, function(index, id) {
|
||||
var node = self._find('[data-id=' + id + ']');
|
||||
if (node.length) {
|
||||
tree.toggleItem(node);
|
||||
tree.updateFocus(node);
|
||||
}
|
||||
}.bind(self));
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Close the dialogue.
|
||||
*
|
||||
* @method close
|
||||
*/
|
||||
Picker.prototype.close = function() {
|
||||
var self = this;
|
||||
self._popup.close();
|
||||
self._reset();
|
||||
};
|
||||
|
||||
/**
|
||||
* Opens the picker.
|
||||
*
|
||||
* @method display
|
||||
* @return {Promise}
|
||||
*/
|
||||
Picker.prototype.display = function() {
|
||||
var self = this;
|
||||
return self._render().then(function(html) {
|
||||
return Str.get_string('competencypicker', 'tool_lp').then(function(title) {
|
||||
self._popup = new Dialogue(
|
||||
title,
|
||||
html,
|
||||
self._afterRender.bind(self)
|
||||
);
|
||||
}.bind(self));
|
||||
}.bind(self)).fail(Notification.exception);
|
||||
};
|
||||
|
||||
/**
|
||||
* Fetch the competencies.
|
||||
*
|
||||
* @param {Number} frameworkId The frameworkId.
|
||||
* @param {String} searchText Limit the competencies to those matching the text.
|
||||
* @method _fetchCompetencies
|
||||
* @return {Promise}
|
||||
*/
|
||||
Picker.prototype._fetchCompetencies = function(frameworkId, searchText) {
|
||||
var self = this;
|
||||
|
||||
return Ajax.call([
|
||||
{ methodname: 'core_competency_search_competencies', args: {
|
||||
searchtext: searchText,
|
||||
competencyframeworkid: frameworkId
|
||||
}}
|
||||
])[0].done(function(competencies) {
|
||||
|
||||
function addCompetencyChildren(parent, competencies) {
|
||||
for (var i = 0; i < competencies.length; i++) {
|
||||
if (competencies[i].parentid == parent.id) {
|
||||
parent.haschildren = true;
|
||||
competencies[i].children = [];
|
||||
competencies[i].haschildren = false;
|
||||
parent.children[parent.children.length] = competencies[i];
|
||||
addCompetencyChildren(competencies[i], competencies);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Expand the list of competencies into a tree.
|
||||
var i, tree = [], comp;
|
||||
for (i = 0; i < competencies.length; i++) {
|
||||
comp = competencies[i];
|
||||
if (comp.parentid == "0") { // Loose check for now, because WS returns a string.
|
||||
comp.children = [];
|
||||
comp.haschildren = 0;
|
||||
tree[tree.length] = comp;
|
||||
addCompetencyChildren(comp, competencies);
|
||||
}
|
||||
}
|
||||
|
||||
self._competencies = tree;
|
||||
|
||||
}.bind(self)).fail(Notification.exception);
|
||||
};
|
||||
|
||||
/**
|
||||
* Find a node in the dialogue.
|
||||
*
|
||||
* @param {String} selector
|
||||
* @method _find
|
||||
*/
|
||||
Picker.prototype._find = function(selector) {
|
||||
return $(this._popup.getContent()).find(selector);
|
||||
};
|
||||
|
||||
/**
|
||||
* Convenience method to get a framework object.
|
||||
*
|
||||
* @param {Number} fid The framework ID.
|
||||
* @method _getFramework
|
||||
*/
|
||||
Picker.prototype._getFramework = function(fid) {
|
||||
var frm;
|
||||
$.each(this._frameworks, function(i, f) {
|
||||
if (f.id == fid) {
|
||||
frm = f;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return frm;
|
||||
};
|
||||
|
||||
/**
|
||||
* Load the competencies.
|
||||
*
|
||||
* @method _loadCompetencies
|
||||
* @return {Promise}
|
||||
*/
|
||||
Picker.prototype._loadCompetencies = function() {
|
||||
return this._fetchCompetencies(this._frameworkId, this._searchText);
|
||||
};
|
||||
|
||||
/**
|
||||
* Load the frameworks.
|
||||
*
|
||||
* @method _loadFrameworks
|
||||
* @return {Promise}
|
||||
*/
|
||||
Picker.prototype._loadFrameworks = function() {
|
||||
var promise,
|
||||
self = this;
|
||||
|
||||
// Quit early because we already have the data.
|
||||
if (self._frameworks.length > 0) {
|
||||
return $.when();
|
||||
}
|
||||
|
||||
if (self._singleFramework) {
|
||||
promise = Ajax.call([
|
||||
{ methodname: 'core_competency_read_competency_framework', args: {
|
||||
id: this._frameworkId
|
||||
}}
|
||||
])[0].then(function(framework) {
|
||||
return [framework];
|
||||
});
|
||||
} else {
|
||||
promise = Ajax.call([
|
||||
{ methodname: 'core_competency_list_competency_frameworks', args: {
|
||||
sort: 'shortname',
|
||||
context: { contextid: self._pageContextId },
|
||||
includes: self._pageContextIncludes,
|
||||
onlyvisible: self._onlyVisible
|
||||
}}
|
||||
])[0];
|
||||
}
|
||||
|
||||
return promise.done(function(frameworks) {
|
||||
self._frameworks = frameworks;
|
||||
}).fail(Notification.exception);
|
||||
};
|
||||
|
||||
/**
|
||||
* Register an event listener.
|
||||
*
|
||||
* @param {String} type The event type.
|
||||
* @param {Function} handler The event listener.
|
||||
* @method on
|
||||
*/
|
||||
Picker.prototype.on = function(type, handler) {
|
||||
this._eventNode.on(type, handler);
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook to executed before render.
|
||||
*
|
||||
* @method _preRender
|
||||
* @return {Promise}
|
||||
*/
|
||||
Picker.prototype._preRender = function() {
|
||||
var self = this;
|
||||
return self._loadFrameworks().then(function() {
|
||||
if (!self._frameworkId && self._frameworks.length > 0) {
|
||||
self._frameworkId = self._frameworks[0].id;
|
||||
}
|
||||
|
||||
// We could not set a framework ID, that probably means there are no frameworks accessible.
|
||||
if (!self._frameworkId) {
|
||||
self._frameworks = [];
|
||||
return $.when();
|
||||
}
|
||||
|
||||
return self._loadCompetencies();
|
||||
}.bind(self));
|
||||
};
|
||||
|
||||
/**
|
||||
* Refresh the view.
|
||||
*
|
||||
* @method _refresh
|
||||
* @return {Promise}
|
||||
*/
|
||||
Picker.prototype._refresh = function() {
|
||||
var self = this;
|
||||
return self._render().then(function(html) {
|
||||
self._find('[data-region="competencylinktree"]').replaceWith(html);
|
||||
self._afterRender();
|
||||
}.bind(self));
|
||||
};
|
||||
|
||||
/**
|
||||
* Render the dialogue.
|
||||
*
|
||||
* @method _render
|
||||
* @return {Promise}
|
||||
*/
|
||||
Picker.prototype._render = function() {
|
||||
var self = this;
|
||||
return self._preRender().then(function() {
|
||||
|
||||
if (!self._singleFramework) {
|
||||
$.each(self._frameworks, function(i, framework) {
|
||||
if (framework.id == self._frameworkId) {
|
||||
framework.selected = true;
|
||||
} else {
|
||||
framework.selected = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var context = {
|
||||
competencies: self._competencies,
|
||||
framework: self._getFramework(self._frameworkId),
|
||||
frameworks: self._frameworks,
|
||||
search: self._searchText,
|
||||
singleFramework: self._singleFramework,
|
||||
};
|
||||
|
||||
return Templates.render('tool_lp/competency_picker', context);
|
||||
}.bind(self));
|
||||
};
|
||||
|
||||
/**
|
||||
* Reset the dialogue properties.
|
||||
*
|
||||
* This does not reset everything, just enough to reset the UI.
|
||||
*
|
||||
* @method _reset
|
||||
*/
|
||||
Picker.prototype._reset = function() {
|
||||
this._competencies = [];
|
||||
this._disallowedCompetencyIDs = [];
|
||||
this._popup = null;
|
||||
this._searchText = '';
|
||||
this._selectedCompetencies = [];
|
||||
};
|
||||
|
||||
/**
|
||||
* Set what competencies cannot be picked.
|
||||
*
|
||||
* This needs to be set after reset/close.
|
||||
*
|
||||
* @params {Number[]} The IDs.
|
||||
* @method _setDisallowedCompetencyIDs
|
||||
*/
|
||||
Picker.prototype.setDisallowedCompetencyIDs = function(ids) {
|
||||
this._disallowedCompetencyIDs = ids;
|
||||
};
|
||||
|
||||
/**
|
||||
* Trigger an event.
|
||||
*
|
||||
* @param {String} type The type of event.
|
||||
* @param {Object} The data to pass to the listeners.
|
||||
* @method _reset
|
||||
*/
|
||||
Picker.prototype._trigger = function(type, data) {
|
||||
this._eventNode.trigger(type, [data]);
|
||||
};
|
||||
|
||||
return /** @alias module:tool_lp/competencypicker */ Picker;
|
||||
|
||||
});
|
||||
@@ -1,240 +0,0 @@
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Competency picker from user plans.
|
||||
*
|
||||
* To handle 'save' events use: picker.on('save').
|
||||
*
|
||||
* This will receive a object with either a single 'competencyId', or an array in 'competencyIds'
|
||||
* depending on the value of multiSelect.
|
||||
*
|
||||
* @package tool_lp
|
||||
* @copyright 2015 Frédéric Massart - FMCorz.net
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
define(['jquery',
|
||||
'core/notification',
|
||||
'core/ajax',
|
||||
'core/templates',
|
||||
'core/str',
|
||||
'tool_lp/tree',
|
||||
'tool_lp/competencypicker'
|
||||
],
|
||||
function($, Notification, Ajax, Templates, Str, Tree, PickerBase) {
|
||||
|
||||
/**
|
||||
* Competency picker in plan class.
|
||||
*
|
||||
* @param {Number|false} singlePlan The ID of the plan when limited to one.
|
||||
* @param {String} pageContextIncludes One of 'children', 'parents', 'self'.
|
||||
* @param {Boolean} multiSelect Support multi-select in the tree.
|
||||
*/
|
||||
var Picker = function(userId, singlePlan, multiSelect) {
|
||||
PickerBase.prototype.constructor.apply(this, [1, false, 'self', multiSelect]);
|
||||
this._userId = userId;
|
||||
this._plans = [];
|
||||
|
||||
if (singlePlan) {
|
||||
this._planId = singlePlan;
|
||||
this._singlePlan = true;
|
||||
}
|
||||
};
|
||||
Picker.prototype = Object.create(PickerBase.prototype);
|
||||
|
||||
/** @type {Array} The list of plans fetched. */
|
||||
Picker.prototype._plans = null;
|
||||
/** @type {Number} The current plan ID. */
|
||||
Picker.prototype._planId = null;
|
||||
/** @type {Boolean} Whether we can browse plans or not. */
|
||||
Picker.prototype._singlePlan = false;
|
||||
/** @type {Number} The user the plans belongs to. */
|
||||
Picker.prototype._userId = null;
|
||||
|
||||
/**
|
||||
* Hook to executed after the view is rendered.
|
||||
*
|
||||
* @method _afterRender
|
||||
*/
|
||||
Picker.prototype._afterRender = function() {
|
||||
var self = this;
|
||||
PickerBase.prototype._afterRender.apply(self, arguments);
|
||||
|
||||
// Add listener for framework change.
|
||||
if (!self._singlePlan) {
|
||||
self._find('[data-action="chooseplan"]').change(function(e) {
|
||||
self._planId = $(e.target).val();
|
||||
self._loadCompetencies().then(self._refresh.bind(self));
|
||||
}.bind(self));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Fetch the competencies.
|
||||
*
|
||||
* @param {Number} planId The planId.
|
||||
* @param {String} searchText Limit the competencies to those matching the text.
|
||||
* @method _fetchCompetencies
|
||||
* @return {Promise}
|
||||
*/
|
||||
Picker.prototype._fetchCompetencies = function(planId, searchText) {
|
||||
var self = this;
|
||||
|
||||
return Ajax.call([
|
||||
{ methodname: 'core_competency_list_plan_competencies', args: {
|
||||
id: planId
|
||||
}}
|
||||
])[0].done(function(competencies) {
|
||||
|
||||
// Expand the list of competencies into a fake tree.
|
||||
var i, tree = [], comp;
|
||||
for (i = 0; i < competencies.length; i++) {
|
||||
comp = competencies[i].competency;
|
||||
if (comp.shortname.toLowerCase().indexOf(searchText.toLowerCase()) < 0) {
|
||||
continue;
|
||||
}
|
||||
comp.children = [];
|
||||
comp.haschildren = 0;
|
||||
tree.push(comp);
|
||||
}
|
||||
|
||||
self._competencies = tree;
|
||||
|
||||
}).fail(Notification.exception);
|
||||
};
|
||||
|
||||
/**
|
||||
* Convenience method to get a plan object.
|
||||
*
|
||||
* @param {Number} id The plan ID.
|
||||
* @return {Object|undefined} The plan.
|
||||
* @method _getPlan
|
||||
*/
|
||||
Picker.prototype._getPlan = function(id) {
|
||||
var plan;
|
||||
$.each(this._plans, function(i, f) {
|
||||
if (f.id == id) {
|
||||
plan = f;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return plan;
|
||||
};
|
||||
|
||||
/**
|
||||
* Load the competencies.
|
||||
*
|
||||
* @method _loadCompetencies
|
||||
* @return {Promise}
|
||||
*/
|
||||
Picker.prototype._loadCompetencies = function() {
|
||||
return this._fetchCompetencies(this._planId, this._searchText);
|
||||
};
|
||||
|
||||
/**
|
||||
* Load the plans.
|
||||
*
|
||||
* @method _loadPlans
|
||||
* @return {Promise}
|
||||
*/
|
||||
Picker.prototype._loadPlans = function() {
|
||||
var promise,
|
||||
self = this;
|
||||
|
||||
// Quit early because we already have the data.
|
||||
if (self._plans.length > 0) {
|
||||
return $.when();
|
||||
}
|
||||
|
||||
if (self._singlePlan) {
|
||||
promise = Ajax.call([
|
||||
{ methodname: 'core_competency_read_plan', args: {
|
||||
id: this._planId
|
||||
}}
|
||||
])[0].then(function(plan) {
|
||||
return [plan];
|
||||
});
|
||||
} else {
|
||||
promise = Ajax.call([
|
||||
{ methodname: 'core_competency_list_user_plans', args: {
|
||||
userid: self._userId
|
||||
}}
|
||||
])[0];
|
||||
}
|
||||
|
||||
return promise.done(function(plans) {
|
||||
self._plans = plans;
|
||||
}).fail(Notification.exception);
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook to executed before render.
|
||||
*
|
||||
* @method _preRender
|
||||
* @return {Promise}
|
||||
*/
|
||||
Picker.prototype._preRender = function() {
|
||||
var self = this;
|
||||
return self._loadPlans().then(function() {
|
||||
if (!self._planId && self._plans.length > 0) {
|
||||
self._planId = self._plans[0].id;
|
||||
}
|
||||
|
||||
// We could not set a framework ID, that probably means there are no frameworks accessible.
|
||||
if (!self._planId) {
|
||||
self._plans = [];
|
||||
return $.when();
|
||||
}
|
||||
|
||||
return self._loadCompetencies();
|
||||
}.bind(self));
|
||||
};
|
||||
|
||||
/**
|
||||
* Render the dialogue.
|
||||
*
|
||||
* @method _render
|
||||
* @return {Promise}
|
||||
*/
|
||||
Picker.prototype._render = function() {
|
||||
var self = this;
|
||||
return self._preRender().then(function() {
|
||||
|
||||
if (!self._singlePlan) {
|
||||
$.each(self._plans, function(i, plan) {
|
||||
if (plan.id == self._planId) {
|
||||
plan.selected = true;
|
||||
} else {
|
||||
plan.selected = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var context = {
|
||||
competencies: self._competencies,
|
||||
plan: self._getPlan(self._planId),
|
||||
plans: self._plans,
|
||||
search: self._searchText,
|
||||
singlePlan: self._singlePlan,
|
||||
};
|
||||
|
||||
return Templates.render('tool_lp/competency_picker_user_plans', context);
|
||||
}.bind(self));
|
||||
};
|
||||
|
||||
return /** @alias module:tool_lp/competencypicker_user_plans */ Picker;
|
||||
|
||||
});
|
||||