Compare commits
895 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 08d74e3320 | |||
| 98fd75b55d | |||
| e7da70e076 | |||
| 200cec0e23 | |||
| 807778a737 | |||
| 66d61c9d20 | |||
| ecae5a856a | |||
| bf8add4f8d | |||
| 256fa3385a | |||
| ebaa46b2fc | |||
| e207185d51 | |||
| 5efc45a7dd | |||
| c3fc27565d | |||
| 0af3f9dce0 | |||
| 426b02b08a | |||
| a4e23ef82b | |||
| d0c6c4aafa | |||
| 3ea7e6fb8a | |||
| 9940b78a57 | |||
| 8371105c10 | |||
| d4b0f3c570 | |||
| 29416320d2 | |||
| d11eb485e1 | |||
| 300bd3bed4 | |||
| 3ca5443350 | |||
| f6d56f51d4 | |||
| 53c0bd6938 | |||
| 174aa9f4ad | |||
| a768fe5bb3 | |||
| d9c66cd4b3 | |||
| 6d3e8e1f6d | |||
| b6185b847f | |||
| c8877d0a2c | |||
| 891810b045 | |||
| 77d910b6b6 | |||
| 47044b3a77 | |||
| 5b693f9310 | |||
| 40ebc1295c | |||
| b769b224c2 | |||
| 89efe40f41 | |||
| 51660d918c | |||
| ea7b053106 | |||
| 3e17201ce7 | |||
| 1f03983628 | |||
| 15aa6fc4b8 | |||
| 41e8a9ef2d | |||
| a492976a32 | |||
| 88e09f9077 | |||
| 65a1709bd3 | |||
| 6478a8424a | |||
| 55ade4e491 | |||
| a767aa9f3a | |||
| 50321e5936 | |||
| 1321702d19 | |||
| 005ff2f830 | |||
| dff3fde840 | |||
| 44504ff6af | |||
| 25d3389759 | |||
| 3f97c74712 | |||
| 1152b61fb0 | |||
| b1842de045 | |||
| 750a2862ee | |||
| 7632075df4 | |||
| aa75cd4ea8 | |||
| 06827bd7a5 | |||
| 9a82ab7d4a | |||
| b1037d1936 | |||
| ccdc3a1eab | |||
| a47387fec0 | |||
| c29d08c915 | |||
| b8f796eb2c | |||
| b9088c9ac0 | |||
| 7a8f8ac0fe | |||
| 49cf0f98ce | |||
| 22ffa86e18 | |||
| c4e2d98138 | |||
| c01211c62d | |||
| d8a3e00440 | |||
| 264c537b50 | |||
| f26c61d736 | |||
| 43f647fd94 | |||
| cc0bcc2d59 | |||
| 1b23540b87 | |||
| c309e18f13 | |||
| dec60885b4 | |||
| eee09ec45b | |||
| b4daab2856 | |||
| fdfbad254d | |||
| 0c6e766030 | |||
| 7444363cef | |||
| a82097b92b | |||
| 07934161a4 | |||
| 9194030a9a | |||
| 1cbaace777 | |||
| ef5052324b | |||
| 204a8d813c | |||
| 8009cb3892 | |||
| 284d168cd7 | |||
| fdd025aefd | |||
| e36d4768e1 | |||
| df2047e8f8 | |||
| d9280d5238 | |||
| 388249f500 | |||
| a08b75592e | |||
| 38ea6dfbfe | |||
| 39ccde221a | |||
| 17b6366ea3 | |||
| 3d6a608b12 | |||
| 851f58df9c | |||
| 0ff0cc6366 | |||
| 08004ecc68 | |||
| 4a2544d0e6 | |||
| bace1cce74 | |||
| acc88e25d8 | |||
| 2a1a16d478 | |||
| a5afb8ed19 | |||
| d02678e05c | |||
| 9e0bbd3c99 | |||
| 539efcc669 | |||
| d0d9d85151 | |||
| ffa307613c | |||
| 19ea6d6005 | |||
| 155b1737d3 | |||
| b66253f33e | |||
| bcbadfe648 | |||
| 3325b06873 | |||
| 852914bf6b | |||
| 3e14807370 | |||
| e44cb6708d | |||
| fd43b27d00 | |||
| 524f113611 | |||
| 04dcf50218 | |||
| 2b497deaa3 | |||
| dbe2f8ea37 | |||
| 7dc0239ad1 | |||
| 72fdc5f472 | |||
| cde3c42cec | |||
| 10b544abb9 | |||
| 88aecdf672 | |||
| ad95736eaa | |||
| 34a21a78a0 | |||
| 1e01c2669f | |||
| d3a7389b89 | |||
| bc8b6c4bea | |||
| 3953a48a3b | |||
| 2f44e94bd0 | |||
| 5eeb8d7df6 | |||
| 231f23cc6e | |||
| 3235678d29 | |||
| f13ddddc16 | |||
| 490c346fcf | |||
| 8f1d8419a0 | |||
| be8320bb4b | |||
| 1d4b6178e5 | |||
| 3427f596e3 | |||
| c31ea7409f | |||
| f88e60bcb5 | |||
| c81919e269 | |||
| c936aaa517 | |||
| b8f88e0459 | |||
| 1628ac917c | |||
| ab586a49ce | |||
| ff2ee540e2 | |||
| b450299d45 | |||
| 0ebe535922 | |||
| f5f8fe7b42 | |||
| f51a66b728 | |||
| f8a7b453c7 | |||
| 89235f707c | |||
| 550166c41b | |||
| 40be3957f6 | |||
| 6ccce4d914 | |||
| 14ea374b24 | |||
| 4d49268c47 | |||
| a569796adb | |||
| 59de0613f5 | |||
| 8391c32886 | |||
| bf2efd30e9 | |||
| 187373132f | |||
| 79584a9cf9 | |||
| 96fa8c7dc9 | |||
| 5e43ddc13c | |||
| 98f76a989f | |||
| 2e8993adb8 | |||
| 81600f0f3c | |||
| 74ccd79408 | |||
| 3e0a754dc0 | |||
| 006a89e136 | |||
| 29dbbee173 | |||
| cd31637371 | |||
| ab70c98d4c | |||
| 424ff02734 | |||
| 80bd8d962b | |||
| 4b4efde490 | |||
| 956364decd | |||
| 7bc2bdae75 | |||
| c43ab7942a | |||
| 166f9b939c | |||
| ede9e00a7f | |||
| 0bfbacfd66 | |||
| 5c5827e319 | |||
| 05ca98219d | |||
| a83a0f1e25 | |||
| ea7d476559 | |||
| 2d2f57a71b | |||
| 6133e8f8c2 | |||
| bfaace373c | |||
| a6d24fce93 | |||
| 7e8aaebfce | |||
| 6a3fb87499 | |||
| 74cad56a6b | |||
| 9b02457f7a | |||
| 6077e24685 | |||
| 39a3a9dc56 | |||
| 801a3731a2 | |||
| bcb7561e74 | |||
| f077520781 | |||
| 61ec1e4c35 | |||
| 3710c0916c | |||
| 863667f5bd | |||
| 7475851bb5 | |||
| a721ed5e0f | |||
| 0bc621c40f | |||
| 620fbde1db | |||
| 39e7947435 | |||
| 2792937b17 | |||
| af9a9a9a7a | |||
| 83f4c0262e | |||
| 08d4ce7667 | |||
| 2340adbe94 | |||
| fb6b234491 | |||
| 15222e176e | |||
| 63b92eaee5 | |||
| 84dd7dc61a | |||
| 5a4b09f9d1 | |||
| bbbd03f001 | |||
| 4a721ddf34 | |||
| d88745bf49 | |||
| 3543204794 | |||
| c565744a9b | |||
| 2470ec3ded | |||
| 7b4f7abbcd | |||
| 1573eb2f74 | |||
| e8e8b536f1 | |||
| 704c3df597 | |||
| 36c107c0ef | |||
| 70f5641b83 | |||
| bbb5fe728a | |||
| 307ea6bd74 | |||
| 76eb06784d | |||
| c6e1235ac4 | |||
| 6ac2cc9f8b | |||
| 9d5c8e5aed | |||
| 56001a8ccb | |||
| ff5dadde53 | |||
| 6d92393f08 | |||
| 6169d13eb5 | |||
| 361c382a2e | |||
| 375b3948e0 | |||
| 6453a82717 | |||
| a4c9fae05c | |||
| 29edbb90a6 | |||
| 71201970e9 | |||
| 992727821b | |||
| 67fd3cc234 | |||
| f70717985c | |||
| ded82611a7 | |||
| 6a8cb5e123 | |||
| 09428d703c | |||
| 2b6b8e9e8c | |||
| a46c088d0c | |||
| 65e591501c | |||
| a0541b000e | |||
| 1f6b139cde | |||
| 17893715fc | |||
| a25e6e0d2c | |||
| 668935548d | |||
| 14141fcaa5 | |||
| 1948fe12b3 | |||
| 4bcf3983c5 | |||
| 7c5942b05f | |||
| 8b4d4e3189 | |||
| 4f008f5848 | |||
| 1a40ccc838 | |||
| 0bf43da825 | |||
| c83db52bd7 | |||
| 00e1556504 | |||
| 5c8440a7d6 | |||
| 3e86fb6298 | |||
| 9b0895c5b0 | |||
| 4ad9ea1537 | |||
| 0b08f19f53 | |||
| 527402a6d8 | |||
| 9eea8c85e0 | |||
| e80963093d | |||
| 6f586c7eeb | |||
| ff3b5baf06 | |||
| 0749124f45 | |||
| 549aeecf31 | |||
| bef970437a | |||
| 0898b13072 | |||
| dda36f0147 | |||
| 9d3f362029 | |||
| 4d13925e3b | |||
| 02481dcfba | |||
| caad775399 | |||
| fd14065f14 | |||
| 7a7720c460 | |||
| b2aeb835d5 | |||
| 8dd950bd52 | |||
| e2881e07d1 | |||
| e0e0076a7a | |||
| 00a96a4888 | |||
| b16cf375b9 | |||
| a3b433c73c | |||
| 855a4961dd | |||
| 71de4dc7de | |||
| 19d3c06470 | |||
| e22476f54a | |||
| 20ae16b2d7 | |||
| 9e466971af | |||
| 7017d8094d | |||
| 0e40971178 | |||
| 1ae9816c28 | |||
| e40cf3b8fc | |||
| 09ea82b37f | |||
| c44918f830 | |||
| 760dd42c43 | |||
| 0409192892 | |||
| d575eaa9c1 | |||
| 373e9755ed | |||
| d6f00d9367 | |||
| 3cabec84d4 | |||
| c9d12f7dc5 | |||
| 9e97b84fb8 | |||
| f4fa090857 | |||
| 0e22a2bb5a | |||
| 36b10e71d7 | |||
| 3c6029c969 | |||
| a4a0de3503 | |||
| 217267bf94 | |||
| 4748366766 | |||
| de15dc36e7 | |||
| ab00782d84 | |||
| 2d6d95a63e | |||
| d19d1b3a18 | |||
| 5a779c24d0 | |||
| c669a2702b | |||
| f777f1b3d6 | |||
| 3e8ada24e4 | |||
| fe884b2070 | |||
| 30cfa4c0ae | |||
| 66aa3084f9 | |||
| d028ee2c3e | |||
| 2bd5e908db | |||
| 154652c896 | |||
| a60e2318ad | |||
| f642a7fd63 | |||
| b4cce4860f | |||
| d1d54d8e84 | |||
| bbeedb6c1b | |||
| 4745995f92 | |||
| c66aca2d41 | |||
| af148a4544 | |||
| d7ea8e02d6 | |||
| 3acec1dd65 | |||
| e52f8dcbc9 | |||
| 60edf7d3b9 | |||
| f626738174 | |||
| ad3c004d95 | |||
| 58814d4ac2 | |||
| c29dbf444a | |||
| bd06729619 | |||
| bd1dc4f88d | |||
| 67c1cc44c5 | |||
| b680f87c12 | |||
| 8db6633c91 | |||
| 8843f6c02c | |||
| 6561a79b5c | |||
| 3e5128147c | |||
| 64c126ea61 | |||
| 3dcbcba9cf | |||
| b5329ace3b | |||
| e1a134f587 | |||
| 1ec2901762 | |||
| 58bfb6999d | |||
| e8056de589 | |||
| bbe6194b06 | |||
| 06a08be6de | |||
| f1e8e845a2 | |||
| 20c5be0a8e | |||
| 6990c46262 | |||
| 099c558797 | |||
| d76fd7d25e | |||
| e020989577 | |||
| f2541cae86 | |||
| a907b5bdcd | |||
| 7258964bb7 | |||
| d290ffa306 | |||
| 75bc3e09c6 | |||
| bcc2424577 | |||
| 67f8b8f88b | |||
| 2d44650139 | |||
| 8eaea3fb54 | |||
| 2166a4a5ac | |||
| 3ba6391dda | |||
| 8574c6b7d0 | |||
| b533a9f690 | |||
| 221bfa5f3d | |||
| 85a74e4fa7 | |||
| 62d4bff8aa | |||
| 095be823c6 | |||
| a8858ecfdd | |||
| 9c48330aae | |||
| 22792a2f8e | |||
| 0dc00a62e2 | |||
| 0c4e442578 | |||
| 9d7d866467 | |||
| 3b26834484 | |||
| aee10348e5 | |||
| d0fc3ddba5 | |||
| 3aadca167f | |||
| 3a92c26a7f | |||
| 6a4ea56dc5 | |||
| cdd6768966 | |||
| d89205abaf | |||
| ff21379547 | |||
| 74f00a9f89 | |||
| 3912300f83 | |||
| c8ff708a43 | |||
| 693899935b | |||
| 1a87d96f77 | |||
| 0a959b5b84 | |||
| f2202eb337 | |||
| 19b7a9dfff | |||
| f432e23a47 | |||
| 20d92432b2 | |||
| 59cdb8a6fe | |||
| aed4c1faed | |||
| 2ecab70772 | |||
| 894a649574 | |||
| 48bbf1ecb2 | |||
| 5dc44ca612 | |||
| 3c771648e3 | |||
| c500d29029 | |||
| 2c8fe5a130 | |||
| d737afa327 | |||
| 2db1c1bb40 | |||
| d95ca7bc6f | |||
| 6b491ac6cd | |||
| 278b681501 | |||
| abd72e7676 | |||
| ec6cb4520c | |||
| 2dfa85c9b4 | |||
| 921a5963e2 | |||
| 3626d5b79d | |||
| 980e8e84a6 | |||
| 4070669e7d | |||
| b20e61d316 | |||
| fb764641c5 | |||
| 405727f1ac | |||
| 6446f63dcb | |||
| f1963fb404 | |||
| c26b72bd10 | |||
| b94cee68e7 | |||
| b67fbbcbd8 | |||
| 71fcc77e9b | |||
| 38509f9d5a | |||
| 3ff04f585c | |||
| 3de8f9bd18 | |||
| c95e7c245e | |||
| fce31a2e02 | |||
| 4d3eef1124 | |||
| 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 | |||
| b048ae4d36 | |||
| 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 | |||
| 366697f4eb | |||
| 987644379e | |||
| f168093b92 | |||
| 1e45abe71e | |||
| a556b4ed21 | |||
| 953c711ca4 | |||
| f06c9e8235 | |||
| f1a439e851 | |||
| 20c2574f94 | |||
| ab4c58b3a3 | |||
| cb63642ce9 | |||
| 3fb756939e | |||
| ec14a16aec | |||
| 6944f25c9f | |||
| 45c7699a33 | |||
| 2bd2f12831 | |||
| a0e496e589 | |||
| e0dcc3afbc | |||
| a4b1b31a24 | |||
| 3634a77d61 | |||
| 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 | |||
| aad0e73fea | |||
| 7d7fcd2093 | |||
| 3ef51d7357 | |||
| 8b553dd067 | |||
| c52123e878 | |||
| 4e6ca57f7a | |||
| ce9cfbf071 | |||
| 8024bde429 | |||
| 9ce79e98a3 | |||
| 3e5553d9b0 | |||
| ccaf82d797 | |||
| 5047c7bbe7 | |||
| 0c45fb1b97 | |||
| 7bd745a870 | |||
| 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 | |||
| 4a095184bb | |||
| 2a81162756 | |||
| 0a7526601c | |||
| 3e22598f4a | |||
| d842f0f5b7 | |||
| 8258619055 | |||
| 7d2f6c13c3 | |||
| b314bff127 | |||
| d66e2e52e9 | |||
| 43c426b46c | |||
| 0714aaa457 | |||
| 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 | |||
| 88182edf8f | |||
| e456dd3886 | |||
| c2c4763faa | |||
| c062d3b71b | |||
| ed83fb8216 | |||
| 80601abb27 | |||
| 79384d8a0a | |||
| 793a1a9aa8 | |||
| e3da493345 | |||
| f674fdf014 | |||
| 6eeb9d6af4 | |||
| cbefabb724 | |||
| f7f6cc64ce | |||
| 1408e4f64e | |||
| 0a68d2f4ee | |||
| 11a4a0436d | |||
| 2583800b2c | |||
| 067268a96e |
@@ -108,3 +108,4 @@ 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/*
|
||||
@@ -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>
|
||||
+5
-1
@@ -1,5 +1,5 @@
|
||||
@ECHO OFF
|
||||
SET release=7.0.4
|
||||
SET release=7.1.0
|
||||
SET comment=
|
||||
SET version=%release%
|
||||
|
||||
@@ -12,6 +12,9 @@ ECHO Installing the Microsoft.Bcl.Build package before anything else, otherwise
|
||||
SET nuGetFolder=%CD%\..\src\packages\
|
||||
..\src\.nuget\NuGet.exe install ..\src\Umbraco.Web.UI\packages.config -OutputDirectory %nuGetFolder%
|
||||
|
||||
ECHO Removing the belle build folder to make sure everything is clean as a whistle
|
||||
RD ..\src\Umbraco.Web.UI.Client\build /Q /S
|
||||
|
||||
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%
|
||||
|
||||
@@ -30,6 +33,7 @@ echo This file is only here so that the containing folder will be included in th
|
||||
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
|
||||
ren .\_BuildOutput\WebApp\Xslt\Web.config Web.config.transform
|
||||
|
||||
ECHO Packing the NuGet release files
|
||||
..\src\.nuget\NuGet.exe pack NuSpecs\UmbracoCms.Core.nuspec -Version %version%
|
||||
|
||||
+11
-1
@@ -310,7 +310,12 @@
|
||||
</Target>
|
||||
|
||||
<Target Name="SetVersionNumber" Condition="'$(BUILD_RELEASE)'!=''">
|
||||
<!-- Match & replace 3 and 4 digit version numbers and -beta (if it's there) -->
|
||||
<PropertyGroup>
|
||||
<NewVersion>$(BUILD_RELEASE)</NewVersion>
|
||||
<NewVersion Condition="'$(BUILD_COMMENT)'!=''">$(BUILD_RELEASE)-$(BUILD_COMMENT)</NewVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Match & replace 3 and 4 digit version numbers and -beta (if it's there) -->
|
||||
<FileUpdate
|
||||
Files="..\src\Umbraco.Core\Configuration\UmbracoVersion.cs"
|
||||
Regex="(\d+)\.(\d+)\.(\d+)(.(\d+))?"
|
||||
@@ -319,5 +324,10 @@
|
||||
<FileUpdate Files="..\src\Umbraco.Core\Configuration\UmbracoVersion.cs"
|
||||
Regex="CurrentComment { get { return "([a-zA-Z]+)?""
|
||||
ReplacementText="CurrentComment { get { return "$(BUILD_COMMENT)""/>
|
||||
|
||||
<XmlPoke XmlInputPath=".\NuSpecs\build\UmbracoCms.targets"
|
||||
Namespaces="<Namespace Prefix='x' Uri='http://schemas.microsoft.com/developer/msbuild/2003' />"
|
||||
Query="//x:UmbracoVersion"
|
||||
Value="$(NewVersion)" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -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!"
|
||||
@@ -4,7 +4,7 @@
|
||||
<id>UmbracoCms.Core</id>
|
||||
<version>7.0.0</version>
|
||||
<title>Umbraco Cms Core Binaries</title>
|
||||
<authors>Morten Christensen</authors>
|
||||
<authors>Umbraco HQ</authors>
|
||||
<owners>Umbraco HQ</owners>
|
||||
<licenseUrl>http://umbraco.codeplex.com/license</licenseUrl>
|
||||
<projectUrl>http://umbraco.com/</projectUrl>
|
||||
@@ -16,8 +16,8 @@
|
||||
<tags>umbraco</tags>
|
||||
<dependencies>
|
||||
<dependency id="Microsoft.AspNet.Mvc" version="[4.0.0,5.0.0)" />
|
||||
<dependency id="Microsoft.AspNet.WebApi" version="[4.0.0,5.0.0)" />
|
||||
<dependency id="Microsoft.AspNet.WebApi.Client" version="[4.0.0, 5.0.0)" />
|
||||
<dependency id="Microsoft.AspNet.WebApi" version="[4.0.30506,5.0.0)" />
|
||||
<dependency id="Microsoft.AspNet.WebApi.Client" version="[4.0.30506, 5.0.0)" />
|
||||
<dependency id="Microsoft.AspNet.Mvc.FixedDisplayModes" version="1.0.0" />
|
||||
<dependency id="Microsoft.Net.Http" version="[2.0.0, 3.0.0)" />
|
||||
<dependency id="MiniProfiler" version="[2.1.0, 3.0.0)" />
|
||||
@@ -26,16 +26,17 @@
|
||||
<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-Mvc" version="[1.7.0, 2.0.0)" />
|
||||
<dependency id="ClientDependency" version="[1.7.1.2, 2.0.0)" />
|
||||
<dependency id="ClientDependency-Mvc" version="[1.7.0.4, 2.0.0)" />
|
||||
<dependency id="AutoMapper" version="[3.0.0, 4.0.0)" />
|
||||
<dependency id="Newtonsoft.Json" version="[4.5.11, 5.0.0)" />
|
||||
<dependency id="ImageProcessor" version="[1.8.7, 2.0.0)" />
|
||||
<dependency id="ImageProcessor.Web" version="[3.2.1, 4.0.0)" />
|
||||
</dependencies>
|
||||
</metadata>
|
||||
<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" />
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<id>UmbracoCms</id>
|
||||
<version>7.0.0</version>
|
||||
<title>Umbraco Cms</title>
|
||||
<authors>Morten Christensen</authors>
|
||||
<authors>Umbraco HQ</authors>
|
||||
<owners>Umbraco HQ</owners>
|
||||
<licenseUrl>http://umbraco.codeplex.com/license</licenseUrl>
|
||||
<projectUrl>http://umbraco.com/</projectUrl>
|
||||
@@ -19,8 +19,6 @@
|
||||
</dependencies>
|
||||
</metadata>
|
||||
<files>
|
||||
<file src="..\_BuildOutput\WebApp\bin\amd64\**" target="Content\bin\amd64" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\x86\**" target="Content\bin\x86" />
|
||||
<file src="..\_BuildOutput\Configs\**" target="Content\config" exclude="..\_BuildOutput\Configs\Web.config.transform" />
|
||||
<file src="..\_BuildOutput\WebApp\css\**" target="Content\css" />
|
||||
<file src="..\_BuildOutput\WebApp\macroScripts\**" target="Content\macroScripts" exclude="..\_BuildOutput\WebApp\macroScripts\Web.config" />
|
||||
@@ -32,15 +30,14 @@
|
||||
<file src="..\_BuildOutput\WebApp\xslt\**" target="Content\xslt" />
|
||||
<file src="..\_BuildOutput\WebApp\default.aspx" target="Content\default.aspx" />
|
||||
<file src="..\_BuildOutput\WebApp\Web.config" target="Content\Web.config" />
|
||||
<file src="..\_BuildOutput\WebApp\Global.asax" target="Content\Global.asax" />
|
||||
<file src="..\_BuildOutput\WebApp\App_Browsers\**" target="UmbracoFiles\App_Browsers" />
|
||||
<file src="..\_BuildOutput\WebApp\App_Code\**" target="UmbracoFiles\App_Code" />
|
||||
<file src="..\_BuildOutput\WebApp\App_Data\**" target="UmbracoFiles\App_Data" />
|
||||
<file src="..\_BuildOutput\WebApp\App_Plugins\**" target="UmbracoFiles\App_Plugins" />
|
||||
<file src="..\_BuildOutput\WebApp\App_Plugins\**" target="UmbracoFiles\App_Plugins" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\amd64\**" target="UmbracoFiles\bin\amd64" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\x86\**" target="UmbracoFiles\bin\x86" />
|
||||
<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" />
|
||||
<file src="..\_BuildOutput\WebApp\Web.config" target="UmbracoFiles\Web.config" />
|
||||
<file src="tools\install.ps1" target="tools\install.ps1" />
|
||||
<file src="tools\Readme.txt" target="tools\Readme.txt" />
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<CopyAllFilesToSingleFolderForPackageDependsOn>
|
||||
AddUmbracoFilesToOutput;
|
||||
$(CopyAllFilesToSingleFolderForPackageDependsOn);
|
||||
</CopyAllFilesToSingleFolderForPackageDependsOn>
|
||||
|
||||
<CopyAllFilesToSingleFolderForMsdeployDependsOn>
|
||||
AddUmbracoFilesToOutput;
|
||||
$(CopyAllFilesToSingleFolderForPackageDependsOn);
|
||||
</CopyAllFilesToSingleFolderForMsdeployDependsOn>
|
||||
</PropertyGroup>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<CopyAllFilesToSingleFolderForPackageDependsOn>
|
||||
AddUmbracoFilesToOutput;
|
||||
$(CopyAllFilesToSingleFolderForPackageDependsOn);
|
||||
</CopyAllFilesToSingleFolderForPackageDependsOn>
|
||||
|
||||
<CopyAllFilesToSingleFolderForMsdeployDependsOn>
|
||||
AddUmbracoFilesToOutput;
|
||||
$(CopyAllFilesToSingleFolderForPackageDependsOn);
|
||||
</CopyAllFilesToSingleFolderForMsdeployDependsOn>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<UmbracoVersion>7.1.0</UmbracoVersion>
|
||||
</PropertyGroup>
|
||||
<Target Name="CopyUmbracoFilesToWebRoot" BeforeTargets="AfterBuild">
|
||||
<PropertyGroup>
|
||||
<UmbracoFilesFolder>..\packages\UmbracoCms.$(UmbracoVersion)\UmbracoFiles\</UmbracoFilesFolder>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<UmbracoFiles Include="$(UmbracoFilesFolder)**\*" />
|
||||
</ItemGroup>
|
||||
<Copy SourceFiles="%(UmbracoFiles.FullPath)" DestinationFiles="%(RecursiveDir)%(Filename)%(Extension)" Condition="!Exists('%(RecursiveDir)%(Filename)%(Extension)')" />
|
||||
</Target>
|
||||
<Target Name="AddUmbracoFilesToOutput">
|
||||
<!-- With help from: http://blog.samstephens.co.nz/2010-10-18/msbuild-including-extra-files-multiple-builds/ -->
|
||||
<ItemGroup>
|
||||
<CustomFilesToInclude Include=".\App_Browsers\**\*">
|
||||
<Dir>App_Browsers</Dir>
|
||||
</CustomFilesToInclude>
|
||||
<CustomFilesToInclude Include=".\App_Code\**\*">
|
||||
<Dir>App_Code</Dir>
|
||||
</CustomFilesToInclude>
|
||||
<CustomFilesToInclude Include=".\App_Plugins\**\*">
|
||||
<Dir>App_Plugins</Dir>
|
||||
</CustomFilesToInclude>
|
||||
<CustomFilesToInclude Include=".\bin\amd64\**\*">
|
||||
<Dir>bin\amd64</Dir>
|
||||
</CustomFilesToInclude>
|
||||
<CustomFilesToInclude Include=".\bin\x86\**\*">
|
||||
<Dir>bin\x86</Dir>
|
||||
</CustomFilesToInclude>
|
||||
<CustomFilesToInclude Include=".\Config\Splashes\**\*">
|
||||
<Dir>Config\Splashes</Dir>
|
||||
</CustomFilesToInclude>
|
||||
<CustomFilesToInclude Include=".\umbraco\**\*">
|
||||
<Dir>umbraco</Dir>
|
||||
</CustomFilesToInclude>
|
||||
<CustomFilesToInclude Include=".\umbraco_client\**\*">
|
||||
<Dir>umbraco_client</Dir>
|
||||
</CustomFilesToInclude>
|
||||
<CustomFilesToInclude Include=".\Global.asax">
|
||||
<Dir>.</Dir>
|
||||
</CustomFilesToInclude>
|
||||
<FilesForPackagingFromProject Include="@(CustomFilesToInclude)">
|
||||
<DestinationRelativePath>%(CustomFilesToInclude.Dir)\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
|
||||
</FilesForPackagingFromProject>
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -1,19 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Target Name="AddUmbracoFilesToOutput">
|
||||
<ItemGroup>
|
||||
<UmbracoFiles Include=".\umbraco\**\*;" />
|
||||
<UmbracoClientFiles Include=".\umbraco_client\**\*;" />
|
||||
<AppBrowsersFiles Include=".\App_Browsers\**\*" />
|
||||
<FilesForPackagingFromProject Include="%(UmbracoFiles.Identity)">
|
||||
<DestinationRelativePath>umbraco\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
|
||||
</FilesForPackagingFromProject>
|
||||
<FilesForPackagingFromProject Include="%(UmbracoClientFiles.Identity)">
|
||||
<DestinationRelativePath>umbraco_client\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
|
||||
</FilesForPackagingFromProject>
|
||||
<FilesForPackagingFromProject Include="%(AppBrowsersFiles.Identity)">
|
||||
<DestinationRelativePath>App_Browsers\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
|
||||
</FilesForPackagingFromProject>
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -1,14 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<CopyAllFilesToSingleFolderForPackageDependsOn>
|
||||
AddUmbracoFilesToOutput;
|
||||
$(CopyAllFilesToSingleFolderForPackageDependsOn);
|
||||
</CopyAllFilesToSingleFolderForPackageDependsOn>
|
||||
|
||||
<CopyAllFilesToSingleFolderForMsdeployDependsOn>
|
||||
AddUmbracoFilesToOutput;
|
||||
$(CopyAllFilesToSingleFolderForPackageDependsOn);
|
||||
</CopyAllFilesToSingleFolderForMsdeployDependsOn>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -1,19 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Target Name="AddUmbracoFilesToOutput">
|
||||
<ItemGroup>
|
||||
<UmbracoFiles Include=".\umbraco\**\*;" />
|
||||
<UmbracoClientFiles Include=".\umbraco_client\**\*;" />
|
||||
<AppBrowsersFiles Include=".\App_Browsers\**\*" />
|
||||
<FilesForPackagingFromProject Include="%(UmbracoFiles.Identity)">
|
||||
<DestinationRelativePath>umbraco\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
|
||||
</FilesForPackagingFromProject>
|
||||
<FilesForPackagingFromProject Include="%(UmbracoClientFiles.Identity)">
|
||||
<DestinationRelativePath>umbraco_client\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
|
||||
</FilesForPackagingFromProject>
|
||||
<FilesForPackagingFromProject Include="%(AppBrowsersFiles.Identity)">
|
||||
<DestinationRelativePath>App_Browsers\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
|
||||
</FilesForPackagingFromProject>
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -1,14 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<CopyAllFilesToSingleFolderForPackageDependsOn>
|
||||
AddUmbracoFilesToOutput;
|
||||
$(CopyAllFilesToSingleFolderForPackageDependsOn);
|
||||
</CopyAllFilesToSingleFolderForPackageDependsOn>
|
||||
|
||||
<CopyAllFilesToSingleFolderForMsdeployDependsOn>
|
||||
AddUmbracoFilesToOutput;
|
||||
$(CopyAllFilesToSingleFolderForPackageDependsOn);
|
||||
</CopyAllFilesToSingleFolderForMsdeployDependsOn>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -1,19 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Target Name="AddUmbracoFilesToOutput">
|
||||
<ItemGroup>
|
||||
<UmbracoFiles Include=".\umbraco\**\*;" />
|
||||
<UmbracoClientFiles Include=".\umbraco_client\**\*;" />
|
||||
<AppBrowsersFiles Include=".\App_Browsers\**\*" />
|
||||
<FilesForPackagingFromProject Include="%(UmbracoFiles.Identity)">
|
||||
<DestinationRelativePath>umbraco\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
|
||||
</FilesForPackagingFromProject>
|
||||
<FilesForPackagingFromProject Include="%(UmbracoClientFiles.Identity)">
|
||||
<DestinationRelativePath>umbraco_client\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
|
||||
</FilesForPackagingFromProject>
|
||||
<FilesForPackagingFromProject Include="%(AppBrowsersFiles.Identity)">
|
||||
<DestinationRelativePath>App_Browsers\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
|
||||
</FilesForPackagingFromProject>
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -1,8 +1,17 @@
|
||||
A note about running Umbraco from Visual Studio.
|
||||
|
||||
When upgrading your website using nuget a backup of config files and web.config will be created. Only the web.config will
|
||||
be overwritten by default to ensure that it has the necessary settings from the current release. This means that you'll
|
||||
have to merge the files if you made any changes to the previous config files.
|
||||
When upgrading your website using NuGet you should answer "No" to the questions to overwrite the Web.config
|
||||
file (and config files in the config folder).
|
||||
We will overwrite Web.config anyway but we keep a backup in the App_Data\NuGetBackup folder. There you'll
|
||||
find a folder with the current date and time in which the backup has been placed. Make sure to merge the
|
||||
new file with the old backup files before you proceed.
|
||||
The web.config will be overwritten by default to ensure that it has the necessary settings from the current release.
|
||||
|
||||
We've also overwritten all the files in the Umbraco and Umbraco_Client folder, these have also been backed up in
|
||||
App_Data\NuGetBackup. We didn't overwrite the UI.xml file nor did we remove any files or folders that you or a package
|
||||
might have added. Only the existing files were overwritten. If you customized anything then make sure to do a compare
|
||||
and merge with the NuGetBackup folder.
|
||||
|
||||
The config files found in the config folder will usually not be changed for patch releases, so they can usually be skipped,
|
||||
but the web.config will have to have its previous "umbracoConfigurationStatus"-appsetting and "umbracoDbDSN" connection string
|
||||
copied over (as a minimum).
|
||||
@@ -10,8 +19,8 @@ copied over (as a minimum).
|
||||
This nuget package includes build targets that extends the creation of a deploy package, which is generated by
|
||||
Publishing from Visual Studio. The targets will only work once Publishing is configured, so if you don't use
|
||||
Publish this won't affect you.
|
||||
These folders will now be automatically included when creating a deploy package or publishing to the file system:
|
||||
umbraco and umbraco_client.
|
||||
These things will now be automatically included when creating a deploy package or publishing to the file system:
|
||||
umbraco, umbraco_client, config\splashes and global.asax.
|
||||
|
||||
Please read the release notes on our.umbraco.org:
|
||||
http://our.umbraco.org/contribute/releases
|
||||
|
||||
@@ -1,27 +1,38 @@
|
||||
param($rootPath, $toolsPath, $package, $project)
|
||||
|
||||
if ($project) {
|
||||
# Create a backup of extisting umbraco config files
|
||||
$configPath = Join-Path (Split-Path $project.FullName -Parent) "\config"
|
||||
$backupPath = Join-Path $configPath "\backup"
|
||||
Get-ChildItem -path $configPath |
|
||||
Where -filterscript {($_.Name.EndsWith("config"))} | Foreach-Object {
|
||||
$newFileName = Join-Path $backupPath $_.Name.replace(".config",".config.backup")
|
||||
New-Item -ItemType File -Path $newFileName -Force
|
||||
Copy-Item $_.FullName $newFileName -Force
|
||||
}
|
||||
|
||||
if ($project) {
|
||||
$dateTime = Get-Date -Format yyyyMMdd-HHmmss
|
||||
$backupPath = Join-Path (Split-Path $project.FullName -Parent) "\App_Data\NuGetBackup\$dateTime"
|
||||
|
||||
# Create backup folder if it doesn't exist yet
|
||||
New-Item -ItemType Directory -Force -Path $backupPath
|
||||
|
||||
# Create a backup of original web.config
|
||||
$projectDestinationPath = Split-Path $project.FullName -Parent
|
||||
$webConfigSource = Join-Path $projectDestinationPath "web.config"
|
||||
$webConfigDestination = Join-Path $projectDestinationPath "web.config.backup"
|
||||
Copy-Item $webConfigSource $webConfigDestination
|
||||
$webConfigSource = Join-Path $projectDestinationPath "Web.config"
|
||||
Copy-Item $webConfigSource $backupPath -Force
|
||||
|
||||
# Copy umbraco files from package to project folder
|
||||
$projectDestinationPath = Split-Path $project.FullName -Parent
|
||||
$umbracoFilesPath = Join-Path $rootPath "UmbracoFiles\*"
|
||||
Copy-Item $umbracoFilesPath $projectDestinationPath -recurse -force
|
||||
|
||||
# Copy Web.config from package to project folder
|
||||
$umbracoFilesPath = Join-Path $rootPath "UmbracoFiles\Web.config"
|
||||
Copy-Item $umbracoFilesPath $projectDestinationPath -Force
|
||||
|
||||
# Copy umbraco and umbraco_files from package to project folder
|
||||
# This is only done when these folders already exist because we
|
||||
# only want to do this for upgrades
|
||||
$umbracoFolder = Join-Path $projectDestinationPath "Umbraco\"
|
||||
if(Test-Path $umbracoFolder) {
|
||||
$umbracoFolderSource = Join-Path $rootPath "UmbracoFiles\Umbraco"
|
||||
Copy-Item $umbracoFolder $backupPath -Force
|
||||
robocopy $umbracoFolderSource $umbracoFolder /e /xf UI.xml
|
||||
}
|
||||
|
||||
$umbracoClientFolder = Join-Path $projectDestinationPath "Umbraco_Client"
|
||||
if(Test-Path $umbracoClientFolder) {
|
||||
$umbracoClientFolderSource = Join-Path $rootPath "UmbracoFiles\Umbraco_Client"
|
||||
Copy-Item $umbracoClientFolder $backupPath -Force
|
||||
robocopy $umbracoFolderSource $umbracoClientFolder /e
|
||||
}
|
||||
|
||||
# Open readme.txt file
|
||||
$DTE.ItemOperations.OpenFile($toolsPath + '\Readme.txt')
|
||||
}
|
||||
@@ -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";
|
||||
|
||||
@@ -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 + 100;
|
||||
//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(UmbracoConfig.For.UmbracoSettings().Providers.DefaultBackOfficeUserProvider);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetMembershipProvidersLegacyEncoding(UmbracoConfig.For.UmbracoSettings().Providers.DefaultBackOfficeUserProvider, 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>
|
||||
|
||||
@@ -34,31 +34,19 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
if (_umbracoSettings == null)
|
||||
{
|
||||
var umbracoSettings = ConfigurationManager.GetSection("umbracoConfiguration/settings") as IUmbracoSettingsSection;
|
||||
if (umbracoSettings == null)
|
||||
{
|
||||
LogHelper.Warn<UmbracoConfig>("Could not load the " + typeof(IUmbracoSettingsSection) + " from config file!");
|
||||
}
|
||||
var umbracoSettings = ConfigurationManager.GetSection("umbracoConfiguration/settings") as IUmbracoSettingsSection;
|
||||
SetUmbracoSettings(umbracoSettings);
|
||||
}
|
||||
|
||||
if (_baseRestExtensions == null)
|
||||
{
|
||||
var baseRestExtensions = ConfigurationManager.GetSection("umbracoConfiguration/BaseRestExtensions") as IBaseRestSection;
|
||||
if (baseRestExtensions == null)
|
||||
{
|
||||
LogHelper.Warn<UmbracoConfig>("Could not load the " + typeof(IBaseRestSection) + " from config file!");
|
||||
}
|
||||
var baseRestExtensions = ConfigurationManager.GetSection("umbracoConfiguration/BaseRestExtensions") as IBaseRestSection;
|
||||
SetBaseRestExtensions(baseRestExtensions);
|
||||
}
|
||||
|
||||
if (_dashboardSection == null)
|
||||
{
|
||||
var dashboardConfig = ConfigurationManager.GetSection("umbracoConfiguration/dashBoard") as IDashboardSection;
|
||||
if (dashboardConfig == null)
|
||||
{
|
||||
LogHelper.Warn<UmbracoConfig>("Could not load the " + typeof(IDashboardSection) + " from config file!");
|
||||
}
|
||||
var dashboardConfig = ConfigurationManager.GetSection("umbracoConfiguration/dashBoard") as IDashboardSection;
|
||||
SetDashboardSettings(dashboardConfig);
|
||||
}
|
||||
}
|
||||
@@ -85,6 +73,13 @@ namespace Umbraco.Core.Configuration
|
||||
/// </summary>
|
||||
public IDashboardSection DashboardSettings()
|
||||
{
|
||||
if (_dashboardSection == null)
|
||||
{
|
||||
var ex = new ConfigurationErrorsException("Could not load the " + typeof(IDashboardSection) + " from config file, ensure the web.config and Dashboard.config files are formatted correctly");
|
||||
LogHelper.Error<UmbracoConfig>("Config error", ex);
|
||||
throw ex;
|
||||
}
|
||||
|
||||
return _dashboardSection;
|
||||
}
|
||||
|
||||
@@ -105,6 +100,13 @@ namespace Umbraco.Core.Configuration
|
||||
/// </summary>
|
||||
public IUmbracoSettingsSection UmbracoSettings()
|
||||
{
|
||||
if (_umbracoSettings == null)
|
||||
{
|
||||
var ex = new ConfigurationErrorsException("Could not load the " + typeof (IUmbracoSettingsSection) + " from config file, ensure the web.config and umbracoSettings.config files are formatted correctly");
|
||||
LogHelper.Error<UmbracoConfig>("Config error", ex);
|
||||
throw ex;
|
||||
}
|
||||
|
||||
return _umbracoSettings;
|
||||
}
|
||||
|
||||
@@ -119,6 +121,13 @@ namespace Umbraco.Core.Configuration
|
||||
/// </summary>
|
||||
public IBaseRestSection BaseRestExtensions()
|
||||
{
|
||||
if (_baseRestExtensions == null)
|
||||
{
|
||||
var ex = new ConfigurationErrorsException("Could not load the " + typeof(IBaseRestSection) + " from config file, ensure the web.config and BaseRestExtensions.config files are formatted correctly");
|
||||
LogHelper.Error<UmbracoConfig>("Config error", ex);
|
||||
throw ex;
|
||||
}
|
||||
|
||||
return _baseRestExtensions;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
{
|
||||
return new OptionalInnerTextConfigurationElement<string>(
|
||||
(InnerTextConfigurationElement<string>)this["DefaultBackofficeProvider"],
|
||||
//set the default
|
||||
//set the default
|
||||
"UsersMembershipProvider");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
public class UmbracoVersion
|
||||
{
|
||||
private static readonly Version Version = new Version("7.0.4");
|
||||
private static readonly Version Version = new Version("7.1.0");
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current version of Umbraco.
|
||||
|
||||
@@ -85,7 +85,7 @@ namespace Umbraco.Core
|
||||
|
||||
/// <summary>
|
||||
/// MediaType alias for a folder.
|
||||
/// </summary>
|
||||
/// </summary>
|
||||
public const string Folder = "Folder";
|
||||
|
||||
/// <summary>
|
||||
@@ -93,10 +93,10 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
public const string Image = "Image";
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Constants for Umbraco Member property aliases.
|
||||
/// </summary>
|
||||
/// </summary>
|
||||
public static class Member
|
||||
{
|
||||
/// <summary>
|
||||
@@ -111,73 +111,78 @@ 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";
|
||||
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";
|
||||
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";
|
||||
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";
|
||||
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";
|
||||
|
||||
/// <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)
|
||||
new PropertyType(PropertyEditors.TextboxMultipleAlias, DataTypeDatabaseType.Ntext, true)
|
||||
{
|
||||
Alias = Comments,
|
||||
Name = CommentsLabel
|
||||
@@ -185,7 +190,7 @@ namespace Umbraco.Core
|
||||
},
|
||||
{
|
||||
FailedPasswordAttempts,
|
||||
new PropertyType(PropertyEditors.IntegerAlias, DataTypeDatabaseType.Integer)
|
||||
new PropertyType(PropertyEditors.NoEditAlias, DataTypeDatabaseType.Integer, true)
|
||||
{
|
||||
Alias = FailedPasswordAttempts,
|
||||
Name = FailedPasswordAttemptsLabel
|
||||
@@ -193,7 +198,7 @@ namespace Umbraco.Core
|
||||
},
|
||||
{
|
||||
IsApproved,
|
||||
new PropertyType(PropertyEditors.TrueFalseAlias, DataTypeDatabaseType.Integer)
|
||||
new PropertyType(PropertyEditors.TrueFalseAlias, DataTypeDatabaseType.Integer, true)
|
||||
{
|
||||
Alias = IsApproved,
|
||||
Name = IsApprovedLabel
|
||||
@@ -201,7 +206,7 @@ namespace Umbraco.Core
|
||||
},
|
||||
{
|
||||
IsLockedOut,
|
||||
new PropertyType(PropertyEditors.TrueFalseAlias, DataTypeDatabaseType.Integer)
|
||||
new PropertyType(PropertyEditors.TrueFalseAlias, DataTypeDatabaseType.Integer, true)
|
||||
{
|
||||
Alias = IsLockedOut,
|
||||
Name = IsLockedOutLabel
|
||||
@@ -209,7 +214,7 @@ namespace Umbraco.Core
|
||||
},
|
||||
{
|
||||
LastLockoutDate,
|
||||
new PropertyType(PropertyEditors.DateAlias, DataTypeDatabaseType.Date)
|
||||
new PropertyType(PropertyEditors.NoEditAlias, DataTypeDatabaseType.Date, true)
|
||||
{
|
||||
Alias = LastLockoutDate,
|
||||
Name = LastLockoutDateLabel
|
||||
@@ -217,7 +222,7 @@ namespace Umbraco.Core
|
||||
},
|
||||
{
|
||||
LastLoginDate,
|
||||
new PropertyType(PropertyEditors.DateAlias, DataTypeDatabaseType.Date)
|
||||
new PropertyType(PropertyEditors.NoEditAlias, DataTypeDatabaseType.Date, true)
|
||||
{
|
||||
Alias = LastLoginDate,
|
||||
Name = LastLoginDateLabel
|
||||
@@ -225,7 +230,7 @@ namespace Umbraco.Core
|
||||
},
|
||||
{
|
||||
LastPasswordChangeDate,
|
||||
new PropertyType(PropertyEditors.DateAlias, DataTypeDatabaseType.Date)
|
||||
new PropertyType(PropertyEditors.NoEditAlias, DataTypeDatabaseType.Date, true)
|
||||
{
|
||||
Alias = LastPasswordChangeDate,
|
||||
Name = LastPasswordChangeDateLabel
|
||||
@@ -233,7 +238,7 @@ namespace Umbraco.Core
|
||||
},
|
||||
{
|
||||
PasswordAnswer,
|
||||
new PropertyType(PropertyEditors.TextboxAlias, DataTypeDatabaseType.Nvarchar)
|
||||
new PropertyType(PropertyEditors.NoEditAlias, DataTypeDatabaseType.Nvarchar, true)
|
||||
{
|
||||
Alias = PasswordAnswer,
|
||||
Name = PasswordAnswerLabel
|
||||
@@ -241,7 +246,7 @@ namespace Umbraco.Core
|
||||
},
|
||||
{
|
||||
PasswordQuestion,
|
||||
new PropertyType(PropertyEditors.TextboxAlias, DataTypeDatabaseType.Nvarchar)
|
||||
new PropertyType(PropertyEditors.NoEditAlias, DataTypeDatabaseType.Nvarchar, true)
|
||||
{
|
||||
Alias = PasswordQuestion,
|
||||
Name = PasswordQuestionLabel
|
||||
@@ -259,7 +264,7 @@ 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";
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
public static partial class Constants
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the constants used for Umbraco packages in the package.config xml
|
||||
/// </summary>
|
||||
public static class Packaging
|
||||
{
|
||||
public const string UmbPackageNodeName = "umbPackage";
|
||||
public const string DataTypesNodeName = "DataTypes";
|
||||
public const string PackageXmlFileName = "package.xml";
|
||||
public const string UmbracoPackageExtention = ".umb";
|
||||
public const string DataTypeNodeName = "DataType";
|
||||
public const string LanguagesNodeName = "Languages";
|
||||
public const string FilesNodeName = "Files";
|
||||
public const string StylesheetsNodeName = "Stylesheets";
|
||||
public const string TemplatesNodeName = "Templates";
|
||||
public const string OrgnameNodeName = "orgName";
|
||||
public const string NameNodeName = "Name";
|
||||
public const string TemplateNodeName = "Template";
|
||||
public const string AliasNodeName = "Alias";
|
||||
public const string DictionaryitemsNodeName = "DictionaryItems";
|
||||
public const string MacrosNodeName = "macros";
|
||||
public const string DocumentSetNodeName = "DocumentSet";
|
||||
public const string DocumentTypesNodeName = "DocumentTypes";
|
||||
public const string DocumentTypeNodeName = "DocumentType";
|
||||
public const string FileNodeName = "file";
|
||||
public const string OrgPathNodeName = "orgPath";
|
||||
public const string GuidNodeName = "guid";
|
||||
public const string StylesheetNodeName = "styleSheet";
|
||||
public const string MacroNodeName = "macro";
|
||||
public const string InfoNodeName = "info";
|
||||
public const string PackageRequirementsMajorXpath = "/package/requirements/major";
|
||||
public const string PackageRequirementsMinorXpath = "/package/requirements/minor";
|
||||
public const string PackageRequirementsPatchXpath = "/package/requirements/patch";
|
||||
public const string PackageNameXpath = "/package/name";
|
||||
public const string PackageVersionXpath = "/package/version";
|
||||
public const string PackageUrlXpath = "/package/url";
|
||||
public const string PackageLicenseXpath = "/package/license";
|
||||
public const string AuthorNameXpath = "/author/name";
|
||||
public const string AuthorWebsiteXpath = "/author/website";
|
||||
public const string ReadmeXpath = "/readme";
|
||||
public const string ControlNodeName = "control";
|
||||
public const string ActionNodeName = "Action";
|
||||
public const string ActionsNodeName = "Actions";
|
||||
public const string UndoNodeAttribute = "undo";
|
||||
public const string RunatNodeAttribute = "runat";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -243,7 +243,6 @@ namespace Umbraco.Core
|
||||
|
||||
//stop the timer and log the output
|
||||
_timer.Dispose();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -287,7 +286,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) })
|
||||
@@ -312,17 +311,15 @@ namespace Umbraco.Core
|
||||
|
||||
//the database migration objects
|
||||
MigrationResolver.Current = new MigrationResolver(
|
||||
() => PluginManager.Current.ResolveMigrationTypes());
|
||||
() => PluginManager.Current.ResolveTypes<IMigration>());
|
||||
|
||||
// todo: remove once we drop IPropertyEditorValueConverter support.
|
||||
PropertyEditorValueConvertersResolver.Current = new PropertyEditorValueConvertersResolver(
|
||||
PluginManager.Current.ResolvePropertyEditorValueConverters());
|
||||
|
||||
//add the internal ones, these are not public currently so need to add them manually
|
||||
PropertyValueConvertersResolver.Current = new PropertyValueConvertersResolver(
|
||||
PluginManager.Current.ResolvePropertyValueConverters());
|
||||
// fixme - why not use the following syntax?
|
||||
//PluginManager.Current.ResolveTypes<IPropertyValueConverter>());
|
||||
// need to filter out the ones we dont want!!
|
||||
PropertyValueConvertersResolver.Current = new PropertyValueConvertersResolver(
|
||||
PluginManager.Current.ResolveTypes<IPropertyValueConverter>());
|
||||
|
||||
// use the new DefaultShortStringHelper
|
||||
ShortStringHelperResolver.Current = new ShortStringHelperResolver(
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Configuration;
|
||||
using System.Data.SqlServerCe;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.Configuration;
|
||||
using System.Xml.Linq;
|
||||
using Umbraco.Core.Configuration;
|
||||
@@ -113,8 +114,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 +123,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 +162,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 +193,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)
|
||||
@@ -417,6 +436,13 @@ namespace Umbraco.Core
|
||||
|
||||
if (_result == null)
|
||||
{
|
||||
|
||||
if (SystemUtilities.GetCurrentTrustLevel() != AspNetHostingPermissionLevel.Unrestricted
|
||||
&& ProviderName == "MySql.Data.MySqlClient")
|
||||
{
|
||||
throw new InvalidOperationException("Cannot use MySql in Medium Trust configuration");
|
||||
}
|
||||
|
||||
var database = new UmbracoDatabase(_connectionString, ProviderName);
|
||||
var dbSchema = new DatabaseSchemaCreation(database);
|
||||
_result = dbSchema.ValidateSchema();
|
||||
@@ -425,15 +451,15 @@ namespace Umbraco.Core
|
||||
}
|
||||
|
||||
internal Result CreateDatabaseSchemaAndData()
|
||||
{
|
||||
var readyForInstall = CheckReadyForInstall();
|
||||
if (readyForInstall.Success == false)
|
||||
{
|
||||
return readyForInstall.Result;
|
||||
}
|
||||
|
||||
{
|
||||
try
|
||||
{
|
||||
var readyForInstall = CheckReadyForInstall();
|
||||
if (readyForInstall.Success == false)
|
||||
{
|
||||
return readyForInstall.Result;
|
||||
}
|
||||
|
||||
LogHelper.Info<DatabaseContext>("Database configuration status: Started");
|
||||
|
||||
string message;
|
||||
@@ -491,14 +517,15 @@ namespace Umbraco.Core
|
||||
/// <returns></returns>
|
||||
internal Result UpgradeSchemaAndData()
|
||||
{
|
||||
var readyForInstall = CheckReadyForInstall();
|
||||
if (readyForInstall.Success == false)
|
||||
{
|
||||
return readyForInstall.Result;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
var readyForInstall = CheckReadyForInstall();
|
||||
if (readyForInstall.Success == false)
|
||||
{
|
||||
return readyForInstall.Result;
|
||||
}
|
||||
|
||||
LogHelper.Info<DatabaseContext>("Database upgrade started");
|
||||
|
||||
var database = new UmbracoDatabase(_connectionString, ProviderName);
|
||||
@@ -511,11 +538,11 @@ namespace Umbraco.Core
|
||||
|
||||
//DO the upgrade!
|
||||
|
||||
var configuredVersion = string.IsNullOrEmpty(GlobalSettings.ConfigurationStatus)
|
||||
var currentVersion = string.IsNullOrEmpty(GlobalSettings.ConfigurationStatus)
|
||||
? installedVersion
|
||||
: new Version(GlobalSettings.ConfigurationStatus);
|
||||
var targetVersion = UmbracoVersion.Current;
|
||||
var runner = new MigrationRunner(configuredVersion, targetVersion, GlobalSettings.UmbracoMigrationName);
|
||||
var runner = new MigrationRunner(currentVersion, targetVersion, GlobalSettings.UmbracoMigrationName);
|
||||
var upgraded = runner.Execute(database, true);
|
||||
message = message + "<p>Upgrade completed!</p>";
|
||||
|
||||
@@ -558,6 +585,12 @@ namespace Umbraco.Core
|
||||
|
||||
private Attempt<Result> CheckReadyForInstall()
|
||||
{
|
||||
if (SystemUtilities.GetCurrentTrustLevel() != AspNetHostingPermissionLevel.Unrestricted
|
||||
&& ProviderName == "MySql.Data.MySqlClient")
|
||||
{
|
||||
throw new InvalidOperationException("Cannot use MySql in Medium Trust configuration");
|
||||
}
|
||||
|
||||
if (_configured == false || (string.IsNullOrEmpty(_connectionString) || string.IsNullOrEmpty(ProviderName)))
|
||||
{
|
||||
return Attempt.Fail(new Result
|
||||
@@ -573,7 +606,7 @@ namespace Umbraco.Core
|
||||
|
||||
private Result HandleInstallException(Exception ex)
|
||||
{
|
||||
LogHelper.Info<DatabaseContext>("Database configuration failed with the following error and stack trace: " + ex.Message + "\n" + ex.StackTrace);
|
||||
LogHelper.Error<DatabaseContext>("Database configuration failed", ex);
|
||||
|
||||
if (_result != null)
|
||||
{
|
||||
@@ -597,5 +630,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>
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Umbraco.Core.Logging;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
@@ -14,7 +15,7 @@ namespace Umbraco.Core
|
||||
public static IEnumerable<IEnumerable<T>> InGroupsOf<T>(this IEnumerable<T> source, int groupSize)
|
||||
{
|
||||
if (source == null)
|
||||
throw new NullReferenceException("source");
|
||||
throw new NullReferenceException("source");
|
||||
|
||||
// enumerate the source only once!
|
||||
return new InGroupsEnumerator<T>(source, groupSize).Groups();
|
||||
@@ -125,23 +126,13 @@ namespace Umbraco.Core
|
||||
}
|
||||
|
||||
/// <summary>The flatten list.</summary>
|
||||
/// <param name="items">The items.</param>
|
||||
/// <param name="selectChild">The select child.</param>
|
||||
/// <typeparam name="TItem">Item type</typeparam>
|
||||
/// <param name="e">The items.</param>
|
||||
/// <param name="f">The select child.</param>
|
||||
/// <typeparam name="T">Item type</typeparam>
|
||||
/// <returns>list of TItem</returns>
|
||||
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "By design")]
|
||||
public static IEnumerable<TItem> FlattenList<TItem>(this IEnumerable<TItem> items, Func<TItem, IEnumerable<TItem>> selectChild)
|
||||
public static IEnumerable<T> FlattenList<T>(this IEnumerable<T> e, Func<T, IEnumerable<T>> f)
|
||||
{
|
||||
IEnumerable<TItem> children = items != null && items.Any()
|
||||
? items.SelectMany(selectChild).FlattenList(selectChild)
|
||||
: Enumerable.Empty<TItem>();
|
||||
|
||||
if (items != null)
|
||||
{
|
||||
return items.Concat(children);
|
||||
}
|
||||
|
||||
return null;
|
||||
return e.SelectMany(c => f(c).FlattenList(f)).Concat(e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to notify the TypeFinder to ignore any class attributed with this during it's discovery
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public sealed class HideFromTypeFinderAttribute : Attribute
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -206,11 +206,10 @@ namespace Umbraco.Core.IO
|
||||
var fileNameThumb = string.IsNullOrWhiteSpace(fileNameAddition)
|
||||
? string.Format("{0}_UMBRACOSYSTHUMBNAIL.jpg", Path.Substring(0, Path.LastIndexOf(".", StringComparison.Ordinal)))
|
||||
: string.Format("{0}_{1}.jpg", Path.Substring(0, Path.LastIndexOf(".", StringComparison.Ordinal)), fileNameAddition);
|
||||
|
||||
|
||||
var thumbnail = maxWidthHeight == -1
|
||||
?ImageHelper.GenerateThumbnail(image, maxWidthHeight, fileNameThumb, Extension, _fs)
|
||||
: ImageHelper.GenerateThumbnail(image, width, height, fileNameThumb, Extension, _fs);
|
||||
|
||||
var thumbnail = maxWidthHeight == -1
|
||||
? ImageHelper.GenerateThumbnail(image, width, height, fileNameThumb, Extension, _fs)
|
||||
: ImageHelper.GenerateThumbnail(image, maxWidthHeight, fileNameThumb, Extension, _fs);
|
||||
|
||||
return thumbnail.FileName;
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
{
|
||||
@@ -13,61 +15,104 @@ namespace Umbraco.Core.Models
|
||||
public class Member : ContentBase, IMember
|
||||
{
|
||||
private readonly IMemberType _contentType;
|
||||
private string _contentTypeAlias;
|
||||
private readonly string _contentTypeAlias;
|
||||
private string _username;
|
||||
private string _email;
|
||||
private string _password;
|
||||
private string _rawPasswordValue;
|
||||
private object _providerUserKey;
|
||||
private Type _userTypeKey;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for creating an empty Member object
|
||||
/// </summary>
|
||||
/// <param name="contentType">ContentType for the current Content object</param>
|
||||
public Member(IMemberType contentType)
|
||||
: base("", -1, contentType, new PropertyCollection())
|
||||
{
|
||||
Mandate.ParameterNotNull(contentType, "contentType");
|
||||
|
||||
_contentTypeAlias = contentType.Alias;
|
||||
_contentType = contentType;
|
||||
IsApproved = true;
|
||||
|
||||
//this cannot be null but can be empty
|
||||
_rawPasswordValue = "";
|
||||
_email = "";
|
||||
_username = "";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for creating a Member object
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the content</param>
|
||||
/// <param name="contentType">ContentType for the current Content object</param>
|
||||
public Member(string name, IMemberType contentType)
|
||||
: this(contentType)
|
||||
{
|
||||
Mandate.ParameterNotNull(contentType, "contentType");
|
||||
Mandate.ParameterNotNullOrEmpty(name, "name");
|
||||
|
||||
_contentTypeAlias = contentType.Alias;
|
||||
_contentType = contentType;
|
||||
IsApproved = true;
|
||||
|
||||
//this cannot be null but can be empty
|
||||
_rawPasswordValue = "";
|
||||
_email = "";
|
||||
_username = "";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for creating a Member object
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="email"></param>
|
||||
/// <param name="username"></param>
|
||||
/// <param name="contentType"></param>
|
||||
public Member(string name, string email, string username, IMemberType contentType)
|
||||
: base(name, -1, contentType, new PropertyCollection())
|
||||
{
|
||||
_contentType = contentType;
|
||||
}
|
||||
|
||||
internal Member(string name, string email, string username, string password, int parentId, IMemberType contentType)
|
||||
: base(name, parentId, contentType, new PropertyCollection())
|
||||
{
|
||||
Mandate.ParameterNotNull(contentType, "contentType");
|
||||
Mandate.ParameterNotNullOrEmpty(name, "name");
|
||||
Mandate.ParameterNotNullOrEmpty(email, "email");
|
||||
Mandate.ParameterNotNullOrEmpty(username, "username");
|
||||
|
||||
_contentTypeAlias = contentType.Alias;
|
||||
_contentType = contentType;
|
||||
_email = email;
|
||||
_username = username;
|
||||
_password = password;
|
||||
IsApproved = true;
|
||||
|
||||
//this cannot be null but can be empty
|
||||
_rawPasswordValue = "";
|
||||
}
|
||||
|
||||
public Member(string name, string email, string username, string password, IMemberType contentType)
|
||||
: this(name, email, username, password, -1, contentType)
|
||||
/// <summary>
|
||||
/// Constructor for creating a Member object
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="email"></param>
|
||||
/// <param name="username"></param>
|
||||
/// <param name="rawPasswordValue">
|
||||
/// The password value passed in to this parameter should be the encoded/encrypted/hashed format of the member's password
|
||||
/// </param>
|
||||
/// <param name="contentType"></param>
|
||||
public Member(string name, string email, string username, string rawPasswordValue, IMemberType contentType)
|
||||
: base(name, -1, contentType, new PropertyCollection())
|
||||
{
|
||||
Mandate.ParameterNotNull(contentType, "contentType");
|
||||
|
||||
_contentTypeAlias = contentType.Alias;
|
||||
_contentType = contentType;
|
||||
_email = email;
|
||||
_username = username;
|
||||
_password = password;
|
||||
_rawPasswordValue = rawPasswordValue;
|
||||
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);
|
||||
private static readonly PropertyInfo PasswordSelector = ExpressionHelper.GetPropertyInfo<Member, string>(x => x.Password);
|
||||
private static readonly PropertyInfo PasswordSelector = ExpressionHelper.GetPropertyInfo<Member, string>(x => x.RawPasswordValue);
|
||||
private static readonly PropertyInfo ProviderUserKeySelector = ExpressionHelper.GetPropertyInfo<Member, object>(x => x.ProviderUserKey);
|
||||
private static readonly PropertyInfo UserTypeKeySelector = ExpressionHelper.GetPropertyInfo<Member, Type>(x => x.ProviderUserKeyType);
|
||||
|
||||
@@ -106,19 +151,19 @@ namespace Umbraco.Core.Models
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Password
|
||||
/// Gets or sets the raw password value
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public string Password
|
||||
public string RawPasswordValue
|
||||
{
|
||||
get { return _password; }
|
||||
get { return _rawPasswordValue; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_password = value;
|
||||
return _password;
|
||||
}, _password, PasswordSelector);
|
||||
_rawPasswordValue = value;
|
||||
return _rawPasswordValue;
|
||||
}, _rawPasswordValue, PasswordSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,7 +181,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]
|
||||
@@ -144,34 +189,50 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Password Answer
|
||||
/// Gets or sets the raw password answer value
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Alias: umbracoPasswordRetrievalAnswerPropertyTypeAlias
|
||||
/// For security reasons this value should be encrypted, the encryption process is handled by the memberhip provider
|
||||
/// Alias: umbracoMemberPasswordRetrievalAnswer
|
||||
///
|
||||
/// Part of the standard properties collection.
|
||||
/// </remarks>
|
||||
[IgnoreDataMember]
|
||||
public string PasswordAnswer
|
||||
public string RawPasswordAnswerValue
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -180,7 +241,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]
|
||||
@@ -188,12 +249,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;
|
||||
}
|
||||
}
|
||||
@@ -202,7 +270,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]
|
||||
@@ -210,17 +278,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;
|
||||
}
|
||||
}
|
||||
@@ -229,7 +305,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]
|
||||
@@ -237,17 +313,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;
|
||||
}
|
||||
}
|
||||
@@ -256,7 +338,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]
|
||||
@@ -264,17 +346,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;
|
||||
}
|
||||
}
|
||||
@@ -283,7 +371,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]
|
||||
@@ -291,17 +379,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;
|
||||
}
|
||||
}
|
||||
@@ -310,7 +404,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]
|
||||
@@ -318,17 +412,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;
|
||||
}
|
||||
}
|
||||
@@ -338,7 +438,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]
|
||||
@@ -346,18 +446,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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -368,14 +474,6 @@ namespace Umbraco.Core.Models
|
||||
public virtual string ContentTypeAlias
|
||||
{
|
||||
get { return _contentTypeAlias; }
|
||||
internal set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_contentTypeAlias = value;
|
||||
return _contentTypeAlias;
|
||||
}, _contentTypeAlias, DefaultContentTypeAliasSelector);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -471,5 +569,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,20 +14,18 @@ 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>
|
||||
@@ -46,28 +44,19 @@ namespace Umbraco.Core.Models
|
||||
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_alias = value == "_umbracoSystemDefaultProtectType" ? value : value.ToSafeAlias();
|
||||
_alias = value == "_umbracoSystemDefaultProtectType"
|
||||
? value
|
||||
: (value == null ? string.Empty : value.ToSafeAlias() );
|
||||
return _alias;
|
||||
}, _alias, AliasSelector);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or Sets a Dictionary of Tuples (MemberCanEdit, VisibleOnProfile, PropertyTypeId) by the PropertyTypes' alias.
|
||||
/// Gets or Sets a Dictionary of Tuples (MemberCanEdit, VisibleOnProfile) by the PropertyTypes' alias.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
internal IDictionary<string, Tuple<bool, bool, int>> MemberTypePropertyTypes
|
||||
{
|
||||
get { return _memberTypePropertyTypes; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_memberTypePropertyTypes = value;
|
||||
return _memberTypePropertyTypes;
|
||||
}, _memberTypePropertyTypes, MemberTypePropertyTypesSelector);
|
||||
}
|
||||
}
|
||||
internal IDictionary<string, MemberTypePropertyProfileAccess> MemberTypePropertyTypes { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean indicating whether a Property is editable by the Member.
|
||||
@@ -78,7 +67,7 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
if (MemberTypePropertyTypes.ContainsKey(propertyTypeAlias))
|
||||
{
|
||||
return MemberTypePropertyTypes[propertyTypeAlias].Item1;
|
||||
return MemberTypePropertyTypes[propertyTypeAlias].IsEditable;
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -93,7 +82,7 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
if (MemberTypePropertyTypes.ContainsKey(propertyTypeAlias))
|
||||
{
|
||||
return MemberTypePropertyTypes[propertyTypeAlias].Item2;
|
||||
return MemberTypePropertyTypes[propertyTypeAlias].IsVisible;
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -108,13 +97,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);
|
||||
}
|
||||
}
|
||||
@@ -128,13 +115,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>
|
||||
|
||||
@@ -9,9 +9,19 @@ namespace Umbraco.Core.Models.Membership
|
||||
object ProviderUserKey { get; set; }
|
||||
string Username { get; set; }
|
||||
string Email { get; set; }
|
||||
string Password { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the raw password value
|
||||
/// </summary>
|
||||
string RawPasswordValue { get; set; }
|
||||
|
||||
string PasswordQuestion { get; set; }
|
||||
string PasswordAnswer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the raw password answer value
|
||||
/// </summary>
|
||||
string RawPasswordAnswerValue { get; set; }
|
||||
|
||||
string Comments { get; set; }
|
||||
bool IsApproved { get; set; }
|
||||
bool IsLockedOut { get; set; }
|
||||
@@ -24,7 +34,7 @@ namespace Umbraco.Core.Models.Membership
|
||||
/// 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>
|
||||
int FailedPasswordAttempts { 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,19 +7,18 @@ 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, IProfile
|
||||
public interface IUser : IMembershipUser
|
||||
{
|
||||
new object Id { get; set; }
|
||||
|
||||
string Name { get; set; }
|
||||
int SessionTimeout { get; set; }
|
||||
int StartContentId { get; set; }
|
||||
int StartMediaId { get; set; }
|
||||
string Language { get; set; }
|
||||
|
||||
//NOTE: I have removed this because it is obsolete in v7 and we are basically removing live editing for now
|
||||
//bool DefaultToLiveEditing { get; set; }
|
||||
|
||||
IUserType UserType { get; }
|
||||
/// <summary>
|
||||
/// Gets/sets the user type for the user
|
||||
/// </summary>
|
||||
IUserType UserType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The default permission set for the user
|
||||
@@ -32,5 +31,10 @@ namespace Umbraco.Core.Models.Membership
|
||||
IEnumerable<string> AllowedSections { get; }
|
||||
void RemoveAllowedSection(string sectionAlias);
|
||||
void AddAllowedSection(string sectionAlias);
|
||||
|
||||
/// <summary>
|
||||
/// Exposes the basic profile data
|
||||
/// </summary>
|
||||
IProfile ProfileData { get; }
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ using Umbraco.Core.Persistence.Mappers;
|
||||
namespace Umbraco.Core.Models.Membership
|
||||
{
|
||||
|
||||
internal interface IUserType : IAggregateRoot
|
||||
public interface IUserType : IAggregateRoot
|
||||
{
|
||||
/// <summary>
|
||||
/// The user type alias
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
namespace Umbraco.Core.Services
|
||||
namespace Umbraco.Core.Models.Membership
|
||||
{
|
||||
/// <summary>
|
||||
/// The types of members to count
|
||||
+5
-3
@@ -1,10 +1,11 @@
|
||||
using System;
|
||||
using System.Web.Security;
|
||||
using Umbraco.Core.Security;
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
namespace Umbraco.Core.Models.Membership
|
||||
{
|
||||
internal static class MembershipExtensions
|
||||
internal static class MembershipUserExtensions
|
||||
{
|
||||
internal static UmbracoMembershipMember AsConcreteMembershipUser(this IMembershipUser member, string providerName)
|
||||
{
|
||||
@@ -32,11 +33,12 @@ namespace Umbraco.Core.Models.Membership
|
||||
{
|
||||
if (_scenario.HasValue == false)
|
||||
{
|
||||
if (System.Web.Security.Membership.Provider.Name == Constants.Conventions.Member.UmbracoMemberProviderName)
|
||||
var provider = MembershipProviderExtensions.GetMembersMembershipProvider();
|
||||
if (provider.IsUmbracoMembershipProvider())
|
||||
{
|
||||
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;
|
||||
@@ -5,6 +5,7 @@ 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;
|
||||
|
||||
@@ -19,33 +20,45 @@ namespace Umbraco.Core.Models.Membership
|
||||
/// </remarks>
|
||||
[Serializable]
|
||||
[DataContract(IsReference = true)]
|
||||
internal class User : TracksChangesEntityBase, IUser
|
||||
public class User : TracksChangesEntityBase, IUser
|
||||
{
|
||||
public User(IUserType userType)
|
||||
{
|
||||
if (userType == null) throw new ArgumentNullException("userType");
|
||||
|
||||
_userType = userType;
|
||||
_defaultPermissions = _userType.Permissions;
|
||||
//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;
|
||||
//cannot be null
|
||||
_rawPasswordValue = "";
|
||||
}
|
||||
|
||||
public User(string name, string email, string username, string password, IUserType userType)
|
||||
public User(string name, string email, string username, string rawPasswordValue, IUserType userType)
|
||||
: this(userType)
|
||||
{
|
||||
_name = name;
|
||||
_email = email;
|
||||
_username = username;
|
||||
_password = password;
|
||||
_rawPasswordValue = rawPasswordValue;
|
||||
_isApproved = true;
|
||||
_isLockedOut = false;
|
||||
_startContentId = -1;
|
||||
_startMediaId = -1;
|
||||
}
|
||||
|
||||
private readonly IUserType _userType;
|
||||
private IUserType _userType;
|
||||
private bool _hasIdentity;
|
||||
private object _id;
|
||||
private int _id;
|
||||
private string _name;
|
||||
private Type _userTypeKey;
|
||||
private readonly List<string> _addedSections;
|
||||
@@ -57,8 +70,7 @@ namespace Umbraco.Core.Models.Membership
|
||||
|
||||
private string _username;
|
||||
private string _email;
|
||||
private string _password;
|
||||
private Guid _key;
|
||||
private string _rawPasswordValue;
|
||||
private bool _isApproved;
|
||||
private bool _isLockedOut;
|
||||
private string _language;
|
||||
@@ -75,29 +87,49 @@ namespace Umbraco.Core.Models.Membership
|
||||
|
||||
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 PasswordSelector = ExpressionHelper.GetPropertyInfo<User, string>(x => x.RawPasswordValue);
|
||||
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(Id.ToString());
|
||||
return _hasIdentity;
|
||||
}
|
||||
protected set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_hasIdentity = value;
|
||||
return _hasIdentity;
|
||||
}, _hasIdentity, HasIdentitySelector);
|
||||
}
|
||||
}
|
||||
|
||||
[DataMember]
|
||||
public int Id
|
||||
{
|
||||
get
|
||||
{
|
||||
return _id;
|
||||
}
|
||||
set
|
||||
{
|
||||
Id = value;
|
||||
_hasIdentity = true;
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_id = value;
|
||||
HasIdentity = true; //set the has Identity
|
||||
return _id;
|
||||
}, _id, IdSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,16 +207,16 @@ namespace Umbraco.Core.Models.Membership
|
||||
}
|
||||
}
|
||||
[DataMember]
|
||||
public string Password
|
||||
public string RawPasswordValue
|
||||
{
|
||||
get { return _password; }
|
||||
get { return _rawPasswordValue; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_password = value;
|
||||
return _password;
|
||||
}, _password, PasswordSelector);
|
||||
_rawPasswordValue = value;
|
||||
return _rawPasswordValue;
|
||||
}, _rawPasswordValue, PasswordSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,7 +254,7 @@ namespace Umbraco.Core.Models.Membership
|
||||
[IgnoreDataMember]
|
||||
public string PasswordQuestion { get; set; }
|
||||
[IgnoreDataMember]
|
||||
public string PasswordAnswer { get; set; }
|
||||
public string RawPasswordAnswerValue { get; set; }
|
||||
[IgnoreDataMember]
|
||||
public string Comments { get; set; }
|
||||
[IgnoreDataMember]
|
||||
@@ -239,8 +271,8 @@ namespace Umbraco.Core.Models.Membership
|
||||
public int FailedPasswordAttempts { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation of IProfile
|
||||
|
||||
#region Implementation of IUser
|
||||
|
||||
[DataMember]
|
||||
public string Name
|
||||
@@ -249,17 +281,13 @@ namespace Umbraco.Core.Models.Membership
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_name = value;
|
||||
return _name;
|
||||
}, _name, NameSelector);
|
||||
{
|
||||
_name = value;
|
||||
return _name;
|
||||
}, _name, NameSelector);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation of IUser
|
||||
|
||||
public IEnumerable<string> AllowedSections
|
||||
{
|
||||
get { return _sectionCollection; }
|
||||
@@ -278,6 +306,11 @@ namespace Umbraco.Core.Models.Membership
|
||||
}
|
||||
}
|
||||
|
||||
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>
|
||||
@@ -354,20 +387,6 @@ namespace Umbraco.Core.Models.Membership
|
||||
}
|
||||
}
|
||||
|
||||
[DataMember]
|
||||
public object Id
|
||||
{
|
||||
get { return _id; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_id = value;
|
||||
return _id;
|
||||
}, _id, IdSelector);
|
||||
}
|
||||
}
|
||||
|
||||
[DataMember]
|
||||
public string Language
|
||||
{
|
||||
@@ -414,6 +433,19 @@ namespace Umbraco.Core.Models.Membership
|
||||
public IUserType UserType
|
||||
{
|
||||
get { return _userType; }
|
||||
set
|
||||
{
|
||||
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
|
||||
@@ -459,5 +491,30 @@ namespace Umbraco.Core.Models.Membership
|
||||
_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; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,10 +5,17 @@
|
||||
/// </summary>
|
||||
public class PreValue
|
||||
{
|
||||
public PreValue(int id, string value, int sortOrder)
|
||||
{
|
||||
Id = id;
|
||||
Value = value;
|
||||
SortOrder = sortOrder;
|
||||
}
|
||||
|
||||
public PreValue(int id, string value)
|
||||
{
|
||||
Value = value;
|
||||
Id = id;
|
||||
Id = id;
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public PreValue(string value)
|
||||
@@ -25,5 +32,10 @@
|
||||
/// The database id for the pre-value field value
|
||||
/// </summary>
|
||||
public int Id { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The sort order stored for the pre-value field value
|
||||
/// </summary>
|
||||
public int SortOrder { 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;
|
||||
|
||||
@@ -141,9 +141,21 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
if (GetPublishedContentTypeCallback != null)
|
||||
return GetPublishedContentTypeCallback(alias);
|
||||
|
||||
var contentType = itemType == PublishedItemType.Content
|
||||
? (IContentTypeComposition) ApplicationContext.Current.Services.ContentTypeService.GetContentType(alias)
|
||||
: (IContentTypeComposition) ApplicationContext.Current.Services.ContentTypeService.GetMediaType(alias);
|
||||
IContentTypeComposition contentType;
|
||||
switch (itemType)
|
||||
{
|
||||
case PublishedItemType.Content:
|
||||
contentType = ApplicationContext.Current.Services.ContentTypeService.GetContentType(alias);
|
||||
break;
|
||||
case PublishedItemType.Media:
|
||||
contentType = ApplicationContext.Current.Services.ContentTypeService.GetMediaType(alias);
|
||||
break;
|
||||
case PublishedItemType.Member:
|
||||
contentType = ApplicationContext.Current.Services.MemberTypeService.Get(alias);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException("itemType");
|
||||
}
|
||||
|
||||
if (contentType == null)
|
||||
throw new Exception(string.Format("ContentTypeService failed to find a {0} type with alias \"{1}\".",
|
||||
|
||||
@@ -269,7 +269,7 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
: Enumerable.Empty<IPropertyValueConverter>();
|
||||
}
|
||||
|
||||
class CompatConverter : PropertyValueConverterBase
|
||||
private class CompatConverter : PropertyValueConverterBase
|
||||
{
|
||||
private readonly IPropertyEditorValueConverter _converter;
|
||||
|
||||
|
||||
@@ -13,6 +13,11 @@ namespace Umbraco.Core.Models
|
||||
/// <summary>
|
||||
/// A media.
|
||||
/// </summary>
|
||||
Media
|
||||
Media,
|
||||
|
||||
/// <summary>
|
||||
/// A member.
|
||||
/// </summary>
|
||||
Member
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ namespace Umbraco.Core.Models.Rdbms
|
||||
internal class PreviewXmlDto
|
||||
{
|
||||
[Column("nodeId")]
|
||||
[PrimaryKeyColumn(AutoIncrement = false, Name = "", OnColumns = "nodeId, versionId")]
|
||||
[PrimaryKeyColumn(AutoIncrement = false, Name = "PK_cmsContentPreviewXml", OnColumns = "nodeId, versionId")]
|
||||
[ForeignKey(typeof(ContentDto), Column = "nodeId")]
|
||||
public int NodeId { get; set; }
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Umbraco.Core.Models.Rdbms
|
||||
internal class UserLoginDto
|
||||
{
|
||||
[Column("contextID")]
|
||||
[Index(IndexTypes.Clustered, Name = "umbracoUserLogins_Index")]
|
||||
[Index(IndexTypes.Clustered, Name = "IX_umbracoUserLogins_Index")]
|
||||
public Guid ContextId { get; set; }
|
||||
|
||||
[Column("userID")]
|
||||
|
||||
@@ -21,9 +21,18 @@ namespace Umbraco.Core.Models
|
||||
|
||||
public RelationType(Guid childObjectType, Guid parentObjectType, string @alias)
|
||||
{
|
||||
Mandate.ParameterNotNullOrEmpty(@alias, "alias");
|
||||
_childObjectType = childObjectType;
|
||||
_parentObjectType = parentObjectType;
|
||||
_alias = alias;
|
||||
Name = _alias;
|
||||
}
|
||||
|
||||
public RelationType(Guid childObjectType, Guid parentObjectType, string @alias, string name)
|
||||
:this(childObjectType, parentObjectType, @alias)
|
||||
{
|
||||
Mandate.ParameterNotNullOrEmpty(name, "name");
|
||||
Name = name;
|
||||
}
|
||||
|
||||
private static readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo<RelationType, string>(x => x.Name);
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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))
|
||||
{
|
||||
@@ -320,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))
|
||||
{
|
||||
@@ -332,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
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using umbraco.interfaces;
|
||||
|
||||
namespace Umbraco.Core.ObjectResolution
|
||||
@@ -8,7 +9,10 @@ namespace Umbraco.Core.ObjectResolution
|
||||
/// <summary>
|
||||
/// A resolver to return all IApplicationEvents objects
|
||||
/// </summary>
|
||||
internal sealed class ApplicationEventsResolver : ManyObjectsResolverBase<ApplicationEventsResolver, IApplicationEventHandler>
|
||||
/// <remarks>
|
||||
/// This is disposable because after the app has started it should be disposed to release any memory being occupied by instances.
|
||||
/// </remarks>
|
||||
internal sealed class ApplicationEventsResolver : ManyObjectsResolverBase<ApplicationEventsResolver, IApplicationEventHandler>, IDisposable
|
||||
{
|
||||
|
||||
private readonly LegacyStartupHandlerResolver _legacyResolver;
|
||||
@@ -53,7 +57,7 @@ namespace Umbraco.Core.ObjectResolution
|
||||
|
||||
protected override bool SupportsClear
|
||||
{
|
||||
get { return false; }
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
protected override bool SupportsInsert
|
||||
@@ -61,7 +65,7 @@ namespace Umbraco.Core.ObjectResolution
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
private class LegacyStartupHandlerResolver : ManyObjectsResolverBase<ApplicationEventsResolver, IApplicationStartupHandler>
|
||||
private class LegacyStartupHandlerResolver : ManyObjectsResolverBase<ApplicationEventsResolver, IApplicationStartupHandler>, IDisposable
|
||||
{
|
||||
internal LegacyStartupHandlerResolver(IEnumerable<Type> legacyStartupHandlers)
|
||||
: base(legacyStartupHandlers)
|
||||
@@ -73,7 +77,72 @@ namespace Umbraco.Core.ObjectResolution
|
||||
{
|
||||
get { return Values; }
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
ResetCollections();
|
||||
}
|
||||
}
|
||||
|
||||
private bool _disposed;
|
||||
private readonly ReaderWriterLockSlim _disposalLocker = new ReaderWriterLockSlim();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance is disposed.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance is disposed; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool IsDisposed
|
||||
{
|
||||
get { return _disposed; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
||||
/// </summary>
|
||||
/// <filterpriority>2</filterpriority>
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
|
||||
// Use SupressFinalize in case a subclass of this type implements a finalizer.
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
~ApplicationEventsResolver()
|
||||
{
|
||||
// Run dispose but let the class know it was due to the finalizer running.
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
private void Dispose(bool disposing)
|
||||
{
|
||||
// Only operate if we haven't already disposed
|
||||
if (IsDisposed || disposing == false) return;
|
||||
|
||||
using (new WriteLock(_disposalLocker))
|
||||
{
|
||||
// Check again now we're inside the lock
|
||||
if (IsDisposed) return;
|
||||
|
||||
// Call to actually release resources. This method is only
|
||||
// kept separate so that the entire disposal logic can be used as a VS snippet
|
||||
DisposeResources();
|
||||
|
||||
// Indicate that the instance has been disposed.
|
||||
_disposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clear out all of the instances, we don't want them hanging around and cluttering up memory
|
||||
/// </summary>
|
||||
private void DisposeResources()
|
||||
{
|
||||
_legacyResolver.Dispose();
|
||||
ResetCollections();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,7 @@ namespace Umbraco.Core.ObjectResolution
|
||||
/// <para>Important notes about this resolver: it does not support Insert or Remove and therefore does not support any ordering unless
|
||||
/// the types are marked with the WeightedPluginAttribute.</para>
|
||||
/// </remarks>
|
||||
internal abstract class LazyManyObjectsResolverBase<TResolver, TResolved> : ManyObjectsResolverBase<TResolver, TResolved>
|
||||
public abstract class LazyManyObjectsResolverBase<TResolver, TResolved> : ManyObjectsResolverBase<TResolver, TResolved>
|
||||
where TResolved : class
|
||||
where TResolver : ResolverBase
|
||||
{
|
||||
|
||||
@@ -322,7 +322,7 @@ namespace Umbraco.Core.ObjectResolution
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the list of types.
|
||||
/// Clears the list of types
|
||||
/// </summary>
|
||||
/// <exception cref="InvalidOperationException">the resolver does not support clearing types.</exception>
|
||||
public virtual void Clear()
|
||||
@@ -336,6 +336,20 @@ namespace Umbraco.Core.ObjectResolution
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// WARNING! Do not use this unless you know what you are doing, clear all types registered and instances
|
||||
/// created. Typically only used if a resolver is no longer used in an application and memory is to be GC'd
|
||||
/// </summary>
|
||||
internal void ResetCollections()
|
||||
{
|
||||
using (new WriteLock(_lock))
|
||||
{
|
||||
_instanceTypes.Clear();
|
||||
_sortedValues = null;
|
||||
_applicationInstances = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts a type at the specified index.
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Xml;
|
||||
|
||||
namespace Umbraco.Core.Packaging.Models
|
||||
{
|
||||
[Serializable]
|
||||
[DataContract(IsReference = true)]
|
||||
internal class InstallAction
|
||||
{
|
||||
public string Alias { get; set; }
|
||||
|
||||
public string PackageName { get; set; }
|
||||
|
||||
public string RunAt { get; set; }//NOTE Should this default to "install"
|
||||
|
||||
public bool Undo { get; set; }
|
||||
|
||||
public XmlNode XmlData { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Umbraco.Core.Packaging.Models
|
||||
{
|
||||
[Serializable]
|
||||
[DataContract(IsReference = true)]
|
||||
internal class InstallationSummary
|
||||
{
|
||||
public MetaData MetaData { get; set; }
|
||||
public IEnumerable<int> DataTypesInstalled { get; set; }
|
||||
public IEnumerable<int> LanguagesInstalled { get; set; }
|
||||
public IEnumerable<int> DictionaryItemsInstalled { get; set; }
|
||||
public IEnumerable<int> MacrosInstalled { get; set; }
|
||||
public IEnumerable<KeyValuePair<string, bool>> FilesInstalled { get; set;}
|
||||
public IEnumerable<int> TemplatesInstalled { get; set; }
|
||||
public IEnumerable<int> DocumentTypesInstalled { get; set; }
|
||||
public IEnumerable<int> StylesheetsInstalled { get; set; }
|
||||
public IEnumerable<int> DocumentsInstalled { get; set; }
|
||||
public IEnumerable<InstallAction> InstallActions { get; set; }
|
||||
public IEnumerable<UninstallAction> UninstallActions { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Umbraco.Core.Packaging.Models
|
||||
{
|
||||
[Serializable]
|
||||
[DataContract(IsReference = true)]
|
||||
internal class MetaData
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Version { get; set; }
|
||||
public string Url { get; set; }
|
||||
public string License { get; set; }
|
||||
public string LicenseUrl { get; set; }
|
||||
public int ReqMajor { get; set; }
|
||||
public int ReqMinor { get; set; }
|
||||
public int ReqPatch { get; set; }
|
||||
public string AuthorName { get; set; }
|
||||
public string AuthorUrl { get; set; }
|
||||
public string Readme { get; set; }
|
||||
public string Control { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Xml;
|
||||
|
||||
namespace Umbraco.Core.Packaging.Models
|
||||
{
|
||||
[Serializable]
|
||||
[DataContract(IsReference = true)]
|
||||
internal class UninstallAction
|
||||
{
|
||||
public string Alias { get; set; }
|
||||
|
||||
public string PackageName { get; set; }
|
||||
|
||||
public string RunAt { get; set; }//NOTE Should this default to "install"
|
||||
|
||||
public bool Undo { get; set; }//NOTE: Should thid default to "False"?
|
||||
|
||||
public XmlNode XmlData { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
namespace Umbraco.Core.Packaging
|
||||
{
|
||||
internal interface IPackageBuilding
|
||||
{
|
||||
}
|
||||
|
||||
internal class PackageBuilding : IPackageBuilding
|
||||
{
|
||||
private readonly PackagingService _packagingService;
|
||||
|
||||
public PackageBuilding(PackagingService packagingService)
|
||||
{
|
||||
_packagingService = packagingService;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Umbraco.Core.IO;
|
||||
|
||||
namespace Umbraco.Core.Packaging
|
||||
{
|
||||
internal interface IPackageExtraction
|
||||
{
|
||||
bool Extract(string packageFilePath, string destinationFolder);
|
||||
string ExtractToTemporaryFolder(string packageFilePath);
|
||||
string GetPackageConfigFromArchive(string packageFilePath, string fileToRead = "package.xml");
|
||||
}
|
||||
|
||||
internal class PackageExtraction : IPackageExtraction
|
||||
{
|
||||
public bool Extract(string packageFilePath, string destinationFolder)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public string ExtractToTemporaryFolder(string packageFilePath)
|
||||
{
|
||||
string tempDir = Path.Combine(IOHelper.MapPath(SystemDirectories.Data), Guid.NewGuid().ToString("D"));
|
||||
Directory.CreateDirectory(tempDir);
|
||||
Extract(packageFilePath, tempDir);
|
||||
return tempDir;
|
||||
}
|
||||
|
||||
public string GetPackageConfigFromArchive(string packageFilePath, string fileToRead = "package.xml")
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using Umbraco.Core.Packaging.Models;
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
namespace Umbraco.Core.Packaging
|
||||
{
|
||||
internal interface IPackageInstallation
|
||||
{
|
||||
InstallationSummary InstallPackage(string packageFilePath, int userId = 0);
|
||||
MetaData GetPackageMetaData(string packageFilePath);
|
||||
}
|
||||
|
||||
internal class PackageInstallation : IPackageInstallation
|
||||
{
|
||||
private readonly PackagingService _packagingService;
|
||||
private readonly PackageExtraction _packageExtraction;
|
||||
|
||||
public PackageInstallation(PackagingService packagingService, PackageExtraction packageExtraction)
|
||||
{
|
||||
_packagingService = packagingService;
|
||||
_packageExtraction = packageExtraction;
|
||||
}
|
||||
|
||||
public InstallationSummary InstallPackage(string packageFilePath, int userId = 0)
|
||||
{
|
||||
var summary = new InstallationSummary();
|
||||
return summary;
|
||||
}
|
||||
|
||||
public MetaData GetPackageMetaData(string packageFilePath)
|
||||
{
|
||||
var metaData = new MetaData();
|
||||
return metaData;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
namespace Umbraco.Core.Persistence.DatabaseModelDefinitions
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a database index definition retreived by querying the database
|
||||
/// </summary>
|
||||
internal class DbIndexDefinition
|
||||
{
|
||||
public virtual string IndexName { get; set; }
|
||||
public virtual string TableName { get; set; }
|
||||
public virtual string ColumnName { get; set; }
|
||||
public virtual bool IsUnique { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
using System.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Umbraco.Core.Persistence
|
||||
{
|
||||
internal static class DbConnectionExtensions
|
||||
{
|
||||
|
||||
public static DatabaseProviders DetectProviderFromConnectionString(string connString)
|
||||
{
|
||||
var builder = new DbConnectionStringBuilder {ConnectionString = connString};
|
||||
var allKeys = builder.Keys.Cast<string>();
|
||||
|
||||
var mySql = new[] {"Server", "Database", "Uid", "Pwd"};
|
||||
if (mySql.All(x => allKeys.InvariantContains(x)))
|
||||
{
|
||||
return DatabaseProviders.MySql;
|
||||
}
|
||||
|
||||
if (allKeys.InvariantContains("Data Source")
|
||||
//this dictionary is case insensitive
|
||||
&& builder["Data source"].ToString().InvariantContains(".sdf"))
|
||||
{
|
||||
return DatabaseProviders.SqlServerCE;
|
||||
}
|
||||
|
||||
return DatabaseProviders.SqlServer;
|
||||
}
|
||||
|
||||
public static bool IsConnectionAvailable(string connString, DatabaseProviders provider)
|
||||
{
|
||||
DbProviderFactory factory;
|
||||
switch (provider)
|
||||
{
|
||||
case DatabaseProviders.SqlServer:
|
||||
case DatabaseProviders.SqlAzure:
|
||||
factory = DbProviderFactories.GetFactory("System.Data.SqlClient");
|
||||
break;
|
||||
case DatabaseProviders.SqlServerCE:
|
||||
factory = DbProviderFactories.GetFactory("System.Data.SqlServerCe.4.0");
|
||||
break;
|
||||
case DatabaseProviders.MySql:
|
||||
factory = DbProviderFactories.GetFactory("MySql.Data.MySqlClient");
|
||||
break;
|
||||
case DatabaseProviders.PostgreSQL:
|
||||
case DatabaseProviders.Oracle:
|
||||
case DatabaseProviders.SQLite:
|
||||
default:
|
||||
throw new NotSupportedException("The provider " + provider + " is not supported");
|
||||
}
|
||||
|
||||
var conn = factory.CreateConnection();
|
||||
if (conn == null)
|
||||
{
|
||||
throw new InvalidOperationException("Could not create a connection for provider " + provider);
|
||||
}
|
||||
conn.ConnectionString = connString;
|
||||
using (var connection = conn)
|
||||
{
|
||||
return connection.IsAvailable();
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsAvailable(this IDbConnection connection)
|
||||
{
|
||||
try
|
||||
{
|
||||
connection.Open();
|
||||
connection.Close();
|
||||
}
|
||||
catch (SqlException)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,7 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
NodeId = entity.Id,
|
||||
Email = entity.Email,
|
||||
LoginName = entity.Username,
|
||||
Password = entity.Password,
|
||||
Password = entity.RawPasswordValue,
|
||||
ContentVersionDto = BuildDto(entity as Member)
|
||||
};
|
||||
return member;
|
||||
|
||||
@@ -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
|
||||
|
||||
}
|
||||
}
|
||||
@@ -19,13 +19,13 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
{
|
||||
var properties = CreateProperties(_memberTypes[dto.ContentTypeAlias], dto.Properties, dto.CreateDate);
|
||||
|
||||
var member = new Member(dto.Text, dto.Email, dto.LoginName, dto.Password, dto.ParentId, _memberTypes[dto.ContentTypeAlias])
|
||||
var member = new Member(dto.Text, dto.Email, dto.LoginName, dto.Password, _memberTypes[dto.ContentTypeAlias])
|
||||
{
|
||||
Id = dto.NodeId,
|
||||
CreateDate = dto.CreateDate,
|
||||
UpdateDate = dto.UpdateDate,
|
||||
Name = dto.Text,
|
||||
ProviderUserKey = dto.UniqueId.Value,
|
||||
ProviderUserKey = dto.NodeId,
|
||||
Trashed = dto.Trashed,
|
||||
Key = dto.UniqueId.Value,
|
||||
CreatorId = dto.UserId.HasValue ? dto.UserId.Value : 0,
|
||||
@@ -33,7 +33,6 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
Path = dto.Path,
|
||||
SortOrder = dto.SortOrder,
|
||||
Version = dto.VersionId,
|
||||
ContentTypeAlias = dto.ContentTypeAlias,
|
||||
Properties = new PropertyCollection(properties)
|
||||
};
|
||||
|
||||
|
||||
@@ -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.GetStandardPropertyTypeStubs();
|
||||
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);
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
Key = guidId,
|
||||
StartContentId = dto.ContentStartId,
|
||||
StartMediaId = dto.MediaStartId.HasValue ? dto.MediaStartId.Value : -1,
|
||||
Password = dto.Password,
|
||||
RawPasswordValue = dto.Password,
|
||||
Username = dto.Login,
|
||||
Name = dto.UserName,
|
||||
IsLockedOut = dto.NoConsole,
|
||||
@@ -59,7 +59,7 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
Email = entity.Email,
|
||||
Login = entity.Username,
|
||||
NoConsole = entity.IsLockedOut,
|
||||
Password = entity.Password,
|
||||
Password = entity.RawPasswordValue,
|
||||
UserLanguage = entity.Language,
|
||||
UserName = entity.Name,
|
||||
Type = short.Parse(entity.UserType.Id.ToString(CultureInfo.InvariantCulture)),
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -48,12 +48,12 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
|
||||
CacheMap<Member, MemberDto>(src => src.Email, dto => dto.Email);
|
||||
CacheMap<Member, MemberDto>(src => src.Username, dto => dto.LoginName);
|
||||
CacheMap<Member, MemberDto>(src => src.Password, dto => dto.Password);
|
||||
CacheMap<Member, MemberDto>(src => src.RawPasswordValue, dto => dto.Password);
|
||||
|
||||
CacheMap<Member, PropertyDataDto>(src => src.IsApproved, dto => dto.Integer);
|
||||
CacheMap<Member, PropertyDataDto>(src => src.IsLockedOut, dto => dto.Integer);
|
||||
CacheMap<Member, PropertyDataDto>(src => src.Comments, dto => dto.Text);
|
||||
CacheMap<Member, PropertyDataDto>(src => src.PasswordAnswer, dto => dto.VarChar);
|
||||
CacheMap<Member, PropertyDataDto>(src => src.RawPasswordAnswerValue, dto => dto.VarChar);
|
||||
CacheMap<Member, PropertyDataDto>(src => src.PasswordQuestion, dto => dto.VarChar);
|
||||
CacheMap<Member, PropertyDataDto>(src => src.FailedPasswordAttempts, dto => dto.Integer);
|
||||
CacheMap<Member, PropertyDataDto>(src => src.LastLockoutDate, dto => dto.Date);
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
using System.Collections.Concurrent;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Mappers
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a <see cref="Tag"/> to DTO mapper used to translate the properties of the public api
|
||||
/// implementation to that of the database's DTO as sql: [tableName].[columnName].
|
||||
/// </summary>
|
||||
[MapperFor(typeof(Tag))]
|
||||
[MapperFor(typeof(ITag))]
|
||||
public sealed class TagMapper : 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 TagMapper()
|
||||
{
|
||||
BuildMap();
|
||||
}
|
||||
|
||||
#region Overrides of BaseMapper
|
||||
|
||||
internal override ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache
|
||||
{
|
||||
get { return PropertyInfoCacheInstance; }
|
||||
}
|
||||
|
||||
internal override void BuildMap()
|
||||
{
|
||||
if (PropertyInfoCache.IsEmpty)
|
||||
{
|
||||
CacheMap<Tag, TagDto>(src => src.Id, dto => dto.Id);
|
||||
CacheMap<Tag, TagDto>(src => src.Text, dto => dto.Tag);
|
||||
CacheMap<Tag, TagDto>(src => src.Group, dto => dto.Group);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -31,7 +31,7 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
CacheMap<User, UserDto>(src => src.Id, dto => dto.Id);
|
||||
CacheMap<User, UserDto>(src => src.Email, dto => dto.Email);
|
||||
CacheMap<User, UserDto>(src => src.Username, dto => dto.Login);
|
||||
CacheMap<User, UserDto>(src => src.Password, dto => dto.Password);
|
||||
CacheMap<User, UserDto>(src => src.RawPasswordValue, dto => dto.Password);
|
||||
CacheMap<User, UserDto>(src => src.Name, dto => dto.UserName);
|
||||
//NOTE: This column in the db is *not* used!
|
||||
//CacheMap<User, UserDto>(src => src.DefaultPermissions, dto => dto.DefaultPermissions);
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations
|
||||
{
|
||||
/// <summary>
|
||||
/// Used if a migration has executed but the whole process has failed and cannot be rolled back
|
||||
/// </summary>
|
||||
internal class DataLossException : Exception
|
||||
{
|
||||
public DataLossException(string msg)
|
||||
: base(msg)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public DataLossException(string msg, Exception inner)
|
||||
: base(msg, inner)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
@@ -121,67 +124,60 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
|
||||
{
|
||||
var result = new DatabaseSchemaResult();
|
||||
|
||||
//get the db index defs
|
||||
result.DbIndexDefinitions = SqlSyntaxContext.SqlSyntaxProvider.GetDefinedIndexes(_database)
|
||||
.Select(x => new DbIndexDefinition()
|
||||
{
|
||||
TableName = x.Item1,
|
||||
IndexName = x.Item2,
|
||||
ColumnName = x.Item3,
|
||||
IsUnique = x.Item4
|
||||
}).ToArray();
|
||||
|
||||
foreach (var item in OrderedTables.OrderBy(x => x.Key))
|
||||
{
|
||||
var tableDefinition = DefinitionFactory.GetTableDefinition(item.Value);
|
||||
result.TableDefinitions.Add(tableDefinition);
|
||||
}
|
||||
|
||||
//Check tables in configured database against tables in schema
|
||||
var tablesInDatabase = SqlSyntaxContext.SqlSyntaxProvider.GetTablesInSchema(_database).ToList();
|
||||
var tablesInSchema = result.TableDefinitions.Select(x => x.Name).ToList();
|
||||
//Add valid and invalid table differences to the result object
|
||||
var validTableDifferences = tablesInDatabase.Intersect(tablesInSchema);
|
||||
foreach (var tableName in validTableDifferences)
|
||||
{
|
||||
result.ValidTables.Add(tableName);
|
||||
}
|
||||
var invalidTableDifferences =
|
||||
tablesInDatabase.Except(tablesInSchema)
|
||||
.Union(tablesInSchema.Except(tablesInDatabase));
|
||||
foreach (var tableName in invalidTableDifferences)
|
||||
{
|
||||
result.Errors.Add(new Tuple<string, string>("Table", tableName));
|
||||
}
|
||||
ValidateDbTables(result);
|
||||
|
||||
//Check columns in configured database against columns in schema
|
||||
var columnsInDatabase = SqlSyntaxContext.SqlSyntaxProvider.GetColumnsInSchema(_database);
|
||||
var columnsPerTableInDatabase = columnsInDatabase.Select(x => string.Concat(x.TableName, ",", x.ColumnName)).ToList();
|
||||
var columnsPerTableInSchema = result.TableDefinitions.SelectMany(x => x.Columns.Select(y => string.Concat(y.TableName, ",", y.Name))).ToList();
|
||||
//Add valid and invalid column differences to the result object
|
||||
var validColumnDifferences = columnsPerTableInDatabase.Intersect(columnsPerTableInSchema);
|
||||
foreach (var column in validColumnDifferences)
|
||||
{
|
||||
result.ValidColumns.Add(column);
|
||||
}
|
||||
var invalidColumnDifferences = columnsPerTableInDatabase.Except(columnsPerTableInSchema);
|
||||
foreach (var column in invalidColumnDifferences)
|
||||
{
|
||||
result.Errors.Add(new Tuple<string, string>("Column", column));
|
||||
}
|
||||
ValidateDbColumns(result);
|
||||
|
||||
ValidateDbIndexes(result);
|
||||
|
||||
ValidateDbConstraints(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void ValidateDbConstraints(DatabaseSchemaResult result)
|
||||
{
|
||||
//MySql doesn't conform to the "normal" naming of constraints, so there is currently no point in doing these checks.
|
||||
//NOTE: At a later point we do other checks for MySql, but ideally it should be necessary to do special checks for different providers.
|
||||
//TODO: At a later point we do other checks for MySql, but ideally it should be necessary to do special checks for different providers.
|
||||
// ALso note that to get the constraints for MySql we have to open a connection which we currently have not.
|
||||
if (SqlSyntaxContext.SqlSyntaxProvider is MySqlSyntaxProvider)
|
||||
return result;
|
||||
return;
|
||||
|
||||
//Check constraints in configured database against constraints in schema
|
||||
var constraintsInDatabase = SqlSyntaxContext.SqlSyntaxProvider.GetConstraintsPerColumn(_database).DistinctBy(x => x.Item3).ToList();
|
||||
var foreignKeysInDatabase = constraintsInDatabase.Where(x => x.Item3.StartsWith("FK_")).Select(x => x.Item3).ToList();
|
||||
var primaryKeysInDatabase = constraintsInDatabase.Where(x => x.Item3.StartsWith("PK_")).Select(x => x.Item3).ToList();
|
||||
var indexesInDatabase = constraintsInDatabase.Where(x => x.Item3.StartsWith("IX_")).Select(x => x.Item3).ToList();
|
||||
var foreignKeysInDatabase = constraintsInDatabase.Where(x => x.Item3.InvariantStartsWith("FK_")).Select(x => x.Item3).ToList();
|
||||
var primaryKeysInDatabase = constraintsInDatabase.Where(x => x.Item3.InvariantStartsWith("PK_")).Select(x => x.Item3).ToList();
|
||||
var indexesInDatabase = constraintsInDatabase.Where(x => x.Item3.InvariantStartsWith("IX_")).Select(x => x.Item3).ToList();
|
||||
var indexesInSchema = result.TableDefinitions.SelectMany(x => x.Indexes.Select(y => y.Name)).ToList();
|
||||
var unknownConstraintsInDatabase =
|
||||
constraintsInDatabase.Where(
|
||||
x =>
|
||||
x.Item3.StartsWith("FK_") == false && x.Item3.StartsWith("PK_") == false &&
|
||||
x.Item3.StartsWith("IX_") == false).Select(x => x.Item3).ToList();
|
||||
x.Item3.InvariantStartsWith("FK_") == false && x.Item3.InvariantStartsWith("PK_") == false &&
|
||||
x.Item3.InvariantStartsWith("IX_") == false).Select(x => x.Item3).ToList();
|
||||
var foreignKeysInSchema = result.TableDefinitions.SelectMany(x => x.ForeignKeys.Select(y => y.Name)).ToList();
|
||||
var primaryKeysInSchema = result.TableDefinitions.SelectMany(x => x.Columns.Select(y => y.PrimaryKeyName)).ToList();
|
||||
var indexesInSchema = result.TableDefinitions.SelectMany(x => x.Indexes.Select(y => y.Name)).ToList();
|
||||
var primaryKeysInSchema = result.TableDefinitions.SelectMany(x => x.Columns.Select(y => y.PrimaryKeyName))
|
||||
.Where(x => x.IsNullOrWhiteSpace() == false).ToList();
|
||||
|
||||
//Add valid and invalid foreign key differences to the result object
|
||||
foreach (var unknown in unknownConstraintsInDatabase)
|
||||
{
|
||||
if (foreignKeysInSchema.Contains(unknown) || primaryKeysInSchema.Contains(unknown) || indexesInSchema.Contains(unknown))
|
||||
if (foreignKeysInSchema.InvariantContains(unknown) || primaryKeysInSchema.InvariantContains(unknown) || indexesInSchema.InvariantContains(unknown))
|
||||
{
|
||||
result.ValidConstraints.Add(unknown);
|
||||
}
|
||||
@@ -190,40 +186,122 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
|
||||
result.Errors.Add(new Tuple<string, string>("Unknown", unknown));
|
||||
}
|
||||
}
|
||||
var validForeignKeyDifferences = foreignKeysInDatabase.Intersect(foreignKeysInSchema);
|
||||
|
||||
//Foreign keys:
|
||||
|
||||
var validForeignKeyDifferences = foreignKeysInDatabase.Intersect(foreignKeysInSchema, StringComparer.InvariantCultureIgnoreCase);
|
||||
foreach (var foreignKey in validForeignKeyDifferences)
|
||||
{
|
||||
result.ValidConstraints.Add(foreignKey);
|
||||
}
|
||||
var invalidForeignKeyDifferences = foreignKeysInDatabase.Except(foreignKeysInSchema);
|
||||
var invalidForeignKeyDifferences =
|
||||
foreignKeysInDatabase.Except(foreignKeysInSchema, StringComparer.InvariantCultureIgnoreCase)
|
||||
.Union(foreignKeysInSchema.Except(foreignKeysInDatabase, StringComparer.InvariantCultureIgnoreCase));
|
||||
foreach (var foreignKey in invalidForeignKeyDifferences)
|
||||
{
|
||||
result.Errors.Add(new Tuple<string, string>("Constraint", foreignKey));
|
||||
}
|
||||
|
||||
|
||||
//Primary keys:
|
||||
|
||||
//Add valid and invalid primary key differences to the result object
|
||||
var validPrimaryKeyDifferences = primaryKeysInDatabase.Intersect(primaryKeysInSchema);
|
||||
var validPrimaryKeyDifferences = primaryKeysInDatabase.Intersect(primaryKeysInSchema, StringComparer.InvariantCultureIgnoreCase);
|
||||
foreach (var primaryKey in validPrimaryKeyDifferences)
|
||||
{
|
||||
result.ValidConstraints.Add(primaryKey);
|
||||
}
|
||||
var invalidPrimaryKeyDifferences = primaryKeysInDatabase.Except(primaryKeysInSchema);
|
||||
var invalidPrimaryKeyDifferences =
|
||||
primaryKeysInDatabase.Except(primaryKeysInSchema, StringComparer.InvariantCultureIgnoreCase)
|
||||
.Union(primaryKeysInSchema.Except(primaryKeysInDatabase, StringComparer.InvariantCultureIgnoreCase));
|
||||
foreach (var primaryKey in invalidPrimaryKeyDifferences)
|
||||
{
|
||||
result.Errors.Add(new Tuple<string, string>("Constraint", primaryKey));
|
||||
}
|
||||
|
||||
//Constaints:
|
||||
|
||||
//NOTE: SD: The colIndex checks above should really take care of this but I need to keep this here because it was here before
|
||||
// and some schema validation checks might rely on this data remaining here!
|
||||
//Add valid and invalid index differences to the result object
|
||||
var validIndexDifferences = indexesInDatabase.Intersect(indexesInSchema);
|
||||
var validIndexDifferences = indexesInDatabase.Intersect(indexesInSchema, StringComparer.InvariantCultureIgnoreCase);
|
||||
foreach (var index in validIndexDifferences)
|
||||
{
|
||||
result.ValidConstraints.Add(index);
|
||||
}
|
||||
var invalidIndexDifferences = indexesInDatabase.Except(indexesInSchema);
|
||||
var invalidIndexDifferences =
|
||||
indexesInDatabase.Except(indexesInSchema, StringComparer.InvariantCultureIgnoreCase)
|
||||
.Union(indexesInSchema.Except(indexesInDatabase, StringComparer.InvariantCultureIgnoreCase));
|
||||
foreach (var index in invalidIndexDifferences)
|
||||
{
|
||||
result.Errors.Add(new Tuple<string, string>("Constraint", index));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
private void ValidateDbColumns(DatabaseSchemaResult result)
|
||||
{
|
||||
//Check columns in configured database against columns in schema
|
||||
var columnsInDatabase = SqlSyntaxContext.SqlSyntaxProvider.GetColumnsInSchema(_database);
|
||||
var columnsPerTableInDatabase = columnsInDatabase.Select(x => string.Concat(x.TableName, ",", x.ColumnName)).ToList();
|
||||
var columnsPerTableInSchema = result.TableDefinitions.SelectMany(x => x.Columns.Select(y => string.Concat(y.TableName, ",", y.Name))).ToList();
|
||||
//Add valid and invalid column differences to the result object
|
||||
var validColumnDifferences = columnsPerTableInDatabase.Intersect(columnsPerTableInSchema, StringComparer.InvariantCultureIgnoreCase);
|
||||
foreach (var column in validColumnDifferences)
|
||||
{
|
||||
result.ValidColumns.Add(column);
|
||||
}
|
||||
|
||||
var invalidColumnDifferences =
|
||||
columnsPerTableInDatabase.Except(columnsPerTableInSchema, StringComparer.InvariantCultureIgnoreCase)
|
||||
.Union(columnsPerTableInSchema.Except(columnsPerTableInDatabase, StringComparer.InvariantCultureIgnoreCase));
|
||||
foreach (var column in invalidColumnDifferences)
|
||||
{
|
||||
result.Errors.Add(new Tuple<string, string>("Column", column));
|
||||
}
|
||||
}
|
||||
|
||||
private void ValidateDbTables(DatabaseSchemaResult result)
|
||||
{
|
||||
//Check tables in configured database against tables in schema
|
||||
var tablesInDatabase = SqlSyntaxContext.SqlSyntaxProvider.GetTablesInSchema(_database).ToList();
|
||||
var tablesInSchema = result.TableDefinitions.Select(x => x.Name).ToList();
|
||||
//Add valid and invalid table differences to the result object
|
||||
var validTableDifferences = tablesInDatabase.Intersect(tablesInSchema, StringComparer.InvariantCultureIgnoreCase);
|
||||
foreach (var tableName in validTableDifferences)
|
||||
{
|
||||
result.ValidTables.Add(tableName);
|
||||
}
|
||||
|
||||
var invalidTableDifferences =
|
||||
tablesInDatabase.Except(tablesInSchema, StringComparer.InvariantCultureIgnoreCase)
|
||||
.Union(tablesInSchema.Except(tablesInDatabase, StringComparer.InvariantCultureIgnoreCase));
|
||||
foreach (var tableName in invalidTableDifferences)
|
||||
{
|
||||
result.Errors.Add(new Tuple<string, string>("Table", tableName));
|
||||
}
|
||||
}
|
||||
|
||||
private void ValidateDbIndexes(DatabaseSchemaResult result)
|
||||
{
|
||||
//These are just column indexes NOT constraints or Keys
|
||||
//var colIndexesInDatabase = result.DbIndexDefinitions.Where(x => x.IndexName.InvariantStartsWith("IX_")).Select(x => x.IndexName).ToList();
|
||||
var colIndexesInDatabase = result.DbIndexDefinitions.Select(x => x.IndexName).ToList();
|
||||
var indexesInSchema = result.TableDefinitions.SelectMany(x => x.Indexes.Select(y => y.Name)).ToList();
|
||||
|
||||
//Add valid and invalid index differences to the result object
|
||||
var validColIndexDifferences = colIndexesInDatabase.Intersect(indexesInSchema, StringComparer.InvariantCultureIgnoreCase);
|
||||
foreach (var index in validColIndexDifferences)
|
||||
{
|
||||
result.ValidIndexes.Add(index);
|
||||
}
|
||||
|
||||
var invalidColIndexDifferences =
|
||||
colIndexesInDatabase.Except(indexesInSchema, StringComparer.InvariantCultureIgnoreCase)
|
||||
.Union(indexesInSchema.Except(colIndexesInDatabase, StringComparer.InvariantCultureIgnoreCase));
|
||||
foreach (var index in invalidColIndexDifferences)
|
||||
{
|
||||
result.Errors.Add(new Tuple<string, string>("Index", index));
|
||||
}
|
||||
}
|
||||
|
||||
#region Events
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@@ -17,6 +17,7 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
|
||||
ValidTables = new List<string>();
|
||||
ValidColumns = new List<string>();
|
||||
ValidConstraints = new List<string>();
|
||||
ValidIndexes = new List<string>();
|
||||
}
|
||||
|
||||
public List<Tuple<string, string>> Errors { get; set; }
|
||||
@@ -29,6 +30,10 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
|
||||
|
||||
public List<string> ValidConstraints { get; set; }
|
||||
|
||||
public List<string> ValidIndexes { get; set; }
|
||||
|
||||
internal IEnumerable<DbIndexDefinition> DbIndexDefinitions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines the version of the currently installed database.
|
||||
/// </summary>
|
||||
@@ -39,43 +44,53 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
|
||||
public Version DetermineInstalledVersion()
|
||||
{
|
||||
//If (ValidTables.Count == 0) database is empty and we return -> new Version(0, 0, 0);
|
||||
if(ValidTables.Count == 0)
|
||||
if (ValidTables.Count == 0)
|
||||
return new Version(0, 0, 0);
|
||||
|
||||
//If Errors is empty or if TableDefinitions tables + columns correspond to valid tables + columns then we're at current version
|
||||
if (!Errors.Any() ||
|
||||
if (Errors.Any() == false ||
|
||||
(TableDefinitions.All(x => ValidTables.Contains(x.Name))
|
||||
&& TableDefinitions.SelectMany(definition => definition.Columns).All(x => ValidColumns.Contains(x.Name))))
|
||||
return UmbracoVersion.Current;
|
||||
|
||||
//If Errors contains umbracoApp or umbracoAppTree its pre-6.0.0 -> new Version(4, 10, 0);
|
||||
if (Errors.Any(x => x.Item1.Equals("Table") && (x.Item2.Equals("umbracoApp") || x.Item2.Equals("umbracoAppTree"))))
|
||||
if (Errors.Any(x => x.Item1.Equals("Table") && (x.Item2.InvariantEquals("umbracoApp") || x.Item2.InvariantEquals("umbracoAppTree"))))
|
||||
{
|
||||
//If Errors contains umbracoUser2app or umbracoAppTree foreignkey to umbracoApp exists its pre-4.8.0 -> new Version(4, 7, 0);
|
||||
if (Errors.Any(x =>
|
||||
x.Item1.Equals("Constraint")
|
||||
&& (x.Item2.Contains("umbracoUser2app_umbracoApp")
|
||||
|| x.Item2.Contains("umbracoAppTree_umbracoApp"))))
|
||||
&& (x.Item2.InvariantContains("umbracoUser2app_umbracoApp")
|
||||
|| x.Item2.InvariantContains("umbracoAppTree_umbracoApp"))))
|
||||
{
|
||||
return new Version(4, 7, 0);
|
||||
}
|
||||
|
||||
return new Version(4, 9, 0);
|
||||
}
|
||||
|
||||
|
||||
//if the error is for umbracoServer
|
||||
if (Errors.Any(x => x.Item1.Equals("Table") && (x.Item2.Equals("umbracoServer"))))
|
||||
if (Errors.Any(x => x.Item1.Equals("Table") && (x.Item2.InvariantEquals("umbracoServer"))))
|
||||
{
|
||||
return new Version(6, 0, 0);
|
||||
}
|
||||
|
||||
//if the error indicates a problem with the column cmsMacroProperty.macroPropertyType then it is not version 7 and the
|
||||
// last db change we made was the umbracoServer in 6.1
|
||||
if (Errors.Any(x => x.Item1.Equals("Column") && (x.Item2.Equals("cmsMacroProperty,macroPropertyType"))))
|
||||
//if the error indicates a problem with the column cmsMacroProperty.macroPropertyType then it is not version 7
|
||||
// since these columns get removed in v7
|
||||
if (Errors.Any(x => x.Item1.Equals("Column") && (x.Item2.InvariantEquals("cmsMacroProperty,macroPropertyType"))))
|
||||
{
|
||||
return new Version(6, 1, 0);
|
||||
//if the error is for this IX_umbracoNodeTrashed which is added in 6.2 AND in 7.1 but we do not have the above columns
|
||||
// then it must mean that we aren't on 6.2 so must be 6.1
|
||||
if (Errors.Any(x => x.Item1.Equals("Index") && (x.Item2.InvariantEquals("IX_umbracoNodeTrashed"))))
|
||||
{
|
||||
return new Version(6, 1, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
//if there are no errors for that index, then the person must have 6.2 installed
|
||||
return new Version(6, 2, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return UmbracoVersion.Current;
|
||||
}
|
||||
|
||||
@@ -113,6 +128,13 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
|
||||
sb.AppendLine(string.Join(",", Errors.Where(x => x.Item1.Equals("Constraint")).Select(x => x.Item2)));
|
||||
sb.AppendLine(" ");
|
||||
}
|
||||
//Index error summary
|
||||
if (Errors.Any(x => x.Item1.Equals("Index")))
|
||||
{
|
||||
sb.AppendLine("The following indexes were found in the database, but are not in the current schema:");
|
||||
sb.AppendLine(string.Join(",", Errors.Where(x => x.Item1.Equals("Index")).Select(x => x.Item2)));
|
||||
sb.AppendLine(" ");
|
||||
}
|
||||
//Unknown constraint error summary
|
||||
if (Errors.Any(x => x.Item1.Equals("Unknown")))
|
||||
{
|
||||
|
||||
@@ -6,8 +6,8 @@ namespace Umbraco.Core.Persistence.Migrations
|
||||
/// Represents the Migration attribute, which is used to mark classes as
|
||||
/// database migrations with Up/Down methods for pushing changes UP or pulling them DOWN.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class MigrationAttribute : Attribute
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
|
||||
public sealed class MigrationAttribute : Attribute
|
||||
{
|
||||
public MigrationAttribute(string targetVersion, int sortOrder, string product)
|
||||
{
|
||||
@@ -16,8 +16,21 @@ namespace Umbraco.Core.Persistence.Migrations
|
||||
ProductName = product;
|
||||
}
|
||||
|
||||
public MigrationAttribute(string minimumCurrentVersion, string targetVersion, int sortOrder, string product)
|
||||
{
|
||||
TargetVersion = new Version(targetVersion);
|
||||
MinimumCurrentVersion = new Version(minimumCurrentVersion);
|
||||
SortOrder = sortOrder;
|
||||
ProductName = product;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the target version of this migration.
|
||||
/// Gets the minimum current version for which this migration is allowed to execute
|
||||
/// </summary>
|
||||
public Version MinimumCurrentVersion { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the target version of this migration.
|
||||
/// </summary>
|
||||
public Version TargetVersion { get; private set; }
|
||||
|
||||
|
||||
@@ -27,26 +27,8 @@ namespace Umbraco.Core.Persistence.Migrations
|
||||
/// </summary>
|
||||
public IEnumerable<IMigration> Migrations
|
||||
{
|
||||
get { return GetSortedValues(); }
|
||||
get { return Values; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Override how we determine object weight, for this resolver we use the MigrationAttribute attribute
|
||||
/// </summary>
|
||||
/// <param name="o"></param>
|
||||
/// <returns></returns>
|
||||
protected override int GetObjectWeight(object o)
|
||||
{
|
||||
var type = o.GetType();
|
||||
var attr = type.GetCustomAttribute<MigrationAttribute>(true);
|
||||
return attr == null ? DefaultPluginWeight : attr.SortOrder;
|
||||
}
|
||||
|
||||
protected override int DefaultPluginWeight
|
||||
{
|
||||
get { return 0; } //set's the default to 0
|
||||
set { base.DefaultPluginWeight = value; }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -3,22 +3,23 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Events;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Persistence.Migrations.Syntax.IfDatabase;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations
|
||||
{
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// Represents the Migration Runner, which is used to apply migrations to
|
||||
/// the umbraco database.
|
||||
/// </summary>
|
||||
public class MigrationRunner
|
||||
{
|
||||
private readonly Version _configuredVersion;
|
||||
private readonly Version _currentVersion;
|
||||
private readonly Version _targetVersion;
|
||||
private readonly string _productName;
|
||||
|
||||
public MigrationRunner(Version configuredVersion, Version targetVersion, string productName)
|
||||
public MigrationRunner(Version currentVersion, Version targetVersion, string productName)
|
||||
{
|
||||
_configuredVersion = configuredVersion;
|
||||
_currentVersion = currentVersion;
|
||||
_targetVersion = targetVersion;
|
||||
_productName = productName;
|
||||
}
|
||||
@@ -45,33 +46,50 @@ namespace Umbraco.Core.Persistence.Migrations
|
||||
{
|
||||
LogHelper.Info<MigrationRunner>("Initializing database migrations");
|
||||
|
||||
var foundMigrations = MigrationResolver.Current.Migrations;
|
||||
var foundMigrations = MigrationResolver.Current.Migrations.ToArray();
|
||||
|
||||
//filter all non-schema migrations
|
||||
var migrations = isUpgrade
|
||||
? OrderedUpgradeMigrations(foundMigrations).ToList()
|
||||
: OrderedDowngradeMigrations(foundMigrations).ToList();
|
||||
|
||||
if (Migrating.IsRaisedEventCancelled(new MigrationEventArgs(migrations, _configuredVersion, _targetVersion, true), this))
|
||||
//SD: Why do we want this?
|
||||
if (Migrating.IsRaisedEventCancelled(new MigrationEventArgs(migrations, _currentVersion, _targetVersion, true), this))
|
||||
return false;
|
||||
|
||||
//Loop through migrations to generate sql
|
||||
var context = new MigrationContext(databaseProvider, database);
|
||||
foreach (MigrationBase migration in migrations)
|
||||
var migrationContext = InitializeMigrations(migrations, database, databaseProvider, isUpgrade);
|
||||
|
||||
try
|
||||
{
|
||||
if (isUpgrade)
|
||||
ExecuteMigrations(migrationContext, database);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
//if this fails then the transaction will be rolled back, BUT if we are using MySql this is not the case,
|
||||
//since it does not support schema changes in a transaction, see: http://dev.mysql.com/doc/refman/5.0/en/implicit-commit.html
|
||||
//so in that case we have to downgrade
|
||||
|
||||
if (databaseProvider == DatabaseProviders.MySql)
|
||||
{
|
||||
migration.GetUpExpressions(context);
|
||||
LogHelper.Info<MigrationRunner>(string.Format("Added UPGRADE migration '{0}' to context", migration.GetType().Name));
|
||||
}
|
||||
else
|
||||
{
|
||||
migration.GetDownExpressions(context);
|
||||
LogHelper.Info<MigrationRunner>(string.Format("Added DOWNGRADE migration '{0}' to context", migration.GetType().Name));
|
||||
throw new DataLossException(
|
||||
"An error occurred running a schema migration but the changes could not be rolled back. Error: " + ex.Message + ". In some cases, it may be required that the database be restored to it's original state before running this upgrade process again.",
|
||||
ex);
|
||||
}
|
||||
|
||||
//continue throwing the exception
|
||||
throw;
|
||||
}
|
||||
|
||||
Migrated.RaiseEvent(new MigrationEventArgs(migrations, migrationContext, _currentVersion, _targetVersion, false), this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void ExecuteMigrations(IMigrationContext context, Database database)
|
||||
{
|
||||
//Transactional execution of the sql that was generated from the found migrations
|
||||
using (Transaction transaction = database.GetTransaction())
|
||||
using (var transaction = database.GetTransaction())
|
||||
{
|
||||
int i = 1;
|
||||
foreach (var expression in context.Expressions)
|
||||
@@ -90,38 +108,89 @@ namespace Umbraco.Core.Persistence.Migrations
|
||||
|
||||
transaction.Complete();
|
||||
}
|
||||
}
|
||||
|
||||
Migrated.RaiseEvent(new MigrationEventArgs(migrations, context, _configuredVersion, _targetVersion, false), this);
|
||||
internal MigrationContext InitializeMigrations(List<IMigration> migrations, Database database, DatabaseProviders databaseProvider, bool isUpgrade = true)
|
||||
{
|
||||
//Loop through migrations to generate sql
|
||||
var context = new MigrationContext(databaseProvider, database);
|
||||
|
||||
foreach (var migration in migrations)
|
||||
{
|
||||
var baseMigration = migration as MigrationBase;
|
||||
if (baseMigration != null)
|
||||
{
|
||||
if (isUpgrade)
|
||||
{
|
||||
baseMigration.GetUpExpressions(context);
|
||||
LogHelper.Info<MigrationRunner>(string.Format("Added UPGRADE migration '{0}' to context", baseMigration.GetType().Name));
|
||||
}
|
||||
else
|
||||
{
|
||||
baseMigration.GetDownExpressions(context);
|
||||
LogHelper.Info<MigrationRunner>(string.Format("Added DOWNGRADE migration '{0}' to context", baseMigration.GetType().Name));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//this is just a normal migration so we can only call Up/Down
|
||||
if (isUpgrade)
|
||||
{
|
||||
migration.Up();
|
||||
LogHelper.Info<MigrationRunner>(string.Format("Added UPGRADE migration '{0}' to context", migration.GetType().Name));
|
||||
}
|
||||
else
|
||||
{
|
||||
migration.Down();
|
||||
LogHelper.Info<MigrationRunner>(string.Format("Added DOWNGRADE migration '{0}' to context", migration.GetType().Name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filters and orders migrations based on the migrations listed and the currently configured version and the target installation version
|
||||
/// </summary>
|
||||
/// <param name="foundMigrations"></param>
|
||||
/// <returns></returns>
|
||||
internal IEnumerable<IMigration> OrderedUpgradeMigrations(IEnumerable<IMigration> foundMigrations)
|
||||
{
|
||||
var migrations = (from migration in foundMigrations
|
||||
let migrationAttribute = migration.GetType().FirstAttribute<MigrationAttribute>()
|
||||
where migrationAttribute != null
|
||||
where
|
||||
migrationAttribute.TargetVersion > _configuredVersion &&
|
||||
migrationAttribute.TargetVersion <= _targetVersion &&
|
||||
migrationAttribute.ProductName == _productName
|
||||
orderby migrationAttribute.TargetVersion, migrationAttribute.SortOrder ascending
|
||||
select migration);
|
||||
let migrationAttributes = migration.GetType().GetCustomAttributes<MigrationAttribute>(false)
|
||||
from migrationAttribute in migrationAttributes
|
||||
where migrationAttribute != null
|
||||
where
|
||||
migrationAttribute.TargetVersion > _currentVersion &&
|
||||
migrationAttribute.TargetVersion <= _targetVersion &&
|
||||
migrationAttribute.ProductName == _productName &&
|
||||
//filter if the migration specifies a minimum current version for which to execute
|
||||
(migrationAttribute.MinimumCurrentVersion == null || _currentVersion >= migrationAttribute.MinimumCurrentVersion)
|
||||
orderby migrationAttribute.TargetVersion, migrationAttribute.SortOrder ascending
|
||||
select migration).Distinct();
|
||||
return migrations;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filters and orders migrations based on the migrations listed and the currently configured version and the target installation version
|
||||
/// </summary>
|
||||
/// <param name="foundMigrations"></param>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<IMigration> OrderedDowngradeMigrations(IEnumerable<IMigration> foundMigrations)
|
||||
{
|
||||
var migrations = (from migration in foundMigrations
|
||||
let migrationAttribute = migration.GetType().FirstAttribute<MigrationAttribute>()
|
||||
where migrationAttribute != null
|
||||
where
|
||||
migrationAttribute.TargetVersion > _configuredVersion &&
|
||||
migrationAttribute.TargetVersion <= _targetVersion &&
|
||||
migrationAttribute.ProductName == _productName
|
||||
orderby migrationAttribute.TargetVersion, migrationAttribute.SortOrder descending
|
||||
|
||||
select migration);
|
||||
let migrationAttributes = migration.GetType().GetCustomAttributes<MigrationAttribute>(false)
|
||||
from migrationAttribute in migrationAttributes
|
||||
where migrationAttribute != null
|
||||
where
|
||||
migrationAttribute.TargetVersion > _currentVersion &&
|
||||
migrationAttribute.TargetVersion <= _targetVersion &&
|
||||
migrationAttribute.ProductName == _productName &&
|
||||
//filter if the migration specifies a minimum current version for which to execute
|
||||
(migrationAttribute.MinimumCurrentVersion == null || _currentVersion >= migrationAttribute.MinimumCurrentVersion)
|
||||
orderby migrationAttribute.TargetVersion, migrationAttribute.SortOrder descending
|
||||
select migration).Distinct();
|
||||
return migrations;
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
@@ -41,7 +42,7 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete.Expressions
|
||||
|
||||
if (string.IsNullOrEmpty(ForeignKey.Name))
|
||||
{
|
||||
ForeignKey.Name = string.Format("FK_{0}_{1}", ForeignKey.ForeignTable, ForeignKey.PrimaryTable);
|
||||
ForeignKey.Name = string.Format("FK_{0}_{1}_{2}", ForeignKey.ForeignTable, ForeignKey.PrimaryTable, ForeignKey.PrimaryColumns.First());
|
||||
}
|
||||
|
||||
return string.Format(SqlSyntaxContext.SqlSyntaxProvider.DeleteConstraint,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Umbraco.Core.Persistence.Migrations.Syntax.Delete.Column;
|
||||
using System;
|
||||
using Umbraco.Core.Persistence.Migrations.Syntax.Delete.Column;
|
||||
using Umbraco.Core.Persistence.Migrations.Syntax.Delete.Constraint;
|
||||
using Umbraco.Core.Persistence.Migrations.Syntax.Delete.DefaultConstraint;
|
||||
using Umbraco.Core.Persistence.Migrations.Syntax.Delete.ForeignKey;
|
||||
@@ -11,6 +12,7 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete
|
||||
void Table(string tableName);
|
||||
IDeleteColumnFromTableSyntax Column(string columnName);
|
||||
IDeleteForeignKeyFromTableSyntax ForeignKey();
|
||||
[Obsolete("Do not use this construct as it does not work with MySql, use the syntax: Delete.ForeignKey().FromTable(\"umbracoUser2app\").ForeignColumn(... instead")]
|
||||
IDeleteForeignKeyOnTableSyntax ForeignKey(string foreignKeyName);
|
||||
IDeleteDataSyntax FromTable(string tableName);
|
||||
IDeleteIndexForTableSyntax Index();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user