Compare commits
598 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7c93b8f157 | |||
| c87a22f347 | |||
| 9cab789425 | |||
| a0cd542ba3 | |||
| 88349c6b66 | |||
| 046ed8ec85 | |||
| aabe6defb2 | |||
| 3245c82ea6 | |||
| beacc5bba8 | |||
| 7ffe0398f9 | |||
| ce5b3531e0 | |||
| a9a5d00916 | |||
| 62a71f8052 | |||
| 36eccb472c | |||
| 289d50d170 | |||
| 0517f29134 | |||
| 467cf8d762 | |||
| 2cdb6d86ad | |||
| d474f60465 | |||
| caf4d1fe34 | |||
| e4f346620e | |||
| be4536cf16 | |||
| 89429bd65a | |||
| 6d3faf91d8 | |||
| 345e6091d2 | |||
| 86a97c30d1 | |||
| 14915e9da7 | |||
| 366058581a | |||
| 9f6a7dec2e | |||
| be30bb0ad0 | |||
| 600a29514f | |||
| 9efec9244b | |||
| ded1a22e45 | |||
| 2e83ac9282 | |||
| 9538981730 | |||
| 791222c3ce | |||
| 1095815878 | |||
| a8bdab8f5c | |||
| ff952a6df1 | |||
| 87e7cec02e | |||
| 5c8cd60275 | |||
| e2483dc874 | |||
| 6482d849e3 | |||
| 34f137c8cf | |||
| 16d8f8846e | |||
| 108416638c | |||
| 20d28ea215 | |||
| 27bc309c55 | |||
| b5b4ee79b4 | |||
| 45227357fd | |||
| a2ba0f6a4c | |||
| 415916c527 | |||
| 40a55cb9df | |||
| 5a9ca8d09f | |||
| 1bfcc9053e | |||
| 3930ae244c | |||
| 365ad2981d | |||
| ca56655d07 | |||
| 4612c03657 | |||
| 41093e5b8b | |||
| efd6bd82bd | |||
| 17527c99eb | |||
| 361557dc39 | |||
| 342b2087e9 | |||
| dc371c1979 | |||
| 2faa4defd8 | |||
| bb8356d7db | |||
| 686f6752f3 | |||
| 66ff4d191a | |||
| 21218b0332 | |||
| 23ccdeb2cf | |||
| 6148ce4e52 | |||
| 06850ed25c | |||
| 0320a56cb5 | |||
| b9e44f381b | |||
| cd27bb210f | |||
| 67f680a675 | |||
| 47c3e3a79f | |||
| 02f49a0039 | |||
| b07df63422 | |||
| 487e45b45b | |||
| 929c84822a | |||
| 993f11cd2c | |||
| 6544b5c272 | |||
| 817a458334 | |||
| f3bfc1ffb2 | |||
| 3603090421 | |||
| 79159b684d | |||
| 26d4d056be | |||
| 6ad28f1103 | |||
| 89cd655df2 | |||
| 14c4c4815d | |||
| bfb69a34ef | |||
| b675f6252c | |||
| d52420183e | |||
| 0cbe0b4796 | |||
| 0feb053e51 | |||
| 09c8ae4e7e | |||
| 2aaca865e7 | |||
| 77dda5a70f | |||
| f6a8d487cc | |||
| 59bf24c461 | |||
| 2748c3635d | |||
| 2252db0d55 | |||
| df896af476 | |||
| 78735ff349 | |||
| 4b605b2580 | |||
| 80d7f1b2c9 | |||
| 1af43498d9 | |||
| 5ada85df29 | |||
| 015ad64e30 | |||
| 6dbb988903 | |||
| 926acb910e | |||
| 57e3187e3a | |||
| 988d51c4c8 | |||
| 4733256ca1 | |||
| 4133a1fe76 | |||
| 37bf6fe938 | |||
| 31716e574c | |||
| 126c4cbd46 | |||
| 7cc91f71c2 | |||
| 7c52b9602c | |||
| c5f1cc15fd | |||
| d089518681 | |||
| cd6ef35bf9 | |||
| 47cdc79fcb | |||
| f7382255c2 | |||
| 2167eada0c | |||
| df11935598 | |||
| d3b4b9fe64 | |||
| 33aff7ff61 | |||
| 4d2c551b79 | |||
| 5b7ae7150f | |||
| 5bf29a907a | |||
| 96d5bdd7b2 | |||
| 7b4023fd5a | |||
| af72729905 | |||
| d5bc54cf6c | |||
| 5625102e2c | |||
| 66abd7b50c | |||
| 2a9bcf0e98 | |||
| e6484687e5 | |||
| 5da1e64bbc | |||
| 7b0979f9fd | |||
| 1a437c1c6a | |||
| 3c0565e516 | |||
| 178b1ccf40 | |||
| c03cd81c23 | |||
| 3d3647b476 | |||
| a4cac670df | |||
| c414dd06cc | |||
| 4ed746e4ef | |||
| c270d8ecac | |||
| ade9bb7324 | |||
| 4134dd16df | |||
| f81588bb13 | |||
| 09793a1744 | |||
| ba7cd48b8f | |||
| 640d2cedb9 | |||
| 0a6237af04 | |||
| 503183331f | |||
| 3effc66b2c | |||
| b64f303537 | |||
| 760f6a1647 | |||
| 0b64e34f05 | |||
| f01be09075 | |||
| 1c5ed58074 | |||
| 42d86f147f | |||
| fa4acb255b | |||
| 1885767ef1 | |||
| 80e6880bb7 | |||
| fabacd1689 | |||
| 23a7654cea | |||
| b2d019bfe1 | |||
| 9f817bf032 | |||
| 01c89bd338 | |||
| e5956e4955 | |||
| 958c3b147b | |||
| 4a33ca99ba | |||
| 568835f7e2 | |||
| 84aa861a5b | |||
| ee2ebc7d14 | |||
| 9ce996cbba | |||
| 580ba79619 | |||
| fbe184ef6e | |||
| 2f7bf413ed | |||
| 390613c796 | |||
| b3e3475bf5 | |||
| 5333b23c23 | |||
| 734086fcf5 | |||
| 12dff9bca3 | |||
| f370e738da | |||
| a018ed9e52 | |||
| 17f73b88dc | |||
| 405e9a79be | |||
| 4d90322842 | |||
| a8b5d69be0 | |||
| 5ebd90aba5 | |||
| bec909c284 | |||
| 46e0b08d65 | |||
| 7a178be031 | |||
| 9d14c9e0b7 | |||
| ef19633a90 | |||
| 80ffd026f6 | |||
| cb7300688c | |||
| 040ebfe9dd | |||
| 44e567aa34 | |||
| 8c5f253b41 | |||
| 7b99e55148 | |||
| ba27eff5cf | |||
| 01d5a12039 | |||
| 6d4d26009f | |||
| 857a8b163d | |||
| acbe82f4c8 | |||
| fad33a97b2 | |||
| 3bfd9b71e2 | |||
| ef714ac258 | |||
| 975816ddd7 | |||
| 8831860174 | |||
| fbf3015de4 | |||
| be587b2064 | |||
| 347c2e8238 | |||
| f5fde0f19e | |||
| ac586c5207 | |||
| 8033931e31 | |||
| 8e29810598 | |||
| be96e2cf08 | |||
| 534ee67ad2 | |||
| 571a3bc257 | |||
| c12bdaacbf | |||
| e7a30d0a5d | |||
| a55323176f | |||
| 1b83e0a87d | |||
| ca15f340b0 | |||
| 23b8e1cce8 | |||
| cf53ba363d | |||
| 1c4b262c57 | |||
| 90d591e5a8 | |||
| ad121bd758 | |||
| 8d67e39e9a | |||
| bd8e344736 | |||
| 014eba971e | |||
| 2f309a2fd6 | |||
| a5fb2d2025 | |||
| 40311f8590 | |||
| a0c51fb212 | |||
| b306e41560 | |||
| 9f45d41a4a | |||
| e8d6daf59a | |||
| a0966be565 | |||
| ba064ba4f5 | |||
| 1994194656 | |||
| 1da2c00f0a | |||
| 71d076aba2 | |||
| c7ec1deee6 | |||
| 36559b8761 | |||
| 8fe7c5599a | |||
| 4dd325cec9 | |||
| d558646d75 | |||
| afac4bb918 | |||
| 0869bf27c7 | |||
| 383a8617ce | |||
| 3865f4fb50 | |||
| d7d58644e5 | |||
| 3e74bbfb45 | |||
| 966b07ba1c | |||
| 56669b5c84 | |||
| 60ed6f6b20 | |||
| 903c163a57 | |||
| 41b8294ce3 | |||
| d4311fe4ab | |||
| eab597a2a8 | |||
| 003ee1a991 | |||
| 601d48277e | |||
| aed6ef28e6 | |||
| 339ae32c3d | |||
| 7d990a2cbb | |||
| b98812b119 | |||
| fafd045ed2 | |||
| acf63fc74d | |||
| 85565f2c5f | |||
| ac6625a80c | |||
| 6d7b439aec | |||
| 9fffdb407a | |||
| 9170061810 | |||
| a7da3d741f | |||
| 255bd10296 | |||
| 4fca0bb735 | |||
| f7aaad86c5 | |||
| 8d12170def | |||
| d2655a9f2f | |||
| c4c2082fa9 | |||
| 40d4a8fe6a | |||
| 4c443b9e2e | |||
| 2898203cb9 | |||
| 5ebdfc7b1c | |||
| 31d7e58191 | |||
| ad4416f663 | |||
| b55d2a8a41 | |||
| 17a4799b97 | |||
| b0121c44b1 | |||
| be9d8e7da7 | |||
| d129989c3d | |||
| 2870ce5e0a | |||
| da1e2680cb | |||
| cd2ce2486a | |||
| 5d4f2ec697 | |||
| c2cb85f1cd | |||
| 4df838c20c | |||
| 4e44871671 | |||
| 37d3692cd0 | |||
| f4b2ff93fc | |||
| 5ea6ebcc66 | |||
| f6ac64f705 | |||
| fcfb107653 | |||
| f829bb8023 | |||
| 1dd2c1cb91 | |||
| 23702ee4dc | |||
| 5c2b0647f3 | |||
| c7a725ad94 | |||
| 5c6a9480a6 | |||
| c1be8e3f00 | |||
| d8dbda8e94 | |||
| a0ab7ace07 | |||
| 7c27189e2e | |||
| 76cbfdb787 | |||
| 56545ad7f1 | |||
| 832dc7f4a5 | |||
| 62dc68e7b2 | |||
| 348c79d841 | |||
| 994c6eed50 | |||
| 9614740410 | |||
| 62e6168e03 | |||
| b6d762c279 | |||
| ab93c4ff2d | |||
| 473c39f7c4 | |||
| 811aea7898 | |||
| 07358eb46d | |||
| 067af64dff | |||
| cb428bb288 | |||
| b69c981100 | |||
| 1709879b14 | |||
| cff5046a9e | |||
| 9f6da2ca4b | |||
| 0c8b0edcda | |||
| 68f9e89a32 | |||
| fecadeec51 | |||
| d3b675a213 | |||
| 316ab6becb | |||
| 9a45bda430 | |||
| 7c11943836 | |||
| 94d2a5cbad | |||
| 99cabe564d | |||
| b0488d2d94 | |||
| 600c8ebbbf | |||
| 3bf43d7ce3 | |||
| 15b1d35c17 | |||
| 872db5877f | |||
| 977c1d9585 | |||
| 46f4984add | |||
| e39e132feb | |||
| 17b479275e | |||
| 9927ff3c86 | |||
| 81077c2681 | |||
| f4593778cb | |||
| 16f6bbcbd4 | |||
| c597da8f97 | |||
| 5775a8b614 | |||
| cc4a7653e5 | |||
| 5b546cc425 | |||
| 7f5f304d2d | |||
| 0827ced915 | |||
| 9c252131f7 | |||
| dec042fce4 | |||
| 8eafadc29b | |||
| c5347a97ce | |||
| 8a19cd4bbc | |||
| 2797011fb0 | |||
| 1307ee7ced | |||
| e0059f1fad | |||
| fd5b5b67bf | |||
| 7ba4c2f353 | |||
| 0381c55ce7 | |||
| 88d9e3321c | |||
| 05f479a58f | |||
| d8180604e8 | |||
| e6a8ba84aa | |||
| 39d93a7ace | |||
| 5ddf21f09f | |||
| 7b3ab72105 | |||
| 1f64ae4682 | |||
| 120f4c3096 | |||
| e59d75f4f9 | |||
| e3b2d427a4 | |||
| 22f54394fb | |||
| 57c368f70d | |||
| 14a056f4f4 | |||
| 580de6befe | |||
| 0120dc6ea3 | |||
| 79cd312912 | |||
| 9b36bc4097 | |||
| 9f346e6ee2 | |||
| 3ea9504620 | |||
| 86db972188 | |||
| 6d12eea789 | |||
| 68174bc7df | |||
| 5ca9600c98 | |||
| 87b3fb5539 | |||
| 4be6a48fb2 | |||
| 53731049de | |||
| 7fd6bfa163 | |||
| 4b2ce522fe | |||
| d0eddbb9a2 | |||
| 938abab9d6 | |||
| 5faa71187d | |||
| c069f262dc | |||
| ac79fe7a77 | |||
| 9f42e6a607 | |||
| 3f8fe334b2 | |||
| 096004db13 | |||
| 202f2d2e27 | |||
| aaab14be3e | |||
| 1c87176d80 | |||
| c17dbbe141 | |||
| 1dde60a1d5 | |||
| 04967143d8 | |||
| 70fb48d94a | |||
| 760d1d7daa | |||
| 3135353a1a | |||
| 1565ff1661 | |||
| bc55d96cde | |||
| 3d2379d582 | |||
| 73e907291b | |||
| 49c76c744e | |||
| 8967061758 | |||
| eff8075102 | |||
| 849feb0683 | |||
| a182c9b1ee | |||
| 17675d389e | |||
| f30aefb614 | |||
| a1722f268c | |||
| 864d83f8f7 | |||
| 2f978e96d4 | |||
| dccc6238e0 | |||
| 0687125343 | |||
| de36edfd58 | |||
| 2842a56356 | |||
| 661246b5f5 | |||
| 457474ecf9 | |||
| 5f67b3a9c1 | |||
| a3547a79e8 | |||
| c6467b355d | |||
| e2ef186dd1 | |||
| 0ccc40bf52 | |||
| ebc21a1cc7 | |||
| 30067d92ae | |||
| 342f924e8f | |||
| ba12efd285 | |||
| ed3efe9bee | |||
| 47a7c08686 | |||
| 5191dbf011 | |||
| 8d9ae085aa | |||
| 161d6505eb | |||
| c292f7ff03 | |||
| 17860fb8c7 | |||
| eb642dc611 | |||
| bc99d074a9 | |||
| d536bebdbe | |||
| 3639d952d5 | |||
| 7c79cf318e | |||
| 6ad1607685 | |||
| c1ed2b9f45 | |||
| 2c5eeaeac8 | |||
| a74a0c343e | |||
| 4eb897ccff | |||
| 20dc77c330 | |||
| 4c79863130 | |||
| 9ec95c7aa2 | |||
| 38bfd07883 | |||
| ce15b7c7c4 | |||
| b090de3cde | |||
| dbd74f5273 | |||
| e87f8b14be | |||
| fb14a4987c | |||
| a471e7d25e | |||
| fef9248b51 | |||
| a8e2798add | |||
| 6af1057ad7 | |||
| 983144c3f9 | |||
| c451498975 | |||
| 8579b5a89b | |||
| 1ad4414026 | |||
| d52d0819ab | |||
| 0dedd7b2d4 | |||
| ca25b3199b | |||
| 460653d078 | |||
| beb9068805 | |||
| f5a00cc3bd | |||
| 86aef126fd | |||
| 0e9d0a5a10 | |||
| a4f1b433eb | |||
| 08b386e180 | |||
| 97ae6165e4 | |||
| 8cdb61195d | |||
| 50c2d574f1 | |||
| c6cabf1239 | |||
| f07fcac13d | |||
| e2746604a1 | |||
| e9b5225676 | |||
| c2046ad173 | |||
| f080260396 | |||
| 5d1da3ada1 | |||
| 2b84f96836 | |||
| 28b669d3a3 | |||
| 225688facf | |||
| 8bc28a4d81 | |||
| e7e74840bc | |||
| ceb1260509 | |||
| 9706a0f76a | |||
| 12d79f2d08 | |||
| ef15c247c2 | |||
| d255cd115b | |||
| 19e2b1c24e | |||
| c0c9f4dfcc | |||
| 61ba78538a | |||
| cb76914a27 | |||
| 9b0d16f0ad | |||
| 3377888219 | |||
| 35645672ae | |||
| f952877d04 | |||
| 62a6a4ec92 | |||
| 943e050493 | |||
| e958ca6f89 | |||
| 0a752c8985 | |||
| b6ad19ccad | |||
| bea1d35ebf | |||
| dae8802c50 | |||
| 58cdff1d71 | |||
| d69a978870 | |||
| 93bc2dc95b | |||
| 1bcf40402c | |||
| 7b101f0b9e | |||
| dad3f31f86 | |||
| e091987f0f | |||
| 60a3cdc5ab | |||
| 03006d7698 | |||
| 8344372ae2 | |||
| d52f6b5810 | |||
| 4fa07389dd | |||
| 33b857d2c6 | |||
| 2bdbd86787 | |||
| 3d86b08e31 | |||
| 5cef71e4e6 | |||
| fe7b114083 | |||
| adc7201e86 | |||
| bb0331e9cc | |||
| 25b8c8a565 | |||
| eb390f8d80 | |||
| be93773399 | |||
| 6f0baa4a8e | |||
| a56f3b23d1 | |||
| 4feb766cc6 | |||
| 55d4457c70 | |||
| 05c85bbce5 | |||
| 2270188668 | |||
| 41e14a62c0 | |||
| a996d46b6f | |||
| e062ea8d31 | |||
| 7cf13cbf94 | |||
| afda7a5661 | |||
| 11ef00c63d | |||
| 2b54cc50ab | |||
| 99319e0b49 | |||
| f99302ac63 | |||
| 890d7d8ce3 | |||
| f039b00a44 | |||
| 34ad8dfb8d | |||
| 2c436d5ae0 | |||
| 6b23a8221d | |||
| 92a0ec2964 | |||
| 760b7ad0ce | |||
| b6918253c0 | |||
| 0f969ecdd4 | |||
| db867c66a3 | |||
| 34a3389c17 | |||
| beb325eacf | |||
| 8e45bcf23f | |||
| 40dc49ed47 | |||
| 4b07305dc5 | |||
| 2514a59e93 | |||
| 6843da790c | |||
| ba1a9c3758 | |||
| 332ad6349d | |||
| 42e48426e4 | |||
| a0cc788f27 | |||
| aecf96d74d | |||
| c75938076e | |||
| cebbcb711a |
@@ -14,6 +14,7 @@
|
||||
<summary>Contains the core assemblies needed to run Umbraco Cms</summary>
|
||||
<language>en-US</language>
|
||||
<tags>umbraco</tags>
|
||||
<repository type="git" url="https://github.com/umbraco/umbraco-cms" />
|
||||
<dependencies>
|
||||
|
||||
<group targetFramework="net472">
|
||||
@@ -44,7 +45,7 @@
|
||||
<dependency id="Umbraco.SqlServerCE" version="[4.0.0.1,4.999999)" />
|
||||
<dependency id="NPoco" version="[3.9.4,3.999999)" />
|
||||
</group>
|
||||
|
||||
|
||||
</dependencies>
|
||||
</metadata>
|
||||
<files>
|
||||
@@ -52,9 +53,9 @@
|
||||
<file src="$BuildTmp$\WebApp\bin\Umbraco.Core.dll" target="lib\net472\Umbraco.Core.dll" />
|
||||
|
||||
<!-- docs -->
|
||||
<file src="$BuildTmp$\WebApp\bin\Umbraco.Core.xml" target="lib\Umbraco.Core.xml" />
|
||||
<file src="$BuildTmp$\WebApp\bin\Umbraco.Core.xml" target="lib\net472\Umbraco.Core.xml" />
|
||||
|
||||
<!-- symbols -->
|
||||
<file src="$BuildTmp$\bin\Umbraco.Core.pdb" target="lib" />
|
||||
<file src="$BuildTmp$\bin\Umbraco.Core.pdb" target="lib\net472\Umbraco.Core.pdb" />
|
||||
</files>
|
||||
</package>
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
<summary>Contains the core assemblies needed to run Umbraco Cms</summary>
|
||||
<language>en-US</language>
|
||||
<tags>umbraco</tags>
|
||||
<repository type="git" url="https://github.com/umbraco/umbraco-cms" />
|
||||
<dependencies>
|
||||
|
||||
<group targetFramework="net472">
|
||||
@@ -43,7 +44,7 @@
|
||||
<dependency id="System.Threading.Tasks.Dataflow" version="[4.9.0,4.999999)" />
|
||||
|
||||
</group>
|
||||
|
||||
|
||||
</dependencies>
|
||||
</metadata>
|
||||
<files>
|
||||
@@ -53,12 +54,12 @@
|
||||
<file src="$BuildTmp$\WebApp\bin\Umbraco.Examine.dll" target="lib\net472\Umbraco.Examine.dll" />
|
||||
|
||||
<!-- docs -->
|
||||
<file src="$BuildTmp$\WebApp\bin\Umbraco.Web.xml" target="lib\Umbraco.Web.xml" />
|
||||
<file src="$BuildTmp$\WebApp\bin\Umbraco.Web.UI.xml" target="lib\Umbraco.Web.UI.xml" />
|
||||
<file src="$BuildTmp$\WebApp\bin\Umbraco.Examine.xml" target="lib\Umbraco.Examine.xml" />
|
||||
<file src="$BuildTmp$\WebApp\bin\Umbraco.Web.xml" target="lib\net472\Umbraco.Web.xml" />
|
||||
<file src="$BuildTmp$\WebApp\bin\Umbraco.Web.UI.xml" target="lib\net472\Umbraco.Web.UI.xml" />
|
||||
<file src="$BuildTmp$\WebApp\bin\Umbraco.Examine.xml" target="lib\net472\Umbraco.Examine.xml" />
|
||||
|
||||
<!-- symbols -->
|
||||
<file src="$BuildTmp$\bin\Umbraco.Web.pdb" target="lib" />
|
||||
<file src="$BuildTmp$\bin\Umbraco.Examine.pdb" target="lib" />
|
||||
<file src="$BuildTmp$\bin\Umbraco.Web.pdb" target="lib\net472\Umbraco.Web.pdb" />
|
||||
<file src="$BuildTmp$\bin\Umbraco.Examine.pdb" target="lib\net472\Umbraco.Examine.pdb" />
|
||||
</files>
|
||||
</package>
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
<summary>Installs Umbraco Cms in your Visual Studio ASP.NET project</summary>
|
||||
<language>en-US</language>
|
||||
<tags>umbraco</tags>
|
||||
<repository type="git" url="https://github.com/umbraco/umbraco-cms" />
|
||||
<dependencies>
|
||||
|
||||
<group targetFramework="net472">
|
||||
@@ -25,7 +26,7 @@
|
||||
not want this to happen as the alpha of the next major is, really, the next major already.
|
||||
-->
|
||||
<dependency id="Microsoft.AspNet.SignalR.Core" version="[2.4.0, 2.999999)" />
|
||||
<dependency id="Umbraco.ModelsBuilder.Ui" version="[8.0.4]" />
|
||||
<dependency id="Umbraco.ModelsBuilder.Ui" version="[8.1.0]" />
|
||||
<dependency id="ImageProcessor.Web" version="[4.10.0.100,4.999999)" />
|
||||
<dependency id="ImageProcessor.Web.Config" version="[2.5.0.100,2.999999)" />
|
||||
<dependency id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="[2.0.1,2.999999)" />
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
</configSections>
|
||||
|
||||
<system.web.webPages.razor>
|
||||
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" xdt:Locator="Match(factoryType)" xdt:Transform="SetAttributes(factoryType)" />
|
||||
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.7.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" xdt:Locator="Match(factoryType)" xdt:Transform="SetAttributes(factoryType)" />
|
||||
<pages pageBaseType="System.Web.Mvc.WebViewPage">
|
||||
<namespaces>
|
||||
<add namespace="Umbraco.Web.PublishedContentModels" xdt:Transform="InsertIfMissing" />
|
||||
@@ -18,13 +18,13 @@
|
||||
|
||||
<system.web>
|
||||
<pages
|
||||
pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
|
||||
pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
|
||||
userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
|
||||
pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=5.2.7.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
|
||||
pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=5.2.7.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
|
||||
userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=5.2.7.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
|
||||
xdt:Locator="Match(pageParserFilterType,pageBaseType,userControlBaseType)"
|
||||
xdt:Transform="SetAttributes(pageParserFilterType,pageBaseType,userControlBaseType)">
|
||||
<controls>
|
||||
<add assembly="System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" namespace="System.Web.Mvc" xdt:Locator="Match(namespace)" xdt:Transform="SetAttributes(assembly)" />
|
||||
<add assembly="System.Web.Mvc, Version=5.2.7.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" namespace="System.Web.Mvc" xdt:Locator="Match(namespace)" xdt:Transform="SetAttributes(assembly)" />
|
||||
</controls>
|
||||
</pages>
|
||||
</system.web>
|
||||
|
||||
@@ -18,9 +18,20 @@ if ($project) {
|
||||
|
||||
# Copy umbraco and umbraco_files from package to project folder
|
||||
$umbracoFolder = Join-Path $projectPath "Umbraco"
|
||||
New-Item -ItemType Directory -Force -Path $umbracoFolder
|
||||
New-Item -ItemType Directory -Force -Path $umbracoFolder
|
||||
$umbracoFolderSource = Join-Path $installPath "UmbracoFiles\Umbraco"
|
||||
robocopy $umbracoFolderSource $umbracoFolder /is /it /e /xf UI.xml /LOG:$copyLogsPath\UmbracoCopy.log
|
||||
|
||||
Write-Host "copying files to $umbracoFolder ..."
|
||||
# see https://support.microsoft.com/en-us/help/954404/return-codes-that-are-used-by-the-robocopy-utility-in-windows-server-2
|
||||
robocopy $umbracoFolderSource $umbracoFolder /is /it /e
|
||||
if (($lastexitcode -eq 1) -or ($lastexitcode -eq 3) -or ($lastexitcode -eq 5) -or ($lastexitcode -eq 7))
|
||||
{
|
||||
write-host "Copy succeeded!"
|
||||
}
|
||||
else
|
||||
{
|
||||
write-host "Copy failed with exit code:" $lastexitcode
|
||||
}
|
||||
|
||||
$copyWebconfig = $true
|
||||
$destinationWebConfig = Join-Path $projectPath "Web.config"
|
||||
@@ -40,7 +51,11 @@ if ($project) {
|
||||
}
|
||||
}
|
||||
}
|
||||
Catch { }
|
||||
Catch
|
||||
{
|
||||
Write-Host "An error occurred:"
|
||||
Write-Host $_
|
||||
}
|
||||
}
|
||||
|
||||
if($copyWebconfig -eq $true)
|
||||
@@ -74,7 +89,9 @@ if ($project) {
|
||||
}
|
||||
Catch
|
||||
{
|
||||
# Not a big problem if this fails, let it go
|
||||
# Not a big problem if this fails, let it go
|
||||
# Write-Host "An error occurred:"
|
||||
# Write-Host $_
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+10
-10
@@ -15,7 +15,7 @@
|
||||
[Parameter(Mandatory=$false)]
|
||||
[Alias("doc")]
|
||||
[switch] $docfx = $false,
|
||||
|
||||
|
||||
# keep the build directories, don't clear them
|
||||
[Parameter(Mandatory=$false)]
|
||||
[Alias("c")]
|
||||
@@ -392,13 +392,13 @@
|
||||
&$this.BuildEnv.NuGet Pack "$nuspecs\UmbracoCms.Core.nuspec" `
|
||||
-Properties BuildTmp="$($this.BuildTemp)" `
|
||||
-Version "$($this.Version.Semver.ToString())" `
|
||||
-Symbols -SymbolPackageFormat snupkg -Verbosity detailed -outputDirectory "$($this.BuildOutput)" > "$($this.BuildTemp)\nupack.cmscore.log"
|
||||
-Verbosity detailed -outputDirectory "$($this.BuildOutput)" > "$($this.BuildTemp)\nupack.cmscore.log"
|
||||
if (-not $?) { throw "Failed to pack NuGet UmbracoCms.Core." }
|
||||
|
||||
&$this.BuildEnv.NuGet Pack "$nuspecs\UmbracoCms.Web.nuspec" `
|
||||
-Properties BuildTmp="$($this.BuildTemp)" `
|
||||
-Version "$($this.Version.Semver.ToString())" `
|
||||
-Symbols -SymbolPackageFormat snupkg -Verbosity detailed -outputDirectory "$($this.BuildOutput)" > "$($this.BuildTemp)\nupack.cmsweb.log"
|
||||
-Verbosity detailed -outputDirectory "$($this.BuildOutput)" > "$($this.BuildTemp)\nupack.cmsweb.log"
|
||||
if (-not $?) { throw "Failed to pack NuGet UmbracoCms.Web." }
|
||||
|
||||
&$this.BuildEnv.NuGet Pack "$nuspecs\UmbracoCms.nuspec" `
|
||||
@@ -429,37 +429,37 @@
|
||||
Write-Host "Prepare Azure Gallery"
|
||||
$this.CopyFile("$($this.SolutionRoot)\build\Azure\azuregalleryrelease.ps1", $this.BuildOutput)
|
||||
})
|
||||
|
||||
|
||||
$ubuild.DefineMethod("PrepareCSharpDocs",
|
||||
{
|
||||
Write-Host "Prepare C# Documentation"
|
||||
|
||||
|
||||
$src = "$($this.SolutionRoot)\src"
|
||||
$tmp = $this.BuildTemp
|
||||
$out = $this.BuildOutput
|
||||
$DocFxJson = Join-Path -Path $src "\ApiDocs\docfx.json"
|
||||
$DocFxSiteOutput = Join-Path -Path $tmp "\_site\*.*"
|
||||
|
||||
|
||||
|
||||
#restore nuget packages
|
||||
$this.RestoreNuGet()
|
||||
# run DocFx
|
||||
$DocFx = $this.BuildEnv.DocFx
|
||||
|
||||
|
||||
& $DocFx metadata $DocFxJson
|
||||
& $DocFx build $DocFxJson
|
||||
|
||||
# zip it
|
||||
& $this.BuildEnv.Zip a -tzip -r "$out\csharp-docs.zip" $DocFxSiteOutput
|
||||
})
|
||||
|
||||
|
||||
$ubuild.DefineMethod("PrepareAngularDocs",
|
||||
{
|
||||
Write-Host "Prepare Angular Documentation"
|
||||
|
||||
|
||||
$src = "$($this.SolutionRoot)\src"
|
||||
$out = $this.BuildOutput
|
||||
|
||||
|
||||
$this.CompileBelle()
|
||||
|
||||
"Moving to Umbraco.Web.UI.Client folder"
|
||||
|
||||
+2
-2
@@ -18,5 +18,5 @@ using System.Resources;
|
||||
[assembly: AssemblyVersion("8.0.0")]
|
||||
|
||||
// these are FYI and changed automatically
|
||||
[assembly: AssemblyFileVersion("8.1.0")]
|
||||
[assembly: AssemblyInformationalVersion("8.1.0")]
|
||||
[assembly: AssemblyFileVersion("8.1.2")]
|
||||
[assembly: AssemblyInformationalVersion("8.1.2")]
|
||||
|
||||
@@ -67,31 +67,34 @@ namespace Umbraco.Core
|
||||
: new NamedSemaphoreReleaser(_semaphore2);
|
||||
}
|
||||
|
||||
public Task<IDisposable> LockAsync()
|
||||
{
|
||||
var wait = _semaphore != null
|
||||
? _semaphore.WaitAsync()
|
||||
: _semaphore2.WaitOneAsync();
|
||||
//NOTE: We don't use the "Async" part of this lock at all
|
||||
//TODO: Remove this and rename this class something like SystemWideLock, then we can re-instate this logic if we ever need an Async lock again
|
||||
|
||||
return wait.IsCompleted
|
||||
? _releaserTask ?? Task.FromResult(CreateReleaser()) // anonymous vs named
|
||||
: wait.ContinueWith((_, state) => (((AsyncLock) state).CreateReleaser()),
|
||||
this, CancellationToken.None,
|
||||
TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
|
||||
}
|
||||
//public Task<IDisposable> LockAsync()
|
||||
//{
|
||||
// var wait = _semaphore != null
|
||||
// ? _semaphore.WaitAsync()
|
||||
// : _semaphore2.WaitOneAsync();
|
||||
|
||||
public Task<IDisposable> LockAsync(int millisecondsTimeout)
|
||||
{
|
||||
var wait = _semaphore != null
|
||||
? _semaphore.WaitAsync(millisecondsTimeout)
|
||||
: _semaphore2.WaitOneAsync(millisecondsTimeout);
|
||||
// return wait.IsCompleted
|
||||
// ? _releaserTask ?? Task.FromResult(CreateReleaser()) // anonymous vs named
|
||||
// : wait.ContinueWith((_, state) => (((AsyncLock) state).CreateReleaser()),
|
||||
// this, CancellationToken.None,
|
||||
// TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
|
||||
//}
|
||||
|
||||
return wait.IsCompleted
|
||||
? _releaserTask ?? Task.FromResult(CreateReleaser()) // anonymous vs named
|
||||
: wait.ContinueWith((_, state) => (((AsyncLock)state).CreateReleaser()),
|
||||
this, CancellationToken.None,
|
||||
TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
|
||||
}
|
||||
//public Task<IDisposable> LockAsync(int millisecondsTimeout)
|
||||
//{
|
||||
// var wait = _semaphore != null
|
||||
// ? _semaphore.WaitAsync(millisecondsTimeout)
|
||||
// : _semaphore2.WaitOneAsync(millisecondsTimeout);
|
||||
|
||||
// return wait.IsCompleted
|
||||
// ? _releaserTask ?? Task.FromResult(CreateReleaser()) // anonymous vs named
|
||||
// : wait.ContinueWith((_, state) => (((AsyncLock)state).CreateReleaser()),
|
||||
// this, CancellationToken.None,
|
||||
// TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
|
||||
//}
|
||||
|
||||
public IDisposable Lock()
|
||||
{
|
||||
|
||||
@@ -12,31 +12,62 @@
|
||||
/// or MS.DI, PerDependency in Autofac.</remarks>
|
||||
Transient,
|
||||
|
||||
// TODO: We need to fix this up, currently LightInject is the only one that behaves differently from all other containers.
|
||||
// ... the simple fix would be to map this to PerScopeLifetime in LI but need to wait on a response here https://github.com/seesharper/LightInject/issues/494#issuecomment-518942625
|
||||
//
|
||||
// we use it for controllers, httpContextBase and other request scoped objects: MembershpHelper, TagQuery, UmbracoTreeSearcher and ISearchableTree
|
||||
// - so that they are automatically disposed at the end of the scope (ie request)
|
||||
// - not sure they should not be simply 'scoped'?
|
||||
|
||||
/// <summary>
|
||||
/// One unique instance per request.
|
||||
/// </summary>
|
||||
// TODO: review lifetimes for LightInject vs other containers
|
||||
// currently, corresponds to 'Request' in LightInject which is 'Transient + disposed by Scope'
|
||||
// but NOT (in LightInject) a per-web-request lifetime, more a TransientScoped
|
||||
//
|
||||
// we use it for controllers, httpContextBase and umbracoContext
|
||||
// - so that they are automatically disposed at the end of the scope (ie request)
|
||||
// - not sure they should not be simply 'scoped'?
|
||||
//
|
||||
// Castle has an extra PerWebRequest something, and others use scope
|
||||
// what about Request before first request ie during application startup?
|
||||
// see http://blog.ploeh.dk/2009/11/17/UsingCastleWindsor'sPerWebRequestlifestylewithASP.NETMVConIIS7/
|
||||
// Castle ends up requiring a special scope manager too
|
||||
// see https://groups.google.com/forum/#!topic/castle-project-users/1E2W9LVIYR4
|
||||
//
|
||||
// but maybe also - why are we requiring scoped services at startup?
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// Any instance created with this lifetime will be disposed at the end of a request.
|
||||
/// </para>
|
||||
/// Corresponds to
|
||||
/// <para>
|
||||
/// PerRequestLifeTime in LightInject - means transient but disposed at the end of the current web request.
|
||||
/// see: https://github.com/seesharper/LightInject/issues/494#issuecomment-518493262
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Scoped in MS.DI - means one per web request.
|
||||
/// see https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-2.2#service-lifetimes</para>
|
||||
/// <para>
|
||||
/// InstancePerRequest in Autofac - means one per web request.
|
||||
/// see https://autofaccn.readthedocs.io/en/latest/lifetime/instance-scope.html#instance-per-request
|
||||
/// But "Behind the scenes, though, it’s still just instance per matching lifetime scope."
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// LifestylePerWebRequest in Castle Windsor - means one per web request.
|
||||
/// see https://github.com/castleproject/Windsor/blob/master/docs/mvc-tutorial-part-7-lifestyles.md#the-perwebrequest-lifestyle
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
Request,
|
||||
|
||||
/// <summary>
|
||||
/// One unique instance per container scope.
|
||||
/// One unique instance per scope.
|
||||
/// </summary>
|
||||
/// <remarks>Corresponds to Scope in LightInject, Scoped in MS.DI
|
||||
/// or Castle Windsor, PerLifetimeScope in Autofac.</remarks>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// Any instance created with this lifetime will be disposed at the end of the current scope.
|
||||
/// </para>
|
||||
/// Corresponds to
|
||||
/// <para>PerScopeLifetime in LightInject (when in a request, means one per web request)</para>
|
||||
/// <para>
|
||||
/// Scoped in MS.DI (when in a request, means one per web request)
|
||||
/// see https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-2.2#service-lifetimes</para>
|
||||
/// <para>
|
||||
/// InstancePerLifetimeScope in Autofac (when in a request, means one per web request)
|
||||
/// see https://autofaccn.readthedocs.io/en/latest/lifetime/instance-scope.html#instance-per-lifetime-scope
|
||||
/// Also note that Autofac's InstancePerRequest is the same as this, see https://autofaccn.readthedocs.io/en/latest/lifetime/instance-scope.html#instance-per-request
|
||||
/// it says "Behind the scenes, though, it’s still just instance per matching lifetime scope."
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// LifestyleScoped in Castle Windsor
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
Scope,
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -42,8 +42,8 @@ namespace Umbraco.Core.Composing
|
||||
private string _currentAssembliesHash;
|
||||
private IEnumerable<Assembly> _assemblies;
|
||||
private bool _reportedChange;
|
||||
private static string _localTempPath;
|
||||
private static string _fileBasePath;
|
||||
private readonly string _localTempPath;
|
||||
private string _fileBasePath;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TypeLoader"/> class.
|
||||
|
||||
@@ -4,6 +4,7 @@ using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Dictionary;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Logging.Viewer;
|
||||
using Umbraco.Core.Manifest;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.PackageActions;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
@@ -66,9 +67,16 @@ namespace Umbraco.Core
|
||||
/// Gets the validators collection builder.
|
||||
/// </summary>
|
||||
/// <param name="composition">The composition.</param>
|
||||
internal static ManifestValueValidatorCollectionBuilder Validators(this Composition composition)
|
||||
internal static ManifestValueValidatorCollectionBuilder ManifestValueValidators(this Composition composition)
|
||||
=> composition.WithCollectionBuilder<ManifestValueValidatorCollectionBuilder>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the manifest filter collection builder.
|
||||
/// </summary>
|
||||
/// <param name="composition">The composition.</param>
|
||||
public static ManifestFilterCollectionBuilder ManifestFilters(this Composition composition)
|
||||
=> composition.WithCollectionBuilder<ManifestFilterCollectionBuilder>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the components collection builder.
|
||||
/// </summary>
|
||||
|
||||
@@ -7,6 +7,7 @@ using Umbraco.Core.Configuration.HealthChecks;
|
||||
using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Manifest;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
@@ -41,7 +42,12 @@ namespace Umbraco.Core
|
||||
configs.Add(() => new CoreDebug());
|
||||
|
||||
// GridConfig depends on runtime caches, manifest parsers... and cannot be available during composition
|
||||
configs.Add<IGridConfig>(factory => new GridConfig(factory.GetInstance<ILogger>(), factory.GetInstance<AppCaches>(), configDir, factory.GetInstance<IRuntimeState>().Debug));
|
||||
configs.Add<IGridConfig>(factory => new GridConfig(
|
||||
factory.GetInstance<ILogger>(),
|
||||
factory.GetInstance<AppCaches>(),
|
||||
configDir,
|
||||
factory.GetInstance<ManifestParser>(),
|
||||
factory.GetInstance<IRuntimeState>().Debug));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
using System.IO;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Manifest;
|
||||
|
||||
namespace Umbraco.Core.Configuration.Grid
|
||||
{
|
||||
class GridConfig : IGridConfig
|
||||
{
|
||||
public GridConfig(ILogger logger, AppCaches appCaches, DirectoryInfo configFolder, bool isDebug)
|
||||
public GridConfig(ILogger logger, AppCaches appCaches, DirectoryInfo configFolder, ManifestParser manifestParser, bool isDebug)
|
||||
{
|
||||
EditorsConfig = new GridEditorsConfig(logger, appCaches, configFolder, isDebug);
|
||||
EditorsConfig = new GridEditorsConfig(logger, appCaches, configFolder, manifestParser, isDebug);
|
||||
}
|
||||
|
||||
public IGridEditorsConfig EditorsConfig { get; }
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Manifest;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
@@ -15,13 +13,15 @@ namespace Umbraco.Core.Configuration.Grid
|
||||
private readonly ILogger _logger;
|
||||
private readonly AppCaches _appCaches;
|
||||
private readonly DirectoryInfo _configFolder;
|
||||
private readonly ManifestParser _manifestParser;
|
||||
private readonly bool _isDebug;
|
||||
|
||||
public GridEditorsConfig(ILogger logger, AppCaches appCaches, DirectoryInfo configFolder, bool isDebug)
|
||||
public GridEditorsConfig(ILogger logger, AppCaches appCaches, DirectoryInfo configFolder, ManifestParser manifestParser, bool isDebug)
|
||||
{
|
||||
_logger = logger;
|
||||
_appCaches = appCaches;
|
||||
_configFolder = configFolder;
|
||||
_manifestParser = manifestParser;
|
||||
_isDebug = isDebug;
|
||||
}
|
||||
|
||||
@@ -31,9 +31,6 @@ namespace Umbraco.Core.Configuration.Grid
|
||||
{
|
||||
List<GridEditor> GetResult()
|
||||
{
|
||||
// TODO: should use the common one somehow! + ignoring _appPlugins here!
|
||||
var parser = new ManifestParser(_appCaches, Current.ManifestValidators, _logger);
|
||||
|
||||
var editors = new List<GridEditor>();
|
||||
var gridConfig = Path.Combine(_configFolder.FullName, "grid.editors.config.js");
|
||||
if (File.Exists(gridConfig))
|
||||
@@ -42,7 +39,7 @@ namespace Umbraco.Core.Configuration.Grid
|
||||
|
||||
try
|
||||
{
|
||||
editors.AddRange(parser.ParseGridEditors(sourceString));
|
||||
editors.AddRange(_manifestParser.ParseGridEditors(sourceString));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -51,7 +48,7 @@ namespace Umbraco.Core.Configuration.Grid
|
||||
}
|
||||
|
||||
// add manifest editors, skip duplicates
|
||||
foreach (var gridEditor in parser.Manifest.GridEditors)
|
||||
foreach (var gridEditor in _manifestParser.Manifest.GridEditors)
|
||||
{
|
||||
if (editors.Contains(gridEditor) == false) editors.Add(gridEditor);
|
||||
}
|
||||
|
||||
@@ -1,27 +1,375 @@
|
||||
namespace Umbraco.Core
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
public static partial class Constants
|
||||
{
|
||||
public static class DataTypes
|
||||
{
|
||||
public const int LabelString = -92;
|
||||
//NOTE: unfortunately due to backwards compat we can't move/rename these, with the addition of the GUID
|
||||
//constants, it would make more sense to have these suffixed with "ID" or in a Subclass called "INT", for
|
||||
//now all we can do is make a subclass called Guids to put the GUID IDs.
|
||||
|
||||
public const int LabelString = System.DefaultLabelDataTypeId;
|
||||
public const int LabelInt = -91;
|
||||
public const int LabelBigint = -93;
|
||||
public const int LabelDateTime = -94;
|
||||
public const int LabelTime = -98;
|
||||
public const int LabelDecimal = -99;
|
||||
|
||||
public const int Textarea = -89;
|
||||
public const int Textbox = -88;
|
||||
public const int RichtextEditor = -87;
|
||||
public const int Boolean = -49;
|
||||
public const int DateTime = -36;
|
||||
public const int DropDownSingle = -39;
|
||||
public const int DropDownMultiple = -42;
|
||||
public const int Upload = -90;
|
||||
|
||||
public const int DefaultContentListView = -95;
|
||||
public const int DefaultMediaListView = -96;
|
||||
public const int DefaultMembersListView = -97;
|
||||
|
||||
public const int ImageCropper = 1043;
|
||||
public const int Tags = 1041;
|
||||
|
||||
public static class ReservedPreValueKeys
|
||||
{
|
||||
public const string IgnoreUserStartNodes = "ignoreUserStartNodes";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the identifiers for Umbraco data types as constants for easy centralized access/management.
|
||||
/// </summary>
|
||||
public static class Guids
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Content Picker as string
|
||||
/// </summary>
|
||||
public const string ContentPicker = "FD1E0DA5-5606-4862-B679-5D0CF3A52A59";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Content Picker
|
||||
/// </summary>
|
||||
public static readonly Guid ContentPickerGuid = new Guid(ContentPicker);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Member Picker as string
|
||||
/// </summary>
|
||||
public const string MemberPicker = "1EA2E01F-EBD8-4CE1-8D71-6B1149E63548";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Member Picker
|
||||
/// </summary>
|
||||
public static readonly Guid MemberPickerGuid = new Guid(MemberPicker);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Media Picker as string
|
||||
/// </summary>
|
||||
public const string MediaPicker = "135D60E0-64D9-49ED-AB08-893C9BA44AE5";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Media Picker
|
||||
/// </summary>
|
||||
public static readonly Guid MediaPickerGuid = new Guid(MediaPicker);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Multiple Media Picker as string
|
||||
/// </summary>
|
||||
public const string MultipleMediaPicker = "9DBBCBBB-2327-434A-B355-AF1B84E5010A";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Multiple Media Picker
|
||||
/// </summary>
|
||||
public static readonly Guid MultipleMediaPickerGuid = new Guid(MultipleMediaPicker);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Related Links as string
|
||||
/// </summary>
|
||||
public const string RelatedLinks = "B4E3535A-1753-47E2-8568-602CF8CFEE6F";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Related Links
|
||||
/// </summary>
|
||||
public static readonly Guid RelatedLinksGuid = new Guid(RelatedLinks);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Member as string
|
||||
/// </summary>
|
||||
public const string Member = "d59be02f-1df9-4228-aa1e-01917d806cda";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Member
|
||||
/// </summary>
|
||||
public static readonly Guid MemberGuid = new Guid(Member);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Image Cropper as string
|
||||
/// </summary>
|
||||
public const string ImageCropper = "1df9f033-e6d4-451f-b8d2-e0cbc50a836f";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Image Cropper
|
||||
/// </summary>
|
||||
public static readonly Guid ImageCropperGuid = new Guid(ImageCropper);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Tags as string
|
||||
/// </summary>
|
||||
public const string Tags = "b6b73142-b9c1-4bf8-a16d-e1c23320b549";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Tags
|
||||
/// </summary>
|
||||
public static readonly Guid TagsGuid = new Guid(Tags);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for List View - Content as string
|
||||
/// </summary>
|
||||
public const string ListViewContent = "C0808DD3-8133-4E4B-8CE8-E2BEA84A96A4";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for List View - Content
|
||||
/// </summary>
|
||||
public static readonly Guid ListViewContentGuid = new Guid(ListViewContent);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for List View - Media as string
|
||||
/// </summary>
|
||||
public const string ListViewMedia = "3A0156C4-3B8C-4803-BDC1-6871FAA83FFF";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for List View - Media
|
||||
/// </summary>
|
||||
public static readonly Guid ListViewMediaGuid = new Guid(ListViewMedia);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for List View - Members as string
|
||||
/// </summary>
|
||||
public const string ListViewMembers = "AA2C52A0-CE87-4E65-A47C-7DF09358585D";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for List View - Members
|
||||
/// </summary>
|
||||
public static readonly Guid ListViewMembersGuid = new Guid(ListViewMembers);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Date Picker with time as string
|
||||
/// </summary>
|
||||
public const string DatePickerWithTime = "e4d66c0f-b935-4200-81f0-025f7256b89a";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Date Picker with time
|
||||
/// </summary>
|
||||
public static readonly Guid DatePickerWithTimeGuid = new Guid(DatePickerWithTime);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Approved Color as string
|
||||
/// </summary>
|
||||
public const string ApprovedColor = "0225af17-b302-49cb-9176-b9f35cab9c17";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Approved Color
|
||||
/// </summary>
|
||||
public static readonly Guid ApprovedColorGuid = new Guid(ApprovedColor);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Dropdown multiple as string
|
||||
/// </summary>
|
||||
public const string DropdownMultiple = "f38f0ac7-1d27-439c-9f3f-089cd8825a53";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Dropdown multiple
|
||||
/// </summary>
|
||||
public static readonly Guid DropdownMultipleGuid = new Guid(DropdownMultiple);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Radiobox as string
|
||||
/// </summary>
|
||||
public const string Radiobox = "bb5f57c9-ce2b-4bb9-b697-4caca783a805";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Radiobox
|
||||
/// </summary>
|
||||
public static readonly Guid RadioboxGuid = new Guid(Radiobox);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Date Picker as string
|
||||
/// </summary>
|
||||
public const string DatePicker = "5046194e-4237-453c-a547-15db3a07c4e1";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Date Picker
|
||||
/// </summary>
|
||||
public static readonly Guid DatePickerGuid = new Guid(DatePicker);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Dropdown as string
|
||||
/// </summary>
|
||||
public const string Dropdown = "0b6a45e7-44ba-430d-9da5-4e46060b9e03";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Dropdown
|
||||
/// </summary>
|
||||
public static readonly Guid DropdownGuid = new Guid(Dropdown);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Checkbox list as string
|
||||
/// </summary>
|
||||
public const string CheckboxList = "fbaf13a8-4036-41f2-93a3-974f678c312a";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Checkbox list
|
||||
/// </summary>
|
||||
public static readonly Guid CheckboxListGuid = new Guid(CheckboxList);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Checkbox as string
|
||||
/// </summary>
|
||||
public const string Checkbox = "92897bc6-a5f3-4ffe-ae27-f2e7e33dda49";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Checkbox
|
||||
/// </summary>
|
||||
public static readonly Guid CheckboxGuid = new Guid(Checkbox);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Numeric as string
|
||||
/// </summary>
|
||||
public const string Numeric = "2e6d3631-066e-44b8-aec4-96f09099b2b5";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Dropdown
|
||||
/// </summary>
|
||||
public static readonly Guid NumericGuid = new Guid(Numeric);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Richtext editor as string
|
||||
/// </summary>
|
||||
public const string RichtextEditor = "ca90c950-0aff-4e72-b976-a30b1ac57dad";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Richtext editor
|
||||
/// </summary>
|
||||
public static readonly Guid RichtextEditorGuid = new Guid(RichtextEditor);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Textstring as string
|
||||
/// </summary>
|
||||
public const string Textstring = "0cc0eba1-9960-42c9-bf9b-60e150b429ae";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Textstring
|
||||
/// </summary>
|
||||
public static readonly Guid TextstringGuid = new Guid(Textstring);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Textarea as string
|
||||
/// </summary>
|
||||
public const string Textarea = "c6bac0dd-4ab9-45b1-8e30-e4b619ee5da3";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Dropdown
|
||||
/// </summary>
|
||||
public static readonly Guid TextareaGuid = new Guid(Textarea);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Upload as string
|
||||
/// </summary>
|
||||
public const string Upload = "84c6b441-31df-4ffe-b67e-67d5bc3ae65a";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Upload
|
||||
/// </summary>
|
||||
public static readonly Guid UploadGuid = new Guid(Upload);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Label as string
|
||||
/// </summary>
|
||||
public const string LabelString = "f0bc4bfb-b499-40d6-ba86-058885a5178c";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Label string
|
||||
/// </summary>
|
||||
public static readonly Guid LabelStringGuid = new Guid(LabelString);
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Label as int
|
||||
/// </summary>
|
||||
public const string LabelInt = "8e7f995c-bd81-4627-9932-c40e568ec788";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Label int
|
||||
/// </summary>
|
||||
public static readonly Guid LabelIntGuid = new Guid(LabelInt);
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Label as big int
|
||||
/// </summary>
|
||||
public const string LabelBigInt = "930861bf-e262-4ead-a704-f99453565708";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Label big int
|
||||
/// </summary>
|
||||
public static readonly Guid LabelBigIntGuid = new Guid(LabelBigInt);
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Label as date time
|
||||
/// </summary>
|
||||
public const string LabelDateTime = "0e9794eb-f9b5-4f20-a788-93acd233a7e4";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Label date time
|
||||
/// </summary>
|
||||
public static readonly Guid LabelDateTimeGuid = new Guid(LabelDateTime);
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Label as time
|
||||
/// </summary>
|
||||
public const string LabelTime = "a97cec69-9b71-4c30-8b12-ec398860d7e8";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Label time
|
||||
/// </summary>
|
||||
public static readonly Guid LabelTimeGuid = new Guid(LabelTime);
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Label as decimal
|
||||
/// </summary>
|
||||
public const string LabelDecimal = "8f1ef1e1-9de4-40d3-a072-6673f631ca64";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Label decimal
|
||||
/// </summary>
|
||||
public static readonly Guid LabelDecimalGuid = new Guid(LabelDecimal);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,39 +5,89 @@
|
||||
public static class Icons
|
||||
{
|
||||
/// <summary>
|
||||
/// System contenttype icon
|
||||
/// System default icon
|
||||
/// </summary>
|
||||
public const string ContentType = "icon-arrangement";
|
||||
public const string DefaultIcon = Content;
|
||||
|
||||
/// <summary>
|
||||
/// System datatype icon
|
||||
/// System content icon
|
||||
/// </summary>
|
||||
public const string Content = "icon-document";
|
||||
|
||||
/// <summary>
|
||||
/// System content type icon
|
||||
/// </summary>
|
||||
public const string ContentType = "icon-item-arrangement";
|
||||
|
||||
/// <summary>
|
||||
/// System data type icon
|
||||
/// </summary>
|
||||
public const string DataType = "icon-autofill";
|
||||
|
||||
/// <summary>
|
||||
/// System property editor icon
|
||||
/// System list view icon
|
||||
/// </summary>
|
||||
public const string PropertyEditor = "icon-autofill";
|
||||
public const string ListView = "icon-thumbnail-list";
|
||||
|
||||
/// <summary>
|
||||
/// System macro icon
|
||||
/// </summary>
|
||||
public const string Macro = "icon-settings-alt";
|
||||
|
||||
/// <summary>
|
||||
/// System media file icon
|
||||
/// </summary>
|
||||
public const string MediaFile = "icon-document";
|
||||
|
||||
/// <summary>
|
||||
/// System media folder icon
|
||||
/// </summary>
|
||||
public const string MediaFolder = "icon-folder";
|
||||
|
||||
/// <summary>
|
||||
/// System media image icon
|
||||
/// </summary>
|
||||
public const string MediaImage = "icon-picture";
|
||||
|
||||
/// <summary>
|
||||
/// System media type icon
|
||||
/// </summary>
|
||||
public const string MediaType = "icon-thumbnails";
|
||||
|
||||
/// <summary>
|
||||
/// System member icon
|
||||
/// </summary>
|
||||
public const string Member = "icon-user";
|
||||
|
||||
/// <summary>
|
||||
/// System member icon
|
||||
/// System member group icon
|
||||
/// </summary>
|
||||
public const string MemberGroup = "icon-users-alt";
|
||||
|
||||
/// <summary>
|
||||
/// System member type icon
|
||||
/// </summary>
|
||||
public const string MemberType = "icon-users";
|
||||
|
||||
/// <summary>
|
||||
/// System property editor icon
|
||||
/// </summary>
|
||||
public const string PropertyEditor = "icon-autofill";
|
||||
|
||||
/// <summary>
|
||||
/// System member icon
|
||||
/// </summary>
|
||||
public const string Template = "icon-layout";
|
||||
|
||||
/// <summary>
|
||||
/// System user icon
|
||||
/// </summary>
|
||||
public const string User = "icon-user";
|
||||
|
||||
/// <summary>
|
||||
/// System user group icon
|
||||
/// </summary>
|
||||
public const string UserGroup = "icon-users";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,23 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
public const string InternalGenericPropertiesPrefix = "_umb_";
|
||||
|
||||
public static class Legacy
|
||||
{
|
||||
public static class Aliases
|
||||
{
|
||||
public const string Textbox = "Umbraco.Textbox";
|
||||
public const string Date = "Umbraco.Date";
|
||||
public const string ContentPicker2 = "Umbraco.ContentPicker2";
|
||||
public const string MediaPicker2 = "Umbraco.MediaPicker2";
|
||||
public const string MemberPicker2 = "Umbraco.MemberPicker2";
|
||||
public const string MultiNodeTreePicker2 = "Umbraco.MultiNodeTreePicker2";
|
||||
public const string TextboxMultiple = "Umbraco.TextboxMultiple";
|
||||
public const string RelatedLinks2 = "Umbraco.RelatedLinks2";
|
||||
public const string RelatedLinks = "Umbraco.RelatedLinks";
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines Umbraco built-in property editor aliases.
|
||||
/// </summary>
|
||||
|
||||
@@ -66,44 +66,44 @@ namespace Umbraco.Core
|
||||
/// <summary>
|
||||
/// Determines whether the content type is invariant.
|
||||
/// </summary>
|
||||
public static bool VariesByNothing(this PublishedContentType contentType) => contentType.Variations.VariesByNothing();
|
||||
public static bool VariesByNothing(this IPublishedContentType contentType) => contentType.Variations.VariesByNothing();
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the content type varies by culture.
|
||||
/// </summary>
|
||||
/// <remarks>And then it could also vary by segment.</remarks>
|
||||
public static bool VariesByCulture(this PublishedContentType contentType) => contentType.Variations.VariesByCulture();
|
||||
public static bool VariesByCulture(this IPublishedContentType contentType) => contentType.Variations.VariesByCulture();
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the content type varies by segment.
|
||||
/// </summary>
|
||||
/// <remarks>And then it could also vary by culture.</remarks>
|
||||
public static bool VariesBySegment(this PublishedContentType contentType) => contentType.Variations.VariesBySegment();
|
||||
public static bool VariesBySegment(this IPublishedContentType contentType) => contentType.Variations.VariesBySegment();
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the content type varies by culture and segment.
|
||||
/// </summary>
|
||||
public static bool VariesByCultureAndSegment(this PublishedContentType contentType) => contentType.Variations.VariesByCultureAndSegment();
|
||||
public static bool VariesByCultureAndSegment(this IPublishedContentType contentType) => contentType.Variations.VariesByCultureAndSegment();
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the property type is invariant.
|
||||
/// </summary>
|
||||
public static bool VariesByNothing(this PublishedPropertyType propertyType) => propertyType.Variations.VariesByNothing();
|
||||
public static bool VariesByNothing(this IPublishedPropertyType propertyType) => propertyType.Variations.VariesByNothing();
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the property type varies by culture.
|
||||
/// </summary>
|
||||
public static bool VariesByCulture(this PublishedPropertyType propertyType) => propertyType.Variations.VariesByCulture();
|
||||
public static bool VariesByCulture(this IPublishedPropertyType propertyType) => propertyType.Variations.VariesByCulture();
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the property type varies by segment.
|
||||
/// </summary>
|
||||
public static bool VariesBySegment(this PublishedPropertyType propertyType) => propertyType.Variations.VariesBySegment();
|
||||
public static bool VariesBySegment(this IPublishedPropertyType propertyType) => propertyType.Variations.VariesBySegment();
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the property type varies by culture and segment.
|
||||
/// </summary>
|
||||
public static bool VariesByCultureAndSegment(this PublishedPropertyType propertyType) => propertyType.Variations.VariesByCultureAndSegment();
|
||||
public static bool VariesByCultureAndSegment(this IPublishedPropertyType propertyType) => propertyType.Variations.VariesByCultureAndSegment();
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether a variation is invariant.
|
||||
|
||||
@@ -10,6 +10,8 @@ namespace Umbraco.Core
|
||||
///</summary>
|
||||
public static class EnumerableExtensions
|
||||
{
|
||||
internal static bool IsCollectionEmpty<T>(this IReadOnlyCollection<T> list) => list == null || list.Count == 0;
|
||||
|
||||
internal static bool HasDuplicates<T>(this IEnumerable<T> items, bool includeNull)
|
||||
{
|
||||
var hs = new HashSet<T>();
|
||||
@@ -112,7 +114,6 @@ namespace Umbraco.Core
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if all items in the other collection exist in this collection
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Umbraco.Core.Exceptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Internal exception that in theory should never ben thrown, it is only thrown in circumstances that should never happen
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
internal class PanicException : Exception
|
||||
{
|
||||
public PanicException()
|
||||
{
|
||||
}
|
||||
|
||||
public PanicException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public PanicException(string message, Exception innerException) : base(message, innerException)
|
||||
{
|
||||
}
|
||||
|
||||
protected PanicException(SerializationInfo info, StreamingContext context) : base(info, context)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,26 +26,26 @@ namespace Umbraco.Core.Logging.Viewer
|
||||
/// A count of number of errors
|
||||
/// By counting Warnings with Exceptions, Errors & Fatal messages
|
||||
/// </summary>
|
||||
int GetNumberOfErrors(DateTimeOffset startDate, DateTimeOffset endDate);
|
||||
int GetNumberOfErrors(LogTimePeriod logTimePeriod);
|
||||
|
||||
/// <summary>
|
||||
/// Returns a number of the different log level entries
|
||||
/// </summary>
|
||||
LogLevelCounts GetLogLevelCounts(DateTimeOffset startDate, DateTimeOffset endDate);
|
||||
LogLevelCounts GetLogLevelCounts(LogTimePeriod logTimePeriod);
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of all unique message templates and their counts
|
||||
/// </summary>
|
||||
IEnumerable<LogTemplate> GetMessageTemplates(DateTimeOffset startDate, DateTimeOffset endDate);
|
||||
IEnumerable<LogTemplate> GetMessageTemplates(LogTimePeriod logTimePeriod);
|
||||
|
||||
bool CanHandleLargeLogs { get; }
|
||||
|
||||
bool CheckCanOpenLogs(DateTimeOffset startDate, DateTimeOffset endDate);
|
||||
bool CheckCanOpenLogs(LogTimePeriod logTimePeriod);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the collection of logs
|
||||
/// </summary>
|
||||
PagedResult<LogMessage> GetLogs(DateTimeOffset startDate, DateTimeOffset endDate,
|
||||
PagedResult<LogMessage> GetLogs(LogTimePeriod logTimePeriod,
|
||||
int pageNumber = 1,
|
||||
int pageSize = 100,
|
||||
Direction orderDirection = Direction.Descending,
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace Umbraco.Core.Logging.Viewer
|
||||
|
||||
public override bool CanHandleLargeLogs => false;
|
||||
|
||||
public override bool CheckCanOpenLogs(DateTimeOffset startDate, DateTimeOffset endDate)
|
||||
public override bool CheckCanOpenLogs(LogTimePeriod logTimePeriod)
|
||||
{
|
||||
//Log Directory
|
||||
var logDirectory = _logsPath;
|
||||
@@ -36,7 +36,7 @@ namespace Umbraco.Core.Logging.Viewer
|
||||
|
||||
//foreach full day in the range - see if we can find one or more filenames that end with
|
||||
//yyyyMMdd.json - Ends with due to MachineName in filenames - could be 1 or more due to load balancing
|
||||
for (var day = startDate.Date; day.Date <= endDate.Date; day = day.AddDays(1))
|
||||
for (var day = logTimePeriod.StartTime.Date; day.Date <= logTimePeriod.EndTime.Date; day = day.AddDays(1))
|
||||
{
|
||||
//Filename ending to search for (As could be multiple)
|
||||
var filesToFind = GetSearchPattern(day);
|
||||
@@ -57,7 +57,7 @@ namespace Umbraco.Core.Logging.Viewer
|
||||
return $"*{day:yyyyMMdd}*.json";
|
||||
}
|
||||
|
||||
protected override IReadOnlyList<LogEvent> GetLogs(DateTimeOffset startDate, DateTimeOffset endDate, ILogFilter filter, int skip, int take)
|
||||
protected override IReadOnlyList<LogEvent> GetLogs(LogTimePeriod logTimePeriod, ILogFilter filter, int skip, int take)
|
||||
{
|
||||
var logs = new List<LogEvent>();
|
||||
|
||||
@@ -68,7 +68,7 @@ namespace Umbraco.Core.Logging.Viewer
|
||||
|
||||
//foreach full day in the range - see if we can find one or more filenames that end with
|
||||
//yyyyMMdd.json - Ends with due to MachineName in filenames - could be 1 or more due to load balancing
|
||||
for (var day = startDate.Date; day.Date <= endDate.Date; day = day.AddDays(1))
|
||||
for (var day = logTimePeriod.StartTime.Date; day.Date <= logTimePeriod.EndTime.Date; day = day.AddDays(1))
|
||||
{
|
||||
//Filename ending to search for (As could be multiple)
|
||||
var filesToFind = GetSearchPattern(day);
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.Logging.Viewer
|
||||
{
|
||||
public class LogTimePeriod
|
||||
{
|
||||
public LogTimePeriod(DateTime startTime, DateTime endTime)
|
||||
{
|
||||
StartTime = startTime;
|
||||
EndTime = endTime;
|
||||
}
|
||||
|
||||
public DateTime StartTime { get; }
|
||||
public DateTime EndTime { get; }
|
||||
}
|
||||
}
|
||||
@@ -27,9 +27,9 @@ namespace Umbraco.Core.Logging.Viewer
|
||||
/// <summary>
|
||||
/// Get all logs from your chosen data source back as Serilog LogEvents
|
||||
/// </summary>
|
||||
protected abstract IReadOnlyList<LogEvent> GetLogs(DateTimeOffset startDate, DateTimeOffset endDate, ILogFilter filter, int skip, int take);
|
||||
protected abstract IReadOnlyList<LogEvent> GetLogs(LogTimePeriod logTimePeriod, ILogFilter filter, int skip, int take);
|
||||
|
||||
public abstract bool CheckCanOpenLogs(DateTimeOffset startDate, DateTimeOffset endDate);
|
||||
public abstract bool CheckCanOpenLogs(LogTimePeriod logTimePeriod);
|
||||
|
||||
public virtual IReadOnlyList<SavedLogSearch> GetSavedSearches()
|
||||
{
|
||||
@@ -82,24 +82,24 @@ namespace Umbraco.Core.Logging.Viewer
|
||||
return searches;
|
||||
}
|
||||
|
||||
public int GetNumberOfErrors(DateTimeOffset startDate, DateTimeOffset endDate)
|
||||
public int GetNumberOfErrors(LogTimePeriod logTimePeriod)
|
||||
{
|
||||
var errorCounter = new ErrorCounterFilter();
|
||||
GetLogs(startDate, endDate, errorCounter, 0, int.MaxValue);
|
||||
GetLogs(logTimePeriod, errorCounter, 0, int.MaxValue);
|
||||
return errorCounter.Count;
|
||||
}
|
||||
|
||||
public LogLevelCounts GetLogLevelCounts(DateTimeOffset startDate, DateTimeOffset endDate)
|
||||
public LogLevelCounts GetLogLevelCounts(LogTimePeriod logTimePeriod)
|
||||
{
|
||||
var counter = new CountingFilter();
|
||||
GetLogs(startDate, endDate, counter, 0, int.MaxValue);
|
||||
GetLogs(logTimePeriod, counter, 0, int.MaxValue);
|
||||
return counter.Counts;
|
||||
}
|
||||
|
||||
public IEnumerable<LogTemplate> GetMessageTemplates(DateTimeOffset startDate, DateTimeOffset endDate)
|
||||
public IEnumerable<LogTemplate> GetMessageTemplates(LogTimePeriod logTimePeriod)
|
||||
{
|
||||
var messageTemplates = new MessageTemplateFilter();
|
||||
GetLogs(startDate, endDate, messageTemplates, 0, int.MaxValue);
|
||||
GetLogs(logTimePeriod, messageTemplates, 0, int.MaxValue);
|
||||
|
||||
var templates = messageTemplates.Counts.
|
||||
Select(x => new LogTemplate { MessageTemplate = x.Key, Count = x.Value })
|
||||
@@ -108,14 +108,14 @@ namespace Umbraco.Core.Logging.Viewer
|
||||
return templates;
|
||||
}
|
||||
|
||||
public PagedResult<LogMessage> GetLogs(DateTimeOffset startDate, DateTimeOffset endDate,
|
||||
public PagedResult<LogMessage> GetLogs(LogTimePeriod logTimePeriod,
|
||||
int pageNumber = 1, int pageSize = 100,
|
||||
Direction orderDirection = Direction.Descending,
|
||||
string filterExpression = null,
|
||||
string[] logLevels = null)
|
||||
{
|
||||
var expression = new ExpressionFilter(filterExpression);
|
||||
var filteredLogs = GetLogs(startDate, endDate, expression, 0, int.MaxValue);
|
||||
var filteredLogs = GetLogs(logTimePeriod, expression, 0, int.MaxValue);
|
||||
|
||||
//This is user used the checkbox UI to toggle which log levels they wish to see
|
||||
//If an empty array or null - its implied all levels to be viewed
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Web.Hosting;
|
||||
@@ -113,7 +114,7 @@ namespace Umbraco.Core
|
||||
|
||||
lock (_locko)
|
||||
{
|
||||
_logger.Debug<MainDom>("Signaled {Signaled} ({SignalSource})", _signaled ? "(again)" : string.Empty, source);
|
||||
_logger.Debug<MainDom>("Signaled ({Signaled}) ({SignalSource})", _signaled ? "again" : "first", source);
|
||||
if (_signaled) return;
|
||||
if (_isMainDom == false) return; // probably not needed
|
||||
_signaled = true;
|
||||
@@ -171,6 +172,7 @@ namespace Umbraco.Core
|
||||
// if more than 1 instance reach that point, one will get the lock
|
||||
// and the other one will timeout, which is accepted
|
||||
|
||||
//TODO: This can throw a TimeoutException - in which case should this be in a try/finally to ensure the signal is always reset?
|
||||
_asyncLocker = _asyncLock.Lock(LockTimeoutMilliseconds);
|
||||
_isMainDom = true;
|
||||
|
||||
@@ -181,6 +183,9 @@ namespace Umbraco.Core
|
||||
// which is accepted
|
||||
|
||||
_signal.Reset();
|
||||
|
||||
//WaitOneAsync (ext method) will wait for a signal without blocking the main thread, the waiting is done on a background thread
|
||||
|
||||
_signal.WaitOneAsync()
|
||||
.ContinueWith(_ => OnSignal("signal"));
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Umbraco.Core.Manifest
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides filtering for package manifests.
|
||||
/// </summary>
|
||||
public interface IManifestFilter
|
||||
{
|
||||
/// <summary>
|
||||
/// Filters package manifests.
|
||||
/// </summary>
|
||||
/// <param name="manifests">The package manifests.</param>
|
||||
/// <remarks>
|
||||
/// <para>It is possible to remove, change, or add manifests.</para>
|
||||
/// </remarks>
|
||||
void Filter(List<PackageManifest> manifests);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Composing;
|
||||
|
||||
namespace Umbraco.Core.Manifest
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains the manifest filters.
|
||||
/// </summary>
|
||||
public class ManifestFilterCollection : BuilderCollectionBase<IManifestFilter>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ManifestFilterCollection"/> class.
|
||||
/// </summary>
|
||||
public ManifestFilterCollection(IEnumerable<IManifestFilter> items)
|
||||
: base(items)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Filters package manifests.
|
||||
/// </summary>
|
||||
/// <param name="manifests">The package manifests.</param>
|
||||
public void Filter(List<PackageManifest> manifests)
|
||||
{
|
||||
foreach (var filter in this)
|
||||
filter.Filter(manifests);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using Umbraco.Core.Composing;
|
||||
|
||||
namespace Umbraco.Core.Manifest
|
||||
{
|
||||
public class ManifestFilterCollectionBuilder : OrderedCollectionBuilderBase<ManifestFilterCollectionBuilder, ManifestFilterCollection, IManifestFilter>
|
||||
{
|
||||
protected override ManifestFilterCollectionBuilder This => this;
|
||||
|
||||
// do NOT cache this, it's only used once
|
||||
protected override Lifetime CollectionLifetime => Lifetime.Transient;
|
||||
}
|
||||
}
|
||||
@@ -22,24 +22,26 @@ namespace Umbraco.Core.Manifest
|
||||
private readonly IAppPolicyCache _cache;
|
||||
private readonly ILogger _logger;
|
||||
private readonly ManifestValueValidatorCollection _validators;
|
||||
private readonly ManifestFilterCollection _filters;
|
||||
|
||||
private string _path;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ManifestParser"/> class.
|
||||
/// </summary>
|
||||
public ManifestParser(AppCaches appCaches, ManifestValueValidatorCollection validators, ILogger logger)
|
||||
: this(appCaches, validators, "~/App_Plugins", logger)
|
||||
public ManifestParser(AppCaches appCaches, ManifestValueValidatorCollection validators, ManifestFilterCollection filters, ILogger logger)
|
||||
: this(appCaches, validators, filters, "~/App_Plugins", logger)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ManifestParser"/> class.
|
||||
/// </summary>
|
||||
private ManifestParser(AppCaches appCaches, ManifestValueValidatorCollection validators, string path, ILogger logger)
|
||||
private ManifestParser(AppCaches appCaches, ManifestValueValidatorCollection validators, ManifestFilterCollection filters, string path, ILogger logger)
|
||||
{
|
||||
if (appCaches == null) throw new ArgumentNullException(nameof(appCaches));
|
||||
_cache = appCaches.RuntimeCache;
|
||||
_validators = validators ?? throw new ArgumentNullException(nameof(validators));
|
||||
_filters = filters ?? throw new ArgumentNullException(nameof(filters));
|
||||
if (string.IsNullOrWhiteSpace(path)) throw new ArgumentNullOrEmptyException(nameof(path));
|
||||
Path = path;
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
@@ -78,6 +80,7 @@ namespace Umbraco.Core.Manifest
|
||||
if (string.IsNullOrWhiteSpace(text))
|
||||
continue;
|
||||
var manifest = ParseManifest(text);
|
||||
manifest.Source = path;
|
||||
manifests.Add(manifest);
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -86,6 +89,8 @@ namespace Umbraco.Core.Manifest
|
||||
}
|
||||
}
|
||||
|
||||
_filters.Filter(manifests);
|
||||
|
||||
return manifests;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,16 @@ namespace Umbraco.Core.Manifest
|
||||
/// </summary>
|
||||
public class PackageManifest
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the source path of the manifest.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>Gets the full absolute file path of the manifest,
|
||||
/// using system directory separators.</para>
|
||||
/// </remarks>
|
||||
[JsonIgnore]
|
||||
public string Source { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the scripts listed in the manifest.
|
||||
/// </summary>
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Exceptions;
|
||||
|
||||
namespace Umbraco.Core.Mapping
|
||||
{
|
||||
@@ -191,7 +192,7 @@ namespace Umbraco.Core.Mapping
|
||||
private TTarget Map<TTarget>(object source, Type sourceType, MapperContext context)
|
||||
{
|
||||
if (source == null)
|
||||
throw new ArgumentNullException(nameof(source));
|
||||
return default;
|
||||
|
||||
var targetType = typeof(TTarget);
|
||||
|
||||
@@ -259,7 +260,7 @@ namespace Umbraco.Core.Mapping
|
||||
if (typeof(TTarget).IsArray)
|
||||
{
|
||||
var elementType = typeof(TTarget).GetElementType();
|
||||
if (elementType == null) throw new Exception("panic");
|
||||
if (elementType == null) throw new PanicException("elementType == null which should never occur");
|
||||
var targetArray = Array.CreateInstance(elementType, targetList.Count);
|
||||
targetList.CopyTo(targetArray, 0);
|
||||
target = targetArray;
|
||||
@@ -382,7 +383,7 @@ namespace Umbraco.Core.Mapping
|
||||
{
|
||||
if (type.IsArray) return type.GetElementType();
|
||||
if (type.IsGenericType) return type.GenericTypeArguments[0];
|
||||
throw new Exception("panic");
|
||||
throw new PanicException($"Could not get enumerable or array type from {type}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -389,7 +389,7 @@ namespace Umbraco.Core.Migrations.Install
|
||||
|
||||
private DatabaseSchemaResult ValidateSchema(IScope scope)
|
||||
{
|
||||
if (_databaseFactory.Configured == false)
|
||||
if (_databaseFactory.Initialized == false)
|
||||
return new DatabaseSchemaResult(_databaseFactory.SqlContext.SqlSyntax);
|
||||
|
||||
if (_databaseSchemaValidationResult != null)
|
||||
@@ -513,7 +513,7 @@ namespace Umbraco.Core.Migrations.Install
|
||||
|
||||
private Attempt<Result> CheckReadyForInstall()
|
||||
{
|
||||
if (_databaseFactory.Configured == false)
|
||||
if (_databaseFactory.CanConnect == false)
|
||||
{
|
||||
return Attempt.Fail(new Result
|
||||
{
|
||||
|
||||
@@ -101,33 +101,33 @@ namespace Umbraco.Core.Migrations.Install
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -1, Trashed = false, ParentId = -1, UserId = -1, Level = 0, Path = "-1", SortOrder = 0, UniqueId = new Guid("916724a5-173d-4619-b97e-b9de133dd6f5"), Text = "SYSTEM DATA: umbraco master root", NodeObjectType = Constants.ObjectTypes.SystemRoot, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -20, Trashed = false, ParentId = -1, UserId = -1, Level = 0, Path = "-1,-20", SortOrder = 0, UniqueId = new Guid("0F582A79-1E41-4CF0-BFA0-76340651891A"), Text = "Recycle Bin", NodeObjectType = Constants.ObjectTypes.ContentRecycleBin, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -21, Trashed = false, ParentId = -1, UserId = -1, Level = 0, Path = "-1,-21", SortOrder = 0, UniqueId = new Guid("BF7C7CBC-952F-4518-97A2-69E9C7B33842"), Text = "Recycle Bin", NodeObjectType = Constants.ObjectTypes.MediaRecycleBin, CreateDate = DateTime.Now });
|
||||
InsertDataTypeNodeDto(Constants.DataTypes.LabelString, 35, "f0bc4bfb-b499-40d6-ba86-058885a5178c", "Label");
|
||||
InsertDataTypeNodeDto(Constants.DataTypes.LabelInt, 36, "8e7f995c-bd81-4627-9932-c40e568ec788", "Label (integer)");
|
||||
InsertDataTypeNodeDto(Constants.DataTypes.LabelBigint, 36, "930861bf-e262-4ead-a704-f99453565708", "Label (bigint)");
|
||||
InsertDataTypeNodeDto(Constants.DataTypes.LabelDateTime, 37, "0e9794eb-f9b5-4f20-a788-93acd233a7e4", "Label (datetime)");
|
||||
InsertDataTypeNodeDto(Constants.DataTypes.LabelTime, 38, "a97cec69-9b71-4c30-8b12-ec398860d7e8", "Label (time)");
|
||||
InsertDataTypeNodeDto(Constants.DataTypes.LabelDecimal, 39, "8f1ef1e1-9de4-40d3-a072-6673f631ca64", "Label (decimal)");
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -90, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-90", SortOrder = 34, UniqueId = new Guid("84c6b441-31df-4ffe-b67e-67d5bc3ae65a"), Text = "Upload", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -89, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-89", SortOrder = 33, UniqueId = new Guid("c6bac0dd-4ab9-45b1-8e30-e4b619ee5da3"), Text = "Textarea", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -88, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-88", SortOrder = 32, UniqueId = new Guid("0cc0eba1-9960-42c9-bf9b-60e150b429ae"), Text = "Textstring", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -87, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-87", SortOrder = 4, UniqueId = new Guid("ca90c950-0aff-4e72-b976-a30b1ac57dad"), Text = "Richtext editor", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -51, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-51", SortOrder = 2, UniqueId = new Guid("2e6d3631-066e-44b8-aec4-96f09099b2b5"), Text = "Numeric", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -49, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-49", SortOrder = 2, UniqueId = new Guid("92897bc6-a5f3-4ffe-ae27-f2e7e33dda49"), Text = "True/false", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -43, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-43", SortOrder = 2, UniqueId = new Guid("fbaf13a8-4036-41f2-93a3-974f678c312a"), Text = "Checkbox list", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DropDownSingle, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DropDownSingle}", SortOrder = 2, UniqueId = new Guid("0b6a45e7-44ba-430d-9da5-4e46060b9e03"), Text = "Dropdown", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -41, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-41", SortOrder = 2, UniqueId = new Guid("5046194e-4237-453c-a547-15db3a07c4e1"), Text = "Date Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -40, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-40", SortOrder = 2, UniqueId = new Guid("bb5f57c9-ce2b-4bb9-b697-4caca783a805"), Text = "Radiobox", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DropDownMultiple, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DropDownMultiple}", SortOrder = 2, UniqueId = new Guid("f38f0ac7-1d27-439c-9f3f-089cd8825a53"), Text = "Dropdown multiple", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -37, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-37", SortOrder = 2, UniqueId = new Guid("0225af17-b302-49cb-9176-b9f35cab9c17"), Text = "Approved Color", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -36, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-36", SortOrder = 2, UniqueId = new Guid("e4d66c0f-b935-4200-81f0-025f7256b89a"), Text = "Date Picker with time", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DefaultContentListView, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DefaultContentListView}", SortOrder = 2, UniqueId = new Guid("C0808DD3-8133-4E4B-8CE8-E2BEA84A96A4"), Text = Constants.Conventions.DataTypes.ListViewPrefix + "Content", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DefaultMediaListView, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DefaultMediaListView}", SortOrder = 2, UniqueId = new Guid("3A0156C4-3B8C-4803-BDC1-6871FAA83FFF"), Text = Constants.Conventions.DataTypes.ListViewPrefix + "Media", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DefaultMembersListView, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DefaultMembersListView}", SortOrder = 2, UniqueId = new Guid("AA2C52A0-CE87-4E65-A47C-7DF09358585D"), Text = Constants.Conventions.DataTypes.ListViewPrefix + "Members", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
InsertDataTypeNodeDto(Constants.DataTypes.LabelString, 35, Constants.DataTypes.Guids.LabelString, "Label (string)");
|
||||
InsertDataTypeNodeDto(Constants.DataTypes.LabelInt, 36, Constants.DataTypes.Guids.LabelInt, "Label (integer)");
|
||||
InsertDataTypeNodeDto(Constants.DataTypes.LabelBigint, 36, Constants.DataTypes.Guids.LabelBigInt, "Label (bigint)");
|
||||
InsertDataTypeNodeDto(Constants.DataTypes.LabelDateTime, 37, Constants.DataTypes.Guids.LabelDateTime, "Label (datetime)");
|
||||
InsertDataTypeNodeDto(Constants.DataTypes.LabelTime, 38, Constants.DataTypes.Guids.LabelTime, "Label (time)");
|
||||
InsertDataTypeNodeDto(Constants.DataTypes.LabelDecimal, 39, Constants.DataTypes.Guids.LabelDecimal, "Label (decimal)");
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.Upload, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.Upload}", SortOrder = 34, UniqueId = Constants.DataTypes.Guids.UploadGuid, Text = "Upload", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.Textarea, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.Textarea}", SortOrder = 33, UniqueId = Constants.DataTypes.Guids.TextareaGuid, Text = "Textarea", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.Textbox, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.Textbox}", SortOrder = 32, UniqueId = Constants.DataTypes.Guids.TextstringGuid, Text = "Textstring", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.RichtextEditor, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.RichtextEditor}", SortOrder = 4, UniqueId = Constants.DataTypes.Guids.RichtextEditorGuid, Text = "Richtext editor", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -51, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-51", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.NumericGuid, Text = "Numeric", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.Boolean, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.Boolean}", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.CheckboxGuid, Text = "True/false", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -43, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-43", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.CheckboxListGuid, Text = "Checkbox list", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DropDownSingle, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DropDownSingle}", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.DropdownGuid, Text = "Dropdown", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -41, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-41", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.DatePickerGuid, Text = "Date Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -40, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-40", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.RadioboxGuid, Text = "Radiobox", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DropDownMultiple, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DropDownMultiple}", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.DropdownMultipleGuid, Text = "Dropdown multiple", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -37, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-37", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.ApprovedColorGuid, Text = "Approved Color", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DateTime, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DateTime}", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.DatePickerWithTimeGuid, Text = "Date Picker with time", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DefaultContentListView, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DefaultContentListView}", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.ListViewContentGuid, Text = Constants.Conventions.DataTypes.ListViewPrefix + "Content", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DefaultMediaListView, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DefaultMediaListView}", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.ListViewMediaGuid, Text = Constants.Conventions.DataTypes.ListViewPrefix + "Media", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DefaultMembersListView, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DefaultMembersListView}", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.ListViewMembersGuid, Text = Constants.Conventions.DataTypes.ListViewPrefix + "Members", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1031, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1031", SortOrder = 2, UniqueId = new Guid("f38bd2d7-65d0-48e6-95dc-87ce06ec2d3d"), Text = Constants.Conventions.MediaTypes.Folder, NodeObjectType = Constants.ObjectTypes.MediaType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1032, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1032", SortOrder = 2, UniqueId = new Guid("cc07b313-0843-4aa8-bbda-871c8da728c8"), Text = Constants.Conventions.MediaTypes.Image, NodeObjectType = Constants.ObjectTypes.MediaType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1033, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1033", SortOrder = 2, UniqueId = new Guid("4c52d8ab-54e6-40cd-999c-7a5f24903e4d"), Text = Constants.Conventions.MediaTypes.File, NodeObjectType = Constants.ObjectTypes.MediaType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1041, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1041", SortOrder = 2, UniqueId = new Guid("b6b73142-b9c1-4bf8-a16d-e1c23320b549"), Text = "Tags", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1043, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1043", SortOrder = 2, UniqueId = new Guid("1df9f033-e6d4-451f-b8d2-e0cbc50a836f"), Text = "Image Cropper", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.Tags, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.Tags}", SortOrder = 2, UniqueId = new Guid("b6b73142-b9c1-4bf8-a16d-e1c23320b549"), Text = "Tags", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.ImageCropper, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.ImageCropper}", SortOrder = 2, UniqueId = new Guid("1df9f033-e6d4-451f-b8d2-e0cbc50a836f"), Text = "Image Cropper", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1044, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1044", SortOrder = 0, UniqueId = new Guid("d59be02f-1df9-4228-aa1e-01917d806cda"), Text = Constants.Conventions.MemberTypes.DefaultAlias, NodeObjectType = Constants.ObjectTypes.MemberType, CreateDate = DateTime.Now });
|
||||
|
||||
//New UDI pickers with newer Ids
|
||||
@@ -155,10 +155,10 @@ namespace Umbraco.Core.Migrations.Install
|
||||
|
||||
private void CreateContentTypeData()
|
||||
{
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 532, NodeId = 1031, Alias = Constants.Conventions.MediaTypes.Folder, Icon = "icon-folder", Thumbnail = "icon-folder", IsContainer = false, AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 533, NodeId = 1032, Alias = Constants.Conventions.MediaTypes.Image, Icon = "icon-picture", Thumbnail = "icon-picture", AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 534, NodeId = 1033, Alias = Constants.Conventions.MediaTypes.File, Icon = "icon-document", Thumbnail = "icon-document", AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 531, NodeId = 1044, Alias = Constants.Conventions.MemberTypes.DefaultAlias, Icon = "icon-user", Thumbnail = "icon-user", Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 532, NodeId = 1031, Alias = Constants.Conventions.MediaTypes.Folder, Icon = Constants.Icons.MediaFolder, Thumbnail = Constants.Icons.MediaFolder, IsContainer = false, AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 533, NodeId = 1032, Alias = Constants.Conventions.MediaTypes.Image, Icon = Constants.Icons.MediaImage, Thumbnail = Constants.Icons.MediaImage, AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 534, NodeId = 1033, Alias = Constants.Conventions.MediaTypes.File, Icon = Constants.Icons.MediaFile, Thumbnail = Constants.Icons.MediaFile, AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 531, NodeId = 1044, Alias = Constants.Conventions.MemberTypes.DefaultAlias, Icon = Constants.Icons.Member, Thumbnail = Constants.Icons.Member, Variations = (byte) ContentVariation.Nothing });
|
||||
}
|
||||
|
||||
private void CreateUserData()
|
||||
@@ -210,19 +210,19 @@ namespace Umbraco.Core.Migrations.Install
|
||||
|
||||
private void CreatePropertyTypeData()
|
||||
{
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 6, UniqueId = 6.ToGuid(), DataTypeId = 1043, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.File, Name = "Upload image", SortOrder = 0, Mandatory = true, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 6, UniqueId = 6.ToGuid(), DataTypeId = Constants.DataTypes.ImageCropper, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.File, Name = "Upload image", SortOrder = 0, Mandatory = true, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 7, UniqueId = 7.ToGuid(), DataTypeId = Constants.DataTypes.LabelInt, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.Width, Name = "Width", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = "in pixels", Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 8, UniqueId = 8.ToGuid(), DataTypeId = Constants.DataTypes.LabelInt, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.Height, Name = "Height", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = "in pixels", Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 9, UniqueId = 9.ToGuid(), DataTypeId = Constants.DataTypes.LabelBigint, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.Bytes, Name = "Size", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = "in bytes", Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 10, UniqueId = 10.ToGuid(), DataTypeId = -92, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.Extension, Name = "Type", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 24, UniqueId = 24.ToGuid(), DataTypeId = -90, ContentTypeId = 1033, PropertyTypeGroupId = 4, Alias = Constants.Conventions.Media.File, Name = "Upload file", SortOrder = 0, Mandatory = true, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 24, UniqueId = 24.ToGuid(), DataTypeId = Constants.DataTypes.Upload, ContentTypeId = 1033, PropertyTypeGroupId = 4, Alias = Constants.Conventions.Media.File, Name = "Upload file", SortOrder = 0, Mandatory = true, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 25, UniqueId = 25.ToGuid(), DataTypeId = -92, ContentTypeId = 1033, PropertyTypeGroupId = 4, Alias = Constants.Conventions.Media.Extension, Name = "Type", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 26, UniqueId = 26.ToGuid(), DataTypeId = Constants.DataTypes.LabelBigint, ContentTypeId = 1033, PropertyTypeGroupId = 4, Alias = Constants.Conventions.Media.Bytes, Name = "Size", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = "in bytes", Variations = (byte) ContentVariation.Nothing });
|
||||
//membership property types
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 28, UniqueId = 28.ToGuid(), DataTypeId = -89, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.Comments, Name = Constants.Conventions.Member.CommentsLabel, SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 28, UniqueId = 28.ToGuid(), DataTypeId = Constants.DataTypes.Textarea, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.Comments, Name = Constants.Conventions.Member.CommentsLabel, SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 29, UniqueId = 29.ToGuid(), DataTypeId = Constants.DataTypes.LabelInt, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.FailedPasswordAttempts, Name = Constants.Conventions.Member.FailedPasswordAttemptsLabel, SortOrder = 1, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 30, UniqueId = 30.ToGuid(), DataTypeId = -49, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.IsApproved, Name = Constants.Conventions.Member.IsApprovedLabel, SortOrder = 2, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 31, UniqueId = 31.ToGuid(), DataTypeId = -49, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.IsLockedOut, Name = Constants.Conventions.Member.IsLockedOutLabel, SortOrder = 3, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 30, UniqueId = 30.ToGuid(), DataTypeId = Constants.DataTypes.Boolean, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.IsApproved, Name = Constants.Conventions.Member.IsApprovedLabel, SortOrder = 2, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 31, UniqueId = 31.ToGuid(), DataTypeId = Constants.DataTypes.Boolean, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.IsLockedOut, Name = Constants.Conventions.Member.IsLockedOutLabel, SortOrder = 3, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 32, UniqueId = 32.ToGuid(), DataTypeId = Constants.DataTypes.LabelDateTime, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.LastLockoutDate, Name = Constants.Conventions.Member.LastLockoutDateLabel, SortOrder = 4, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 33, UniqueId = 33.ToGuid(), DataTypeId = Constants.DataTypes.LabelDateTime, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.LastLoginDate, Name = Constants.Conventions.Member.LastLoginDateLabel, SortOrder = 5, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 34, UniqueId = 34.ToGuid(), DataTypeId = Constants.DataTypes.LabelDateTime, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.LastPasswordChangeDate, Name = Constants.Conventions.Member.LastPasswordChangeDateLabel, SortOrder = 6, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
|
||||
@@ -266,30 +266,30 @@ namespace Umbraco.Core.Migrations.Install
|
||||
const string layouts = "[" + cardLayout + "," + listLayout + "]";
|
||||
|
||||
// TODO: Check which of the DataTypeIds below doesn't exist in umbracoNode, which results in a foreign key constraint errors.
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -49, EditorAlias = Constants.PropertyEditors.Aliases.Boolean, DbType = "Integer" });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = Constants.DataTypes.Boolean, EditorAlias = Constants.PropertyEditors.Aliases.Boolean, DbType = "Integer" });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -51, EditorAlias = Constants.PropertyEditors.Aliases.Integer, DbType = "Integer" });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -87, EditorAlias = Constants.PropertyEditors.Aliases.TinyMce, DbType = "Ntext",
|
||||
Configuration = "{\"value\":\",code,undo,redo,cut,copy,mcepasteword,stylepicker,bold,italic,bullist,numlist,outdent,indent,mcelink,unlink,mceinsertanchor,mceimage,umbracomacro,mceinserttable,umbracoembed,mcecharmap,|1|1,2,3,|0|500,400|1049,|true|\"}" });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -88, EditorAlias = Constants.PropertyEditors.Aliases.TextBox, DbType = "Nvarchar" });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -89, EditorAlias = Constants.PropertyEditors.Aliases.TextArea, DbType = "Ntext" });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -90, EditorAlias = Constants.PropertyEditors.Aliases.UploadField, DbType = "Nvarchar" });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = Constants.DataTypes.Textbox, EditorAlias = Constants.PropertyEditors.Aliases.TextBox, DbType = "Nvarchar" });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = Constants.DataTypes.Textarea, EditorAlias = Constants.PropertyEditors.Aliases.TextArea, DbType = "Ntext" });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = Constants.DataTypes.Upload, EditorAlias = Constants.PropertyEditors.Aliases.UploadField, DbType = "Nvarchar" });
|
||||
InsertDataTypeDto(Constants.DataTypes.LabelString, Constants.PropertyEditors.Aliases.Label, "Nvarchar", "{\"umbracoDataValueType\":\"STRING\"}");
|
||||
InsertDataTypeDto(Constants.DataTypes.LabelInt, Constants.PropertyEditors.Aliases.Label, "Integer", "{\"umbracoDataValueType\":\"INT\"}");
|
||||
InsertDataTypeDto(Constants.DataTypes.LabelBigint, Constants.PropertyEditors.Aliases.Label, "Nvarchar", "{\"umbracoDataValueType\":\"BIGINT\"}");
|
||||
InsertDataTypeDto(Constants.DataTypes.LabelDateTime, Constants.PropertyEditors.Aliases.Label, "Date", "{\"umbracoDataValueType\":\"DATETIME\"}");
|
||||
InsertDataTypeDto(Constants.DataTypes.LabelDecimal, Constants.PropertyEditors.Aliases.Label, "Decimal", "{\"umbracoDataValueType\":\"DECIMAL\"}");
|
||||
InsertDataTypeDto(Constants.DataTypes.LabelTime, Constants.PropertyEditors.Aliases.Label, "Date", "{\"umbracoDataValueType\":\"TIME\"}");
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -36, EditorAlias = Constants.PropertyEditors.Aliases.DateTime, DbType = "Date" });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = Constants.DataTypes.DateTime, EditorAlias = Constants.PropertyEditors.Aliases.DateTime, DbType = "Date" });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -37, EditorAlias = Constants.PropertyEditors.Aliases.ColorPicker, DbType = "Nvarchar" });
|
||||
InsertDataTypeDto(Constants.DataTypes.DropDownSingle, Constants.PropertyEditors.Aliases.DropDownListFlexible, "Nvarchar", "{\"multiple\":false}");
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -40, EditorAlias = Constants.PropertyEditors.Aliases.RadioButtonList, DbType = "Nvarchar" });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -41, EditorAlias = "Umbraco.DateTime", DbType = "Date", Configuration = "{\"format\":\"YYYY-MM-DD\"}" });
|
||||
InsertDataTypeDto(Constants.DataTypes.DropDownMultiple, Constants.PropertyEditors.Aliases.DropDownListFlexible, "Nvarchar", "{\"multiple\":true}");
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -43, EditorAlias = Constants.PropertyEditors.Aliases.CheckBoxList, DbType = "Nvarchar" });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = 1041, EditorAlias = Constants.PropertyEditors.Aliases.Tags, DbType = "Ntext",
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = Constants.DataTypes.Tags, EditorAlias = Constants.PropertyEditors.Aliases.Tags, DbType = "Ntext",
|
||||
Configuration = "{\"group\":\"default\", \"storageType\":\"Json\"}"
|
||||
});
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = 1043, EditorAlias = Constants.PropertyEditors.Aliases.ImageCropper, DbType = "Ntext" });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = Constants.DataTypes.ImageCropper, EditorAlias = Constants.PropertyEditors.Aliases.ImageCropper, DbType = "Ntext" });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = Constants.DataTypes.DefaultContentListView, EditorAlias = Constants.PropertyEditors.Aliases.ListView, DbType = "Nvarchar",
|
||||
Configuration = "{\"pageSize\":100, \"orderBy\":\"updateDate\", \"orderDirection\":\"desc\", \"layouts\":" + layouts + ", \"includeProperties\":[{\"alias\":\"updateDate\",\"header\":\"Last edited\",\"isSystem\":1},{\"alias\":\"owner\",\"header\":\"Updated by\",\"isSystem\":1}]}" });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = Constants.DataTypes.DefaultMediaListView, EditorAlias = Constants.PropertyEditors.Aliases.ListView, DbType = "Nvarchar",
|
||||
|
||||
@@ -74,6 +74,11 @@ namespace Umbraco.Core.Migrations.Upgrade
|
||||
throw new InvalidOperationException($"Version {currentVersion} cannot be migrated to {UmbracoVersion.SemanticVersion}."
|
||||
+ $" Please upgrade first to at least {minVersion}.");
|
||||
|
||||
// Force versions between 7.14.*-7.15.* into into 7.14 initial state. Because there is no db-changes,
|
||||
// and we don't want users to workaround my putting in version 7.14.0 them self.
|
||||
if (minVersion <= currentVersion && currentVersion < new SemVersion(7, 16))
|
||||
return GetInitState(minVersion);
|
||||
|
||||
// initial state is eg "{init-7.14.0}"
|
||||
return GetInitState(currentVersion);
|
||||
}
|
||||
|
||||
@@ -19,8 +19,8 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
var sqlDataTypes = Sql()
|
||||
.Select<DataTypeDto>()
|
||||
.From<DataTypeDto>()
|
||||
.Where<DataTypeDto>(x => x.EditorAlias == "Umbraco.RelatedLinks"
|
||||
|| x.EditorAlias == "Umbraco.RelatedLinks2");
|
||||
.Where<DataTypeDto>(x => x.EditorAlias == Constants.PropertyEditors.Legacy.Aliases.RelatedLinks
|
||||
|| x.EditorAlias == Constants.PropertyEditors.Legacy.Aliases.RelatedLinks2);
|
||||
|
||||
var dataTypes = Database.Fetch<DataTypeDto>(sqlDataTypes);
|
||||
var dataTypeIds = dataTypes.Select(x => x.NodeId).ToList();
|
||||
@@ -50,10 +50,10 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
var properties = Database.Fetch<PropertyDataDto>(sqlPropertyData);
|
||||
|
||||
// Create a Multi URL Picker datatype for the converted RelatedLinks data
|
||||
|
||||
|
||||
foreach (var property in properties)
|
||||
{
|
||||
var value = property.Value.ToString();
|
||||
var value = property.Value?.ToString();
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
continue;
|
||||
|
||||
@@ -89,7 +89,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
Name = relatedLink.Caption,
|
||||
Target = relatedLink.NewWindow ? "_blank" : null,
|
||||
Udi = udi,
|
||||
// Should only have a URL if it's an external link otherwise it wil be a UDI
|
||||
// Should only have a URL if it's an external link otherwise it wil be a UDI
|
||||
Url = relatedLink.IsInternal == false ? relatedLink.Link : null
|
||||
};
|
||||
|
||||
@@ -103,7 +103,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
Database.Update(property);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using Umbraco.Core.Composing;
|
||||
@@ -18,6 +19,18 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
private readonly PropertyEditorCollection _propertyEditors;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
private static readonly ISet<string> LegacyAliases = new HashSet<string>()
|
||||
{
|
||||
Constants.PropertyEditors.Legacy.Aliases.Date,
|
||||
Constants.PropertyEditors.Legacy.Aliases.Textbox,
|
||||
Constants.PropertyEditors.Legacy.Aliases.ContentPicker2,
|
||||
Constants.PropertyEditors.Legacy.Aliases.MediaPicker2,
|
||||
Constants.PropertyEditors.Legacy.Aliases.MemberPicker2,
|
||||
Constants.PropertyEditors.Legacy.Aliases.RelatedLinks2,
|
||||
Constants.PropertyEditors.Legacy.Aliases.TextboxMultiple,
|
||||
Constants.PropertyEditors.Legacy.Aliases.MultiNodeTreePicker2,
|
||||
};
|
||||
|
||||
public DataTypeMigration(IMigrationContext context, PreValueMigratorCollection preValueMigrators, PropertyEditorCollection propertyEditors, ILogger logger)
|
||||
: base(context)
|
||||
{
|
||||
@@ -70,16 +83,23 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
var newAlias = migrator.GetNewAlias(dataType.EditorAlias);
|
||||
if (newAlias == null)
|
||||
{
|
||||
_logger.Warn<DataTypeMigration>("Skipping validation of configuration for data type {NodeId} : {EditorAlias}."
|
||||
+ " Please ensure that the configuration is valid. The site may fail to start and / or load data types and run.",
|
||||
dataType.NodeId, dataType.EditorAlias);
|
||||
if (!LegacyAliases.Contains(dataType.EditorAlias))
|
||||
{
|
||||
_logger.Warn<DataTypeMigration>(
|
||||
"Skipping validation of configuration for data type {NodeId} : {EditorAlias}."
|
||||
+ " Please ensure that the configuration is valid. The site may fail to start and / or load data types and run.",
|
||||
dataType.NodeId, dataType.EditorAlias);
|
||||
}
|
||||
}
|
||||
else if (!_propertyEditors.TryGet(newAlias, out var propertyEditor))
|
||||
{
|
||||
_logger.Warn<DataTypeMigration>("Skipping validation of configuration for data type {NodeId} : {NewEditorAlias} (was: {EditorAlias})"
|
||||
+ " because no property editor with that alias was found."
|
||||
+ " Please ensure that the configuration is valid. The site may fail to start and / or load data types and run.",
|
||||
dataType.NodeId, newAlias, dataType.EditorAlias);
|
||||
if (!LegacyAliases.Contains(newAlias))
|
||||
{
|
||||
_logger.Warn<DataTypeMigration>("Skipping validation of configuration for data type {NodeId} : {NewEditorAlias} (was: {EditorAlias})"
|
||||
+ " because no property editor with that alias was found."
|
||||
+ " Please ensure that the configuration is valid. The site may fail to start and / or load data types and run.",
|
||||
dataType.NodeId, newAlias, dataType.EditorAlias);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
class ContentPickerPreValueMigrator : DefaultPreValueMigrator
|
||||
{
|
||||
public override bool CanMigrate(string editorAlias)
|
||||
=> editorAlias == "Umbraco.ContentPicker2";
|
||||
=> editorAlias == Constants.PropertyEditors.Legacy.Aliases.ContentPicker2;
|
||||
|
||||
public override string GetNewAlias(string editorAlias)
|
||||
=> null;
|
||||
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0.DataTypes
|
||||
{
|
||||
class DropDownFlexiblePreValueMigrator : IPreValueMigrator
|
||||
{
|
||||
public bool CanMigrate(string editorAlias)
|
||||
=> editorAlias == "Umbraco.DropDown.Flexible";
|
||||
|
||||
public virtual string GetNewAlias(string editorAlias)
|
||||
=> null;
|
||||
|
||||
public object GetConfiguration(int dataTypeId, string editorAlias, Dictionary<string, PreValueDto> preValues)
|
||||
{
|
||||
var config = new DropDownFlexibleConfiguration();
|
||||
foreach (var preValue in preValues.Values)
|
||||
{
|
||||
if (preValue.Alias == "multiple")
|
||||
{
|
||||
config.Multiple = (preValue.Value == "1");
|
||||
}
|
||||
else
|
||||
{
|
||||
config.Items.Add(new ValueListConfiguration.ValueListItem { Id = preValue.Id, Value = preValue.Value });
|
||||
}
|
||||
}
|
||||
return config;
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -6,15 +6,15 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0.DataTypes
|
||||
{
|
||||
private readonly string[] _editors =
|
||||
{
|
||||
"Umbraco.MediaPicker2",
|
||||
"Umbraco.MediaPicker"
|
||||
Constants.PropertyEditors.Legacy.Aliases.MediaPicker2,
|
||||
Constants.PropertyEditors.Aliases.MediaPicker
|
||||
};
|
||||
|
||||
public override bool CanMigrate(string editorAlias)
|
||||
=> _editors.Contains(editorAlias);
|
||||
|
||||
public override string GetNewAlias(string editorAlias)
|
||||
=> "Umbraco.MediaPicker";
|
||||
=> Constants.PropertyEditors.Aliases.MediaPicker;
|
||||
|
||||
// you wish - but MediaPickerConfiguration lives in Umbraco.Web
|
||||
/*
|
||||
|
||||
@@ -2,24 +2,25 @@
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0.DataTypes
|
||||
{
|
||||
[RuntimeLevel(MinLevel = RuntimeLevel.Upgrade, MaxLevel = RuntimeLevel.Upgrade)] // only on upgrades
|
||||
public class PreValueMigratorComposer : ICoreComposer
|
||||
[RuntimeLevel(MinLevel = RuntimeLevel.Upgrade, MaxLevel = RuntimeLevel.Upgrade)] // only on upgrades
|
||||
public class PreValueMigratorComposer : ICoreComposer
|
||||
{
|
||||
public void Compose(Composition composition)
|
||||
{
|
||||
public void Compose(Composition composition)
|
||||
{
|
||||
// do NOT add DefaultPreValueMigrator to this list!
|
||||
// it will be automatically used if nothing matches
|
||||
// do NOT add DefaultPreValueMigrator to this list!
|
||||
// it will be automatically used if nothing matches
|
||||
|
||||
composition.WithCollectionBuilder<PreValueMigratorCollectionBuilder>()
|
||||
.Append<RenamingPreValueMigrator>()
|
||||
.Append<RichTextPreValueMigrator>()
|
||||
.Append<UmbracoSliderPreValueMigrator>()
|
||||
.Append<MediaPickerPreValueMigrator>()
|
||||
.Append<ContentPickerPreValueMigrator>()
|
||||
.Append<NestedContentPreValueMigrator>()
|
||||
.Append<DecimalPreValueMigrator>()
|
||||
.Append<ListViewPreValueMigrator>()
|
||||
.Append<ValueListPreValueMigrator>();
|
||||
}
|
||||
composition.WithCollectionBuilder<PreValueMigratorCollectionBuilder>()
|
||||
.Append<RenamingPreValueMigrator>()
|
||||
.Append<RichTextPreValueMigrator>()
|
||||
.Append<UmbracoSliderPreValueMigrator>()
|
||||
.Append<MediaPickerPreValueMigrator>()
|
||||
.Append<ContentPickerPreValueMigrator>()
|
||||
.Append<NestedContentPreValueMigrator>()
|
||||
.Append<DecimalPreValueMigrator>()
|
||||
.Append<ListViewPreValueMigrator>()
|
||||
.Append<DropDownFlexiblePreValueMigrator>()
|
||||
.Append<ValueListPreValueMigrator>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Exceptions;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0.DataTypes
|
||||
{
|
||||
@@ -20,7 +21,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0.DataTypes
|
||||
case "Umbraco.NoEdit":
|
||||
return Constants.PropertyEditors.Aliases.Label;
|
||||
default:
|
||||
throw new Exception("panic");
|
||||
throw new PanicException($"The alias {editorAlias} is not supported");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0.DataTypes
|
||||
private readonly string[] _editors =
|
||||
{
|
||||
"Umbraco.RadioButtonList",
|
||||
"Umbraco.CheckBoxList",
|
||||
"Umbraco.DropDown",
|
||||
"Umbraco.DropdownlistPublishingKeys",
|
||||
"Umbraco.DropDownMultiple",
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
var dataTypes = GetDataTypes("Umbraco.Date");
|
||||
var dataTypes = GetDataTypes(Constants.PropertyEditors.Legacy.Aliases.Date);
|
||||
|
||||
foreach (var dataType in dataTypes)
|
||||
{
|
||||
@@ -25,6 +25,14 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
{
|
||||
config = (DateTimeConfiguration) new CustomDateTimeConfigurationEditor().FromDatabase(
|
||||
dataType.Configuration);
|
||||
|
||||
// If the Umbraco.Date type is the default from V7 and it has never been updated, then the
|
||||
// configuration is empty, and the format stuff is handled by in JS by moment.js. - We can't do that
|
||||
// after the migration, so we force the format to the default from V7.
|
||||
if (string.IsNullOrEmpty(dataType.Configuration))
|
||||
{
|
||||
config.Format = "YYYY-MM-DD";
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -12,12 +12,12 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
RenameDataType(Constants.PropertyEditors.Aliases.ContentPicker + "2", Constants.PropertyEditors.Aliases.ContentPicker);
|
||||
RenameDataType(Constants.PropertyEditors.Aliases.MediaPicker + "2", Constants.PropertyEditors.Aliases.MediaPicker);
|
||||
RenameDataType(Constants.PropertyEditors.Aliases.MemberPicker + "2", Constants.PropertyEditors.Aliases.MemberPicker);
|
||||
RenameDataType(Constants.PropertyEditors.Aliases.MultiNodeTreePicker + "2", Constants.PropertyEditors.Aliases.MultiNodeTreePicker);
|
||||
RenameDataType("Umbraco.TextboxMultiple", Constants.PropertyEditors.Aliases.TextArea, false);
|
||||
RenameDataType("Umbraco.Textbox", Constants.PropertyEditors.Aliases.TextBox, false);
|
||||
RenameDataType(Constants.PropertyEditors.Legacy.Aliases.ContentPicker2, Constants.PropertyEditors.Aliases.ContentPicker);
|
||||
RenameDataType(Constants.PropertyEditors.Legacy.Aliases.MediaPicker2, Constants.PropertyEditors.Aliases.MediaPicker);
|
||||
RenameDataType(Constants.PropertyEditors.Legacy.Aliases.MemberPicker2, Constants.PropertyEditors.Aliases.MemberPicker);
|
||||
RenameDataType(Constants.PropertyEditors.Legacy.Aliases.MultiNodeTreePicker2, Constants.PropertyEditors.Aliases.MultiNodeTreePicker);
|
||||
RenameDataType(Constants.PropertyEditors.Legacy.Aliases.TextboxMultiple, Constants.PropertyEditors.Aliases.TextArea, false);
|
||||
RenameDataType(Constants.PropertyEditors.Legacy.Aliases.Textbox, Constants.PropertyEditors.Aliases.TextBox, false);
|
||||
}
|
||||
|
||||
private void RenameDataType(string fromAlias, string toAlias, bool checkCollision = true)
|
||||
@@ -30,7 +30,20 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
.Where<DataTypeDto>(x => x.EditorAlias == toAlias));
|
||||
|
||||
if (oldCount > 0)
|
||||
throw new InvalidOperationException($"Cannot rename datatype alias \"{fromAlias}\" to \"{toAlias}\" because the target alias is already used.");
|
||||
{
|
||||
// If we throw it means that the upgrade will exit and cannot continue.
|
||||
// This will occur if a v7 site has the old "Obsolete" property editors that are already named with the `toAlias` name.
|
||||
// TODO: We should have an additional upgrade step when going from 7 -> 8 like we did with 6 -> 7 that shows a compatibility report,
|
||||
// this would include this check and then we can provide users with information on what they should do (i.e. before upgrading to v8 they will
|
||||
// need to migrate these old obsolete editors to non-obsolete editors)
|
||||
|
||||
throw new InvalidOperationException(
|
||||
$"Cannot rename datatype alias \"{fromAlias}\" to \"{toAlias}\" because the target alias is already used." +
|
||||
$"This is generally because when upgrading from a v7 to v8 site, the v7 site contains Data Types that reference old and already Obsolete " +
|
||||
$"Property Editors. Before upgrading to v8, any Data Types using property editors that are named with the prefix '(Obsolete)' must be migrated " +
|
||||
$"to the non-obsolete v7 property editors of the same type.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Database.Execute(Sql()
|
||||
|
||||
@@ -14,11 +14,18 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
public override void Migrate()
|
||||
{
|
||||
//Get anything currently scheduled
|
||||
var scheduleSql = new Sql()
|
||||
.Select("nodeId", "releaseDate", "expireDate")
|
||||
var releaseSql = new Sql()
|
||||
.Select("nodeId", "releaseDate")
|
||||
.From("umbracoDocument")
|
||||
.Where("releaseDate IS NOT NULL OR expireDate IS NOT NULL");
|
||||
var schedules = Database.Dictionary<int, (DateTime? releaseDate, DateTime? expireDate)> (scheduleSql);
|
||||
.Where("releaseDate IS NOT NULL");
|
||||
var releases = Database.Dictionary<int, DateTime> (releaseSql);
|
||||
|
||||
var expireSql = new Sql()
|
||||
.Select("nodeId", "expireDate")
|
||||
.From("umbracoDocument")
|
||||
.Where("expireDate IS NOT NULL");
|
||||
var expires = Database.Dictionary<int, DateTime>(expireSql);
|
||||
|
||||
|
||||
//drop old cols
|
||||
Delete.Column("releaseDate").FromTable("umbracoDocument").Do();
|
||||
@@ -27,20 +34,25 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
Create.Table<ContentScheduleDto>(true).Do();
|
||||
|
||||
//migrate the schedule
|
||||
foreach(var s in schedules)
|
||||
foreach(var s in releases)
|
||||
{
|
||||
var date = s.Value.releaseDate;
|
||||
var date = s.Value;
|
||||
var action = ContentScheduleAction.Release.ToString();
|
||||
if (!date.HasValue)
|
||||
{
|
||||
date = s.Value.expireDate;
|
||||
action = ContentScheduleAction.Expire.ToString();
|
||||
}
|
||||
|
||||
Insert.IntoTable(ContentScheduleDto.TableName)
|
||||
.Row(new { nodeId = s.Key, date = date.Value, action = action })
|
||||
.Row(new { id = Guid.NewGuid(), nodeId = s.Key, date = date, action = action })
|
||||
.Do();
|
||||
}
|
||||
|
||||
foreach (var s in expires)
|
||||
{
|
||||
var date = s.Value;
|
||||
var action = ContentScheduleAction.Expire.ToString();
|
||||
|
||||
Insert.IntoTable(ContentScheduleDto.TableName)
|
||||
.Row(new { id = Guid.NewGuid(), nodeId = s.Key, date = date, action = action })
|
||||
.Do();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+31
-8
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using Newtonsoft.Json;
|
||||
@@ -36,6 +37,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_1_0
|
||||
|
||||
var properties = Database.Fetch<PropertyDataDto>(sqlPropertyData);
|
||||
|
||||
var exceptions = new List<Exception>();
|
||||
foreach (var property in properties)
|
||||
{
|
||||
var value = property.TextValue;
|
||||
@@ -43,19 +45,34 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_1_0
|
||||
|
||||
if (property.PropertyTypeDto.DataTypeDto.EditorAlias == Constants.PropertyEditors.Aliases.Grid)
|
||||
{
|
||||
var obj = JsonConvert.DeserializeObject<JObject>(value);
|
||||
var allControls = obj.SelectTokens("$.sections..rows..areas..controls");
|
||||
|
||||
foreach (var control in allControls.SelectMany(c => c))
|
||||
try
|
||||
{
|
||||
var controlValue = control["value"];
|
||||
if (controlValue.Type == JTokenType.String)
|
||||
var obj = JsonConvert.DeserializeObject<JObject>(value);
|
||||
var allControls = obj.SelectTokens("$.sections..rows..areas..controls");
|
||||
|
||||
foreach (var control in allControls.SelectMany(c => c))
|
||||
{
|
||||
control["value"] = UpdateMediaUrls(mediaLinkPattern, controlValue.Value<string>());
|
||||
var controlValue = control["value"];
|
||||
if (controlValue.Type == JTokenType.String)
|
||||
{
|
||||
control["value"] = UpdateMediaUrls(mediaLinkPattern, controlValue.Value<string>());
|
||||
}
|
||||
}
|
||||
|
||||
property.TextValue = JsonConvert.SerializeObject(obj);
|
||||
}
|
||||
catch (JsonException e)
|
||||
{
|
||||
exceptions.Add(new InvalidOperationException(
|
||||
"Cannot deserialize the value as json. This can be because the property editor " +
|
||||
"type is changed from another type into a grid. Old versions of the value in this " +
|
||||
"property can have the structure from the old property editor type. This needs to be " +
|
||||
"changed manually before updating the database.\n" +
|
||||
$"Property info: Id = {property.Id}, LanguageId = {property.LanguageId}, VersionId = {property.VersionId}, Value = {property.Value}"
|
||||
, e));
|
||||
continue;
|
||||
}
|
||||
|
||||
property.TextValue = JsonConvert.SerializeObject(obj);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -65,6 +82,12 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_1_0
|
||||
Database.Update(property);
|
||||
}
|
||||
|
||||
|
||||
if (exceptions.Any())
|
||||
{
|
||||
throw new AggregateException("One or more errors related to unexpected data in grid values occurred.", exceptions);
|
||||
}
|
||||
|
||||
Context.AddPostMigration<RebuildPublishedSnapshot>();
|
||||
}
|
||||
|
||||
|
||||
@@ -222,7 +222,13 @@ namespace Umbraco.Core.Models
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void UnpublishCulture(this IContent content, string culture = "*")
|
||||
/// <summary>
|
||||
/// Returns false if the culture is already unpublished
|
||||
/// </summary>
|
||||
/// <param name="content"></param>
|
||||
/// <param name="culture"></param>
|
||||
/// <returns></returns>
|
||||
public static bool UnpublishCulture(this IContent content, string culture = "*")
|
||||
{
|
||||
culture = culture.NullOrWhiteSpaceAsNull();
|
||||
|
||||
@@ -230,16 +236,31 @@ namespace Umbraco.Core.Models
|
||||
if (!content.ContentType.SupportsPropertyVariation(culture, "*", true))
|
||||
throw new NotSupportedException($"Culture \"{culture}\" is not supported by content type \"{content.ContentType.Alias}\" with variation \"{content.ContentType.Variations}\".");
|
||||
|
||||
if (culture == "*") // all cultures
|
||||
|
||||
var keepProcessing = true;
|
||||
|
||||
if (culture == "*")
|
||||
{
|
||||
// all cultures
|
||||
content.ClearPublishInfos();
|
||||
else // one single culture
|
||||
content.ClearPublishInfo(culture);
|
||||
}
|
||||
else
|
||||
{
|
||||
// one single culture
|
||||
keepProcessing = content.ClearPublishInfo(culture);
|
||||
}
|
||||
|
||||
|
||||
// property.PublishValues only publishes what is valid, variation-wise
|
||||
foreach (var property in content.Properties)
|
||||
property.UnpublishValues(culture);
|
||||
if (keepProcessing)
|
||||
{
|
||||
// property.PublishValues only publishes what is valid, variation-wise
|
||||
foreach (var property in content.Properties)
|
||||
property.UnpublishValues(culture);
|
||||
|
||||
content.PublishedState = PublishedState.Publishing;
|
||||
content.PublishedState = PublishedState.Publishing;
|
||||
}
|
||||
|
||||
return keepProcessing;
|
||||
}
|
||||
|
||||
public static void ClearPublishInfos(this IContent content)
|
||||
@@ -247,15 +268,24 @@ namespace Umbraco.Core.Models
|
||||
content.PublishCultureInfos = null;
|
||||
}
|
||||
|
||||
public static void ClearPublishInfo(this IContent content, string culture)
|
||||
/// <summary>
|
||||
/// Returns false if the culture is already unpublished
|
||||
/// </summary>
|
||||
/// <param name="content"></param>
|
||||
/// <param name="culture"></param>
|
||||
/// <returns></returns>
|
||||
public static bool ClearPublishInfo(this IContent content, string culture)
|
||||
{
|
||||
if (culture.IsNullOrWhiteSpace())
|
||||
throw new ArgumentNullOrEmptyException(nameof(culture));
|
||||
|
||||
content.PublishCultureInfos.Remove(culture);
|
||||
|
||||
// set the culture to be dirty - it's been modified
|
||||
content.TouchCulture(culture);
|
||||
var removed = content.PublishCultureInfos.Remove(culture);
|
||||
if (removed)
|
||||
{
|
||||
// set the culture to be dirty - it's been modified
|
||||
content.TouchCulture(culture);
|
||||
}
|
||||
return removed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -35,5 +35,58 @@ namespace Umbraco.Core.Models
|
||||
|
||||
throw new InvalidCastException($"Cannot cast dataType configuration, of type {configuration.GetType().Name}, to {typeof(T).Name}.");
|
||||
}
|
||||
|
||||
private static readonly ISet<Guid> IdsOfBuildInDataTypes = new HashSet<Guid>()
|
||||
{
|
||||
Constants.DataTypes.Guids.ContentPickerGuid,
|
||||
Constants.DataTypes.Guids.MemberPickerGuid,
|
||||
Constants.DataTypes.Guids.MediaPickerGuid,
|
||||
Constants.DataTypes.Guids.MultipleMediaPickerGuid,
|
||||
Constants.DataTypes.Guids.RelatedLinksGuid,
|
||||
Constants.DataTypes.Guids.MemberGuid,
|
||||
Constants.DataTypes.Guids.ImageCropperGuid,
|
||||
Constants.DataTypes.Guids.TagsGuid,
|
||||
Constants.DataTypes.Guids.ListViewContentGuid,
|
||||
Constants.DataTypes.Guids.ListViewMediaGuid,
|
||||
Constants.DataTypes.Guids.ListViewMembersGuid,
|
||||
Constants.DataTypes.Guids.DatePickerWithTimeGuid,
|
||||
Constants.DataTypes.Guids.ApprovedColorGuid,
|
||||
Constants.DataTypes.Guids.DropdownMultipleGuid,
|
||||
Constants.DataTypes.Guids.RadioboxGuid,
|
||||
Constants.DataTypes.Guids.DatePickerGuid,
|
||||
Constants.DataTypes.Guids.DropdownGuid,
|
||||
Constants.DataTypes.Guids.CheckboxListGuid,
|
||||
Constants.DataTypes.Guids.CheckboxGuid,
|
||||
Constants.DataTypes.Guids.NumericGuid,
|
||||
Constants.DataTypes.Guids.RichtextEditorGuid,
|
||||
Constants.DataTypes.Guids.TextstringGuid,
|
||||
Constants.DataTypes.Guids.TextareaGuid,
|
||||
Constants.DataTypes.Guids.UploadGuid,
|
||||
Constants.DataTypes.Guids.LabelStringGuid,
|
||||
Constants.DataTypes.Guids.LabelDecimalGuid,
|
||||
Constants.DataTypes.Guids.LabelDateTimeGuid,
|
||||
Constants.DataTypes.Guids.LabelBigIntGuid,
|
||||
Constants.DataTypes.Guids.LabelTimeGuid,
|
||||
Constants.DataTypes.Guids.LabelDateTimeGuid,
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if this date type is build-in/default.
|
||||
/// </summary>
|
||||
/// <param name="dataType">The data type definition.</param>
|
||||
/// <returns></returns>
|
||||
internal static bool IsBuildInDataType(this IDataType dataType)
|
||||
{
|
||||
return IsBuildInDataType(dataType.Key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if this date type is build-in/default.
|
||||
/// </summary>
|
||||
internal static bool IsBuildInDataType(Guid key)
|
||||
{
|
||||
return IdsOfBuildInDataTypes.Contains(key);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Linq;
|
||||
|
||||
namespace Umbraco.Core.Models.Entities
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Implements <see cref="IDocumentEntitySlim"/>.
|
||||
/// </summary>
|
||||
|
||||
@@ -81,37 +81,7 @@ namespace Umbraco.Core.Models.Entities
|
||||
_key = Guid.Empty;
|
||||
_hasIdentity = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the entity when it is being saved for the first time.
|
||||
/// </summary>
|
||||
internal virtual void AddingEntity()
|
||||
{
|
||||
var now = DateTime.Now;
|
||||
|
||||
// set the create and update dates, if not already set
|
||||
if (IsPropertyDirty("CreateDate") == false || _createDate == default)
|
||||
CreateDate = now;
|
||||
if (IsPropertyDirty("UpdateDate") == false || _updateDate == default)
|
||||
UpdateDate = now;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the entity when it is being saved.
|
||||
/// </summary>
|
||||
internal virtual void UpdatingEntity()
|
||||
{
|
||||
var now = DateTime.Now;
|
||||
|
||||
// just in case
|
||||
if (_createDate == default)
|
||||
CreateDate = now;
|
||||
|
||||
// set the update date if not already set
|
||||
if (IsPropertyDirty("UpdateDate") == false || _updateDate == default)
|
||||
UpdateDate = now;
|
||||
}
|
||||
|
||||
|
||||
public virtual bool Equals(EntityBase other)
|
||||
{
|
||||
return other != null && (ReferenceEquals(this, other) || SameIdentityAs(other));
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.Models.Entities
|
||||
{
|
||||
internal static class EntityExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Updates the entity when it is being saved.
|
||||
/// </summary>
|
||||
internal static void UpdatingEntity(this IEntity entity)
|
||||
{
|
||||
var now = DateTime.Now;
|
||||
|
||||
// just in case
|
||||
if (entity.CreateDate == default)
|
||||
{
|
||||
entity.CreateDate = now;
|
||||
}
|
||||
|
||||
// set the update date if not already set
|
||||
if (entity.UpdateDate == default || (entity is ICanBeDirty canBeDirty && canBeDirty.IsPropertyDirty("UpdateDate") == false))
|
||||
{
|
||||
entity.UpdateDate = now;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the entity when it is being saved for the first time.
|
||||
/// </summary>
|
||||
internal static void AddingEntity(this IEntity entity)
|
||||
{
|
||||
var now = DateTime.Now;
|
||||
var canBeDirty = entity as ICanBeDirty;
|
||||
|
||||
// set the create and update dates, if not already set
|
||||
if (entity.CreateDate == default || canBeDirty?.IsPropertyDirty("CreateDate") == false)
|
||||
{
|
||||
entity.CreateDate = now;
|
||||
}
|
||||
if (entity.UpdateDate == default || canBeDirty?.IsPropertyDirty("UpdateDate") == false)
|
||||
{
|
||||
entity.UpdateDate = now;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -111,52 +111,6 @@ namespace Umbraco.Core.Models.Entities
|
||||
public virtual bool IsContainer { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Represents a lightweight property.
|
||||
/// </summary>
|
||||
public class PropertySlim
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PropertySlim"/> class.
|
||||
/// </summary>
|
||||
public PropertySlim(string editorAlias, object value)
|
||||
{
|
||||
PropertyEditorAlias = editorAlias;
|
||||
Value = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the property editor alias.
|
||||
/// </summary>
|
||||
public string PropertyEditorAlias { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the property value.
|
||||
/// </summary>
|
||||
public object Value { get; }
|
||||
|
||||
protected bool Equals(PropertySlim other)
|
||||
{
|
||||
return PropertyEditorAlias.Equals(other.PropertyEditorAlias) && Equals(Value, other.Value);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj)) return false;
|
||||
if (ReferenceEquals(this, obj)) return true;
|
||||
if (obj.GetType() != GetType()) return false;
|
||||
return Equals((PropertySlim) obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
return (PropertyEditorAlias.GetHashCode() * 397) ^ (Value != null ? Value.GetHashCode() : 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region IDeepCloneable
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Umbraco.Core.Models.Entities
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Represents a lightweight document entity, managed by the entity service.
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
namespace Umbraco.Core.Models.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a lightweight media entity, managed by the entity service.
|
||||
/// </summary>
|
||||
public interface IMediaEntitySlim : IContentEntitySlim
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// The media file's path/url
|
||||
/// </summary>
|
||||
string MediaPath { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace Umbraco.Core.Models.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements <see cref="IMediaEntitySlim"/>.
|
||||
/// </summary>
|
||||
public class MediaEntitySlim : ContentEntitySlim, IMediaEntitySlim
|
||||
{
|
||||
public string MediaPath { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -101,7 +101,7 @@ namespace Umbraco.Core.Models
|
||||
PropertyGroupCollection PropertyGroups { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets all local property types belonging to a group, across all local property groups.
|
||||
/// Gets all local property types all local property groups or ungrouped.
|
||||
/// </summary>
|
||||
IEnumerable<PropertyType> PropertyTypes { get; }
|
||||
|
||||
|
||||
@@ -478,19 +478,6 @@ namespace Umbraco.Core.Models
|
||||
set => SetPropertyValueAndDetectChanges(value, ref _providerUserKey, nameof(ProviderUserKey));
|
||||
}
|
||||
|
||||
|
||||
/// <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 (ProviderUserKey == null)
|
||||
ProviderUserKey = Key;
|
||||
}
|
||||
|
||||
/* Internal experiment - only used for mapping queries.
|
||||
* Adding these to have first level properties instead of the Properties collection.
|
||||
*/
|
||||
|
||||
@@ -21,6 +21,7 @@ namespace Umbraco.Core.Models
|
||||
private string _alias;
|
||||
private string _description;
|
||||
private int _dataTypeId;
|
||||
private Guid _dataTypeKey;
|
||||
private Lazy<int> _propertyGroupId;
|
||||
private string _propertyEditorAlias;
|
||||
private ValueStorageType _valueStorageType;
|
||||
@@ -139,6 +140,13 @@ namespace Umbraco.Core.Models
|
||||
set => SetPropertyValueAndDetectChanges(value, ref _dataTypeId, nameof(DataTypeId));
|
||||
}
|
||||
|
||||
[DataMember]
|
||||
public Guid DataTypeKey
|
||||
{
|
||||
get => _dataTypeKey;
|
||||
set => SetPropertyValueAndDetectChanges(value, ref _dataTypeKey, nameof(DataTypeKey));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the alias of the property editor for this property type.
|
||||
/// </summary>
|
||||
|
||||
@@ -13,6 +13,10 @@
|
||||
/// <summary>
|
||||
/// Refreshes the factory.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>This will typically re-compiled models/classes into a new DLL that are used to populate the cache.</para>
|
||||
/// <para>This is called prior to refreshing the cache.</para>
|
||||
/// </remarks>
|
||||
void Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
|
||||
namespace Umbraco.Core.Models.PublishedContent
|
||||
{
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Represents a published content item.
|
||||
@@ -27,21 +26,13 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
int Id { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the content item.
|
||||
/// Gets the name of the content item for the current culture.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>The value of this property is contextual. When the content type is multi-lingual,
|
||||
/// this is the name for the 'current' culture. Otherwise, it is the invariant name.</para>
|
||||
/// </remarks>
|
||||
string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the url segment of the content item.
|
||||
/// Gets the url segment of the content item for the current culture.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>The value of this property is contextual. When the content type is multi-lingual,
|
||||
/// this is the name for the 'current' culture. Otherwise, it is the invariant url segment.</para>
|
||||
/// </remarks>
|
||||
string UrlSegment { get; }
|
||||
|
||||
/// <summary>
|
||||
@@ -94,43 +85,28 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>For published content items, this is also the date the item was published.</para>
|
||||
/// <para>This date is always global to the content item, see GetCulture().Date for the
|
||||
/// <para>This date is always global to the content item, see CultureDate() for the
|
||||
/// date each culture was published.</para>
|
||||
/// </remarks>
|
||||
DateTime UpdateDate { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the url of the content item.
|
||||
/// Gets the url of the content item for the current culture.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>The value of this property is contextual. It depends on the 'current' request uri,
|
||||
/// if any. In addition, when the content type is multi-lingual, this is the url for the
|
||||
/// 'current' culture. Otherwise, it is the invariant url.</para>
|
||||
/// if any.</para>
|
||||
/// </remarks>
|
||||
string Url { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the url of the content item.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>The value of this property is contextual. It depends on the 'current' request uri,
|
||||
/// if any. In addition, when the content type is multi-lingual, this is the url for the
|
||||
/// specified culture. Otherwise, it is the invariant url.</para>
|
||||
/// </remarks>
|
||||
string GetUrl(string culture = null);
|
||||
|
||||
/// <summary>
|
||||
/// Gets culture infos for a culture.
|
||||
/// </summary>
|
||||
PublishedCultureInfo GetCulture(string culture = null);
|
||||
|
||||
/// <summary>
|
||||
/// Gets culture infos.
|
||||
/// Gets available culture infos.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>Contains only those culture that are available. For a published content, these are
|
||||
/// the cultures that are published. For a draft content, those that are 'available' ie
|
||||
/// have a non-empty content name.</para>
|
||||
/// <para>Does not contain the invariant culture.</para> // fixme?
|
||||
/// </remarks>
|
||||
IReadOnlyDictionary<string, PublishedCultureInfo> Cultures { get; }
|
||||
|
||||
@@ -178,11 +154,15 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
IPublishedContent Parent { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the children of the content item.
|
||||
/// Gets the children of the content item that are available for the current culture.
|
||||
/// </summary>
|
||||
/// <remarks>Children are sorted by their sortOrder.</remarks>
|
||||
IEnumerable<IPublishedContent> Children { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets all the children of the content item, regardless of whether they are available for the current culture.
|
||||
/// </summary>
|
||||
IEnumerable<IPublishedContent> ChildrenForAllCultures { get; }
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Umbraco.Core.Models.PublishedContent
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an <see cref="IPublishedElement"/> type.
|
||||
/// </summary>
|
||||
/// <remarks>Instances implementing the <see cref="IPublishedContentType"/> interface should be
|
||||
/// immutable, ie if the content type changes, then a new instance needs to be created.</remarks>
|
||||
public interface IPublishedContentType
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the content type identifier.
|
||||
/// </summary>
|
||||
int Id { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the content type alias.
|
||||
/// </summary>
|
||||
string Alias { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the content item type.
|
||||
/// </summary>
|
||||
PublishedItemType ItemType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the aliases of the content types participating in the composition.
|
||||
/// </summary>
|
||||
HashSet<string> CompositionAliases { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the content variations of the content type.
|
||||
/// </summary>
|
||||
ContentVariation Variations { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this content type is for an element.
|
||||
/// </summary>
|
||||
bool IsElement { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the content type properties.
|
||||
/// </summary>
|
||||
IEnumerable<IPublishedPropertyType> PropertyTypes { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a property type index.
|
||||
/// </summary>
|
||||
/// <remarks>The alias is case-insensitive. This is the only place where alias strings are compared.</remarks>
|
||||
int GetPropertyIndex(string alias);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a property type.
|
||||
/// </summary>
|
||||
IPublishedPropertyType GetPropertyType(string alias);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a property type.
|
||||
/// </summary>
|
||||
IPublishedPropertyType GetPropertyType(int index);
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@
|
||||
/// </summary>
|
||||
/// <param name="contentType">An content type.</param>
|
||||
/// <returns>A published content type corresponding to the item type and content type.</returns>
|
||||
PublishedContentType CreateContentType(IContentTypeComposition contentType);
|
||||
IPublishedContentType CreateContentType(IContentTypeComposition contentType);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a published property type.
|
||||
@@ -18,7 +18,7 @@
|
||||
/// <param name="contentType">The published content type owning the property.</param>
|
||||
/// <param name="propertyType">A property type.</param>
|
||||
/// <remarks>Is used by <see cref="PublishedContentType"/> constructor to create property types.</remarks>
|
||||
PublishedPropertyType CreatePropertyType(PublishedContentType contentType, PropertyType propertyType);
|
||||
IPublishedPropertyType CreatePropertyType(IPublishedContentType contentType, PropertyType propertyType);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a published property type.
|
||||
@@ -28,7 +28,7 @@
|
||||
/// <param name="dataTypeId">The datatype identifier.</param>
|
||||
/// <param name="variations">The variations.</param>
|
||||
/// <remarks>Is used by <see cref="PublishedContentType"/> constructor to create special property types.</remarks>
|
||||
PublishedPropertyType CreatePropertyType(PublishedContentType contentType, string propertyTypeAlias, int dataTypeId, ContentVariation variations);
|
||||
IPublishedPropertyType CreatePropertyType(IPublishedContentType contentType, string propertyTypeAlias, int dataTypeId, ContentVariation variations);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a published datatype.
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
/// <summary>
|
||||
/// Gets the content type.
|
||||
/// </summary>
|
||||
PublishedContentType ContentType { get; }
|
||||
IPublishedContentType ContentType { get; }
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
/// </summary>
|
||||
public interface IPublishedProperty
|
||||
{
|
||||
PublishedPropertyType PropertyType { get; }
|
||||
IPublishedPropertyType PropertyType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the alias of the property.
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
using System;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
|
||||
namespace Umbraco.Core.Models.PublishedContent
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a published property type.
|
||||
/// </summary>
|
||||
/// <remarks>Instances implementing the <see cref="PublishedPropertyType"/> interface should be
|
||||
/// immutable, ie if the property type changes, then a new instance needs to be created.</remarks>
|
||||
public interface IPublishedPropertyType
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the published content type containing the property type.
|
||||
/// </summary>
|
||||
IPublishedContentType ContentType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the data type.
|
||||
/// </summary>
|
||||
PublishedDataType DataType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets property type alias.
|
||||
/// </summary>
|
||||
string Alias { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the property editor alias.
|
||||
/// </summary>
|
||||
string EditorAlias { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the property is a user content property.
|
||||
/// </summary>
|
||||
/// <remarks>A non-user content property is a property that has been added to a
|
||||
/// published content type by Umbraco but does not corresponds to a user-defined
|
||||
/// published property.</remarks>
|
||||
bool IsUserProperty { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the content variations of the property type.
|
||||
/// </summary>
|
||||
ContentVariation Variations { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether a value is an actual value, or not a value.
|
||||
/// </summary>
|
||||
/// <remarks>Used by property.HasValue and, for instance, in fallback scenarios.</remarks>
|
||||
bool? IsValue(object value, PropertyValueLevel level);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the property cache level.
|
||||
/// </summary>
|
||||
PropertyCacheLevel CacheLevel { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Converts the source value into the intermediate value.
|
||||
/// </summary>
|
||||
/// <param name="owner">The published element owning the property.</param>
|
||||
/// <param name="source">The source value.</param>
|
||||
/// <param name="preview">A value indicating whether content should be considered draft.</param>
|
||||
/// <returns>The intermediate value.</returns>
|
||||
object ConvertSourceToInter(IPublishedElement owner, object source, bool preview);
|
||||
|
||||
/// <summary>
|
||||
/// Converts the intermediate value into the object value.
|
||||
/// </summary>
|
||||
/// <param name="owner">The published element owning the property.</param>
|
||||
/// <param name="referenceCacheLevel">The reference cache level.</param>
|
||||
/// <param name="inter">The intermediate value.</param>
|
||||
/// <param name="preview">A value indicating whether content should be considered draft.</param>
|
||||
/// <returns>The object value.</returns>
|
||||
object ConvertInterToObject(IPublishedElement owner, PropertyCacheLevel referenceCacheLevel, object inter, bool preview);
|
||||
|
||||
/// <summary>
|
||||
/// Converts the intermediate value into the XPath value.
|
||||
/// </summary>
|
||||
/// <param name="owner">The published element owning the property.</param>
|
||||
/// <param name="referenceCacheLevel">The reference cache level.</param>
|
||||
/// <param name="inter">The intermediate value.</param>
|
||||
/// <param name="preview">A value indicating whether content should be considered draft.</param>
|
||||
/// <returns>The XPath value.</returns>
|
||||
/// <remarks>
|
||||
/// <para>The XPath value can be either a string or an XPathNavigator.</para>
|
||||
/// </remarks>
|
||||
object ConvertInterToXPath(IPublishedElement owner, PropertyCacheLevel referenceCacheLevel, object inter, bool preview);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the property model CLR type.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>The model CLR type may be a <see cref="ModelType"/> type, or may contain <see cref="ModelType"/> types.</para>
|
||||
/// <para>For the actual CLR type, see <see cref="ClrType"/>.</para>
|
||||
/// </remarks>
|
||||
Type ModelClrType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the property CLR type.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>Returns the actual CLR type which does not contain <see cref="ModelType"/> types.</para>
|
||||
/// <para>Mapping from <see cref="ModelClrType"/> may throw if some <see cref="ModelType"/> instances
|
||||
/// could not be mapped to actual CLR types.</para>
|
||||
/// </remarks>
|
||||
Type ClrType { get; }
|
||||
}
|
||||
}
|
||||
@@ -75,7 +75,7 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
return type;
|
||||
var def = type.GetGenericTypeDefinition();
|
||||
if (def == null)
|
||||
throw new InvalidOperationException("panic");
|
||||
throw new PanicException($"The type {type} has not generic type definition");
|
||||
|
||||
var args = type.GetGenericArguments().Select(x => Map(x, modelTypes, true)).ToArray();
|
||||
return def.MakeGenericType(args);
|
||||
@@ -114,7 +114,7 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
return type.FullName;
|
||||
var def = type.GetGenericTypeDefinition();
|
||||
if (def == null)
|
||||
throw new InvalidOperationException("panic");
|
||||
throw new PanicException($"The type {type} has not generic type definition");
|
||||
|
||||
var args = type.GetGenericArguments().Select(x => MapToName(x, map, true)).ToArray();
|
||||
var defFullName = def.FullName.Substring(0, def.FullName.IndexOf('`'));
|
||||
|
||||
@@ -5,13 +5,13 @@ using System.Linq;
|
||||
namespace Umbraco.Core.Models.PublishedContent
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an <see cref="IPublishedContent"/> type.
|
||||
/// Represents an <see cref="IPublishedElement"/> type.
|
||||
/// </summary>
|
||||
/// <remarks>Instances of the <see cref="PublishedContentType"/> class are immutable, ie
|
||||
/// if the content type changes, then a new class needs to be created.</remarks>
|
||||
public class PublishedContentType
|
||||
public class PublishedContentType : IPublishedContentType
|
||||
{
|
||||
private readonly PublishedPropertyType[] _propertyTypes;
|
||||
private readonly IPublishedPropertyType[] _propertyTypes;
|
||||
|
||||
// fast alias-to-index xref containing both the raw alias and its lowercase version
|
||||
private readonly Dictionary<string, int> _indexes = new Dictionary<string, int>();
|
||||
@@ -35,11 +35,10 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PublishedContentType"/> with specific values.
|
||||
/// This constructor is for tests and is not intended to be used directly from application code.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>This constructor is for tests and is not intended to be used directly from application code.</para>
|
||||
/// <para>Values are assumed to be consisted and are not checked.</para>
|
||||
/// <para>Values are assumed to be consistent and are not checked.</para>
|
||||
/// </remarks>
|
||||
public PublishedContentType(int id, string alias, PublishedItemType itemType, IEnumerable<string> compositionAliases, IEnumerable<PublishedPropertyType> propertyTypes, ContentVariation variations, bool isElement = false)
|
||||
: this (id, alias, itemType, compositionAliases, variations, isElement)
|
||||
@@ -52,6 +51,20 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
InitializeIndexes();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This constructor is for tests and is not intended to be used directly from application code.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>Values are assumed to be consistent and are not checked.</para>
|
||||
/// </remarks>
|
||||
public PublishedContentType(int id, string alias, PublishedItemType itemType, IEnumerable<string> compositionAliases, Func<IPublishedContentType, IEnumerable<IPublishedPropertyType>> propertyTypes, ContentVariation variations, bool isElement = false)
|
||||
: this(id, alias, itemType, compositionAliases, variations, isElement)
|
||||
{
|
||||
_propertyTypes = propertyTypes(this).ToArray();
|
||||
|
||||
InitializeIndexes();
|
||||
}
|
||||
|
||||
private PublishedContentType(int id, string alias, PublishedItemType itemType, IEnumerable<string> compositionAliases, ContentVariation variations, bool isElement)
|
||||
{
|
||||
Id = id;
|
||||
@@ -75,7 +88,7 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
// Members have properties such as IMember LastLoginDate which are plain C# properties and not content
|
||||
// properties; they are exposed as pseudo content properties, as long as a content property with the
|
||||
// same alias does not exist already.
|
||||
private void EnsureMemberProperties(List<PublishedPropertyType> propertyTypes, IPublishedContentTypeFactory factory)
|
||||
private void EnsureMemberProperties(List<IPublishedPropertyType> propertyTypes, IPublishedContentTypeFactory factory)
|
||||
{
|
||||
var aliases = new HashSet<string>(propertyTypes.Select(x => x.Alias), StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
@@ -103,44 +116,29 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
|
||||
#region Content type
|
||||
|
||||
/// <summary>
|
||||
/// Gets the content type identifier.
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public int Id { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the content type alias.
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public string Alias { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the content item type.
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public PublishedItemType ItemType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the aliases of the content types participating in the composition.
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public HashSet<string> CompositionAliases { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the content variations of the content type.
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public ContentVariation Variations { get; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets the content type properties.
|
||||
/// </summary>
|
||||
public IEnumerable<PublishedPropertyType> PropertyTypes => _propertyTypes;
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<IPublishedPropertyType> PropertyTypes => _propertyTypes;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a property type index.
|
||||
/// </summary>
|
||||
/// <remarks>The alias is case-insensitive. This is the only place where alias strings are compared.</remarks>
|
||||
/// <inheritdoc />
|
||||
public int GetPropertyIndex(string alias)
|
||||
{
|
||||
if (_indexes.TryGetValue(alias, out var index)) return index; // fastest
|
||||
@@ -150,10 +148,8 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
|
||||
// virtual for unit tests
|
||||
// TODO: explain why
|
||||
/// <summary>
|
||||
/// Gets a property type.
|
||||
/// </summary>
|
||||
public virtual PublishedPropertyType GetPropertyType(string alias)
|
||||
/// <inheritdoc />
|
||||
public virtual IPublishedPropertyType GetPropertyType(string alias)
|
||||
{
|
||||
var index = GetPropertyIndex(alias);
|
||||
return GetPropertyType(index);
|
||||
@@ -161,17 +157,13 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
|
||||
// virtual for unit tests
|
||||
// TODO: explain why
|
||||
/// <summary>
|
||||
/// Gets a property type.
|
||||
/// </summary>
|
||||
public virtual PublishedPropertyType GetPropertyType(int index)
|
||||
/// <inheritdoc />
|
||||
public virtual IPublishedPropertyType GetPropertyType(int index)
|
||||
{
|
||||
return index >= 0 && index < _propertyTypes.Length ? _propertyTypes[index] : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this content type is for an element.
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public bool IsElement { get; }
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -26,37 +26,46 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public PublishedContentType CreateContentType(IContentTypeComposition contentType)
|
||||
public IPublishedContentType CreateContentType(IContentTypeComposition contentType)
|
||||
{
|
||||
return new PublishedContentType(contentType, this);
|
||||
}
|
||||
|
||||
// for tests
|
||||
internal PublishedContentType CreateContentType(int id, string alias, IEnumerable<PublishedPropertyType> propertyTypes, ContentVariation variations = ContentVariation.Nothing, bool isElement = false)
|
||||
/// <summary>
|
||||
/// This method is for tests and is not intended to be used directly from application code.
|
||||
/// </summary>
|
||||
/// <remarks>Values are assumed to be consisted and are not checked.</remarks>
|
||||
internal IPublishedContentType CreateContentType(int id, string alias, Func<IPublishedContentType, IEnumerable<IPublishedPropertyType>> propertyTypes, ContentVariation variations = ContentVariation.Nothing, bool isElement = false)
|
||||
{
|
||||
return new PublishedContentType(id, alias, PublishedItemType.Content, Enumerable.Empty<string>(), propertyTypes, variations, isElement);
|
||||
}
|
||||
|
||||
// for tests
|
||||
internal PublishedContentType CreateContentType(int id, string alias, IEnumerable<string> compositionAliases, IEnumerable<PublishedPropertyType> propertyTypes, ContentVariation variations = ContentVariation.Nothing, bool isElement = false)
|
||||
/// <summary>
|
||||
/// This method is for tests and is not intended to be used directly from application code.
|
||||
/// </summary>
|
||||
/// <remarks>Values are assumed to be consisted and are not checked.</remarks>
|
||||
internal IPublishedContentType CreateContentType(int id, string alias, IEnumerable<string> compositionAliases, Func<IPublishedContentType, IEnumerable<IPublishedPropertyType>> propertyTypes, ContentVariation variations = ContentVariation.Nothing, bool isElement = false)
|
||||
{
|
||||
return new PublishedContentType(id, alias, PublishedItemType.Content, compositionAliases, propertyTypes, variations, isElement);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public PublishedPropertyType CreatePropertyType(PublishedContentType contentType, PropertyType propertyType)
|
||||
public IPublishedPropertyType CreatePropertyType(IPublishedContentType contentType, PropertyType propertyType)
|
||||
{
|
||||
return new PublishedPropertyType(contentType, propertyType, _propertyValueConverters, _publishedModelFactory, this);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public PublishedPropertyType CreatePropertyType(PublishedContentType contentType, string propertyTypeAlias, int dataTypeId, ContentVariation variations = ContentVariation.Nothing)
|
||||
public IPublishedPropertyType CreatePropertyType(IPublishedContentType contentType, string propertyTypeAlias, int dataTypeId, ContentVariation variations = ContentVariation.Nothing)
|
||||
{
|
||||
return new PublishedPropertyType(contentType, propertyTypeAlias, dataTypeId, true, variations, _propertyValueConverters, _publishedModelFactory, this);
|
||||
}
|
||||
|
||||
// for tests
|
||||
internal PublishedPropertyType CreatePropertyType(string propertyTypeAlias, int dataTypeId, bool umbraco = false, ContentVariation variations = ContentVariation.Nothing)
|
||||
/// <summary>
|
||||
/// This method is for tests and is not intended to be used directly from application code.
|
||||
/// </summary>
|
||||
/// <remarks>Values are assumed to be consisted and are not checked.</remarks>
|
||||
internal IPublishedPropertyType CreatePropertyType(string propertyTypeAlias, int dataTypeId, bool umbraco = false, ContentVariation variations = ContentVariation.Nothing)
|
||||
{
|
||||
return new PublishedPropertyType(propertyTypeAlias, dataTypeId, umbraco, variations, _propertyValueConverters, _publishedModelFactory, this);
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
#region ContentType
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual PublishedContentType ContentType => _content.ContentType;
|
||||
public virtual IPublishedContentType ContentType => _content.ContentType;
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -96,12 +96,6 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
/// <inheritdoc />
|
||||
public virtual string Url => _content.Url;
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual string GetUrl(string culture = null) => _content.GetUrl(culture);
|
||||
|
||||
/// <inheritdoc />
|
||||
public PublishedCultureInfo GetCulture(string culture = null) => _content.GetCulture(culture);
|
||||
|
||||
/// <inheritdoc />
|
||||
public IReadOnlyDictionary<string, PublishedCultureInfo> Cultures => _content.Cultures;
|
||||
|
||||
@@ -124,6 +118,9 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
/// <inheritdoc />
|
||||
public virtual IEnumerable<IPublishedContent> Children => _content.Children;
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual IEnumerable<IPublishedContent> ChildrenForAllCultures => _content.ChildrenForAllCultures;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
@@ -13,10 +13,9 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
/// </summary>
|
||||
public PublishedCultureInfo(string culture, string name, string urlSegment, DateTime date)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(culture)) throw new ArgumentNullOrEmptyException(nameof(culture));
|
||||
if (string.IsNullOrWhiteSpace(name)) throw new ArgumentNullOrEmptyException(nameof(name));
|
||||
|
||||
Culture = culture;
|
||||
Culture = culture ?? throw new ArgumentNullException(nameof(culture));
|
||||
Name = name;
|
||||
UrlSegment = urlSegment;
|
||||
Date = date;
|
||||
@@ -30,12 +29,12 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
/// <summary>
|
||||
/// Gets the name of the item.
|
||||
/// </summary>
|
||||
public string Name { get; }
|
||||
internal string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the url segment of the item.
|
||||
/// </summary>
|
||||
public string UrlSegment { get; }
|
||||
internal string UrlSegment { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the date associated with the culture.
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
public IPublishedElement Unwrap() => _content;
|
||||
|
||||
/// <inheritdoc />
|
||||
public PublishedContentType ContentType => _content.ContentType;
|
||||
public IPublishedContentType ContentType => _content.ContentType;
|
||||
|
||||
/// <inheritdoc />
|
||||
public Guid Key => _content.Key;
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PublishedPropertyBase"/> class.
|
||||
/// </summary>
|
||||
protected PublishedPropertyBase(PublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel)
|
||||
protected PublishedPropertyBase(IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel)
|
||||
{
|
||||
PropertyType = propertyType ?? throw new ArgumentNullException(nameof(propertyType));
|
||||
ReferenceCacheLevel = referenceCacheLevel;
|
||||
@@ -42,7 +42,7 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
/// <summary>
|
||||
/// Gets the property type.
|
||||
/// </summary>
|
||||
public PublishedPropertyType PropertyType { get; }
|
||||
public IPublishedPropertyType PropertyType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the property reference cache level.
|
||||
|
||||
@@ -10,10 +10,8 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
/// </summary>
|
||||
/// <remarks>Instances of the <see cref="PublishedPropertyType"/> class are immutable, ie
|
||||
/// if the property type changes, then a new class needs to be created.</remarks>
|
||||
public class PublishedPropertyType
|
||||
public class PublishedPropertyType : IPublishedPropertyType
|
||||
{
|
||||
// TODO: API design review, should this be an interface?
|
||||
|
||||
private readonly IPublishedModelFactory _publishedModelFactory;
|
||||
private readonly PropertyValueConverterCollection _propertyValueConverters;
|
||||
private readonly object _locker = new object();
|
||||
@@ -32,7 +30,7 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
/// <remarks>
|
||||
/// <para>The new published property type belongs to the published content type.</para>
|
||||
/// </remarks>
|
||||
public PublishedPropertyType(PublishedContentType contentType, PropertyType propertyType, PropertyValueConverterCollection propertyValueConverters, IPublishedModelFactory publishedModelFactory, IPublishedContentTypeFactory factory)
|
||||
public PublishedPropertyType(IPublishedContentType contentType, PropertyType propertyType, PropertyValueConverterCollection propertyValueConverters, IPublishedModelFactory publishedModelFactory, IPublishedContentTypeFactory factory)
|
||||
: this(propertyType.Alias, propertyType.DataTypeId, true, propertyType.Variations, propertyValueConverters, publishedModelFactory, factory)
|
||||
{
|
||||
ContentType = contentType ?? throw new ArgumentNullException(nameof(contentType));
|
||||
@@ -45,7 +43,7 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
/// <para>Values are assumed to be consisted and are not checked.</para>
|
||||
/// <para>The new published property type belongs to the published content type.</para>
|
||||
/// </remarks>
|
||||
public PublishedPropertyType(PublishedContentType contentType, string propertyTypeAlias, int dataTypeId, bool isUserProperty, ContentVariation variations, PropertyValueConverterCollection propertyValueConverters, IPublishedModelFactory publishedModelFactory, IPublishedContentTypeFactory factory)
|
||||
public PublishedPropertyType(IPublishedContentType contentType, string propertyTypeAlias, int dataTypeId, bool isUserProperty, ContentVariation variations, PropertyValueConverterCollection propertyValueConverters, IPublishedModelFactory publishedModelFactory, IPublishedContentTypeFactory factory)
|
||||
: this(propertyTypeAlias, dataTypeId, isUserProperty, variations, propertyValueConverters, publishedModelFactory, factory)
|
||||
{
|
||||
ContentType = contentType ?? throw new ArgumentNullException(nameof(contentType));
|
||||
@@ -75,37 +73,22 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
|
||||
#region Property type
|
||||
|
||||
/// <summary>
|
||||
/// Gets the published content type containing the property type.
|
||||
/// </summary>
|
||||
public PublishedContentType ContentType { get; internal set; } // internally set by PublishedContentType constructor
|
||||
/// <inheritdoc />
|
||||
public IPublishedContentType ContentType { get; internal set; } // internally set by PublishedContentType constructor
|
||||
|
||||
/// <summary>
|
||||
/// Gets the data type.
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public PublishedDataType DataType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets property type alias.
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public string Alias { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the property editor alias.
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public string EditorAlias => DataType.EditorAlias;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the property is a user content property.
|
||||
/// </summary>
|
||||
/// <remarks>A non-user content property is a property that has been added to a
|
||||
/// published content type by Umbraco but does not corresponds to a user-defined
|
||||
/// published property.</remarks>
|
||||
/// <inheritdoc />
|
||||
public bool IsUserProperty { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the content variations of the property type.
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public ContentVariation Variations { get; }
|
||||
|
||||
#endregion
|
||||
@@ -193,10 +176,7 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
_modelClrType = _converter == null ? typeof (object) : _converter.GetPropertyValueType(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether a value is an actual value, or not a value.
|
||||
/// </summary>
|
||||
/// <remarks>Used by property.HasValue and, for instance, in fallback scenarios.</remarks>
|
||||
/// <inheritdoc />
|
||||
public bool? IsValue(object value, PropertyValueLevel level)
|
||||
{
|
||||
if (!_initialized) Initialize();
|
||||
@@ -209,9 +189,7 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
return value != null && (!(value is string) || string.IsNullOrWhiteSpace((string) value) == false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the property cache level.
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public PropertyCacheLevel CacheLevel
|
||||
{
|
||||
get
|
||||
@@ -221,13 +199,7 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the source value into the intermediate value.
|
||||
/// </summary>
|
||||
/// <param name="owner">The published element owning the property.</param>
|
||||
/// <param name="source">The source value.</param>
|
||||
/// <param name="preview">A value indicating whether content should be considered draft.</param>
|
||||
/// <returns>The intermediate value.</returns>
|
||||
/// <inheritdoc />
|
||||
public object ConvertSourceToInter(IPublishedElement owner, object source, bool preview)
|
||||
{
|
||||
if (!_initialized) Initialize();
|
||||
@@ -238,14 +210,7 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
: source;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the intermediate value into the object value.
|
||||
/// </summary>
|
||||
/// <param name="owner">The published element owning the property.</param>
|
||||
/// <param name="referenceCacheLevel">The reference cache level.</param>
|
||||
/// <param name="inter">The intermediate value.</param>
|
||||
/// <param name="preview">A value indicating whether content should be considered draft.</param>
|
||||
/// <returns>The object value.</returns>
|
||||
/// <inheritdoc />
|
||||
public object ConvertInterToObject(IPublishedElement owner, PropertyCacheLevel referenceCacheLevel, object inter, bool preview)
|
||||
{
|
||||
if (!_initialized) Initialize();
|
||||
@@ -256,17 +221,7 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
: inter;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the intermediate value into the XPath value.
|
||||
/// </summary>
|
||||
/// <param name="owner">The published element owning the property.</param>
|
||||
/// <param name="referenceCacheLevel">The reference cache level.</param>
|
||||
/// <param name="inter">The intermediate value.</param>
|
||||
/// <param name="preview">A value indicating whether content should be considered draft.</param>
|
||||
/// <returns>The XPath value.</returns>
|
||||
/// <remarks>
|
||||
/// <para>The XPath value can be either a string or an XPathNavigator.</para>
|
||||
/// </remarks>
|
||||
/// <inheritdoc />
|
||||
public object ConvertInterToXPath(IPublishedElement owner, PropertyCacheLevel referenceCacheLevel, object inter, bool preview)
|
||||
{
|
||||
if (!_initialized) Initialize();
|
||||
@@ -282,13 +237,7 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
return inter.ToString().Trim();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the property model CLR type.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>The model CLR type may be a <see cref="ModelType"/> type, or may contain <see cref="ModelType"/> types.</para>
|
||||
/// <para>For the actual CLR type, see <see cref="ClrType"/>.</para>
|
||||
/// </remarks>
|
||||
/// <inheritdoc />
|
||||
public Type ModelClrType
|
||||
{
|
||||
get
|
||||
@@ -298,14 +247,7 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the property CLR type.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>Returns the actual CLR type which does not contain <see cref="ModelType"/> types.</para>
|
||||
/// <para>Mapping from <see cref="ModelClrType"/> may throw if some <see cref="ModelType"/> instances
|
||||
/// could not be mapped to actual CLR types.</para>
|
||||
/// </remarks>
|
||||
/// <inheritdoc />
|
||||
public Type ClrType
|
||||
{
|
||||
get
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
public override object GetXPathValue(string culture = null, string segment = null)
|
||||
=> string.IsNullOrEmpty(culture) & string.IsNullOrEmpty(segment) ? _xpathValue.Value : null;
|
||||
|
||||
public RawValueProperty(PublishedPropertyType propertyType, IPublishedElement content, object sourceValue, bool isPreviewing = false)
|
||||
public RawValueProperty(IPublishedPropertyType propertyType, IPublishedElement content, object sourceValue, bool isPreviewing = false)
|
||||
: base(propertyType, PropertyCacheLevel.Unknown) // cache level is ignored
|
||||
{
|
||||
if (propertyType.Variations != ContentVariation.Nothing)
|
||||
|
||||
+7
-7
@@ -1,14 +1,14 @@
|
||||
namespace Umbraco.Web.Routing
|
||||
namespace Umbraco.Core.Models.PublishedContent
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies the type of urls that the url provider should produce, Auto is the default
|
||||
/// Specifies the type of urls that the url provider should produce, Auto is the default.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>The <c>Relative</c> option can lead to invalid results when combined with hostnames, but it is the only way to reproduce
|
||||
/// the true, pre-4.10, always-relative behavior of Umbraco.</para>
|
||||
/// </remarks>
|
||||
public enum UrlProviderMode
|
||||
public enum UrlMode
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates that the url provider should do what it has been configured to do.
|
||||
/// </summary>
|
||||
Default = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the url provider should produce relative urls exclusively.
|
||||
@@ -193,19 +193,6 @@ namespace Umbraco.Core.Models
|
||||
return ContentPermissionsHelper.HasPathAccess(entity.Path, user.CalculateMediaStartNodeIds(entityService), Constants.System.RecycleBinMedia);
|
||||
}
|
||||
|
||||
internal static bool IsInBranchOfStartNode(this IUser user, IUmbracoEntity entity, IEntityService entityService, int recycleBinId, out bool hasPathAccess)
|
||||
{
|
||||
switch (recycleBinId)
|
||||
{
|
||||
case Constants.System.RecycleBinMedia:
|
||||
return ContentPermissionsHelper.IsInBranchOfStartNode(entity.Path, user.CalculateMediaStartNodeIds(entityService), user.GetMediaStartNodePaths(entityService), out hasPathAccess);
|
||||
case Constants.System.RecycleBinContent:
|
||||
return ContentPermissionsHelper.IsInBranchOfStartNode(entity.Path, user.CalculateContentStartNodeIds(entityService), user.GetContentStartNodePaths(entityService), out hasPathAccess);
|
||||
default:
|
||||
throw new NotSupportedException("Path access is only determined on content or media");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether this user has access to view sensitive data
|
||||
/// </summary>
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
public static IEnumerable<Property> BuildEntities(PropertyType[] propertyTypes, IReadOnlyCollection<PropertyDataDto> dtos, int publishedVersionId, ILanguageRepository languageRepository)
|
||||
{
|
||||
var properties = new List<Property>();
|
||||
var xdtos = dtos.GroupBy(x => x.PropertyTypeId).ToDictionary(x => x.Key, x => (IEnumerable<PropertyDataDto>) x);
|
||||
var xdtos = dtos.GroupBy(x => x.PropertyTypeId).ToDictionary(x => x.Key, x => (IEnumerable<PropertyDataDto>)x);
|
||||
|
||||
foreach (var propertyType in propertyTypes)
|
||||
{
|
||||
@@ -104,10 +104,14 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
/// <param name="properties">The properties to map</param>
|
||||
/// <param name="languageRepository"></param>
|
||||
/// <param name="edited">out parameter indicating that one or more properties have been edited</param>
|
||||
/// <param name="editedCultures">out parameter containing a collection of edited cultures when the contentVariation varies by culture</param>
|
||||
/// <param name="editedCultures">
|
||||
/// Out parameter containing a collection of edited cultures when the contentVariation varies by culture.
|
||||
/// The value of this will be used to populate the edited cultures in the umbracoDocumentCultureVariation table.
|
||||
/// </param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<PropertyDataDto> BuildDtos(ContentVariation contentVariation, int currentVersionId, int publishedVersionId, IEnumerable<Property> properties,
|
||||
ILanguageRepository languageRepository, out bool edited, out HashSet<string> editedCultures)
|
||||
ILanguageRepository languageRepository, out bool edited,
|
||||
out HashSet<string> editedCultures)
|
||||
{
|
||||
var propertyDataDtos = new List<PropertyDataDto>();
|
||||
edited = false;
|
||||
@@ -130,6 +134,9 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
// publishing = deal with edit and published values
|
||||
foreach (var propertyValue in property.Values)
|
||||
{
|
||||
var isInvariantValue = propertyValue.Culture == null;
|
||||
var isCultureValue = propertyValue.Culture != null && propertyValue.Segment == null;
|
||||
|
||||
// deal with published value
|
||||
if (propertyValue.PublishedValue != null && publishedVersionId > 0)
|
||||
propertyDataDtos.Add(BuildDto(publishedVersionId, property, languageRepository.GetIdByIsoCode(propertyValue.Culture), propertyValue.Segment, propertyValue.PublishedValue));
|
||||
@@ -138,26 +145,36 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
if (propertyValue.EditedValue != null)
|
||||
propertyDataDtos.Add(BuildDto(currentVersionId, property, languageRepository.GetIdByIsoCode(propertyValue.Culture), propertyValue.Segment, propertyValue.EditedValue));
|
||||
|
||||
// property.Values will contain ALL of it's values, both variant and invariant which will be populated if the
|
||||
// administrator has previously changed the property type to be variant vs invariant.
|
||||
// We need to check for this scenario here because otherwise the editedCultures and edited flags
|
||||
// will end up incorrectly set in the umbracoDocumentCultureVariation table so here we need to
|
||||
// only process edited cultures based on the current value type and how the property varies.
|
||||
// The above logic will still persist the currently saved property value for each culture in case the admin
|
||||
// decides to swap the property's variance again, in which case the edited flag will be recalculated.
|
||||
|
||||
if (property.PropertyType.VariesByCulture() && isInvariantValue || !property.PropertyType.VariesByCulture() && isCultureValue)
|
||||
continue;
|
||||
|
||||
// use explicit equals here, else object comparison fails at comparing eg strings
|
||||
var sameValues = propertyValue.PublishedValue == null ? propertyValue.EditedValue == null : propertyValue.PublishedValue.Equals(propertyValue.EditedValue);
|
||||
|
||||
edited |= !sameValues;
|
||||
|
||||
if (entityVariesByCulture // cultures can be edited, ie CultureNeutral is supported
|
||||
&& propertyValue.Culture != null && propertyValue.Segment == null // and value is CultureNeutral
|
||||
&& !sameValues) // and edited and published are different
|
||||
if (entityVariesByCulture && !sameValues)
|
||||
{
|
||||
editedCultures.Add(propertyValue.Culture); // report culture as edited
|
||||
}
|
||||
if (isCultureValue)
|
||||
{
|
||||
editedCultures.Add(propertyValue.Culture); // report culture as edited
|
||||
}
|
||||
else if (isInvariantValue)
|
||||
{
|
||||
// flag culture as edited if it contains an edited invariant property
|
||||
if (defaultCulture == null)
|
||||
defaultCulture = languageRepository.GetDefaultIsoCode();
|
||||
|
||||
// flag culture as edited if it contains an edited invariant property
|
||||
if (propertyValue.Culture == null //invariant property
|
||||
&& !sameValues // and edited and published are different
|
||||
&& entityVariesByCulture) //only when the entity is variant
|
||||
{
|
||||
if (defaultCulture == null)
|
||||
defaultCulture = languageRepository.GetDefaultIsoCode();
|
||||
|
||||
editedCultures.Add(defaultCulture);
|
||||
editedCultures.Add(defaultCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -167,7 +184,7 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
{
|
||||
// not publishing = only deal with edit values
|
||||
if (propertyValue.EditedValue != null)
|
||||
propertyDataDtos.Add(BuildDto(currentVersionId, property, languageRepository.GetIdByIsoCode(propertyValue.Culture), propertyValue.Segment, propertyValue.EditedValue));
|
||||
propertyDataDtos.Add(BuildDto(currentVersionId, property, languageRepository.GetIdByIsoCode(propertyValue.Culture), propertyValue.Segment, propertyValue.EditedValue));
|
||||
}
|
||||
edited = true;
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
|
||||
propertyType.Alias = typeDto.Alias;
|
||||
propertyType.DataTypeId = typeDto.DataTypeId;
|
||||
propertyType.DataTypeKey = typeDto.DataTypeDto.NodeDto.UniqueId;
|
||||
propertyType.Description = typeDto.Description;
|
||||
propertyType.Id = typeDto.Id;
|
||||
propertyType.Key = typeDto.UniqueId;
|
||||
|
||||
@@ -10,22 +10,35 @@ namespace Umbraco.Core.Persistence
|
||||
/// <summary>
|
||||
/// Creates a new database.
|
||||
/// </summary>
|
||||
/// <remarks>The new database must be disposed after being used.</remarks>
|
||||
/// <remarks>
|
||||
/// <para>The new database must be disposed after being used.</para>
|
||||
/// <para>Creating a database causes the factory to initialize if it is not already initialized.</para>
|
||||
/// </remarks>
|
||||
IUmbracoDatabase CreateDatabase();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the database factory is configured.
|
||||
/// Gets a value indicating whether the database factory is configured, i.e. whether
|
||||
/// its connection string and provider name have been set. The factory may however not
|
||||
/// be initialized (see <see cref="Initialized"/>).
|
||||
/// </summary>
|
||||
bool Configured { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the database factory is initialized, i.e. whether
|
||||
/// its internal state is ready and it has been possible to connect to the database.
|
||||
/// </summary>
|
||||
bool Initialized { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the connection string.
|
||||
/// </summary>
|
||||
/// <remarks>Throws if the factory is not configured.</remarks>
|
||||
/// <remarks>May return <c>null</c> if the database factory is not configured.</remarks>
|
||||
string ConnectionString { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the database can connect.
|
||||
/// Gets a value indicating whether the database factory is configured (see <see cref="Configured"/>),
|
||||
/// and it is possible to connect to the database. The factory may however not be initialized (see
|
||||
/// <see cref="Initialized"/>).
|
||||
/// </summary>
|
||||
bool CanConnect { get; }
|
||||
|
||||
@@ -37,6 +50,9 @@ namespace Umbraco.Core.Persistence
|
||||
/// <summary>
|
||||
/// Gets the Sql context.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>Getting the Sql context causes the factory to initialize if it is not already initialized.</para>
|
||||
/// </remarks>
|
||||
ISqlContext SqlContext { get; }
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -18,7 +18,8 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
DefineMap<AuditItem, LogDto>(nameof(AuditItem.Id), nameof(LogDto.NodeId));
|
||||
DefineMap<AuditItem, LogDto>(nameof(AuditItem.CreateDate), nameof(LogDto.Datestamp));
|
||||
DefineMap<AuditItem, LogDto>(nameof(AuditItem.UserId), nameof(LogDto.UserId));
|
||||
DefineMap<AuditItem, LogDto>(nameof(AuditItem.AuditType), nameof(LogDto.Header));
|
||||
// we cannot map that one - because AuditType is an enum but Header is a string
|
||||
//DefineMap<AuditItem, LogDto>(nameof(AuditItem.AuditType), nameof(LogDto.Header));
|
||||
DefineMap<AuditItem, LogDto>(nameof(AuditItem.Comment), nameof(LogDto.Comment));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,6 +232,14 @@ namespace Umbraco.Core.Persistence
|
||||
using (var copy = new SqlBulkCopy(tConnection, SqlBulkCopyOptions.Default, tTransaction) { BulkCopyTimeout = 10000, DestinationTableName = tableName })
|
||||
using (var bulkReader = new PocoDataDataReader<T, SqlServerSyntaxProvider>(records, pocoData, syntax))
|
||||
{
|
||||
//we need to add column mappings here because otherwise columns will be matched by their order and if the order of them are different in the DB compared
|
||||
//to the order in which they are declared in the model then this will not work, so instead we will add column mappings by name so that this explicitly uses
|
||||
//the names instead of their ordering.
|
||||
foreach(var col in bulkReader.ColumnMappings)
|
||||
{
|
||||
copy.ColumnMappings.Add(col.DestinationColumn, col.DestinationColumn);
|
||||
}
|
||||
|
||||
copy.WriteToServer(bulkReader);
|
||||
return bulkReader.RecordsAffected;
|
||||
}
|
||||
|
||||
@@ -85,6 +85,17 @@ namespace Umbraco.Core.Persistence.Querying
|
||||
// I'm just unsure right now due to time constraints how to make it correct. It won't matter right now and has been working already with this bug but I've
|
||||
// only just discovered what it is actually doing.
|
||||
|
||||
// TODO
|
||||
// in most cases we want to convert the value to a plain object,
|
||||
// but for in some rare cases, we may want to do it differently,
|
||||
// for instance a Models.AuditType (an enum) may in some cases
|
||||
// need to be converted to its string value.
|
||||
// but - we cannot have specific code here, really - and how would
|
||||
// we configure this? is it even possible?
|
||||
/*
|
||||
var toString = typeof(object).GetMethod("ToString");
|
||||
var member = Expression.Call(m, toString);
|
||||
*/
|
||||
var member = Expression.Convert(m, typeof(object));
|
||||
var lambda = Expression.Lambda<Func<object>>(member);
|
||||
var getter = lambda.Compile();
|
||||
|
||||
@@ -33,5 +33,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
Direction orderDirection,
|
||||
AuditType[] auditTypeFilter,
|
||||
IQuery<IAuditItem> customFilter);
|
||||
|
||||
IEnumerable<IAuditItem> Get(AuditType type, IQuery<IAuditItem> query);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
/// <inheritdoc />
|
||||
protected override void PersistNewItem(IAuditEntry entity)
|
||||
{
|
||||
((EntityBase) entity).AddingEntity();
|
||||
entity.AddingEntity();
|
||||
|
||||
var dto = AuditEntryFactory.BuildDto(entity);
|
||||
Database.Insert(dto);
|
||||
|
||||
@@ -74,6 +74,18 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
return dtos.Select(x => new AuditItem(x.NodeId, Enum<AuditType>.Parse(x.Header), x.UserId ?? Constants.Security.UnknownUserId, x.EntityType, x.Comment, x.Parameters)).ToList();
|
||||
}
|
||||
|
||||
public IEnumerable<IAuditItem> Get(AuditType type, IQuery<IAuditItem> query)
|
||||
{
|
||||
var sqlClause = GetBaseQuery(false)
|
||||
.Where<LogDto>(x => x.Header == type.ToString());
|
||||
var translator = new SqlTranslator<IAuditItem>(sqlClause, query);
|
||||
var sql = translator.Translate();
|
||||
|
||||
var dtos = Database.Fetch<LogDto>(sql);
|
||||
|
||||
return dtos.Select(x => new AuditItem(x.NodeId, Enum<AuditType>.Parse(x.Header), x.UserId ?? Constants.Security.UnknownUserId, x.EntityType, x.Comment, x.Parameters)).ToList();
|
||||
}
|
||||
|
||||
protected override Sql<ISqlContext> GetBaseQuery(bool isCount)
|
||||
{
|
||||
var sql = SqlContext.Sql();
|
||||
|
||||
@@ -69,7 +69,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
/// <inheritdoc />
|
||||
protected override void PersistNewItem(IConsent entity)
|
||||
{
|
||||
((EntityBase) entity).AddingEntity();
|
||||
entity.AddingEntity();
|
||||
|
||||
var dto = ConsentFactory.BuildDto(entity);
|
||||
Database.Insert(dto);
|
||||
@@ -80,7 +80,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
/// <inheritdoc />
|
||||
protected override void PersistUpdatedItem(IConsent entity)
|
||||
{
|
||||
((EntityBase) entity).UpdatingEntity();
|
||||
entity.UpdatingEntity();
|
||||
|
||||
var dto = ConsentFactory.BuildDto(entity);
|
||||
Database.Update(dto);
|
||||
|
||||
@@ -512,31 +512,16 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
foreach (var a in allPropertyDataDtos)
|
||||
a.PropertyTypeDto = indexedPropertyTypeDtos[a.PropertyTypeId];
|
||||
|
||||
// prefetch configuration for tag properties
|
||||
var tagEditors = new Dictionary<string, TagConfiguration>();
|
||||
foreach (var propertyTypeDto in indexedPropertyTypeDtos.Values)
|
||||
{
|
||||
var editorAlias = propertyTypeDto.DataTypeDto.EditorAlias;
|
||||
var editorAttribute = PropertyEditors[editorAlias].GetTagAttribute();
|
||||
if (editorAttribute == null) continue;
|
||||
var tagConfigurationSource = propertyTypeDto.DataTypeDto.Configuration;
|
||||
var tagConfiguration = string.IsNullOrWhiteSpace(tagConfigurationSource)
|
||||
? new TagConfiguration()
|
||||
: JsonConvert.DeserializeObject<TagConfiguration>(tagConfigurationSource);
|
||||
if (tagConfiguration.Delimiter == default) tagConfiguration.Delimiter = editorAttribute.Delimiter;
|
||||
tagEditors[editorAlias] = tagConfiguration;
|
||||
}
|
||||
|
||||
// now we have
|
||||
// - the definitions
|
||||
// - all property data dtos
|
||||
// - tag editors
|
||||
// - tag editors (Actually ... no we don't since i removed that code, but we don't need them anyways it seems)
|
||||
// and we need to build the proper property collections
|
||||
|
||||
return GetPropertyCollections(temps, allPropertyDataDtos, tagEditors);
|
||||
return GetPropertyCollections(temps, allPropertyDataDtos);
|
||||
}
|
||||
|
||||
private IDictionary<int, PropertyCollection> GetPropertyCollections<T>(List<TempContent<T>> temps, IEnumerable<PropertyDataDto> allPropertyDataDtos, Dictionary<string, TagConfiguration> tagConfigurations)
|
||||
private IDictionary<int, PropertyCollection> GetPropertyCollections<T>(List<TempContent<T>> temps, IEnumerable<PropertyDataDto> allPropertyDataDtos)
|
||||
where T : class, IContentBase
|
||||
{
|
||||
var result = new Dictionary<int, PropertyCollection>();
|
||||
|
||||
@@ -3,10 +3,12 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NPoco;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Exceptions;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
using Umbraco.Core.Persistence.Factories;
|
||||
using Umbraco.Core.Scoping;
|
||||
using static Umbraco.Core.Persistence.NPocoSqlExtensions.Statics;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
{
|
||||
@@ -89,7 +91,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
contentType = ContentTypeFactory.BuildContentTypeEntity(contentTypeDto);
|
||||
else if (contentTypeDto.NodeDto.NodeObjectType == Constants.ObjectTypes.MemberType)
|
||||
contentType = ContentTypeFactory.BuildMemberTypeEntity(contentTypeDto);
|
||||
else throw new Exception("panic");
|
||||
else throw new PanicException($"The node object type {contentTypeDto.NodeDto.NodeObjectType} is not supported");
|
||||
contentTypes.Add(contentType.Id, contentType);
|
||||
|
||||
// map allowed content types
|
||||
@@ -140,10 +142,10 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
while (templateDtoIx < templateDtos.Count && templateDtos[templateDtoIx].ContentTypeNodeId == contentType.Id)
|
||||
{
|
||||
var allowedDto = templateDtos[templateDtoIx];
|
||||
templateDtoIx++;
|
||||
if (!templates.TryGetValue(allowedDto.TemplateNodeId, out var template)) continue;
|
||||
allowedTemplates.Add(template);
|
||||
templateDtoIx++;
|
||||
|
||||
|
||||
if (allowedDto.IsDefault)
|
||||
defaultTemplateId = template.Id;
|
||||
}
|
||||
@@ -188,10 +190,11 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
var groupDtos = Database.Fetch<PropertyTypeGroupDto>(sql1);
|
||||
|
||||
var sql2 = Sql()
|
||||
.Select<PropertyTypeDto>(r => r.Select(x => x.DataTypeDto))
|
||||
.Select<PropertyTypeDto>(r => r.Select(x => x.DataTypeDto, r1 => r1.Select(x => x.NodeDto)))
|
||||
.AndSelect<MemberPropertyTypeDto>()
|
||||
.From<PropertyTypeDto>()
|
||||
.InnerJoin<DataTypeDto>().On<PropertyTypeDto, DataTypeDto>((pt, dt) => pt.DataTypeId == dt.NodeId)
|
||||
.InnerJoin<NodeDto>().On<DataTypeDto, NodeDto>((dt, n) => dt.NodeId == n.NodeId)
|
||||
.InnerJoin<ContentTypeDto>().On<PropertyTypeDto, ContentTypeDto>((pt, ct) => pt.ContentTypeId == ct.NodeId)
|
||||
.LeftJoin<PropertyTypeGroupDto>().On<PropertyTypeDto, PropertyTypeGroupDto>((pt, ptg) => pt.PropertyTypeGroupId == ptg.Id)
|
||||
.LeftJoin<MemberPropertyTypeDto>().On<PropertyTypeDto, MemberPropertyTypeDto>((pt, mpt) => pt.Id == mpt.PropertyTypeId)
|
||||
@@ -290,6 +293,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
{
|
||||
Description = dto.Description,
|
||||
DataTypeId = dto.DataTypeId,
|
||||
DataTypeKey = dto.DataTypeDto.NodeDto.UniqueId,
|
||||
Id = dto.Id,
|
||||
Key = dto.UniqueId,
|
||||
Mandatory = dto.Mandatory,
|
||||
|
||||
@@ -3,8 +3,10 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NPoco;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Exceptions;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Entities;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
using Umbraco.Core.Persistence.Querying;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
@@ -17,8 +19,8 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
/// </summary>
|
||||
internal class ContentTypeRepository : ContentTypeRepositoryBase<IContentType>, IContentTypeRepository
|
||||
{
|
||||
public ContentTypeRepository(IScopeAccessor scopeAccessor, AppCaches cache, ILogger logger, IContentTypeCommonRepository commonRepository)
|
||||
: base(scopeAccessor, cache, logger, commonRepository)
|
||||
public ContentTypeRepository(IScopeAccessor scopeAccessor, AppCaches cache, ILogger logger, IContentTypeCommonRepository commonRepository, ILanguageRepository languageRepository)
|
||||
: base(scopeAccessor, cache, logger, commonRepository, languageRepository)
|
||||
{ }
|
||||
|
||||
protected override bool SupportsPublishing => ContentType.SupportsPublishingConst;
|
||||
@@ -55,7 +57,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
{
|
||||
// the cache policy will always want everything
|
||||
// even GetMany(ids) gets everything and filters afterwards
|
||||
if (ids.Any()) throw new Exception("panic");
|
||||
if (ids.Any()) throw new PanicException("There can be no ids specified");
|
||||
return CommonRepository.GetAllTypes().OfType<IContentType>();
|
||||
}
|
||||
|
||||
@@ -230,7 +232,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
throw ex;
|
||||
}
|
||||
|
||||
((ContentType)entity).AddingEntity();
|
||||
entity.AddingEntity();
|
||||
|
||||
PersistNewBaseContentType(entity);
|
||||
PersistTemplates(entity, false);
|
||||
@@ -270,7 +272,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
ValidateAlias(entity);
|
||||
|
||||
//Updates Modified date
|
||||
((ContentType)entity).UpdatingEntity();
|
||||
entity.UpdatingEntity();
|
||||
|
||||
//Look up parent to get and set the correct Path if ParentId has changed
|
||||
if (entity.IsPropertyDirty("ParentId"))
|
||||
|
||||
@@ -15,6 +15,7 @@ using Umbraco.Core.Persistence.Factories;
|
||||
using Umbraco.Core.Persistence.Querying;
|
||||
using Umbraco.Core.Scoping;
|
||||
using Umbraco.Core.Services;
|
||||
using static Umbraco.Core.Persistence.NPocoSqlExtensions.Statics;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
{
|
||||
@@ -26,14 +27,15 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
internal abstract class ContentTypeRepositoryBase<TEntity> : NPocoRepositoryBase<int, TEntity>, IReadRepository<Guid, TEntity>
|
||||
where TEntity : class, IContentTypeComposition
|
||||
{
|
||||
protected ContentTypeRepositoryBase(IScopeAccessor scopeAccessor, AppCaches cache, ILogger logger, IContentTypeCommonRepository commonRepository)
|
||||
protected ContentTypeRepositoryBase(IScopeAccessor scopeAccessor, AppCaches cache, ILogger logger, IContentTypeCommonRepository commonRepository, ILanguageRepository languageRepository)
|
||||
: base(scopeAccessor, cache, logger)
|
||||
{
|
||||
CommonRepository = commonRepository;
|
||||
LanguageRepository = languageRepository;
|
||||
}
|
||||
|
||||
protected IContentTypeCommonRepository CommonRepository { get; }
|
||||
|
||||
protected ILanguageRepository LanguageRepository { get; }
|
||||
protected abstract bool SupportsPublishing { get; }
|
||||
|
||||
public IEnumerable<MoveEventInfo<TEntity>> Move(TEntity moving, EntityContainer container)
|
||||
@@ -98,6 +100,8 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
|
||||
protected void PersistNewBaseContentType(IContentTypeComposition entity)
|
||||
{
|
||||
ValidateVariations(entity);
|
||||
|
||||
var dto = ContentTypeFactory.BuildContentTypeDto(entity);
|
||||
|
||||
//Cannot add a duplicate content type
|
||||
@@ -163,11 +167,11 @@ AND umbracoNode.nodeObjectType = @objectType",
|
||||
foreach (var allowedContentType in entity.AllowedContentTypes)
|
||||
{
|
||||
Database.Insert(new ContentTypeAllowedContentTypeDto
|
||||
{
|
||||
Id = entity.Id,
|
||||
AllowedId = allowedContentType.Id.Value,
|
||||
SortOrder = allowedContentType.SortOrder
|
||||
});
|
||||
{
|
||||
Id = entity.Id,
|
||||
AllowedId = allowedContentType.Id.Value,
|
||||
SortOrder = allowedContentType.SortOrder
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -214,6 +218,8 @@ AND umbracoNode.nodeObjectType = @objectType",
|
||||
|
||||
protected void PersistUpdatedBaseContentType(IContentTypeComposition entity)
|
||||
{
|
||||
ValidateVariations(entity);
|
||||
|
||||
var dto = ContentTypeFactory.BuildContentTypeDto(entity);
|
||||
|
||||
// ensure the alias is not used already
|
||||
@@ -370,7 +376,7 @@ AND umbracoNode.id <> @id",
|
||||
foreach (var propertyGroup in entity.PropertyGroups)
|
||||
{
|
||||
// insert or update group
|
||||
var groupDto = PropertyGroupFactory.BuildGroupDto(propertyGroup,entity.Id);
|
||||
var groupDto = PropertyGroupFactory.BuildGroupDto(propertyGroup, entity.Id);
|
||||
var groupId = propertyGroup.HasIdentity
|
||||
? Database.Update(groupDto)
|
||||
: Convert.ToInt32(Database.Insert(groupDto));
|
||||
@@ -388,7 +394,7 @@ AND umbracoNode.id <> @id",
|
||||
|
||||
//check if the content type variation has been changed
|
||||
var contentTypeVariationDirty = entity.IsPropertyDirty("Variations");
|
||||
var oldContentTypeVariation = (ContentVariation) dtoPk.Variations;
|
||||
var oldContentTypeVariation = (ContentVariation)dtoPk.Variations;
|
||||
var newContentTypeVariation = entity.Variations;
|
||||
var contentTypeVariationChanging = contentTypeVariationDirty && oldContentTypeVariation != newContentTypeVariation;
|
||||
if (contentTypeVariationChanging)
|
||||
@@ -449,7 +455,7 @@ AND umbracoNode.id <> @id",
|
||||
// via composition, with their original variations (ie not filtered by this
|
||||
// content type variations - we need this true value to make decisions.
|
||||
|
||||
foreach (var propertyType in ((ContentTypeCompositionBase) entity).RawComposedPropertyTypes)
|
||||
foreach (var propertyType in ((ContentTypeCompositionBase)entity).RawComposedPropertyTypes)
|
||||
{
|
||||
if (propertyType.VariesBySegment() || newContentTypeVariation.VariesBySegment())
|
||||
throw new NotSupportedException(); // TODO: support this
|
||||
@@ -518,6 +524,25 @@ AND umbracoNode.id <> @id",
|
||||
CommonRepository.ClearCache(); // always
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures that no property types are flagged for a variance that is not supported by the content type itself
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
private void ValidateVariations(IContentTypeComposition entity)
|
||||
{
|
||||
//if the entity does not vary at all, then the property cannot have a variance value greater than it
|
||||
if (entity.Variations == ContentVariation.Nothing)
|
||||
{
|
||||
foreach (var prop in entity.PropertyTypes)
|
||||
{
|
||||
if (prop.IsPropertyDirty(nameof(prop.Variations)) && prop.Variations > entity.Variations)
|
||||
throw new InvalidOperationException($"The property {prop.Alias} cannot have variations of {prop.Variations} with the content type variations of {entity.Variations}");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private IEnumerable<IContentTypeComposition> GetImpactedContentTypes(IContentTypeComposition contentType, IEnumerable<IContentTypeComposition> all)
|
||||
{
|
||||
var impact = new List<IContentTypeComposition>();
|
||||
@@ -525,12 +550,12 @@ AND umbracoNode.id <> @id",
|
||||
|
||||
var tree = new Dictionary<int, List<IContentTypeComposition>>();
|
||||
foreach (var x in all)
|
||||
foreach (var y in x.ContentTypeComposition)
|
||||
{
|
||||
if (!tree.TryGetValue(y.Id, out var list))
|
||||
list = tree[y.Id] = new List<IContentTypeComposition>();
|
||||
list.Add(x);
|
||||
}
|
||||
foreach (var y in x.ContentTypeComposition)
|
||||
{
|
||||
if (!tree.TryGetValue(y.Id, out var list))
|
||||
list = tree[y.Id] = new List<IContentTypeComposition>();
|
||||
list.Add(x);
|
||||
}
|
||||
|
||||
var nset = new List<IContentTypeComposition>();
|
||||
do
|
||||
@@ -572,7 +597,7 @@ AND umbracoNode.id <> @id",
|
||||
// new property type, ignore
|
||||
if (!oldVariations.TryGetValue(propertyType.Id, out var oldVariationB))
|
||||
continue;
|
||||
var oldVariation = (ContentVariation) oldVariationB; // NPoco cannot fetch directly
|
||||
var oldVariation = (ContentVariation)oldVariationB; // NPoco cannot fetch directly
|
||||
|
||||
// only those property types that *actually* changed
|
||||
var newVariation = propertyType.Variations;
|
||||
@@ -636,7 +661,7 @@ AND umbracoNode.id <> @id",
|
||||
var impactedL = impacted.Select(x => x.Id).ToList();
|
||||
|
||||
//Group by the "To" variation so we can bulk update in the correct batches
|
||||
foreach(var grouping in propertyTypeChanges.GroupBy(x => x.Value.ToVariation))
|
||||
foreach (var grouping in propertyTypeChanges.GroupBy(x => x.Value.ToVariation))
|
||||
{
|
||||
var propertyTypeIds = grouping.Select(x => x.Key).ToList();
|
||||
var toVariation = grouping.Key;
|
||||
@@ -646,10 +671,12 @@ AND umbracoNode.id <> @id",
|
||||
case ContentVariation.Culture:
|
||||
CopyPropertyData(null, defaultLanguageId, propertyTypeIds, impactedL);
|
||||
CopyTagData(null, defaultLanguageId, propertyTypeIds, impactedL);
|
||||
RenormalizeDocumentEditedFlags(propertyTypeIds, impactedL);
|
||||
break;
|
||||
case ContentVariation.Nothing:
|
||||
CopyPropertyData(defaultLanguageId, null, propertyTypeIds, impactedL);
|
||||
CopyTagData(defaultLanguageId, null, propertyTypeIds, impactedL);
|
||||
RenormalizeDocumentEditedFlags(propertyTypeIds, impactedL);
|
||||
break;
|
||||
case ContentVariation.CultureAndSegment:
|
||||
case ContentVariation.Segment:
|
||||
@@ -963,6 +990,205 @@ AND umbracoNode.id <> @id",
|
||||
|
||||
Database.Execute(sqlDelete);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Re-normalizes the edited value in the umbracoDocumentCultureVariation and umbracoDocument table when variations are changed
|
||||
/// </summary>
|
||||
/// <param name="propertyTypeIds"></param>
|
||||
/// <param name="contentTypeIds"></param>
|
||||
/// <remarks>
|
||||
/// If this is not done, then in some cases the "edited" value for a particular culture for a document will remain true when it should be false
|
||||
/// if the property was changed to invariant. In order to do this we need to recalculate this value based on the values stored for each
|
||||
/// property, culture and current/published version.
|
||||
/// </remarks>
|
||||
private void RenormalizeDocumentEditedFlags(IReadOnlyCollection<int> propertyTypeIds, IReadOnlyCollection<int> contentTypeIds = null)
|
||||
{
|
||||
var defaultLang = LanguageRepository.GetDefaultId();
|
||||
|
||||
//This will build up a query to get the property values of both the current and the published version so that we can check
|
||||
//based on the current variance of each item to see if it's 'edited' value should be true/false.
|
||||
|
||||
var whereInArgsCount = propertyTypeIds.Count + (contentTypeIds?.Count ?? 0);
|
||||
if (whereInArgsCount > 2000)
|
||||
throw new NotSupportedException("Too many property/content types.");
|
||||
|
||||
var propertySql = Sql()
|
||||
.Select<PropertyDataDto>()
|
||||
.AndSelect<ContentVersionDto>(x => x.NodeId, x => x.Current)
|
||||
.AndSelect<DocumentVersionDto>(x => x.Published)
|
||||
.AndSelect<PropertyTypeDto>(x => x.Variations)
|
||||
.From<PropertyDataDto>()
|
||||
.InnerJoin<ContentVersionDto>().On<ContentVersionDto, PropertyDataDto>((left, right) => left.Id == right.VersionId)
|
||||
.InnerJoin<PropertyTypeDto>().On<PropertyTypeDto, PropertyDataDto>((left, right) => left.Id == right.PropertyTypeId);
|
||||
|
||||
if (contentTypeIds != null)
|
||||
{
|
||||
propertySql.InnerJoin<ContentDto>().On<ContentDto, ContentVersionDto>((c, cversion) => c.NodeId == cversion.NodeId);
|
||||
}
|
||||
|
||||
propertySql.LeftJoin<DocumentVersionDto>().On<DocumentVersionDto, ContentVersionDto>((docversion, cversion) => cversion.Id == docversion.Id)
|
||||
.Where<DocumentVersionDto, ContentVersionDto>((docversion, cversion) => cversion.Current || docversion.Published)
|
||||
.WhereIn<PropertyDataDto>(x => x.PropertyTypeId, propertyTypeIds);
|
||||
|
||||
if (contentTypeIds != null)
|
||||
{
|
||||
propertySql.WhereIn<ContentDto>(x => x.ContentTypeId, contentTypeIds);
|
||||
}
|
||||
|
||||
propertySql
|
||||
.OrderBy<ContentVersionDto>(x => x.NodeId)
|
||||
.OrderBy<PropertyDataDto>(x => x.PropertyTypeId, x => x.LanguageId, x => x.VersionId);
|
||||
|
||||
//keep track of this node/lang to mark or unmark a culture as edited
|
||||
var editedLanguageVersions = new Dictionary<(int nodeId, int? langId), bool>();
|
||||
//keep track of which node to mark or unmark as edited
|
||||
var editedDocument = new Dictionary<int, bool>();
|
||||
var nodeId = -1;
|
||||
var propertyTypeId = -1;
|
||||
|
||||
PropertyValueVersionDto pubRow = null;
|
||||
|
||||
//This is a reader (Query), we are not fetching this all into memory so we cannot make any changes during this iteration, we are just collecting data.
|
||||
//Published data will always come before Current data based on the version id sort.
|
||||
//There will only be one published row (max) and one current row per property.
|
||||
foreach (var row in Database.Query<PropertyValueVersionDto>(propertySql))
|
||||
{
|
||||
//make sure to reset on each node/property change
|
||||
if (nodeId != row.NodeId || propertyTypeId != row.PropertyTypeId)
|
||||
{
|
||||
nodeId = row.NodeId;
|
||||
propertyTypeId = row.PropertyTypeId;
|
||||
pubRow = null;
|
||||
}
|
||||
|
||||
if (row.Published)
|
||||
pubRow = row;
|
||||
|
||||
if (row.Current)
|
||||
{
|
||||
var propVariations = (ContentVariation)row.Variations;
|
||||
|
||||
//if this prop doesn't vary but the row has a lang assigned or vice versa, flag this as not edited
|
||||
if (!propVariations.VariesByCulture() && row.LanguageId.HasValue
|
||||
|| propVariations.VariesByCulture() && !row.LanguageId.HasValue)
|
||||
{
|
||||
//Flag this as not edited for this node/lang if the key doesn't exist
|
||||
if (!editedLanguageVersions.TryGetValue((row.NodeId, row.LanguageId), out _))
|
||||
editedLanguageVersions.Add((row.NodeId, row.LanguageId), false);
|
||||
|
||||
//mark as false if the item doesn't exist, else coerce to true
|
||||
editedDocument[row.NodeId] = editedDocument.TryGetValue(row.NodeId, out var edited) ? (edited |= false) : false;
|
||||
}
|
||||
else if (pubRow == null)
|
||||
{
|
||||
//this would mean that that this property is 'edited' since there is no published version
|
||||
editedLanguageVersions[(row.NodeId, row.LanguageId)] = true;
|
||||
editedDocument[row.NodeId] = true;
|
||||
}
|
||||
//compare the property values, if they differ from versions then flag the current version as edited
|
||||
else if (IsPropertyValueChanged(pubRow, row))
|
||||
{
|
||||
//Here we would check if the property is invariant, in which case the edited language should be indicated by the default lang
|
||||
editedLanguageVersions[(row.NodeId, !propVariations.VariesByCulture() ? defaultLang : row.LanguageId)] = true;
|
||||
editedDocument[row.NodeId] = true;
|
||||
}
|
||||
|
||||
//reset
|
||||
pubRow = null;
|
||||
}
|
||||
}
|
||||
|
||||
//lookup all matching rows in umbracoDocumentCultureVariation
|
||||
var docCultureVariationsToUpdate = editedLanguageVersions.InGroupsOf(2000)
|
||||
.SelectMany(_ => Database.Fetch<DocumentCultureVariationDto>(
|
||||
Sql().Select<DocumentCultureVariationDto>().From<DocumentCultureVariationDto>()
|
||||
.WhereIn<DocumentCultureVariationDto>(x => x.LanguageId, editedLanguageVersions.Keys.Select(x => x.langId).ToList())
|
||||
.WhereIn<DocumentCultureVariationDto>(x => x.NodeId, editedLanguageVersions.Keys.Select(x => x.nodeId))))
|
||||
//convert to dictionary with the same key type
|
||||
.ToDictionary(x => (x.NodeId, (int?)x.LanguageId), x => x);
|
||||
|
||||
var toUpdate = new List<DocumentCultureVariationDto>();
|
||||
foreach (var ev in editedLanguageVersions)
|
||||
{
|
||||
if (docCultureVariationsToUpdate.TryGetValue(ev.Key, out var docVariations))
|
||||
{
|
||||
//check if it needs updating
|
||||
if (docVariations.Edited != ev.Value)
|
||||
{
|
||||
docVariations.Edited = ev.Value;
|
||||
toUpdate.Add(docVariations);
|
||||
}
|
||||
}
|
||||
else if (ev.Key.langId.HasValue)
|
||||
{
|
||||
//This should never happen! If a property culture is flagged as edited then the culture must exist at the document level
|
||||
throw new PanicException($"The existing DocumentCultureVariationDto was not found for node {ev.Key.nodeId} and language {ev.Key.langId}");
|
||||
}
|
||||
}
|
||||
|
||||
//Now bulk update the table DocumentCultureVariationDto, once for edited = true, another for edited = false
|
||||
foreach (var editValue in toUpdate.GroupBy(x => x.Edited))
|
||||
{
|
||||
Database.Execute(Sql().Update<DocumentCultureVariationDto>(u => u.Set(x => x.Edited, editValue.Key))
|
||||
.WhereIn<DocumentCultureVariationDto>(x => x.Id, editValue.Select(x => x.Id)));
|
||||
}
|
||||
|
||||
//Now bulk update the umbracoDocument table
|
||||
foreach (var editValue in editedDocument.GroupBy(x => x.Value))
|
||||
{
|
||||
Database.Execute(Sql().Update<DocumentDto>(u => u.Set(x => x.Edited, editValue.Key))
|
||||
.WhereIn<DocumentDto>(x => x.NodeId, editValue.Select(x => x.Key)));
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsPropertyValueChanged(PropertyValueVersionDto pubRow, PropertyValueVersionDto row)
|
||||
{
|
||||
return !pubRow.TextValue.IsNullOrWhiteSpace() && pubRow.TextValue != row.TextValue
|
||||
|| !pubRow.VarcharValue.IsNullOrWhiteSpace() && pubRow.VarcharValue != row.VarcharValue
|
||||
|| pubRow.DateValue.HasValue && pubRow.DateValue != row.DateValue
|
||||
|| pubRow.DecimalValue.HasValue && pubRow.DecimalValue != row.DecimalValue
|
||||
|| pubRow.IntValue.HasValue && pubRow.IntValue != row.IntValue;
|
||||
}
|
||||
|
||||
private class NameCompareDto
|
||||
{
|
||||
public int NodeId { get; set; }
|
||||
public int CurrentVersion { get; set; }
|
||||
public int LanguageId { get; set; }
|
||||
public string CurrentName { get; set; }
|
||||
public string PublishedName { get; set; }
|
||||
public int? PublishedVersion { get; set; }
|
||||
public int Id { get; set; } // the Id of the DocumentCultureVariationDto
|
||||
public bool Edited { get; set; }
|
||||
}
|
||||
|
||||
private class PropertyValueVersionDto
|
||||
{
|
||||
public int VersionId { get; set; }
|
||||
public int PropertyTypeId { get; set; }
|
||||
public int? LanguageId { get; set; }
|
||||
public string Segment { get; set; }
|
||||
public int? IntValue { get; set; }
|
||||
|
||||
private decimal? _decimalValue;
|
||||
[Column("decimalValue")]
|
||||
public decimal? DecimalValue
|
||||
{
|
||||
get => _decimalValue;
|
||||
set => _decimalValue = value?.Normalize();
|
||||
}
|
||||
|
||||
public DateTime? DateValue { get; set; }
|
||||
public string VarcharValue { get; set; }
|
||||
public string TextValue { get; set; }
|
||||
|
||||
public int NodeId { get; set; }
|
||||
public bool Current { get; set; }
|
||||
public bool Published { get; set; }
|
||||
|
||||
public byte Variations { get; set; }
|
||||
}
|
||||
|
||||
private void DeletePropertyType(int contentTypeId, int propertyTypeId)
|
||||
@@ -1013,8 +1239,9 @@ AND umbracoNode.id <> @id",
|
||||
if (propertyType.PropertyEditorAlias.IsNullOrWhiteSpace() == false)
|
||||
{
|
||||
var sql = Sql()
|
||||
.SelectAll()
|
||||
.Select<DataTypeDto>(dt => dt.Select(x => x.NodeDto))
|
||||
.From<DataTypeDto>()
|
||||
.InnerJoin<NodeDto>().On<DataTypeDto, NodeDto>((dt, n) => dt.NodeId == n.NodeId)
|
||||
.Where("propertyEditorAlias = @propertyEditorAlias", new { propertyEditorAlias = propertyType.PropertyEditorAlias })
|
||||
.OrderBy<DataTypeDto>(typeDto => typeDto.NodeId);
|
||||
var datatype = Database.FirstOrDefault<DataTypeDto>(sql);
|
||||
@@ -1022,6 +1249,7 @@ AND umbracoNode.id <> @id",
|
||||
if (datatype != null)
|
||||
{
|
||||
propertyType.DataTypeId = datatype.NodeId;
|
||||
propertyType.DataTypeKey = datatype.NodeDto.UniqueId;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -9,6 +9,7 @@ using Umbraco.Core.Events;
|
||||
using Umbraco.Core.Exceptions;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Entities;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
using Umbraco.Core.Persistence.Factories;
|
||||
using Umbraco.Core.Persistence.Querying;
|
||||
@@ -106,7 +107,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
|
||||
protected override void PersistNewItem(IDataType entity)
|
||||
{
|
||||
((DataType)entity).AddingEntity();
|
||||
entity.AddingEntity();
|
||||
|
||||
//ensure a datatype has a unique name before creating it
|
||||
entity.Name = EnsureUniqueNodeName(entity.Name);
|
||||
@@ -174,7 +175,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
}
|
||||
|
||||
//Updates Modified date
|
||||
((DataType)entity).UpdatingEntity();
|
||||
entity.UpdatingEntity();
|
||||
|
||||
//Look up parent to get and set the correct Path if ParentId has changed
|
||||
if (entity.IsPropertyDirty("ParentId"))
|
||||
|
||||
@@ -148,7 +148,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
|
||||
protected override void PersistUpdatedItem(IDictionaryItem entity)
|
||||
{
|
||||
((EntityBase)entity).UpdatingEntity();
|
||||
entity.UpdatingEntity();
|
||||
|
||||
foreach (var translation in entity.Translations)
|
||||
translation.Value = translation.Value.ToValidXmlString();
|
||||
|
||||
@@ -6,6 +6,7 @@ using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Exceptions;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Entities;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
using Umbraco.Core.Persistence.Factories;
|
||||
@@ -205,7 +206,10 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
"DELETE FROM " + Constants.DatabaseSchema.Tables.ContentVersionCultureVariation + " WHERE versionId IN (SELECT id FROM " + Constants.DatabaseSchema.Tables.ContentVersion + " WHERE nodeId = @id)",
|
||||
"DELETE FROM " + Constants.DatabaseSchema.Tables.ContentVersion + " WHERE nodeId = @id",
|
||||
"DELETE FROM " + Constants.DatabaseSchema.Tables.Content + " WHERE nodeId = @id",
|
||||
"DELETE FROM " + Constants.DatabaseSchema.Tables.AccessRule + " WHERE accessId IN (SELECT id FROM " + Constants.DatabaseSchema.Tables.Access + " WHERE nodeId = @id OR loginNodeId = @id OR noAccessNodeId = @id)",
|
||||
"DELETE FROM " + Constants.DatabaseSchema.Tables.Access + " WHERE nodeId = @id",
|
||||
"DELETE FROM " + Constants.DatabaseSchema.Tables.Access + " WHERE loginNodeId = @id",
|
||||
"DELETE FROM " + Constants.DatabaseSchema.Tables.Access + " WHERE noAccessNodeId = @id",
|
||||
"DELETE FROM " + Constants.DatabaseSchema.Tables.Node + " WHERE id = @id"
|
||||
};
|
||||
return list;
|
||||
@@ -260,21 +264,16 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
|
||||
protected override void PersistNewItem(IContent entity)
|
||||
{
|
||||
// TODO: https://github.com/umbraco/Umbraco-CMS/issues/4234 - sort out IContent vs Content
|
||||
// however, it's not just so we have access to AddingEntity
|
||||
// there are tons of things at the end of the methods, that can only work with a true Content
|
||||
// and basically, the repository requires a Content, not an IContent
|
||||
var content = (Content)entity;
|
||||
entity.AddingEntity();
|
||||
|
||||
content.AddingEntity();
|
||||
var publishing = content.PublishedState == PublishedState.Publishing;
|
||||
var publishing = entity.PublishedState == PublishedState.Publishing;
|
||||
|
||||
// ensure that the default template is assigned
|
||||
if (entity.TemplateId.HasValue == false)
|
||||
entity.TemplateId = entity.ContentType.DefaultTemplate?.Id;
|
||||
|
||||
// sanitize names
|
||||
SanitizeNames(content, publishing);
|
||||
SanitizeNames(entity, publishing);
|
||||
|
||||
// ensure that strings don't contain characters that are invalid in xml
|
||||
// TODO: do we really want to keep doing this here?
|
||||
@@ -324,11 +323,11 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
contentVersionDto.NodeId = nodeDto.NodeId;
|
||||
contentVersionDto.Current = !publishing;
|
||||
Database.Insert(contentVersionDto);
|
||||
content.VersionId = contentVersionDto.Id;
|
||||
entity.VersionId = contentVersionDto.Id;
|
||||
|
||||
// persist the document version dto
|
||||
var documentVersionDto = dto.DocumentVersionDto;
|
||||
documentVersionDto.Id = content.VersionId;
|
||||
documentVersionDto.Id = entity.VersionId;
|
||||
if (publishing)
|
||||
documentVersionDto.Published = true;
|
||||
Database.Insert(documentVersionDto);
|
||||
@@ -336,62 +335,62 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
// and again in case we're publishing immediately
|
||||
if (publishing)
|
||||
{
|
||||
content.PublishedVersionId = content.VersionId;
|
||||
entity.PublishedVersionId = entity.VersionId;
|
||||
contentVersionDto.Id = 0;
|
||||
contentVersionDto.Current = true;
|
||||
contentVersionDto.Text = content.Name;
|
||||
contentVersionDto.Text = entity.Name;
|
||||
Database.Insert(contentVersionDto);
|
||||
content.VersionId = contentVersionDto.Id;
|
||||
entity.VersionId = contentVersionDto.Id;
|
||||
|
||||
documentVersionDto.Id = content.VersionId;
|
||||
documentVersionDto.Id = entity.VersionId;
|
||||
documentVersionDto.Published = false;
|
||||
Database.Insert(documentVersionDto);
|
||||
}
|
||||
|
||||
// persist the property data
|
||||
var propertyDataDtos = PropertyFactory.BuildDtos(content.ContentType.Variations, content.VersionId, content.PublishedVersionId, entity.Properties, LanguageRepository, out var edited, out var editedCultures);
|
||||
var propertyDataDtos = PropertyFactory.BuildDtos(entity.ContentType.Variations, entity.VersionId, entity.PublishedVersionId, entity.Properties, LanguageRepository, out var edited, out var editedCultures);
|
||||
foreach (var propertyDataDto in propertyDataDtos)
|
||||
Database.Insert(propertyDataDto);
|
||||
|
||||
// if !publishing, we may have a new name != current publish name,
|
||||
// also impacts 'edited'
|
||||
if (!publishing && content.PublishName != content.Name)
|
||||
if (!publishing && entity.PublishName != entity.Name)
|
||||
edited = true;
|
||||
|
||||
// persist the document dto
|
||||
// at that point, when publishing, the entity still has its old Published value
|
||||
// so we need to explicitly update the dto to persist the correct value
|
||||
if (content.PublishedState == PublishedState.Publishing)
|
||||
if (entity.PublishedState == PublishedState.Publishing)
|
||||
dto.Published = true;
|
||||
dto.NodeId = nodeDto.NodeId;
|
||||
content.Edited = dto.Edited = !dto.Published || edited; // if not published, always edited
|
||||
entity.Edited = dto.Edited = !dto.Published || edited; // if not published, always edited
|
||||
Database.Insert(dto);
|
||||
|
||||
//insert the schedule
|
||||
PersistContentSchedule(content, false);
|
||||
PersistContentSchedule(entity, false);
|
||||
|
||||
// persist the variations
|
||||
if (content.ContentType.VariesByCulture())
|
||||
if (entity.ContentType.VariesByCulture())
|
||||
{
|
||||
// bump dates to align cultures to version
|
||||
if (publishing)
|
||||
content.AdjustDates(contentVersionDto.VersionDate);
|
||||
entity.AdjustDates(contentVersionDto.VersionDate);
|
||||
|
||||
// names also impact 'edited'
|
||||
// ReSharper disable once UseDeconstruction
|
||||
foreach (var cultureInfo in content.CultureInfos)
|
||||
if (cultureInfo.Name != content.GetPublishName(cultureInfo.Culture))
|
||||
foreach (var cultureInfo in entity.CultureInfos)
|
||||
if (cultureInfo.Name != entity.GetPublishName(cultureInfo.Culture))
|
||||
(editedCultures ?? (editedCultures = new HashSet<string>(StringComparer.OrdinalIgnoreCase))).Add(cultureInfo.Culture);
|
||||
|
||||
// insert content variations
|
||||
Database.BulkInsertRecords(GetContentVariationDtos(content, publishing));
|
||||
Database.BulkInsertRecords(GetContentVariationDtos(entity, publishing));
|
||||
|
||||
// insert document variations
|
||||
Database.BulkInsertRecords(GetDocumentVariationDtos(content, publishing, editedCultures));
|
||||
Database.BulkInsertRecords(GetDocumentVariationDtos(entity, editedCultures));
|
||||
}
|
||||
|
||||
// refresh content
|
||||
content.SetCultureEdited(editedCultures);
|
||||
entity.SetCultureEdited(editedCultures);
|
||||
|
||||
// trigger here, before we reset Published etc
|
||||
OnUowRefreshedEntity(new ScopedEntityEventArgs(AmbientScope, entity));
|
||||
@@ -399,23 +398,23 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
// flip the entity's published property
|
||||
// this also flips its published state
|
||||
// note: what depends on variations (eg PublishNames) is managed directly by the content
|
||||
if (content.PublishedState == PublishedState.Publishing)
|
||||
if (entity.PublishedState == PublishedState.Publishing)
|
||||
{
|
||||
content.Published = true;
|
||||
content.PublishTemplateId = content.TemplateId;
|
||||
content.PublisherId = content.WriterId;
|
||||
content.PublishName = content.Name;
|
||||
content.PublishDate = content.UpdateDate;
|
||||
entity.Published = true;
|
||||
entity.PublishTemplateId = entity.TemplateId;
|
||||
entity.PublisherId = entity.WriterId;
|
||||
entity.PublishName = entity.Name;
|
||||
entity.PublishDate = entity.UpdateDate;
|
||||
|
||||
SetEntityTags(entity, _tagRepository);
|
||||
}
|
||||
else if (content.PublishedState == PublishedState.Unpublishing)
|
||||
else if (entity.PublishedState == PublishedState.Unpublishing)
|
||||
{
|
||||
content.Published = false;
|
||||
content.PublishTemplateId = null;
|
||||
content.PublisherId = null;
|
||||
content.PublishName = null;
|
||||
content.PublishDate = null;
|
||||
entity.Published = false;
|
||||
entity.PublishTemplateId = null;
|
||||
entity.PublisherId = null;
|
||||
entity.PublishName = null;
|
||||
entity.PublishDate = null;
|
||||
|
||||
ClearEntityTags(entity, _tagRepository);
|
||||
}
|
||||
@@ -437,34 +436,33 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
|
||||
protected override void PersistUpdatedItem(IContent entity)
|
||||
{
|
||||
// however, it's not just so we have access to AddingEntity
|
||||
// there are tons of things at the end of the methods, that can only work with a true Content
|
||||
// and basically, the repository requires a Content, not an IContent
|
||||
var content = (Content)entity;
|
||||
var entityBase = entity as EntityBase;
|
||||
var isEntityDirty = entityBase != null && entityBase.IsDirty();
|
||||
|
||||
// check if we need to make any database changes at all
|
||||
if ((content.PublishedState == PublishedState.Published || content.PublishedState == PublishedState.Unpublished)
|
||||
&& !content.IsEntityDirty() && !content.IsAnyUserPropertyDirty())
|
||||
if ((entity.PublishedState == PublishedState.Published || entity.PublishedState == PublishedState.Unpublished)
|
||||
&& !isEntityDirty && !entity.IsAnyUserPropertyDirty())
|
||||
return; // no change to save, do nothing, don't even update dates
|
||||
|
||||
// whatever we do, we must check that we are saving the current version
|
||||
var version = Database.Fetch<ContentVersionDto>(SqlContext.Sql().Select<ContentVersionDto>().From<ContentVersionDto>().Where<ContentVersionDto>(x => x.Id == content.VersionId)).FirstOrDefault();
|
||||
var version = Database.Fetch<ContentVersionDto>(SqlContext.Sql().Select<ContentVersionDto>().From<ContentVersionDto>().Where<ContentVersionDto>(x => x.Id == entity.VersionId)).FirstOrDefault();
|
||||
if (version == null || !version.Current)
|
||||
throw new InvalidOperationException("Cannot save a non-current version.");
|
||||
|
||||
// update
|
||||
content.UpdatingEntity();
|
||||
var publishing = content.PublishedState == PublishedState.Publishing;
|
||||
entity.UpdatingEntity();
|
||||
|
||||
var publishing = entity.PublishedState == PublishedState.Publishing;
|
||||
|
||||
// check if we need to create a new version
|
||||
if (publishing && content.PublishedVersionId > 0)
|
||||
if (publishing && entity.PublishedVersionId > 0)
|
||||
{
|
||||
// published version is not published anymore
|
||||
Database.Execute(Sql().Update<DocumentVersionDto>(u => u.Set(x => x.Published, false)).Where<DocumentVersionDto>(x => x.Id == content.PublishedVersionId));
|
||||
Database.Execute(Sql().Update<DocumentVersionDto>(u => u.Set(x => x.Published, false)).Where<DocumentVersionDto>(x => x.Id == entity.PublishedVersionId));
|
||||
}
|
||||
|
||||
// sanitize names
|
||||
SanitizeNames(content, publishing);
|
||||
SanitizeNames(entity, publishing);
|
||||
|
||||
// ensure that strings don't contain characters that are invalid in xml
|
||||
// TODO: do we really want to keep doing this here?
|
||||
@@ -504,45 +502,45 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
// and, if publishing, insert new content & document version dtos
|
||||
if (publishing)
|
||||
{
|
||||
content.PublishedVersionId = content.VersionId;
|
||||
entity.PublishedVersionId = entity.VersionId;
|
||||
|
||||
contentVersionDto.Id = 0; // want a new id
|
||||
contentVersionDto.Current = true; // current version
|
||||
contentVersionDto.Text = content.Name;
|
||||
contentVersionDto.Text = entity.Name;
|
||||
Database.Insert(contentVersionDto);
|
||||
content.VersionId = documentVersionDto.Id = contentVersionDto.Id; // get the new id
|
||||
entity.VersionId = documentVersionDto.Id = contentVersionDto.Id; // get the new id
|
||||
|
||||
documentVersionDto.Published = false; // non-published version
|
||||
Database.Insert(documentVersionDto);
|
||||
Database.Insert(documentVersionDto);
|
||||
}
|
||||
|
||||
// replace the property data (rather than updating)
|
||||
// only need to delete for the version that existed, the new version (if any) has no property data yet
|
||||
var versionToDelete = publishing ? content.PublishedVersionId : content.VersionId;
|
||||
var versionToDelete = publishing ? entity.PublishedVersionId : entity.VersionId;
|
||||
var deletePropertyDataSql = Sql().Delete<PropertyDataDto>().Where<PropertyDataDto>(x => x.VersionId == versionToDelete);
|
||||
Database.Execute(deletePropertyDataSql);
|
||||
|
||||
// insert property data
|
||||
var propertyDataDtos = PropertyFactory.BuildDtos(content.ContentType.Variations, content.VersionId, publishing ? content.PublishedVersionId : 0,
|
||||
var propertyDataDtos = PropertyFactory.BuildDtos(entity.ContentType.Variations, entity.VersionId, publishing ? entity.PublishedVersionId : 0,
|
||||
entity.Properties, LanguageRepository, out var edited, out var editedCultures);
|
||||
foreach (var propertyDataDto in propertyDataDtos)
|
||||
Database.Insert(propertyDataDto);
|
||||
|
||||
// if !publishing, we may have a new name != current publish name,
|
||||
// also impacts 'edited'
|
||||
if (!publishing && content.PublishName != content.Name)
|
||||
if (!publishing && entity.PublishName != entity.Name)
|
||||
edited = true;
|
||||
|
||||
if (content.ContentType.VariesByCulture())
|
||||
if (entity.ContentType.VariesByCulture())
|
||||
{
|
||||
// bump dates to align cultures to version
|
||||
if (publishing)
|
||||
content.AdjustDates(contentVersionDto.VersionDate);
|
||||
entity.AdjustDates(contentVersionDto.VersionDate);
|
||||
|
||||
// names also impact 'edited'
|
||||
// ReSharper disable once UseDeconstruction
|
||||
foreach (var cultureInfo in content.CultureInfos)
|
||||
if (cultureInfo.Name != content.GetPublishName(cultureInfo.Culture))
|
||||
foreach (var cultureInfo in entity.CultureInfos)
|
||||
if (cultureInfo.Name != entity.GetPublishName(cultureInfo.Culture))
|
||||
{
|
||||
edited = true;
|
||||
(editedCultures ?? (editedCultures = new HashSet<string>(StringComparer.OrdinalIgnoreCase))).Add(cultureInfo.Culture);
|
||||
@@ -560,7 +558,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
Database.Execute(deleteContentVariations);
|
||||
|
||||
// replace the document version variations (rather than updating)
|
||||
var deleteDocumentVariations = Sql().Delete<DocumentCultureVariationDto>().Where<DocumentCultureVariationDto>(x => x.NodeId == content.Id);
|
||||
var deleteDocumentVariations = Sql().Delete<DocumentCultureVariationDto>().Where<DocumentCultureVariationDto>(x => x.NodeId == entity.Id);
|
||||
Database.Execute(deleteDocumentVariations);
|
||||
|
||||
// TODO: NPoco InsertBulk issue?
|
||||
@@ -570,32 +568,32 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
// (same in PersistNewItem above)
|
||||
|
||||
// insert content variations
|
||||
Database.BulkInsertRecords(GetContentVariationDtos(content, publishing));
|
||||
Database.BulkInsertRecords(GetContentVariationDtos(entity, publishing));
|
||||
|
||||
// insert document variations
|
||||
Database.BulkInsertRecords(GetDocumentVariationDtos(content, publishing, editedCultures));
|
||||
Database.BulkInsertRecords(GetDocumentVariationDtos(entity, editedCultures));
|
||||
}
|
||||
|
||||
// refresh content
|
||||
content.SetCultureEdited(editedCultures);
|
||||
entity.SetCultureEdited(editedCultures);
|
||||
|
||||
// update the document dto
|
||||
// at that point, when un/publishing, the entity still has its old Published value
|
||||
// so we need to explicitly update the dto to persist the correct value
|
||||
if (content.PublishedState == PublishedState.Publishing)
|
||||
if (entity.PublishedState == PublishedState.Publishing)
|
||||
dto.Published = true;
|
||||
else if (content.PublishedState == PublishedState.Unpublishing)
|
||||
else if (entity.PublishedState == PublishedState.Unpublishing)
|
||||
dto.Published = false;
|
||||
content.Edited = dto.Edited = !dto.Published || edited; // if not published, always edited
|
||||
entity.Edited = dto.Edited = !dto.Published || edited; // if not published, always edited
|
||||
Database.Update(dto);
|
||||
|
||||
//update the schedule
|
||||
if (content.IsPropertyDirty("ContentSchedule"))
|
||||
PersistContentSchedule(content, true);
|
||||
if (entity.IsPropertyDirty("ContentSchedule"))
|
||||
PersistContentSchedule(entity, true);
|
||||
|
||||
// if entity is publishing, update tags, else leave tags there
|
||||
// means that implicitly unpublished, or trashed, entities *still* have tags in db
|
||||
if (content.PublishedState == PublishedState.Publishing)
|
||||
if (entity.PublishedState == PublishedState.Publishing)
|
||||
SetEntityTags(entity, _tagRepository);
|
||||
|
||||
// trigger here, before we reset Published etc
|
||||
@@ -603,23 +601,23 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
|
||||
// flip the entity's published property
|
||||
// this also flips its published state
|
||||
if (content.PublishedState == PublishedState.Publishing)
|
||||
if (entity.PublishedState == PublishedState.Publishing)
|
||||
{
|
||||
content.Published = true;
|
||||
content.PublishTemplateId = content.TemplateId;
|
||||
content.PublisherId = content.WriterId;
|
||||
content.PublishName = content.Name;
|
||||
content.PublishDate = content.UpdateDate;
|
||||
entity.Published = true;
|
||||
entity.PublishTemplateId = entity.TemplateId;
|
||||
entity.PublisherId = entity.WriterId;
|
||||
entity.PublishName = entity.Name;
|
||||
entity.PublishDate = entity.UpdateDate;
|
||||
|
||||
SetEntityTags(entity, _tagRepository);
|
||||
}
|
||||
else if (content.PublishedState == PublishedState.Unpublishing)
|
||||
else if (entity.PublishedState == PublishedState.Unpublishing)
|
||||
{
|
||||
content.Published = false;
|
||||
content.PublishTemplateId = null;
|
||||
content.PublisherId = null;
|
||||
content.PublishName = null;
|
||||
content.PublishDate = null;
|
||||
entity.Published = false;
|
||||
entity.PublishTemplateId = null;
|
||||
entity.PublisherId = null;
|
||||
entity.PublishName = null;
|
||||
entity.PublishDate = null;
|
||||
|
||||
ClearEntityTags(entity, _tagRepository);
|
||||
}
|
||||
@@ -1299,25 +1297,28 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
};
|
||||
}
|
||||
|
||||
private IEnumerable<DocumentCultureVariationDto> GetDocumentVariationDtos(IContent content, bool publishing, HashSet<string> editedCultures)
|
||||
private IEnumerable<DocumentCultureVariationDto> GetDocumentVariationDtos(IContent content, HashSet<string> editedCultures)
|
||||
{
|
||||
var allCultures = content.AvailableCultures.Union(content.PublishedCultures); // union = distinct
|
||||
foreach (var culture in allCultures)
|
||||
yield return new DocumentCultureVariationDto
|
||||
{
|
||||
var dto = new DocumentCultureVariationDto
|
||||
{
|
||||
NodeId = content.Id,
|
||||
LanguageId = LanguageRepository.GetIdByIsoCode(culture) ?? throw new InvalidOperationException("Not a valid culture."),
|
||||
Culture = culture,
|
||||
|
||||
Name = content.GetCultureName(culture) ?? content.GetPublishName(culture),
|
||||
|
||||
// note: can't use IsCultureEdited at that point - hasn't been updated yet - see PersistUpdatedItem
|
||||
|
||||
Available = content.IsCultureAvailable(culture),
|
||||
Published = content.IsCulturePublished(culture),
|
||||
// note: can't use IsCultureEdited at that point - hasn't been updated yet - see PersistUpdatedItem
|
||||
Edited = content.IsCultureAvailable(culture) &&
|
||||
(!content.IsCulturePublished(culture) || (editedCultures != null && editedCultures.Contains(culture)))
|
||||
};
|
||||
|
||||
yield return dto;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class ContentVariation
|
||||
@@ -1335,7 +1336,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
|
||||
#region Utilities
|
||||
|
||||
private void SanitizeNames(Content content, bool publishing)
|
||||
private void SanitizeNames(IContent content, bool publishing)
|
||||
{
|
||||
// a content item *must* have an invariant name, and invariant published name
|
||||
// else we just cannot write the invariant rows (node, content version...) to the database
|
||||
@@ -1400,7 +1401,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
x.NodeId != SqlTemplate.Arg<int>("id"))
|
||||
.OrderBy<ContentVersionCultureVariationDto>(x => x.LanguageId));
|
||||
|
||||
private void EnsureVariantNamesAreUnique(Content content, bool publishing)
|
||||
private void EnsureVariantNamesAreUnique(IContent content, bool publishing)
|
||||
{
|
||||
if (!EnsureUniqueNaming || !content.ContentType.VariesByCulture() || content.CultureInfos.Count == 0) return;
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ using NPoco;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Entities;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
using Umbraco.Core.Persistence.Querying;
|
||||
using Umbraco.Core.Scoping;
|
||||
@@ -101,7 +102,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
if (languageExists == 0) throw new NullReferenceException("No language exists with id " + entity.LanguageId.Value);
|
||||
}
|
||||
|
||||
((UmbracoDomain)entity).AddingEntity();
|
||||
entity.AddingEntity();
|
||||
|
||||
var factory = new DomainModelFactory();
|
||||
var dto = factory.BuildDto(entity);
|
||||
@@ -120,7 +121,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
|
||||
protected override void PersistUpdatedItem(IDomain entity)
|
||||
{
|
||||
((UmbracoDomain)entity).UpdatingEntity();
|
||||
entity.UpdatingEntity();
|
||||
|
||||
var exists = Database.ExecuteScalar<int>("SELECT COUNT(*) FROM umbracoDomain WHERE domainName = @domainName AND umbracoDomain.id <> @id",
|
||||
new { domainName = entity.DomainName, id = entity.Id });
|
||||
|
||||
@@ -75,6 +75,12 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
dtos = page.Items;
|
||||
totalRecords = page.TotalItems;
|
||||
}
|
||||
else if (isMedia)
|
||||
{
|
||||
var page = Database.Page<MediaEntityDto>(pageIndexToFetch, pageSize, sql);
|
||||
dtos = page.Items;
|
||||
totalRecords = page.TotalItems;
|
||||
}
|
||||
else
|
||||
{
|
||||
var page = Database.Page<BaseDto>(pageIndexToFetch, pageSize, sql);
|
||||
@@ -87,10 +93,6 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
if (isContent)
|
||||
BuildVariants(entities.Cast<DocumentEntitySlim>());
|
||||
|
||||
// TODO: see https://github.com/umbraco/Umbraco-CMS/pull/3460#issuecomment-434903930 we need to not load any property data at all for media
|
||||
if (isMedia)
|
||||
BuildProperties(entities, dtos.ToList());
|
||||
|
||||
return entities;
|
||||
}
|
||||
|
||||
@@ -112,14 +114,14 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
return cdtos.Count == 0 ? null : BuildVariants(BuildDocumentEntity(cdtos[0]));
|
||||
}
|
||||
|
||||
var dto = Database.FirstOrDefault<BaseDto>(sql);
|
||||
var dto = isMedia
|
||||
? Database.FirstOrDefault<MediaEntityDto>(sql)
|
||||
: Database.FirstOrDefault<BaseDto>(sql);
|
||||
|
||||
if (dto == null) return null;
|
||||
|
||||
var entity = BuildEntity(false, isMedia, dto);
|
||||
|
||||
if (isMedia)
|
||||
BuildProperties(entity, dto);
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
@@ -162,7 +164,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
: PerformGetAll(objectType);
|
||||
}
|
||||
|
||||
private IEnumerable<IEntitySlim> GetEntities(Sql<ISqlContext> sql, bool isContent, bool isMedia, bool loadMediaProperties)
|
||||
private IEnumerable<IEntitySlim> GetEntities(Sql<ISqlContext> sql, bool isContent, bool isMedia)
|
||||
{
|
||||
//isContent is going to return a 1:M result now with the variants so we need to do different things
|
||||
if (isContent)
|
||||
@@ -174,15 +176,12 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
: BuildVariants(cdtos.Select(BuildDocumentEntity)).ToList();
|
||||
}
|
||||
|
||||
var dtos = Database.Fetch<BaseDto>(sql);
|
||||
if (dtos.Count == 0) return Enumerable.Empty<IEntitySlim>();
|
||||
var dtos = isMedia
|
||||
? (IEnumerable<BaseDto>)Database.Fetch<MediaEntityDto>(sql)
|
||||
: Database.Fetch<BaseDto>(sql);
|
||||
|
||||
var entities = dtos.Select(x => BuildEntity(false, isMedia, x)).ToArray();
|
||||
|
||||
// TODO: See https://github.com/umbraco/Umbraco-CMS/pull/3460#issuecomment-434903930 we need to not load any property data at all for media
|
||||
if (isMedia && loadMediaProperties)
|
||||
BuildProperties(entities, dtos);
|
||||
|
||||
return entities;
|
||||
}
|
||||
|
||||
@@ -192,7 +191,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
var isMedia = objectType == Constants.ObjectTypes.Media;
|
||||
|
||||
var sql = GetFullSqlForEntityType(isContent, isMedia, objectType, filter);
|
||||
return GetEntities(sql, isContent, isMedia, true);
|
||||
return GetEntities(sql, isContent, isMedia);
|
||||
}
|
||||
|
||||
public IEnumerable<TreeEntityPath> GetAllPaths(Guid objectType, params int[] ids)
|
||||
@@ -238,22 +237,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
sql = translator.Translate();
|
||||
sql = AddGroupBy(isContent, isMedia, sql, true);
|
||||
|
||||
return GetEntities(sql, isContent, isMedia, true);
|
||||
}
|
||||
|
||||
// TODO: See https://github.com/umbraco/Umbraco-CMS/pull/3460#issuecomment-434903930 we need to not load any property data at all for media
|
||||
internal IEnumerable<IEntitySlim> GetMediaByQueryWithoutPropertyData(IQuery<IUmbracoEntity> query)
|
||||
{
|
||||
var isContent = false;
|
||||
var isMedia = true;
|
||||
|
||||
var sql = GetBaseWhere(isContent, isMedia, false, null, Constants.ObjectTypes.Media);
|
||||
|
||||
var translator = new SqlTranslator<IUmbracoEntity>(sql, query);
|
||||
sql = translator.Translate();
|
||||
sql = AddGroupBy(isContent, isMedia, sql, true);
|
||||
|
||||
return GetEntities(sql, isContent, isMedia, false);
|
||||
return GetEntities(sql, isContent, isMedia);
|
||||
}
|
||||
|
||||
public UmbracoObjectTypes GetObjectType(int id)
|
||||
@@ -280,41 +264,6 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
return Database.ExecuteScalar<int>(sql) > 0;
|
||||
}
|
||||
|
||||
// TODO: see https://github.com/umbraco/Umbraco-CMS/pull/3460#issuecomment-434903930 we need to not load any property data at all for media
|
||||
private void BuildProperties(EntitySlim entity, BaseDto dto)
|
||||
{
|
||||
var pdtos = Database.Fetch<PropertyDataDto>(GetPropertyData(dto.VersionId));
|
||||
foreach (var pdto in pdtos)
|
||||
BuildProperty(entity, pdto);
|
||||
}
|
||||
|
||||
// TODO: see https://github.com/umbraco/Umbraco-CMS/pull/3460#issuecomment-434903930 we need to not load any property data at all for media
|
||||
private void BuildProperties(EntitySlim[] entities, List<BaseDto> dtos)
|
||||
{
|
||||
var versionIds = dtos.Select(x => x.VersionId).Distinct().ToList();
|
||||
var pdtos = Database.FetchByGroups<PropertyDataDto, int>(versionIds, 2000, GetPropertyData);
|
||||
|
||||
var xentity = entities.ToDictionary(x => x.Id, x => x); // nodeId -> entity
|
||||
var xdto = dtos.ToDictionary(x => x.VersionId, x => x.NodeId); // versionId -> nodeId
|
||||
foreach (var pdto in pdtos)
|
||||
{
|
||||
var nodeId = xdto[pdto.VersionId];
|
||||
var entity = xentity[nodeId];
|
||||
BuildProperty(entity, pdto);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: see https://github.com/umbraco/Umbraco-CMS/pull/3460#issuecomment-434903930 we need to not load any property data at all for media
|
||||
private void BuildProperty(EntitySlim entity, PropertyDataDto pdto)
|
||||
{
|
||||
// explain ?!
|
||||
var value = string.IsNullOrWhiteSpace(pdto.TextValue)
|
||||
? pdto.VarcharValue
|
||||
: pdto.TextValue.ConvertToJsonIfPossible();
|
||||
|
||||
entity.AdditionalData[pdto.PropertyTypeDto.Alias] = new EntitySlim.PropertySlim(pdto.PropertyTypeDto.DataTypeDto.EditorAlias, value);
|
||||
}
|
||||
|
||||
private DocumentEntitySlim BuildVariants(DocumentEntitySlim entity)
|
||||
=> BuildVariants(new[] { entity }).First();
|
||||
|
||||
@@ -400,31 +349,10 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
return AddGroupBy(isContent, isMedia, sql, true);
|
||||
}
|
||||
|
||||
private Sql<ISqlContext> GetPropertyData(int versionId)
|
||||
{
|
||||
return Sql()
|
||||
.Select<PropertyDataDto>(r => r.Select(x => x.PropertyTypeDto, r1 => r1.Select(x => x.DataTypeDto)))
|
||||
.From<PropertyDataDto>()
|
||||
.InnerJoin<PropertyTypeDto>().On<PropertyDataDto, PropertyTypeDto>((left, right) => left.PropertyTypeId == right.Id)
|
||||
.InnerJoin<DataTypeDto>().On<PropertyTypeDto, DataTypeDto>((left, right) => left.DataTypeId == right.NodeId)
|
||||
.Where<PropertyDataDto>(x => x.VersionId == versionId);
|
||||
}
|
||||
|
||||
private Sql<ISqlContext> GetPropertyData(IEnumerable<int> versionIds)
|
||||
{
|
||||
return Sql()
|
||||
.Select<PropertyDataDto>(r => r.Select(x => x.PropertyTypeDto, r1 => r1.Select(x => x.DataTypeDto)))
|
||||
.From<PropertyDataDto>()
|
||||
.InnerJoin<PropertyTypeDto>().On<PropertyDataDto, PropertyTypeDto>((left, right) => left.PropertyTypeId == right.Id)
|
||||
.InnerJoin<DataTypeDto>().On<PropertyTypeDto, DataTypeDto>((left, right) => left.DataTypeId == right.NodeId)
|
||||
.WhereIn<PropertyDataDto>(x => x.VersionId, versionIds)
|
||||
.OrderBy<PropertyDataDto>(x => x.VersionId);
|
||||
}
|
||||
|
||||
// gets the base SELECT + FROM [+ filter] sql
|
||||
// always from the 'current' content version
|
||||
protected Sql<ISqlContext> GetBase(bool isContent, bool isMedia, Action<Sql<ISqlContext>> filter, bool isCount = false)
|
||||
{
|
||||
{
|
||||
var sql = Sql();
|
||||
|
||||
if (isCount)
|
||||
@@ -448,6 +376,12 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
sql
|
||||
.AndSelect<DocumentDto>(x => x.Published, x => x.Edited);
|
||||
}
|
||||
|
||||
if (isMedia)
|
||||
{
|
||||
sql
|
||||
.AndSelect<MediaVersionDto>(x => Alias(x.Path, "MediaPath"));
|
||||
}
|
||||
}
|
||||
|
||||
sql
|
||||
@@ -467,6 +401,12 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
.InnerJoin<DocumentDto>().On<NodeDto, DocumentDto>((left, right) => left.NodeId == right.NodeId);
|
||||
}
|
||||
|
||||
if (isMedia)
|
||||
{
|
||||
sql
|
||||
.InnerJoin<MediaVersionDto>().On<ContentVersionDto, MediaVersionDto>((left, right) => left.Id == right.Id);
|
||||
}
|
||||
|
||||
//Any LeftJoin statements need to come last
|
||||
if (isCount == false)
|
||||
{
|
||||
@@ -536,6 +476,12 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
.AndBy<DocumentDto>(x => x.Published, x => x.Edited);
|
||||
}
|
||||
|
||||
if (isMedia)
|
||||
{
|
||||
sql
|
||||
.AndBy<MediaVersionDto>(x => Alias(x.Path, "MediaPath"));
|
||||
}
|
||||
|
||||
|
||||
if (isContent || isMedia)
|
||||
sql
|
||||
@@ -566,23 +512,6 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
|
||||
#region Classes
|
||||
|
||||
[ExplicitColumns]
|
||||
internal class UmbracoPropertyDto
|
||||
{
|
||||
[Column("propertyEditorAlias")]
|
||||
public string PropertyEditorAlias { get; set; }
|
||||
|
||||
[Column("propertyTypeAlias")]
|
||||
public string PropertyAlias { get; set; }
|
||||
|
||||
[Column("varcharValue")]
|
||||
public string VarcharValue { get; set; }
|
||||
|
||||
[Column("textValue")]
|
||||
public string TextValue { get; set; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The DTO used to fetch results for a content item with its variation info
|
||||
/// </summary>
|
||||
@@ -594,6 +523,11 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
public bool Edited { get; set; }
|
||||
}
|
||||
|
||||
private class MediaEntityDto : BaseDto
|
||||
{
|
||||
public string MediaPath { get; set; }
|
||||
}
|
||||
|
||||
public class VariantInfoDto
|
||||
{
|
||||
public int NodeId { get; set; }
|
||||
@@ -645,7 +579,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
if (isContent)
|
||||
return BuildDocumentEntity(dto);
|
||||
if (isMedia)
|
||||
return BuildContentEntity(dto);
|
||||
return BuildMediaEntity(dto);
|
||||
|
||||
// EntitySlim does not track changes
|
||||
var entity = new EntitySlim();
|
||||
@@ -678,11 +612,18 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
entity.ContentTypeThumbnail = dto.Thumbnail;
|
||||
}
|
||||
|
||||
private static EntitySlim BuildContentEntity(BaseDto dto)
|
||||
private MediaEntitySlim BuildMediaEntity(BaseDto dto)
|
||||
{
|
||||
// EntitySlim does not track changes
|
||||
var entity = new ContentEntitySlim();
|
||||
var entity = new MediaEntitySlim();
|
||||
BuildContentEntity(entity, dto);
|
||||
|
||||
if (dto is MediaEntityDto contentDto)
|
||||
{
|
||||
// fill in the media info
|
||||
entity.MediaPath = contentDto.MediaPath;
|
||||
}
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
|
||||
@@ -139,7 +139,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
|
||||
protected override void PersistNewItem(IIdentityUserLogin entity)
|
||||
{
|
||||
((EntityBase)entity).AddingEntity();
|
||||
entity.AddingEntity();
|
||||
|
||||
var dto = ExternalLoginFactory.BuildDto(entity);
|
||||
|
||||
@@ -151,7 +151,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
|
||||
protected override void PersistUpdatedItem(IIdentityUserLogin entity)
|
||||
{
|
||||
((EntityBase)entity).UpdatingEntity();
|
||||
entity.UpdatingEntity();
|
||||
|
||||
var dto = ExternalLoginFactory.BuildDto(entity);
|
||||
|
||||
|
||||
@@ -129,7 +129,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
if (entity.IsoCode.IsNullOrWhiteSpace() || entity.CultureName.IsNullOrWhiteSpace())
|
||||
throw new InvalidOperationException("Cannot save a language without an ISO code and a culture name.");
|
||||
|
||||
((EntityBase) entity).AddingEntity();
|
||||
entity.AddingEntity();
|
||||
|
||||
// deal with entity becoming the new default entity
|
||||
if (entity.IsDefault)
|
||||
@@ -156,7 +156,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
if (entity.IsoCode.IsNullOrWhiteSpace() || entity.CultureName.IsNullOrWhiteSpace())
|
||||
throw new InvalidOperationException("Cannot save a language without an ISO code and a culture name.");
|
||||
|
||||
((EntityBase) entity).UpdatingEntity();
|
||||
entity.UpdatingEntity();
|
||||
|
||||
if (entity.IsDefault)
|
||||
{
|
||||
|
||||
@@ -132,7 +132,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
|
||||
protected override void PersistNewItem(IMacro entity)
|
||||
{
|
||||
((EntityBase)entity).AddingEntity();
|
||||
entity.AddingEntity();
|
||||
|
||||
var dto = MacroFactory.BuildDto(entity);
|
||||
|
||||
@@ -152,7 +152,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
|
||||
protected override void PersistUpdatedItem(IMacro entity)
|
||||
{
|
||||
((EntityBase)entity).UpdatingEntity();
|
||||
entity.UpdatingEntity();
|
||||
;
|
||||
var dto = MacroFactory.BuildDto(entity);
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
using Umbraco.Core.Exceptions;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Entities;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
using Umbraco.Core.Persistence.Factories;
|
||||
using Umbraco.Core.Persistence.Querying;
|
||||
@@ -217,7 +218,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
protected override void PersistNewItem(IMedia entity)
|
||||
{
|
||||
var media = (Models.Media) entity;
|
||||
media.AddingEntity();
|
||||
entity.AddingEntity();
|
||||
|
||||
// ensure unique name on the same level
|
||||
entity.Name = EnsureUniqueNodeName(entity.ParentId, entity.Name);
|
||||
|
||||
@@ -3,8 +3,10 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NPoco;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Exceptions;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Entities;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
using Umbraco.Core.Persistence.Querying;
|
||||
using Umbraco.Core.Scoping;
|
||||
@@ -16,8 +18,8 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
/// </summary>
|
||||
internal class MediaTypeRepository : ContentTypeRepositoryBase<IMediaType>, IMediaTypeRepository
|
||||
{
|
||||
public MediaTypeRepository(IScopeAccessor scopeAccessor, AppCaches cache, ILogger logger, IContentTypeCommonRepository commonRepository)
|
||||
: base(scopeAccessor, cache, logger, commonRepository)
|
||||
public MediaTypeRepository(IScopeAccessor scopeAccessor, AppCaches cache, ILogger logger, IContentTypeCommonRepository commonRepository, ILanguageRepository languageRepository)
|
||||
: base(scopeAccessor, cache, logger, commonRepository, languageRepository)
|
||||
{ }
|
||||
|
||||
protected override bool SupportsPublishing => MediaType.SupportsPublishingConst;
|
||||
@@ -49,7 +51,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
{
|
||||
// the cache policy will always want everything
|
||||
// even GetMany(ids) gets everything and filters afterwards
|
||||
if (ids.Any()) throw new Exception("panic");
|
||||
if (ids.Any()) throw new PanicException("There can be no ids specified");
|
||||
return CommonRepository.GetAllTypes().OfType<IMediaType>();
|
||||
}
|
||||
|
||||
@@ -102,7 +104,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
|
||||
protected override void PersistNewItem(IMediaType entity)
|
||||
{
|
||||
((MediaType)entity).AddingEntity();
|
||||
entity.AddingEntity();
|
||||
|
||||
PersistNewBaseContentType(entity);
|
||||
|
||||
@@ -114,7 +116,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
ValidateAlias(entity);
|
||||
|
||||
//Updates Modified date
|
||||
((MediaType)entity).UpdatingEntity();
|
||||
entity.UpdatingEntity();
|
||||
|
||||
//Look up parent to get and set the correct Path if ParentId has changed
|
||||
if (entity.IsPropertyDirty("ParentId"))
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user