Compare commits
869 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fce31a2e02 | |||
| b816e7f4db | |||
| 45f6d4f911 | |||
| 6a9a1d1547 | |||
| 391eb99e10 | |||
| 3b4487c836 | |||
| 46461c7c5d | |||
| 7104629ffd | |||
| b46abecde5 | |||
| e82795f798 | |||
| a6faf5b757 | |||
| 3e6e6faf03 | |||
| b3f18bc677 | |||
| a48fe40675 | |||
| 74c777b1ae | |||
| 1e955fa813 | |||
| bc371e69a3 | |||
| 9a97b636eb | |||
| 878156e21e | |||
| af376d2837 | |||
| 9dd5f250c7 | |||
| bb527996b9 | |||
| 1a171161cd | |||
| d410663a68 | |||
| 9e332ca0a4 | |||
| 02388a33ba | |||
| 3f52364308 | |||
| e157837e0e | |||
| c2318349e5 | |||
| c540c74a04 | |||
| e5b1271ce1 | |||
| dfaa15c6e7 | |||
| 4aa3e1368a | |||
| 25f10011fc | |||
| d08f08ffaf | |||
| 9a9237e78e | |||
| 1511ad58b2 | |||
| 2e9b751174 | |||
| d61ab97be3 | |||
| dd40d73b71 | |||
| 068bca84b7 | |||
| 0fda528b94 | |||
| 3552f63d87 | |||
| 01d04fde37 | |||
| 7f8c526136 | |||
| ea4be14f0c | |||
| 20df48e2f0 | |||
| 2c0f6f975c | |||
| fa7f91b39d | |||
| 72c5853fb1 | |||
| f03b1a22f9 | |||
| e7fb6e5beb | |||
| d0cc93d6a2 | |||
| 4adc2562b1 | |||
| ba6878666c | |||
| 30da7fb801 | |||
| 7086a5153a | |||
| 37937e2c8e | |||
| 7676099f2e | |||
| 0d1bb355b5 | |||
| 3276b8a4d8 | |||
| 792ab8d088 | |||
| 3d4409e52a | |||
| acd377956f | |||
| 3b6dcc3421 | |||
| cec4d41df7 | |||
| ff0bcffefa | |||
| 5dbc72897a | |||
| 83736bec01 | |||
| 2f953c3819 | |||
| 026d040a62 | |||
| 7747b8f64f | |||
| feab2de260 | |||
| 24cc417395 | |||
| 56e1fc07e4 | |||
| fbd2b3a1e1 | |||
| 8f7f761bb3 | |||
| a40ba2f27e | |||
| 893f86d34c | |||
| ddd2ab463e | |||
| cbced2caed | |||
| ce068a60d5 | |||
| 7f7f3202d2 | |||
| 0227b800a0 | |||
| 8e89aa233c | |||
| 24ceb5ce2d | |||
| 923eb300e5 | |||
| 0d93db5f1f | |||
| d2aecd12eb | |||
| 1e99c466ee | |||
| 71a9fb4f68 | |||
| 0497771750 | |||
| 000b2b639f | |||
| 885f691c0e | |||
| 92f6b5564d | |||
| ce65ae8742 | |||
| 57c9d9ca7b | |||
| feb9f40237 | |||
| 3fc96a45a6 | |||
| 3b71a6c3a5 | |||
| 9c4212703b | |||
| a20c11d438 | |||
| 89b8d056a2 | |||
| 8707348215 | |||
| 70ba0cd592 | |||
| 429b5f7c01 | |||
| db4a547801 | |||
| a9916fc415 | |||
| 64a37209b8 | |||
| f9304d7f04 | |||
| 24ae424207 | |||
| b86ef0d7ac | |||
| de97d8849a | |||
| a3576d8564 | |||
| ffdf4e7256 | |||
| f9475305bb | |||
| 0a6208f3ef | |||
| 00f2afe454 | |||
| 3800ffc11c | |||
| 2a9b1cb246 | |||
| 651182f5de | |||
| 784f873777 | |||
| a938605461 | |||
| bb9c968d3a | |||
| b8fe5df3c9 | |||
| 22b15a06f6 | |||
| cb09795280 | |||
| 81dfd0c6bc | |||
| 9f028e6d61 | |||
| ac57ec2211 | |||
| 218bb28440 | |||
| d02b230f71 | |||
| 289361c02f | |||
| fc3020ffa4 | |||
| 7c4c44cf7e | |||
| 458c51a955 | |||
| f3d64bb85d | |||
| 8261a2b69b | |||
| a5637af2d8 | |||
| ac59c5deb0 | |||
| 683ddf6d34 | |||
| eda33b1ac4 | |||
| ed0f884348 | |||
| b561351340 | |||
| 690ab29863 | |||
| a1b3345671 | |||
| e1022bd5a1 | |||
| 1f2c00e3be | |||
| bf4c58a6f4 | |||
| 9de0a62cff | |||
| 3c3f2d7c8d | |||
| 27cb1d5223 | |||
| c677f36f08 | |||
| 750f7a6b33 | |||
| dea804b402 | |||
| 3803d1d7da | |||
| 3e67b3034d | |||
| 1ada5210ad | |||
| 92e1db1667 | |||
| f0258b2bce | |||
| 9a608674eb | |||
| 0fc5af5e17 | |||
| 7dae412a29 | |||
| c3471ffbc3 | |||
| f8baf343bf | |||
| a1067e676f | |||
| ce649f54d7 | |||
| 09b9056fb0 | |||
| 8da2c22a4e | |||
| d159792256 | |||
| d08712306c | |||
| 5e30fd4ced | |||
| 314abde9ac | |||
| 606b5aa60a | |||
| 5441c30780 | |||
| 2c563168e7 | |||
| 59f8508332 | |||
| a206652a0d | |||
| 545040fdf0 | |||
| 2954b31435 | |||
| 40d1a09609 | |||
| 2e25bc8fdb | |||
| 1618ac86b8 | |||
| a4adbca12c | |||
| 8728e2f918 | |||
| d6b55c54e6 | |||
| cd53682ddb | |||
| d000b67703 | |||
| e2d5fbf545 | |||
| a6c4ce3a31 | |||
| 64246b4eef | |||
| fe8098adac | |||
| d339e7c814 | |||
| 9860ffc3bf | |||
| 7db829b2a3 | |||
| 10759773ca | |||
| 078deb704b | |||
| 6858eb3330 | |||
| 16e16f9578 | |||
| e267b7700a | |||
| f780c21ef0 | |||
| 84e7396729 | |||
| 7ed11c04c5 | |||
| 81305173ca | |||
| 6637ceaf41 | |||
| 82d5f7b72b | |||
| e69dea26a5 | |||
| 85d6f1d54a | |||
| f168093b92 | |||
| 1e45abe71e | |||
| a556b4ed21 | |||
| 953c711ca4 | |||
| f06c9e8235 | |||
| f1a439e851 | |||
| 20c2574f94 | |||
| ab4c58b3a3 | |||
| cb63642ce9 | |||
| 3fb756939e | |||
| ec14a16aec | |||
| 6944f25c9f | |||
| 45c7699a33 | |||
| 2bd2f12831 | |||
| a0e496e589 | |||
| e0dcc3afbc | |||
| a4b1b31a24 | |||
| 3634a77d61 | |||
| 13f76f7922 | |||
| d12a9e046f | |||
| 846f4b5b6c | |||
| 2869f17eff | |||
| b73c39b4e9 | |||
| feefb052fd | |||
| 87f93be6ba | |||
| 7e7c4b52b6 | |||
| 4d2d9156ba | |||
| a1603c3cbd | |||
| 82ba1a24a3 | |||
| 357db9d0b6 | |||
| 61766287bc | |||
| ffbf8b2fd6 | |||
| e8c25283b0 | |||
| f7a703195c | |||
| 848e8b5722 | |||
| 4d316c9671 | |||
| 509be9b431 | |||
| 8154382fb1 | |||
| 10ef5eb7bc | |||
| f4c1c4578f | |||
| 6f15949af7 | |||
| 2849ecadb7 | |||
| 778c698ef7 | |||
| 697f93c3ce | |||
| e6c2f0ad70 | |||
| 13976559a8 | |||
| 18121e8726 | |||
| 8b6583b554 | |||
| 234d4cf427 | |||
| 81cdc71145 | |||
| f822400036 | |||
| 2aae108cb4 | |||
| 4069fc8d1f | |||
| 643f05d949 | |||
| d36cd035e9 | |||
| c4acbf0dbc | |||
| 0a80c39962 | |||
| edee8134c2 | |||
| 2f66303b38 | |||
| 7102ed49ec | |||
| f5d94c3a05 | |||
| 92502f946b | |||
| 30a73c0886 | |||
| f5ee02a3e9 | |||
| 9827b40bea | |||
| 2de6f09634 | |||
| df16a69582 | |||
| f9323c85e4 | |||
| 2677672e50 | |||
| a38e0dcf86 | |||
| fdd7227494 | |||
| 6b74e14cdd | |||
| db528d8d7a | |||
| 9d7b3b965a | |||
| 806008a7e9 | |||
| 45fa192c95 | |||
| 92235128f1 | |||
| 06cb7a529e | |||
| fa4e9d0cd1 | |||
| 764644fc5d | |||
| 0bf27f4371 | |||
| 7622937cfd | |||
| bf41694572 | |||
| 7b897ce64c | |||
| 36a8599e62 | |||
| 1ca950f721 | |||
| ffba271fd0 | |||
| ec08d3e910 | |||
| 0bfd032fad | |||
| 2bb58b6fca | |||
| 4d2d656b3d | |||
| fa625d72f9 | |||
| 1991380e02 | |||
| 3b8d6dc2c7 | |||
| 1faeb76c27 | |||
| a064903e90 | |||
| 2850c3c3de | |||
| 1fa7cd234d | |||
| cec8001c38 | |||
| 7dbd21a854 | |||
| 3a513668fd | |||
| 9ff82f3a00 | |||
| 25999be0c9 | |||
| 853baf9462 | |||
| 6f36384a35 | |||
| d55e492d17 | |||
| fcbdf6c635 | |||
| 1fda22a4e0 | |||
| deeaf724bd | |||
| 34824ffbb0 | |||
| 6f28a0a686 | |||
| b3f6a8c71b | |||
| 98684e6292 | |||
| aad0e73fea | |||
| 9687b2abee | |||
| 4ea589e954 | |||
| 621a19d4bd | |||
| 5821444678 | |||
| 7533baf368 | |||
| d691e525b3 | |||
| 02d9d42ae2 | |||
| 17838e044c | |||
| 73173f92d6 | |||
| 7d7fcd2093 | |||
| 2ab1cf59a6 | |||
| 3ef51d7357 | |||
| 56cd1cee81 | |||
| 002988ce86 | |||
| 81c32716fe | |||
| 8b553dd067 | |||
| c52123e878 | |||
| 4e6ca57f7a | |||
| ce9cfbf071 | |||
| 8024bde429 | |||
| 9ce79e98a3 | |||
| 3e5553d9b0 | |||
| c2f34cefb5 | |||
| ccaf82d797 | |||
| 2f7727af68 | |||
| 5a9874bfad | |||
| 5047c7bbe7 | |||
| 0c45fb1b97 | |||
| 7bd745a870 | |||
| 68b4a493c6 | |||
| 6338d57959 | |||
| 7de1b2d09d | |||
| 93a4e8f426 | |||
| fcc115004e | |||
| 24062c0061 | |||
| 06cbdc37b4 | |||
| f28ae52ae3 | |||
| cfd0973f00 | |||
| 1bfdd83ba7 | |||
| 6fefcacc61 | |||
| 3b639e61b2 | |||
| 9959ff667e | |||
| de1f86c7a1 | |||
| 28d8fd0531 | |||
| e4e76eb0bf | |||
| 677cc8c8fd | |||
| 3fa5c4e0b2 | |||
| 360393c464 | |||
| d3daf88a8d | |||
| 7a99ebd6d9 | |||
| a7298e2e5a | |||
| 15d7443c61 | |||
| f2b7e27b34 | |||
| 690d08aa8c | |||
| 6719d70cc0 | |||
| 3cdcf513ec | |||
| 23d9944a61 | |||
| 31429ad9c8 | |||
| 05a8d80284 | |||
| c2d978a0db | |||
| e17b32c6e5 | |||
| de79512dd4 | |||
| 06ae6ad15e | |||
| 2a81162756 | |||
| 0a7526601c | |||
| 3e22598f4a | |||
| d842f0f5b7 | |||
| 8258619055 | |||
| 7d2f6c13c3 | |||
| b314bff127 | |||
| d66e2e52e9 | |||
| 43c426b46c | |||
| 0714aaa457 | |||
| 81dac97917 | |||
| de6e0dc8d7 | |||
| 57c68daf38 | |||
| a705561a51 | |||
| a7107f01e8 | |||
| e2ac82abca | |||
| 64d1a484bd | |||
| 585b42af48 | |||
| 7c4412fc4b | |||
| 0be8039c8f | |||
| 668265f1ac | |||
| 4735f27a66 | |||
| 6377b9aa50 | |||
| 011be60205 | |||
| a272675ed8 | |||
| 80697cf9ca | |||
| f4534aa94c | |||
| 56dec485a5 | |||
| ffde0f48cf | |||
| 5663b6890f | |||
| a2905c13f6 | |||
| e8f7a83f68 | |||
| 2956aee4e3 | |||
| 9bd8d729fa | |||
| fb9569d914 | |||
| 47974d49fe | |||
| 3f8b3031c2 | |||
| 7da41594fd | |||
| 9796b30bbb | |||
| ead837f654 | |||
| 10a4eb3ddc | |||
| 51f46cf871 | |||
| 88182edf8f | |||
| e456dd3886 | |||
| 697548d1c7 | |||
| f717628322 | |||
| c2c4763faa | |||
| e91b297cc2 | |||
| c062d3b71b | |||
| ed83fb8216 | |||
| c92441e544 | |||
| f0573fc68c | |||
| eb44480fdf | |||
| 1ad05fbfc9 | |||
| 673e24a2ea | |||
| 4842be01cd | |||
| dddb38d4ee | |||
| 727ce0f795 | |||
| ba27acead9 | |||
| a026a81a8a | |||
| 5e7ee0c236 | |||
| bb30d5ebd2 | |||
| 2ae3b09b8c | |||
| 473d76f1b7 | |||
| 918e454c42 | |||
| 7e32fdb682 | |||
| 171a472966 | |||
| 8194655ad1 | |||
| 80c1812bc8 | |||
| 6c37b33509 | |||
| 509bcee540 | |||
| 3dec881848 | |||
| 65b522a0a0 | |||
| 9164567abe | |||
| 12314f16a2 | |||
| 1621d01992 | |||
| ae05bfd350 | |||
| 79567d4e8f | |||
| 334a56ce5c | |||
| c2ee3303a5 | |||
| bfc89a7247 | |||
| 326309e61e | |||
| 8926e8c7d9 | |||
| ee7ee81098 | |||
| f4b707e928 | |||
| c38030def2 | |||
| 43a61d8a06 | |||
| 4fd3725c51 | |||
| 949861a890 | |||
| 122069752a | |||
| c288734877 | |||
| 4b22ff3a75 | |||
| 2b1a43b40a | |||
| 076d90ddc4 | |||
| 1e2e26d898 | |||
| f56cb2c3ac | |||
| ae83b0fbaf | |||
| fb7b65cf3b | |||
| 168abddacf | |||
| 99e91a1053 | |||
| bad118ac6b | |||
| f334c3d74a | |||
| 0e6c199a7e | |||
| 0bc39afdab | |||
| cf3de52249 | |||
| 3f0569af41 | |||
| 9f078357a7 | |||
| bb837232ba | |||
| 6d57afc71a | |||
| fd682efdb1 | |||
| 5c614a88a2 | |||
| f27a0c0461 | |||
| 3ef9635406 | |||
| 80601abb27 | |||
| 79384d8a0a | |||
| 793a1a9aa8 | |||
| e3da493345 | |||
| c527833081 | |||
| 5caf091406 | |||
| 5a29441640 | |||
| 75a42fd0d6 | |||
| 84da5f43a2 | |||
| 0da7ed8d93 | |||
| 0aa72e5026 | |||
| 14cfd2a8df | |||
| d6b3d115b0 | |||
| 7b1fd5378f | |||
| 9e9b94b1d5 | |||
| cf837d783d | |||
| 3df44e2990 | |||
| 0c5ebb2674 | |||
| ba2fa2bff4 | |||
| 03090e85fd | |||
| 5c55d6a6e3 | |||
| 0632d73e32 | |||
| 000c2637d6 | |||
| bf24e101d3 | |||
| 08c837602f | |||
| 563867cd8b | |||
| 86c66511dd | |||
| eedd109332 | |||
| 7d57521ad8 | |||
| d5fc18dc95 | |||
| e36b3d46e8 | |||
| d8aa98e60c | |||
| 4a8a09c78a | |||
| 8a8899397e | |||
| dc69b5a825 | |||
| df7691ada3 | |||
| 1048df7e63 | |||
| 457560920d | |||
| e79c0ae2b5 | |||
| e74e8f9d73 | |||
| 23b0c89848 | |||
| 285989e737 | |||
| 2c580d0b20 | |||
| 3c1f6abd0d | |||
| 4eb1ef3444 | |||
| 0f503fc320 | |||
| aebc30c7a3 | |||
| 44bc365fdd | |||
| 06defee410 | |||
| d5d4dc9561 | |||
| be2c72f8b4 | |||
| 62f46d531f | |||
| 6bfdbe3e8a | |||
| 7095b21eb4 | |||
| efce912332 | |||
| b33a265ea4 | |||
| db849c1e36 | |||
| b01721c2a9 | |||
| 4f2a807327 | |||
| 955573256d | |||
| d963f5cd7d | |||
| 2467b5ee3b | |||
| f86eb4b741 | |||
| 33b99073f0 | |||
| 880636c5a6 | |||
| 6e344f335e | |||
| 6b205bd725 | |||
| d97a0f5b6c | |||
| a510396a57 | |||
| 297d54ec98 | |||
| 531306a091 | |||
| 4346f73159 | |||
| 3cb5754ff2 | |||
| bf5bb8bc70 | |||
| 7b7ad4d350 | |||
| 544a0756f3 | |||
| 934215307d | |||
| 349825b4f8 | |||
| f3f1a161e4 | |||
| c088187a13 | |||
| 4db6ce4b22 | |||
| 72a366d0dc | |||
| fc18189fc8 | |||
| 49cfeee5b0 | |||
| 01d09548aa | |||
| 1ff049a063 | |||
| 7c720460f5 | |||
| d0c0ec56a4 | |||
| 3c965e8c32 | |||
| 5bcd6a9982 | |||
| 525477f84f | |||
| 7d051dffbb | |||
| c5a7eab1d5 | |||
| 115c8b15fd | |||
| 29c8f065f7 | |||
| 961755336a | |||
| e0aff8a1e4 | |||
| 6fa0c627a5 | |||
| b3c2574aac | |||
| 98b2320421 | |||
| 66a63b3cbb | |||
| 077f3468b9 | |||
| 21c5b6fe02 | |||
| 3274d873a9 | |||
| ffed85640d | |||
| 250f082346 | |||
| cdbf89ee57 | |||
| 056b13eb98 | |||
| e2a395e245 | |||
| 6b760dcfe8 | |||
| 5ded732188 | |||
| 9467a67661 | |||
| d6a83d9887 | |||
| 96e00bc1eb | |||
| 0f9f11bbcf | |||
| 5b6cc51516 | |||
| 80b83ab64b | |||
| 326d81286a | |||
| 13641473d0 | |||
| c6751f0374 | |||
| d71c686aea | |||
| 4c5dfb42d5 | |||
| 0245efe3cb | |||
| b3151ca788 | |||
| aa1edb6e69 | |||
| 0b4ddf82aa | |||
| 3ff173732b | |||
| f3f7aa70d1 | |||
| cd82bc6d21 | |||
| c3a6c7c473 | |||
| 5538a2e793 | |||
| 1b7dc76df2 | |||
| 85c85cd1eb | |||
| ba5f2bc69d | |||
| 3fcdbe85b5 | |||
| 78336181ea | |||
| 17883358b6 | |||
| fc0c6a1cd8 | |||
| 934d4020b2 | |||
| 8b03ba4f42 | |||
| 3caf84c63c | |||
| aae16f227e | |||
| 443002cdde | |||
| 75150f0bfa | |||
| af73fd8b68 | |||
| 139df63ddf | |||
| a49058fe00 | |||
| dcde00cec1 | |||
| bcc70f7a1e | |||
| 32bc2f1d69 | |||
| 4d3f67885a | |||
| a269e9d426 | |||
| af5a382f93 | |||
| 90174a39e3 | |||
| 4d9f9c890d | |||
| dad910b8ab | |||
| 8a70c440f2 | |||
| 07f3de8b67 | |||
| 0955b0c474 | |||
| 57d1ff20fd | |||
| fbdb1d5d6c | |||
| b924b06062 | |||
| fb029861cf | |||
| 4eb19bd26c | |||
| 71a07060a9 | |||
| edaa5ebd43 | |||
| c12b270511 | |||
| c8fa2b3880 | |||
| d474481cba | |||
| 62e3ab27fe | |||
| 86c008fc8c | |||
| 154ee39755 | |||
| 63ca9f210b | |||
| 1c139b685a | |||
| 7a8b3dc9bc | |||
| a4dde1948f | |||
| 0f68818a19 | |||
| 414b65b269 | |||
| 28c2aa1195 | |||
| 391c778b80 | |||
| f2c2b7590b | |||
| 22d6981ab0 | |||
| 4dbe317c03 | |||
| dc727ba0de | |||
| 2dd04799b2 | |||
| 1c901e00cc | |||
| d7207f7c2a | |||
| a5828a2c3e | |||
| c589c741e8 | |||
| c8923cbc27 | |||
| 063f405a06 | |||
| 68a25bb5b1 | |||
| addfbcf2a7 | |||
| 8ee133bb75 | |||
| fa1185cbd8 | |||
| 68e0a414a0 | |||
| 6ddef7df27 | |||
| 66f572b642 | |||
| a7a1730898 | |||
| 155e7338cf | |||
| 89860bd786 | |||
| b5cfefa052 | |||
| b2c0f3c35a | |||
| d5e0c6ff68 | |||
| a43f4b7b7f | |||
| 7ce3949852 | |||
| 4862419744 | |||
| 6b810c89f6 | |||
| 89b0a2fd89 | |||
| 73c479c843 | |||
| 8aceae9880 | |||
| 384d4d60f1 | |||
| 67caf81a74 | |||
| 763ab26446 | |||
| 67a8fa5f07 | |||
| f7b61d09e2 | |||
| 5c59317bf8 | |||
| a2ec53dd4f | |||
| db78c78df2 | |||
| 4558549d5a | |||
| d98801d5d1 | |||
| de9ecf6afc | |||
| 702790bf77 | |||
| 3a1dbc778b | |||
| c912e80134 | |||
| 098c856138 | |||
| b45306e1ff | |||
| 3499f39970 | |||
| 4fb61be092 | |||
| 9115aa1a6d | |||
| f98b81116c | |||
| 904cbbb906 | |||
| c0380e491b | |||
| 8656d3e4b9 | |||
| 40988b4655 | |||
| 8a8b69a442 | |||
| 06dbea84d8 | |||
| f54cf32057 | |||
| 64dbf0207b | |||
| f743830167 | |||
| 206c88105e | |||
| 3177b979d3 | |||
| 0addd719d3 | |||
| 662dfb37d3 | |||
| 4ab32dd270 | |||
| fec55e9d1c | |||
| a21aa079ff | |||
| ef4246478d | |||
| dda538d1fc | |||
| 137d859532 | |||
| d6d80ae037 | |||
| 82b2821e27 | |||
| b270cefacc | |||
| 8b064fc2ec | |||
| b4e984fe6a | |||
| 1a3339d485 | |||
| f62e4fa973 | |||
| ee8050f38f | |||
| 8cb0f5762c | |||
| 287596220a | |||
| f870ee18d4 | |||
| b506b5c8e9 | |||
| d9e843f0ba | |||
| 805c1dfb5b | |||
| 66dd0d073c | |||
| f269b1931d | |||
| 29c22cc4b5 | |||
| 76695fc7b2 | |||
| e29031a2c4 | |||
| 9b2b8e8166 | |||
| 3ff0cca033 | |||
| aa398b4f36 | |||
| fe16cc91fa | |||
| 7e6fdcb05e | |||
| ae54f34bcf | |||
| d1e071b9cb | |||
| 3e253f9c19 | |||
| 2ce952bdbb | |||
| b8f5d1c42c | |||
| 6a9b8d5540 | |||
| fdc9261399 | |||
| 64b247157c | |||
| fcacc1bd71 | |||
| 68d581ac82 | |||
| af86a5d7b1 | |||
| 0f25029ff6 | |||
| 060e584503 | |||
| 743c0bb31c | |||
| 4bac3e19fe | |||
| b86cddda94 | |||
| 11103c0bc5 | |||
| 8210702474 | |||
| a42b660648 | |||
| f11d4fbedd | |||
| 9105c08a4c | |||
| 71b3ea2e56 | |||
| 33b3032b30 | |||
| 31e5ed7b1b | |||
| 98c8d637f4 | |||
| 8a3eae9ea6 | |||
| 5aec753859 | |||
| eeaa9166ac | |||
| 751ace1168 | |||
| 51da5343ea | |||
| 34df5009e0 | |||
| d4db7d9523 | |||
| 62cf1cd87d | |||
| e17b5e6a7b | |||
| 3f1b057f45 | |||
| cacf87be2d | |||
| 24fcfd9fcb | |||
| 48dd619899 | |||
| f8375857c2 | |||
| 997e0e5492 | |||
| 376fe0bf55 | |||
| 282da69d61 | |||
| c83844468d | |||
| 80b5cfbb07 | |||
| aacb86bf92 | |||
| 59391f58ec | |||
| 0debf9c34f | |||
| 9fa17ef6cb | |||
| d227aa19b8 | |||
| e0a10080b1 | |||
| 807df434f6 | |||
| d963917556 | |||
| 347d41c841 | |||
| f16aa38fff | |||
| 62a7e0acd0 | |||
| 8e89d13142 | |||
| a5782a40af | |||
| 516beedbbb | |||
| 7cd01fc50b | |||
| e9d12ae0d8 | |||
| 02e167c1f6 | |||
| baed01518c | |||
| a0106ff811 | |||
| e0da5a9cb2 | |||
| 451d5eb484 | |||
| 1923b68594 | |||
| 3abd4df8bd | |||
| ea239e6122 | |||
| 3fe99a402e | |||
| e738738e54 | |||
| f502912225 | |||
| c8a26bf6a3 | |||
| e06e50c4fc | |||
| 4236473b14 | |||
| 3285e161c0 | |||
| b5c3fb1728 | |||
| e1caf3a470 | |||
| b6cf182341 | |||
| c74cdb28d6 | |||
| b200cb463e | |||
| cdf5ddf539 | |||
| 0fe33c120b | |||
| 10ea234dbf | |||
| 31f146fc6f | |||
| 0af73b0290 | |||
| 6675bac1dc | |||
| 0d49a59cfe | |||
| baa22301e9 | |||
| fdfb6187e9 | |||
| 69830f28c2 | |||
| e65a71a05a | |||
| 7a2a444579 | |||
| e16ebecda4 | |||
| 0218e39664 | |||
| 7e645f9a6a | |||
| fe23502e67 | |||
| ad2764e3ac |
@@ -107,3 +107,5 @@ src/Umbraco.Web.UI/[Cc]onfig/appSettings.config
|
||||
src/Umbraco.Web.UI/[Cc]onfig/connectionStrings.config
|
||||
src/Umbraco.Web.UI/umbraco/plugins/*
|
||||
src/Umbraco.Web.UI/umbraco/js/init.js
|
||||
build/ApiDocs/*
|
||||
build/ApiDocs/Output/*
|
||||
@@ -1,7 +1,11 @@
|
||||
Umbraco CMS
|
||||
===========
|
||||
##Note: Building version 7 from source##
|
||||
If you're interested in using the source code and building version 7, make sure to read the [Belle ReadMe file](src/Umbraco.Web.UI.Client/README.md). Note that you can always [download a nightly build](http://nightly.umbraco.org/umbraco%207.0.0/) so you don't have to build the code yourself.
|
||||
Umbraco is a free open source Content Management System built on the ASP.NET platform.
|
||||
|
||||
## Building Umbraco from source ##
|
||||
The easiest way to get started is to run `build/build.bat` which will build both the backoffice (also known as "Belle") and the Umbraco core. You can then easily start debugging from Visual Studio, or if you need to debug Belle you can run `grunt dev` in `src\Umbraco.Web.UI.Client`.
|
||||
|
||||
If you're interested in making changes to Belle make sure to read the [Belle ReadMe file](src/Umbraco.Web.UI.Client/README.md). Note that you can always [download a nightly build](http://nightly.umbraco.org/umbraco%207.0.0/) so you don't have to build the code yourself.
|
||||
|
||||
## Watch a five minute introduction video ##
|
||||
|
||||
|
||||
@@ -0,0 +1,170 @@
|
||||
/* File : TOC.css
|
||||
// Author : Eric Woodruff (Eric@EWoodruff.us)
|
||||
// Updated : 09/07/2007
|
||||
//
|
||||
// Stylesheet for the table of content
|
||||
*/
|
||||
|
||||
*
|
||||
{
|
||||
margin: 0px 0px 0px 0px;
|
||||
padding: 0px 0px 0px 0px;
|
||||
}
|
||||
|
||||
body
|
||||
{
|
||||
font-family: Segoe UI, Arial, Verdana, Helvetica, sans-serif;
|
||||
font-size: 0.9em;
|
||||
background-color: white;
|
||||
color: White;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
input
|
||||
{
|
||||
padding:5px;
|
||||
margin: 3px 0px 3px 0px
|
||||
}
|
||||
|
||||
img
|
||||
{
|
||||
border: 0;
|
||||
margin-left: 5px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
|
||||
img.TreeNodeImg
|
||||
{
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
img.TOCLink
|
||||
{
|
||||
cursor: pointer;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
a.SelectedNode, a.UnselectedNode
|
||||
{
|
||||
color: #333;
|
||||
text-decoration: none;
|
||||
padding: 1px 3px 1px 3px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
a.SelectedNode
|
||||
{
|
||||
background-color: #ffffff;
|
||||
border: solid 1px #999999;
|
||||
padding: 0px 2px 0px 2px;
|
||||
}
|
||||
|
||||
a.UnselectedNode:hover, a.SelectedNode:hover
|
||||
{
|
||||
background-color: #cccccc;
|
||||
border: solid 1px #999999;
|
||||
padding: 0px 2px 0px 2px;
|
||||
}
|
||||
|
||||
.Visible
|
||||
{
|
||||
display: block;
|
||||
margin-left: 2em;
|
||||
}
|
||||
|
||||
.Hidden
|
||||
{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.Tree
|
||||
{
|
||||
background-color: #fff;
|
||||
color: #333;
|
||||
width: 300px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.TreeNode, .TreeItem
|
||||
{
|
||||
white-space: nowrap;
|
||||
margin: 2px 2px 2px 2px;
|
||||
}
|
||||
|
||||
.TOCDiv
|
||||
{
|
||||
position: relative;
|
||||
float: left;
|
||||
width: 300px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.TOCSizer
|
||||
{
|
||||
clear: none;
|
||||
float: left;
|
||||
width: 10px;
|
||||
height: 100%;
|
||||
background-image: url("Splitter.gif");
|
||||
background-position:center center;
|
||||
background-repeat:no-repeat;
|
||||
position: relative;
|
||||
cursor: w-resize;
|
||||
border-left: solid 1px #CCC;
|
||||
}
|
||||
|
||||
.TopicContent
|
||||
{
|
||||
position: relative;
|
||||
float: right;
|
||||
background-color: white;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.SearchOpts
|
||||
{
|
||||
padding: 5px 5px 10px 5px;
|
||||
color: black;
|
||||
width: 300px;
|
||||
border-bottom: solid lightgrey 1px;
|
||||
height: 110px !important;
|
||||
}
|
||||
|
||||
.NavOpts
|
||||
{
|
||||
padding: 5px 5px 6px 5px;
|
||||
color: black;
|
||||
width: 300px;
|
||||
border-bottom: solid lightgrey 1px;
|
||||
}
|
||||
|
||||
.NavOpts img {
|
||||
display:inline-block;
|
||||
margin: 0px 5px 0px 5px;
|
||||
}
|
||||
|
||||
.IndexOpts
|
||||
{
|
||||
padding: 5px 5px 6px 5px;
|
||||
color: black;
|
||||
width: 300px;
|
||||
border-bottom: solid lightgrey 1px;
|
||||
}
|
||||
|
||||
.IndexItem
|
||||
{
|
||||
white-space: nowrap;
|
||||
margin: 2px 2px 2px 2px;
|
||||
}
|
||||
|
||||
.IndexSubItem
|
||||
{
|
||||
white-space: nowrap;
|
||||
margin: 2px 2px 2px 12px;
|
||||
}
|
||||
|
||||
.PaddedText
|
||||
{
|
||||
margin: 10px 10px 10px 10px;
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
|
||||
<PropertyGroup>
|
||||
<!-- The configuration and platform will be used to determine which
|
||||
assemblies to include from solution and project documentation
|
||||
sources -->
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{cb4d85f1-7390-40ee-b41f-a724bb8fddea}</ProjectGuid>
|
||||
<SHFBSchemaVersion>1.9.5.0</SHFBSchemaVersion>
|
||||
<!-- AssemblyName, Name, and RootNamespace are not used by SHFB but Visual
|
||||
Studio adds them anyway -->
|
||||
<AssemblyName>Documentation</AssemblyName>
|
||||
<RootNamespace>Documentation</RootNamespace>
|
||||
<Name>Documentation</Name>
|
||||
<!-- SHFB properties -->
|
||||
<FrameworkVersion>.NET Framework 4.5</FrameworkVersion>
|
||||
<OutputPath>.\Output\</OutputPath>
|
||||
<HtmlHelpName>UmbracoClassLibrary</HtmlHelpName>
|
||||
<Language>en-US</Language>
|
||||
<BuildAssemblerVerbosity>OnlyErrors</BuildAssemblerVerbosity>
|
||||
<BuildLogFile>csharp-api-docs.log</BuildLogFile>
|
||||
<HelpFileFormat>Website</HelpFileFormat>
|
||||
<IndentHtml>True</IndentHtml>
|
||||
<KeepLogFile>False</KeepLogFile>
|
||||
<DisableCodeBlockComponent>False</DisableCodeBlockComponent>
|
||||
<CppCommentsFixup>False</CppCommentsFixup>
|
||||
<CleanIntermediates>True</CleanIntermediates>
|
||||
<SyntaxFilters>CSharp</SyntaxFilters>
|
||||
<SdkLinkTarget>Blank</SdkLinkTarget>
|
||||
<RootNamespaceContainer>False</RootNamespaceContainer>
|
||||
<PresentationStyle>VS2010</PresentationStyle>
|
||||
<Preliminary>False</Preliminary>
|
||||
<NamingMethod>Guid</NamingMethod>
|
||||
<HelpTitle>Umbraco .Net Class Library</HelpTitle>
|
||||
<ContentPlacement>AboveNamespaces</ContentPlacement>
|
||||
<VisibleItems>Attributes, InheritedMembers, InheritedFrameworkMembers, Protected, SealedProtected</VisibleItems>
|
||||
<ComponentConfigurations />
|
||||
<DocumentationSources>
|
||||
<DocumentationSource sourceFile="..\..\src\Umbraco.Core\Umbraco.Core.csproj" />
|
||||
<DocumentationSource sourceFile="..\..\src\Umbraco.Core\bin\Release\Umbraco.Core.xml" />
|
||||
<DocumentationSource sourceFile="..\..\src\Umbraco.Web\Umbraco.Web.csproj" />
|
||||
<DocumentationSource sourceFile="..\..\src\Umbraco.Web\bin\Release\umbraco.xml" /></DocumentationSources>
|
||||
<WebsiteSdkLinkType>None</WebsiteSdkLinkType>
|
||||
<HtmlSdkLinkType>None</HtmlSdkLinkType>
|
||||
<IncludeFavorites>False</IncludeFavorites>
|
||||
<BinaryTOC>True</BinaryTOC>
|
||||
<MissingTags>Summary, AutoDocumentCtors, AutoDocumentDispose</MissingTags>
|
||||
<TransformComponentArguments>
|
||||
<Argument Key="logoFile" Value="" />
|
||||
<Argument Key="logoHeight" Value="" />
|
||||
<Argument Key="logoWidth" Value="" />
|
||||
<Argument Key="logoAltText" Value="" />
|
||||
<Argument Key="logoPlacement" Value="left" />
|
||||
<Argument Key="logoAlignment" Value="left" />
|
||||
</TransformComponentArguments>
|
||||
<ApiFilter>
|
||||
<Filter entryType="Namespace" fullName="CookComputing.Blogger" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="CookComputing.MetaWeblog" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="dashboardUtilities" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="presentation.umbraco.webservices" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco" isExposed="False" xmlns="">
|
||||
<Filter entryType="Class" fullName="umbraco.content" filterName="content" isExposed="True" />
|
||||
<Filter entryType="Delegate" fullName="umbraco.content.ContentCacheDatabaseLoadXmlStringEventHandler" filterName="content.ContentCacheDatabaseLoadXmlStringEventHandler" isExposed="False" />
|
||||
<Filter entryType="Delegate" fullName="umbraco.content.ContentCacheLoadNodeEventHandler" filterName="content.ContentCacheLoadNodeEventHandler" isExposed="False" />
|
||||
<Filter entryType="Delegate" fullName="umbraco.content.DocumentCacheEventHandler" filterName="content.DocumentCacheEventHandler" isExposed="False" />
|
||||
<Filter entryType="Delegate" fullName="umbraco.content.RefreshContentEventHandler" filterName="content.RefreshContentEventHandler" isExposed="False" />
|
||||
<Filter entryType="Class" fullName="umbraco.ContentExtensions" filterName="ContentExtensions" isExposed="True" />
|
||||
<Filter entryType="Class" fullName="umbraco.ContentTypeExtensions" filterName="ContentTypeExtensions" isExposed="True" />
|
||||
<Filter entryType="Class" fullName="umbraco.item" filterName="item" isExposed="True" />
|
||||
<Filter entryType="Class" fullName="umbraco.library" filterName="library" isExposed="True" />
|
||||
<Filter entryType="Class" fullName="umbraco.macro" filterName="macro" isExposed="True" />
|
||||
<Filter entryType="Class" fullName="umbraco.MacroCacheContent" filterName="MacroCacheContent" isExposed="True" />
|
||||
<Filter entryType="Class" fullName="umbraco.MacroRenderingEventArgs" filterName="MacroRenderingEventArgs" isExposed="True" />
|
||||
<Filter entryType="Class" fullName="umbraco.MediaExtensions" filterName="MediaExtensions" isExposed="True" />
|
||||
<Filter entryType="Class" fullName="umbraco.MemberExtensions" filterName="MemberExtensions" isExposed="True" />
|
||||
<Filter entryType="Class" fullName="umbraco.page" filterName="page" isExposed="True" />
|
||||
<Filter entryType="Class" fullName="umbraco.PreValueExtensions" filterName="PreValueExtensions" isExposed="True" />
|
||||
<Filter entryType="Class" fullName="umbraco.RelationTypeExtensions" filterName="RelationTypeExtensions" isExposed="True" />
|
||||
<Filter entryType="Class" fullName="umbraco.template" filterName="template" isExposed="True" />
|
||||
<Filter entryType="Class" fullName="umbraco.UmbracoObjectTypeExtensions" filterName="UmbracoObjectTypeExtensions" isExposed="True" />
|
||||
<Filter entryType="Class" fullName="umbraco.uQuery" filterName="uQuery" isExposed="True" />
|
||||
<Filter entryType="Interface" fullName="umbraco.uQuery.IGetProperty" filterName="uQuery.IGetProperty" isExposed="True" />
|
||||
<Filter entryType="Class" fullName="umbraco.uQuery.Members" filterName="uQuery.Members" isExposed="True" />
|
||||
<Filter entryType="Enumeration" fullName="umbraco.uQuery.UmbracoObjectType" filterName="uQuery.UmbracoObjectType" isExposed="True" />
|
||||
</Filter>
|
||||
<Filter entryType="Namespace" fullName="umbraco.cms.presentation" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.cms.presentation.create.controls" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.cms.presentation.developer" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.cms.presentation.developer.RelationTypes" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.cms.presentation.developer.RelationTypes.TreeMenu" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.cms.presentation.members" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.cms.presentation.settings" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.cms.presentation.settings.modal" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.cms.presentation.settings.scripts" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.cms.presentation.settings.stylesheet" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.cms.presentation.user" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.controls" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.controls.GenericProperties" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.controls.Images" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.controls.Tree" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.developer" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.dialogs" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.js" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.layoutControls" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.NodeFactory" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.actions" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.channels" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.channels.businesslogic" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.create" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.developer.packages" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.dialogs" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.masterpages" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.members" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.nodeFactory" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.org.umbraco.update" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.plugins.tinymce3" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.preview" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.Search" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.settings" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.templateControls" isExposed="False" xmlns="">
|
||||
<Filter entryType="Class" fullName="umbraco.presentation.templateControls.Item" filterName="Item" isExposed="True" />
|
||||
<Filter entryType="Class" fullName="umbraco.presentation.templateControls.ItemRenderer" filterName="ItemRenderer" isExposed="True" />
|
||||
<Filter entryType="Class" fullName="umbraco.presentation.templateControls.Macro" filterName="Macro" isExposed="True" />
|
||||
<Filter entryType="Enumeration" fullName="umbraco.presentation.templateControls.Macro.RenderEvents" filterName="Macro.RenderEvents" isExposed="False" />
|
||||
</Filter>
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.tinymce3" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.translation" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.umbraco" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.umbraco.channels" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.umbraco.controls" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.umbraco.create" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.umbraco.developer.Xslt" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.umbraco.dialogs" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.umbraco.masterpages" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.umbraco.members" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.umbraco.plugins.tinymce3" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.umbraco.Search" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.umbraco.translation" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.umbraco.webservices" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.umbraco_client.tinymce3.plugins.spellchecker" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.urlRewriter" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.Web.UI" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.webservices" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.scripting" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.settings" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="Umbraco.Web.org.umbraco.our" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.webservices" isExposed="False" xmlns="" /></ApiFilter>
|
||||
</PropertyGroup>
|
||||
<!-- There are no properties for these groups. AnyCPU needs to appear in
|
||||
order for Visual Studio to perform the build. The others are optional
|
||||
common platform types that may appear. -->
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|Win32' ">
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|Win32' ">
|
||||
</PropertyGroup>
|
||||
<!-- Import the SHFB build targets -->
|
||||
<Import Project="$(SHFBROOT)\SandcastleHelpFileBuilder.targets" />
|
||||
</Project>
|
||||
+11
-2
@@ -1,14 +1,21 @@
|
||||
@ECHO OFF
|
||||
SET release=7.0.1
|
||||
SET comment=
|
||||
SET release=7.1.0
|
||||
SET comment=beta
|
||||
SET version=%release%
|
||||
|
||||
IF [%comment%] EQU [] (SET version=%release%) ELSE (SET version=%release%-%comment%)
|
||||
ECHO Building Umbraco %version%
|
||||
|
||||
ReplaceIISExpressPortNumber.exe ..\src\Umbraco.Web.UI\Umbraco.Web.UI.csproj %release%
|
||||
|
||||
ECHO Installing the Microsoft.Bcl.Build package before anything else, otherwise you'd have to run build.cmd twice
|
||||
SET nuGetFolder=%CD%\..\src\packages\
|
||||
..\src\.nuget\NuGet.exe install ..\src\Umbraco.Web.UI\packages.config -OutputDirectory %nuGetFolder%
|
||||
|
||||
ECHO Performing MSBuild and producing Umbraco binaries zip files
|
||||
%windir%\Microsoft.NET\Framework\v4.0.30319\msbuild.exe "Build.proj" /p:BUILD_RELEASE=%release% /p:BUILD_COMMENT=%comment%
|
||||
|
||||
ECHO Adding dummy files to include in the NuGet package so that empty folders actually get created
|
||||
echo This file is only here so that the containing folder will be included in the NuGet package, it is safe to delete. > .\_BuildOutput\WebApp\App_Code\dummy.txt
|
||||
echo This file is only here so that the containing folder will be included in the NuGet package, it is safe to delete. > .\_BuildOutput\WebApp\App_Data\dummy.txt
|
||||
echo This file is only here so that the containing folder will be included in the NuGet package, it is safe to delete. > .\_BuildOutput\WebApp\App_Plugins\dummy.txt
|
||||
@@ -20,9 +27,11 @@ echo This file is only here so that the containing folder will be included in th
|
||||
echo This file is only here so that the containing folder will be included in the NuGet package, it is safe to delete. > .\_BuildOutput\WebApp\Views\Partials\dummy.txt
|
||||
echo This file is only here so that the containing folder will be included in the NuGet package, it is safe to delete. > .\_BuildOutput\WebApp\Views\MacroPartials\dummy.txt
|
||||
|
||||
ECHO Adding Web.config transform files to the NuGet package
|
||||
ren .\_BuildOutput\WebApp\MacroScripts\Web.config Web.config.transform
|
||||
ren .\_BuildOutput\WebApp\Views\Web.config Web.config.transform
|
||||
|
||||
ECHO Packing the NuGet release files
|
||||
..\src\.nuget\NuGet.exe pack NuSpecs\UmbracoCms.Core.nuspec -Version %version%
|
||||
..\src\.nuget\NuGet.exe pack NuSpecs\UmbracoCms.nuspec -Version %version%
|
||||
|
||||
|
||||
+1
-1
@@ -267,7 +267,7 @@
|
||||
<Message Text="Compiling web project to build\$(BuildFolder)" Importance="high" />
|
||||
<!-- For UseWPP_CopyWebApplication=True see http://stackoverflow.com/questions/1983575/copywebapplication-with-web-config-transformations -->
|
||||
<!-- Build the Umbraco.Web.UI project -->
|
||||
<MSBuild Projects="..\src\Umbraco.Web.UI\Umbraco.Web.UI.csproj" Properties="WarningLevel=0;Configuration=$(BuildConfiguration);UseWPP_CopyWebApplication=True;PipelineDependsOnBuild=False;OutDir=$(SolutionBinFolderAbsolutePath);WebProjectOutputDir=$(WebAppFolderAbsolutePath)" Targets="Clean;Build;" BuildInParallel="False" ToolsVersion="4.0" UnloadProjectsOnCompletion="False">
|
||||
<MSBuild Projects="..\src\Umbraco.Web.UI\Umbraco.Web.UI.csproj" Properties="WarningLevel=0;Configuration=$(BuildConfiguration);UseWPP_CopyWebApplication=True;PipelineDependsOnBuild=False;OutDir=$(SolutionBinFolderAbsolutePath);WebProjectOutputDir=$(WebAppFolderAbsolutePath)" Targets="Clean;Rebuild;" BuildInParallel="False" ToolsVersion="4.0" UnloadProjectsOnCompletion="False">
|
||||
</MSBuild>
|
||||
|
||||
<!-- DONE -->
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
@ECHO OFF
|
||||
ECHO Installing Npm NuGet Package
|
||||
|
||||
SET nuGetFolder=%CD%\..\src\packages\
|
||||
ECHO Configured packages folder: %nuGetFolder%
|
||||
ECHO Current folder: %CD%
|
||||
|
||||
%CD%\..\src\.nuget\NuGet.exe install Npm.js -OutputDirectory %nuGetFolder%
|
||||
|
||||
for /f "delims=" %%A in ('dir %nuGetFolder%node.js.* /b') do set "nodePath=%nuGetFolder%%%A\"
|
||||
for /f "delims=" %%A in ('dir %nuGetFolder%npm.js.* /b') do set "npmPath=%nuGetFolder%%%A\tools\"
|
||||
|
||||
ECHO Temporarily adding Npm and Node to path
|
||||
SET oldPath=%PATH%
|
||||
|
||||
path=%npmPath%;%nodePath%;%PATH%
|
||||
|
||||
SET buildFolder=%CD%
|
||||
|
||||
ECHO Change directory to %CD%\..\src\Umbraco.Web.UI.Client\
|
||||
CD %CD%\..\src\Umbraco.Web.UI.Client\
|
||||
|
||||
ECHO Do npm install and the grunt build of Belle
|
||||
call npm install
|
||||
call npm install -g grunt-cli
|
||||
call grunt build
|
||||
|
||||
ECHO Reset path to what it was before
|
||||
path=%oldPath%
|
||||
|
||||
ECHO Move back to the build folder
|
||||
CD %buildFolder%
|
||||
@@ -0,0 +1,27 @@
|
||||
##We cannot continue if sandcastle is not installed determined by env variable: SHFBROOT
|
||||
|
||||
if (-not (Test-Path Env:\SHFBROOT))
|
||||
{
|
||||
throw "The docs cannot be build, install Sandcastle help file builder"
|
||||
}
|
||||
|
||||
$PSScriptFilePath = (Get-Item $MyInvocation.MyCommand.Path).FullName
|
||||
$BuildRoot = Split-Path -Path $PSScriptFilePath -Parent
|
||||
$OutputPath = Join-Path -Path $BuildRoot -ChildPath "ApiDocs\Output"
|
||||
$ProjFile = Join-Path -Path $BuildRoot -ChildPath "ApiDocs\csharp-api-docs.shfbproj"
|
||||
|
||||
"Building docs with project file: $ProjFile"
|
||||
|
||||
$MSBuild = "$Env:SYSTEMROOT\Microsoft.NET\Framework\v4.0.30319\msbuild.exe"
|
||||
|
||||
# build it!
|
||||
& $MSBuild "$ProjFile"
|
||||
|
||||
# remove files left over
|
||||
Remove-Item $BuildRoot\* -include csharp-api-docs.shfbproj_*
|
||||
|
||||
# copy our custom styles in
|
||||
Copy-Item $BuildRoot\ApiDocs\TOC.css $OutputPath\TOC.css
|
||||
|
||||
""
|
||||
"Done!"
|
||||
@@ -26,7 +26,7 @@
|
||||
<dependency id="SharpZipLib" version="[0.86.0, 1.0.0)" />
|
||||
<dependency id="MySql.Data" version="[6.6.5]" />
|
||||
<dependency id="xmlrpcnet" version="[2.5.0, 3.0.0)" />
|
||||
<dependency id="ClientDependency" version="[1.7.0, 2.0.0)" />
|
||||
<!--<dependency id="ClientDependency" version="[1.7.0, 2.0.0)" />-->
|
||||
<dependency id="ClientDependency-Mvc" version="[1.7.0, 2.0.0)" />
|
||||
<dependency id="AutoMapper" version="[3.0.0, 4.0.0)" />
|
||||
<dependency id="Newtonsoft.Json" version="[4.5.11, 5.0.0)" />
|
||||
@@ -35,6 +35,7 @@
|
||||
<files>
|
||||
<file src="..\_BuildOutput\WebApp\bin\businesslogic.dll" target="lib\businesslogic.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\businesslogic.xml" target="lib\businesslogic.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\ClientDependency.Core.dll" target="lib\ClientDependency.Core.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\cms.dll" target="lib\cms.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\cms.xml" target="lib\cms.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\controls.dll" target="lib\controls.dll" />
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
<file src="..\_BuildOutput\WebApp\App_Data\**" target="UmbracoFiles\App_Data" />
|
||||
<file src="..\_BuildOutput\WebApp\App_Plugins\**" target="UmbracoFiles\App_Plugins" />
|
||||
<file src="..\_BuildOutput\WebApp\config\splashes\**" target="UmbracoFiles\config\splashes" />
|
||||
<file src="..\_BuildOutput\WebApp\install\**" target="UmbracoFiles\install" />
|
||||
<file src="..\_BuildOutput\WebApp\umbraco\**" target="UmbracoFiles\umbraco" />
|
||||
<file src="..\_BuildOutput\WebApp\umbraco_client\**" target="UmbracoFiles\umbraco_client" />
|
||||
<file src="..\_BuildOutput\WebApp\Global.asax" target="UmbracoFiles\Global.asax" />
|
||||
|
||||
Binary file not shown.
+12
-27
@@ -18,13 +18,13 @@
|
||||
|
||||
<ItemGroup Condition=" '$(PackageSources)' == '' ">
|
||||
<!-- Package sources used to restore packages. By default, registered sources under %APPDATA%\NuGet\NuGet.Config will be used -->
|
||||
<!-- The official NuGet package source (https://nuget.org/api/v2/) will be excluded if package sources are specified and it does not appear in the list -->
|
||||
<!-- The official NuGet package source (https://www.nuget.org/api/v2/) will be excluded if package sources are specified and it does not appear in the list -->
|
||||
<!--
|
||||
<PackageSource Include="https://nuget.org/api/v2/" />
|
||||
<PackageSource Include="https://www.nuget.org/api/v2/" />
|
||||
<PackageSource Include="https://my-nuget-source/nuget/" />
|
||||
-->
|
||||
<PackageSource Include="https://nuget.org/api/v2/" />
|
||||
<PackageSource Include="http://www.myget.org/F/umbracocore/" />
|
||||
<PackageSource Include="http://www.myget.org/F/umbracocore/" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(OS)' == 'Windows_NT'">
|
||||
@@ -41,7 +41,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- NuGet command -->
|
||||
<NuGetExePath Condition=" '$(NuGetExePath)' == '' ">$(NuGetToolsPath)\nuget.exe</NuGetExePath>
|
||||
<NuGetExePath Condition=" '$(NuGetExePath)' == '' ">$(NuGetToolsPath)\NuGet.exe</NuGetExePath>
|
||||
<PackageSources Condition=" $(PackageSources) == '' ">@(PackageSource)</PackageSources>
|
||||
|
||||
<NuGetCommand Condition=" '$(OS)' == 'Windows_NT'">"$(NuGetExePath)"</NuGetCommand>
|
||||
@@ -50,9 +50,14 @@
|
||||
<PackageOutputDir Condition="$(PackageOutputDir) == ''">$(TargetDir.Trim('\\'))</PackageOutputDir>
|
||||
|
||||
<RequireConsentSwitch Condition=" $(RequireRestoreConsent) == 'true' ">-RequireConsent</RequireConsentSwitch>
|
||||
<NonInteractiveSwitch Condition=" '$(VisualStudioVersion)' != '' AND '$(OS)' == 'Windows_NT' ">-NonInteractive</NonInteractiveSwitch>
|
||||
|
||||
<PaddedSolutionDir Condition=" '$(OS)' == 'Windows_NT'">"$(SolutionDir) "</PaddedSolutionDir>
|
||||
<PaddedSolutionDir Condition=" '$(OS)' != 'Windows_NT' ">"$(SolutionDir)"</PaddedSolutionDir>
|
||||
|
||||
<!-- Commands -->
|
||||
<RestoreCommand>$(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)" $(RequireConsentSwitch) -solutionDir "$(SolutionDir) "</RestoreCommand>
|
||||
<BuildCommand>$(NuGetCommand) pack "$(ProjectPath)" -p Configuration=$(Configuration) -o "$(PackageOutputDir)" -symbols</BuildCommand>
|
||||
<RestoreCommand>$(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)" $(NonInteractiveSwitch) $(RequireConsentSwitch) -solutionDir $(PaddedSolutionDir)</RestoreCommand>
|
||||
<BuildCommand>$(NuGetCommand) pack "$(ProjectPath)" -Properties "Configuration=$(Configuration);Platform=$(Platform)" $(NonInteractiveSwitch) -OutputDirectory "$(PackageOutputDir)" -symbols</BuildCommand>
|
||||
|
||||
<!-- We need to ensure packages are restored prior to assembly resolve -->
|
||||
<BuildDependsOn Condition="$(RestorePackages) == 'true'">
|
||||
@@ -70,7 +75,6 @@
|
||||
<Target Name="CheckPrerequisites">
|
||||
<!-- Raise an error if we're unable to locate nuget.exe -->
|
||||
<Error Condition="'$(DownloadNuGetExe)' != 'true' AND !Exists('$(NuGetExePath)')" Text="Unable to locate '$(NuGetExePath)'" />
|
||||
<SetEnvironmentVariable EnvKey="VisualStudioVersion" EnvValue="$(VisualStudioVersion)" Condition=" '$(VisualStudioVersion)' != '' AND '$(OS)' == 'Windows_NT' " />
|
||||
<!--
|
||||
Take advantage of MsBuild's build dependency tracking to make sure that we only ever download nuget.exe once.
|
||||
This effectively acts as a lock that makes sure that the download operation will only happen once and all
|
||||
@@ -119,7 +123,7 @@
|
||||
|
||||
Log.LogMessage("Downloading latest version of NuGet.exe...");
|
||||
WebClient webClient = new WebClient();
|
||||
webClient.DownloadFile("https://nuget.org/nuget.exe", OutputFilename);
|
||||
webClient.DownloadFile("https://www.nuget.org/nuget.exe", OutputFilename);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -131,23 +135,4 @@
|
||||
</Code>
|
||||
</Task>
|
||||
</UsingTask>
|
||||
|
||||
<UsingTask TaskName="SetEnvironmentVariable" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
|
||||
<ParameterGroup>
|
||||
<EnvKey ParameterType="System.String" Required="true" />
|
||||
<EnvValue ParameterType="System.String" Required="true" />
|
||||
</ParameterGroup>
|
||||
<Task>
|
||||
<Using Namespace="System" />
|
||||
<Code Type="Fragment" Language="cs">
|
||||
<![CDATA[
|
||||
try {
|
||||
Environment.SetEnvironmentVariable(EnvKey, EnvValue, System.EnvironmentVariableTarget.Process);
|
||||
}
|
||||
catch {
|
||||
}
|
||||
]]>
|
||||
</Code>
|
||||
</Task>
|
||||
</UsingTask>
|
||||
</Project>
|
||||
@@ -42,6 +42,13 @@ namespace SqlCE4Umbraco
|
||||
{
|
||||
var sqlCeEngine = new SqlCeEngine(ConnectionString);
|
||||
sqlCeEngine.CreateDatabase();
|
||||
|
||||
// SD: Pretty sure this should be in a using clause but i don't want to cause unknown side-effects here
|
||||
// since it's been like this for quite some time
|
||||
//using (var sqlCeEngine = new SqlCeEngine(ConnectionString))
|
||||
//{
|
||||
// sqlCeEngine.CreateDatabase();
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -165,6 +165,9 @@ namespace Umbraco.Core
|
||||
/// </remarks>
|
||||
internal string OriginalRequestUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the version configured matches the assembly version
|
||||
/// </summary>
|
||||
private bool Configured
|
||||
{
|
||||
get
|
||||
|
||||
@@ -160,5 +160,15 @@ namespace Umbraco.Core
|
||||
{
|
||||
return new Attempt<T>(condition, result, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implicity operator to check if the attempt was successful without having to access the 'success' property
|
||||
/// </summary>
|
||||
/// <param name="a"></param>
|
||||
/// <returns></returns>
|
||||
public static implicit operator bool(Attempt<T> a)
|
||||
{
|
||||
return a.Success;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
|
||||
@@ -9,6 +11,7 @@ namespace Umbraco.Core.Cache
|
||||
public const string ApplicationTreeCacheKey = "ApplicationTreeCache";
|
||||
public const string ApplicationsCacheKey = "ApplicationCache";
|
||||
|
||||
[Obsolete("This is no longer used and will be removed from the codebase in the future")]
|
||||
public const string UserTypeCacheKey = "UserTypeCache";
|
||||
|
||||
public const string ContentItemCacheKey = "contentItem";
|
||||
@@ -24,13 +27,16 @@ namespace Umbraco.Core.Cache
|
||||
|
||||
public const string MemberLibraryCacheKey = "UL_GetMember";
|
||||
public const string MemberBusinessLogicCacheKey = "MemberCacheItem_";
|
||||
|
||||
|
||||
public const string TemplateFrontEndCacheKey = "template";
|
||||
public const string TemplateBusinessLogicCacheKey = "UmbracoTemplateCache";
|
||||
|
||||
public const string UserContextCacheKey = "UmbracoUserContext";
|
||||
public const string UserContextTimeoutCacheKey = "UmbracoUserContextTimeout";
|
||||
|
||||
[Obsolete("This is no longer used and will be removed from the codebase in the future")]
|
||||
public const string UserCacheKey = "UmbracoUser";
|
||||
|
||||
public const string UserPermissionsCacheKey = "UmbracoUserPermissions";
|
||||
|
||||
public const string ContentTypeCacheKey = "UmbracoContentType";
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ using System.Threading;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
internal abstract class DictionaryCacheProdiverBase : ICacheProvider
|
||||
internal abstract class DictionaryCacheProviderBase : ICacheProvider
|
||||
{
|
||||
protected static readonly ReaderWriterLockSlim Locker = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
|
||||
protected abstract DictionaryCacheWrapper DictionaryCache { get; }
|
||||
@@ -10,7 +10,7 @@ namespace Umbraco.Core.Cache
|
||||
/// <summary>
|
||||
/// A cache provider that caches items in the HttpContext.Items
|
||||
/// </summary>
|
||||
internal class HttpRequestCacheProvider : DictionaryCacheProdiverBase
|
||||
internal class HttpRequestCacheProvider : DictionaryCacheProviderBase
|
||||
{
|
||||
private readonly Func<HttpContextBase> _context;
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Umbraco.Core.Cache
|
||||
/// <summary>
|
||||
/// A CacheProvider that wraps the logic of the HttpRuntime.Cache
|
||||
/// </summary>
|
||||
internal class HttpRuntimeCacheProvider : DictionaryCacheProdiverBase, IRuntimeCacheProvider
|
||||
internal class HttpRuntimeCacheProvider : DictionaryCacheProviderBase, IRuntimeCacheProvider
|
||||
{
|
||||
private readonly System.Web.Caching.Cache _cache;
|
||||
private readonly DictionaryCacheWrapper _wrapper;
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace Umbraco.Core
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ICacheRefresher"/> implementations.
|
||||
/// </summary>
|
||||
public IEnumerable<ICacheRefresher> CacheResolvers
|
||||
public IEnumerable<ICacheRefresher> CacheRefreshers
|
||||
{
|
||||
get
|
||||
{
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Umbraco.Core.Configuration
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Increases the version number in ClientDependency.config by 1
|
||||
/// Changes the version number in ClientDependency.config to a random value to avoid stale caches
|
||||
/// </summary>
|
||||
internal bool IncreaseVersionNumber()
|
||||
{
|
||||
@@ -28,9 +28,9 @@ namespace Umbraco.Core.Configuration
|
||||
|
||||
var versionAttribute = clientDependencyConfigXml.Root.Attribute("version");
|
||||
|
||||
int oldVersion;
|
||||
int.TryParse(versionAttribute.Value, out oldVersion);
|
||||
var newVersion = oldVersion + 1;
|
||||
//Set the new version to the hashcode of now
|
||||
var oldVersion = versionAttribute.Value;
|
||||
var newVersion = Math.Abs(DateTime.UtcNow.GetHashCode());
|
||||
|
||||
versionAttribute.SetValue(newVersion);
|
||||
clientDependencyConfigXml.Save(_fileName, SaveOptions.DisableFormatting);
|
||||
|
||||
@@ -6,10 +6,13 @@ using System.Web;
|
||||
using System.Web.Configuration;
|
||||
using System.Web.Hosting;
|
||||
using System.Web.Routing;
|
||||
using System.Web.Security;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using System.Xml.XPath;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Security;
|
||||
|
||||
namespace Umbraco.Core.Configuration
|
||||
{
|
||||
@@ -38,7 +41,7 @@ namespace Umbraco.Core.Configuration
|
||||
private static string _reservedUrls;
|
||||
//ensure the built on (non-changeable) reserved paths are there at all times
|
||||
private const string StaticReservedPaths = "~/app_plugins/,~/install/,";
|
||||
private const string StaticReservedUrls = "~/config/splashes/booting.aspx,~/install/default.aspx,~/config/splashes/noNodes.aspx,~/VSEnterpriseHelper.axd,";
|
||||
private const string StaticReservedUrls = "~/config/splashes/booting.aspx,~/config/splashes/noNodes.aspx,~/VSEnterpriseHelper.axd,";
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -259,7 +262,38 @@ namespace Umbraco.Core.Configuration
|
||||
SaveSetting("umbracoConfigurationStatus", value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Umbraco members membership providers' useLegacyEncoding state. This will return a boolean
|
||||
/// </summary>
|
||||
/// <value>The useLegacyEncoding status.</value>
|
||||
public static bool UmbracoMembershipProviderLegacyEncoding
|
||||
{
|
||||
get
|
||||
{
|
||||
return IsConfiguredMembershipProviderUsingLegacyEncoding(Constants.Conventions.Member.UmbracoMemberProviderName);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetMembershipProvidersLegacyEncoding(Constants.Conventions.Member.UmbracoMemberProviderName, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Umbraco users membership providers' useLegacyEncoding state. This will return a boolean
|
||||
/// </summary>
|
||||
/// <value>The useLegacyEncoding status.</value>
|
||||
public static bool UmbracoUsersMembershipProviderLegacyEncoding
|
||||
{
|
||||
get
|
||||
{
|
||||
return IsConfiguredMembershipProviderUsingLegacyEncoding(Constants.Conventions.User.UmbracoUsersProviderName);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetMembershipProvidersLegacyEncoding(Constants.Conventions.User.UmbracoUsersProviderName, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves a setting into the configuration file.
|
||||
@@ -301,7 +335,51 @@ namespace Umbraco.Core.Configuration
|
||||
setting.Remove();
|
||||
xml.Save(fileName, SaveOptions.DisableFormatting);
|
||||
ConfigurationManager.RefreshSection("appSettings");
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetMembershipProvidersLegacyEncoding(string providerName, bool useLegacyEncoding)
|
||||
{
|
||||
//check if this can even be configured.
|
||||
var membershipProvider = Membership.Providers[providerName] as MembershipProviderBase;
|
||||
if (membershipProvider == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (membershipProvider.GetType().Namespace == "umbraco.providers.members")
|
||||
{
|
||||
//its the legacy one, this cannot be changed
|
||||
return;
|
||||
}
|
||||
|
||||
var webConfigFilename = IOHelper.MapPath(string.Format("{0}/web.config", SystemDirectories.Root));
|
||||
var webConfigXml = XDocument.Load(webConfigFilename, LoadOptions.PreserveWhitespace);
|
||||
|
||||
var membershipConfigs = webConfigXml.XPathSelectElements("configuration/system.web/membership/providers/add").ToList();
|
||||
|
||||
if (membershipConfigs.Any() == false)
|
||||
return;
|
||||
|
||||
var provider = membershipConfigs.SingleOrDefault(c => c.Attribute("name") != null && c.Attribute("name").Value == providerName);
|
||||
|
||||
if (provider == null)
|
||||
return;
|
||||
|
||||
provider.SetAttributeValue("useLegacyEncoding", useLegacyEncoding);
|
||||
|
||||
webConfigXml.Save(webConfigFilename, SaveOptions.DisableFormatting);
|
||||
}
|
||||
|
||||
private static bool IsConfiguredMembershipProviderUsingLegacyEncoding(string providerName)
|
||||
{
|
||||
//check if this can even be configured.
|
||||
var membershipProvider = Membership.Providers[providerName] as MembershipProviderBase;
|
||||
if (membershipProvider == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return membershipProvider.UseLegacyEncoding;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -697,8 +775,12 @@ namespace Umbraco.Core.Configuration
|
||||
StartsWithContainer _newReservedList = new StartsWithContainer();
|
||||
foreach (string reservedUrl in _reservedUrlsCache.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(reservedUrl))
|
||||
continue;
|
||||
|
||||
|
||||
//resolves the url to support tilde chars
|
||||
string reservedUrlTrimmed = IOHelper.ResolveUrl(reservedUrl).Trim().ToLower();
|
||||
string reservedUrlTrimmed = IOHelper.ResolveUrl(reservedUrl.Trim()).Trim().ToLower();
|
||||
if (reservedUrlTrimmed.Length > 0)
|
||||
_newReservedList.Add(reservedUrlTrimmed);
|
||||
}
|
||||
@@ -706,8 +788,11 @@ namespace Umbraco.Core.Configuration
|
||||
foreach (string reservedPath in _reservedPathsCache.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
bool trimEnd = !reservedPath.EndsWith("/");
|
||||
if (string.IsNullOrWhiteSpace(reservedPath))
|
||||
continue;
|
||||
|
||||
//resolves the url to support tilde chars
|
||||
string reservedPathTrimmed = IOHelper.ResolveUrl(reservedPath).Trim().ToLower();
|
||||
string reservedPathTrimmed = IOHelper.ResolveUrl(reservedPath.Trim()).Trim().ToLower();
|
||||
|
||||
if (reservedPathTrimmed.Length > 0)
|
||||
_newReservedList.Add(reservedPathTrimmed + (reservedPathTrimmed.EndsWith("/") ? "" : "/"));
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Configuration;
|
||||
|
||||
namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
{
|
||||
internal class ContentImagingElement : ConfigurationElement
|
||||
{
|
||||
|
||||
[ConfigurationProperty("imageFileTypes")]
|
||||
internal CommaDelimitedConfigurationElement ImageFileTypes
|
||||
{
|
||||
|
||||
@@ -10,6 +10,8 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
|
||||
bool RemoveDoubleDashes { get; }
|
||||
|
||||
bool ConvertUrlsToAscii { get; }
|
||||
|
||||
IEnumerable<IChar> CharCollection { get; }
|
||||
}
|
||||
}
|
||||
@@ -121,6 +121,11 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
get { return UrlReplacing.RemoveDoubleDashes; }
|
||||
}
|
||||
|
||||
bool IRequestHandlerSection.ConvertUrlsToAscii
|
||||
{
|
||||
get { return UrlReplacing.ConvertUrlsToAscii; }
|
||||
}
|
||||
|
||||
IEnumerable<IChar> IRequestHandlerSection.CharCollection
|
||||
{
|
||||
get { return UrlReplacing.CharCollection; }
|
||||
|
||||
@@ -11,6 +11,12 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
get { return (bool) base["removeDoubleDashes"]; }
|
||||
}
|
||||
|
||||
[ConfigurationProperty("toAscii", DefaultValue = false)]
|
||||
internal bool ConvertUrlsToAscii
|
||||
{
|
||||
get { return (bool)base["toAscii"]; }
|
||||
}
|
||||
|
||||
[ConfigurationCollection(typeof(CharCollection), AddItemName = "char")]
|
||||
[ConfigurationProperty("", IsDefaultCollection = true)]
|
||||
internal CharCollection CharCollection
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
return new OptionalInnerTextConfigurationElement<string>(
|
||||
(InnerTextConfigurationElement<string>)this["DefaultBackofficeProvider"],
|
||||
//set the default
|
||||
"UsersMembershipProvider");
|
||||
Constants.Conventions.User.UmbracoUsersProviderName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
public class UmbracoVersion
|
||||
{
|
||||
private static readonly Version Version = new Version("7.0.1");
|
||||
private static readonly Version Version = new Version("7.1.0");
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current version of Umbraco.
|
||||
@@ -23,7 +23,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets the version comment (like beta or RC).
|
||||
/// </summary>
|
||||
/// <value>The version comment.</value>
|
||||
public static string CurrentComment { get { return ""; } }
|
||||
public static string CurrentComment { get { return "beta"; } }
|
||||
|
||||
// Get the version of the umbraco.dll by looking at a class in that dll
|
||||
// Had to do it like this due to medium trust issues, see: http://haacked.com/archive/2010/11/04/assembly-location-and-medium-trust.aspx
|
||||
|
||||
@@ -85,7 +85,7 @@ namespace Umbraco.Core
|
||||
|
||||
/// <summary>
|
||||
/// MediaType alias for a folder.
|
||||
/// </summary>
|
||||
/// </summary>
|
||||
public const string Folder = "Folder";
|
||||
|
||||
/// <summary>
|
||||
@@ -94,9 +94,18 @@ namespace Umbraco.Core
|
||||
public const string Image = "Image";
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Constants for Umbraco user
|
||||
/// </summary>
|
||||
public static class User
|
||||
{
|
||||
public static readonly string UmbracoUsersProviderName = "UsersMembershipProvider";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constants for Umbraco Member property aliases.
|
||||
/// </summary>
|
||||
/// </summary>
|
||||
public static class Member
|
||||
{
|
||||
/// <summary>
|
||||
@@ -111,191 +120,149 @@ namespace Umbraco.Core
|
||||
/// <summary>
|
||||
/// Property alias for a Members Password Question
|
||||
/// </summary>
|
||||
public const string PasswordQuestion = "umbracoPasswordRetrievalQuestionPropertyTypeAlias";
|
||||
public const string PasswordQuestion = "umbracoMemberPasswordRetrievalQuestion";
|
||||
|
||||
public const string PasswordQuestionLabel = "Password Question";
|
||||
|
||||
/// <summary>
|
||||
/// Property alias for Members Password Answer
|
||||
/// </summary>
|
||||
public const string PasswordAnswer = "umbracoPasswordRetrievalAnswerPropertyTypeAlias";
|
||||
public const string PasswordAnswer = "umbracoMemberPasswordRetrievalAnswer";
|
||||
|
||||
public const string PasswordAnswerLabel = "Password Answer";
|
||||
|
||||
/// <summary>
|
||||
/// Property alias for the Comments on a Member
|
||||
/// </summary>
|
||||
public const string Comments = "umbracoCommentPropertyTypeAlias";
|
||||
public const string Comments = "umbracoMemberComments";
|
||||
|
||||
public const string CommentsLabel = "Comments";
|
||||
|
||||
/// <summary>
|
||||
/// Property alias for the Approved boolean of a Member
|
||||
/// </summary>
|
||||
public const string IsApproved = "umbracoApprovePropertyTypeAlias";
|
||||
public const string IsApproved = "umbracoMemberApproved";
|
||||
|
||||
public const string IsApprovedLabel = "Is Approved";
|
||||
|
||||
/// <summary>
|
||||
/// Property alias for the Locked out boolean of a Member
|
||||
/// </summary>
|
||||
public const string IsLockedOut = "umbracoLockPropertyTypeAlias";
|
||||
public const string IsLockedOut = "umbracoMemberLockedOut";
|
||||
|
||||
public const string IsLockedOutLabel = "Is Locked Out";
|
||||
|
||||
/// <summary>
|
||||
/// Property alias for the last date the Member logged in
|
||||
/// </summary>
|
||||
public const string LastLoginDate = "umbracoLastLoginPropertyTypeAlias";
|
||||
public const string LastLoginDate = "umbracoMemberLastLogin";
|
||||
|
||||
public const string LastLoginDateLabel = "Last Login Date";
|
||||
|
||||
/// <summary>
|
||||
/// Property alias for the last date a Member changed its password
|
||||
/// </summary>
|
||||
public const string LastPasswordChangeDate = "umbracoMemberLastPasswordChange";
|
||||
public const string LastPasswordChangeDate = "umbracoMemberLastPasswordChangeDate";
|
||||
|
||||
public const string LastPasswordChangeDateLabel = "Last Password Change Date";
|
||||
|
||||
/// <summary>
|
||||
/// Property alias for the last date a Member was locked out
|
||||
/// </summary>
|
||||
public const string LastLockoutDate = "umbracoMemberLastLockout";
|
||||
public const string LastLockoutDate = "umbracoMemberLastLockoutDate";
|
||||
|
||||
public const string LastLockoutDateLabel = "Last Lockout Date";
|
||||
|
||||
/// <summary>
|
||||
/// Property alias for the number of failed login attemps
|
||||
/// </summary>
|
||||
public const string FailedPasswordAttempts = "umbracoFailedPasswordAttemptsPropertyTypeAlias";
|
||||
public const string FailedPasswordAttempts = "umbracoMemberFailedPasswordAttempts";
|
||||
|
||||
public const string FailedPasswordAttemptsLabel = "Failed Password Attempts";
|
||||
|
||||
internal static Dictionary<string, PropertyType>
|
||||
StandardPropertyTypeStubs = new Dictionary<string, PropertyType>
|
||||
{
|
||||
{
|
||||
Comments,
|
||||
new PropertyType(
|
||||
PropertyEditors
|
||||
.TextboxMultipleAlias,
|
||||
DataTypeDatabaseType
|
||||
.Ntext)
|
||||
{
|
||||
Alias = Comments,
|
||||
Name =
|
||||
CommentsLabel
|
||||
}
|
||||
},
|
||||
{
|
||||
FailedPasswordAttempts,
|
||||
new PropertyType(
|
||||
PropertyEditors
|
||||
.IntegerAlias,
|
||||
DataTypeDatabaseType
|
||||
.Integer)
|
||||
{
|
||||
Alias =
|
||||
FailedPasswordAttempts,
|
||||
Name =
|
||||
FailedPasswordAttemptsLabel
|
||||
}
|
||||
},
|
||||
{
|
||||
IsApproved,
|
||||
new PropertyType(
|
||||
PropertyEditors
|
||||
.TrueFalseAlias,
|
||||
DataTypeDatabaseType
|
||||
.Integer)
|
||||
{
|
||||
Alias = IsApproved,
|
||||
Name =
|
||||
IsApprovedLabel
|
||||
}
|
||||
},
|
||||
{
|
||||
IsLockedOut,
|
||||
new PropertyType(
|
||||
PropertyEditors
|
||||
.TrueFalseAlias,
|
||||
DataTypeDatabaseType
|
||||
.Integer)
|
||||
{
|
||||
Alias =
|
||||
IsLockedOut,
|
||||
Name =
|
||||
IsLockedOutLabel
|
||||
}
|
||||
},
|
||||
{
|
||||
LastLockoutDate,
|
||||
new PropertyType(
|
||||
PropertyEditors.DateAlias,
|
||||
DataTypeDatabaseType
|
||||
.Date)
|
||||
{
|
||||
Alias =
|
||||
LastLockoutDate,
|
||||
Name =
|
||||
LastLockoutDateLabel
|
||||
}
|
||||
},
|
||||
{
|
||||
LastLoginDate,
|
||||
new PropertyType(
|
||||
PropertyEditors.DateAlias,
|
||||
DataTypeDatabaseType
|
||||
.Date)
|
||||
{
|
||||
Alias =
|
||||
LastLoginDate,
|
||||
Name =
|
||||
LastLoginDateLabel
|
||||
}
|
||||
},
|
||||
{
|
||||
LastPasswordChangeDate,
|
||||
new PropertyType(
|
||||
PropertyEditors.DateAlias,
|
||||
DataTypeDatabaseType
|
||||
.Date)
|
||||
{
|
||||
Alias =
|
||||
LastPasswordChangeDate,
|
||||
Name =
|
||||
LastPasswordChangeDateLabel
|
||||
}
|
||||
},
|
||||
{
|
||||
PasswordAnswer,
|
||||
new PropertyType(
|
||||
PropertyEditors
|
||||
.TextboxAlias,
|
||||
DataTypeDatabaseType
|
||||
.Nvarchar)
|
||||
{
|
||||
Alias =
|
||||
PasswordAnswer,
|
||||
Name =
|
||||
PasswordAnswerLabel
|
||||
}
|
||||
},
|
||||
{
|
||||
PasswordQuestion,
|
||||
new PropertyType(
|
||||
PropertyEditors
|
||||
.TextboxAlias,
|
||||
DataTypeDatabaseType
|
||||
.Nvarchar)
|
||||
{
|
||||
Alias =
|
||||
PasswordQuestion,
|
||||
Name =
|
||||
PasswordQuestionLabel
|
||||
}
|
||||
}
|
||||
};
|
||||
/// <summary>
|
||||
/// Group name to put the membership properties on
|
||||
/// </summary>
|
||||
internal const string StandardPropertiesGroupName = "Membership";
|
||||
|
||||
internal static Dictionary<string, PropertyType> GetStandardPropertyTypeStubs()
|
||||
{
|
||||
return new Dictionary<string, PropertyType>
|
||||
{
|
||||
{
|
||||
Comments,
|
||||
new PropertyType(PropertyEditors.TextboxMultipleAlias, DataTypeDatabaseType.Ntext, true)
|
||||
{
|
||||
Alias = Comments,
|
||||
Name = CommentsLabel
|
||||
}
|
||||
},
|
||||
{
|
||||
FailedPasswordAttempts,
|
||||
new PropertyType(PropertyEditors.NoEditAlias, DataTypeDatabaseType.Integer, true)
|
||||
{
|
||||
Alias = FailedPasswordAttempts,
|
||||
Name = FailedPasswordAttemptsLabel
|
||||
}
|
||||
},
|
||||
{
|
||||
IsApproved,
|
||||
new PropertyType(PropertyEditors.TrueFalseAlias, DataTypeDatabaseType.Integer, true)
|
||||
{
|
||||
Alias = IsApproved,
|
||||
Name = IsApprovedLabel
|
||||
}
|
||||
},
|
||||
{
|
||||
IsLockedOut,
|
||||
new PropertyType(PropertyEditors.TrueFalseAlias, DataTypeDatabaseType.Integer, true)
|
||||
{
|
||||
Alias = IsLockedOut,
|
||||
Name = IsLockedOutLabel
|
||||
}
|
||||
},
|
||||
{
|
||||
LastLockoutDate,
|
||||
new PropertyType(PropertyEditors.NoEditAlias, DataTypeDatabaseType.Date, true)
|
||||
{
|
||||
Alias = LastLockoutDate,
|
||||
Name = LastLockoutDateLabel
|
||||
}
|
||||
},
|
||||
{
|
||||
LastLoginDate,
|
||||
new PropertyType(PropertyEditors.NoEditAlias, DataTypeDatabaseType.Date, true)
|
||||
{
|
||||
Alias = LastLoginDate,
|
||||
Name = LastLoginDateLabel
|
||||
}
|
||||
},
|
||||
{
|
||||
LastPasswordChangeDate,
|
||||
new PropertyType(PropertyEditors.NoEditAlias, DataTypeDatabaseType.Date, true)
|
||||
{
|
||||
Alias = LastPasswordChangeDate,
|
||||
Name = LastPasswordChangeDateLabel
|
||||
}
|
||||
},
|
||||
{
|
||||
PasswordAnswer,
|
||||
new PropertyType(PropertyEditors.NoEditAlias, DataTypeDatabaseType.Nvarchar, true)
|
||||
{
|
||||
Alias = PasswordAnswer,
|
||||
Name = PasswordAnswerLabel
|
||||
}
|
||||
},
|
||||
{
|
||||
PasswordQuestion,
|
||||
new PropertyType(PropertyEditors.NoEditAlias, DataTypeDatabaseType.Nvarchar, true)
|
||||
{
|
||||
Alias = PasswordQuestion,
|
||||
Name = PasswordQuestionLabel
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -306,7 +273,9 @@ namespace Umbraco.Core
|
||||
/// <summary>
|
||||
/// MemberType alias for default member type.
|
||||
/// </summary>
|
||||
public const string Member = "Member";
|
||||
public const string DefaultAlias = "Member";
|
||||
|
||||
public const string SystemDefaultProtectType = "_umbracoSystemDefaultProtectType";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -139,7 +139,7 @@ namespace Umbraco.Core
|
||||
///// <summary>
|
||||
///// Alias for the Image Cropper datatype.
|
||||
///// </summary>
|
||||
//public const string ImageCropperAlias = "Umbraco.ImageCropper";
|
||||
public const string ImageCropperAlias = "Umbraco.ImageCropper";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Integer datatype.
|
||||
|
||||
@@ -23,22 +23,5 @@
|
||||
public const int RecycleBinMedia = -21;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the identifiers for Umbraco system nodes.
|
||||
/// </summary>
|
||||
public static class Web
|
||||
{
|
||||
/// <summary>
|
||||
/// The preview cookie name
|
||||
/// </summary>
|
||||
public const string PreviewCookieName = "UMB_PREVIEW";
|
||||
|
||||
/// <summary>
|
||||
/// The auth cookie name
|
||||
/// </summary>
|
||||
public const string AuthCookieName = "UMB_UCONTEXT";
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
public static partial class Constants
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the identifiers for Umbraco system nodes.
|
||||
/// </summary>
|
||||
public static class Web
|
||||
{
|
||||
/// <summary>
|
||||
/// The preview cookie name
|
||||
/// </summary>
|
||||
public const string PreviewCookieName = "UMB_PREVIEW";
|
||||
|
||||
/// <summary>
|
||||
/// The auth cookie name
|
||||
/// </summary>
|
||||
public const string AuthCookieName = "UMB_UCONTEXT";
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Web.UI;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
internal static class ControlExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Recursively finds a control with the specified identifier.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">
|
||||
/// The type of control to be found.
|
||||
/// </typeparam>
|
||||
/// <param name="parent">
|
||||
/// The parent control from which the search will start.
|
||||
/// </param>
|
||||
/// <param name="id">
|
||||
/// The identifier of the control to be found.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The control with the specified identifier, otherwise <see langword="null"/> if the control
|
||||
/// is not found.
|
||||
/// </returns>
|
||||
public static T FindControlRecursive<T>(this Control parent, string id) where T : Control
|
||||
{
|
||||
if ((parent is T) && (parent.ID == id))
|
||||
{
|
||||
return (T)parent;
|
||||
}
|
||||
|
||||
foreach (Control control in parent.Controls)
|
||||
{
|
||||
var foundControl = FindControlRecursive<T>(control, id);
|
||||
if (foundControl != null)
|
||||
{
|
||||
return foundControl;
|
||||
}
|
||||
}
|
||||
return default(T);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -287,7 +287,7 @@ namespace Umbraco.Core
|
||||
() => PluginManager.Current.ResolveAssignedMapperTypes());
|
||||
|
||||
RepositoryResolver.Current = new RepositoryResolver(
|
||||
new RepositoryFactory());
|
||||
new RepositoryFactory(ApplicationCache));
|
||||
|
||||
SqlSyntaxProvidersResolver.Current = new SqlSyntaxProvidersResolver(
|
||||
new[] { typeof(MySqlSyntaxProvider), typeof(SqlCeSyntaxProvider), typeof(SqlServerSyntaxProvider) })
|
||||
@@ -324,17 +324,10 @@ namespace Umbraco.Core
|
||||
// fixme - why not use the following syntax?
|
||||
//PluginManager.Current.ResolveTypes<IPropertyValueConverter>());
|
||||
|
||||
// use the new DefaultShortStringHelper but sort-of remain compatible
|
||||
// - use UmbracoSettings UrlReplaceCharacters
|
||||
// - allow underscores in terms, allow leading digits
|
||||
// use the new DefaultShortStringHelper
|
||||
ShortStringHelperResolver.Current = new ShortStringHelperResolver(
|
||||
new DefaultShortStringHelper()
|
||||
.WithConfig(CleanStringType.Url, DefaultShortStringHelper.ApplyUrlReplaceCharacters,
|
||||
allowUnderscoreInTerm: true, allowLeadingDigits: true));
|
||||
|
||||
// that was the old one
|
||||
//ShortStringHelperResolver.Current = new ShortStringHelperResolver(
|
||||
// new LegacyShortStringHelper());
|
||||
//new LegacyShortStringHelper());
|
||||
new DefaultShortStringHelper().WithDefaultConfig());
|
||||
|
||||
UrlSegmentProviderResolver.Current = new UrlSegmentProviderResolver(
|
||||
typeof (DefaultUrlSegmentProvider));
|
||||
|
||||
@@ -113,8 +113,8 @@ namespace Umbraco.Core
|
||||
public void ConfigureEmbeddedDatabaseConnection()
|
||||
{
|
||||
const string providerName = "System.Data.SqlServerCe.4.0";
|
||||
const string connectionString = @"Data Source=|DataDirectory|\Umbraco.sdf;Flush Interval=1;";
|
||||
|
||||
var connectionString = GetEmbeddedDatabaseConnectionString();
|
||||
SaveConnectionString(connectionString, providerName);
|
||||
|
||||
var path = Path.Combine(GlobalSettings.FullpathToRoot, "App_Data", "Umbraco.sdf");
|
||||
@@ -122,11 +122,23 @@ namespace Umbraco.Core
|
||||
{
|
||||
var engine = new SqlCeEngine(connectionString);
|
||||
engine.CreateDatabase();
|
||||
|
||||
// SD: Pretty sure this should be in a using clause but i don't want to cause unknown side-effects here
|
||||
// since it's been like this for quite some time
|
||||
//using (var engine = new SqlCeEngine(connectionString))
|
||||
//{
|
||||
// engine.CreateDatabase();
|
||||
//}
|
||||
}
|
||||
|
||||
Initialize(providerName);
|
||||
}
|
||||
|
||||
public string GetEmbeddedDatabaseConnectionString()
|
||||
{
|
||||
return @"Data Source=|DataDirectory|\Umbraco.sdf;Flush Interval=1;";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configure a ConnectionString that has been entered manually.
|
||||
/// </summary>
|
||||
@@ -149,27 +161,29 @@ namespace Umbraco.Core
|
||||
/// <param name="password">Database Password</param>
|
||||
/// <param name="databaseProvider">Type of the provider to be used (Sql, Sql Azure, Sql Ce, MySql)</param>
|
||||
public void ConfigureDatabaseConnection(string server, string databaseName, string user, string password, string databaseProvider)
|
||||
{
|
||||
string connectionString;
|
||||
string providerName = "System.Data.SqlClient";
|
||||
if (databaseProvider.ToLower().Contains("mysql"))
|
||||
{
|
||||
providerName = "MySql.Data.MySqlClient";
|
||||
connectionString = string.Format("Server={0}; Database={1};Uid={2};Pwd={3}", server, databaseName, user, password);
|
||||
}
|
||||
else if (databaseProvider.ToLower().Contains("azure"))
|
||||
{
|
||||
connectionString = BuildAzureConnectionString(server, databaseName, user, password);
|
||||
}
|
||||
else
|
||||
{
|
||||
connectionString = string.Format("server={0};database={1};user id={2};password={3}", server, databaseName, user, password);
|
||||
}
|
||||
{
|
||||
string providerName;
|
||||
var connectionString = GetDatabaseConnectionString(server, databaseName, user, password, databaseProvider, out providerName);
|
||||
|
||||
SaveConnectionString(connectionString, providerName);
|
||||
Initialize(providerName);
|
||||
}
|
||||
|
||||
public string GetDatabaseConnectionString(string server, string databaseName, string user, string password, string databaseProvider, out string providerName)
|
||||
{
|
||||
providerName = "System.Data.SqlClient";
|
||||
if (databaseProvider.ToLower().Contains("mysql"))
|
||||
{
|
||||
providerName = "MySql.Data.MySqlClient";
|
||||
return string.Format("Server={0}; Database={1};Uid={2};Pwd={3}", server, databaseName, user, password);
|
||||
}
|
||||
if (databaseProvider.ToLower().Contains("azure"))
|
||||
{
|
||||
return BuildAzureConnectionString(server, databaseName, user, password);
|
||||
}
|
||||
return string.Format("server={0};database={1};user id={2};password={3}", server, databaseName, user, password);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configures a ConnectionString for the Umbraco database that uses Microsoft SQL Server integrated security.
|
||||
/// </summary>
|
||||
@@ -178,12 +192,16 @@ namespace Umbraco.Core
|
||||
public void ConfigureIntegratedSecurityDatabaseConnection(string server, string databaseName)
|
||||
{
|
||||
const string providerName = "System.Data.SqlClient";
|
||||
string connectionString = String.Format("Server={0};Database={1};Integrated Security=true", server, databaseName);
|
||||
|
||||
var connectionString = GetIntegratedSecurityDatabaseConnectionString(server, databaseName);
|
||||
SaveConnectionString(connectionString, providerName);
|
||||
Initialize(providerName);
|
||||
}
|
||||
|
||||
public string GetIntegratedSecurityDatabaseConnectionString(string server, string databaseName)
|
||||
{
|
||||
return String.Format("Server={0};Database={1};Integrated Security=true", server, databaseName);
|
||||
}
|
||||
|
||||
internal string BuildAzureConnectionString(string server, string databaseName, string user, string password)
|
||||
{
|
||||
if (server.Contains(".") && ServerStartsWithTcp(server) == false)
|
||||
@@ -597,5 +615,34 @@ namespace Umbraco.Core
|
||||
public bool Success { get; set; }
|
||||
public string Percentage { get; set; }
|
||||
}
|
||||
|
||||
internal bool IsConnectionStringConfigured(ConnectionStringSettings databaseSettings)
|
||||
{
|
||||
var dbIsSqlCe = false;
|
||||
if (databaseSettings != null && databaseSettings.ProviderName != null)
|
||||
dbIsSqlCe = databaseSettings.ProviderName == "System.Data.SqlServerCe.4.0";
|
||||
var sqlCeDatabaseExists = false;
|
||||
if (dbIsSqlCe)
|
||||
{
|
||||
var parts = databaseSettings.ConnectionString.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
var dataSourcePart = parts.FirstOrDefault(x => x.InvariantStartsWith("Data Source="));
|
||||
if (dataSourcePart != null)
|
||||
{
|
||||
var datasource = dataSourcePart.Replace("|DataDirectory|", AppDomain.CurrentDomain.GetData("DataDirectory").ToString());
|
||||
var filePath = datasource.Replace("Data Source=", string.Empty);
|
||||
sqlCeDatabaseExists = File.Exists(filePath);
|
||||
}
|
||||
}
|
||||
|
||||
// Either the connection details are not fully specified or it's a SQL CE database that doesn't exist yet
|
||||
if (databaseSettings == null
|
||||
|| string.IsNullOrWhiteSpace(databaseSettings.ConnectionString) || string.IsNullOrWhiteSpace(databaseSettings.ProviderName)
|
||||
|| (dbIsSqlCe && sqlCeDatabaseExists == false))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,5 +18,30 @@ namespace Umbraco.Core
|
||||
return dt.ToString("yyyy-MM-dd HH:mm:ss");
|
||||
}
|
||||
|
||||
public static DateTime TruncateTo(this DateTime dt, DateTruncate truncateTo)
|
||||
{
|
||||
if (truncateTo == DateTruncate.Year)
|
||||
return new DateTime(dt.Year, 0, 0);
|
||||
if (truncateTo == DateTruncate.Month)
|
||||
return new DateTime(dt.Year, dt.Month, 0);
|
||||
if (truncateTo == DateTruncate.Day)
|
||||
return new DateTime(dt.Year, dt.Month, dt.Day);
|
||||
if (truncateTo == DateTruncate.Hour)
|
||||
return new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, 0, 0);
|
||||
if (truncateTo == DateTruncate.Minute)
|
||||
return new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, 0);
|
||||
return new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, dt.Second);
|
||||
}
|
||||
|
||||
public enum DateTruncate
|
||||
{
|
||||
Year,
|
||||
Month,
|
||||
Day,
|
||||
Hour,
|
||||
Minute,
|
||||
Second
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,25 @@ namespace Umbraco.Core
|
||||
///</summary>
|
||||
internal static class DictionaryExtensions
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Method to Get a value by the key. If the key doesn't exist it will create a new TVal object for the key and return it.
|
||||
/// </summary>
|
||||
/// <typeparam name="TKey"></typeparam>
|
||||
/// <typeparam name="TVal"></typeparam>
|
||||
/// <param name="dict"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public static TVal GetOrCreate<TKey, TVal>(this IDictionary<TKey, TVal> dict, TKey key)
|
||||
where TVal : class, new()
|
||||
{
|
||||
if (dict.ContainsKey(key) == false)
|
||||
{
|
||||
dict.Add(key, new TVal());
|
||||
}
|
||||
return dict[key];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates an item with the specified key with the specified value
|
||||
/// </summary>
|
||||
@@ -231,7 +250,7 @@ namespace Umbraco.Core
|
||||
/// <returns>The contains key ignore case.</returns>
|
||||
public static bool ContainsKeyIgnoreCase<TValue>(this IDictionary<string, TValue> dictionary, string key)
|
||||
{
|
||||
return dictionary.Keys.Any(i => i.Equals(key, StringComparison.CurrentCultureIgnoreCase));
|
||||
return dictionary.Keys.InvariantContains(key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -257,9 +276,9 @@ namespace Umbraco.Core
|
||||
/// <param name="key">The key.</param>
|
||||
/// <typeparam name="TValue">The type</typeparam>
|
||||
/// <returns>The entry</returns>
|
||||
public static TValue GetEntryIgnoreCase<TValue>(this IDictionary<string, TValue> dictionary, string key)
|
||||
public static TValue GetValueIgnoreCase<TValue>(this IDictionary<string, TValue> dictionary, string key)
|
||||
{
|
||||
return dictionary.GetEntryIgnoreCase(key, default(TValue));
|
||||
return dictionary.GetValueIgnoreCase(key, default(TValue));
|
||||
}
|
||||
|
||||
/// <summary>The get entry ignore case.</summary>
|
||||
@@ -268,11 +287,11 @@ namespace Umbraco.Core
|
||||
/// <param name="defaultValue">The default value.</param>
|
||||
/// <typeparam name="TValue">The type</typeparam>
|
||||
/// <returns>The entry</returns>
|
||||
public static TValue GetEntryIgnoreCase<TValue>(this IDictionary<string, TValue> dictionary, string key, TValue defaultValue)
|
||||
public static TValue GetValueIgnoreCase<TValue>(this IDictionary<string, TValue> dictionary, string key, TValue defaultValue)
|
||||
{
|
||||
key = dictionary.Keys.Where(i => i.Equals(key, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();
|
||||
key = dictionary.Keys.FirstOrDefault(i => i.InvariantEquals(key));
|
||||
|
||||
return !key.IsNullOrWhiteSpace()
|
||||
return key.IsNullOrWhiteSpace() == false
|
||||
? dictionary[key]
|
||||
: defaultValue;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Umbraco.Core.Events
|
||||
{
|
||||
public class ExportEventArgs<TEntity> : CancellableObjectEventArgs<IEnumerable<TEntity>>
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor accepting a single entity instance
|
||||
/// </summary>
|
||||
/// <param name="eventObject"></param>
|
||||
/// <param name="xml"></param>
|
||||
/// <param name="canCancel"></param>
|
||||
public ExportEventArgs(TEntity eventObject, XElement xml, bool canCancel)
|
||||
: base(new List<TEntity> { eventObject }, canCancel)
|
||||
{
|
||||
Xml = xml;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor accepting a single entity instance
|
||||
/// and cancellable by default
|
||||
/// </summary>
|
||||
/// <param name="eventObject"></param>
|
||||
/// <param name="elementName"></param>
|
||||
public ExportEventArgs(TEntity eventObject, string elementName) : base(new List<TEntity> {eventObject}, true)
|
||||
{
|
||||
Xml = new XElement(elementName);
|
||||
}
|
||||
|
||||
protected ExportEventArgs(IEnumerable<TEntity> eventObject, bool canCancel) : base(eventObject, canCancel)
|
||||
{
|
||||
}
|
||||
|
||||
protected ExportEventArgs(IEnumerable<TEntity> eventObject) : base(eventObject)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all entities that were exported during the operation
|
||||
/// </summary>
|
||||
public IEnumerable<TEntity> ExportedEntities
|
||||
{
|
||||
get { return EventObject; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the xml relating to the export event
|
||||
/// </summary>
|
||||
public XElement Xml { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Umbraco.Core.Events
|
||||
{
|
||||
public class ImportEventArgs<TEntity> : CancellableObjectEventArgs<IEnumerable<TEntity>>
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor accepting an XElement with the xml being imported
|
||||
/// </summary>
|
||||
/// <param name="xml"></param>
|
||||
public ImportEventArgs(XElement xml) : base(new List<TEntity>(), true)
|
||||
{
|
||||
Xml = xml;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor accepting a list of entities and an XElement with the imported xml
|
||||
/// </summary>
|
||||
/// <param name="eventObject"></param>
|
||||
/// <param name="xml"></param>
|
||||
/// <param name="canCancel"></param>
|
||||
public ImportEventArgs(IEnumerable<TEntity> eventObject, XElement xml, bool canCancel)
|
||||
: base(eventObject, canCancel)
|
||||
{
|
||||
Xml = xml;
|
||||
}
|
||||
|
||||
protected ImportEventArgs(IEnumerable<TEntity> eventObject, bool canCancel) : base(eventObject, canCancel)
|
||||
{
|
||||
}
|
||||
|
||||
protected ImportEventArgs(IEnumerable<TEntity> eventObject) : base(eventObject)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all entities that were imported during the operation
|
||||
/// </summary>
|
||||
public IEnumerable<TEntity> ImportedEntities
|
||||
{
|
||||
get { return EventObject; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the xml relating to the import event
|
||||
/// </summary>
|
||||
public XElement Xml { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -49,8 +49,5 @@ namespace Umbraco.Core.Events
|
||||
{
|
||||
get { return EventObject; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.IO;
|
||||
using System;
|
||||
using System.IO;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
|
||||
namespace Umbraco.Core.IO
|
||||
@@ -30,5 +31,17 @@ namespace Umbraco.Core.IO
|
||||
{
|
||||
return Path.GetFileName(fs.GetFullPath(path));
|
||||
}
|
||||
|
||||
//TODO: Currently this is the only way to do this
|
||||
internal static void CreateFolder(this IFileSystem fs, string folderPath)
|
||||
{
|
||||
var path = fs.GetRelativePath(folderPath);
|
||||
var tempFile = Path.Combine(path, Guid.NewGuid().ToString("N") + ".tmp");
|
||||
using (var s = new MemoryStream())
|
||||
{
|
||||
fs.AddFile(tempFile, s);
|
||||
}
|
||||
fs.DeleteFile(tempFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ using Umbraco.Core.CodeAnnotations;
|
||||
|
||||
namespace Umbraco.Core.IO
|
||||
{
|
||||
//TODO: There is no way to create a directory here without creating a file in a directory and then deleting it
|
||||
|
||||
public interface IFileSystem
|
||||
{
|
||||
IEnumerable<string> GetDirectories(string path);
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace Umbraco.Core.IO
|
||||
//Replaces tildes with the root dir
|
||||
public static string ResolveUrl(string virtualPath)
|
||||
{
|
||||
if (virtualPath.StartsWith("~"))
|
||||
if (virtualPath.StartsWith("~"))
|
||||
return virtualPath.Replace("~", SystemDirectories.Root).Replace("//", "/");
|
||||
else if (Uri.IsWellFormedUriString(virtualPath, UriKind.Absolute))
|
||||
return virtualPath;
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Umbraco.Core.Macros
|
||||
internal class MacroTagParser
|
||||
{
|
||||
private static readonly Regex MacroRteContent = new Regex(@"(<!--\s*?)(<\?UMBRACO_MACRO.*?/>)(\s*?-->)", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline);
|
||||
private static readonly Regex MacroPersistedFormat = new Regex(@"(<\?UMBRACO_MACRO macroAlias=[""'](\w+?)[""'].+?)(?:/>|>.*?</\?UMBRACO_MACRO>)", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline);
|
||||
private static readonly Regex MacroPersistedFormat = new Regex(@"(<\?UMBRACO_MACRO macroAlias=[""']([\w\.]+?)[""'].+?)(?:/>|>.*?</\?UMBRACO_MACRO>)", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline);
|
||||
|
||||
/// <summary>
|
||||
/// This formats the persisted string to something useful for the rte so that the macro renders properly since we
|
||||
@@ -39,8 +39,8 @@ namespace Umbraco.Core.Macros
|
||||
//<div class="umb-macro-holder myMacro mceNonEditable">
|
||||
var alias = match.Groups[2].Value;
|
||||
var sb = new StringBuilder("<div class=\"umb-macro-holder ");
|
||||
sb.Append(alias);
|
||||
sb.Append(" mceNonEditable\"");
|
||||
//sb.Append(alias.ToSafeAlias());
|
||||
sb.Append("mceNonEditable\"");
|
||||
foreach (var htmlAttribute in htmlAttributes)
|
||||
{
|
||||
sb.Append(" ");
|
||||
|
||||
@@ -125,8 +125,23 @@ namespace Umbraco.Core.Media
|
||||
{
|
||||
using (var g = Graphics.FromImage(bp))
|
||||
{
|
||||
g.SmoothingMode = SmoothingMode.HighQuality;
|
||||
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||||
//if the image size is rather large we cannot use the best quality interpolation mode
|
||||
// because we'll get out of mem exceptions. So we'll detect how big the image is and use
|
||||
// the mid quality interpolation mode when the image size exceeds our max limit.
|
||||
|
||||
if (image.Width > 5000 || image.Height > 5000)
|
||||
{
|
||||
//use mid quality
|
||||
g.InterpolationMode = InterpolationMode.Bilinear;
|
||||
}
|
||||
else
|
||||
{
|
||||
//use best quality
|
||||
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||||
}
|
||||
|
||||
|
||||
g.SmoothingMode = SmoothingMode.HighQuality;
|
||||
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
||||
g.CompositingQuality = CompositingQuality.HighQuality;
|
||||
|
||||
|
||||
@@ -306,10 +306,8 @@ namespace Umbraco.Core.Models
|
||||
/// <returns><see cref="Property"/> Value as a <see cref="TPassType"/></returns>
|
||||
public virtual TPassType GetValue<TPassType>(string propertyTypeAlias)
|
||||
{
|
||||
if (Properties[propertyTypeAlias].Value is TPassType)
|
||||
return (TPassType)Properties[propertyTypeAlias].Value;
|
||||
|
||||
return (TPassType)Convert.ChangeType(Properties[propertyTypeAlias].Value, typeof(TPassType));
|
||||
var convertAttempt = Properties[propertyTypeAlias].Value.TryConvertTo<TPassType>();
|
||||
return convertAttempt.Success ? convertAttempt.Result : default(TPassType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -26,6 +26,20 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
#region IContent
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if this entity was just published as part of a recent save operation (i.e. it wasn't previously published)
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// This is helpful for determining if the published event will execute during the saved event for a content item.
|
||||
/// </remarks>
|
||||
internal static bool JustPublished(this IContent entity)
|
||||
{
|
||||
var dirty = (IRememberBeingDirty)entity;
|
||||
return dirty.WasPropertyDirty("Published") && entity.Published;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if a new version should be created
|
||||
/// </summary>
|
||||
@@ -618,7 +632,7 @@ namespace Umbraco.Core.Models
|
||||
/// <returns>Xml representation of the passed in <see cref="IContent"/></returns>
|
||||
internal static XElement ToDeepXml(this IContent content)
|
||||
{
|
||||
return ApplicationContext.Current.Services.PackagingService.Export(content, true);
|
||||
return ApplicationContext.Current.Services.PackagingService.Export(content, true, raiseEvents: false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -628,7 +642,7 @@ namespace Umbraco.Core.Models
|
||||
/// <returns>Xml representation of the passed in <see cref="IContent"/></returns>
|
||||
public static XElement ToXml(this IContent content)
|
||||
{
|
||||
return ApplicationContext.Current.Services.PackagingService.Export(content);
|
||||
return ApplicationContext.Current.Services.PackagingService.Export(content, raiseEvents: false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -638,24 +652,19 @@ namespace Umbraco.Core.Models
|
||||
/// <returns>Xml representation of the passed in <see cref="IContent"/></returns>
|
||||
public static XElement ToXml(this IMedia media)
|
||||
{
|
||||
return ApplicationContext.Current.Services.PackagingService.Export(media);
|
||||
}
|
||||
|
||||
internal static XElement ToDeepXml(this IMedia media)
|
||||
{
|
||||
return ApplicationContext.Current.Services.PackagingService.Export(media, true);
|
||||
return ApplicationContext.Current.Services.PackagingService.Export(media, raiseEvents: false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the xml representation for the <see cref="IMedia"/> object
|
||||
/// Creates the full xml representation for the <see cref="IMedia"/> object and all of it's descendants
|
||||
/// </summary>
|
||||
/// <param name="member"><see cref="IContent"/> to generate xml for</param>
|
||||
/// <returns>Xml representation of the passed in <see cref="IContent"/></returns>
|
||||
public static XElement ToXml(this IMember member)
|
||||
/// <param name="media"><see cref="IMedia"/> to generate xml for</param>
|
||||
/// <returns>Xml representation of the passed in <see cref="IMedia"/></returns>
|
||||
internal static XElement ToDeepXml(this IMedia media)
|
||||
{
|
||||
return ApplicationContext.Current.Services.PackagingService.Export(member);
|
||||
return ApplicationContext.Current.Services.PackagingService.Export(media, true, raiseEvents: false);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Creates the xml representation for the <see cref="IContent"/> object
|
||||
/// </summary>
|
||||
@@ -668,6 +677,16 @@ namespace Umbraco.Core.Models
|
||||
//If current IContent is published we should get latest unpublished version
|
||||
return content.ToXml();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the xml representation for the <see cref="IMember"/> object
|
||||
/// </summary>
|
||||
/// <param name="member"><see cref="IMember"/> to generate xml for</param>
|
||||
/// <returns>Xml representation of the passed in <see cref="IContent"/></returns>
|
||||
public static XElement ToXml(this IMember member)
|
||||
{
|
||||
return ((PackagingService)(ApplicationContext.Current.Services.PackagingService)).Export(member);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ namespace Umbraco.Core.Models
|
||||
_allowedContentTypes = new List<ContentTypeSort>();
|
||||
_propertyGroups = new PropertyGroupCollection();
|
||||
_propertyTypes = new PropertyTypeCollection();
|
||||
_propertyTypes.CollectionChanged += PropertyTypesChanged;
|
||||
_additionalData = new Dictionary<string, object>();
|
||||
}
|
||||
|
||||
@@ -54,6 +55,7 @@ namespace Umbraco.Core.Models
|
||||
_allowedContentTypes = new List<ContentTypeSort>();
|
||||
_propertyGroups = new PropertyGroupCollection();
|
||||
_propertyTypes = new PropertyTypeCollection();
|
||||
_propertyTypes.CollectionChanged += PropertyTypesChanged;
|
||||
_additionalData = new Dictionary<string, object>();
|
||||
}
|
||||
|
||||
@@ -433,8 +435,7 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
if (PropertyTypeExists(propertyType.Alias) == false)
|
||||
{
|
||||
_propertyTypes.Add(propertyType);
|
||||
_propertyTypes.CollectionChanged += PropertyTypesChanged;
|
||||
_propertyTypes.Add(propertyType);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
public static class EntityExtensions
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if this entity has just been created and persisted to the data store
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// This is useful when handling events to determine if an entity is a brand new entity or was
|
||||
/// already existing.
|
||||
/// </remarks>
|
||||
public static bool IsNewEntity(this IEntity entity)
|
||||
{
|
||||
var dirty = (IRememberBeingDirty)entity;
|
||||
return dirty.WasPropertyDirty("Id");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,16 @@ using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
internal sealed class Folder : Entity
|
||||
{
|
||||
public Folder(string folderPath)
|
||||
{
|
||||
Path = folderPath;
|
||||
}
|
||||
|
||||
public string Path { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents an abstract file which provides basic functionality for a File with an Alias and Name
|
||||
/// </summary>
|
||||
@@ -23,6 +33,8 @@ namespace Umbraco.Core.Models
|
||||
|
||||
private static readonly PropertyInfo ContentSelector = ExpressionHelper.GetPropertyInfo<File, string>(x => x.Content);
|
||||
private static readonly PropertyInfo PathSelector = ExpressionHelper.GetPropertyInfo<File, string>(x => x.Path);
|
||||
private string _alias;
|
||||
private string _name;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Name of the File including extension
|
||||
@@ -32,7 +44,11 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
get
|
||||
{
|
||||
return new FileInfo(Path).Name;
|
||||
if (_name == null)
|
||||
{
|
||||
_name = System.IO.Path.GetFileName(Path);
|
||||
}
|
||||
return _name;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,10 +60,14 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
get
|
||||
{
|
||||
var fileInfo = new FileInfo(Path);
|
||||
var name = fileInfo.Name;
|
||||
int lastIndexOf = name.LastIndexOf(".", StringComparison.InvariantCultureIgnoreCase);
|
||||
return name.Substring(0, lastIndexOf);
|
||||
if (_alias == null)
|
||||
{
|
||||
var name = System.IO.Path.GetFileName(Path);
|
||||
if (name == null) return string.Empty;
|
||||
var lastIndexOf = name.LastIndexOf(".", StringComparison.InvariantCultureIgnoreCase);
|
||||
_alias = name.Substring(0, lastIndexOf);
|
||||
}
|
||||
return _alias;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,6 +80,10 @@ namespace Umbraco.Core.Models
|
||||
get { return _path; }
|
||||
set
|
||||
{
|
||||
//reset
|
||||
_alias = null;
|
||||
_name = null;
|
||||
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_path = value;
|
||||
|
||||
@@ -1,106 +1,10 @@
|
||||
using System;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
public interface IMember : IContentBase
|
||||
public interface IMember : IContentBase, IMembershipUser
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the Username
|
||||
/// </summary>
|
||||
string Username { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Email
|
||||
/// </summary>
|
||||
string Email { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Password
|
||||
/// </summary>
|
||||
string Password { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Password Question
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Alias: umbracoPasswordRetrievalQuestionPropertyTypeAlias
|
||||
/// Part of the standard properties collection.
|
||||
/// </remarks>
|
||||
string PasswordQuestion { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Password Answer
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Alias: umbracoPasswordRetrievalAnswerPropertyTypeAlias
|
||||
/// Part of the standard properties collection.
|
||||
/// </remarks>
|
||||
string PasswordAnswer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or set the comments for the member
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Alias: umbracoCommentPropertyTypeAlias
|
||||
/// Part of the standard properties collection.
|
||||
/// </remarks>
|
||||
string Comments { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a boolean indicating whether the Member is approved
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Alias: umbracoApprovePropertyTypeAlias
|
||||
/// Part of the standard properties collection.
|
||||
/// </remarks>
|
||||
bool IsApproved { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a boolean indicating whether the Member is locked out
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Alias: umbracoLockPropertyTypeAlias
|
||||
/// Part of the standard properties collection.
|
||||
/// </remarks>
|
||||
bool IsLockedOut { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the date for last login
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Alias: umbracoLastLoginPropertyTypeAlias
|
||||
/// Part of the standard properties collection.
|
||||
/// </remarks>
|
||||
DateTime LastLoginDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gest or sets the date for last password change
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Alias: umbracoMemberLastPasswordChange
|
||||
/// Part of the standard properties collection.
|
||||
/// </remarks>
|
||||
DateTime LastPasswordChangeDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the date for when Member was locked out
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Alias: umbracoMemberLastLockout
|
||||
/// Part of the standard properties collection.
|
||||
/// </remarks>
|
||||
DateTime LastLockoutDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the number of failed password attempts.
|
||||
/// This is the number of times the password was entered incorrectly upon login.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Alias: umbracoFailedPasswordAttemptsPropertyTypeAlias
|
||||
/// Part of the standard properties collection.
|
||||
/// </remarks>
|
||||
int FailedPasswordAttempts { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// String alias of the default ContentType
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a member type
|
||||
/// </summary>
|
||||
public interface IMemberGroup : IAggregateRoot
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of the member group
|
||||
/// </summary>
|
||||
string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Profile of the user who created this Entity
|
||||
/// </summary>
|
||||
int CreatorId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Some entities may expose additional data that other's might not, this custom data will be available in this collection
|
||||
/// </summary>
|
||||
IDictionary<string, object> AdditionalData { get; }
|
||||
}
|
||||
}
|
||||
@@ -10,5 +10,11 @@
|
||||
/// </summary>
|
||||
/// <returns><see cref="RenderingEngine"/></returns>
|
||||
RenderingEngine GetTypeOfRenderingEngine();
|
||||
|
||||
/// <summary>
|
||||
/// Set the mastertemplate
|
||||
/// </summary>
|
||||
/// <param name="masterTemplate"></param>
|
||||
void SetMasterTemplate(ITemplate masterTemplate);
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,6 @@ using System.Globalization;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
|
||||
@@ -107,7 +107,7 @@ namespace Umbraco.Core.Models
|
||||
private bool _dontRender;
|
||||
private string _scriptFile;
|
||||
private string _scriptAssembly;
|
||||
private string _python;
|
||||
private string _scriptPath;
|
||||
private string _xslt;
|
||||
private readonly MacroPropertyCollection _properties;
|
||||
private readonly List<string> _addedProperties;
|
||||
@@ -360,14 +360,14 @@ namespace Umbraco.Core.Models
|
||||
[DataMember]
|
||||
public string ScriptPath
|
||||
{
|
||||
get { return _python; }
|
||||
get { return _scriptPath; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_python = value;
|
||||
return _python;
|
||||
}, _python, ScriptPathSelector);
|
||||
_scriptPath = value;
|
||||
return _scriptPath;
|
||||
}, _scriptPath, ScriptPathSelector);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -155,7 +155,6 @@ namespace Umbraco.Core.Models
|
||||
/// </remarks>
|
||||
[DataMember]
|
||||
public string EditorAlias
|
||||
|
||||
{
|
||||
get { return _editorAlias; }
|
||||
set
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Umbraco.Core.Models.Mapping
|
||||
/// All automapper configurations are done during startup
|
||||
/// inside an Automapper Initialize call which is better for performance
|
||||
/// </remarks>
|
||||
internal interface IMapperConfiguration : IApplicationEventHandler
|
||||
public interface IMapperConfiguration : IApplicationEventHandler
|
||||
{
|
||||
void ConfigureMappings(IConfiguration config, ApplicationContext applicationContext);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace Umbraco.Core.Models.Mapping
|
||||
/// <remarks>
|
||||
/// Use this class if your mapper configuration isn't also explicitly an ApplicationEventHandler.
|
||||
/// </remarks>
|
||||
internal abstract class MapperConfiguration : ApplicationEventHandler, IMapperConfiguration
|
||||
public abstract class MapperConfiguration : ApplicationEventHandler, IMapperConfiguration
|
||||
{
|
||||
public abstract void ConfigureMappings(IConfiguration config, ApplicationContext applicationContext);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Logging;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
@@ -29,9 +31,11 @@ namespace Umbraco.Core.Models
|
||||
: base(name, -1, contentType, new PropertyCollection())
|
||||
{
|
||||
_contentType = contentType;
|
||||
IsApproved = true;
|
||||
}
|
||||
|
||||
public Member(string name, string email, string username, string password, int parentId, IMemberType contentType)
|
||||
//TODO: Should we just get rid of this one? no reason to have a level set.
|
||||
internal Member(string name, string email, string username, string password, int parentId, IMemberType contentType)
|
||||
: base(name, parentId, contentType, new PropertyCollection())
|
||||
{
|
||||
Mandate.ParameterNotNull(contentType, "contentType");
|
||||
@@ -40,10 +44,11 @@ namespace Umbraco.Core.Models
|
||||
_email = email;
|
||||
_username = username;
|
||||
_password = password;
|
||||
IsApproved = true;
|
||||
}
|
||||
|
||||
public Member(string name, string email, string username, string password, IContentBase parent, IMemberType contentType)
|
||||
: base(name, parent, contentType, new PropertyCollection())
|
||||
public Member(string name, string email, string username, string password, IMemberType contentType)
|
||||
: this(name, email, username, password, -1, contentType)
|
||||
{
|
||||
Mandate.ParameterNotNull(contentType, "contentType");
|
||||
|
||||
@@ -51,8 +56,20 @@ namespace Umbraco.Core.Models
|
||||
_email = email;
|
||||
_username = username;
|
||||
_password = password;
|
||||
IsApproved = true;
|
||||
}
|
||||
|
||||
//public Member(string name, string email, string username, string password, IContentBase parent, IMemberType contentType)
|
||||
// : base(name, parent, contentType, new PropertyCollection())
|
||||
//{
|
||||
// Mandate.ParameterNotNull(contentType, "contentType");
|
||||
|
||||
// _contentType = contentType;
|
||||
// _email = email;
|
||||
// _username = username;
|
||||
// _password = password;
|
||||
//}
|
||||
|
||||
private static readonly PropertyInfo DefaultContentTypeAliasSelector = ExpressionHelper.GetPropertyInfo<Member, string>(x => x.ContentTypeAlias);
|
||||
private static readonly PropertyInfo UsernameSelector = ExpressionHelper.GetPropertyInfo<Member, string>(x => x.Username);
|
||||
private static readonly PropertyInfo EmailSelector = ExpressionHelper.GetPropertyInfo<Member, string>(x => x.Email);
|
||||
@@ -125,7 +142,7 @@ namespace Umbraco.Core.Models
|
||||
/// Gets or sets the Password Question
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Alias: umbracoPasswordRetrievalQuestionPropertyTypeAlias
|
||||
/// Alias: umbracoMemberPasswordRetrievalQuestion
|
||||
/// Part of the standard properties collection.
|
||||
/// </remarks>
|
||||
[IgnoreDataMember]
|
||||
@@ -133,12 +150,19 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
get
|
||||
{
|
||||
var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.PasswordQuestion, "PasswordQuestion", default(string));
|
||||
if (a.Success == false) return a.Result;
|
||||
|
||||
return Properties[Constants.Conventions.Member.PasswordQuestion].Value == null
|
||||
? string.Empty
|
||||
: Properties[Constants.Conventions.Member.PasswordQuestion].Value.ToString();
|
||||
}
|
||||
set
|
||||
{
|
||||
if (WarnIfPropertyTypeNotFoundOnSet(
|
||||
Constants.Conventions.Member.PasswordQuestion,
|
||||
"PasswordQuestion") == false) return;
|
||||
|
||||
Properties[Constants.Conventions.Member.PasswordQuestion].Value = value;
|
||||
}
|
||||
}
|
||||
@@ -147,7 +171,7 @@ namespace Umbraco.Core.Models
|
||||
/// Gets or sets the Password Answer
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Alias: umbracoPasswordRetrievalAnswerPropertyTypeAlias
|
||||
/// Alias: umbracoMemberPasswordRetrievalAnswer
|
||||
/// Part of the standard properties collection.
|
||||
/// </remarks>
|
||||
[IgnoreDataMember]
|
||||
@@ -155,12 +179,19 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
get
|
||||
{
|
||||
var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.PasswordAnswer, "PasswordAnswer", default(string));
|
||||
if (a.Success == false) return a.Result;
|
||||
|
||||
return Properties[Constants.Conventions.Member.PasswordAnswer].Value == null
|
||||
? string.Empty
|
||||
: Properties[Constants.Conventions.Member.PasswordAnswer].Value.ToString();
|
||||
}
|
||||
set
|
||||
{
|
||||
if (WarnIfPropertyTypeNotFoundOnSet(
|
||||
Constants.Conventions.Member.PasswordAnswer,
|
||||
"PasswordAnswer") == false) return;
|
||||
|
||||
Properties[Constants.Conventions.Member.PasswordAnswer].Value = value;
|
||||
}
|
||||
}
|
||||
@@ -169,7 +200,7 @@ namespace Umbraco.Core.Models
|
||||
/// Gets or set the comments for the member
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Alias: umbracoCommentPropertyTypeAlias
|
||||
/// Alias: umbracoMemberComments
|
||||
/// Part of the standard properties collection.
|
||||
/// </remarks>
|
||||
[IgnoreDataMember]
|
||||
@@ -177,12 +208,19 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
get
|
||||
{
|
||||
var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.Comments, "Comments", default(string));
|
||||
if (a.Success == false) return a.Result;
|
||||
|
||||
return Properties[Constants.Conventions.Member.Comments].Value == null
|
||||
? string.Empty
|
||||
: Properties[Constants.Conventions.Member.Comments].Value.ToString();
|
||||
}
|
||||
set
|
||||
{
|
||||
if (WarnIfPropertyTypeNotFoundOnSet(
|
||||
Constants.Conventions.Member.Comments,
|
||||
"Comments") == false) return;
|
||||
|
||||
Properties[Constants.Conventions.Member.Comments].Value = value;
|
||||
}
|
||||
}
|
||||
@@ -191,7 +229,7 @@ namespace Umbraco.Core.Models
|
||||
/// Gets or sets a boolean indicating whether the Member is approved
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Alias: umbracoApprovePropertyTypeAlias
|
||||
/// Alias: umbracoMemberApproved
|
||||
/// Part of the standard properties collection.
|
||||
/// </remarks>
|
||||
[IgnoreDataMember]
|
||||
@@ -199,17 +237,25 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Properties[Constants.Conventions.Member.IsApproved].Value == null)
|
||||
return default(bool);
|
||||
var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.IsApproved, "IsApproved",
|
||||
//This is the default value if the prop is not found
|
||||
true);
|
||||
if (a.Success == false) return a.Result;
|
||||
|
||||
if (Properties[Constants.Conventions.Member.IsApproved].Value is bool)
|
||||
return (bool)Properties[Constants.Conventions.Member.IsApproved].Value;
|
||||
|
||||
//TODO: Use TryConvertTo<T> instead
|
||||
return (bool)Convert.ChangeType(Properties[Constants.Conventions.Member.IsApproved].Value, typeof(bool));
|
||||
var tryConvert = Properties[Constants.Conventions.Member.IsApproved].Value.TryConvertTo<bool>();
|
||||
if (tryConvert.Success)
|
||||
{
|
||||
return tryConvert.Result;
|
||||
}
|
||||
//if the property exists but it cannot be converted, we will assume true
|
||||
return true;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (WarnIfPropertyTypeNotFoundOnSet(
|
||||
Constants.Conventions.Member.IsApproved,
|
||||
"IsApproved") == false) return;
|
||||
|
||||
Properties[Constants.Conventions.Member.IsApproved].Value = value;
|
||||
}
|
||||
}
|
||||
@@ -218,7 +264,7 @@ namespace Umbraco.Core.Models
|
||||
/// Gets or sets a boolean indicating whether the Member is locked out
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Alias: umbracoLockPropertyTypeAlias
|
||||
/// Alias: umbracoMemberLockedOut
|
||||
/// Part of the standard properties collection.
|
||||
/// </remarks>
|
||||
[IgnoreDataMember]
|
||||
@@ -226,17 +272,23 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Properties[Constants.Conventions.Member.IsLockedOut].Value == null)
|
||||
return default(bool);
|
||||
|
||||
if (Properties[Constants.Conventions.Member.IsLockedOut].Value is bool)
|
||||
return (bool)Properties[Constants.Conventions.Member.IsLockedOut].Value;
|
||||
|
||||
var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.IsLockedOut, "IsLockedOut", false);
|
||||
if (a.Success == false) return a.Result;
|
||||
|
||||
var tryConvert = Properties[Constants.Conventions.Member.IsLockedOut].Value.TryConvertTo<bool>();
|
||||
if (tryConvert.Success)
|
||||
{
|
||||
return tryConvert.Result;
|
||||
}
|
||||
return false;
|
||||
//TODO: Use TryConvertTo<T> instead
|
||||
return (bool)Convert.ChangeType(Properties[Constants.Conventions.Member.IsLockedOut].Value, typeof(bool));
|
||||
}
|
||||
set
|
||||
{
|
||||
if (WarnIfPropertyTypeNotFoundOnSet(
|
||||
Constants.Conventions.Member.IsLockedOut,
|
||||
"IsLockedOut") == false) return;
|
||||
|
||||
Properties[Constants.Conventions.Member.IsLockedOut].Value = value;
|
||||
}
|
||||
}
|
||||
@@ -245,7 +297,7 @@ namespace Umbraco.Core.Models
|
||||
/// Gets or sets the date for last login
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Alias: umbracoLastLoginPropertyTypeAlias
|
||||
/// Alias: umbracoMemberLastLogin
|
||||
/// Part of the standard properties collection.
|
||||
/// </remarks>
|
||||
[IgnoreDataMember]
|
||||
@@ -253,17 +305,23 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Properties[Constants.Conventions.Member.LastLoginDate].Value == null)
|
||||
return default(DateTime);
|
||||
|
||||
if (Properties[Constants.Conventions.Member.LastLoginDate].Value is DateTime)
|
||||
return (DateTime)Properties[Constants.Conventions.Member.LastLoginDate].Value;
|
||||
|
||||
var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.LastLoginDate, "LastLoginDate", default(DateTime));
|
||||
if (a.Success == false) return a.Result;
|
||||
|
||||
var tryConvert = Properties[Constants.Conventions.Member.LastLoginDate].Value.TryConvertTo<DateTime>();
|
||||
if (tryConvert.Success)
|
||||
{
|
||||
return tryConvert.Result;
|
||||
}
|
||||
return default(DateTime);
|
||||
//TODO: Use TryConvertTo<T> instead
|
||||
return (DateTime)Convert.ChangeType(Properties[Constants.Conventions.Member.LastLoginDate].Value, typeof(DateTime));
|
||||
}
|
||||
set
|
||||
{
|
||||
if (WarnIfPropertyTypeNotFoundOnSet(
|
||||
Constants.Conventions.Member.LastLoginDate,
|
||||
"LastLoginDate") == false) return;
|
||||
|
||||
Properties[Constants.Conventions.Member.LastLoginDate].Value = value;
|
||||
}
|
||||
}
|
||||
@@ -272,7 +330,7 @@ namespace Umbraco.Core.Models
|
||||
/// Gest or sets the date for last password change
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Alias: umbracoMemberLastPasswordChange
|
||||
/// Alias: umbracoMemberLastPasswordChangeDate
|
||||
/// Part of the standard properties collection.
|
||||
/// </remarks>
|
||||
[IgnoreDataMember]
|
||||
@@ -280,17 +338,23 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Properties[Constants.Conventions.Member.LastPasswordChangeDate].Value == null)
|
||||
return default(DateTime);
|
||||
|
||||
if (Properties[Constants.Conventions.Member.LastPasswordChangeDate].Value is DateTime)
|
||||
return (DateTime)Properties[Constants.Conventions.Member.LastPasswordChangeDate].Value;
|
||||
var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.LastPasswordChangeDate, "LastPasswordChangeDate", default(DateTime));
|
||||
if (a.Success == false) return a.Result;
|
||||
|
||||
var tryConvert = Properties[Constants.Conventions.Member.LastPasswordChangeDate].Value.TryConvertTo<DateTime>();
|
||||
if (tryConvert.Success)
|
||||
{
|
||||
return tryConvert.Result;
|
||||
}
|
||||
return default(DateTime);
|
||||
//TODO: Use TryConvertTo<T> instead
|
||||
return (DateTime)Convert.ChangeType(Properties[Constants.Conventions.Member.LastPasswordChangeDate].Value, typeof(DateTime));
|
||||
}
|
||||
set
|
||||
{
|
||||
if (WarnIfPropertyTypeNotFoundOnSet(
|
||||
Constants.Conventions.Member.LastPasswordChangeDate,
|
||||
"LastPasswordChangeDate") == false) return;
|
||||
|
||||
Properties[Constants.Conventions.Member.LastPasswordChangeDate].Value = value;
|
||||
}
|
||||
}
|
||||
@@ -299,7 +363,7 @@ namespace Umbraco.Core.Models
|
||||
/// Gets or sets the date for when Member was locked out
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Alias: umbracoMemberLastLockout
|
||||
/// Alias: umbracoMemberLastLockoutDate
|
||||
/// Part of the standard properties collection.
|
||||
/// </remarks>
|
||||
[IgnoreDataMember]
|
||||
@@ -307,17 +371,23 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Properties[Constants.Conventions.Member.LastLockoutDate].Value == null)
|
||||
return default(DateTime);
|
||||
|
||||
if (Properties[Constants.Conventions.Member.LastLockoutDate].Value is DateTime)
|
||||
return (DateTime)Properties[Constants.Conventions.Member.LastLockoutDate].Value;
|
||||
|
||||
var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.LastLockoutDate, "LastLockoutDate", default(DateTime));
|
||||
if (a.Success == false) return a.Result;
|
||||
|
||||
var tryConvert = Properties[Constants.Conventions.Member.LastLockoutDate].Value.TryConvertTo<DateTime>();
|
||||
if (tryConvert.Success)
|
||||
{
|
||||
return tryConvert.Result;
|
||||
}
|
||||
return default(DateTime);
|
||||
//TODO: Use TryConvertTo<T> instead
|
||||
return (DateTime)Convert.ChangeType(Properties[Constants.Conventions.Member.LastLockoutDate].Value, typeof(DateTime));
|
||||
}
|
||||
set
|
||||
{
|
||||
if (WarnIfPropertyTypeNotFoundOnSet(
|
||||
Constants.Conventions.Member.LastLockoutDate,
|
||||
"LastLockoutDate") == false) return;
|
||||
|
||||
Properties[Constants.Conventions.Member.LastLockoutDate].Value = value;
|
||||
}
|
||||
}
|
||||
@@ -327,7 +397,7 @@ namespace Umbraco.Core.Models
|
||||
/// This is the number of times the password was entered incorrectly upon login.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Alias: umbracoFailedPasswordAttemptsPropertyTypeAlias
|
||||
/// Alias: umbracoMemberFailedPasswordAttempts
|
||||
/// Part of the standard properties collection.
|
||||
/// </remarks>
|
||||
[IgnoreDataMember]
|
||||
@@ -335,18 +405,24 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Properties[Constants.Conventions.Member.FailedPasswordAttempts].Value == null)
|
||||
return default(int);
|
||||
|
||||
if (Properties[Constants.Conventions.Member.FailedPasswordAttempts].Value is int)
|
||||
return (int)Properties[Constants.Conventions.Member.FailedPasswordAttempts].Value;
|
||||
|
||||
var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.FailedPasswordAttempts, "FailedPasswordAttempts", 0);
|
||||
if (a.Success == false) return a.Result;
|
||||
|
||||
var tryConvert = Properties[Constants.Conventions.Member.FailedPasswordAttempts].Value.TryConvertTo<int>();
|
||||
if (tryConvert.Success)
|
||||
{
|
||||
return tryConvert.Result;
|
||||
}
|
||||
return default(int);
|
||||
//TODO: Use TryConvertTo<T> instead
|
||||
return (int)Convert.ChangeType(Properties[Constants.Conventions.Member.FailedPasswordAttempts].Value, typeof(int));
|
||||
}
|
||||
set
|
||||
{
|
||||
Properties[Constants.Conventions.Member.LastLockoutDate].Value = value;
|
||||
if (WarnIfPropertyTypeNotFoundOnSet(
|
||||
Constants.Conventions.Member.FailedPasswordAttempts,
|
||||
"FailedPasswordAttempts") == false) return;
|
||||
|
||||
Properties[Constants.Conventions.Member.FailedPasswordAttempts].Value = value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -377,7 +453,7 @@ namespace Umbraco.Core.Models
|
||||
/// membership provider.
|
||||
/// </remarks>
|
||||
[DataMember]
|
||||
internal virtual object ProviderUserKey
|
||||
public virtual object ProviderUserKey
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -460,5 +536,73 @@ namespace Umbraco.Core.Models
|
||||
internal bool BoolPropertyValue { get; set; }
|
||||
internal DateTime DateTimePropertyValue { get; set; }
|
||||
internal string PropertyTypeAlias { get; set; }
|
||||
|
||||
private Attempt<T> WarnIfPropertyTypeNotFoundOnGet<T>(string propertyAlias, string propertyName, T defaultVal)
|
||||
{
|
||||
Action doLog = () => LogHelper.Warn<Member>(
|
||||
"Trying to access the '"
|
||||
+ propertyName
|
||||
+ "' property on "
|
||||
+ typeof(Member)
|
||||
+ " but the "
|
||||
+ propertyAlias
|
||||
+ " property does not exist on the member type so a default value is returned. Ensure that you have a property type with alias: "
|
||||
+ propertyAlias
|
||||
+ " configured on your member type in order to use the '"
|
||||
+ propertyName
|
||||
+ "' property on the model correctly.");
|
||||
|
||||
//if the property doesn't exist, then do the logging and return a failure
|
||||
if (Properties.Contains(propertyAlias) == false)
|
||||
{
|
||||
//we'll put a warn in the log if this entity has been persisted
|
||||
if (HasIdentity)
|
||||
{
|
||||
doLog();
|
||||
}
|
||||
return Attempt<T>.Fail(defaultVal);
|
||||
}
|
||||
|
||||
//if the property doesn't have an identity but we do, then do logging and return failure
|
||||
var prop = Properties.Single(x => x.Alias == propertyAlias);
|
||||
if (prop.HasIdentity == false && HasIdentity)
|
||||
{
|
||||
doLog();
|
||||
return Attempt<T>.Fail(defaultVal);
|
||||
}
|
||||
|
||||
return Attempt<T>.Succeed();
|
||||
}
|
||||
|
||||
private bool WarnIfPropertyTypeNotFoundOnSet(string propertyAlias, string propertyname)
|
||||
{
|
||||
Action doLog = () => LogHelper.Warn<Member>("An attempt was made to set a value on the property '"
|
||||
+ propertyname
|
||||
+ "' on type "
|
||||
+ typeof(Member)
|
||||
+ " but the property type "
|
||||
+ propertyAlias
|
||||
+ " does not exist on the member type, ensure that this property type exists so that setting this property works correctly.");
|
||||
|
||||
//if the property doesn't exist, then do the logging and return a failure
|
||||
if (Properties.Contains(propertyAlias) == false)
|
||||
{
|
||||
if (HasIdentity)
|
||||
{
|
||||
doLog();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//if the property doesn't have an identity but we do, then do logging and return failure
|
||||
var prop = Properties.Single(x => x.Alias == propertyAlias);
|
||||
if (prop.HasIdentity == false && HasIdentity)
|
||||
{
|
||||
doLog();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a member type
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[DataContract(IsReference = true)]
|
||||
public class MemberGroup : Entity, IMemberGroup
|
||||
{
|
||||
public MemberGroup()
|
||||
{
|
||||
AdditionalData = new Dictionary<string, object>();
|
||||
}
|
||||
|
||||
private string _name;
|
||||
private int _creatorId;
|
||||
|
||||
private static readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo<MemberGroup, string>(x => x.Name);
|
||||
private static readonly PropertyInfo CreatorIdSelector = ExpressionHelper.GetPropertyInfo<MemberGroup, int>(x => x.CreatorId);
|
||||
|
||||
[DataMember]
|
||||
public string Name
|
||||
{
|
||||
get { return _name; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
if (_name != value)
|
||||
{
|
||||
//if the name has changed, add the value to the additional data,
|
||||
//this is required purely for event handlers to know the previous name of the group
|
||||
//so we can keep the public access up to date.
|
||||
AdditionalData["previousName"] = _name;
|
||||
}
|
||||
|
||||
_name = value;
|
||||
return _name;
|
||||
}, _name, NameSelector);
|
||||
}
|
||||
}
|
||||
|
||||
public int CreatorId
|
||||
{
|
||||
get { return _creatorId; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_creatorId = value;
|
||||
return _creatorId;
|
||||
}, _creatorId, CreatorIdSelector);
|
||||
}
|
||||
}
|
||||
|
||||
public IDictionary<string, object> AdditionalData { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Method to call when Entity is being saved
|
||||
/// </summary>
|
||||
/// <remarks>Created date is set and a Unique key is assigned</remarks>
|
||||
internal override void AddingEntity()
|
||||
{
|
||||
base.AddingEntity();
|
||||
|
||||
if (Key == Guid.Empty)
|
||||
Key = Guid.NewGuid();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,37 +14,48 @@ namespace Umbraco.Core.Models
|
||||
public class MemberType : ContentTypeCompositionBase, IMemberType
|
||||
{
|
||||
//Dictionary is divided into string: PropertyTypeAlias, Tuple: MemberCanEdit, VisibleOnProfile, PropertyTypeId
|
||||
private IDictionary<string, Tuple<bool, bool, int>> _memberTypePropertyTypes;
|
||||
private string _alias;
|
||||
|
||||
public MemberType(int parentId) : base(parentId)
|
||||
{
|
||||
_memberTypePropertyTypes = new Dictionary<string, Tuple<bool, bool, int>>();
|
||||
MemberTypePropertyTypes = new Dictionary<string, MemberTypePropertyProfileAccess>();
|
||||
}
|
||||
|
||||
public MemberType(IContentTypeComposition parent) : base(parent)
|
||||
{
|
||||
_memberTypePropertyTypes = new Dictionary<string, Tuple<bool, bool, int>>();
|
||||
MemberTypePropertyTypes = new Dictionary<string, MemberTypePropertyProfileAccess>();
|
||||
}
|
||||
|
||||
private static readonly PropertyInfo MemberTypePropertyTypesSelector = ExpressionHelper.GetPropertyInfo<MemberType, IDictionary<string, Tuple<bool, bool, int>>>(x => x.MemberTypePropertyTypes);
|
||||
private static readonly PropertyInfo AliasSelector = ExpressionHelper.GetPropertyInfo<MemberType, string>(x => x.Alias);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or Sets a Dictionary of Tuples (MemberCanEdit, VisibleOnProfile, PropertyTypeId) by the PropertyTypes' alias.
|
||||
/// The Alias of the ContentType
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
internal IDictionary<string, Tuple<bool, bool, int>> MemberTypePropertyTypes
|
||||
public override string Alias
|
||||
{
|
||||
get { return _memberTypePropertyTypes; }
|
||||
get { return _alias; }
|
||||
set
|
||||
{
|
||||
//NOTE: WE are overriding this because we don't want to do a ToSafeAlias when the alias is the special case of
|
||||
// "_umbracoSystemDefaultProtectType" which is used internally, currently there is an issue with the safe alias as it strips
|
||||
// leading underscores which we don't want in this case.
|
||||
// see : http://issues.umbraco.org/issue/U4-3968
|
||||
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_memberTypePropertyTypes = value;
|
||||
return _memberTypePropertyTypes;
|
||||
}, _memberTypePropertyTypes, MemberTypePropertyTypesSelector);
|
||||
_alias = value == "_umbracoSystemDefaultProtectType" ? value : value.ToSafeAlias();
|
||||
return _alias;
|
||||
}, _alias, AliasSelector);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or Sets a Dictionary of Tuples (MemberCanEdit, VisibleOnProfile) by the PropertyTypes' alias.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
internal IDictionary<string, MemberTypePropertyProfileAccess> MemberTypePropertyTypes { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean indicating whether a Property is editable by the Member.
|
||||
/// </summary>
|
||||
@@ -54,7 +65,7 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
if (MemberTypePropertyTypes.ContainsKey(propertyTypeAlias))
|
||||
{
|
||||
return MemberTypePropertyTypes[propertyTypeAlias].Item1;
|
||||
return MemberTypePropertyTypes[propertyTypeAlias].IsEditable;
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -69,7 +80,7 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
if (MemberTypePropertyTypes.ContainsKey(propertyTypeAlias))
|
||||
{
|
||||
return MemberTypePropertyTypes[propertyTypeAlias].Item2;
|
||||
return MemberTypePropertyTypes[propertyTypeAlias].IsVisible;
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -84,13 +95,11 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
if (MemberTypePropertyTypes.ContainsKey(propertyTypeAlias))
|
||||
{
|
||||
var tuple = MemberTypePropertyTypes[propertyTypeAlias];
|
||||
MemberTypePropertyTypes[propertyTypeAlias] = new Tuple<bool, bool, int>(value, tuple.Item2, tuple.Item3);
|
||||
MemberTypePropertyTypes[propertyTypeAlias].IsEditable = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
var propertyType = PropertyTypes.First(x => x.Alias.Equals(propertyTypeAlias));
|
||||
var tuple = new Tuple<bool, bool, int>(value, false, propertyType.Id);
|
||||
var tuple = new MemberTypePropertyProfileAccess(false, value);
|
||||
MemberTypePropertyTypes.Add(propertyTypeAlias, tuple);
|
||||
}
|
||||
}
|
||||
@@ -104,13 +113,11 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
if (MemberTypePropertyTypes.ContainsKey(propertyTypeAlias))
|
||||
{
|
||||
var tuple = MemberTypePropertyTypes[propertyTypeAlias];
|
||||
MemberTypePropertyTypes[propertyTypeAlias] = new Tuple<bool, bool, int>(tuple.Item1, value, tuple.Item3);
|
||||
MemberTypePropertyTypes[propertyTypeAlias].IsVisible = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
var propertyType = PropertyTypes.First(x => x.Alias.Equals(propertyTypeAlias));
|
||||
var tuple = new Tuple<bool, bool, int>(false, value, propertyType.Id);
|
||||
var tuple = new MemberTypePropertyProfileAccess(value, false);
|
||||
MemberTypePropertyTypes.Add(propertyTypeAlias, tuple);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to track the property types that are visible/editable on member profiles
|
||||
/// </summary>
|
||||
internal class MemberTypePropertyProfileAccess
|
||||
{
|
||||
public MemberTypePropertyProfileAccess(bool isVisible, bool isEditable)
|
||||
{
|
||||
IsVisible = isVisible;
|
||||
IsEditable = isEditable;
|
||||
}
|
||||
|
||||
public bool IsVisible { get; set; }
|
||||
public bool IsEditable { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -5,14 +5,14 @@
|
||||
/// </summary>
|
||||
public class EntityPermission
|
||||
{
|
||||
public EntityPermission(object userId, int entityId, string[] assignedPermissions)
|
||||
public EntityPermission(int userId, int entityId, string[] assignedPermissions)
|
||||
{
|
||||
UserId = userId;
|
||||
EntityId = entityId;
|
||||
AssignedPermissions = assignedPermissions;
|
||||
}
|
||||
|
||||
public object UserId { get; private set; }
|
||||
public int UserId { get; private set; }
|
||||
public int EntityId { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -4,9 +4,9 @@ using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
namespace Umbraco.Core.Models.Membership
|
||||
{
|
||||
internal interface IMembershipUser : IMembershipUserId, IAggregateRoot
|
||||
{
|
||||
/*new object Id { get; set; }*/
|
||||
public interface IMembershipUser : IAggregateRoot
|
||||
{
|
||||
object ProviderUserKey { get; set; }
|
||||
string Username { get; set; }
|
||||
string Email { get; set; }
|
||||
string Password { get; set; }
|
||||
@@ -14,13 +14,22 @@ namespace Umbraco.Core.Models.Membership
|
||||
string PasswordAnswer { get; set; }
|
||||
string Comments { get; set; }
|
||||
bool IsApproved { get; set; }
|
||||
bool IsOnline { get; set; }
|
||||
bool IsLockedOut { get; set; }
|
||||
DateTime LastLoginDate { get; set; }
|
||||
DateTime LastPasswordChangeDate { get; set; }
|
||||
DateTime LastLockoutDate { get; set; }
|
||||
|
||||
object ProfileId { get; set; }
|
||||
IEnumerable<object> Groups { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the number of failed password attempts.
|
||||
/// This is the number of times the password was entered incorrectly upon login.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Alias: umbracoMemberFailedPasswordAttempts
|
||||
/// Part of the standard properties collection.
|
||||
/// </remarks>
|
||||
int FailedPasswordAttempts { get; set; }
|
||||
|
||||
//object ProfileId { get; set; }
|
||||
//IEnumerable<object> Groups { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
namespace Umbraco.Core.Models.Membership
|
||||
{
|
||||
internal interface IMembershipUserId
|
||||
{
|
||||
object ProviderUserKey { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,10 @@
|
||||
/// <summary>
|
||||
/// Defines the the Profile interface
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This interface is pretty useless but has been exposed publicly from 6.x so we're stuck with it. It would make more sense
|
||||
/// if the Id was an int but since it's not people have to cast it to int all of the time!
|
||||
/// </remarks>
|
||||
public interface IProfile
|
||||
{
|
||||
object Id { get; set; }
|
||||
|
||||
@@ -7,31 +7,34 @@ namespace Umbraco.Core.Models.Membership
|
||||
/// Defines the interface for a <see cref="User"/>
|
||||
/// </summary>
|
||||
/// <remarks>Will be left internal until a proper Membership implementation is part of the roadmap</remarks>
|
||||
internal interface IUser : IMembershipUser, IUserProfile
|
||||
public interface IUser : IMembershipUser
|
||||
{
|
||||
new object Id { get; set; }
|
||||
//string Name { get; set; }
|
||||
string Name { get; set; }
|
||||
int SessionTimeout { get; set; }
|
||||
int StartContentId { get; set; }
|
||||
int StartMediaId { get; set; }
|
||||
string Language { get; set; }
|
||||
|
||||
bool NoConsole { get; set; }
|
||||
IUserType UserType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The default permissions for the user
|
||||
/// Gets/sets the user type for the user
|
||||
/// </summary>
|
||||
IUserType UserType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The default permission set for the user
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The default permissions are assigned to the user object based on the user type's default permissions
|
||||
/// </remarks>
|
||||
string DefaultPermissions { get; }
|
||||
}
|
||||
/// Currently in umbraco each permission is a single char but with an Enumerable{string} collection this allows for flexible changes to this in the future
|
||||
/// </remarks>
|
||||
IEnumerable<string> DefaultPermissions { get; set; }
|
||||
|
||||
internal interface IUserProfile : IProfile
|
||||
{
|
||||
IEnumerable<string> AllowedSections { get; }
|
||||
void RemoveAllowedSection(string sectionAlias);
|
||||
void AddAllowedSection(string sectionAlias);
|
||||
|
||||
/// <summary>
|
||||
/// Exposes the basic profile data
|
||||
/// </summary>
|
||||
IProfile ProfileData { get; }
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,28 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
|
||||
namespace Umbraco.Core.Models.Membership
|
||||
{
|
||||
|
||||
internal interface IUserType : IAggregateRoot
|
||||
public interface IUserType : IAggregateRoot
|
||||
{
|
||||
/// <summary>
|
||||
/// The user type alias
|
||||
/// </summary>
|
||||
string Alias { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The user type name
|
||||
/// </summary>
|
||||
string Name { get; set; }
|
||||
string Permissions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The set of default permissions for the user type
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// By default each permission is simply a single char but we've made this an enumerable{string} to support a more flexible permissions structure in the future.
|
||||
/// </remarks>
|
||||
IEnumerable<string> Permissions { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -6,15 +6,15 @@ namespace Umbraco.Core.Models.Membership
|
||||
{
|
||||
internal static class MembershipExtensions
|
||||
{
|
||||
internal static MembershipUser AsConcreteMembershipUser(this IMember member)
|
||||
internal static UmbracoMembershipMember AsConcreteMembershipUser(this IMembershipUser member, string providerName)
|
||||
{
|
||||
var membershipMember = new UmbracoMembershipMember(member);
|
||||
var membershipMember = new UmbracoMembershipMember(member, providerName);
|
||||
return membershipMember;
|
||||
}
|
||||
|
||||
internal static IMember AsIMember(this MembershipUser membershipMember)
|
||||
internal static IMembershipUser AsIMember(this UmbracoMembershipMember membershipMember)
|
||||
{
|
||||
var member = membershipMember as UmbracoMembershipMember;
|
||||
var member = membershipMember;
|
||||
if (member != null)
|
||||
{
|
||||
return member.Member;
|
||||
@@ -36,7 +36,7 @@ namespace Umbraco.Core.Models.Membership
|
||||
{
|
||||
return MembershipScenario.NativeUmbraco;
|
||||
}
|
||||
var memberType = ApplicationContext.Current.Services.MemberTypeService.GetMemberType(Constants.Conventions.MemberTypes.Member);
|
||||
var memberType = ApplicationContext.Current.Services.MemberTypeService.Get(Constants.Conventions.MemberTypes.DefaultAlias);
|
||||
return memberType != null
|
||||
? MembershipScenario.CustomProviderWithUmbracoLink
|
||||
: MembershipScenario.StandaloneCustomProvider;
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
namespace Umbraco.Core.Models.Membership
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a Profile which is shared between Members and Users
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[DataContract(IsReference = true)]
|
||||
internal class Profile : TracksChangesEntityBase, IProfile, IRememberBeingDirty
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Profile"/> class.
|
||||
/// </summary>
|
||||
protected Profile()
|
||||
{
|
||||
ProviderUserKeyType = typeof(int);
|
||||
}
|
||||
|
||||
public Profile(object id, string name)
|
||||
{
|
||||
ProviderUserKeyType = typeof(int);
|
||||
Id = id;
|
||||
Name = name;
|
||||
}
|
||||
|
||||
private object _id;
|
||||
private string _name;
|
||||
private object _providerUserKey;
|
||||
private Type _userTypeKey;
|
||||
|
||||
private static readonly PropertyInfo IdSelector = ExpressionHelper.GetPropertyInfo<Profile, object>(x => x.Id);
|
||||
private static readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo<Profile, string>(x => x.Name);
|
||||
private static readonly PropertyInfo ProviderUserKeySelector = ExpressionHelper.GetPropertyInfo<Profile, object>(x => x.ProviderUserKey);
|
||||
private static readonly PropertyInfo UserTypeKeySelector = ExpressionHelper.GetPropertyInfo<Profile, Type>(x => x.ProviderUserKeyType);
|
||||
|
||||
[DataMember]
|
||||
public virtual object Id
|
||||
{
|
||||
get
|
||||
{
|
||||
return _id;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_id = value;
|
||||
return _id;
|
||||
}, _id, IdSelector);
|
||||
}
|
||||
}
|
||||
|
||||
[DataMember]
|
||||
public virtual string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_name = value;
|
||||
return _name;
|
||||
}, _name, NameSelector);
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public virtual object ProviderUserKey
|
||||
{
|
||||
get
|
||||
{
|
||||
return _providerUserKey;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_providerUserKey = value;
|
||||
return _id;
|
||||
}, _providerUserKey, ProviderUserKeySelector);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the type of the provider user key.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The type of the provider user key.
|
||||
/// </value>
|
||||
[IgnoreDataMember]
|
||||
internal Type ProviderUserKeyType
|
||||
{
|
||||
get
|
||||
{
|
||||
return _userTypeKey;
|
||||
}
|
||||
private set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_userTypeKey = value;
|
||||
return _userTypeKey;
|
||||
}, _userTypeKey, UserTypeKeySelector);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the type of the provider user key.
|
||||
/// </summary>
|
||||
/// <param name="type">The type.</param>
|
||||
internal void SetProviderUserKeyType(Type type)
|
||||
{
|
||||
ProviderUserKeyType = type;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,66 +1,127 @@
|
||||
using System.Web.Security;
|
||||
using System;
|
||||
using System.Web.Security;
|
||||
|
||||
namespace Umbraco.Core.Models.Membership
|
||||
{
|
||||
//TODO: THere's still a bunch of properties that don't exist in this use that need to be mapped somehow.
|
||||
|
||||
internal class UmbracoMembershipMember : MembershipUser
|
||||
{
|
||||
private readonly IMember _member;
|
||||
private readonly IMembershipUser _member;
|
||||
private readonly string _userName;
|
||||
private readonly object _providerUserKey;
|
||||
private readonly string _passwordQuestion;
|
||||
private readonly bool _isLockedOut;
|
||||
private readonly DateTime _lastLockoutDate;
|
||||
private readonly DateTime _creationDate;
|
||||
private DateTime _lastLoginDate;
|
||||
private readonly DateTime _lastPasswordChangedDate;
|
||||
private readonly string _providerName;
|
||||
private string _email;
|
||||
private string _comment;
|
||||
private bool _isApproved;
|
||||
private DateTime _lastActivityDate;
|
||||
|
||||
public UmbracoMembershipMember(IMember member)
|
||||
//NOTE: We are only overriding the properties that matter, we don't override things like IsOnline since that is handled with the sub-class and the membership providers.
|
||||
|
||||
//NOTE: We are not calling the base constructor which will validate that a provider with the specified name exists which causes issues with unit tests. The ctor
|
||||
// validation for that doesn't need to be there anyways (have checked the source).
|
||||
public UmbracoMembershipMember(IMembershipUser member, string providerName)
|
||||
{
|
||||
_member = member;
|
||||
//NOTE: We are copying the values here so that everything is consistent with how the underlying built-in ASP.Net membership user
|
||||
// handles data! We don't want to do anything differently there but since we cannot use their ctor we'll need to handle this logic ourselves.
|
||||
if (member.Username != null)
|
||||
_userName = member.Username.Trim();
|
||||
if (member.Email != null)
|
||||
_email = member.Email.Trim();
|
||||
if (member.PasswordQuestion != null)
|
||||
_passwordQuestion = member.PasswordQuestion.Trim();
|
||||
_providerName = providerName;
|
||||
_providerUserKey = member.ProviderUserKey;
|
||||
_comment = member.Comments;
|
||||
_isApproved = member.IsApproved;
|
||||
_isLockedOut = member.IsLockedOut;
|
||||
_creationDate = member.CreateDate.ToUniversalTime();
|
||||
_lastLoginDate = member.LastLoginDate.ToUniversalTime();
|
||||
//TODO: We currently don't really have any place to store this data!!
|
||||
_lastActivityDate = member.LastLoginDate.ToUniversalTime();
|
||||
_lastPasswordChangedDate = member.LastPasswordChangeDate.ToUniversalTime();
|
||||
_lastLockoutDate = member.LastLockoutDate.ToUniversalTime();
|
||||
}
|
||||
|
||||
internal IMember Member
|
||||
|
||||
internal IMembershipUser Member
|
||||
{
|
||||
get { return _member; }
|
||||
}
|
||||
|
||||
public override string Email
|
||||
public override string UserName
|
||||
{
|
||||
get { return _member.Email; }
|
||||
set { _member.Email = value; }
|
||||
get { return _userName; }
|
||||
}
|
||||
|
||||
public override object ProviderUserKey
|
||||
{
|
||||
get { return _member.Key; }
|
||||
get { return _providerUserKey; }
|
||||
}
|
||||
|
||||
public override System.DateTime CreationDate
|
||||
public override string Email
|
||||
{
|
||||
get { return _member.CreateDate; }
|
||||
get { return _email; }
|
||||
set { _email = value; }
|
||||
}
|
||||
|
||||
public override string UserName
|
||||
public override string PasswordQuestion
|
||||
{
|
||||
get { return _member.Username; }
|
||||
get { return _passwordQuestion; }
|
||||
}
|
||||
|
||||
public override string Comment
|
||||
{
|
||||
get { return _member.Comments; }
|
||||
set { _member.Comments = value; }
|
||||
get { return _comment; }
|
||||
set { _comment = value; }
|
||||
}
|
||||
|
||||
public override bool IsApproved
|
||||
{
|
||||
get { return _member.IsApproved; }
|
||||
set { _member.IsApproved = value; }
|
||||
get { return _isApproved; }
|
||||
set { _isApproved = value; }
|
||||
}
|
||||
|
||||
public override bool IsLockedOut
|
||||
{
|
||||
get { return _member.IsLockedOut; }
|
||||
get { return _isLockedOut; }
|
||||
}
|
||||
|
||||
public override System.DateTime LastLoginDate
|
||||
public override DateTime LastLockoutDate
|
||||
{
|
||||
get { return _member.LastLoginDate; }
|
||||
set { _member.LastLoginDate = value; }
|
||||
get { return _lastLockoutDate; }
|
||||
}
|
||||
|
||||
public override DateTime CreationDate
|
||||
{
|
||||
get { return _creationDate; }
|
||||
}
|
||||
|
||||
public override DateTime LastLoginDate
|
||||
{
|
||||
get { return _lastLoginDate; }
|
||||
set { _lastLoginDate = value; }
|
||||
}
|
||||
|
||||
public override DateTime LastActivityDate
|
||||
{
|
||||
get { return _lastActivityDate; }
|
||||
set { _lastActivityDate = value; }
|
||||
}
|
||||
|
||||
public override DateTime LastPasswordChangedDate
|
||||
{
|
||||
get { return _lastPasswordChangedDate; }
|
||||
}
|
||||
|
||||
public override string ProviderName
|
||||
{
|
||||
get { return _providerName; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
|
||||
@@ -16,97 +20,498 @@ namespace Umbraco.Core.Models.Membership
|
||||
/// </remarks>
|
||||
[Serializable]
|
||||
[DataContract(IsReference = true)]
|
||||
internal class User : UserProfile, IUser
|
||||
public class User : TracksChangesEntityBase, IUser
|
||||
{
|
||||
private bool _hasIdentity;
|
||||
|
||||
public User(IUserType userType)
|
||||
{
|
||||
Groups = new List<object> { userType };
|
||||
if (userType == null) throw new ArgumentNullException("userType");
|
||||
|
||||
_userType = userType;
|
||||
//Groups = new List<object> { userType };
|
||||
SessionTimeout = 60;
|
||||
_sectionCollection = new ObservableCollection<string>();
|
||||
_addedSections = new List<string>();
|
||||
_removedSections = new List<string>();
|
||||
_language = GlobalSettings.DefaultUILanguage;
|
||||
_sectionCollection.CollectionChanged += SectionCollectionChanged;
|
||||
_isApproved = true;
|
||||
_isLockedOut = false;
|
||||
_startContentId = -1;
|
||||
_startMediaId = -1;
|
||||
}
|
||||
|
||||
public User(string name, string email, string username, string password, IUserType userType)
|
||||
: this(userType)
|
||||
{
|
||||
_name = name;
|
||||
_email = email;
|
||||
_username = username;
|
||||
_password = password;
|
||||
_isApproved = true;
|
||||
_isLockedOut = false;
|
||||
_startContentId = -1;
|
||||
_startMediaId = -1;
|
||||
}
|
||||
|
||||
private IUserType _userType;
|
||||
private bool _hasIdentity;
|
||||
private int _id;
|
||||
private string _name;
|
||||
private Type _userTypeKey;
|
||||
private readonly List<string> _addedSections;
|
||||
private readonly List<string> _removedSections;
|
||||
private readonly ObservableCollection<string> _sectionCollection;
|
||||
private int _sessionTimeout;
|
||||
private int _startContentId;
|
||||
private int _startMediaId;
|
||||
|
||||
private string _username;
|
||||
private string _email;
|
||||
private string _password;
|
||||
private bool _isApproved;
|
||||
private bool _isLockedOut;
|
||||
private string _language;
|
||||
private IEnumerable<string> _defaultPermissions;
|
||||
private bool _defaultToLiveEditing;
|
||||
|
||||
private static readonly PropertyInfo SessionTimeoutSelector = ExpressionHelper.GetPropertyInfo<User, int>(x => x.SessionTimeout);
|
||||
private static readonly PropertyInfo StartContentIdSelector = ExpressionHelper.GetPropertyInfo<User, int>(x => x.StartContentId);
|
||||
private static readonly PropertyInfo StartMediaIdSelector = ExpressionHelper.GetPropertyInfo<User, int>(x => x.StartMediaId);
|
||||
private static readonly PropertyInfo AllowedSectionsSelector = ExpressionHelper.GetPropertyInfo<User, IEnumerable<string>>(x => x.AllowedSections);
|
||||
private static readonly PropertyInfo IdSelector = ExpressionHelper.GetPropertyInfo<User, object>(x => x.Id);
|
||||
private static readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo<User, string>(x => x.Name);
|
||||
private static readonly PropertyInfo UserTypeKeySelector = ExpressionHelper.GetPropertyInfo<User, Type>(x => x.ProviderUserKeyType);
|
||||
|
||||
private static readonly PropertyInfo UsernameSelector = ExpressionHelper.GetPropertyInfo<User, string>(x => x.Username);
|
||||
private static readonly PropertyInfo EmailSelector = ExpressionHelper.GetPropertyInfo<User, string>(x => x.Email);
|
||||
private static readonly PropertyInfo PasswordSelector = ExpressionHelper.GetPropertyInfo<User, string>(x => x.Password);
|
||||
private static readonly PropertyInfo IsLockedOutSelector = ExpressionHelper.GetPropertyInfo<User, bool>(x => x.IsLockedOut);
|
||||
private static readonly PropertyInfo IsApprovedSelector = ExpressionHelper.GetPropertyInfo<User, bool>(x => x.IsApproved);
|
||||
private static readonly PropertyInfo LanguageSelector = ExpressionHelper.GetPropertyInfo<User, string>(x => x.Language);
|
||||
private static readonly PropertyInfo DefaultPermissionsSelector = ExpressionHelper.GetPropertyInfo<User, IEnumerable<string>>(x => x.DefaultPermissions);
|
||||
private static readonly PropertyInfo DefaultToLiveEditingSelector = ExpressionHelper.GetPropertyInfo<User, bool>(x => x.DefaultToLiveEditing);
|
||||
private static readonly PropertyInfo HasIdentitySelector = ExpressionHelper.GetPropertyInfo<User, bool>(x => x.HasIdentity);
|
||||
private static readonly PropertyInfo UserTypeSelector = ExpressionHelper.GetPropertyInfo<User, IUserType>(x => x.UserType);
|
||||
|
||||
#region Implementation of IEntity
|
||||
|
||||
[IgnoreDataMember]
|
||||
public bool HasIdentity { get { return Id != null || _hasIdentity; } }
|
||||
|
||||
[IgnoreDataMember]
|
||||
int IEntity.Id
|
||||
public bool HasIdentity
|
||||
{
|
||||
get
|
||||
{
|
||||
return int.Parse(base.Id.ToString());
|
||||
return _hasIdentity;
|
||||
}
|
||||
set
|
||||
protected set
|
||||
{
|
||||
base.Id = value;
|
||||
_hasIdentity = true;
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_hasIdentity = value;
|
||||
return _hasIdentity;
|
||||
}, _hasIdentity, HasIdentitySelector);
|
||||
}
|
||||
}
|
||||
|
||||
[DataMember]
|
||||
public int Id
|
||||
{
|
||||
get
|
||||
{
|
||||
return _id;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_id = value;
|
||||
HasIdentity = true; //set the has Identity
|
||||
return _id;
|
||||
}, _id, IdSelector);
|
||||
}
|
||||
}
|
||||
|
||||
//this doesn't get used
|
||||
[IgnoreDataMember]
|
||||
public Guid Key { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation of IMembershipUser
|
||||
|
||||
[IgnoreDataMember]
|
||||
public object ProviderUserKey
|
||||
{
|
||||
get { return Id; }
|
||||
set { throw new NotSupportedException("Cannot set the provider user key for a user"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the type of the provider user key.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The type of the provider user key.
|
||||
/// </value>
|
||||
[IgnoreDataMember]
|
||||
internal Type ProviderUserKeyType
|
||||
{
|
||||
get
|
||||
{
|
||||
return _userTypeKey;
|
||||
}
|
||||
private set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_userTypeKey = value;
|
||||
return _userTypeKey;
|
||||
}, _userTypeKey, UserTypeKeySelector);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the type of the provider user key.
|
||||
/// </summary>
|
||||
/// <param name="type">The type.</param>
|
||||
internal void SetProviderUserKeyType(Type type)
|
||||
{
|
||||
ProviderUserKeyType = type;
|
||||
}
|
||||
|
||||
[DataMember]
|
||||
public string Username { get; set; }
|
||||
public string Username
|
||||
{
|
||||
get { return _username; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_username = value;
|
||||
return _username;
|
||||
}, _username, UsernameSelector);
|
||||
}
|
||||
}
|
||||
[DataMember]
|
||||
public string Email { get; set; }
|
||||
public string Email
|
||||
{
|
||||
get { return _email; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_email = value;
|
||||
return _email;
|
||||
}, _email, EmailSelector);
|
||||
}
|
||||
}
|
||||
[DataMember]
|
||||
public string Password { get; set; }
|
||||
public string Password
|
||||
{
|
||||
get { return _password; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_password = value;
|
||||
return _password;
|
||||
}, _password, PasswordSelector);
|
||||
}
|
||||
}
|
||||
|
||||
[DataMember]
|
||||
public bool IsApproved
|
||||
{
|
||||
get { return _isApproved; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_isApproved = value;
|
||||
return _isApproved;
|
||||
}, _isApproved, IsApprovedSelector);
|
||||
}
|
||||
}
|
||||
|
||||
[DataMember]
|
||||
public bool IsLockedOut
|
||||
{
|
||||
get { return _isLockedOut; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_isLockedOut = value;
|
||||
return _isLockedOut;
|
||||
}, _isLockedOut, IsLockedOutSelector);
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: Figure out how to support all of this! - we cannot have NotImplementedExceptions because these get used by the IMembershipMemberService<IUser> service so
|
||||
// we'll just have them as generic get/set which don't interact with the db.
|
||||
|
||||
[IgnoreDataMember]
|
||||
public string PasswordQuestion { get; set; }
|
||||
[DataMember]
|
||||
[IgnoreDataMember]
|
||||
public string PasswordAnswer { get; set; }
|
||||
[DataMember]
|
||||
[IgnoreDataMember]
|
||||
public string Comments { get; set; }
|
||||
[DataMember]
|
||||
public bool IsApproved { get; set; }
|
||||
[DataMember]
|
||||
public bool IsOnline { get; set; }
|
||||
[DataMember]
|
||||
public bool IsLockedOut { get; set; }
|
||||
[DataMember]
|
||||
[IgnoreDataMember]
|
||||
public DateTime CreateDate { get; set; }
|
||||
[DataMember]
|
||||
[IgnoreDataMember]
|
||||
public DateTime UpdateDate { get; set; }
|
||||
[DataMember]
|
||||
[IgnoreDataMember]
|
||||
public DateTime LastLoginDate { get; set; }
|
||||
[DataMember]
|
||||
[IgnoreDataMember]
|
||||
public DateTime LastPasswordChangeDate { get; set; }
|
||||
[DataMember]
|
||||
[IgnoreDataMember]
|
||||
public DateTime LastLockoutDate { get; set; }
|
||||
|
||||
[DataMember]
|
||||
public object ProfileId { get; set; }
|
||||
[DataMember]
|
||||
public IEnumerable<object> Groups { get; set; }
|
||||
|
||||
[IgnoreDataMember]
|
||||
public int FailedPasswordAttempts { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Implementation of IUser
|
||||
|
||||
[DataMember]
|
||||
public string Language { get; set; }
|
||||
public string Name
|
||||
{
|
||||
get { return _name; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_name = value;
|
||||
return _name;
|
||||
}, _name, NameSelector);
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<string> AllowedSections
|
||||
{
|
||||
get { return _sectionCollection; }
|
||||
}
|
||||
|
||||
public void RemoveAllowedSection(string sectionAlias)
|
||||
{
|
||||
_sectionCollection.Remove(sectionAlias);
|
||||
}
|
||||
|
||||
public void AddAllowedSection(string sectionAlias)
|
||||
{
|
||||
if (_sectionCollection.Contains(sectionAlias) == false)
|
||||
{
|
||||
_sectionCollection.Add(sectionAlias);
|
||||
}
|
||||
}
|
||||
|
||||
public IProfile ProfileData
|
||||
{
|
||||
get { return new UserProfile(this); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used internally to check if we need to add a section in the repository to the db
|
||||
/// </summary>
|
||||
internal IEnumerable<string> AddedSections
|
||||
{
|
||||
get { return _addedSections; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used internally to check if we need to remove a section in the repository to the db
|
||||
/// </summary>
|
||||
internal IEnumerable<string> RemovedSections
|
||||
{
|
||||
get { return _removedSections; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the session timeout.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The session timeout.
|
||||
/// </value>
|
||||
[DataMember]
|
||||
public int SessionTimeout
|
||||
{
|
||||
get { return _sessionTimeout; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_sessionTimeout = value;
|
||||
return _sessionTimeout;
|
||||
}, _sessionTimeout, SessionTimeoutSelector);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the start content id.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The start content id.
|
||||
/// </value>
|
||||
[DataMember]
|
||||
public int StartContentId
|
||||
{
|
||||
get { return _startContentId; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_startContentId = value;
|
||||
return _startContentId;
|
||||
}, _startContentId, StartContentIdSelector);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the start media id.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The start media id.
|
||||
/// </value>
|
||||
[DataMember]
|
||||
public int StartMediaId
|
||||
{
|
||||
get { return _startMediaId; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_startMediaId = value;
|
||||
return _startMediaId;
|
||||
}, _startMediaId, StartMediaIdSelector);
|
||||
}
|
||||
}
|
||||
|
||||
[DataMember]
|
||||
public string DefaultPermissions { get; set; }
|
||||
|
||||
public string Language
|
||||
{
|
||||
get { return _language; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_language = value;
|
||||
return _language;
|
||||
}, _language, LanguageSelector);
|
||||
}
|
||||
}
|
||||
|
||||
[DataMember]
|
||||
public bool NoConsole { get; set; }
|
||||
public IEnumerable<string> DefaultPermissions
|
||||
{
|
||||
get { return _defaultPermissions; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_defaultPermissions = value;
|
||||
return _defaultPermissions;
|
||||
}, _defaultPermissions, DefaultPermissionsSelector);
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
internal bool DefaultToLiveEditing
|
||||
{
|
||||
get { return _defaultToLiveEditing; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_defaultToLiveEditing = value;
|
||||
return _defaultToLiveEditing;
|
||||
}, _defaultToLiveEditing, DefaultToLiveEditingSelector);
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public IUserType UserType
|
||||
{
|
||||
get
|
||||
get { return _userType; }
|
||||
set
|
||||
{
|
||||
var type = Groups.FirstOrDefault();
|
||||
return type as IUserType;
|
||||
if (value.HasIdentity == false)
|
||||
{
|
||||
throw new InvalidOperationException("Cannot assign a User Type that has not been persisted");
|
||||
}
|
||||
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_userType = value;
|
||||
return _userType;
|
||||
}, _userType, UserTypeSelector);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Whenever resetting occurs, clear the remembered add/removed collections, even if
|
||||
/// rememberPreviouslyChangedProperties is true, the AllowedSections property will still
|
||||
/// be flagged as dirty.
|
||||
/// </summary>
|
||||
/// <param name="rememberPreviouslyChangedProperties"></param>
|
||||
public override void ResetDirtyProperties(bool rememberPreviouslyChangedProperties)
|
||||
{
|
||||
_addedSections.Clear();
|
||||
_removedSections.Clear();
|
||||
base.ResetDirtyProperties(rememberPreviouslyChangedProperties);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the collection changed event in order for us to flag the AllowedSections property as changed
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
void SectionCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
OnPropertyChanged(AllowedSectionsSelector);
|
||||
|
||||
if (e.Action == NotifyCollectionChangedAction.Add)
|
||||
{
|
||||
//remove from the removed/added sections (since people could add/remove all they want in one request)
|
||||
_removedSections.RemoveAll(s => s == e.NewItems.Cast<string>().First());
|
||||
_addedSections.RemoveAll(s => s == e.NewItems.Cast<string>().First());
|
||||
|
||||
//add to the added sections
|
||||
_addedSections.Add(e.NewItems.Cast<string>().First());
|
||||
}
|
||||
else if (e.Action == NotifyCollectionChangedAction.Remove)
|
||||
{
|
||||
//remove from the removed/added sections (since people could add/remove all they want in one request)
|
||||
_removedSections.RemoveAll(s => s == e.OldItems.Cast<string>().First());
|
||||
_addedSections.RemoveAll(s => s == e.OldItems.Cast<string>().First());
|
||||
|
||||
//add to the added sections
|
||||
_removedSections.Add(e.OldItems.Cast<string>().First());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal class used to wrap the user in a profile
|
||||
/// </summary>
|
||||
private class UserProfile : IProfile
|
||||
{
|
||||
private readonly IUser _user;
|
||||
|
||||
public UserProfile(IUser user)
|
||||
{
|
||||
_user = user;
|
||||
}
|
||||
|
||||
public object Id
|
||||
{
|
||||
get { return _user.Id; }
|
||||
set { _user.Id = (int)value; }
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return _user.Name; }
|
||||
set { _user.Name = value; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,188 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Umbraco.Core.Models.Membership
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the Profile implementation for a backoffice User
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Should be internal until a proper user/membership implementation
|
||||
/// is part of the roadmap.
|
||||
/// </remarks>
|
||||
[Serializable]
|
||||
[DataContract(IsReference = true)]
|
||||
internal class UserProfile : Profile, IUserProfile
|
||||
{
|
||||
public UserProfile()
|
||||
{
|
||||
SessionTimeout = 60;
|
||||
_sectionCollection = new ObservableCollection<string>();
|
||||
_addedSections = new List<string>();
|
||||
_removedSections = new List<string>();
|
||||
_sectionCollection.CollectionChanged += SectionCollectionChanged;
|
||||
}
|
||||
|
||||
private readonly List<string> _addedSections;
|
||||
private readonly List<string> _removedSections;
|
||||
private readonly ObservableCollection<string> _sectionCollection;
|
||||
private int _sessionTimeout;
|
||||
private int _startContentId;
|
||||
private int _startMediaId;
|
||||
|
||||
private static readonly PropertyInfo SessionTimeoutSelector = ExpressionHelper.GetPropertyInfo<UserProfile, int>(x => x.SessionTimeout);
|
||||
private static readonly PropertyInfo StartContentIdSelector = ExpressionHelper.GetPropertyInfo<UserProfile, int>(x => x.StartContentId);
|
||||
private static readonly PropertyInfo StartMediaIdSelector = ExpressionHelper.GetPropertyInfo<UserProfile, int>(x => x.StartMediaId);
|
||||
private static readonly PropertyInfo AllowedSectionsSelector = ExpressionHelper.GetPropertyInfo<UserProfile, IEnumerable<string>>(x => x.AllowedSections);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the session timeout.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The session timeout.
|
||||
/// </value>
|
||||
[DataMember]
|
||||
public int SessionTimeout
|
||||
{
|
||||
get
|
||||
{
|
||||
return _sessionTimeout;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_sessionTimeout = value;
|
||||
return _sessionTimeout;
|
||||
}, _sessionTimeout, SessionTimeoutSelector);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the start content id.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The start content id.
|
||||
/// </value>
|
||||
[DataMember]
|
||||
public int StartContentId
|
||||
{
|
||||
get
|
||||
{
|
||||
return _startContentId;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_startContentId = value;
|
||||
return _startContentId;
|
||||
}, _startContentId, StartContentIdSelector);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the start media id.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The start media id.
|
||||
/// </value>
|
||||
[DataMember]
|
||||
public int StartMediaId
|
||||
{
|
||||
get
|
||||
{
|
||||
return _startMediaId;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_startMediaId = value;
|
||||
return _startMediaId;
|
||||
}, _startMediaId, StartMediaIdSelector);
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<string> AllowedSections
|
||||
{
|
||||
get { return _sectionCollection; }
|
||||
}
|
||||
|
||||
public void RemoveAllowedSection(string sectionAlias)
|
||||
{
|
||||
_sectionCollection.Remove(sectionAlias);
|
||||
}
|
||||
|
||||
public void AddAllowedSection(string sectionAlias)
|
||||
{
|
||||
if (!_sectionCollection.Contains(sectionAlias))
|
||||
{
|
||||
_sectionCollection.Add(sectionAlias);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whenever resetting occurs, clear the remembered add/removed collections, even if
|
||||
/// rememberPreviouslyChangedProperties is true, the AllowedSections property will still
|
||||
/// be flagged as dirty.
|
||||
/// </summary>
|
||||
/// <param name="rememberPreviouslyChangedProperties"></param>
|
||||
public override void ResetDirtyProperties(bool rememberPreviouslyChangedProperties)
|
||||
{
|
||||
_addedSections.Clear();
|
||||
_removedSections.Clear();
|
||||
base.ResetDirtyProperties(rememberPreviouslyChangedProperties);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used internally to check if we need to add a section in the repository to the db
|
||||
/// </summary>
|
||||
internal IEnumerable<string> AddedSections
|
||||
{
|
||||
get { return _addedSections; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used internally to check if we need to remove a section in the repository to the db
|
||||
/// </summary>
|
||||
internal IEnumerable<string> RemovedSections
|
||||
{
|
||||
get { return _removedSections; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the collection changed event in order for us to flag the AllowedSections property as changed
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
void SectionCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
OnPropertyChanged(AllowedSectionsSelector);
|
||||
|
||||
if (e.Action == NotifyCollectionChangedAction.Add)
|
||||
{
|
||||
//remove from the removed/added sections (since people could add/remove all they want in one request)
|
||||
_removedSections.RemoveAll(s => s == e.NewItems.Cast<string>().First());
|
||||
_addedSections.RemoveAll(s => s == e.NewItems.Cast<string>().First());
|
||||
|
||||
//add to the added sections
|
||||
_addedSections.Add(e.NewItems.Cast<string>().First());
|
||||
}
|
||||
else if (e.Action == NotifyCollectionChangedAction.Remove)
|
||||
{
|
||||
//remove from the removed/added sections (since people could add/remove all they want in one request)
|
||||
_removedSections.RemoveAll(s => s == e.OldItems.Cast<string>().First());
|
||||
_addedSections.RemoveAll(s => s == e.OldItems.Cast<string>().First());
|
||||
|
||||
//add to the added sections
|
||||
_removedSections.Add(e.OldItems.Cast<string>().First());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
@@ -22,7 +23,13 @@ namespace Umbraco.Core.Models.Membership
|
||||
[DataMember]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The set of default permissions for the user type
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// By default each permission is simply a single char but we've made this an enumerable{string} to support a more flexible permissions structure in the future.
|
||||
/// </remarks>
|
||||
[DataMember]
|
||||
public string Permissions { get; set; }
|
||||
public IEnumerable<string> Permissions { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
internal class Notification
|
||||
{
|
||||
public Notification(int entityId, int userId, string action, Guid entityType)
|
||||
{
|
||||
EntityId = entityId;
|
||||
UserId = userId;
|
||||
Action = action;
|
||||
EntityType = entityType;
|
||||
}
|
||||
|
||||
public int EntityId { get; private set; }
|
||||
public int UserId { get; private set; }
|
||||
public string Action { get; private set; }
|
||||
public Guid EntityType { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -44,7 +44,7 @@ namespace Umbraco.Core.Models
|
||||
|
||||
private static readonly PropertyInfo ValueSelector = ExpressionHelper.GetPropertyInfo<Property, object>(x => x.Value);
|
||||
private static readonly PropertyInfo VersionSelector = ExpressionHelper.GetPropertyInfo<Property, Guid>(x => x.Version);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns the instance of the tag support, by default tags are not enabled
|
||||
/// </summary>
|
||||
@@ -68,9 +68,14 @@ namespace Umbraco.Core.Models
|
||||
/// <summary>
|
||||
/// Returns the DatabaseType that the underlaying DataType is using to store its values
|
||||
/// </summary>
|
||||
/// <remarks>Only used internally when saving the property value</remarks>
|
||||
/// <remarks>
|
||||
/// Only used internally when saving the property value.
|
||||
/// </remarks>
|
||||
[IgnoreDataMember]
|
||||
internal DataTypeDatabaseType DataTypeDatabaseType { get { return _propertyType.DataTypeDatabaseType; } }
|
||||
internal DataTypeDatabaseType DataTypeDatabaseType
|
||||
{
|
||||
get { return _propertyType.DataTypeDatabaseType; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the PropertyType, which this Property is based on
|
||||
|
||||
@@ -15,6 +15,7 @@ namespace Umbraco.Core.Models
|
||||
[DataContract(IsReference = true)]
|
||||
public class PropertyType : Entity, IEquatable<PropertyType>
|
||||
{
|
||||
private readonly bool _isExplicitDbType;
|
||||
private string _name;
|
||||
private string _alias;
|
||||
private string _description;
|
||||
@@ -30,16 +31,29 @@ namespace Umbraco.Core.Models
|
||||
public PropertyType(IDataTypeDefinition dataTypeDefinition)
|
||||
{
|
||||
if(dataTypeDefinition.HasIdentity)
|
||||
DataTypeDefinitionId = dataTypeDefinition.Id;
|
||||
_dataTypeDefinitionId = dataTypeDefinition.Id;
|
||||
|
||||
PropertyEditorAlias = dataTypeDefinition.PropertyEditorAlias;
|
||||
DataTypeDatabaseType = dataTypeDefinition.DatabaseType;
|
||||
_propertyEditorAlias = dataTypeDefinition.PropertyEditorAlias;
|
||||
_dataTypeDatabaseType = dataTypeDefinition.DatabaseType;
|
||||
}
|
||||
|
||||
internal PropertyType(string propertyEditorAlias, DataTypeDatabaseType dataTypeDatabaseType)
|
||||
: this(propertyEditorAlias, dataTypeDatabaseType, false)
|
||||
{
|
||||
PropertyEditorAlias = propertyEditorAlias;
|
||||
DataTypeDatabaseType = dataTypeDatabaseType;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used internally to assign an explicity database type for this property type regardless of what the underlying data type/property editor is.
|
||||
/// </summary>
|
||||
/// <param name="propertyEditorAlias"></param>
|
||||
/// <param name="dataTypeDatabaseType"></param>
|
||||
/// <param name="isExplicitDbType"></param>
|
||||
internal PropertyType(string propertyEditorAlias, DataTypeDatabaseType dataTypeDatabaseType, bool isExplicitDbType)
|
||||
{
|
||||
_isExplicitDbType = isExplicitDbType;
|
||||
_propertyEditorAlias = propertyEditorAlias;
|
||||
_dataTypeDatabaseType = dataTypeDatabaseType;
|
||||
}
|
||||
|
||||
private static readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo<PropertyType, string>(x => x.Name);
|
||||
@@ -165,6 +179,9 @@ namespace Umbraco.Core.Models
|
||||
get { return _dataTypeDatabaseType; }
|
||||
set
|
||||
{
|
||||
//don't allow setting this if an explicit declaration has been made in the ctor
|
||||
if (_isExplicitDbType) return;
|
||||
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_dataTypeDatabaseType = value;
|
||||
@@ -377,8 +394,16 @@ namespace Umbraco.Core.Models
|
||||
//Check against Regular Expression for Legacy DataTypes - Validation exists and value is not null:
|
||||
if(string.IsNullOrEmpty(ValidationRegExp) == false && (value != null && string.IsNullOrEmpty(value.ToString()) == false))
|
||||
{
|
||||
var regexPattern = new Regex(ValidationRegExp);
|
||||
return regexPattern.IsMatch(value.ToString());
|
||||
try
|
||||
{
|
||||
var regexPattern = new Regex(ValidationRegExp);
|
||||
return regexPattern.IsMatch(value.ToString());
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw new Exception(string .Format("Invalid validation expression on property {0}",this.Alias));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//TODO Add PropertyEditor validation when its relevant to introduce
|
||||
|
||||
@@ -80,11 +80,8 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
|
||||
private void InitializeConverters()
|
||||
{
|
||||
var converters = PropertyValueConvertersResolver.Current.Converters.ToArray();
|
||||
|
||||
var defaultConverters = converters
|
||||
.Where(x => x.GetType().GetCustomAttribute<DefaultPropertyValueConverterAttribute>(false) != null)
|
||||
.ToArray();
|
||||
var converters = PropertyValueConvertersResolver.Current.Converters.ToArray();
|
||||
var defaultConvertersWithAttributes = PropertyValueConvertersResolver.Current.DefaultConverters;
|
||||
|
||||
_converter = null;
|
||||
|
||||
@@ -98,8 +95,14 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
else if (foundConverters.Length > 1)
|
||||
{
|
||||
//more than one was found, we need to first figure out if one of these is an Umbraco default value type converter
|
||||
var nonDefault = foundConverters.Except(defaultConverters).ToArray();
|
||||
if (nonDefault.Length > 1)
|
||||
//get the non-default and see if we have one
|
||||
var nonDefault = foundConverters.Except(defaultConvertersWithAttributes.Select(x => x.Item1)).ToArray();
|
||||
if (nonDefault.Length == 1)
|
||||
{
|
||||
//there's only 1 custom converter registered that so use it
|
||||
_converter = nonDefault[0];
|
||||
}
|
||||
else if (nonDefault.Length > 1)
|
||||
{
|
||||
//this is not allowed, there cannot be more than 1 custom converter
|
||||
throw new InvalidOperationException(
|
||||
@@ -109,9 +112,31 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
ContentType.Alias, PropertyTypeAlias,
|
||||
nonDefault[1].GetType().FullName, nonDefault[0].GetType().FullName));
|
||||
}
|
||||
else
|
||||
{
|
||||
//we need to remove any converters that have been shadowed by another converter
|
||||
var foundDefaultConvertersWithAttributes = defaultConvertersWithAttributes.Where(x => foundConverters.Contains(x.Item1));
|
||||
var shadowedTypes = foundDefaultConvertersWithAttributes.SelectMany(x => x.Item2.DefaultConvertersToShadow);
|
||||
var shadowedDefaultConverters = foundConverters.Where(x => shadowedTypes.Contains(x.GetType()));
|
||||
var nonShadowedDefaultConverters = foundConverters.Except(shadowedDefaultConverters).ToArray();
|
||||
|
||||
//there's only 1 custom converter registered that so use it
|
||||
_converter = nonDefault[0];
|
||||
if (nonShadowedDefaultConverters.Length == 1)
|
||||
{
|
||||
//assign to the single default converter
|
||||
_converter = nonShadowedDefaultConverters[0];
|
||||
}
|
||||
else if (nonShadowedDefaultConverters.Length > 1)
|
||||
{
|
||||
//this is not allowed, there cannot be more than 1 custom converter
|
||||
throw new InvalidOperationException(
|
||||
string.Format("Type '{2}' cannot be an IPropertyValueConverter"
|
||||
+ " for property '{1}' of content type '{0}' because type '{3}' has already been detected as a converter"
|
||||
+ " for that property, and only one converter can exist for a property.",
|
||||
ContentType.Alias, PropertyTypeAlias,
|
||||
nonShadowedDefaultConverters[1].GetType().FullName, nonShadowedDefaultConverters[0].GetType().FullName));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// get the cache levels, quietely fixing the inconsistencies (no need to throw, really)
|
||||
|
||||
@@ -30,7 +30,6 @@ namespace Umbraco.Core.Models.Rdbms
|
||||
public DateTime DateRegistered { get; set; }
|
||||
|
||||
[Column("lastNotifiedDate")]
|
||||
[Constraint(Default = "getdate()")]
|
||||
public DateTime LastNotified { get; set; }
|
||||
|
||||
[Column("isActive")]
|
||||
|
||||
@@ -183,5 +183,11 @@ namespace Umbraco.Core.Models
|
||||
if (Key == Guid.Empty)
|
||||
Key = Guid.NewGuid();
|
||||
}
|
||||
|
||||
|
||||
public void SetMasterTemplate(ITemplate masterTemplate)
|
||||
{
|
||||
MasterTemplateId = new Lazy<int>(() => masterTemplate.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
@@ -53,6 +54,13 @@ namespace Umbraco.Core.Models
|
||||
Trashed = trashed;
|
||||
}
|
||||
|
||||
// for MySql
|
||||
public UmbracoEntity(UInt64 trashed)
|
||||
{
|
||||
AdditionalData = new Dictionary<string, object>();
|
||||
Trashed = trashed == 1;
|
||||
}
|
||||
|
||||
public int CreatorId
|
||||
{
|
||||
get { return _creatorId; }
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web.UI.WebControls;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
internal static class UmbracoEntityExtensions
|
||||
{
|
||||
|
||||
public static object GetAdditionalDataValueIgnoreCase(this IUmbracoEntity entity, string key, object defaultVal)
|
||||
{
|
||||
if (entity.AdditionalData.ContainsKeyIgnoreCase(key) == false) return defaultVal;
|
||||
return entity.AdditionalData.GetValueIgnoreCase(key, defaultVal);
|
||||
}
|
||||
|
||||
public static bool IsContainer(this IUmbracoEntity entity)
|
||||
{
|
||||
if (entity.AdditionalData.ContainsKeyIgnoreCase("IsContainer") == false) return false;
|
||||
var val = entity.AdditionalData.GetValueIgnoreCase("IsContainer", null);
|
||||
if (val is bool && (bool) val)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -246,12 +246,14 @@ namespace Umbraco.Core
|
||||
else if (destinationType == typeof(Double))
|
||||
{
|
||||
Double value;
|
||||
return Double.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
var input2 = NormalizeNumberDecimalSeparator(input);
|
||||
return Double.TryParse(input2, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
}
|
||||
else if (destinationType == typeof(Single))
|
||||
{
|
||||
Single value;
|
||||
return Single.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
var input2 = NormalizeNumberDecimalSeparator(input);
|
||||
return Single.TryParse(input2, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
}
|
||||
else if (destinationType == typeof(Char))
|
||||
{
|
||||
@@ -292,7 +294,20 @@ namespace Umbraco.Core
|
||||
else if (destinationType == typeof(DateTime))
|
||||
{
|
||||
DateTime value;
|
||||
return DateTime.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
if (DateTime.TryParse(input, out value))
|
||||
{
|
||||
switch (value.Kind)
|
||||
{
|
||||
case DateTimeKind.Unspecified:
|
||||
case DateTimeKind.Utc:
|
||||
return Attempt<object>.Succeed(value);
|
||||
case DateTimeKind.Local:
|
||||
return Attempt<object>.Succeed(value.ToUniversalTime());
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
return Attempt<object>.Fail();
|
||||
}
|
||||
else if (destinationType == typeof(DateTimeOffset))
|
||||
{
|
||||
@@ -307,7 +322,8 @@ namespace Umbraco.Core
|
||||
else if (destinationType == typeof(Decimal))
|
||||
{
|
||||
Decimal value;
|
||||
return Decimal.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
var input2 = NormalizeNumberDecimalSeparator(input);
|
||||
return Decimal.TryParse(input2, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
}
|
||||
else if (destinationType == typeof(Version))
|
||||
{
|
||||
@@ -319,6 +335,14 @@ namespace Umbraco.Core
|
||||
return null; // we can't decide...
|
||||
}
|
||||
|
||||
private readonly static char[] NumberDecimalSeparatorsToNormalize = new[] {'.', ','};
|
||||
|
||||
private static string NormalizeNumberDecimalSeparator(string s)
|
||||
{
|
||||
var normalized = System.Threading.Thread.CurrentThread.CurrentUICulture.NumberFormat.NumberDecimalSeparator[0];
|
||||
return s.ReplaceMany(NumberDecimalSeparatorsToNormalize, normalized);
|
||||
}
|
||||
|
||||
internal static void CheckThrowObjectDisposed(this IDisposable disposable, bool isDisposed, string objectname)
|
||||
{
|
||||
//TODO: Localise this exception
|
||||
@@ -526,7 +550,7 @@ namespace Umbraco.Core
|
||||
if (type == typeof(bool)) return XmlConvert.ToString((bool)value);
|
||||
if (type == typeof(byte)) return XmlConvert.ToString((byte)value);
|
||||
if (type == typeof(char)) return XmlConvert.ToString((char)value);
|
||||
if (type == typeof(DateTime)) return XmlConvert.ToString((DateTime)value, XmlDateTimeSerializationMode.RoundtripKind);
|
||||
if (type == typeof(DateTime)) return XmlConvert.ToString((DateTime)value, XmlDateTimeSerializationMode.Unspecified);
|
||||
if (type == typeof(DateTimeOffset)) return XmlConvert.ToString((DateTimeOffset)value);
|
||||
if (type == typeof(decimal)) return XmlConvert.ToString((decimal)value);
|
||||
if (type == typeof(double)) return XmlConvert.ToString((double)value);
|
||||
|
||||
@@ -151,6 +151,21 @@ namespace Umbraco.Core.Persistence.Caching
|
||||
_keyTracker.Remove(key);
|
||||
}
|
||||
|
||||
public void Delete(Type type, int entityId)
|
||||
{
|
||||
var key = GetCompositeId(type, entityId);
|
||||
if (_memoryCache != null)
|
||||
{
|
||||
_memoryCache.Remove(key);
|
||||
}
|
||||
else
|
||||
{
|
||||
HttpRuntime.Cache.Remove(key);
|
||||
}
|
||||
|
||||
_keyTracker.Remove(key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clear cache by type
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Umbraco.Core.Persistence
|
||||
{
|
||||
|
||||
//TODO: Would be good to use this exception type anytime we cannot find an entity
|
||||
|
||||
/// <summary>
|
||||
/// An exception used to indicate that an umbraco entity could not be found
|
||||
/// </summary>
|
||||
public class EntityNotFoundException : Exception
|
||||
{
|
||||
public object Id { get; private set; }
|
||||
private readonly string _msg;
|
||||
|
||||
public EntityNotFoundException(object id, string msg)
|
||||
{
|
||||
Id = id;
|
||||
_msg = msg;
|
||||
}
|
||||
|
||||
public EntityNotFoundException(string msg)
|
||||
{
|
||||
_msg = msg;
|
||||
}
|
||||
|
||||
public override string Message
|
||||
{
|
||||
get { return _msg; }
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var result = base.ToString();
|
||||
|
||||
if (Id != null)
|
||||
{
|
||||
return "Umbraco entity (id: " + Id + ") not found. " + result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
using System;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Factories
|
||||
{
|
||||
internal class MemberGroupFactory : IEntityFactory<IMemberGroup, NodeDto>
|
||||
{
|
||||
|
||||
private readonly Guid _nodeObjectTypeId;
|
||||
|
||||
public MemberGroupFactory()
|
||||
{
|
||||
_nodeObjectTypeId = new Guid(Constants.ObjectTypes.MemberGroup);
|
||||
}
|
||||
|
||||
#region Implementation of IEntityFactory<ITemplate,TemplateDto>
|
||||
|
||||
public IMemberGroup BuildEntity(NodeDto dto)
|
||||
{
|
||||
var template = new MemberGroup
|
||||
{
|
||||
CreateDate = dto.CreateDate,
|
||||
Id = dto.NodeId,
|
||||
Key = dto.UniqueId.Value,
|
||||
Name = dto.Text
|
||||
};
|
||||
|
||||
//on initial construction we don't want to have dirty properties tracked
|
||||
// http://issues.umbraco.org/issue/U4-1946
|
||||
template.ResetDirtyProperties(false);
|
||||
return template;
|
||||
}
|
||||
|
||||
public NodeDto BuildDto(IMemberGroup entity)
|
||||
{
|
||||
var dto = new NodeDto
|
||||
{
|
||||
CreateDate = entity.CreateDate,
|
||||
NodeId = entity.Id,
|
||||
Level = 0,
|
||||
NodeObjectType = _nodeObjectTypeId,
|
||||
ParentId = -1,
|
||||
Path = "",
|
||||
SortOrder = 0,
|
||||
Text = entity.Name,
|
||||
Trashed = false,
|
||||
UniqueId = entity.Key,
|
||||
UserId = entity.CreatorId
|
||||
};
|
||||
|
||||
if (entity.HasIdentity)
|
||||
{
|
||||
dto.NodeId = entity.Id;
|
||||
dto.Path = "-1," + entity.Id;
|
||||
}
|
||||
|
||||
return dto;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
CreateDate = dto.CreateDate,
|
||||
UpdateDate = dto.UpdateDate,
|
||||
Name = dto.Text,
|
||||
ProviderUserKey = dto.UniqueId,
|
||||
ProviderUserKey = dto.NodeId,
|
||||
Trashed = dto.Trashed,
|
||||
Key = dto.UniqueId.Value,
|
||||
CreatorId = dto.UserId.HasValue ? dto.UserId.Value : 0,
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence.Repositories;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Factories
|
||||
{
|
||||
@@ -10,6 +11,8 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
{
|
||||
public IMemberType BuildEntity(MemberTypeReadOnlyDto dto)
|
||||
{
|
||||
var standardPropertyTypes = Constants.Conventions.Member.GetStandardPropertyTypeStubs();
|
||||
|
||||
var memberType = new MemberType(dto.ParentId)
|
||||
{
|
||||
Alias = dto.Alias,
|
||||
@@ -31,12 +34,12 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
AllowedContentTypes = Enumerable.Empty<ContentTypeSort>()
|
||||
};
|
||||
|
||||
var propertyTypeGroupCollection = GetPropertyTypeGroupCollection(dto, memberType);
|
||||
var propertyTypeGroupCollection = GetPropertyTypeGroupCollection(dto, memberType, standardPropertyTypes);
|
||||
memberType.PropertyGroups = propertyTypeGroupCollection;
|
||||
|
||||
var propertyTypes = GetPropertyTypes(dto, memberType);
|
||||
//By Convention we add 9 stnd PropertyTypes - This is only here to support loading of types that didn't have these conventions before.
|
||||
var standardPropertyTypes = Constants.Conventions.Member.StandardPropertyTypeStubs;
|
||||
var propertyTypes = GetPropertyTypes(dto, memberType, standardPropertyTypes);
|
||||
|
||||
//By Convention we add 9 stnd PropertyTypes - This is only here to support loading of types that didn't have these conventions before.
|
||||
foreach (var standardPropertyType in standardPropertyTypes)
|
||||
{
|
||||
if(dto.PropertyTypes.Any(x => x.Alias.Equals(standardPropertyType.Key))) continue;
|
||||
@@ -46,16 +49,17 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
|
||||
//Internal dictionary for adding "MemberCanEdit" and "VisibleOnProfile" properties to each PropertyType
|
||||
memberType.MemberTypePropertyTypes.Add(standardPropertyType.Key,
|
||||
new Tuple<bool, bool, int>(false, false, default(int)));
|
||||
new MemberTypePropertyProfileAccess(false, false));
|
||||
}
|
||||
memberType.PropertyTypes = propertyTypes;
|
||||
|
||||
return memberType;
|
||||
}
|
||||
|
||||
private PropertyGroupCollection GetPropertyTypeGroupCollection(MemberTypeReadOnlyDto dto, MemberType memberType)
|
||||
private PropertyGroupCollection GetPropertyTypeGroupCollection(MemberTypeReadOnlyDto dto, MemberType memberType, Dictionary<string, PropertyType> standardProps)
|
||||
{
|
||||
var propertyGroups = new PropertyGroupCollection();
|
||||
var propertyGroups = new PropertyGroupCollection();
|
||||
|
||||
foreach (var groupDto in dto.PropertyTypeGroups.Where(x => x.Id.HasValue))
|
||||
{
|
||||
var group = new PropertyGroup();
|
||||
@@ -85,11 +89,23 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
{
|
||||
//Internal dictionary for adding "MemberCanEdit" and "VisibleOnProfile" properties to each PropertyType
|
||||
memberType.MemberTypePropertyTypes.Add(typeDto.Alias,
|
||||
new Tuple<bool, bool, int>(typeDto.CanEdit, typeDto.ViewOnProfile, typeDto.Id.Value));
|
||||
new MemberTypePropertyProfileAccess(typeDto.ViewOnProfile, typeDto.CanEdit));
|
||||
|
||||
var tempGroupDto = groupDto;
|
||||
var propertyType = new PropertyType(typeDto.PropertyEditorAlias,
|
||||
typeDto.DbType.EnumParse<DataTypeDatabaseType>(true))
|
||||
|
||||
//ensures that any built-in membership properties have their correct dbtype assigned no matter
|
||||
//what the underlying data type is
|
||||
var propDbType = MemberTypeRepository.GetDbTypeForBuiltInProperty(
|
||||
typeDto.Alias,
|
||||
typeDto.DbType.EnumParse<DataTypeDatabaseType>(true),
|
||||
standardProps);
|
||||
|
||||
var propertyType = new PropertyType(
|
||||
typeDto.PropertyEditorAlias,
|
||||
propDbType.Result,
|
||||
//This flag tells the property type that it has an explicit dbtype and that it cannot be changed
|
||||
// which is what we want for the built-in properties.
|
||||
propDbType.Success)
|
||||
{
|
||||
Alias = typeDto.Alias,
|
||||
DataTypeDefinitionId = typeDto.DataTypeId,
|
||||
@@ -118,32 +134,47 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
return propertyGroups;
|
||||
}
|
||||
|
||||
private List<PropertyType> GetPropertyTypes(MemberTypeReadOnlyDto dto, MemberType memberType)
|
||||
|
||||
|
||||
private List<PropertyType> GetPropertyTypes(MemberTypeReadOnlyDto dto, MemberType memberType, Dictionary<string, PropertyType> standardProps)
|
||||
{
|
||||
//Find PropertyTypes that does not belong to a PropertyTypeGroup
|
||||
var propertyTypes = new List<PropertyType>();
|
||||
foreach (var propertyType in dto.PropertyTypes.Where(x => (x.PropertyTypeGroupId.HasValue == false || x.PropertyTypeGroupId.Value == 0) && x.Id.HasValue))
|
||||
foreach (var typeDto in dto.PropertyTypes.Where(x => (x.PropertyTypeGroupId.HasValue == false || x.PropertyTypeGroupId.Value == 0) && x.Id.HasValue))
|
||||
{
|
||||
//Internal dictionary for adding "MemberCanEdit" and "VisibleOnProfile" properties to each PropertyType
|
||||
memberType.MemberTypePropertyTypes.Add(propertyType.Alias,
|
||||
new Tuple<bool, bool, int>(propertyType.CanEdit, propertyType.ViewOnProfile, propertyType.Id.Value));
|
||||
//PropertyType Collection
|
||||
propertyTypes.Add(new PropertyType(propertyType.PropertyEditorAlias,
|
||||
propertyType.DbType.EnumParse<DataTypeDatabaseType>(true))
|
||||
{
|
||||
Alias = propertyType.Alias,
|
||||
DataTypeDefinitionId = propertyType.DataTypeId,
|
||||
Description = propertyType.Description,
|
||||
HelpText = propertyType.HelpText,
|
||||
Id = propertyType.Id.Value,
|
||||
Mandatory = propertyType.Mandatory,
|
||||
Name = propertyType.Name,
|
||||
SortOrder = propertyType.SortOrder,
|
||||
ValidationRegExp = propertyType.ValidationRegExp,
|
||||
PropertyGroupId = new Lazy<int>(() => default(int)),
|
||||
CreateDate = dto.CreateDate,
|
||||
UpdateDate = dto.CreateDate
|
||||
});
|
||||
memberType.MemberTypePropertyTypes.Add(typeDto.Alias,
|
||||
new MemberTypePropertyProfileAccess(typeDto.ViewOnProfile, typeDto.CanEdit));
|
||||
|
||||
//ensures that any built-in membership properties have their correct dbtype assigned no matter
|
||||
//what the underlying data type is
|
||||
var propDbType = MemberTypeRepository.GetDbTypeForBuiltInProperty(
|
||||
typeDto.Alias,
|
||||
typeDto.DbType.EnumParse<DataTypeDatabaseType>(true),
|
||||
standardProps);
|
||||
|
||||
var propertyType = new PropertyType(
|
||||
typeDto.PropertyEditorAlias,
|
||||
propDbType.Result,
|
||||
//This flag tells the property type that it has an explicit dbtype and that it cannot be changed
|
||||
// which is what we want for the built-in properties.
|
||||
propDbType.Success)
|
||||
{
|
||||
Alias = typeDto.Alias,
|
||||
DataTypeDefinitionId = typeDto.DataTypeId,
|
||||
Description = typeDto.Description,
|
||||
HelpText = typeDto.HelpText,
|
||||
Id = typeDto.Id.Value,
|
||||
Mandatory = typeDto.Mandatory,
|
||||
Name = typeDto.Name,
|
||||
SortOrder = typeDto.SortOrder,
|
||||
ValidationRegExp = typeDto.ValidationRegExp,
|
||||
PropertyGroupId = new Lazy<int>(() => default(int)),
|
||||
CreateDate = dto.CreateDate,
|
||||
UpdateDate = dto.CreateDate
|
||||
};
|
||||
|
||||
propertyTypes.Add(propertyType);
|
||||
}
|
||||
return propertyTypes;
|
||||
}
|
||||
|
||||
@@ -11,17 +11,21 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
private readonly int _id;
|
||||
private readonly DateTime _createDate;
|
||||
private readonly DateTime _updateDate;
|
||||
//a callback to create a property type which can be injected via a contructor
|
||||
private readonly Func<string, DataTypeDatabaseType, string, PropertyType> _propertyTypeCtor;
|
||||
|
||||
public PropertyGroupFactory(int id)
|
||||
{
|
||||
_id = id;
|
||||
_propertyTypeCtor = (propertyEditorAlias, dbType, alias) => new PropertyType(propertyEditorAlias, dbType);
|
||||
}
|
||||
|
||||
public PropertyGroupFactory(int id, DateTime createDate, DateTime updateDate)
|
||||
public PropertyGroupFactory(int id, DateTime createDate, DateTime updateDate, Func<string, DataTypeDatabaseType, string, PropertyType> propertyTypeCtor)
|
||||
{
|
||||
_id = id;
|
||||
_createDate = createDate;
|
||||
_updateDate = updateDate;
|
||||
_propertyTypeCtor = propertyTypeCtor;
|
||||
}
|
||||
|
||||
#region Implementation of IEntityFactory<IEnumerable<PropertyGroup>,IEnumerable<TabDto>>
|
||||
@@ -55,22 +59,23 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
foreach (var typeDto in typeDtos)
|
||||
{
|
||||
var tempGroupDto = groupDto;
|
||||
var propertyType = new PropertyType(typeDto.DataTypeDto.PropertyEditorAlias,
|
||||
typeDto.DataTypeDto.DbType.EnumParse<DataTypeDatabaseType>(true))
|
||||
{
|
||||
Alias = typeDto.Alias,
|
||||
DataTypeDefinitionId = typeDto.DataTypeId,
|
||||
Description = typeDto.Description,
|
||||
Id = typeDto.Id,
|
||||
Name = typeDto.Name,
|
||||
HelpText = typeDto.HelpText,
|
||||
Mandatory = typeDto.Mandatory,
|
||||
SortOrder = typeDto.SortOrder,
|
||||
ValidationRegExp = typeDto.ValidationRegExp,
|
||||
PropertyGroupId = new Lazy<int>(() => tempGroupDto.Id),
|
||||
CreateDate = _createDate,
|
||||
UpdateDate = _updateDate
|
||||
};
|
||||
var propertyType = _propertyTypeCtor(typeDto.DataTypeDto.PropertyEditorAlias,
|
||||
typeDto.DataTypeDto.DbType.EnumParse<DataTypeDatabaseType>(true),
|
||||
typeDto.Alias);
|
||||
|
||||
propertyType.Alias = typeDto.Alias;
|
||||
propertyType.DataTypeDefinitionId = typeDto.DataTypeId;
|
||||
propertyType.Description = typeDto.Description;
|
||||
propertyType.Id = typeDto.Id;
|
||||
propertyType.Name = typeDto.Name;
|
||||
propertyType.HelpText = typeDto.HelpText;
|
||||
propertyType.Mandatory = typeDto.Mandatory;
|
||||
propertyType.SortOrder = typeDto.SortOrder;
|
||||
propertyType.ValidationRegExp = typeDto.ValidationRegExp;
|
||||
propertyType.PropertyGroupId = new Lazy<int>(() => tempGroupDto.Id);
|
||||
propertyType.CreateDate = _createDate;
|
||||
propertyType.UpdateDate = _updateDate;
|
||||
|
||||
//on initial construction we don't want to have dirty properties tracked
|
||||
// http://issues.umbraco.org/issue/U4-1946
|
||||
propertyType.ResetDirtyProperties(false);
|
||||
|
||||
@@ -17,12 +17,12 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
public IRelation BuildEntity(RelationDto dto)
|
||||
{
|
||||
var entity = new Relation(dto.ParentId, dto.ChildId, _relationType)
|
||||
{
|
||||
Comment = dto.Comment,
|
||||
CreateDate = dto.Datetime,
|
||||
Id = dto.Id,
|
||||
UpdateDate = dto.Datetime
|
||||
};
|
||||
{
|
||||
Comment = dto.Comment,
|
||||
CreateDate = dto.Datetime,
|
||||
Id = dto.Id,
|
||||
UpdateDate = dto.Datetime
|
||||
};
|
||||
//on initial construction we don't want to have dirty properties tracked
|
||||
// http://issues.umbraco.org/issue/U4-1946
|
||||
entity.ResetDirtyProperties(false);
|
||||
@@ -32,13 +32,13 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
public RelationDto BuildDto(IRelation entity)
|
||||
{
|
||||
var dto = new RelationDto
|
||||
{
|
||||
ChildId = entity.ChildId,
|
||||
Comment = string.IsNullOrEmpty(entity.Comment) ? string.Empty : entity.Comment,
|
||||
Datetime = entity.CreateDate,
|
||||
ParentId = entity.ParentId,
|
||||
RelationType = entity.RelationType.Id
|
||||
};
|
||||
{
|
||||
ChildId = entity.ChildId,
|
||||
Comment = string.IsNullOrEmpty(entity.Comment) ? string.Empty : entity.Comment,
|
||||
Datetime = entity.CreateDate,
|
||||
ParentId = entity.ParentId,
|
||||
RelationType = entity.RelationType.Id
|
||||
};
|
||||
|
||||
if (entity.HasIdentity)
|
||||
dto.Id = entity.Id;
|
||||
|
||||
@@ -10,11 +10,11 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
public IRelationType BuildEntity(RelationTypeDto dto)
|
||||
{
|
||||
var entity = new RelationType(dto.ChildObjectType, dto.ParentObjectType, dto.Alias)
|
||||
{
|
||||
Id = dto.Id,
|
||||
IsBidirectional = dto.Dual,
|
||||
Name = dto.Name
|
||||
};
|
||||
{
|
||||
Id = dto.Id,
|
||||
IsBidirectional = dto.Dual,
|
||||
Name = dto.Name
|
||||
};
|
||||
//on initial construction we don't want to have dirty properties tracked
|
||||
// http://issues.umbraco.org/issue/U4-1946
|
||||
entity.ResetDirtyProperties(false);
|
||||
@@ -24,14 +24,14 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
public RelationTypeDto BuildDto(IRelationType entity)
|
||||
{
|
||||
var dto = new RelationTypeDto
|
||||
{
|
||||
Alias = entity.Alias,
|
||||
ChildObjectType = entity.ChildObjectType,
|
||||
Dual = entity.IsBidirectional,
|
||||
Name = entity.Name,
|
||||
ParentObjectType = entity.ParentObjectType
|
||||
};
|
||||
if(entity.HasIdentity)
|
||||
{
|
||||
Alias = entity.Alias,
|
||||
ChildObjectType = entity.ChildObjectType,
|
||||
Dual = entity.IsBidirectional,
|
||||
Name = entity.Name,
|
||||
ParentObjectType = entity.ParentObjectType
|
||||
};
|
||||
if (entity.HasIdentity)
|
||||
dto.Id = entity.Id;
|
||||
|
||||
return dto;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
|
||||
@@ -18,24 +19,23 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
|
||||
public IUser BuildEntity(UserDto dto)
|
||||
{
|
||||
var guidId = dto.Id.ToGuid();
|
||||
var user = new User(_userType)
|
||||
{
|
||||
Id = dto.Id,
|
||||
ProfileId = dto.Id,
|
||||
StartContentId = dto.ContentStartId,
|
||||
StartMediaId = dto.MediaStartId.HasValue ? dto.MediaStartId.Value : -1,
|
||||
Password = dto.Password,
|
||||
Username = dto.Login,
|
||||
Name = dto.UserName,
|
||||
IsLockedOut = dto.Disabled,
|
||||
IsApproved = dto.Disabled == false,
|
||||
Email = dto.Email,
|
||||
Language = dto.UserLanguage,
|
||||
NoConsole = dto.NoConsole,
|
||||
|
||||
//NOTE: The default permission come from the user type's default permissions
|
||||
DefaultPermissions = _userType.Permissions
|
||||
};
|
||||
{
|
||||
Id = dto.Id,
|
||||
Key = guidId,
|
||||
StartContentId = dto.ContentStartId,
|
||||
StartMediaId = dto.MediaStartId.HasValue ? dto.MediaStartId.Value : -1,
|
||||
Password = dto.Password,
|
||||
Username = dto.Login,
|
||||
Name = dto.UserName,
|
||||
IsLockedOut = dto.NoConsole,
|
||||
IsApproved = dto.Disabled == false,
|
||||
Email = dto.Email,
|
||||
Language = dto.UserLanguage,
|
||||
//NOTE: The default permission come from the user type's default permissions
|
||||
DefaultPermissions = _userType.Permissions
|
||||
};
|
||||
|
||||
foreach (var app in dto.User2AppDtos)
|
||||
{
|
||||
@@ -58,7 +58,7 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
Disabled = entity.IsApproved == false,
|
||||
Email = entity.Email,
|
||||
Login = entity.Username,
|
||||
NoConsole = entity.NoConsole,
|
||||
NoConsole = entity.IsLockedOut,
|
||||
Password = entity.Password,
|
||||
UserLanguage = entity.Language,
|
||||
UserName = entity.Name,
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using Umbraco.Core.Models.Membership;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Factories
|
||||
@@ -10,12 +12,14 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
public IUserType BuildEntity(UserTypeDto dto)
|
||||
{
|
||||
var userType = new UserType
|
||||
{
|
||||
Alias = dto.Alias,
|
||||
Id = dto.Id,
|
||||
Name = dto.Name,
|
||||
Permissions = dto.DefaultPermissions
|
||||
};
|
||||
{
|
||||
Alias = dto.Alias,
|
||||
Id = dto.Id,
|
||||
Name = dto.Name,
|
||||
Permissions = dto.DefaultPermissions.IsNullOrWhiteSpace()
|
||||
? Enumerable.Empty<string>()
|
||||
: dto.DefaultPermissions.ToCharArray().Select(x => x.ToString(CultureInfo.InvariantCulture))
|
||||
};
|
||||
//on initial construction we don't want to have dirty properties tracked
|
||||
// http://issues.umbraco.org/issue/U4-1946
|
||||
userType.ResetDirtyProperties(false);
|
||||
@@ -27,7 +31,7 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
var userType = new UserTypeDto
|
||||
{
|
||||
Alias = entity.Alias,
|
||||
DefaultPermissions = entity.Permissions,
|
||||
DefaultPermissions = entity.Permissions == null ? "" : string.Join("", entity.Permissions),
|
||||
Name = entity.Name
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
using System.Collections.Concurrent;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Mappers
|
||||
{
|
||||
[MapperFor(typeof (IMemberGroup))]
|
||||
[MapperFor(typeof (MemberGroup))]
|
||||
public sealed class MemberGroupMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCacheInstance = new ConcurrentDictionary<string, DtoMapModel>();
|
||||
|
||||
//NOTE: its an internal class but the ctor must be public since we're using Activator.CreateInstance to create it
|
||||
// otherwise that would fail because there is no public constructor.
|
||||
public MemberGroupMapper()
|
||||
{
|
||||
BuildMap();
|
||||
}
|
||||
|
||||
internal override ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache
|
||||
{
|
||||
get { return PropertyInfoCacheInstance; }
|
||||
}
|
||||
|
||||
internal override void BuildMap()
|
||||
{
|
||||
CacheMap<MemberGroup, NodeDto>(src => src.Id, dto => dto.NodeId);
|
||||
CacheMap<MemberGroup, NodeDto>(src => src.CreateDate, dto => dto.CreateDate);
|
||||
CacheMap<MemberGroup, NodeDto>(src => src.CreatorId, dto => dto.UserId);
|
||||
CacheMap<MemberGroup, NodeDto>(src => src.Name, dto => dto.Text);
|
||||
CacheMap<MemberGroup, NodeDto>(src => src.Key, dto => dto.UniqueId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -39,7 +39,7 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
CacheMap<Relation, RelationDto>(src => src.ParentId, dto => dto.ParentId);
|
||||
CacheMap<Relation, RelationDto>(src => src.RelationTypeId, dto => dto.RelationType);
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -39,7 +39,7 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
CacheMap<RelationType, RelationTypeDto>(src => src.Name, dto => dto.Name);
|
||||
CacheMap<RelationType, RelationTypeDto>(src => src.ParentObjectType, dto => dto.ParentObjectType);
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -38,7 +38,7 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
CacheMap<User, UserDto>(src => src.StartMediaId, dto => dto.MediaStartId);
|
||||
CacheMap<User, UserDto>(src => src.StartContentId, dto => dto.ContentStartId);
|
||||
CacheMap<User, UserDto>(src => src.IsApproved, dto => dto.Disabled);
|
||||
CacheMap<User, UserDto>(src => src.NoConsole, dto => dto.NoConsole);
|
||||
CacheMap<User, UserDto>(src => src.IsLockedOut, dto => dto.NoConsole);
|
||||
CacheMap<User, UserDto>(src => src.UserType, dto => dto.Type);
|
||||
CacheMap<User, UserDto>(src => src.Language, dto => dto.UserLanguage);
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
|
||||
_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 1036, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,1036", SortOrder = 2, UniqueId = new Guid("2b24165f-9782-4aa3-b459-1de4a4d21f60"), Text = "Member Picker", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now });
|
||||
_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 1040, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,1040", SortOrder = 2, UniqueId = new Guid("21e798da-e06e-4eda-a511-ed257f78d4fa"), Text = "Related Links", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now });
|
||||
_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 1041, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,1041", SortOrder = 2, UniqueId = new Guid("b6b73142-b9c1-4bf8-a16d-e1c23320b549"), Text = "Tags", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now });
|
||||
_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 1044, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,1044", SortOrder = 0, UniqueId = new Guid("d59be02f-1df9-4228-aa1e-01917d806cda"), Text = Constants.Conventions.MemberTypes.Member, NodeObjectType = new Guid(Constants.ObjectTypes.MemberType), CreateDate = DateTime.Now });
|
||||
_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 1044, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,1044", SortOrder = 0, UniqueId = new Guid("d59be02f-1df9-4228-aa1e-01917d806cda"), Text = Constants.Conventions.MemberTypes.DefaultAlias, NodeObjectType = new Guid(Constants.ObjectTypes.MemberType), CreateDate = DateTime.Now });
|
||||
_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 1045, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,1045", SortOrder = 2, UniqueId = new Guid("7E3962CC-CE20-4FFC-B661-5897A894BA7E"), Text = "Multiple Media Picker", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now });
|
||||
|
||||
//TODO: We're not creating these for 7.0
|
||||
@@ -135,7 +135,7 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
|
||||
_database.Insert("cmsContentType", "pk", false, new ContentTypeDto { PrimaryKey = 532, NodeId = 1031, Alias = Constants.Conventions.MediaTypes.Folder, Icon = "icon-folder", Thumbnail = "folder.png", IsContainer = false, AllowAtRoot = true });
|
||||
_database.Insert("cmsContentType", "pk", false, new ContentTypeDto { PrimaryKey = 533, NodeId = 1032, Alias = Constants.Conventions.MediaTypes.Image, Icon = "icon-picture", Thumbnail = "mediaPhoto.png" });
|
||||
_database.Insert("cmsContentType", "pk", false, new ContentTypeDto { PrimaryKey = 534, NodeId = 1033, Alias = Constants.Conventions.MediaTypes.File, Icon = "icon-document", Thumbnail = "mediaFile.png" });
|
||||
_database.Insert("cmsContentType", "pk", false, new ContentTypeDto { PrimaryKey = 531, NodeId = 1044, Alias = Constants.Conventions.MemberTypes.Member, Icon = "icon-user", Thumbnail = "folder.png" });
|
||||
_database.Insert("cmsContentType", "pk", false, new ContentTypeDto { PrimaryKey = 531, NodeId = 1044, Alias = Constants.Conventions.MemberTypes.DefaultAlias, Icon = "icon-user", Thumbnail = "folder.png" });
|
||||
}
|
||||
|
||||
private void CreateUmbracoUserData()
|
||||
|
||||
@@ -79,7 +79,10 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
|
||||
|
||||
try
|
||||
{
|
||||
_database.DropTable(tableName);
|
||||
if (_database.TableExist(tableName))
|
||||
{
|
||||
_database.DropTable(tableName);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user