Compare commits
442 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8e1c45e981 | |||
| 4a7ee52d63 | |||
| b4d88b0361 | |||
| b41cf37dd5 | |||
| fc32100142 | |||
| 7ecbc3b391 | |||
| c3c44df52e | |||
| 13a86624ff | |||
| 2f61bc27c8 | |||
| e7d157a209 | |||
| d3ed90c23e | |||
| b916360771 | |||
| db4b93dbc3 | |||
| 40868ac361 | |||
| f399a9f52b | |||
| 562851b93e | |||
| e61b567ee1 | |||
| 4ce22b836e | |||
| f5bf05a6f5 | |||
| e50569597b | |||
| 071f3dcc01 | |||
| 6943a454f3 | |||
| 532f407260 | |||
| 834d04f8ed | |||
| f36ab37f6a | |||
| aeff33d0a6 | |||
| 5cfe9e57ce | |||
| 4863e657df | |||
| c0e1be4df9 | |||
| a93e562f14 | |||
| 822cac5d87 | |||
| d58487fafc | |||
| ea9653fa83 | |||
| 8cca1b77b3 | |||
| 53e4308c29 | |||
| 6f26f7b57c | |||
| bda2614290 | |||
| efc482511e | |||
| 40b90b8a58 | |||
| a009dfe2a1 | |||
| 41e87fca98 | |||
| f23c6c53cc | |||
| 0762decd92 | |||
| 0b58c1c03c | |||
| 38c6a21896 | |||
| 15bff44ec1 | |||
| a626efa9b6 | |||
| 54d2258634 | |||
| 25be0621b2 | |||
| cba09ed817 | |||
| d5d00553b4 | |||
| c52669fb05 | |||
| c4a071523e | |||
| ca99319ead | |||
| 81360f629e | |||
| aa36c66f39 | |||
| 09e31d6595 | |||
| f9fc2619fa | |||
| 5d8cfa5efb | |||
| 297f8e2a0b | |||
| 8ddfb5f6ad | |||
| 9387544865 | |||
| 66ddb21ef8 | |||
| 9d19ed9463 | |||
| df62697477 | |||
| f0cacf0d52 | |||
| d501fcb679 | |||
| f5994d8442 | |||
| 4295cba915 | |||
| 6d66fc6cb8 | |||
| 4484f83caa | |||
| 3ada1770eb | |||
| 0b6f05e630 | |||
| 2170380f7b | |||
| a8ab7e4c35 | |||
| c20c9c638f | |||
| 43b2a2185e | |||
| 2423bdd623 | |||
| bcb90d64a5 | |||
| 7d448d0959 | |||
| 53fe02db7e | |||
| a03dd7b11e | |||
| 6d994f48ac | |||
| f0e8252e38 | |||
| ad06aded1b | |||
| 0ca52fcc60 | |||
| c53342ba4c | |||
| 25eea8d599 | |||
| 22498649b1 | |||
| 25ce7baa7d | |||
| e885384678 | |||
| 528209f8da | |||
| 153fe248a7 | |||
| 7fc4822bbe | |||
| d65bee76b2 | |||
| 385d6396b0 | |||
| 46858af1ed | |||
| 34163625fe | |||
| e53b388a5e | |||
| 4fb4af0b4f | |||
| 461f032777 | |||
| ab37f9ae35 | |||
| a3347c0037 | |||
| f3835d1ca3 | |||
| 8fae55e44e | |||
| a8ca3a89bd | |||
| 765f959f20 | |||
| 2cf90477ed | |||
| 6ca6a08233 | |||
| 0119f1eb1b | |||
| cd4f66e7c5 | |||
| d30c4791fe | |||
| 7ee9b9ebcc | |||
| b4caf109f7 | |||
| 0e8ffe528a | |||
| a8029d1dc5 | |||
| 3fdc0e5361 | |||
| 4bfb8569c8 | |||
| df9a887032 | |||
| 1e0a4690fc | |||
| 52163494db | |||
| 8416764a83 | |||
| 2d3eb8c208 | |||
| aa84a3f7f2 | |||
| 3594693f4b | |||
| c573459626 | |||
| b99de245bf | |||
| 222723b8fe | |||
| f758b33da5 | |||
| eeb0e0026a | |||
| 082dacf737 | |||
| afc2fd9420 | |||
| ff6715d42a | |||
| b776675ac8 | |||
| 1e21671b62 | |||
| 59184981cb | |||
| 0632ffb93d | |||
| 034aa6d8f9 | |||
| 1484fba1ad | |||
| 82fc1a5304 | |||
| f0aab6ae81 | |||
| 9ac325c1a4 | |||
| 8c257d39f9 | |||
| 76f040aef4 | |||
| 721f813d1e | |||
| 7ed5a6f706 | |||
| 35a698cdc9 | |||
| 6c9e82e735 | |||
| f7ddb1ed49 | |||
| c0fd974cc1 | |||
| e9c4a031c9 | |||
| 123e65c55f | |||
| e5e4e7b685 | |||
| 88795b86fd | |||
| 378a544c1a | |||
| a159b50c05 | |||
| 3891e46549 | |||
| e7bcc642a9 | |||
| 4983990d39 | |||
| e9a496df4f | |||
| 2f6dada481 | |||
| 580123cb87 | |||
| de0e47d7ef | |||
| ff5dc324fe | |||
| 096c5ad69f | |||
| eba7582a97 | |||
| 0cf2a1fc2a | |||
| 77ee87178e | |||
| a6997a5cb7 | |||
| ff3fc5d825 | |||
| 3b9bf7b0f9 | |||
| 3882e1984d | |||
| b32ea68fd0 | |||
| eb2db791b8 | |||
| 158f4d0614 | |||
| 7a38970cf4 | |||
| 7f6d8b6bdd | |||
| 22fb7e1706 | |||
| 12b1168de9 | |||
| 01290f8174 | |||
| 26a7bf8187 | |||
| ba1d0fa193 | |||
| 97355bde6f | |||
| ed35f234de | |||
| c874fa6507 | |||
| ba387598ed | |||
| 3ff1b01e46 | |||
| 36e803713c | |||
| a3e7f644de | |||
| 1586f1679a | |||
| 809badd1cf | |||
| da92ece774 | |||
| a531afb819 | |||
| 1d6009e3c7 | |||
| 8dfeb1e616 | |||
| 1b086e2267 | |||
| 1f86d8c562 | |||
| 25b9262cf1 | |||
| 1012a4814d | |||
| bae41cde14 | |||
| b3260f05c0 | |||
| e33a79ac65 | |||
| c4dbabf654 | |||
| 423643d66c | |||
| 4ccb655f73 | |||
| c8330d60f9 | |||
| a9aa3a04b5 | |||
| 0bffa8e3f4 | |||
| 436322f58c | |||
| e90c46dd78 | |||
| deda2534f8 | |||
| 8112c13857 | |||
| 57792de185 | |||
| e1f93029a5 | |||
| f64e0c7eb7 | |||
| bf024e9011 | |||
| 036b888d30 | |||
| 1838a8dac5 | |||
| 205bf5fe4e | |||
| a50e192ab7 | |||
| 9684255e6e | |||
| 72790d74f5 | |||
| bb70bee6ae | |||
| 0430e7966c | |||
| 2e9a52b1f8 | |||
| db4ed70d70 | |||
| e6ccd8a5b5 | |||
| a9781d79e2 | |||
| 7ae8b28466 | |||
| 29a4cb8b71 | |||
| ffb39de003 | |||
| 527375b238 | |||
| a4ed0e266c | |||
| 1929f60ea8 | |||
| b9cc2efc8c | |||
| eadb1bb194 | |||
| 30be665a40 | |||
| bad284515c | |||
| 5b660d95f1 | |||
| 106ac44e64 | |||
| 64bb7e1db0 | |||
| 25b9ca3b0e | |||
| b928170103 | |||
| e25ee246fb | |||
| 8e8ec41dae | |||
| fb34c4716a | |||
| 29bf61b1f2 | |||
| 9803309e34 | |||
| 3a539629dc | |||
| 74b970d586 | |||
| 518898b04b | |||
| a773e0a018 | |||
| 99fe89addc | |||
| 668d4f9f91 | |||
| 90e73cb89f | |||
| dcd6477030 | |||
| 13b73231de | |||
| 50a70c28df | |||
| 7d5589118f | |||
| c39b698d4c | |||
| 103efbdc27 | |||
| 3d51dd767b | |||
| e22988e435 | |||
| 9736aaafaa | |||
| bf3fa20a53 | |||
| f936f8b0dd | |||
| 1bd20c9b06 | |||
| 099b713947 | |||
| 165d9c7dff | |||
| 09400be6e0 | |||
| 7934ba7ec4 | |||
| 7edbc34e6c | |||
| 60b6608289 | |||
| 792599a42f | |||
| 7610ee5f8b | |||
| eab9be4ef7 | |||
| e48a030aab | |||
| e207b1f1e1 | |||
| fd3540f92d | |||
| b9d7f0c5a5 | |||
| 3d76614a78 | |||
| de0e6f3179 | |||
| 39edb9b7e2 | |||
| a638488eb7 | |||
| a2a539f7db | |||
| 6768bb4793 | |||
| 19c2841576 | |||
| 71aa248a4e | |||
| eeaef5ac5c | |||
| bea50f4562 | |||
| ff337457f8 | |||
| 49b5ddf850 | |||
| b449b8762b | |||
| 13e555f50b | |||
| 48c809a797 | |||
| 55c7f72d8e | |||
| 8612113fc0 | |||
| 69b0c7cf09 | |||
| 37a97a2e7c | |||
| 5f4eaef4a2 | |||
| 44f5c3a34f | |||
| a33ae696a2 | |||
| 2705efb809 | |||
| 648d631151 | |||
| 27c0c4d64e | |||
| 52cf559536 | |||
| c9b0362c62 | |||
| 11e5bdf556 | |||
| 3d0be3836c | |||
| 2bc33e0115 | |||
| 8576d9c67e | |||
| a0651f4383 | |||
| 9452d5fd09 | |||
| 1f40d726de | |||
| 2699611ba3 | |||
| 43795f0007 | |||
| b1fa06bfe8 | |||
| 4dc22b6ce4 | |||
| d4ab60f8af | |||
| 883277125a | |||
| 8edfc0ffdd | |||
| ff961abaab | |||
| b2414c1ab8 | |||
| 9dde86d591 | |||
| b4ce4fbdef | |||
| 4285484c1b | |||
| 2fd299ebfc | |||
| f545f293b1 | |||
| b745c0ae90 | |||
| f2efff5411 | |||
| 9ef5890636 | |||
| bc9fd04a36 | |||
| 185c5d78f1 | |||
| 3ea9963166 | |||
| ab40822a98 | |||
| dffce76e29 | |||
| d1e02f506c | |||
| 5e18d13178 | |||
| 1dfca6836d | |||
| dbbdd16bb9 | |||
| 74362fba23 | |||
| 112502cf18 | |||
| 1db7f808c9 | |||
| 762cca145f | |||
| 65dc5eaeee | |||
| 4f81e06d3d | |||
| 6b74b75b6f | |||
| 98e53b3d74 | |||
| a1f01f9d5c | |||
| f5d8cb0275 | |||
| 0d8b65caea | |||
| 70285991bb | |||
| a336eaa4a1 | |||
| fdefe993b7 | |||
| ba0e72a1c1 | |||
| c5710277a5 | |||
| 5cd2d568e3 | |||
| 9c89a56d8d | |||
| 9ba7664f78 | |||
| 4b87a5c2d3 | |||
| f0699afb6e | |||
| b4d5658d45 | |||
| d485c3da97 | |||
| 1214082997 | |||
| 1a56e6693a | |||
| c6b7f20dab | |||
| 5cc55ad6e2 | |||
| a55fedab0a | |||
| 0e12f14a4a | |||
| 3e25b71d9e | |||
| 63de9e6691 | |||
| b9ea85d29d | |||
| d0787e92fe | |||
| ffe9953c43 | |||
| 99a9f1ab87 | |||
| 7def26a489 | |||
| a76ffe8daf | |||
| 259fbcb8f0 | |||
| ee9f91b5cf | |||
| db3f21429e | |||
| 033692d7ee | |||
| 23146cb12a | |||
| 04b9607741 | |||
| 0e392b398c | |||
| 5914690ad8 | |||
| c4aa9095f2 | |||
| 79ce586c8b | |||
| 8fba03c05d | |||
| 2fdcb9164a | |||
| 7404a1f93d | |||
| c8b8b28e9b | |||
| 5bd2571395 | |||
| c0cd157e60 | |||
| ac2f9b172c | |||
| b8e4a73c3b | |||
| 63192f3a65 | |||
| 727f62d418 | |||
| 68c4255a51 | |||
| 187af3e361 | |||
| c6f29a50d6 | |||
| d07212c89b | |||
| 28c55320a1 | |||
| cb0dd70434 | |||
| fd58017e97 | |||
| 928d92fce4 | |||
| 09408b898e | |||
| d1b05332c5 | |||
| 836b0f39c2 | |||
| 1b01386673 | |||
| 2a09f02afb | |||
| ee95434cea | |||
| caad0afed8 | |||
| fe08e7fc2f | |||
| 4ad96b49e7 | |||
| 9a1bb4a2dd | |||
| c39f902ed5 | |||
| b7dc052cb2 | |||
| 0c77114cd5 | |||
| 222a5237b0 | |||
| de55cb8392 | |||
| df164ee618 | |||
| 21b0687a57 | |||
| 9310efa280 | |||
| a41b55a9e6 | |||
| af2d8a4755 | |||
| d48e339b81 | |||
| 9b6d498cf7 | |||
| 62d365573f | |||
| 04bf011fcd | |||
| f3b7a8a581 | |||
| 5d62902684 | |||
| 82d645a0f7 | |||
| a8936de638 | |||
| a765f36d24 | |||
| 6b691eb461 | |||
| 046da1a8ce | |||
| ca7abd6c78 | |||
| 452688b2bb | |||
| 7cc0f2a514 | |||
| a2251fe062 | |||
| 3d0684eac0 | |||
| a8fafaa194 |
@@ -44,6 +44,7 @@ src\Umbraco.Web.UI\[Mm]acro[Ss]cripts\*
|
||||
src\Umbraco.Web.UI\[Xx]slt\*
|
||||
src\Umbraco.Web.UI\[Ii]mages\*
|
||||
src\Umbraco.Web.UI\[Ss]cripts\*
|
||||
src\Umbraco.Web.UI\Web.*.config.transformed
|
||||
|
||||
umbraco\presentation\umbraco\plugins\uComponents\uComponentsInstaller.ascx
|
||||
umbraco\presentation\packages\uComponents\MultiNodePicker\CustomTreeService.asmx
|
||||
|
||||
@@ -26,3 +26,8 @@ ff3bb24ea0c915878396a6ae27f1ff164e8ac150 Release-6.0.0-beta
|
||||
56015ac26f5ab60e3c61b1d09075297b660afa07 Release-6.0.0-RC
|
||||
1719fbd857f28b376639ac2aa0abada0ef2e7560 Release-6.0.0
|
||||
e02f5aebb87e3f07d27376647756caa9762931d8 Release-4.11.4
|
||||
14338b0ab1738fbd8987677ecdb9a73d79fc229d release-4.11.6
|
||||
ce47176bc6b9298741783e20f1fe2672c811f744 release-4.11.7
|
||||
b247b35d821144849f551e02da8ba719f91d5fb0 Release-6.0.2
|
||||
aed55cba29009ad3db48880a7cfb66407ce9805f release-6.0.3
|
||||
0dee9964687ea51ea797984cf7cce3655d6a6558 release-6.0.4
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
@ECHO OFF
|
||||
SET release=6.0.2
|
||||
SET release=6.0.6
|
||||
SET comment=
|
||||
SET version=%release%
|
||||
|
||||
|
||||
@@ -63,8 +63,6 @@
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.providers.dll" target="lib\umbraco.providers.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.providers.xml" target="lib\umbraco.providers.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Umbraco.Web.UI.dll" target="lib\Umbraco.Web.UI.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.webservices.dll" target="lib\umbraco.webservices.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.webservices.xml" target="lib\umbraco.webservices.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.XmlSerializers.dll" target="lib\umbraco.XmlSerializers.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\UmbracoExamine.dll" target="lib\UmbracoExamine.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\UrlRewritingNet.UrlRewriter.dll" target="lib\UrlRewritingNet.UrlRewriter.dll" />
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
@ECHO OFF
|
||||
|
||||
:choice
|
||||
set /P c=WARNING! Are you sure you want to continue, this will remove all package files, view files, sqlce database, etc... Press 'Y' to auto-remove all files/folders, 'N' to cancel or 'C' to prompt for each folder removal?
|
||||
if /I "%c%" EQU "C" goto :prompt
|
||||
if /I "%c%" EQU "Y" goto :auto
|
||||
if /I "%c%" EQU "N" goto :exit
|
||||
goto :choice
|
||||
|
||||
|
||||
:prompt
|
||||
|
||||
echo Current folder: %CD%
|
||||
|
||||
echo Regenerating SQL CE database
|
||||
SET buildfolder=%CD%
|
||||
CD ..\tools\RegenerateUmbracoSQLCEDatabase\
|
||||
RegenerateUmbracoSQLCEDatabase.exe %CD%\..\..\src\Umbraco.Web.UI
|
||||
CD %buildfolder%
|
||||
|
||||
echo Removing bin files
|
||||
del ..\src\Umbraco.Web.UI\bin\*.*
|
||||
|
||||
echo Building solution
|
||||
%windir%\Microsoft.NET\Framework\v4.0.30319\msbuild.exe ..\src\umbraco.sln /t:Clean,Build
|
||||
|
||||
echo Resetting installedPackages.config
|
||||
echo ^<?xml version="1.0" encoding="utf-8"?^>^<packages^>^</packages^> >..\src\Umbraco.Web.UI\App_Data\packages\installed\installedPackages.config
|
||||
|
||||
echo Removing plugin cache files
|
||||
del ..\src\Umbraco.Web.UI\App_Data\TEMP\PluginCache\*.*
|
||||
|
||||
echo Removing cache files and examine index
|
||||
del ..\src\Umbraco.Web.UI\App_Data\TEMP\*.*
|
||||
|
||||
echo Removing log files
|
||||
del ..\src\Umbraco.Web.UI\App_Data\Logs\*.*
|
||||
|
||||
echo Removing packages
|
||||
del ..\src\Umbraco.Web.UI\App_Data\packages\*.*
|
||||
|
||||
echo Removing previews
|
||||
del ..\src\Umbraco.Web.UI\App_Data\preview\*.*
|
||||
|
||||
echo Removing app code files (typically added by starterkits)
|
||||
del ..\src\Umbraco.Web.UI\App_Code\*.*
|
||||
|
||||
echo Removing xslt files
|
||||
del ..\src\Umbraco.Web.UI\xslt\*.*
|
||||
|
||||
echo Removing user control files
|
||||
del ..\src\Umbraco.Web.UI\UserControls\*.*
|
||||
|
||||
echo Removing masterpage files
|
||||
del ..\src\Umbraco.Web.UI\masterpages\*.*
|
||||
|
||||
echo Removing view files
|
||||
del ..\src\Umbraco.Web.UI\Views\*.*
|
||||
|
||||
echo Removing razor files
|
||||
del ..\src\Umbraco.Web.UI\macroScripts\*.*
|
||||
|
||||
echo Removing media files
|
||||
del ..\src\Umbraco.Web.UI\media\*.*
|
||||
|
||||
echo Removing script files
|
||||
del ..\src\Umbraco.Web.UI\scripts\*.*
|
||||
|
||||
echo Removing css files
|
||||
del ..\src\Umbraco.Web.UI\css\*.*
|
||||
|
||||
echo "Umbraco install reverted to clean install"
|
||||
pause
|
||||
exit
|
||||
|
||||
|
||||
|
||||
:auto
|
||||
|
||||
echo Current folder: %CD%
|
||||
|
||||
echo Regenerating SQL CE database
|
||||
SET buildfolder=%CD%
|
||||
CD ..\tools\RegenerateUmbracoSQLCEDatabase\
|
||||
RegenerateUmbracoSQLCEDatabase.exe %CD%\..\..\src\Umbraco.Web.UI
|
||||
CD %buildfolder%
|
||||
|
||||
echo Removing bin files
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\bin\*.*) DO DEL %%A
|
||||
|
||||
echo Building solution
|
||||
%windir%\Microsoft.NET\Framework\v4.0.30319\msbuild.exe ..\src\umbraco.sln /t:Clean,Build
|
||||
|
||||
echo Resetting installedPackages.config
|
||||
echo ^<?xml version="1.0" encoding="utf-8"?^>^<packages^>^</packages^> >..\src\Umbraco.Web.UI\App_Data\packages\installed\installedPackages.config
|
||||
|
||||
echo Removing plugin cache files
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\App_Data\TEMP\PluginCache\*.*) DO DEL %%A
|
||||
|
||||
echo Removing cache files and examine index
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\App_Data\TEMP\*.*) DO DEL %%A
|
||||
|
||||
echo Removing log files
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\App_Data\Logs\*.*) DO DEL %%A
|
||||
|
||||
echo Removing packages
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\App_Data\packages\*.*) DO DEL %%A
|
||||
|
||||
echo Removing previews
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\App_Data\preview\*.*) DO DEL %%A
|
||||
|
||||
echo Removing app code files (typically added by starterkits)
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\App_Code\*.*) DO DEL %%A
|
||||
|
||||
echo Removing xslt files
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\xslt\*.*) DO DEL %%A
|
||||
|
||||
echo Removing masterpage files
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\masterpages\*.*) DO DEL %%A
|
||||
|
||||
echo Removing user control files
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\usercontrols\*.*) DO DEL %%A
|
||||
|
||||
echo Removing view files
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\Views\*.*) DO DEL %%A
|
||||
|
||||
echo Removing razor files
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\macroScripts\*.*) DO DEL %%A
|
||||
|
||||
echo Removing media files
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\media\*.*) DO DEL %%A
|
||||
|
||||
echo Removing script files
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\scripts\*.*) DO DEL %%A
|
||||
|
||||
echo Removing css files
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\css\*.*) DO DEL %%A
|
||||
|
||||
echo Removing Courier files
|
||||
del ..\src\Umbraco.Web.UI\config\courier.config
|
||||
del ..\src\Umbraco.Web.UI\umbraco\images\tray\courier.jpg
|
||||
rmdir "..\src\Umbraco.Web.UI\umbraco\plugins\courier\" /S /Q
|
||||
|
||||
echo Removing Contour files
|
||||
del ..\src\Umbraco.Web.UI\umbraco\images\tray\contour.png
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\umbraco\images\umbraco\icon_*.*) DO DEL %%A
|
||||
rmdir "..\src\Umbraco.Web.UI\umbraco\plugins\umbracoContour\" /S /Q
|
||||
del ..\src\Umbraco.Web.UI\umbraco\xslt\templates\UmbracoContour*.* /S /Q
|
||||
rmdir "..\src\Umbraco.Web.UI\usercontrols\umbracoContour\" /S /Q
|
||||
|
||||
echo Start with a clean web.config
|
||||
copy ..\src\Umbraco.Web.UI\web.Template.config ..\src\Umbraco.Web.UI\web.config /Y
|
||||
|
||||
echo "Umbraco install reverted to clean install"
|
||||
pause
|
||||
exit
|
||||
|
||||
|
||||
|
||||
:exit
|
||||
exit
|
||||
Binary file not shown.
@@ -1,24 +0,0 @@
|
||||
Hi! Thanks for grabbing the Umbraco sourcecode.
|
||||
|
||||
===========================================
|
||||
NOTE - DEFAULT BRANCH EMPTY - December 2010
|
||||
===========================================
|
||||
|
||||
|
||||
- With the help of CodePlex we have migrated much of our previous changesets (as of Dec 13th 2010) from TFS to Mercurial.
|
||||
|
||||
- However, not everything could be migrated to our new branching workflow. So for each nominal group of 4.x changes, we've created named branches. For upcoming 5.x changesets, we'll adhere to our new workflow which we'll describe on the Wiki for contributors.
|
||||
|
||||
- FOR THE MOMENT, the 'default' branch is empty - pending the addition of the 5.0 changesets
|
||||
|
||||
- To switch to the codebase on which you want to work, 'hg update' to the named branch (e.g. "4.6.0") or tag (e.g. "Release-4.5.2") and browse or work from that point.
|
||||
|
||||
|
||||
Thanks to Matt Hawley at CodePlex for his help in our migration!
|
||||
|
||||
Cheers,
|
||||
The Umbraco Team
|
||||
|
||||
http://umbraco.org
|
||||
http://our.umbraco.org
|
||||
http://umbraco.codeplex.com
|
||||
@@ -1,82 +0,0 @@
|
||||
{\rtf1\ansi\ansicpg1252\uc1\deff0\stshfdbch0\stshfloch0\stshfhich0\stshfbi0\deflang1033\deflangfe1033{\fonttbl{\f0\froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f36\fswiss\fcharset0\fprq2{\*\panose 020b0604030504040204}Tahoma;}
|
||||
{\f39\froman\fcharset238\fprq2 Times New Roman CE;}{\f40\froman\fcharset204\fprq2 Times New Roman Cyr;}{\f42\froman\fcharset161\fprq2 Times New Roman Greek;}{\f43\froman\fcharset162\fprq2 Times New Roman Tur;}
|
||||
{\f44\froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f45\froman\fcharset178\fprq2 Times New Roman (Arabic);}{\f46\froman\fcharset186\fprq2 Times New Roman Baltic;}{\f47\froman\fcharset163\fprq2 Times New Roman (Vietnamese);}
|
||||
{\f399\fswiss\fcharset238\fprq2 Tahoma CE;}{\f400\fswiss\fcharset204\fprq2 Tahoma Cyr;}{\f402\fswiss\fcharset161\fprq2 Tahoma Greek;}{\f403\fswiss\fcharset162\fprq2 Tahoma Tur;}{\f404\fswiss\fcharset177\fprq2 Tahoma (Hebrew);}
|
||||
{\f405\fswiss\fcharset178\fprq2 Tahoma (Arabic);}{\f406\fswiss\fcharset186\fprq2 Tahoma Baltic;}{\f407\fswiss\fcharset163\fprq2 Tahoma (Vietnamese);}{\f408\fswiss\fcharset222\fprq2 Tahoma (Thai);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;
|
||||
\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;
|
||||
\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext0 Normal;}{\*\cs10 \additive
|
||||
\ssemihidden Default Paragraph Font;}{\*\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tscellwidthfts0\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv
|
||||
\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs20\lang1024\langfe1024\cgrid\langnp1024\langfenp1024 \snext11 \ssemihidden Normal Table;}{\s15\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0
|
||||
\f36\fs16\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext15 \ssemihidden \styrsid668380 Balloon Text;}}{\*\latentstyles\lsdstimax156\lsdlockeddef0}{\*\listtable{\list\listtemplateid130696116{\listlevel\levelnfc0\levelnfcn0\leveljc0
|
||||
\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'00.;}{\levelnumbers\'01;}\fi-360\li720\jclisttab\tx720\lin720 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0
|
||||
{\leveltext\'02\'01.;}{\levelnumbers\'01;}\fi-360\li1440\jclisttab\tx1440\lin1440 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'02.;}{\levelnumbers\'01;}\fi-360\li2160
|
||||
\jclisttab\tx2160\lin2160 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'03.;}{\levelnumbers\'01;}\fi-360\li2880\jclisttab\tx2880\lin2880 }{\listlevel\levelnfc0\levelnfcn0\leveljc0
|
||||
\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'04.;}{\levelnumbers\'01;}\fi-360\li3600\jclisttab\tx3600\lin3600 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0
|
||||
{\leveltext\'02\'05.;}{\levelnumbers\'01;}\fi-360\li4320\jclisttab\tx4320\lin4320 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'06.;}{\levelnumbers\'01;}\fi-360\li5040
|
||||
\jclisttab\tx5040\lin5040 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'07.;}{\levelnumbers\'01;}\fi-360\li5760\jclisttab\tx5760\lin5760 }{\listlevel\levelnfc0\levelnfcn0\leveljc0
|
||||
\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'08.;}{\levelnumbers\'01;}\fi-360\li6480\jclisttab\tx6480\lin6480 }{\listname ;}\listid723138990}}{\*\listoverridetable{\listoverride\listid723138990\listoverridecount0\ls1}}
|
||||
{\*\pgptbl {\pgp\ipgp2\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp4\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}}{\*\rsidtbl \rsid288726\rsid668380\rsid1077358\rsid1250157\rsid1778664
|
||||
\rsid2232581\rsid3018318\rsid3766585\rsid4417501\rsid4531485\rsid4807452\rsid5341002\rsid7018004\rsid7880391\rsid10749719\rsid12150908\rsid12939982\rsid13596669\rsid15149892\rsid15551579\rsid16128754\rsid16674677}{\*\generator Microsoft Word 11.0.6359;}
|
||||
{\info{\title Shared Source License for Software included in Workspaces}{\author suev}{\operator Martin Maly}{\creatim\yr2005\mo3\dy22\hr10\min45}{\revtim\yr2005\mo3\dy22\hr15\min54}{\printim\yr2002\mo9\dy20\hr15\min39}{\version3}{\edmins1}{\nofpages1}
|
||||
{\nofwords672}{\nofchars3837}{\*\company Microsoft}{\nofcharsws4501}{\vern24703}}\widowctrl\ftnbj\aenddoc\noxlattoyen\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\hyphcaps0\formshade\horzdoc\dgmargin\dghspace180\dgvspace180\dghorigin1701\dgvorigin1984
|
||||
\dghshow1\dgvshow1\jexpand\viewkind5\viewscale100\pgbrdrhead\pgbrdrfoot\splytwnine\ftnlytwnine\htmautsp\nolnhtadjtbl\useltbaln\alntblind\lytcalctblwd\lyttblrtgr\lnbrkrule\nobrkwrptbl\snaptogridincell\allowfieldendsel\wrppunct
|
||||
\asianbrkrule\nojkernpunct\rsidroot15149892 \fet0\sectd \linex0\endnhere\sectlinegrid360\sectdefaultcl\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3
|
||||
\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}
|
||||
{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain
|
||||
\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\b\fs28\insrsid1250157\charrsid1250157 Shared Source License for }{\b\fs28\insrsid16674677 IronPython}{
|
||||
\b\fs28\insrsid1250157
|
||||
\par }{\b\fs28\insrsid5341002
|
||||
\par }{\b\insrsid5341002\charrsid5341002 This license governs use of the accompanying software}{\b\insrsid5341002 (\'93Software\'94)}{\b\insrsid5341002\charrsid5341002 , and your use of the }{\b\insrsid5341002 S}{\b\insrsid5341002\charrsid5341002
|
||||
oftware constitutes acceptance of this license.
|
||||
\par }{\insrsid1250157\charrsid5341002
|
||||
\par }{\b\insrsid1250157\charrsid1250157 You }{\b\insrsid5341002 may}{\b\insrsid1250157\charrsid1250157 use }{\b\insrsid5341002 the}{\b\insrsid1250157\charrsid1250157 Software for any }{\b\insrsid1250157 commercial or }{\b\insrsid1250157\charrsid1250157
|
||||
noncommercial purpose, including distributing derivative}{\b\insrsid4417501 work}{\b\insrsid1250157\charrsid1250157 s}{\b\insrsid1250157 .
|
||||
\par }{\insrsid1250157
|
||||
\par }\pard \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid1250157 {\insrsid1250157\charrsid1250157 In return, we simply require that you agree:
|
||||
\par {\listtext\pard\plain\insrsid1250157\charrsid1250157 \hich\af0\dbch\af0\loch\f0 1.\tab}}\pard \ql \fi-360\li720\ri0\widctlpar\jclisttab\tx720\aspalpha\aspnum\faauto\ls1\adjustright\rin0\lin720\itap0\pararsid1250157 {\insrsid1250157\charrsid1250157
|
||||
Not to remove any copyright}{\insrsid5341002 or other}{\insrsid1250157\charrsid1250157 notices from the Software.
|
||||
\par {\listtext\pard\plain\insrsid1250157\charrsid1250157 \hich\af0\dbch\af0\loch\f0 2.\tab}That if you distribute the Software in source code form you do so only under this }{\insrsid5341002 l}{\insrsid1250157\charrsid1250157
|
||||
icense (i.e. you must include a complete copy of this }{\insrsid5341002 l}{\insrsid1250157\charrsid1250157 icense with your distribution), and if you distribute the Software solely in object form you only do so under a license that complies with this }{
|
||||
\insrsid5341002 l}{\insrsid1250157\charrsid1250157 icense.
|
||||
\par {\listtext\pard\plain\b\insrsid1250157\charrsid1250157 \hich\af0\dbch\af0\loch\f0 3.\tab}}{\b\insrsid1250157\charrsid1250157
|
||||
That the Software comes "as is", with no warranties. None whatsoever. This means no express, implied or statutory warranty, including without limitation, warranties of merchantability or fitness for a particular purpose or any warranty of }{
|
||||
\b\insrsid5341002 title or }{\b\insrsid1250157\charrsid1250157 non}{\b\insrsid5341002 -}{\b\insrsid1250157\charrsid1250157 infringement. Also, you must pass this disclaimer on whenever you distribute the Software}{\b\insrsid5341002 or derivative works}{
|
||||
\b\insrsid1250157\charrsid1250157 .}{\insrsid1250157\charrsid1250157
|
||||
\par {\listtext\pard\plain\b\insrsid1250157\charrsid1250157 \hich\af0\dbch\af0\loch\f0 4.\tab}}{\b\insrsid1250157\charrsid1250157 That neither Microsoft nor }{\b\insrsid1250157 any contributor to the Software}{\b\insrsid1250157\charrsid1250157
|
||||
will be liable for any of those types of damages known as}{\b\insrsid5341002 }{\b\insrsid1250157\charrsid1250157 indirect, special, consequential, or incidental related to the Software or this }{\b\insrsid5341002 l}{\b\insrsid1250157\charrsid1250157
|
||||
icense, to the maximum extent the law permits, no matter what legal theory it\rquote s based on. Also, you must pass this limitation of liability on whenever you distribute the Software}{\b\insrsid5341002 or derivative works}{
|
||||
\b\insrsid1250157\charrsid1250157 .}{\insrsid1250157\charrsid1250157
|
||||
\par {\listtext\pard\plain\insrsid1250157\charrsid1250157 \hich\af0\dbch\af0\loch\f0 5.\tab}That if you sue anyone over patents that you think may apply to the Software for a person's use of the Software, your license to the Software ends automatically.
|
||||
|
||||
\par {\listtext\pard\plain\insrsid1250157 \hich\af0\dbch\af0\loch\f0 6.\tab}}{\insrsid1250157 That the patent rights, if any, }{\insrsid288726 granted in this license}{\insrsid1250157\charrsid1250157 only apply to the Software, not to any derivative}{
|
||||
\insrsid4417501 work}{\insrsid1250157\charrsid1250157 s you make.}{\insrsid3018318
|
||||
\par {\listtext\pard\plain\insrsid3018318\charrsid3018318 \hich\af0\dbch\af0\loch\f0 7.\tab}}{\insrsid3018318\charrsid3018318 That if you are an agency of the U.S. Government, (i) Software provided pursuant to a solicitation issued on or after Dece
|
||||
mber 1, 1995, is provided with the commercial license rights set forth in this license, and (ii) Software provided pursuant to a solicitation issued prior to December 1, 1995, is provided with \'93Restricted Rights\'94
|
||||
as set forth in FAR, 48 C.F.R. 52.227-14 (June 1987) or DFAR, 48 C.F.R. 252.227-7013 (Oct 1988), as applicable.}{\insrsid1250157
|
||||
\par {\listtext\pard\plain\insrsid1250157 \hich\af0\dbch\af0\loch\f0 8.\tab}That your rights under this License end automatically if you breach it in any way.
|
||||
\par {\listtext\pard\plain\insrsid5341002 \hich\af0\dbch\af0\loch\f0 9.\tab}}{\insrsid5341002 That all rights not expressly granted to you in this license are reserved.
|
||||
\par }\pard \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid1778664 {\insrsid1778664
|
||||
\par }{\insrsid12150908 Read below}{\insrsid1778664 for answers to frequently asked questions about this license.
|
||||
\par }{\insrsid12150908
|
||||
\par }\pard \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid12150908 {\b\insrsid12150908\charrsid12150908 Q: Is this license OSI compliant?
|
||||
\par }{\insrsid12150908
|
||||
A: This license has not been submitted to OSI, but it allows developers to take full advantage of a dynamic language on the CLR and to have the freedom to distribute their works for the benefit of the community at large. The license is half of a
|
||||
page long and very straight forward. We believe it stands up to what developers demand of an "open" license.
|
||||
\par
|
||||
\par }{\b\insrsid12150908\charrsid12150908 Q: What copyright rights does the license grant me?
|
||||
\par }{\insrsid12150908 A: The license grants you a copyright license to make unlimited copies of the Software in sour
|
||||
ce or object code form, as well as to create Derivative Works (as that term is defined under US copyright law). This means that in addition to making unlimited copies of the Software, you have a copyright license to modify the Software and to use all or p
|
||||
art of the Software to create a Derivative Work.
|
||||
\par
|
||||
\par }{\b\insrsid12150908\charrsid12150908 Q: What patent rights does the license grant me?
|
||||
\par }{\insrsid12150908 A: This license grants you a patent license to use and distribute the Software under any Microsoft patent claims that read on the Software itself. In other wo
|
||||
rds, if you create a modified version of the Software, you still retain the patent license to use and distribute the original portions of the Software under the specific Microsoft patent claims that read on the Software, but you do not have a patent licen
|
||||
s
|
||||
e as to the new functionality you may have added by modifying the Software. This result is typical of many common open source licenses, including the Common Public License (CPL) and the Mozilla Public License (MPL). In addition, this license grants no rig
|
||||
h
|
||||
ts to any Microsoft patents that read on other components or files not included in the Software. This means that no patent license is granted to use or distribute any other software or technology that may be needed to use the Software or was created from
|
||||
t
|
||||
he Software (for example, any compiled output of the Software, the combination of the Software with other hardware or other software, or any additional enabling technologies that may be necessary to make or use the Software or any final product that inclu
|
||||
des the Software).}{\insrsid12150908
|
||||
\par }{\insrsid12150908\charrsid1250157
|
||||
\par }}
|
||||
+30
-6
@@ -1,9 +1,33 @@
|
||||
!! Umbraco - the simple, flexible and friendly ASP.NET CMS
|
||||
Umbraco - the simple, flexible and friendly ASP.NET CMS
|
||||
=======================================================
|
||||
For the first time on the Microsoft platform a free user and developer friendly cms that makes it quick and easy to create websites - or a breeze to build complex web applications. umbraco got award-winning integration capabilities and supports your ASP.NET User and Custom Controls out of the box. It's a developers dream and your users will love it too. Used by more than 57.000 active websites including Heinz.com, Peugeot.com, NAIAS.com and Microsofts documentinteropinitiative.org website you can be sure that the technology is proven, stable and scales.
|
||||
[url:More info at http://umbraco.org|http://umbraco.org]
|
||||
|
||||
!! Forums
|
||||
We have a forum running on [url:http://our.umbraco.org]. The discussions area on CodePlex will be for discussions on developing the core, and not on Umbraco-implementations or extensions in general. For those topics, please use [url:http://our.umbraco.org].
|
||||
More info at http://umbraco.com
|
||||
|
||||
!! Submitting Issues
|
||||
Another way you can contribute to Umbraco is by providing issue reports, for information on how to submit an issue report refer to our [url:online guide|http://our.umbraco.org/wiki/how-tos/submitting-bug-reports].
|
||||
Exploring the repository
|
||||
========================
|
||||
Most contributors will work on their own fork and should pick the branch in which they need their fix. For more information see:
|
||||
http://our.umbraco.org/contribute/guidelines-for-core-contribution
|
||||
|
||||
Exploring the source
|
||||
====================
|
||||
The Umbraco source code is never required for you to start building sites. If you are not using the source code for debugging purposes or to contribute to the source then please download the binaries listed at http://umbraco.codeplex.com
|
||||
|
||||
With that said, the Umbraco solution can be opened in Visual Studio 2010 with SP1 installed or Visual Studio 2012.
|
||||
|
||||
Contributing
|
||||
============
|
||||
Umbraco is Open Source which means you can contribute to make it great!
|
||||
Read all about it at http://our.umbraco.org/contribute
|
||||
|
||||
Forums
|
||||
======
|
||||
We have a forum running on http://our.umbraco.org for friendly community support.
|
||||
|
||||
Documentation
|
||||
=============
|
||||
Our documentation section provides help on installing and using Umbraco including API reference documentation: http://our.umbraco.org/documentation
|
||||
|
||||
Submitting Issues
|
||||
=================
|
||||
Another way you can contribute to Umbraco is by providing issue reports, for information on how to submit an issue report refer to our online guide at http://our.umbraco.org/contribute/report-an-issue-or-request-a-feature
|
||||
@@ -149,7 +149,9 @@ namespace SqlCE4Umbraco
|
||||
var dataDirectory = AppDomain.CurrentDomain.GetData("DataDirectory") as string;
|
||||
if (!string.IsNullOrEmpty(dataDirectory))
|
||||
{
|
||||
path = path.Replace("|DataDirectory|", dataDirectory + System.IO.Path.DirectorySeparatorChar);
|
||||
path = path.Contains(@"|\")
|
||||
? path.Replace("|DataDirectory|", dataDirectory)
|
||||
: path.Replace("|DataDirectory|", dataDirectory + System.IO.Path.DirectorySeparatorChar);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -100,6 +100,18 @@ namespace Umbraco.Core
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The original/first url that the web application executes
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// we need to set the initial url in our ApplicationContext, this is so our keep alive service works and this must
|
||||
/// exist on a global context because the keep alive service doesn't run in a web context.
|
||||
/// we are NOT going to put a lock on this because locking will slow down the application and we don't really care
|
||||
/// if two threads write to this at the exact same time during first page hit.
|
||||
/// see: http://issues.umbraco.org/issue/U4-2059
|
||||
/// </remarks>
|
||||
internal string OriginalRequestUrl { get; set; }
|
||||
|
||||
private bool Configured
|
||||
{
|
||||
get
|
||||
@@ -140,7 +152,6 @@ namespace Umbraco.Core
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void AssertIsReady()
|
||||
{
|
||||
if (!this.IsReady)
|
||||
|
||||
@@ -19,7 +19,41 @@ namespace Umbraco.Core
|
||||
return new FileInfo(path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// Returns true if the assembly is the App_Code assembly
|
||||
/// </summary>
|
||||
/// <param name="assembly"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsAppCodeAssembly(this Assembly assembly)
|
||||
{
|
||||
if (assembly.FullName.StartsWith("App_Code"))
|
||||
{
|
||||
try
|
||||
{
|
||||
Assembly.Load("App_Code");
|
||||
return true;
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
//this will occur if it cannot load the assembly
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the assembly is the compiled global asax.
|
||||
/// </summary>
|
||||
/// <param name="assembly"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsGlobalAsaxAssembly(this Assembly assembly)
|
||||
{
|
||||
//only way I can figure out how to test is by the name
|
||||
return assembly.FullName.StartsWith("App_global.asax");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the file used to load the assembly
|
||||
/// </summary>
|
||||
/// <param name="assemblyName"></param>
|
||||
|
||||
@@ -154,6 +154,9 @@ namespace Umbraco.Core.Configuration
|
||||
/// This will return the MVC area that we will route all custom routes through like surface controllers, etc...
|
||||
/// We will use the 'Path' (default ~/umbraco) to create it but since it cannot contain '/' and people may specify a path of ~/asdf/asdf/admin
|
||||
/// we will convert the '/' to '-' and use that as the path. its a bit lame but will work.
|
||||
///
|
||||
/// We also make sure that the virtual directory (SystemDirectories.Root) is stripped off first, otherwise we'd end up with something
|
||||
/// like "MyVirtualDirectory-Umbraco" instead of just "Umbraco".
|
||||
/// </remarks>
|
||||
internal static string UmbracoMvcArea
|
||||
{
|
||||
@@ -163,7 +166,7 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
throw new InvalidOperationException("Cannot create an MVC Area path without the umbracoPath specified");
|
||||
}
|
||||
return Path.TrimStart('~').TrimStart('/').Replace('/', '-').Trim();
|
||||
return Path.TrimStart(SystemDirectories.Root).TrimStart('~').TrimStart('/').Replace('/', '-').Trim().ToLower();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -671,6 +671,18 @@ namespace Umbraco.Core.Configuration
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// File types that will not be allowed to be uploaded via the content/media upload control
|
||||
/// </summary>
|
||||
public static IEnumerable<string> DisallowedUploadFiles
|
||||
{
|
||||
get
|
||||
{
|
||||
var val = GetKey("/settings/content/disallowedUploadFiles");
|
||||
return val.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the allowed image file types.
|
||||
/// </summary>
|
||||
@@ -1216,6 +1228,75 @@ namespace Umbraco.Core.Configuration
|
||||
}
|
||||
}
|
||||
|
||||
private static MacroErrorBehaviour? _macroErrorBehaviour;
|
||||
|
||||
/// <summary>
|
||||
/// This configuration setting defines how to handle macro errors:
|
||||
/// - Inline - Show error within macro as text (default and current Umbraco 'normal' behavior)
|
||||
/// - Silent - Suppress error and hide macro
|
||||
/// - Throw - Throw an exception and invoke the global error handler (if one is defined, if not you'll get a YSOD)
|
||||
/// </summary>
|
||||
/// <value>MacroErrorBehaviour enum defining how to handle macro errors.</value>
|
||||
public static MacroErrorBehaviour MacroErrorBehaviour
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_macroErrorBehaviour == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var behaviour = MacroErrorBehaviour.Inline;
|
||||
var value = GetKey("/settings/content/MacroErrors");
|
||||
if (value != null)
|
||||
{
|
||||
Enum<MacroErrorBehaviour>.TryParse(value, true, out behaviour);
|
||||
}
|
||||
_macroErrorBehaviour = behaviour;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.Error<UmbracoSettings>("Could not load /settings/content/MacroErrors from umbracosettings.config", ex);
|
||||
_macroErrorBehaviour = MacroErrorBehaviour.Inline;
|
||||
}
|
||||
}
|
||||
return _macroErrorBehaviour.Value;
|
||||
}
|
||||
}
|
||||
|
||||
private static IconPickerBehaviour? _iconPickerBehaviour;
|
||||
|
||||
/// <summary>
|
||||
/// This configuration setting defines how to show icons in the document type editor.
|
||||
/// - ShowDuplicates - Show duplicates in files and sprites. (default and current Umbraco 'normal' behaviour)
|
||||
/// - HideSpriteDuplicates - Show files on disk and hide duplicates from the sprite
|
||||
/// - HideFileDuplicates - Show files in the sprite and hide duplicates on disk
|
||||
/// </summary>
|
||||
/// <value>MacroErrorBehaviour enum defining how to show icons in the document type editor.</value>
|
||||
public static IconPickerBehaviour IconPickerBehaviour
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_iconPickerBehaviour == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var behaviour = IconPickerBehaviour.ShowDuplicates;
|
||||
var value = GetKey("/settings/content/DocumentTypeIconList");
|
||||
if (value != null)
|
||||
{
|
||||
Enum<IconPickerBehaviour>.TryParse(value, true, out behaviour);
|
||||
}
|
||||
_iconPickerBehaviour = behaviour;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.Error<UmbracoSettings>("Could not load /settings/content/DocumentTypeIconList from umbracosettings.config", ex);
|
||||
_iconPickerBehaviour = IconPickerBehaviour.ShowDuplicates;
|
||||
}
|
||||
}
|
||||
return _iconPickerBehaviour.Value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configuration regarding webservices
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
public class UmbracoVersion
|
||||
{
|
||||
private static readonly Version Version = new Version("6.0.2");
|
||||
private static readonly Version Version = new Version("6.0.6");
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current version of Umbraco.
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.ObjectResolution;
|
||||
@@ -10,6 +8,7 @@ using Umbraco.Core.Persistence.Mappers;
|
||||
using Umbraco.Core.Persistence.Migrations;
|
||||
using Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix;
|
||||
using Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixZeroOne;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.Publishing;
|
||||
@@ -61,27 +60,36 @@ namespace Umbraco.Core
|
||||
new PetaPocoUnitOfWorkProvider(dbFactory),
|
||||
new FileUnitOfWorkProvider(),
|
||||
new PublishingStrategy());
|
||||
|
||||
//create the ApplicationContext
|
||||
ApplicationContext = ApplicationContext.Current = new ApplicationContext(dbContext, serviceContext);
|
||||
|
||||
//initialize the DatabaseContext
|
||||
dbContext.Initialize();
|
||||
CreateApplicationContext(dbContext, serviceContext);
|
||||
|
||||
InitializeApplicationEventsResolver();
|
||||
|
||||
InitializeResolvers();
|
||||
|
||||
|
||||
//initialize the DatabaseContext
|
||||
dbContext.Initialize();
|
||||
|
||||
//now we need to call the initialize methods
|
||||
ApplicationEventsResolver.Current.ApplicationEventHandlers
|
||||
.ForEach(x => x.OnApplicationInitialized(UmbracoApplication, ApplicationContext));
|
||||
|
||||
|
||||
_isInitialized = true;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and assigns the application context singleton
|
||||
/// </summary>
|
||||
/// <param name="dbContext"></param>
|
||||
/// <param name="serviceContext"></param>
|
||||
protected virtual void CreateApplicationContext(DatabaseContext dbContext, ServiceContext serviceContext)
|
||||
{
|
||||
//create the ApplicationContext
|
||||
ApplicationContext = ApplicationContext.Current = new ApplicationContext(dbContext, serviceContext);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Special method to initialize the ApplicationEventsResolver and any modifications required for it such
|
||||
/// as adding custom types to the resolver.
|
||||
@@ -135,8 +143,7 @@ namespace Umbraco.Core
|
||||
if (_isComplete)
|
||||
throw new InvalidOperationException("The boot manager has already been completed");
|
||||
|
||||
//freeze resolution to not allow Resolvers to be modified
|
||||
Resolution.Freeze();
|
||||
FreezeResolution();
|
||||
|
||||
//stop the timer and log the output
|
||||
_timer.Dispose();
|
||||
@@ -161,6 +168,14 @@ namespace Umbraco.Core
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Freeze resolution to not allow Resolvers to be modified
|
||||
/// </summary>
|
||||
protected virtual void FreezeResolution()
|
||||
{
|
||||
Resolution.Freeze();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create the resolvers
|
||||
/// </summary>
|
||||
@@ -169,6 +184,12 @@ namespace Umbraco.Core
|
||||
RepositoryResolver.Current = new RepositoryResolver(
|
||||
new RepositoryFactory());
|
||||
|
||||
SqlSyntaxProvidersResolver.Current = new SqlSyntaxProvidersResolver(
|
||||
new[] { typeof(MySqlSyntaxProvider), typeof(SqlCeSyntaxProvider), typeof(SqlServerSyntaxProvider) })
|
||||
{
|
||||
CanResolveBeforeFrozen = true
|
||||
};
|
||||
|
||||
CacheRefreshersResolver.Current = new CacheRefreshersResolver(
|
||||
() => PluginManager.Current.ResolveCacheRefreshers());
|
||||
|
||||
|
||||
@@ -112,7 +112,7 @@ namespace Umbraco.Core
|
||||
public void ConfigureEmbeddedDatabaseConnection()
|
||||
{
|
||||
const string providerName = "System.Data.SqlServerCe.4.0";
|
||||
const string connectionString = "Datasource=|DataDirectory|Umbraco.sdf";
|
||||
const string connectionString = @"Data Source=|DataDirectory|\Umbraco.sdf";
|
||||
|
||||
SaveConnectionString(connectionString, providerName);
|
||||
|
||||
@@ -337,21 +337,22 @@ namespace Umbraco.Core
|
||||
|
||||
internal void Initialize(string providerName)
|
||||
{
|
||||
if (providerName.StartsWith("MySql"))
|
||||
{
|
||||
SyntaxConfig.SqlSyntaxProvider = MySqlSyntax.Provider;
|
||||
}
|
||||
else if (providerName.Contains("SqlServerCe"))
|
||||
{
|
||||
SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider;
|
||||
}
|
||||
else
|
||||
{
|
||||
SyntaxConfig.SqlSyntaxProvider = SqlServerSyntax.Provider;
|
||||
}
|
||||
|
||||
_providerName = providerName;
|
||||
_configured = true;
|
||||
|
||||
try
|
||||
{
|
||||
SqlSyntaxContext.SqlSyntaxProvider =
|
||||
SqlSyntaxProvidersResolver.Current.GetByProviderNameOrDefault(providerName);
|
||||
|
||||
_configured = true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_configured = false;
|
||||
|
||||
LogHelper.Info<DatabaseContext>("Initialization of the DatabaseContext failed with following error: " + e.Message);
|
||||
LogHelper.Info<DatabaseContext>(e.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
internal DatabaseSchemaResult ValidateDatabaseSchema()
|
||||
@@ -388,7 +389,7 @@ namespace Umbraco.Core
|
||||
var message = string.Empty;
|
||||
|
||||
var database = new UmbracoDatabase(_connectionString, ProviderName);
|
||||
var supportsCaseInsensitiveQueries = SyntaxConfig.SqlSyntaxProvider.SupportsCaseInsensitiveQueries(database);
|
||||
var supportsCaseInsensitiveQueries = SqlSyntaxContext.SqlSyntaxProvider.SupportsCaseInsensitiveQueries(database);
|
||||
if (supportsCaseInsensitiveQueries == false)
|
||||
{
|
||||
message = "<p> </p><p>The database you're trying to use does not support case insensitive queries. <br />We currently do not support these types of databases.</p>" +
|
||||
@@ -411,7 +412,7 @@ namespace Umbraco.Core
|
||||
}
|
||||
else
|
||||
{
|
||||
if (SyntaxConfig.SqlSyntaxProvider == MySqlSyntaxProvider.Instance)
|
||||
if (SqlSyntaxContext.SqlSyntaxProvider.GetType() == typeof(MySqlSyntaxProvider))
|
||||
{
|
||||
message = "<p> </p><p>Congratulations, the database step ran successfully!</p>" +
|
||||
"<p>Note: You're using MySQL and the database instance you're connecting to seems to support case insensitive queries.</p>" +
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Umbraco.Core.Events
|
||||
{
|
||||
// Provides information on the macro that caused an error
|
||||
public class MacroErrorEventArgs : System.EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Name of the faulting macro.
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Alias of the faulting macro.
|
||||
/// </summary>
|
||||
public string Alias { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Filename, file path, fully qualified class name, or other key used by the macro engine to do it's processing of the faulting macro.
|
||||
/// </summary>
|
||||
public string ItemKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Exception raised.
|
||||
/// </summary>
|
||||
public Exception Exception { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the desired behaviour when a matching macro causes an error. See
|
||||
/// <see cref="MacroErrorBehaviour"/> for definitions. By setting this in your event
|
||||
/// you can override the default behaviour defined in UmbracoSettings.config.
|
||||
/// </summary>
|
||||
/// <value>Macro error behaviour enum.</value>
|
||||
public MacroErrorBehaviour Behaviour { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -5,12 +5,11 @@ using System.Text;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
|
||||
namespace Umbraco.Core.IO
|
||||
{
|
||||
[UmbracoExperimentalFeature("http://issues.umbraco.org/issue/U4-1156", "Will be declared public after 4.10")]
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
|
||||
internal class FileSystemProviderAttribute : Attribute
|
||||
public class FileSystemProviderAttribute : Attribute
|
||||
{
|
||||
public string Alias { get; set; }
|
||||
public string Alias { get; private set; }
|
||||
|
||||
public FileSystemProviderAttribute(string alias)
|
||||
{
|
||||
|
||||
+1
-2
@@ -6,8 +6,7 @@ using Umbraco.Core.CodeAnnotations;
|
||||
|
||||
namespace Umbraco.Core.IO
|
||||
{
|
||||
[UmbracoExperimentalFeature("http://issues.umbraco.org/issue/U4-1156", "Will be declared public after 4.10")]
|
||||
internal class FileSystemProvider
|
||||
internal class FileSystemProviderConstants
|
||||
{
|
||||
public const string Media = "media";
|
||||
}
|
||||
@@ -9,9 +9,8 @@ using Umbraco.Core.CodeAnnotations;
|
||||
using Umbraco.Core.Configuration;
|
||||
|
||||
namespace Umbraco.Core.IO
|
||||
{
|
||||
[UmbracoExperimentalFeature("http://issues.umbraco.org/issue/U4-1156", "Will be declared public after 4.10")]
|
||||
internal class FileSystemProviderManager
|
||||
{
|
||||
public class FileSystemProviderManager
|
||||
{
|
||||
private readonly FileSystemProvidersSection _config;
|
||||
|
||||
@@ -28,7 +27,7 @@ namespace Umbraco.Core.IO
|
||||
|
||||
#region Constructors
|
||||
|
||||
public FileSystemProviderManager()
|
||||
internal FileSystemProviderManager()
|
||||
{
|
||||
_config = (FileSystemProvidersSection)ConfigurationManager.GetSection("FileSystemProviders");
|
||||
}
|
||||
@@ -48,7 +47,15 @@ namespace Umbraco.Core.IO
|
||||
private readonly ConcurrentDictionary<string, ProviderConstructionInfo> _providerLookup = new ConcurrentDictionary<string, ProviderConstructionInfo>();
|
||||
private readonly ConcurrentDictionary<Type, string> _wrappedProviderLookup = new ConcurrentDictionary<Type, string>();
|
||||
|
||||
public IFileSystem GetFileSystemProvider(string alias)
|
||||
/// <summary>
|
||||
/// Returns the underlying (non-typed) file system provider for the alias specified
|
||||
/// </summary>
|
||||
/// <param name="alias"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// It is recommended to use the typed GetFileSystemProvider method instead to get a strongly typed provider instance.
|
||||
/// </remarks>
|
||||
public IFileSystem GetUnderlyingFileSystemProvider(string alias)
|
||||
{
|
||||
//either get the constructor info from cache or create it and add to cache
|
||||
var ctorInfo = _providerLookup.GetOrAdd(alias, s =>
|
||||
@@ -88,6 +95,11 @@ namespace Umbraco.Core.IO
|
||||
return fs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the strongly typed file system provider
|
||||
/// </summary>
|
||||
/// <typeparam name="TProviderTypeFilter"></typeparam>
|
||||
/// <returns></returns>
|
||||
public TProviderTypeFilter GetFileSystemProvider<TProviderTypeFilter>()
|
||||
where TProviderTypeFilter : FileSystemWrapper
|
||||
{
|
||||
@@ -111,7 +123,7 @@ namespace Umbraco.Core.IO
|
||||
return attr.Alias;
|
||||
});
|
||||
|
||||
var innerFs = GetFileSystemProvider(alias);
|
||||
var innerFs = GetUnderlyingFileSystemProvider(alias);
|
||||
var outputFs = Activator.CreateInstance(typeof (TProviderTypeFilter), innerFs);
|
||||
return (TProviderTypeFilter)outputFs;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ using System.IO;
|
||||
using System.Configuration;
|
||||
using System.Web;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Xml;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
|
||||
@@ -230,6 +231,20 @@ namespace Umbraco.Core.IO
|
||||
filePath = String.Empty;
|
||||
}
|
||||
|
||||
//Break up the file in name and extension before applying the UrlReplaceCharacters
|
||||
var fileNamePart = filePath.Substring(0, filePath.LastIndexOf('.'));
|
||||
var ext = filePath.Substring(filePath.LastIndexOf('.'));
|
||||
|
||||
//Because the file usually is downloadable as well we check characters against 'UmbracoSettings.UrlReplaceCharacters'
|
||||
XmlNode replaceChars = UmbracoSettings.UrlReplaceCharacters;
|
||||
foreach (XmlNode n in replaceChars.SelectNodes("char"))
|
||||
{
|
||||
if (n.Attributes.GetNamedItem("org") != null && n.Attributes.GetNamedItem("org").Value != "")
|
||||
fileNamePart = fileNamePart.Replace(n.Attributes.GetNamedItem("org").Value, XmlHelper.GetNodeValue(n));
|
||||
}
|
||||
|
||||
filePath = string.Concat(fileNamePart, ext);
|
||||
|
||||
// Adapted from: http://stackoverflow.com/a/4827510/5018
|
||||
// Combined both Reserved Characters and Character Data
|
||||
// from http://en.wikipedia.org/wiki/Percent-encoding
|
||||
|
||||
@@ -183,16 +183,26 @@ namespace Umbraco.Core.IO
|
||||
}
|
||||
}
|
||||
|
||||
private static string _root;
|
||||
/// <summary>
|
||||
/// Gets the root path of the application
|
||||
/// </summary>
|
||||
public static string Root
|
||||
{
|
||||
get
|
||||
{
|
||||
string appPath = HttpRuntime.AppDomainAppVirtualPath ?? string.Empty;
|
||||
if (appPath == "/")
|
||||
appPath = string.Empty;
|
||||
if (_root == null)
|
||||
{
|
||||
string appPath = HttpRuntime.AppDomainAppVirtualPath ?? string.Empty;
|
||||
if (appPath == "/")
|
||||
appPath = string.Empty;
|
||||
|
||||
return appPath;
|
||||
_root = appPath;
|
||||
}
|
||||
return _root;
|
||||
}
|
||||
//Only required for unit tests
|
||||
internal set { _root = value; }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
public enum IconPickerBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// Default umbraco behavior - show duplicates in files and sprites
|
||||
/// </summary>
|
||||
ShowDuplicates,
|
||||
|
||||
/// <summary>
|
||||
/// If a file exists on disk with the same name as one in the sprite
|
||||
/// then the file on disk overrules the one in the sprite, the
|
||||
/// sprite icon will not be shown
|
||||
/// </summary>
|
||||
HideSpriteDuplicates,
|
||||
|
||||
/// <summary>
|
||||
/// If a file exists on disk with the same name as one in the sprite
|
||||
/// then the file in the sprite overrules the one on disk, the file
|
||||
/// on disk will be shown
|
||||
/// </summary>
|
||||
HideFileDuplicates
|
||||
}
|
||||
}
|
||||
@@ -64,23 +64,28 @@ namespace Umbraco.Core.Logging
|
||||
{
|
||||
_forceStop = true;
|
||||
var windowsIdentity = WindowsIdentity.GetCurrent();
|
||||
base.Append(new LoggingEvent(new LoggingEventData
|
||||
{
|
||||
Level = Level.Error,
|
||||
Message =
|
||||
"Unable to clear out the AsynchronousRollingFileAppender buffer in the allotted time, forcing a shutdown",
|
||||
TimeStamp = DateTime.UtcNow,
|
||||
Identity = "",
|
||||
ExceptionString = "",
|
||||
UserName = windowsIdentity != null ? windowsIdentity.Name : "",
|
||||
Domain = AppDomain.CurrentDomain.FriendlyName,
|
||||
ThreadName = Thread.CurrentThread.ManagedThreadId.ToString(),
|
||||
LocationInfo =
|
||||
new LocationInfo(this.GetType().Name, "OnClose", "AsynchronousRollingFileAppender.cs", "59"),
|
||||
LoggerName = this.GetType().FullName,
|
||||
Properties = new PropertiesDictionary(),
|
||||
})
|
||||
);
|
||||
|
||||
var logEvent = new LoggingEvent(new LoggingEventData
|
||||
{
|
||||
Level = global::log4net.Core.Level.Error,
|
||||
Message =
|
||||
"Unable to clear out the AsynchronousRollingFileAppender buffer in the allotted time, forcing a shutdown",
|
||||
TimeStamp = DateTime.UtcNow,
|
||||
Identity = "",
|
||||
ExceptionString = "",
|
||||
UserName = windowsIdentity != null ? windowsIdentity.Name : "",
|
||||
Domain = AppDomain.CurrentDomain.FriendlyName,
|
||||
ThreadName = Thread.CurrentThread.ManagedThreadId.ToString(),
|
||||
LocationInfo =
|
||||
new LocationInfo(this.GetType().Name, "OnClose", "AsynchronousRollingFileAppender.cs", "59"),
|
||||
LoggerName = this.GetType().FullName,
|
||||
Properties = new PropertiesDictionary(),
|
||||
});
|
||||
|
||||
if (this.DateTimeStrategy != null)
|
||||
{
|
||||
base.Append(logEvent);
|
||||
}
|
||||
}
|
||||
|
||||
base.OnClose();
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
public enum MacroErrorBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// Default umbraco behavior - show an inline error within the
|
||||
/// macro but allow the page to continue rendering.
|
||||
/// </summary>
|
||||
Inline,
|
||||
|
||||
/// <summary>
|
||||
/// Silently eat the error and do not display the offending macro.
|
||||
/// </summary>
|
||||
Silent,
|
||||
|
||||
/// <summary>
|
||||
/// Throw an exception which can be caught by the global error handler
|
||||
/// defined in Application_OnError. If no such error handler is defined
|
||||
/// then you'll see the Yellow Screen Of Death (YSOD) error page.
|
||||
/// </summary>
|
||||
Throw
|
||||
}
|
||||
}
|
||||
@@ -117,8 +117,10 @@ namespace Umbraco.Core.Models
|
||||
if (fileName.LastIndexOf(@"\") > 0)
|
||||
fileName = fileName.Substring(fileName.LastIndexOf(@"\") + 1);
|
||||
|
||||
if (string.IsNullOrEmpty(fileName) == false)
|
||||
SetFileOnContent(content, propertyTypeAlias, fileName, value.InputStream);
|
||||
var name = IOHelper.SafeFileName(fileName);
|
||||
|
||||
if (string.IsNullOrEmpty(name) == false)
|
||||
SetFileOnContent(content, propertyTypeAlias, name, value.InputStream);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -131,8 +133,10 @@ namespace Umbraco.Core.Models
|
||||
public static void SetValue(this IContentBase content, string propertyTypeAlias, string fileName,
|
||||
Stream fileStream)
|
||||
{
|
||||
if (string.IsNullOrEmpty(fileName) == false && fileStream != null)
|
||||
SetFileOnContent(content, propertyTypeAlias, fileName, fileStream);
|
||||
var name = IOHelper.SafeFileName(fileName);
|
||||
|
||||
if (string.IsNullOrEmpty(name) == false && fileStream != null)
|
||||
SetFileOnContent(content, propertyTypeAlias, name, fileStream);
|
||||
}
|
||||
|
||||
private static void SetFileOnContent(IContentBase content, string propertyTypeAlias, string name, Stream fileStream)
|
||||
|
||||
@@ -381,7 +381,7 @@ namespace Umbraco.Core.Models
|
||||
oldPropertyGroup.PropertyTypes.RemoveItem(propertyTypeAlias);
|
||||
}
|
||||
|
||||
propertyType.PropertyGroupId = default(int);
|
||||
propertyType.PropertyGroupId = new Lazy<int>(() => default(int));
|
||||
propertyType.ResetDirtyProperties();
|
||||
|
||||
var propertyGroup = PropertyGroups.First(x => x.Name == propertyGroupName);
|
||||
|
||||
@@ -140,8 +140,8 @@ namespace Umbraco.Core.Models
|
||||
|
||||
if (CompositionPropertyGroups.Any(x => x.Name == groupName))
|
||||
{
|
||||
var first = CompositionPropertyGroups.First(x => x.Name == groupName && x.ParentId.HasValue == false);
|
||||
propertyGroup.ParentId = first.Id;
|
||||
var firstGroup = CompositionPropertyGroups.First(x => x.Name == groupName && x.ParentId.HasValue == false);
|
||||
propertyGroup.SetLazyParentId(new Lazy<int?>(() => firstGroup.Id));
|
||||
}
|
||||
|
||||
if (PropertyGroups.Any())
|
||||
@@ -166,7 +166,7 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
if (PropertyGroups.Contains(propertyGroupName))
|
||||
{
|
||||
propertyType.PropertyGroupId = PropertyGroups[propertyGroupName].Id;
|
||||
propertyType.PropertyGroupId = new Lazy<int>(() => PropertyGroups[propertyGroupName].Id);
|
||||
PropertyGroups[propertyGroupName].PropertyTypes.Add(propertyType);
|
||||
}
|
||||
else
|
||||
@@ -179,7 +179,8 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
var parentPropertyGroup = CompositionPropertyGroups.First(x => x.Name == propertyGroupName && x.ParentId.HasValue == false);
|
||||
propertyGroup.SortOrder = parentPropertyGroup.SortOrder;
|
||||
propertyGroup.ParentId = parentPropertyGroup.Id;
|
||||
//propertyGroup.ParentId = parentPropertyGroup.Id;
|
||||
propertyGroup.SetLazyParentId(new Lazy<int?>(() => parentPropertyGroup.Id));
|
||||
}
|
||||
|
||||
PropertyGroups.Add(propertyGroup);
|
||||
|
||||
@@ -8,6 +8,17 @@ namespace Umbraco.Core.Models
|
||||
/// </summary>
|
||||
public class ContentTypeSort : IValueObject
|
||||
{
|
||||
public ContentTypeSort()
|
||||
{
|
||||
}
|
||||
|
||||
public ContentTypeSort(Lazy<int> id, int sortOrder, string @alias)
|
||||
{
|
||||
Id = id;
|
||||
SortOrder = sortOrder;
|
||||
Alias = alias;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Id of the ContentType
|
||||
/// </summary>
|
||||
|
||||
@@ -15,12 +15,12 @@ namespace Umbraco.Core.Models
|
||||
public enum DataTypeDatabaseType
|
||||
{
|
||||
[EnumMember]
|
||||
Integer,
|
||||
[EnumMember]
|
||||
Date,
|
||||
Ntext,
|
||||
[EnumMember]
|
||||
Nvarchar,
|
||||
[EnumMember]
|
||||
Ntext /*, Object*/
|
||||
Integer,
|
||||
[EnumMember]
|
||||
Date
|
||||
}
|
||||
}
|
||||
@@ -172,7 +172,9 @@ namespace Umbraco.Core.Models
|
||||
internal override void AddingEntity()
|
||||
{
|
||||
base.AddingEntity();
|
||||
Key = Guid.NewGuid();
|
||||
|
||||
if(Key == default(Guid))
|
||||
Key = Guid.NewGuid();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -66,6 +66,15 @@ namespace Umbraco.Core.Models.EntityBase
|
||||
[DataMember]
|
||||
public DateTime UpdateDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the WasCancelled flag, which is used to track
|
||||
/// whether some action against an entity was cancelled through some event.
|
||||
/// This only exists so we have a way to check if an event was cancelled through
|
||||
/// the new api, which also needs to take effect in the legacy api.
|
||||
/// </summary>
|
||||
[IgnoreDataMember]
|
||||
internal bool WasCancelled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Property changed event
|
||||
/// </summary>
|
||||
@@ -159,19 +168,6 @@ namespace Umbraco.Core.Models.EntityBase
|
||||
}
|
||||
}
|
||||
|
||||
public static bool operator ==(Entity left, Entity right)
|
||||
{
|
||||
if (ReferenceEquals(null, left))
|
||||
return false;
|
||||
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
public static bool operator !=(Entity left, Entity right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
public virtual bool SameIdentityAs(IEntity other)
|
||||
{
|
||||
if (ReferenceEquals(null, other))
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
@@ -10,7 +11,7 @@ namespace Umbraco.Core.Models
|
||||
/// <remarks>
|
||||
/// A replacement for INode which needs to occur since INode doesn't contain the document type alias
|
||||
/// and INode is poorly formatted with mutable properties (i.e. Lists instead of IEnumerable)
|
||||
/// </remarks>
|
||||
/// </remarks>
|
||||
public interface IPublishedContent
|
||||
{
|
||||
int Id { get; }
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace Umbraco.Core.Models
|
||||
public class PropertyGroup : Entity, IEquatable<PropertyGroup>
|
||||
{
|
||||
private string _name;
|
||||
private int? _parentId;
|
||||
private Lazy<int?> _parentId;
|
||||
private int _sortOrder;
|
||||
private PropertyTypeCollection _propertyTypes;
|
||||
|
||||
@@ -60,10 +60,15 @@ namespace Umbraco.Core.Models
|
||||
[DataMember]
|
||||
public int? ParentId
|
||||
{
|
||||
get { return _parentId; }
|
||||
get
|
||||
{
|
||||
if (_parentId == null)
|
||||
return default(int?);
|
||||
return _parentId.Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
_parentId = value;
|
||||
_parentId = new Lazy<int?>(() => value);
|
||||
OnPropertyChanged(ParentIdSelector);
|
||||
}
|
||||
}
|
||||
@@ -96,6 +101,15 @@ namespace Umbraco.Core.Models
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the ParentId from the lazy integer id
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the Parent</param>
|
||||
internal void SetLazyParentId(Lazy<int?> id)
|
||||
{
|
||||
_parentId = id;
|
||||
}
|
||||
|
||||
public bool Equals(PropertyGroup other)
|
||||
{
|
||||
//Check whether the compared object is null.
|
||||
|
||||
@@ -13,12 +13,11 @@ namespace Umbraco.Core.Models
|
||||
[DataContract(IsReference = true)]
|
||||
public class PropertyType : Entity, IEquatable<PropertyType>
|
||||
{
|
||||
//private SerializationService _service;
|
||||
private string _name;
|
||||
private string _alias;
|
||||
private string _description;
|
||||
private int _dataTypeDefinitionId;
|
||||
private int _propertyGroupId;
|
||||
private Lazy<int> _propertyGroupId;
|
||||
private Guid _dataTypeId;
|
||||
private DataTypeDatabaseType _dataTypeDatabaseType;
|
||||
private bool _mandatory;
|
||||
@@ -33,22 +32,12 @@ namespace Umbraco.Core.Models
|
||||
|
||||
DataTypeId = dataTypeDefinition.ControlId;
|
||||
DataTypeDatabaseType = dataTypeDefinition.DatabaseType;
|
||||
|
||||
EnsureSerializationService();
|
||||
}
|
||||
|
||||
internal PropertyType(Guid dataTypeControlId, DataTypeDatabaseType dataTypeDatabaseType)
|
||||
{
|
||||
DataTypeId = dataTypeControlId;
|
||||
DataTypeDatabaseType = dataTypeDatabaseType;
|
||||
|
||||
EnsureSerializationService();
|
||||
}
|
||||
|
||||
private void EnsureSerializationService()
|
||||
{
|
||||
/*var serviceStackSerializer = new ServiceStackXmlSerializer();
|
||||
_service = new SerializationService(serviceStackSerializer);*/
|
||||
}
|
||||
|
||||
private static readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo<PropertyType, string>(x => x.Name);
|
||||
@@ -61,7 +50,7 @@ namespace Umbraco.Core.Models
|
||||
private static readonly PropertyInfo HelpTextSelector = ExpressionHelper.GetPropertyInfo<PropertyType, string>(x => x.HelpText);
|
||||
private static readonly PropertyInfo SortOrderSelector = ExpressionHelper.GetPropertyInfo<PropertyType, int>(x => x.SortOrder);
|
||||
private static readonly PropertyInfo ValidationRegExpSelector = ExpressionHelper.GetPropertyInfo<PropertyType, string>(x => x.ValidationRegExp);
|
||||
private static readonly PropertyInfo PropertyGroupIdSelector = ExpressionHelper.GetPropertyInfo<PropertyType, int>(x => x.PropertyGroupId);
|
||||
private static readonly PropertyInfo PropertyGroupIdSelector = ExpressionHelper.GetPropertyInfo<PropertyType, Lazy<int>>(x => x.PropertyGroupId);
|
||||
|
||||
/// <summary>
|
||||
/// Gets of Sets the Name of the PropertyType
|
||||
@@ -153,7 +142,7 @@ namespace Umbraco.Core.Models
|
||||
/// Gets or Sets the PropertyGroup's Id for which this PropertyType belongs
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
internal int PropertyGroupId
|
||||
internal Lazy<int> PropertyGroupId
|
||||
{
|
||||
get { return _propertyGroupId; }
|
||||
set
|
||||
@@ -181,6 +170,7 @@ namespace Umbraco.Core.Models
|
||||
/// Gets of Sets the Help text for the current PropertyType
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
[Obsolete("Not used anywhere in the UI")]
|
||||
public string HelpText
|
||||
{
|
||||
get { return _helpText; }
|
||||
@@ -209,7 +199,7 @@ namespace Umbraco.Core.Models
|
||||
/// Gets or Sets the RegEx for validation of legacy DataTypes
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
internal string ValidationRegExp
|
||||
public string ValidationRegExp
|
||||
{
|
||||
get { return _validationRegExp; }
|
||||
set
|
||||
@@ -218,7 +208,6 @@ namespace Umbraco.Core.Models
|
||||
OnPropertyChanged(ValidationRegExpSelector);
|
||||
}
|
||||
}
|
||||
//Note that Validation should eventually come from PropertyEditors like in v5
|
||||
|
||||
/// <summary>
|
||||
/// Create a new Property object from a "raw" database value.
|
||||
@@ -335,8 +324,8 @@ namespace Umbraco.Core.Models
|
||||
if (Mandatory && (value == null || string.IsNullOrEmpty(value.ToString())))
|
||||
return false;
|
||||
|
||||
//Check against Regular Expression for Legacy DataTypes
|
||||
if(!string.IsNullOrEmpty(ValidationRegExp))
|
||||
//Check against Regular Expression for Legacy DataTypes - Validation exists and value is not null:
|
||||
if(string.IsNullOrEmpty(ValidationRegExp) == false && (value != null && string.IsNullOrEmpty(value.ToString()) == false))
|
||||
{
|
||||
var regexPattern = new Regex(ValidationRegExp);
|
||||
return regexPattern.IsMatch(value.ToString());
|
||||
|
||||
@@ -28,12 +28,8 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
base.Path = path;
|
||||
ParentId = -1;
|
||||
Key = name.EncodeAsGuid();
|
||||
_name = name;
|
||||
_alias = alias;
|
||||
|
||||
CreateDate = DateTime.Now;
|
||||
UpdateDate = DateTime.Now;
|
||||
_name = name.Replace("/", ".").Replace("\\", "");
|
||||
_alias = alias.ToSafeAlias();
|
||||
}
|
||||
|
||||
[DataMember]
|
||||
@@ -52,7 +48,7 @@ namespace Umbraco.Core.Models
|
||||
internal string NodePath { get; set; }
|
||||
|
||||
[DataMember]
|
||||
internal int MasterTemplateId { get; set; }
|
||||
internal Lazy<int> MasterTemplateId { get; set; }
|
||||
|
||||
[DataMember]
|
||||
internal string MasterTemplateAlias { get; set; }
|
||||
@@ -116,5 +112,17 @@ namespace Umbraco.Core.Models
|
||||
|
||||
return validFile && validExtension;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method to call when Entity is being saved
|
||||
/// </summary>
|
||||
/// <remarks>Created date is set and a Unique key is assigned</remarks>
|
||||
internal override void AddingEntity()
|
||||
{
|
||||
base.AddingEntity();
|
||||
|
||||
if (Key == Guid.Empty)
|
||||
Key = Guid.NewGuid();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.Web;
|
||||
using Umbraco.Core.Configuration;
|
||||
|
||||
@@ -16,7 +17,12 @@ namespace Umbraco.Core.Persistence
|
||||
private readonly string _connectionStringName;
|
||||
private readonly string _connectionString;
|
||||
private readonly string _providerName;
|
||||
private static volatile UmbracoDatabase _globalInstance = null;
|
||||
|
||||
//very important to have ThreadStatic:
|
||||
// see: http://issues.umbraco.org/issue/U4-2172
|
||||
[ThreadStatic]
|
||||
private static volatile UmbracoDatabase _nonHttpInstance;
|
||||
|
||||
private static readonly object Locker = new object();
|
||||
|
||||
/// <summary>
|
||||
@@ -55,27 +61,27 @@ namespace Umbraco.Core.Persistence
|
||||
//no http context, create the singleton global object
|
||||
if (HttpContext.Current == null)
|
||||
{
|
||||
if (_globalInstance == null)
|
||||
if (_nonHttpInstance == null)
|
||||
{
|
||||
lock (Locker)
|
||||
{
|
||||
//double check
|
||||
if (_globalInstance == null)
|
||||
if (_nonHttpInstance == null)
|
||||
{
|
||||
_globalInstance = string.IsNullOrEmpty(_providerName) == false && string.IsNullOrEmpty(_providerName) == false
|
||||
_nonHttpInstance = string.IsNullOrEmpty(_connectionString) == false && string.IsNullOrEmpty(_providerName) == false
|
||||
? new UmbracoDatabase(_connectionString, _providerName)
|
||||
: new UmbracoDatabase(_connectionStringName);
|
||||
}
|
||||
}
|
||||
}
|
||||
return _globalInstance;
|
||||
return _nonHttpInstance;
|
||||
}
|
||||
|
||||
//we have an http context, so only create one per request
|
||||
if (!HttpContext.Current.Items.Contains(typeof(DefaultDatabaseFactory)))
|
||||
if (HttpContext.Current.Items.Contains(typeof(DefaultDatabaseFactory)) == false)
|
||||
{
|
||||
HttpContext.Current.Items.Add(typeof (DefaultDatabaseFactory),
|
||||
string.IsNullOrEmpty(_providerName) == false && string.IsNullOrEmpty(_providerName) == false
|
||||
string.IsNullOrEmpty(_connectionString) == false && string.IsNullOrEmpty(_providerName) == false
|
||||
? new UmbracoDatabase(_connectionString, _providerName)
|
||||
: new UmbracoDatabase(_connectionStringName));
|
||||
}
|
||||
@@ -86,7 +92,7 @@ namespace Umbraco.Core.Persistence
|
||||
{
|
||||
if (HttpContext.Current == null)
|
||||
{
|
||||
_globalInstance.Dispose();
|
||||
_nonHttpInstance.Dispose();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -51,7 +51,8 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
UpdateDate = dto.ContentVersionDto.VersionDate,
|
||||
ExpireDate = dto.ExpiresDate.HasValue ? dto.ExpiresDate.Value : (DateTime?)null,
|
||||
ReleaseDate = dto.ReleaseDate.HasValue ? dto.ReleaseDate.Value : (DateTime?)null,
|
||||
Version = dto.ContentVersionDto.VersionId
|
||||
Version = dto.ContentVersionDto.VersionId,
|
||||
PublishedState = dto.Published ? PublishedState.Published : PublishedState.Unpublished
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -8,23 +8,26 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
{
|
||||
internal class PropertyFactory : IEntityFactory<IEnumerable<Property>, IEnumerable<PropertyDataDto>>
|
||||
{
|
||||
private readonly IContentType _contentType;
|
||||
private readonly IMediaType _mediaType;
|
||||
private readonly IContentTypeComposition _contentType;
|
||||
private readonly Guid _version;
|
||||
private readonly int _id;
|
||||
private readonly DateTime _createDate;
|
||||
private readonly DateTime _updateDate;
|
||||
|
||||
public PropertyFactory(IContentType contentType, Guid version, int id)
|
||||
public PropertyFactory(IContentTypeComposition contentType, Guid version, int id)
|
||||
{
|
||||
_contentType = contentType;
|
||||
_version = version;
|
||||
_id = id;
|
||||
}
|
||||
|
||||
public PropertyFactory(IMediaType mediaType, Guid version, int id)
|
||||
public PropertyFactory(IContentTypeComposition contentType, Guid version, int id, DateTime createDate, DateTime updateDate)
|
||||
{
|
||||
_mediaType = mediaType;
|
||||
_contentType = contentType;
|
||||
_version = version;
|
||||
_id = id;
|
||||
_createDate = createDate;
|
||||
_updateDate = updateDate;
|
||||
}
|
||||
|
||||
#region Implementation of IEntityFactory<IContent,PropertyDataDto>
|
||||
@@ -42,6 +45,8 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
propertyDataDto.VersionId.Value,
|
||||
propertyDataDto.Id);
|
||||
|
||||
property.CreateDate = _createDate;
|
||||
property.UpdateDate = _updateDate;
|
||||
property.ResetDirtyProperties();
|
||||
properties.Add(property);
|
||||
}
|
||||
@@ -98,22 +103,5 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public IEnumerable<Property> BuildMediaEntity(IEnumerable<PropertyDataDto> dtos)
|
||||
{
|
||||
var properties = new List<Property>();
|
||||
foreach (var dto in dtos)
|
||||
{
|
||||
if (_mediaType.CompositionPropertyTypes.Any(x => x.Id == dto.PropertyTypeId))
|
||||
{
|
||||
var propertyType = _mediaType.CompositionPropertyTypes.First(x => x.Id == dto.PropertyTypeId);
|
||||
var property = propertyType.CreatePropertyFromRawValue(dto.GetValue, dto.VersionId.Value, dto.Id);
|
||||
|
||||
property.ResetDirtyProperties();
|
||||
properties.Add(property);
|
||||
}
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
@@ -8,12 +9,21 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
internal class PropertyGroupFactory : IEntityFactory<IEnumerable<PropertyGroup>, IEnumerable<PropertyTypeGroupDto>>
|
||||
{
|
||||
private readonly int _id;
|
||||
private readonly DateTime _createDate;
|
||||
private readonly DateTime _updateDate;
|
||||
|
||||
public PropertyGroupFactory(int id)
|
||||
{
|
||||
_id = id;
|
||||
}
|
||||
|
||||
public PropertyGroupFactory(int id, DateTime createDate, DateTime updateDate)
|
||||
{
|
||||
_id = id;
|
||||
_createDate = createDate;
|
||||
_updateDate = updateDate;
|
||||
}
|
||||
|
||||
#region Implementation of IEntityFactory<IEnumerable<PropertyGroup>,IEnumerable<TabDto>>
|
||||
|
||||
public IEnumerable<PropertyGroup> BuildEntity(IEnumerable<PropertyTypeGroupDto> dto)
|
||||
@@ -44,6 +54,7 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
var typeDtos = groupDto.PropertyTypeDtos.Where(x => x.Id > 0);
|
||||
foreach (var typeDto in typeDtos)
|
||||
{
|
||||
var tempGroupDto = groupDto;
|
||||
var propertyType = new PropertyType(typeDto.DataTypeDto.ControlId,
|
||||
typeDto.DataTypeDto.DbType.EnumParse<DataTypeDatabaseType>(true))
|
||||
{
|
||||
@@ -56,7 +67,9 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
Mandatory = typeDto.Mandatory,
|
||||
SortOrder = typeDto.SortOrder,
|
||||
ValidationRegExp = typeDto.ValidationRegExp,
|
||||
PropertyGroupId = groupDto.Id
|
||||
PropertyGroupId = new Lazy<int>(() => tempGroupDto.Id),
|
||||
CreateDate = _createDate,
|
||||
UpdateDate = _updateDate
|
||||
};
|
||||
|
||||
propertyType.ResetDirtyProperties();
|
||||
|
||||
@@ -28,17 +28,22 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
|
||||
public Template BuildEntity(TemplateDto dto)
|
||||
{
|
||||
return new Template(string.Empty, dto.NodeDto.Text, dto.Alias)
|
||||
{
|
||||
CreateDate = dto.NodeDto.CreateDate,
|
||||
Id = dto.NodeId,
|
||||
Key = dto.NodeDto.UniqueId.Value,
|
||||
CreatorId = dto.NodeDto.UserId.Value,
|
||||
Level = dto.NodeDto.Level,
|
||||
ParentId = dto.NodeDto.ParentId,
|
||||
SortOrder = dto.NodeDto.SortOrder,
|
||||
NodePath = dto.NodeDto.Path
|
||||
};
|
||||
var template = new Template(string.Empty, dto.NodeDto.Text, dto.Alias)
|
||||
{
|
||||
CreateDate = dto.NodeDto.CreateDate,
|
||||
Id = dto.NodeId,
|
||||
Key = dto.NodeDto.UniqueId.Value,
|
||||
CreatorId = dto.NodeDto.UserId.Value,
|
||||
Level = dto.NodeDto.Level,
|
||||
ParentId = dto.NodeDto.ParentId,
|
||||
SortOrder = dto.NodeDto.SortOrder,
|
||||
NodePath = dto.NodeDto.Path
|
||||
};
|
||||
|
||||
if(dto.Master.HasValue)
|
||||
template.MasterTemplateId = new Lazy<int>(() => dto.Master.Value);
|
||||
|
||||
return template;
|
||||
}
|
||||
|
||||
public TemplateDto BuildDto(Template entity)
|
||||
@@ -50,6 +55,11 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
NodeDto = BuildNodeDto(entity)
|
||||
};
|
||||
|
||||
if (entity.MasterTemplateId != null && entity.MasterTemplateId.Value != default(int))
|
||||
{
|
||||
dto.Master = entity.MasterTemplateId.Value;
|
||||
}
|
||||
|
||||
if (entity.HasIdentity)
|
||||
{
|
||||
dto.NodeId = entity.Id;
|
||||
|
||||
@@ -30,8 +30,8 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
string columnName = columnAttribute.Name;
|
||||
|
||||
string columnMap = string.Format("{0}.{1}",
|
||||
SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(tableName),
|
||||
SyntaxConfig.SqlSyntaxProvider.GetQuotedColumnName(columnName));
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(tableName),
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName(columnName));
|
||||
return columnMap;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Events;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
@@ -54,15 +55,39 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
|
||||
{34, typeof (TaskTypeDto)},
|
||||
{35, typeof (TaskDto)},
|
||||
{36, typeof (ContentType2ContentTypeDto)},
|
||||
{
|
||||
37,
|
||||
typeof (ContentTypeAllowedContentTypeDto)
|
||||
},
|
||||
{37, typeof (ContentTypeAllowedContentTypeDto)},
|
||||
{38, typeof (User2AppDto)},
|
||||
{39, typeof (User2NodeNotifyDto)},
|
||||
{40, typeof (User2NodePermissionDto)}
|
||||
};
|
||||
#endregion
|
||||
/// <summary>
|
||||
/// Drops all Umbraco tables in the db
|
||||
/// </summary>
|
||||
internal void UninstallDatabaseSchema()
|
||||
{
|
||||
LogHelper.Info<DatabaseSchemaCreation>("Start UninstallDatabaseSchema");
|
||||
|
||||
foreach (var item in OrderedTables.OrderByDescending(x => x.Key))
|
||||
{
|
||||
var tableNameAttribute = item.Value.FirstAttribute<TableNameAttribute>();
|
||||
|
||||
string tableName = tableNameAttribute == null ? item.Value.Name : tableNameAttribute.Value;
|
||||
|
||||
LogHelper.Info<DatabaseSchemaCreation>("Uninstall" + tableName);
|
||||
|
||||
try
|
||||
{
|
||||
_database.DropTable(tableName);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
//swallow this for now, not sure how best to handle this with diff databases... though this is internal
|
||||
// and only used for unit tests. If this fails its because the table doesn't exist... generally!
|
||||
LogHelper.Error<DatabaseSchemaCreation>("Could not drop table " + tableName, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public DatabaseSchemaCreation(Database database)
|
||||
{
|
||||
@@ -102,7 +127,7 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
|
||||
}
|
||||
|
||||
//Check tables in configured database against tables in schema
|
||||
var tablesInDatabase = SyntaxConfig.SqlSyntaxProvider.GetTablesInSchema(_database).ToList();
|
||||
var tablesInDatabase = SqlSyntaxContext.SqlSyntaxProvider.GetTablesInSchema(_database).ToList();
|
||||
var tablesInSchema = result.TableDefinitions.Select(x => x.Name).ToList();
|
||||
//Add valid and invalid table differences to the result object
|
||||
var validTableDifferences = tablesInDatabase.Intersect(tablesInSchema);
|
||||
@@ -117,7 +142,7 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
|
||||
}
|
||||
|
||||
//Check columns in configured database against columns in schema
|
||||
var columnsInDatabase = SyntaxConfig.SqlSyntaxProvider.GetColumnsInSchema(_database);
|
||||
var columnsInDatabase = SqlSyntaxContext.SqlSyntaxProvider.GetColumnsInSchema(_database);
|
||||
var columnsPerTableInDatabase = columnsInDatabase.Select(x => string.Concat(x.TableName, ",", x.ColumnName)).ToList();
|
||||
var columnsPerTableInSchema = result.TableDefinitions.SelectMany(x => x.Columns.Select(y => string.Concat(y.TableName, ",", y.Name))).ToList();
|
||||
//Add valid and invalid column differences to the result object
|
||||
@@ -134,11 +159,11 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
|
||||
|
||||
//MySql doesn't conform to the "normal" naming of constraints, so there is currently no point in doing these checks.
|
||||
//NOTE: At a later point we do other checks for MySql, but ideally it should be necessary to do special checks for different providers.
|
||||
if (SyntaxConfig.SqlSyntaxProvider is MySqlSyntaxProvider)
|
||||
if (SqlSyntaxContext.SqlSyntaxProvider is MySqlSyntaxProvider)
|
||||
return result;
|
||||
|
||||
//Check constraints in configured database against constraints in schema
|
||||
var constraintsInDatabase = SyntaxConfig.SqlSyntaxProvider.GetConstraintsPerColumn(_database).DistinctBy(x => x.Item3).ToList();
|
||||
var constraintsInDatabase = SqlSyntaxContext.SqlSyntaxProvider.GetConstraintsPerColumn(_database).DistinctBy(x => x.Item3).ToList();
|
||||
var foreignKeysInDatabase = constraintsInDatabase.Where(x => x.Item3.StartsWith("FK_")).Select(x => x.Item3).ToList();
|
||||
var primaryKeysInDatabase = constraintsInDatabase.Where(x => x.Item3.StartsWith("PK_")).Select(x => x.Item3).ToList();
|
||||
var indexesInDatabase = constraintsInDatabase.Where(x => x.Item3.StartsWith("IX_")).Select(x => x.Item3).ToList();
|
||||
|
||||
@@ -111,7 +111,7 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
|
||||
sb.AppendLine(" ");
|
||||
}
|
||||
|
||||
if (SyntaxConfig.SqlSyntaxProvider is MySqlSyntaxProvider)
|
||||
if (SqlSyntaxContext.SqlSyntaxProvider is MySqlSyntaxProvider)
|
||||
{
|
||||
sb.AppendLine("Please note that the constraints could not be validated because the current dataprovider is MySql.");
|
||||
}
|
||||
|
||||
+3
-3
@@ -21,9 +21,9 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Alter.Expressions
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format(SyntaxConfig.SqlSyntaxProvider.AlterColumn,
|
||||
SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(TableName),
|
||||
SyntaxConfig.SqlSyntaxProvider.GetQuotedColumnName(Column.Name));
|
||||
return string.Format(SqlSyntaxContext.SqlSyntaxProvider.AlterColumn,
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(TableName),
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName(Column.Name));
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -22,9 +22,9 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Alter.Expressions
|
||||
{
|
||||
//NOTE Should probably investigate if Deleting a Default Constraint is different from deleting a 'regular' constraint
|
||||
|
||||
return string.Format(SyntaxConfig.SqlSyntaxProvider.DeleteConstraint,
|
||||
SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(TableName),
|
||||
SyntaxConfig.SqlSyntaxProvider.GetQuotedName(ConstraintName));
|
||||
return string.Format(SqlSyntaxContext.SqlSyntaxProvider.DeleteConstraint,
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(TableName),
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedName(ConstraintName));
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
-5
@@ -17,7 +17,7 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Create.Expressions
|
||||
{
|
||||
var constraintType = (Constraint.IsPrimaryKeyConstraint) ? "PRIMARY KEY" : "UNIQUE";
|
||||
|
||||
if (Constraint.IsPrimaryKeyConstraint && SyntaxConfig.SqlSyntaxProvider.SupportsClustered())
|
||||
if (Constraint.IsPrimaryKeyConstraint && SqlSyntaxContext.SqlSyntaxProvider.SupportsClustered())
|
||||
constraintType += " CLUSTERED";
|
||||
|
||||
if (Constraint.IsNonUniqueConstraint)
|
||||
@@ -27,12 +27,12 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Create.Expressions
|
||||
|
||||
for (int i = 0; i < Constraint.Columns.Count; i++)
|
||||
{
|
||||
columns[i] = SyntaxConfig.SqlSyntaxProvider.GetQuotedColumnName(Constraint.Columns.ElementAt(i));
|
||||
columns[i] = SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName(Constraint.Columns.ElementAt(i));
|
||||
}
|
||||
|
||||
return string.Format(SyntaxConfig.SqlSyntaxProvider.CreateConstraint,
|
||||
SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(Constraint.TableName),
|
||||
SyntaxConfig.SqlSyntaxProvider.GetQuotedName(Constraint.ConstraintName),
|
||||
return string.Format(SqlSyntaxContext.SqlSyntaxProvider.CreateConstraint,
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(Constraint.TableName),
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedName(Constraint.ConstraintName),
|
||||
constraintType,
|
||||
string.Join(", ", columns));
|
||||
}
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Create.Expressions
|
||||
{
|
||||
var table = new TableDefinition{Name = TableName, SchemaName = SchemaName, Columns = Columns};
|
||||
|
||||
return string.Format(SyntaxConfig.SqlSyntaxProvider.Format(table));
|
||||
return string.Format(SqlSyntaxContext.SqlSyntaxProvider.Format(table));
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -31,9 +31,9 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete.Expressions
|
||||
foreach (string columnName in ColumnNames)
|
||||
{
|
||||
if (ColumnNames.First() != columnName) sb.AppendLine(";");
|
||||
sb.AppendFormat(SyntaxConfig.SqlSyntaxProvider.DropColumn,
|
||||
SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(TableName),
|
||||
SyntaxConfig.SqlSyntaxProvider.GetQuotedColumnName(columnName));
|
||||
sb.AppendFormat(SqlSyntaxContext.SqlSyntaxProvider.DropColumn,
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(TableName),
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName(columnName));
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
|
||||
+3
-3
@@ -14,9 +14,9 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete.Expressions
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format(SyntaxConfig.SqlSyntaxProvider.DeleteConstraint,
|
||||
SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(Constraint.TableName),
|
||||
SyntaxConfig.SqlSyntaxProvider.GetQuotedName(Constraint.ConstraintName));
|
||||
return string.Format(SqlSyntaxContext.SqlSyntaxProvider.DeleteConstraint,
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(Constraint.TableName),
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedName(Constraint.ConstraintName));
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
-5
@@ -32,7 +32,7 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete.Expressions
|
||||
|
||||
if (IsAllRows)
|
||||
{
|
||||
deleteItems.Add(string.Format(SyntaxConfig.SqlSyntaxProvider.DeleteData, SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(TableName), "1 = 1"));
|
||||
deleteItems.Add(string.Format(SqlSyntaxContext.SqlSyntaxProvider.DeleteData, SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(TableName), "1 = 1"));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -42,13 +42,13 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete.Expressions
|
||||
foreach (KeyValuePair<string, object> item in row)
|
||||
{
|
||||
whereClauses.Add(string.Format("{0} {1} {2}",
|
||||
SyntaxConfig.SqlSyntaxProvider.GetQuotedColumnName(item.Key),
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName(item.Key),
|
||||
item.Value == null ? "IS" : "=",
|
||||
SyntaxConfig.SqlSyntaxProvider.GetQuotedValue(item.Value.ToString())));
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedValue(item.Value.ToString())));
|
||||
}
|
||||
|
||||
deleteItems.Add(string.Format(SyntaxConfig.SqlSyntaxProvider.DeleteData,
|
||||
SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(TableName),
|
||||
deleteItems.Add(string.Format(SqlSyntaxContext.SqlSyntaxProvider.DeleteData,
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(TableName),
|
||||
String.Join(" AND ", whereClauses.ToArray())));
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete.Expressions
|
||||
if (IsExpressionSupported() == false)
|
||||
return string.Empty;
|
||||
|
||||
return string.Format(SyntaxConfig.SqlSyntaxProvider.DeleteDefaultConstraint,
|
||||
return string.Format(SqlSyntaxContext.SqlSyntaxProvider.DeleteDefaultConstraint,
|
||||
TableName,
|
||||
ColumnName);
|
||||
}
|
||||
|
||||
+6
-6
@@ -33,10 +33,10 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete.Expressions
|
||||
if (string.IsNullOrEmpty(ForeignKey.Name))
|
||||
ForeignKey.Name = string.Format("{0}_ibfk_1", ForeignKey.ForeignTable.ToLower());
|
||||
|
||||
return string.Format(SyntaxConfig.SqlSyntaxProvider.DeleteConstraint,
|
||||
SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(ForeignKey.ForeignTable),
|
||||
return string.Format(SqlSyntaxContext.SqlSyntaxProvider.DeleteConstraint,
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(ForeignKey.ForeignTable),
|
||||
"FOREIGN KEY ",
|
||||
SyntaxConfig.SqlSyntaxProvider.GetQuotedName(ForeignKey.Name));
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedName(ForeignKey.Name));
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(ForeignKey.Name))
|
||||
@@ -44,9 +44,9 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete.Expressions
|
||||
ForeignKey.Name = string.Format("FK_{0}_{1}", ForeignKey.ForeignTable, ForeignKey.PrimaryTable);
|
||||
}
|
||||
|
||||
return string.Format(SyntaxConfig.SqlSyntaxProvider.DeleteConstraint,
|
||||
SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(ForeignKey.ForeignTable),
|
||||
SyntaxConfig.SqlSyntaxProvider.GetQuotedName(ForeignKey.Name));
|
||||
return string.Format(SqlSyntaxContext.SqlSyntaxProvider.DeleteConstraint,
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(ForeignKey.ForeignTable),
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedName(ForeignKey.Name));
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -19,9 +19,9 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete.Expressions
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format(SyntaxConfig.SqlSyntaxProvider.DropIndex,
|
||||
SyntaxConfig.SqlSyntaxProvider.GetQuotedName(Index.Name),
|
||||
SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(Index.TableName));
|
||||
return string.Format(SqlSyntaxContext.SqlSyntaxProvider.DropIndex,
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedName(Index.Name),
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(Index.TableName));
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -17,8 +17,8 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete.Expressions
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format(SyntaxConfig.SqlSyntaxProvider.DropTable,
|
||||
SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(TableName));
|
||||
return string.Format(SqlSyntaxContext.SqlSyntaxProvider.DropTable,
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(TableName));
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -28,9 +28,9 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Expressions
|
||||
if (string.IsNullOrEmpty(Column.TableName))
|
||||
Column.TableName = TableName;
|
||||
|
||||
return string.Format(SyntaxConfig.SqlSyntaxProvider.AddColumn,
|
||||
SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(Column.TableName),
|
||||
SyntaxConfig.SqlSyntaxProvider.Format(Column));
|
||||
return string.Format(SqlSyntaxContext.SqlSyntaxProvider.AddColumn,
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(Column.TableName),
|
||||
SqlSyntaxContext.SqlSyntaxProvider.Format(Column));
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -23,7 +23,7 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Expressions
|
||||
if (IsExpressionSupported() == false)
|
||||
return string.Empty;
|
||||
|
||||
return SyntaxConfig.SqlSyntaxProvider.Format(ForeignKey);
|
||||
return SqlSyntaxContext.SqlSyntaxProvider.Format(ForeignKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,7 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Expressions
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return SyntaxConfig.SqlSyntaxProvider.Format(Index);
|
||||
return SqlSyntaxContext.SqlSyntaxProvider.Format(Index);
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -52,7 +52,7 @@ SELECT CONCAT(
|
||||
if (IsExpressionSupported() == false)
|
||||
return string.Empty;
|
||||
|
||||
return SyntaxConfig.SqlSyntaxProvider.FormatColumnRename(TableName, OldName, NewName);
|
||||
return SqlSyntaxContext.SqlSyntaxProvider.FormatColumnRename(TableName, OldName, NewName);
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -22,7 +22,7 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Rename.Expressions
|
||||
if (IsExpressionSupported() == false)
|
||||
return string.Empty;
|
||||
|
||||
return SyntaxConfig.SqlSyntaxProvider.FormatTableRename(OldName, NewName);
|
||||
return SqlSyntaxContext.SqlSyntaxProvider.FormatTableRename(OldName, NewName);
|
||||
}
|
||||
}
|
||||
}
|
||||
+6
-6
@@ -31,8 +31,8 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Update.Expressions
|
||||
foreach (var item in Set)
|
||||
{
|
||||
updateItems.Add(string.Format("{0} = {1}",
|
||||
SyntaxConfig.SqlSyntaxProvider.GetQuotedColumnName(item.Key),
|
||||
SyntaxConfig.SqlSyntaxProvider.GetQuotedValue(item.Value.ToString())));
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName(item.Key),
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedValue(item.Value.ToString())));
|
||||
}
|
||||
|
||||
if (IsAllRows)
|
||||
@@ -44,13 +44,13 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Update.Expressions
|
||||
foreach (var item in Where)
|
||||
{
|
||||
whereClauses.Add(string.Format("{0} {1} {2}",
|
||||
SyntaxConfig.SqlSyntaxProvider.GetQuotedColumnName(item.Key),
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName(item.Key),
|
||||
item.Value == null ? "IS" : "=",
|
||||
SyntaxConfig.SqlSyntaxProvider.GetQuotedValue(item.Value.ToString())));
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedValue(item.Value.ToString())));
|
||||
}
|
||||
}
|
||||
return string.Format(SyntaxConfig.SqlSyntaxProvider.UpdateData,
|
||||
SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(TableName),
|
||||
return string.Format(SqlSyntaxContext.SqlSyntaxProvider.UpdateData,
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(TableName),
|
||||
string.Join(", ", updateItems.ToArray()),
|
||||
string.Join(" AND ", whereClauses.ToArray()));
|
||||
}
|
||||
|
||||
@@ -33,10 +33,10 @@ namespace Umbraco.Core.Persistence
|
||||
var tableDefinition = DefinitionFactory.GetTableDefinition(modelType);
|
||||
var tableName = tableDefinition.Name;
|
||||
|
||||
string createSql = SyntaxConfig.SqlSyntaxProvider.Format(tableDefinition);
|
||||
string createPrimaryKeySql = SyntaxConfig.SqlSyntaxProvider.FormatPrimaryKey(tableDefinition);
|
||||
var foreignSql = SyntaxConfig.SqlSyntaxProvider.Format(tableDefinition.ForeignKeys);
|
||||
var indexSql = SyntaxConfig.SqlSyntaxProvider.Format(tableDefinition.Indexes);
|
||||
string createSql = SqlSyntaxContext.SqlSyntaxProvider.Format(tableDefinition);
|
||||
string createPrimaryKeySql = SqlSyntaxContext.SqlSyntaxProvider.FormatPrimaryKey(tableDefinition);
|
||||
var foreignSql = SqlSyntaxContext.SqlSyntaxProvider.Format(tableDefinition.ForeignKeys);
|
||||
var indexSql = SqlSyntaxContext.SqlSyntaxProvider.Format(tableDefinition.Indexes);
|
||||
|
||||
var tableExist = db.TableExist(tableName);
|
||||
if (overwrite && tableExist)
|
||||
@@ -65,18 +65,18 @@ namespace Umbraco.Core.Persistence
|
||||
var e = new TableCreationEventArgs();
|
||||
|
||||
//Turn on identity insert if db provider is not mysql
|
||||
if (SyntaxConfig.SqlSyntaxProvider.SupportsIdentityInsert() && tableDefinition.Columns.Any(x => x.IsIdentity))
|
||||
db.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} ON ", SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(tableName))));
|
||||
if (SqlSyntaxContext.SqlSyntaxProvider.SupportsIdentityInsert() && tableDefinition.Columns.Any(x => x.IsIdentity))
|
||||
db.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} ON ", SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(tableName))));
|
||||
|
||||
//Call the NewTable-event to trigger the insert of base/default data
|
||||
NewTable(tableName, db, e);
|
||||
|
||||
//Turn off identity insert if db provider is not mysql
|
||||
if (SyntaxConfig.SqlSyntaxProvider.SupportsIdentityInsert() && tableDefinition.Columns.Any(x => x.IsIdentity))
|
||||
db.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} OFF;", SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(tableName))));
|
||||
if (SqlSyntaxContext.SqlSyntaxProvider.SupportsIdentityInsert() && tableDefinition.Columns.Any(x => x.IsIdentity))
|
||||
db.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} OFF;", SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(tableName))));
|
||||
|
||||
//Special case for MySql
|
||||
if (SyntaxConfig.SqlSyntaxProvider is MySqlSyntaxProvider && tableName.Equals("umbracoUser"))
|
||||
if (SqlSyntaxContext.SqlSyntaxProvider is MySqlSyntaxProvider && tableName.Equals("umbracoUser"))
|
||||
{
|
||||
db.Update<UserDto>("SET id = @IdAfter WHERE id = @IdBefore AND userLogin = @Login", new { IdAfter = 0, IdBefore = 1, Login = "admin" });
|
||||
}
|
||||
@@ -120,18 +120,28 @@ namespace Umbraco.Core.Persistence
|
||||
|
||||
public static void DropTable(this Database db, string tableName)
|
||||
{
|
||||
var sql = new Sql(string.Format("DROP TABLE {0}", SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(tableName)));
|
||||
var sql = new Sql(string.Format(
|
||||
SqlSyntaxContext.SqlSyntaxProvider.DropTable,
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(tableName)));
|
||||
db.Execute(sql);
|
||||
}
|
||||
|
||||
public static void TruncateTable(this Database db, string tableName)
|
||||
{
|
||||
var sql = new Sql(string.Format(
|
||||
SqlSyntaxContext.SqlSyntaxProvider.TruncateTable,
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(tableName)));
|
||||
db.Execute(sql);
|
||||
}
|
||||
|
||||
public static bool TableExist(this Database db, string tableName)
|
||||
{
|
||||
return SyntaxConfig.SqlSyntaxProvider.DoesTableExist(db, tableName);
|
||||
return SqlSyntaxContext.SqlSyntaxProvider.DoesTableExist(db, tableName);
|
||||
}
|
||||
|
||||
public static bool TableExist(this UmbracoDatabase db, string tableName)
|
||||
{
|
||||
return SyntaxConfig.SqlSyntaxProvider.DoesTableExist(db, tableName);
|
||||
return SqlSyntaxContext.SqlSyntaxProvider.DoesTableExist(db, tableName);
|
||||
}
|
||||
|
||||
public static void CreateDatabaseSchema(this Database db)
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace Umbraco.Core.Persistence
|
||||
var tableNameAttribute = type.FirstAttribute<TableNameAttribute>();
|
||||
string tableName = tableNameAttribute == null ? string.Empty : tableNameAttribute.Value;
|
||||
|
||||
return sql.From(SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(tableName));
|
||||
return sql.From(SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(tableName));
|
||||
}
|
||||
|
||||
public static Sql Where<T>(this Sql sql, Expression<Func<T, bool>> predicate)
|
||||
@@ -38,8 +38,8 @@ namespace Umbraco.Core.Persistence
|
||||
string tableName = tableNameAttribute == null ? string.Empty : tableNameAttribute.Value;
|
||||
|
||||
var syntax = string.Format("{0}.{1}",
|
||||
SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(tableName),
|
||||
SyntaxConfig.SqlSyntaxProvider.GetQuotedColumnName(columnName));
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(tableName),
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName(columnName));
|
||||
|
||||
return sql.OrderBy(syntax);
|
||||
}
|
||||
@@ -54,8 +54,8 @@ namespace Umbraco.Core.Persistence
|
||||
string tableName = tableNameAttribute == null ? string.Empty : tableNameAttribute.Value;
|
||||
|
||||
var syntax = string.Format("{0}.{1} DESC",
|
||||
SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(tableName),
|
||||
SyntaxConfig.SqlSyntaxProvider.GetQuotedColumnName(columnName));
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(tableName),
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName(columnName));
|
||||
|
||||
return sql.OrderBy(syntax);
|
||||
}
|
||||
@@ -65,7 +65,7 @@ namespace Umbraco.Core.Persistence
|
||||
var column = ExpressionHelper.FindProperty(columnMember) as PropertyInfo;
|
||||
var columnName = column.FirstAttribute<ColumnAttribute>().Name;
|
||||
|
||||
return sql.GroupBy(SyntaxConfig.SqlSyntaxProvider.GetQuotedColumnName(columnName));
|
||||
return sql.GroupBy(SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName(columnName));
|
||||
}
|
||||
|
||||
public static Sql.SqlJoinClause InnerJoin<T>(this Sql sql)
|
||||
@@ -74,7 +74,7 @@ namespace Umbraco.Core.Persistence
|
||||
var tableNameAttribute = type.FirstAttribute<TableNameAttribute>();
|
||||
string tableName = tableNameAttribute == null ? string.Empty : tableNameAttribute.Value;
|
||||
|
||||
return sql.InnerJoin(SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(tableName));
|
||||
return sql.InnerJoin(SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(tableName));
|
||||
}
|
||||
|
||||
public static Sql.SqlJoinClause LeftJoin<T>(this Sql sql)
|
||||
@@ -83,7 +83,7 @@ namespace Umbraco.Core.Persistence
|
||||
var tableNameAttribute = type.FirstAttribute<TableNameAttribute>();
|
||||
string tableName = tableNameAttribute == null ? string.Empty : tableNameAttribute.Value;
|
||||
|
||||
return sql.LeftJoin(SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(tableName));
|
||||
return sql.LeftJoin(SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(tableName));
|
||||
}
|
||||
|
||||
public static Sql.SqlJoinClause LeftOuterJoin<T>(this Sql sql)
|
||||
@@ -92,7 +92,7 @@ namespace Umbraco.Core.Persistence
|
||||
var tableNameAttribute = type.FirstAttribute<TableNameAttribute>();
|
||||
string tableName = tableNameAttribute == null ? string.Empty : tableNameAttribute.Value;
|
||||
|
||||
return sql.LeftOuterJoin(SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(tableName));
|
||||
return sql.LeftOuterJoin(SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(tableName));
|
||||
}
|
||||
|
||||
public static Sql.SqlJoinClause RightJoin<T>(this Sql sql)
|
||||
@@ -101,7 +101,7 @@ namespace Umbraco.Core.Persistence
|
||||
var tableNameAttribute = type.FirstAttribute<TableNameAttribute>();
|
||||
string tableName = tableNameAttribute == null ? string.Empty : tableNameAttribute.Value;
|
||||
|
||||
return sql.RightJoin(SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(tableName));
|
||||
return sql.RightJoin(SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(tableName));
|
||||
}
|
||||
|
||||
public static Sql On<TLeft, TRight>(this Sql.SqlJoinClause sql, Expression<Func<TLeft, object>> leftMember,
|
||||
@@ -118,10 +118,10 @@ namespace Umbraco.Core.Persistence
|
||||
var rightColumnName = right.FirstAttribute<ColumnAttribute>().Name;
|
||||
|
||||
string onClause = string.Format("{0}.{1} = {2}.{3}",
|
||||
SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(leftTableName),
|
||||
SyntaxConfig.SqlSyntaxProvider.GetQuotedColumnName(leftColumnName),
|
||||
SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(rightTableName),
|
||||
SyntaxConfig.SqlSyntaxProvider.GetQuotedColumnName(rightColumnName));
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(leftTableName),
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName(leftColumnName),
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(rightTableName),
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName(rightColumnName));
|
||||
return sql.On(onClause);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -455,9 +455,12 @@ namespace Umbraco.Core.Persistence.Querying
|
||||
if (fieldType == typeof(decimal))
|
||||
return ((decimal)value).ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
if(fieldType == typeof(DateTime))
|
||||
if (fieldType == typeof(DateTime))
|
||||
return "'" + EscapeParam(((DateTime)value).ToString(CultureInfo.InvariantCulture)) + "'";
|
||||
|
||||
|
||||
if (fieldType == typeof(bool))
|
||||
return ((bool)value) ? Convert.ToString(1, CultureInfo.InvariantCulture) : Convert.ToString(0, CultureInfo.InvariantCulture);
|
||||
|
||||
return ShouldQuoteValue(fieldType)
|
||||
? "'" + EscapeParam(value) + "'"
|
||||
: value.ToString();
|
||||
@@ -523,7 +526,8 @@ namespace Umbraco.Core.Persistence.Querying
|
||||
|
||||
protected bool IsFieldName(string quotedExp)
|
||||
{
|
||||
return true;
|
||||
//Not entirely sure this is reliable, but its better then simply returning true
|
||||
return quotedExp.LastIndexOf("'", StringComparison.InvariantCultureIgnoreCase) + 1 != quotedExp.Length;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -468,6 +468,9 @@ namespace Umbraco.Core.Persistence.Querying
|
||||
if(fieldType == typeof(DateTime))
|
||||
return "'" + EscapeParam(((DateTime)value).ToString(CultureInfo.InvariantCulture)) + "'";
|
||||
|
||||
if (fieldType == typeof(bool))
|
||||
return ((bool)value) ? Convert.ToString(1, CultureInfo.InvariantCulture) : Convert.ToString(0, CultureInfo.InvariantCulture);
|
||||
|
||||
return ShouldQuoteValue(fieldType)
|
||||
? "'" + EscapeParam(value) + "'"
|
||||
: value.ToString();
|
||||
@@ -487,8 +490,8 @@ namespace Umbraco.Core.Persistence.Querying
|
||||
{
|
||||
var column = pocoData.Columns.FirstOrDefault(x => x.Value.PropertyInfo.Name == name);
|
||||
return string.Format("{0}.{1}",
|
||||
SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(pocoData.TableInfo.TableName),
|
||||
SyntaxConfig.SqlSyntaxProvider.GetQuotedColumnName(column.Value.ColumnName));
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(pocoData.TableInfo.TableName),
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName(column.Value.ColumnName));
|
||||
}
|
||||
|
||||
protected string RemoveQuote(string exp)
|
||||
|
||||
@@ -266,8 +266,11 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
var parent = Database.First<NodeDto>("WHERE id = @ParentId", new { ParentId = entity.ParentId });
|
||||
entity.Path = string.Concat(parent.Path, ",", entity.Id);
|
||||
entity.Level = parent.Level + 1;
|
||||
var maxSortOrder = Database.ExecuteScalar<int>("SELECT coalesce(max(sortOrder),0) FROM umbracoNode WHERE parentid = @ParentId", new { ParentId = entity.ParentId });
|
||||
entity.SortOrder = maxSortOrder;
|
||||
var maxSortOrder =
|
||||
Database.ExecuteScalar<int>(
|
||||
"SELECT coalesce(max(sortOrder),0) FROM umbracoNode WHERE parentid = @ParentId AND nodeObjectType = @NodeObjectType",
|
||||
new {ParentId = entity.ParentId, NodeObjectType = NodeObjectTypeId});
|
||||
entity.SortOrder = maxSortOrder + 1;
|
||||
}
|
||||
|
||||
var factory = new ContentFactory(NodeObjectTypeId, entity.Id);
|
||||
@@ -398,6 +401,24 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
#region Implementation of IContentRepository
|
||||
|
||||
public IEnumerable<IContent> GetByPublishedVersion(IQuery<IContent> query)
|
||||
{
|
||||
var sqlClause = GetBaseQuery(false);
|
||||
var translator = new SqlTranslator<IContent>(sqlClause, query);
|
||||
var sql = translator.Translate()
|
||||
.Where<DocumentDto>(x => x.Published)
|
||||
.OrderByDescending<ContentVersionDto>(x => x.VersionDate)
|
||||
.OrderBy<NodeDto>(x => x.SortOrder);
|
||||
|
||||
//NOTE: This doesn't allow properties to be part of the query
|
||||
var dtos = Database.Fetch<DocumentDto, ContentVersionDto, ContentDto, NodeDto>(sql);
|
||||
|
||||
foreach (var dto in dtos)
|
||||
{
|
||||
yield return CreateContentFromDto(dto, dto.VersionId);
|
||||
}
|
||||
}
|
||||
|
||||
public IContent GetByLanguage(int id, string language)
|
||||
{
|
||||
var sql = GetBaseQuery(false);
|
||||
@@ -434,13 +455,13 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
content.Template = _templateRepository.Get(dto.TemplateId.Value);
|
||||
}
|
||||
|
||||
content.Properties = GetPropertyCollection(dto.NodeId, versionId, contentType);
|
||||
content.Properties = GetPropertyCollection(dto.NodeId, versionId, contentType, content.CreateDate, content.UpdateDate);
|
||||
|
||||
((ICanBeDirty)content).ResetDirtyProperties();
|
||||
return content;
|
||||
}
|
||||
|
||||
private PropertyCollection GetPropertyCollection(int id, Guid versionId, IContentType contentType)
|
||||
private PropertyCollection GetPropertyCollection(int id, Guid versionId, IContentType contentType, DateTime createDate, DateTime updateDate)
|
||||
{
|
||||
var sql = new Sql();
|
||||
sql.Select("*")
|
||||
@@ -451,7 +472,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
.Where<PropertyDataDto>(x => x.VersionId == versionId);
|
||||
|
||||
var propertyDataDtos = Database.Fetch<PropertyDataDto, PropertyTypeDto>(sql);
|
||||
var propertyFactory = new PropertyFactory(contentType, versionId, id);
|
||||
var propertyFactory = new PropertyFactory(contentType, versionId, id, createDate, updateDate);
|
||||
var properties = propertyFactory.BuildEntity(propertyDataDtos);
|
||||
|
||||
var newProperties = properties.Where(x => x.HasIdentity == false);
|
||||
|
||||
@@ -41,11 +41,11 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
.RightJoin<PropertyTypeDto>()
|
||||
.On<PropertyTypeGroupDto, PropertyTypeDto>(left => left.Id, right => right.PropertyTypeGroupId)
|
||||
.InnerJoin<DataTypeDto>()
|
||||
.On<PropertyTypeDto, DataTypeDto>(left => left.DataTypeId, right => right.DataTypeId)
|
||||
.OrderBy<PropertyTypeDto>(x => x.PropertyTypeGroupId);
|
||||
.On<PropertyTypeDto, DataTypeDto>(left => left.DataTypeId, right => right.DataTypeId);
|
||||
|
||||
var translator = new SqlTranslator<PropertyType>(sqlClause, query);
|
||||
var sql = translator.Translate();
|
||||
var sql = translator.Translate()
|
||||
.OrderBy<PropertyTypeDto>(x => x.PropertyTypeGroupId);
|
||||
|
||||
var dtos = Database.Fetch<PropertyTypeGroupDto, PropertyTypeDto, DataTypeDto, PropertyTypeGroupDto>(new GroupPropertyTypeRelator().Map, sql);
|
||||
|
||||
@@ -108,7 +108,12 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
//Insert collection of allowed content types
|
||||
foreach (var allowedContentType in entity.AllowedContentTypes)
|
||||
{
|
||||
Database.Insert(new ContentTypeAllowedContentTypeDto { Id = entity.Id, AllowedId = allowedContentType.Id.Value, SortOrder = allowedContentType.SortOrder });
|
||||
Database.Insert(new ContentTypeAllowedContentTypeDto
|
||||
{
|
||||
Id = entity.Id,
|
||||
AllowedId = allowedContentType.Id.Value,
|
||||
SortOrder = allowedContentType.SortOrder
|
||||
});
|
||||
}
|
||||
|
||||
var propertyFactory = new PropertyGroupFactory(nodeDto.NodeId);
|
||||
@@ -119,22 +124,31 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
var tabDto = propertyFactory.BuildGroupDto(propertyGroup);
|
||||
var primaryKey = Convert.ToInt32(Database.Insert(tabDto));
|
||||
propertyGroup.Id = primaryKey;//Set Id on PropertyGroup
|
||||
|
||||
//Ensure that the PropertyGroup's Id is set on the PropertyTypes within a group
|
||||
//unless the PropertyGroupId has already been changed.
|
||||
foreach (var propertyType in propertyGroup.PropertyTypes)
|
||||
{
|
||||
if (propertyType.IsPropertyDirty("PropertyGroupId") == false)
|
||||
{
|
||||
var tempGroup = propertyGroup;
|
||||
propertyType.PropertyGroupId = new Lazy<int>(() => tempGroup.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Insert PropertyTypes
|
||||
foreach (var propertyGroup in entity.PropertyGroups)
|
||||
foreach (var propertyType in entity.PropertyTypes)
|
||||
{
|
||||
foreach (var propertyType in propertyGroup.PropertyTypes)
|
||||
{
|
||||
var propertyTypeDto = propertyFactory.BuildPropertyTypeDto(propertyGroup.Id, propertyType);
|
||||
var primaryKey = Convert.ToInt32(Database.Insert(propertyTypeDto));
|
||||
propertyType.Id = primaryKey;//Set Id on PropertyType
|
||||
var tabId = propertyType.PropertyGroupId != null ? propertyType.PropertyGroupId.Value : default(int);
|
||||
var propertyTypeDto = propertyFactory.BuildPropertyTypeDto(tabId, propertyType);
|
||||
int typePrimaryKey = Convert.ToInt32(Database.Insert(propertyTypeDto));
|
||||
propertyType.Id = typePrimaryKey; //Set Id on new PropertyType
|
||||
|
||||
//Update the current PropertyType with correct ControlId and DatabaseType
|
||||
var dataTypeDto = Database.FirstOrDefault<DataTypeDto>("WHERE nodeId = @Id", new { Id = propertyTypeDto.DataTypeId });
|
||||
propertyType.DataTypeId = dataTypeDto.ControlId;
|
||||
propertyType.DataTypeDatabaseType = dataTypeDto.DbType.EnumParse<DataTypeDatabaseType>(true);
|
||||
}
|
||||
//Update the current PropertyType with correct ControlId and DatabaseType
|
||||
var dataTypeDto = Database.FirstOrDefault<DataTypeDto>("WHERE nodeId = @Id", new { Id = propertyTypeDto.DataTypeId });
|
||||
propertyType.DataTypeId = dataTypeDto.ControlId;
|
||||
propertyType.DataTypeDatabaseType = dataTypeDto.DbType.EnumParse<DataTypeDatabaseType>(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -267,15 +281,18 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
foreach (var propertyType in propertyGroup.PropertyTypes)
|
||||
{
|
||||
if (propertyType.IsPropertyDirty("PropertyGroupId") == false)
|
||||
propertyType.PropertyGroupId = propertyGroup.Id;
|
||||
{
|
||||
var tempGroup = propertyGroup;
|
||||
propertyType.PropertyGroupId = new Lazy<int>(() => tempGroup.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Run through all PropertyTypes to insert or update entries
|
||||
foreach (var propertyType in entity.PropertyTypes)
|
||||
{
|
||||
var propertyTypeDto = propertyGroupFactory.BuildPropertyTypeDto(propertyType.PropertyGroupId,
|
||||
propertyType);
|
||||
var tabId = propertyType.PropertyGroupId != null ? propertyType.PropertyGroupId.Value : default(int);
|
||||
var propertyTypeDto = propertyGroupFactory.BuildPropertyTypeDto(tabId, propertyType);
|
||||
int typePrimaryKey = propertyType.HasIdentity
|
||||
? Database.Update(propertyTypeDto)
|
||||
: Convert.ToInt32(Database.Insert(propertyTypeDto));
|
||||
@@ -295,7 +312,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
return allowedContentTypeDtos.Select(x => new ContentTypeSort { Id = new Lazy<int>(() => x.AllowedId), SortOrder = x.SortOrder }).ToList();
|
||||
}
|
||||
|
||||
protected PropertyGroupCollection GetPropertyGroupCollection(int id)
|
||||
protected PropertyGroupCollection GetPropertyGroupCollection(int id, DateTime createDate, DateTime updateDate)
|
||||
{
|
||||
var sql = new Sql();
|
||||
sql.Select("*")
|
||||
@@ -309,12 +326,12 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
var dtos = Database.Fetch<PropertyTypeGroupDto, PropertyTypeDto, DataTypeDto, PropertyTypeGroupDto>(new GroupPropertyTypeRelator().Map, sql);
|
||||
|
||||
var propertyGroupFactory = new PropertyGroupFactory(id);
|
||||
var propertyGroupFactory = new PropertyGroupFactory(id, createDate, updateDate);
|
||||
var propertyGroups = propertyGroupFactory.BuildEntity(dtos);
|
||||
return new PropertyGroupCollection(propertyGroups);
|
||||
}
|
||||
|
||||
protected PropertyTypeCollection GetPropertyTypeCollection(int id)
|
||||
protected PropertyTypeCollection GetPropertyTypeCollection(int id, DateTime createDate, DateTime updateDate)
|
||||
{
|
||||
var sql = new Sql();
|
||||
sql.Select("*")
|
||||
@@ -340,7 +357,9 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
HelpText = dto.HelpText,
|
||||
Mandatory = dto.Mandatory,
|
||||
SortOrder = dto.SortOrder,
|
||||
ValidationRegExp = dto.ValidationRegExp
|
||||
ValidationRegExp = dto.ValidationRegExp,
|
||||
CreateDate = createDate,
|
||||
UpdateDate = updateDate
|
||||
}).ToList();
|
||||
|
||||
//Reset dirty properties
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
@@ -50,8 +51,8 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
var contentType = factory.BuildEntity(dto);
|
||||
|
||||
contentType.AllowedContentTypes = GetAllowedContentTypeIds(id);
|
||||
contentType.PropertyGroups = GetPropertyGroupCollection(id);
|
||||
((ContentType)contentType).PropertyTypes = GetPropertyTypeCollection(id);
|
||||
contentType.PropertyGroups = GetPropertyGroupCollection(id, contentType.CreateDate, contentType.UpdateDate);
|
||||
((ContentType)contentType).PropertyTypes = GetPropertyTypeCollection(id, contentType.CreateDate, contentType.UpdateDate);
|
||||
|
||||
var templates = Database.Fetch<DocumentTypeDto>("WHERE contentTypeNodeId = @Id", new { Id = id });
|
||||
if(templates.Any())
|
||||
@@ -167,6 +168,19 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
protected override void PersistNewItem(IContentType entity)
|
||||
{
|
||||
Mandate.That<Exception>(string.IsNullOrEmpty(entity.Alias) == false,
|
||||
() =>
|
||||
{
|
||||
var message =
|
||||
string.Format(
|
||||
"ContentType '{0}' cannot have an empty Alias. This is most likely due to invalid characters stripped from the Alias.",
|
||||
entity.Name);
|
||||
var exception = new Exception(message);
|
||||
|
||||
LogHelper.Error<ContentTypeRepository>(message, exception);
|
||||
throw exception;
|
||||
});
|
||||
|
||||
((ContentType)entity).AddingEntity();
|
||||
|
||||
var factory = new ContentTypeFactory(NodeObjectTypeId);
|
||||
@@ -192,6 +206,19 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
protected override void PersistUpdatedItem(IContentType entity)
|
||||
{
|
||||
Mandate.That<Exception>(string.IsNullOrEmpty(entity.Alias) == false,
|
||||
() =>
|
||||
{
|
||||
var message =
|
||||
string.Format(
|
||||
"ContentType '{0}' cannot have an empty Alias. This is most likely due to invalid characters stripped from the Alias.",
|
||||
entity.Name);
|
||||
var exception = new Exception(message);
|
||||
|
||||
LogHelper.Error<ContentTypeRepository>(message, exception);
|
||||
throw exception;
|
||||
});
|
||||
|
||||
//Updates Modified date
|
||||
((ContentType)entity).UpdatingEntity();
|
||||
|
||||
@@ -200,6 +227,12 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
var parent = Database.First<NodeDto>("WHERE id = @ParentId", new { ParentId = entity.ParentId });
|
||||
entity.Path = string.Concat(parent.Path, ",", entity.Id);
|
||||
entity.Level = parent.Level + 1;
|
||||
var maxSortOrder =
|
||||
Database.ExecuteScalar<int>(
|
||||
"SELECT coalesce(max(sortOrder),0) FROM umbracoNode WHERE parentid = @ParentId AND nodeObjectType = @NodeObjectType",
|
||||
new { ParentId = entity.ParentId, NodeObjectType = NodeObjectTypeId });
|
||||
entity.SortOrder = maxSortOrder + 1;
|
||||
}
|
||||
|
||||
var factory = new ContentTypeFactory(NodeObjectTypeId);
|
||||
|
||||
@@ -159,6 +159,12 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
var parent = Database.First<NodeDto>("WHERE id = @ParentId", new { ParentId = entity.ParentId });
|
||||
entity.Path = string.Concat(parent.Path, ",", entity.Id);
|
||||
entity.Level = parent.Level + 1;
|
||||
var maxSortOrder =
|
||||
Database.ExecuteScalar<int>(
|
||||
"SELECT coalesce(max(sortOrder),0) FROM umbracoNode WHERE parentid = @ParentId AND nodeObjectType = @NodeObjectType",
|
||||
new { ParentId = entity.ParentId, NodeObjectType = NodeObjectTypeId });
|
||||
entity.SortOrder = maxSortOrder + 1;
|
||||
}
|
||||
|
||||
var factory = new DataTypeDefinitionFactory(NodeObjectTypeId);
|
||||
|
||||
@@ -111,6 +111,20 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
#endregion
|
||||
|
||||
protected IEnumerable<string> FindAllFiles(string path)
|
||||
{
|
||||
var list = new List<string>();
|
||||
list.AddRange(FileSystem.GetFiles(path, "*"));
|
||||
|
||||
var directories = FileSystem.GetDirectories(path);
|
||||
foreach (var directory in directories)
|
||||
{
|
||||
list.AddRange(FindAllFiles(directory));
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose any disposable properties
|
||||
/// </summary>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using Umbraco.Core.Models;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.Querying;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
@@ -11,5 +13,12 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// <param name="language">Culture code for the language to retrieve</param>
|
||||
/// <returns>An <see cref="IContent"/> item</returns>
|
||||
IContent GetByLanguage(int id, string language);
|
||||
|
||||
/// <summary>
|
||||
/// Gets all published Content byh the specified query
|
||||
/// </summary>
|
||||
/// <param name="query">Query to execute against published versions</param>
|
||||
/// <returns>An enumerable list of <see cref="IContent"/></returns>
|
||||
IEnumerable<IContent> GetByPublishedVersion(IQuery<IContent> query);
|
||||
}
|
||||
}
|
||||
@@ -51,7 +51,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
var factory = new MediaFactory(mediaType, NodeObjectTypeId, id);
|
||||
var media = factory.BuildEntity(dto);
|
||||
|
||||
media.Properties = GetPropertyCollection(id, dto.VersionId, mediaType);
|
||||
media.Properties = GetPropertyCollection(id, dto.VersionId, mediaType, media.CreateDate, media.UpdateDate);
|
||||
|
||||
((ICanBeDirty)media).ResetDirtyProperties();
|
||||
return media;
|
||||
@@ -118,6 +118,8 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
"DELETE FROM umbracoUser2NodeNotify WHERE nodeId = @Id",
|
||||
"DELETE FROM umbracoUser2NodePermission WHERE nodeId = @Id",
|
||||
"DELETE FROM umbracoRelation WHERE parentId = @Id",
|
||||
"DELETE FROM umbracoRelation WHERE childId = @Id",
|
||||
"DELETE FROM cmsTagRelationship WHERE nodeId = @Id",
|
||||
"DELETE FROM cmsDocument WHERE NodeId = @Id",
|
||||
"DELETE FROM cmsPropertyData WHERE contentNodeId = @Id",
|
||||
@@ -155,7 +157,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
var factory = new MediaFactory(mediaType, NodeObjectTypeId, dto.NodeId);
|
||||
var media = factory.BuildEntity(dto);
|
||||
|
||||
media.Properties = GetPropertyCollection(dto.NodeId, dto.VersionId, mediaType);
|
||||
media.Properties = GetPropertyCollection(dto.NodeId, dto.VersionId, mediaType, media.CreateDate, media.UpdateDate);
|
||||
|
||||
((ICanBeDirty)media).ResetDirtyProperties();
|
||||
return media;
|
||||
@@ -246,8 +248,11 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
var parent = Database.First<NodeDto>("WHERE id = @ParentId", new { ParentId = entity.ParentId });
|
||||
entity.Path = string.Concat(parent.Path, ",", entity.Id);
|
||||
entity.Level = parent.Level + 1;
|
||||
var maxSortOrder = Database.ExecuteScalar<int>("SELECT coalesce(max(sortOrder),0) FROM umbracoNode WHERE parentid = @ParentId", new { ParentId = entity.ParentId });
|
||||
entity.SortOrder = maxSortOrder;
|
||||
var maxSortOrder =
|
||||
Database.ExecuteScalar<int>(
|
||||
"SELECT coalesce(max(sortOrder),0) FROM umbracoNode WHERE parentid = @ParentId AND nodeObjectType = @NodeObjectType",
|
||||
new { ParentId = entity.ParentId, NodeObjectType = NodeObjectTypeId });
|
||||
entity.SortOrder = maxSortOrder + 1;
|
||||
}
|
||||
|
||||
var factory = new MediaFactory(NodeObjectTypeId, entity.Id);
|
||||
@@ -335,7 +340,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
#endregion
|
||||
|
||||
private PropertyCollection GetPropertyCollection(int id, Guid versionId, IMediaType contentType)
|
||||
private PropertyCollection GetPropertyCollection(int id, Guid versionId, IMediaType contentType, DateTime createDate, DateTime updateDate)
|
||||
{
|
||||
var sql = new Sql();
|
||||
sql.Select("*")
|
||||
@@ -346,8 +351,19 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
.Where<PropertyDataDto>(x => x.VersionId == versionId);
|
||||
|
||||
var propertyDataDtos = Database.Fetch<PropertyDataDto, PropertyTypeDto>(sql);
|
||||
var propertyFactory = new PropertyFactory(contentType, versionId, id);
|
||||
var properties = propertyFactory.BuildMediaEntity(propertyDataDtos);
|
||||
var propertyFactory = new PropertyFactory(contentType, versionId, id, createDate, updateDate);
|
||||
var properties = propertyFactory.BuildEntity(propertyDataDtos);
|
||||
|
||||
var newProperties = properties.Where(x => x.HasIdentity == false);
|
||||
foreach (var property in newProperties)
|
||||
{
|
||||
var propertyDataDto = new PropertyDataDto { NodeId = id, PropertyTypeId = property.PropertyTypeId, VersionId = versionId };
|
||||
int primaryKey = Convert.ToInt32(Database.Insert(propertyDataDto));
|
||||
|
||||
property.Version = versionId;
|
||||
property.Id = primaryKey;
|
||||
}
|
||||
|
||||
return new PropertyCollection(properties);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,8 +42,8 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
var contentType = factory.BuildEntity(dto);
|
||||
|
||||
contentType.AllowedContentTypes = GetAllowedContentTypeIds(id);
|
||||
contentType.PropertyGroups = GetPropertyGroupCollection(id);
|
||||
((MediaType)contentType).PropertyTypes = GetPropertyTypeCollection(id);
|
||||
contentType.PropertyGroups = GetPropertyGroupCollection(id, contentType.CreateDate, contentType.UpdateDate);
|
||||
((MediaType)contentType).PropertyTypes = GetPropertyTypeCollection(id, contentType.CreateDate, contentType.UpdateDate);
|
||||
|
||||
var list = Database.Fetch<ContentType2ContentTypeDto>("WHERE childContentTypeId = @Id", new{ Id = id});
|
||||
foreach (var contentTypeDto in list)
|
||||
@@ -168,6 +168,12 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
var parent = Database.First<NodeDto>("WHERE id = @ParentId", new { ParentId = entity.ParentId });
|
||||
entity.Path = string.Concat(parent.Path, ",", entity.Id);
|
||||
entity.Level = parent.Level + 1;
|
||||
var maxSortOrder =
|
||||
Database.ExecuteScalar<int>(
|
||||
"SELECT coalesce(max(sortOrder),0) FROM umbracoNode WHERE parentid = @ParentId AND nodeObjectType = @NodeObjectType",
|
||||
new { ParentId = entity.ParentId, NodeObjectType = NodeObjectTypeId });
|
||||
entity.SortOrder = maxSortOrder + 1;
|
||||
}
|
||||
|
||||
var factory = new MediaTypeFactory(NodeObjectTypeId);
|
||||
|
||||
@@ -45,12 +45,11 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
var path = FileSystem.GetRelativePath(id);
|
||||
var created = FileSystem.GetCreated(path).UtcDateTime;
|
||||
var updated = FileSystem.GetLastModified(path).UtcDateTime;
|
||||
var name = new FileInfo(path).Name;
|
||||
|
||||
var script = new Script(path)
|
||||
{
|
||||
Content = content,
|
||||
Key = name.EncodeAsGuid(),
|
||||
Key = path.EncodeAsGuid(),
|
||||
CreateDate = created,
|
||||
UpdateDate = updated
|
||||
};
|
||||
@@ -71,7 +70,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
}
|
||||
else
|
||||
{
|
||||
var files = FileSystem.GetFiles("", "*");
|
||||
var files = FindAllFiles("");
|
||||
foreach (var file in files)
|
||||
{
|
||||
yield return Get(file);
|
||||
|
||||
@@ -47,12 +47,11 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
var path = FileSystem.GetRelativePath(id);
|
||||
var created = FileSystem.GetCreated(path).UtcDateTime;
|
||||
var updated = FileSystem.GetLastModified(path).UtcDateTime;
|
||||
var name = new FileInfo(path).Name;
|
||||
|
||||
var stylesheet = new Stylesheet(path)
|
||||
{
|
||||
Content = content,
|
||||
Key = name.EncodeAsGuid(),
|
||||
Key = path.EncodeAsGuid(),
|
||||
CreateDate = created,
|
||||
UpdateDate = updated
|
||||
};
|
||||
@@ -73,7 +72,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
}
|
||||
else
|
||||
{
|
||||
var files = FileSystem.GetFiles("", "*");
|
||||
var files = FindAllFiles("");
|
||||
foreach (var file in files)
|
||||
{
|
||||
yield return Get(file);
|
||||
|
||||
@@ -71,7 +71,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
var masterTemplate = Get(dto.Master.Value);
|
||||
template.MasterTemplateAlias = masterTemplate.Alias;
|
||||
template.MasterTemplateId = dto.Master.Value;
|
||||
template.MasterTemplateId = new Lazy<int>(() => dto.Master.Value);
|
||||
}
|
||||
|
||||
if (_viewsFileSystem.FileExists(csViewName))
|
||||
@@ -172,16 +172,22 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
if (entity.GetTypeOfRenderingEngine() == RenderingEngine.Mvc)
|
||||
{
|
||||
_viewsFileSystem.AddFile(entity.Name, stream, true);
|
||||
string viewName = string.Concat(entity.Alias, ".cshtml");
|
||||
_viewsFileSystem.AddFile(viewName, stream, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
_masterpagesFileSystem.AddFile(entity.Name, stream, true);
|
||||
string masterpageName = string.Concat(entity.Alias, ".master");
|
||||
_masterpagesFileSystem.AddFile(masterpageName, stream, true);
|
||||
}
|
||||
}
|
||||
|
||||
//TODO Possibly ensure unique alias here (as is done in the legacy Template class)?
|
||||
|
||||
//Save to db
|
||||
var template = entity as Template;
|
||||
template.AddingEntity();
|
||||
|
||||
var factory = new TemplateFactory(NodeObjectTypeId);
|
||||
var dto = factory.BuildDto(template);
|
||||
|
||||
@@ -223,11 +229,13 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
if (entity.GetTypeOfRenderingEngine() == RenderingEngine.Mvc)
|
||||
{
|
||||
_viewsFileSystem.AddFile(entity.Name, stream, true);
|
||||
string viewName = string.Concat(entity.Alias, ".cshtml");
|
||||
_viewsFileSystem.AddFile(viewName, stream, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
_masterpagesFileSystem.AddFile(entity.Name, stream, true);
|
||||
string masterpageName = string.Concat(entity.Alias, ".master");
|
||||
_masterpagesFileSystem.AddFile(masterpageName, stream, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -236,12 +244,19 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
var parent = Database.First<NodeDto>("WHERE id = @ParentId", new { ParentId = ((Template)entity).ParentId });
|
||||
entity.Path = string.Concat(parent.Path, ",", entity.Id);
|
||||
((Template)entity).Level = parent.Level + 1;
|
||||
var maxSortOrder =
|
||||
Database.ExecuteScalar<int>(
|
||||
"SELECT coalesce(max(sortOrder),0) FROM umbracoNode WHERE parentid = @ParentId AND nodeObjectType = @NodeObjectType",
|
||||
new { ParentId = ((Template)entity).ParentId, NodeObjectType = NodeObjectTypeId });
|
||||
((Template)entity).SortOrder = maxSortOrder + 1;
|
||||
}
|
||||
|
||||
//Get TemplateDto from db to get the Primary key of the entity
|
||||
var templateDto = Database.SingleOrDefault<TemplateDto>("WHERE nodeId = @Id", new { Id = entity.Id });
|
||||
//Save updated entity to db
|
||||
var template = entity as Template;
|
||||
template.UpdateDate = DateTime.Now;
|
||||
var factory = new TemplateFactory(templateDto.PrimaryKey, NodeObjectTypeId);
|
||||
var dto = factory.BuildDto(template);
|
||||
|
||||
@@ -328,8 +343,8 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
public ITemplate Get(string alias)
|
||||
{
|
||||
var sql = GetBaseQuery(false);
|
||||
sql.Where("cmsTemplate.alias = @Alias", new { Alias = alias });
|
||||
var sql = GetBaseQuery(false)
|
||||
.Where<TemplateDto>(x => x.Alias == alias);
|
||||
|
||||
var dto = Database.Fetch<TemplateDto, NodeDto>(sql).FirstOrDefault();
|
||||
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence.Caching;
|
||||
using Umbraco.Core.Persistence.Factories;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
@@ -4,7 +4,7 @@ using System.Data;
|
||||
|
||||
namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
{
|
||||
internal class DbTypes<TSyntax>
|
||||
public class DbTypes<TSyntax>
|
||||
where TSyntax : ISqlSyntaxProvider
|
||||
{
|
||||
public DbType DbType;
|
||||
|
||||
@@ -31,6 +31,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
string InsertData { get; }
|
||||
string UpdateData { get; }
|
||||
string DeleteData { get; }
|
||||
string TruncateTable { get; }
|
||||
string CreateConstraint { get; }
|
||||
string DeleteConstraint { get; }
|
||||
string CreateForeignKeyConstraint { get; }
|
||||
|
||||
@@ -7,21 +7,20 @@ using Umbraco.Core.Persistence.DatabaseModelDefinitions;
|
||||
namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
{
|
||||
/// <summary>
|
||||
/// Static class that provides simple access to the MySql SqlSyntax Providers singleton
|
||||
/// Static class that provides simple access to the MySql SqlSyntax Provider
|
||||
/// </summary>
|
||||
internal static class MySqlSyntax
|
||||
{
|
||||
public static ISqlSyntaxProvider Provider { get { return MySqlSyntaxProvider.Instance; } }
|
||||
public static ISqlSyntaxProvider Provider { get { return new MySqlSyntaxProvider(); } }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents an SqlSyntaxProvider for MySql
|
||||
/// </summary>
|
||||
internal class MySqlSyntaxProvider : SqlSyntaxProviderBase<MySqlSyntaxProvider>
|
||||
[SqlSyntaxProviderAttribute("MySql.Data.MySqlClient")]
|
||||
public class MySqlSyntaxProvider : SqlSyntaxProviderBase<MySqlSyntaxProvider>
|
||||
{
|
||||
public static MySqlSyntaxProvider Instance = new MySqlSyntaxProvider();
|
||||
|
||||
private MySqlSyntaxProvider()
|
||||
public MySqlSyntaxProvider()
|
||||
{
|
||||
DefaultStringLength = 255;
|
||||
StringLengthColumnDefinitionFormat = StringLengthUnicodeColumnDefinitionFormat;
|
||||
|
||||
@@ -1,28 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Umbraco.Core.Persistence.DatabaseAnnotations;
|
||||
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
|
||||
|
||||
namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
{
|
||||
/// <summary>
|
||||
/// Static class that provides simple access to the Sql CE SqlSyntax Providers singleton
|
||||
/// Static class that provides simple access to the Sql CE SqlSyntax Provider
|
||||
/// </summary>
|
||||
internal static class SqlCeSyntax
|
||||
{
|
||||
public static ISqlSyntaxProvider Provider { get { return SqlCeSyntaxProvider.Instance; } }
|
||||
public static ISqlSyntaxProvider Provider { get { return new SqlCeSyntaxProvider(); } }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents an SqlSyntaxProvider for Sql Ce
|
||||
/// </summary>
|
||||
internal class SqlCeSyntaxProvider : SqlSyntaxProviderBase<SqlCeSyntaxProvider>
|
||||
[SqlSyntaxProviderAttribute("System.Data.SqlServerCe.4.0")]
|
||||
public class SqlCeSyntaxProvider : SqlSyntaxProviderBase<SqlCeSyntaxProvider>
|
||||
{
|
||||
public static SqlCeSyntaxProvider Instance = new SqlCeSyntaxProvider();
|
||||
|
||||
private SqlCeSyntaxProvider()
|
||||
public SqlCeSyntaxProvider()
|
||||
{
|
||||
StringLengthColumnDefinitionFormat = StringLengthUnicodeColumnDefinitionFormat;
|
||||
StringColumnDefinition = string.Format(StringLengthColumnDefinitionFormat, DefaultStringLength);
|
||||
@@ -44,6 +42,14 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// SqlCe doesn't support the Truncate Table syntax, so we just have to do a DELETE FROM which is slower but we have no choice.
|
||||
/// </summary>
|
||||
public override string TruncateTable
|
||||
{
|
||||
get { return "DELETE FROM {0}"; }
|
||||
}
|
||||
|
||||
public override string GetIndexType(IndexTypes indexTypes)
|
||||
{
|
||||
string indexType;
|
||||
|
||||
@@ -6,21 +6,20 @@ using Umbraco.Core.Persistence.DatabaseModelDefinitions;
|
||||
namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
{
|
||||
/// <summary>
|
||||
/// Static class that provides simple access to the Sql Server SqlSyntax Providers singleton
|
||||
/// Static class that provides simple access to the Sql Server SqlSyntax Provider
|
||||
/// </summary>
|
||||
internal static class SqlServerSyntax
|
||||
{
|
||||
public static ISqlSyntaxProvider Provider { get { return SqlServerSyntaxProvider.Instance; } }
|
||||
public static ISqlSyntaxProvider Provider { get { return new SqlServerSyntaxProvider(); } }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents an SqlSyntaxProvider for Sql Server
|
||||
/// </summary>
|
||||
internal class SqlServerSyntaxProvider : SqlSyntaxProviderBase<SqlServerSyntaxProvider>
|
||||
[SqlSyntaxProviderAttribute("System.Data.SqlClient")]
|
||||
public class SqlServerSyntaxProvider : SqlSyntaxProviderBase<SqlServerSyntaxProvider>
|
||||
{
|
||||
public static SqlServerSyntaxProvider Instance = new SqlServerSyntaxProvider();
|
||||
|
||||
private SqlServerSyntaxProvider()
|
||||
public SqlServerSyntaxProvider()
|
||||
{
|
||||
StringLengthColumnDefinitionFormat = StringLengthUnicodeColumnDefinitionFormat;
|
||||
StringColumnDefinition = string.Format(StringLengthColumnDefinitionFormat, DefaultStringLength);
|
||||
|
||||
+3
-3
@@ -3,9 +3,9 @@
|
||||
namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
{
|
||||
/// <summary>
|
||||
/// Singleton to handle the configuration of an SqlSyntaxProvider
|
||||
/// Singleton to handle the configuration of a SqlSyntaxProvider
|
||||
/// </summary>
|
||||
internal static class SyntaxConfig
|
||||
public static class SqlSyntaxContext
|
||||
{
|
||||
private static ISqlSyntaxProvider _sqlSyntaxProvider;
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
if(_sqlSyntaxProvider == null)
|
||||
{
|
||||
throw new ArgumentNullException("SqlSyntaxProvider",
|
||||
"You must set the singleton 'Umbraco.Core.Persistence.SqlSyntax.SyntaxConfig' to use an sql syntax provider");
|
||||
"You must set the singleton 'Umbraco.Core.Persistence.SqlSyntax.SqlSyntaxContext' to use an sql syntax provider");
|
||||
}
|
||||
return _sqlSyntaxProvider;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
{
|
||||
/// <summary>
|
||||
/// Attribute for implementations of an ISqlSyntaxProvider
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class SqlSyntaxProviderAttribute : Attribute
|
||||
{
|
||||
public SqlSyntaxProviderAttribute(string providerName)
|
||||
{
|
||||
ProviderName = providerName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the ProviderName that corresponds to the sql syntax in a provider.
|
||||
/// </summary>
|
||||
public string ProviderName { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
/// All Sql Syntax provider implementations should derive from this abstract class.
|
||||
/// </remarks>
|
||||
/// <typeparam name="TSyntax"></typeparam>
|
||||
internal abstract class SqlSyntaxProviderBase<TSyntax> : ISqlSyntaxProvider
|
||||
public abstract class SqlSyntaxProviderBase<TSyntax> : ISqlSyntaxProvider
|
||||
where TSyntax : ISqlSyntaxProvider
|
||||
{
|
||||
protected SqlSyntaxProviderBase()
|
||||
@@ -436,6 +436,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
public virtual string InsertData { get { return "INSERT INTO {0} ({1}) VALUES ({2})"; } }
|
||||
public virtual string UpdateData { get { return "UPDATE {0} SET {1} WHERE {2}"; } }
|
||||
public virtual string DeleteData { get { return "DELETE FROM {0} WHERE {1}"; } }
|
||||
public virtual string TruncateTable { get { return "TRUNCATE TABLE {0}"; } }
|
||||
|
||||
public virtual string CreateConstraint { get { return "ALTER TABLE {0} ADD CONSTRAINT {1} {2} ({3})"; } }
|
||||
public virtual string DeleteConstraint { get { return "ALTER TABLE {0} DROP CONSTRAINT {1}"; } }
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.ObjectResolution;
|
||||
|
||||
namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
{
|
||||
/// <summary>
|
||||
/// A resolver to return all ISqlSyntaxProvider objects
|
||||
/// </summary>
|
||||
internal sealed class SqlSyntaxProvidersResolver : ManyObjectsResolverBase<SqlSyntaxProvidersResolver, ISqlSyntaxProvider>
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="syntaxProviders"></param>
|
||||
internal SqlSyntaxProvidersResolver(IEnumerable<Type> syntaxProviders)
|
||||
: base(syntaxProviders)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ISqlSyntaxProvider"/> implementations.
|
||||
/// </summary>
|
||||
public IEnumerable<ISqlSyntaxProvider> SqlSyntaxProviders
|
||||
{
|
||||
get
|
||||
{
|
||||
return Values;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="ISqlSyntaxProvider"/> by its attributed provider.
|
||||
/// </summary>
|
||||
/// <param name="providerName">ProviderName from the ConnectionString settings</param>
|
||||
/// <returns><see cref="ISqlSyntaxProvider"/> that corresponds to the attributed provider or the default Sql Server Syntax Provider.</returns>
|
||||
public ISqlSyntaxProvider GetByProviderNameOrDefault(string providerName)
|
||||
{
|
||||
var provider =
|
||||
Values.FirstOrDefault(
|
||||
x =>
|
||||
x.GetType()
|
||||
.FirstAttribute<SqlSyntaxProviderAttribute>()
|
||||
.ProviderName.ToLowerInvariant()
|
||||
.Equals(providerName.ToLowerInvariant()));
|
||||
|
||||
if (provider != null)
|
||||
return provider;
|
||||
|
||||
return Values.First(x => x.GetType() == typeof (SqlServerSyntaxProvider));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@ using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.Migrations;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using umbraco.interfaces;
|
||||
using File = System.IO.File;
|
||||
@@ -477,6 +478,15 @@ namespace Umbraco.Core
|
||||
return ResolveTypes<IMigration>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all SqlSyntaxProviders with the SqlSyntaxProviderAttribute
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
internal IEnumerable<Type> ResolveSqlSyntaxProviders()
|
||||
{
|
||||
return ResolveTypesWithAttribute<ISqlSyntaxProvider, SqlSyntaxProviderAttribute>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets/sets which assemblies to scan when type finding, generally used for unit testing, if not explicitly set
|
||||
/// this will search all assemblies known to have plugins and exclude ones known to not have them.
|
||||
|
||||
@@ -29,11 +29,11 @@ using System.Security.Permissions;
|
||||
[assembly: InternalsVisibleTo("businesslogic")]
|
||||
[assembly: InternalsVisibleTo("cms")]
|
||||
[assembly: InternalsVisibleTo("umbraco.editorControls")]
|
||||
[assembly: InternalsVisibleTo("umbraco.webservices")]
|
||||
[assembly: InternalsVisibleTo("umbraco.datalayer")]
|
||||
[assembly: InternalsVisibleTo("umbraco.MacroEngines")]
|
||||
|
||||
[assembly: InternalsVisibleTo("umbraco.editorControls")]
|
||||
[assembly: InternalsVisibleTo("umbraco.webservices")]
|
||||
[assembly: InternalsVisibleTo("Umbraco.Tests")]
|
||||
[assembly: InternalsVisibleTo("Umbraco.Core")]
|
||||
[assembly: InternalsVisibleTo("Umbraco.Web")]
|
||||
|
||||
+1266
-1005
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Xml.Linq;
|
||||
using System.Threading;
|
||||
using Umbraco.Core.Auditing;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Events;
|
||||
@@ -22,6 +25,9 @@ namespace Umbraco.Core.Services
|
||||
private readonly IContentService _contentService;
|
||||
private readonly IMediaService _mediaService;
|
||||
private readonly IDatabaseUnitOfWorkProvider _uowProvider;
|
||||
//Support recursive locks because some of the methods that require locking call other methods that require locking.
|
||||
//for example, the Move method needs to be locked but this calls the Save method which also needs to be locked.
|
||||
private static readonly ReaderWriterLockSlim Locker = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
|
||||
|
||||
public ContentTypeService(IContentService contentService, IMediaService mediaService)
|
||||
: this(new PetaPocoUnitOfWorkProvider(), new RepositoryFactory(), contentService, mediaService)
|
||||
@@ -173,19 +179,22 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
if (DeletingContentType.IsRaisedEventCancelled(new DeleteEventArgs<IContentType>(contentType), this))
|
||||
return;
|
||||
|
||||
_contentService.DeleteContentOfType(contentType.Id);
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateContentTypeRepository(uow))
|
||||
{
|
||||
repository.Delete(contentType);
|
||||
uow.Commit();
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
_contentService.DeleteContentOfType(contentType.Id);
|
||||
|
||||
DeletedContentType.RaiseEvent(new DeleteEventArgs<IContentType>(contentType, false), this);
|
||||
}
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateContentTypeRepository(uow))
|
||||
{
|
||||
repository.Delete(contentType);
|
||||
uow.Commit();
|
||||
|
||||
Audit.Add(AuditTypes.Delete, string.Format("Delete ContentType performed by user"), userId, contentType.Id);
|
||||
DeletedContentType.RaiseEvent(new DeleteEventArgs<IContentType>(contentType, false), this);
|
||||
}
|
||||
|
||||
Audit.Add(AuditTypes.Delete, string.Format("Delete ContentType performed by user"), userId, contentType.Id);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -200,27 +209,30 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
if (DeletingContentType.IsRaisedEventCancelled(new DeleteEventArgs<IContentType>(contentTypes), this))
|
||||
return;
|
||||
|
||||
var contentTypeList = contentTypes.ToList();
|
||||
foreach (var contentType in contentTypeList)
|
||||
{
|
||||
_contentService.DeleteContentOfType(contentType.Id);
|
||||
}
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateContentTypeRepository(uow))
|
||||
{
|
||||
foreach (var contentType in contentTypeList)
|
||||
{
|
||||
repository.Delete(contentType);
|
||||
}
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
var contentTypeList = contentTypes.ToList();
|
||||
foreach (var contentType in contentTypeList)
|
||||
{
|
||||
_contentService.DeleteContentOfType(contentType.Id);
|
||||
}
|
||||
|
||||
uow.Commit();
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateContentTypeRepository(uow))
|
||||
{
|
||||
foreach (var contentType in contentTypeList)
|
||||
{
|
||||
repository.Delete(contentType);
|
||||
}
|
||||
|
||||
DeletedContentType.RaiseEvent(new DeleteEventArgs<IContentType>(contentTypes, false), this);
|
||||
}
|
||||
uow.Commit();
|
||||
|
||||
Audit.Add(AuditTypes.Delete, string.Format("Delete ContentTypes performed by user"), userId, -1);
|
||||
DeletedContentType.RaiseEvent(new DeleteEventArgs<IContentType>(contentTypes, false), this);
|
||||
}
|
||||
|
||||
Audit.Add(AuditTypes.Delete, string.Format("Delete ContentTypes performed by user"), userId, -1);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -357,20 +369,22 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
if (DeletingMediaType.IsRaisedEventCancelled(new DeleteEventArgs<IMediaType>(mediaType), this))
|
||||
return;
|
||||
|
||||
_mediaService.DeleteMediaOfType(mediaType.Id, userId);
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
_mediaService.DeleteMediaOfType(mediaType.Id, userId);
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMediaTypeRepository(uow))
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMediaTypeRepository(uow))
|
||||
{
|
||||
|
||||
repository.Delete(mediaType);
|
||||
uow.Commit();
|
||||
repository.Delete(mediaType);
|
||||
uow.Commit();
|
||||
|
||||
DeletedMediaType.RaiseEvent(new DeleteEventArgs<IMediaType>(mediaType, false), this);
|
||||
}
|
||||
DeletedMediaType.RaiseEvent(new DeleteEventArgs<IMediaType>(mediaType, false), this);
|
||||
}
|
||||
|
||||
Audit.Add(AuditTypes.Delete, string.Format("Delete MediaType performed by user"), userId, mediaType.Id);
|
||||
Audit.Add(AuditTypes.Delete, string.Format("Delete MediaType performed by user"), userId, mediaType.Id);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -383,26 +397,28 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
if (DeletingMediaType.IsRaisedEventCancelled(new DeleteEventArgs<IMediaType>(mediaTypes), this))
|
||||
return;
|
||||
|
||||
var mediaTypeList = mediaTypes.ToList();
|
||||
foreach (var mediaType in mediaTypeList)
|
||||
{
|
||||
_mediaService.DeleteMediaOfType(mediaType.Id);
|
||||
}
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
var mediaTypeList = mediaTypes.ToList();
|
||||
foreach (var mediaType in mediaTypeList)
|
||||
{
|
||||
_mediaService.DeleteMediaOfType(mediaType.Id);
|
||||
}
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMediaTypeRepository(uow))
|
||||
{
|
||||
foreach (var mediaType in mediaTypeList)
|
||||
{
|
||||
repository.Delete(mediaType);
|
||||
}
|
||||
uow.Commit();
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMediaTypeRepository(uow))
|
||||
{
|
||||
foreach (var mediaType in mediaTypeList)
|
||||
{
|
||||
repository.Delete(mediaType);
|
||||
}
|
||||
uow.Commit();
|
||||
|
||||
DeletedMediaType.RaiseEvent(new DeleteEventArgs<IMediaType>(mediaTypes, false), this);
|
||||
}
|
||||
DeletedMediaType.RaiseEvent(new DeleteEventArgs<IMediaType>(mediaTypes, false), this);
|
||||
}
|
||||
|
||||
Audit.Add(AuditTypes.Delete, string.Format("Delete MediaTypes performed by user"), userId, -1);
|
||||
Audit.Add(AuditTypes.Delete, string.Format("Delete MediaTypes performed by user"), userId, -1);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -459,7 +475,7 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
return dtd.ToString();
|
||||
}
|
||||
|
||||
|
||||
#region Event Handlers
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Umbraco.Core.Auditing;
|
||||
using Umbraco.Core.Events;
|
||||
using Umbraco.Core.Models;
|
||||
@@ -19,6 +20,7 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
private readonly RepositoryFactory _repositoryFactory;
|
||||
private readonly IDatabaseUnitOfWorkProvider _uowProvider;
|
||||
private static readonly ReaderWriterLockSlim Locker = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
|
||||
|
||||
public DataTypeService()
|
||||
: this(new RepositoryFactory())
|
||||
@@ -105,11 +107,26 @@ namespace Umbraco.Core.Services
|
||||
/// <returns>An enumerable list of string values</returns>
|
||||
public IEnumerable<string> GetPreValuesByDataTypeId(int id)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
var dtos = uow.Database.Fetch<DataTypePreValueDto>("WHERE datatypeNodeId = @Id", new {Id = id});
|
||||
var list = dtos.Select(x => x.Value).ToList();
|
||||
uow.Dispose();
|
||||
return list;
|
||||
using (var uow = _uowProvider.GetUnitOfWork())
|
||||
{
|
||||
var dtos = uow.Database.Fetch<DataTypePreValueDto>("WHERE datatypeNodeId = @Id", new {Id = id});
|
||||
var list = dtos.Select(x => x.Value).ToList();
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a specific PreValue by its Id
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the PreValue to retrieve the value from</param>
|
||||
/// <returns>PreValue as a string</returns>
|
||||
public string GetPreValueAsString(int id)
|
||||
{
|
||||
using (var uow = _uowProvider.GetUnitOfWork())
|
||||
{
|
||||
var dto = uow.Database.FirstOrDefault<DataTypePreValueDto>("WHERE id = @Id", new { Id = id });
|
||||
return dto != null ? dto.Value : string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -121,18 +138,84 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IDataTypeDefinition>(dataTypeDefinition), this))
|
||||
return;
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateDataTypeDefinitionRepository(uow))
|
||||
{
|
||||
dataTypeDefinition.CreatorId = userId;
|
||||
repository.AddOrUpdate(dataTypeDefinition);
|
||||
uow.Commit();
|
||||
|
||||
Saved.RaiseEvent(new SaveEventArgs<IDataTypeDefinition>(dataTypeDefinition, false), this);
|
||||
}
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateDataTypeDefinitionRepository(uow))
|
||||
{
|
||||
dataTypeDefinition.CreatorId = userId;
|
||||
repository.AddOrUpdate(dataTypeDefinition);
|
||||
uow.Commit();
|
||||
|
||||
Audit.Add(AuditTypes.Save, string.Format("Save DataTypeDefinition performed by user"), userId, dataTypeDefinition.Id);
|
||||
Saved.RaiseEvent(new SaveEventArgs<IDataTypeDefinition>(dataTypeDefinition, false), this);
|
||||
}
|
||||
}
|
||||
|
||||
Audit.Add(AuditTypes.Save, string.Format("Save DataTypeDefinition performed by user"), userId, dataTypeDefinition.Id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves a collection of <see cref="IDataTypeDefinition"/>
|
||||
/// </summary>
|
||||
/// <param name="dataTypeDefinitions"><see cref="IDataTypeDefinition"/> to save</param>
|
||||
/// <param name="userId">Id of the user issueing the save</param>
|
||||
public void Save(IEnumerable<IDataTypeDefinition> dataTypeDefinitions, int userId = 0)
|
||||
{
|
||||
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IDataTypeDefinition>(dataTypeDefinitions), this))
|
||||
return;
|
||||
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateDataTypeDefinitionRepository(uow))
|
||||
{
|
||||
foreach (var dataTypeDefinition in dataTypeDefinitions)
|
||||
{
|
||||
dataTypeDefinition.CreatorId = userId;
|
||||
repository.AddOrUpdate(dataTypeDefinition);
|
||||
}
|
||||
uow.Commit();
|
||||
|
||||
Saved.RaiseEvent(new SaveEventArgs<IDataTypeDefinition>(dataTypeDefinitions, false), this);
|
||||
}
|
||||
}
|
||||
Audit.Add(AuditTypes.Save, string.Format("Save DataTypeDefinition performed by user"), userId, -1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves a list of PreValues for a given DataTypeDefinition
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the DataTypeDefinition to save PreValues for</param>
|
||||
/// <param name="values">List of string values to save</param>
|
||||
public void SavePreValues(int id, IEnumerable<string> values)
|
||||
{
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
using (var uow = _uowProvider.GetUnitOfWork())
|
||||
{
|
||||
var sortOrderObj =
|
||||
uow.Database.ExecuteScalar<object>(
|
||||
"SELECT max(sortorder) FROM cmsDataTypePreValues WHERE datatypeNodeId = @DataTypeId", new { DataTypeId = id });
|
||||
int sortOrder;
|
||||
if (sortOrderObj == null || int.TryParse(sortOrderObj.ToString(), out sortOrder) == false)
|
||||
{
|
||||
sortOrder = 1;
|
||||
}
|
||||
|
||||
using (var transaction = uow.Database.GetTransaction())
|
||||
{
|
||||
foreach (var value in values)
|
||||
{
|
||||
var dto = new DataTypePreValueDto { DataTypeNodeId = id, Value = value, SortOrder = sortOrder };
|
||||
uow.Database.Insert(dto);
|
||||
sortOrder++;
|
||||
}
|
||||
|
||||
transaction.Complete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -163,7 +246,7 @@ namespace Umbraco.Core.Services
|
||||
|
||||
foreach (var group in contentType.PropertyGroups)
|
||||
{
|
||||
var types = @group.PropertyTypes.Where(x => x.DataTypeDefinitionId == dataTypeDefinition.Id);
|
||||
var types = @group.PropertyTypes.Where(x => x.DataTypeDefinitionId == dataTypeDefinition.Id).ToList();
|
||||
foreach (var propertyType in types)
|
||||
{
|
||||
@group.PropertyTypes.Remove(propertyType);
|
||||
|
||||
@@ -255,6 +255,31 @@ namespace Umbraco.Core.Services
|
||||
Audit.Add(AuditTypes.Save, string.Format("Save Template performed by user"), userId, template.Id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves a collection of <see cref="Template"/> objects
|
||||
/// </summary>
|
||||
/// <param name="templates">List of <see cref="Template"/> to save</param>
|
||||
/// <param name="userId">Optional id of the user</param>
|
||||
public void SaveTemplate(IEnumerable<ITemplate> templates, int userId = 0)
|
||||
{
|
||||
if (SavingTemplate.IsRaisedEventCancelled(new SaveEventArgs<ITemplate>(templates), this))
|
||||
return;
|
||||
|
||||
var uow = _dataUowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateTemplateRepository(uow))
|
||||
{
|
||||
foreach (var template in templates)
|
||||
{
|
||||
repository.AddOrUpdate(template);
|
||||
}
|
||||
uow.Commit();
|
||||
|
||||
SavedTemplate.RaiseEvent(new SaveEventArgs<ITemplate>(templates, false), this);
|
||||
}
|
||||
|
||||
Audit.Add(AuditTypes.Save, string.Format("Save Template performed by user"), userId, -1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a template by its alias
|
||||
/// </summary>
|
||||
|
||||
@@ -11,8 +11,13 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates an <see cref="IContent"/> object using the alias of the <see cref="IContentType"/>
|
||||
/// that this Content is based on.
|
||||
/// that this Content should based on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Note that using this method will simply return a new IContent without any identity
|
||||
/// as it has not yet been persisted. It is intended as a shortcut to creating new content objects
|
||||
/// that does not invoke a save operation against the database.
|
||||
/// </remarks>
|
||||
/// <param name="name">Name of the Content object</param>
|
||||
/// <param name="parentId">Id of Parent for the new Content</param>
|
||||
/// <param name="contentTypeAlias">Alias of the <see cref="IContentType"/></param>
|
||||
@@ -22,8 +27,13 @@ namespace Umbraco.Core.Services
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="IContent"/> object using the alias of the <see cref="IContentType"/>
|
||||
/// that this Content is based on.
|
||||
/// that this Content should based on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Note that using this method will simply return a new IContent without any identity
|
||||
/// as it has not yet been persisted. It is intended as a shortcut to creating new content objects
|
||||
/// that does not invoke a save operation against the database.
|
||||
/// </remarks>
|
||||
/// <param name="name">Name of the Content object</param>
|
||||
/// <param name="parent">Parent <see cref="IContent"/> object for the new Content</param>
|
||||
/// <param name="contentTypeAlias">Alias of the <see cref="IContentType"/></param>
|
||||
@@ -287,5 +297,49 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="content"><see cref="IContent"/> to check if anscestors are published</param>
|
||||
/// <returns>True if the Content can be published, otherwise False</returns>
|
||||
bool IsPublishable(IContent content);
|
||||
|
||||
/// <summary>
|
||||
/// Sorts a collection of <see cref="IContent"/> objects by updating the SortOrder according
|
||||
/// to the ordering of items in the passed in <see cref="SortedSet{T}"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Using this method will ensure that the Published-state is maintained upon sorting
|
||||
/// so the cache is updated accordingly - as needed.
|
||||
/// </remarks>
|
||||
/// <param name="items"></param>
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="raiseEvents"></param>
|
||||
/// <returns>True if sorting succeeded, otherwise False</returns>
|
||||
bool Sort(SortedSet<IContent> items, int userId = 0, bool raiseEvents = true);
|
||||
|
||||
/// <summary>
|
||||
/// Creates and saves an <see cref="IContent"/> object using the alias of the <see cref="IContentType"/>
|
||||
/// that this Content should based on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method returns an <see cref="IContent"/> object that has been persisted to the database
|
||||
/// and therefor has an identity.
|
||||
/// </remarks>
|
||||
/// <param name="name">Name of the Content object</param>
|
||||
/// <param name="parent">Parent <see cref="IContent"/> object for the new Content</param>
|
||||
/// <param name="contentTypeAlias">Alias of the <see cref="IContentType"/></param>
|
||||
/// <param name="userId">Optional id of the user creating the content</param>
|
||||
/// <returns><see cref="IContent"/></returns>
|
||||
IContent CreateContentWithIdentity(string name, IContent parent, string contentTypeAlias, int userId = 0);
|
||||
|
||||
/// <summary>
|
||||
/// Creates and saves an <see cref="IContent"/> object using the alias of the <see cref="IContentType"/>
|
||||
/// that this Content should based on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method returns an <see cref="IContent"/> object that has been persisted to the database
|
||||
/// and therefor has an identity.
|
||||
/// </remarks>
|
||||
/// <param name="name">Name of the Content object</param>
|
||||
/// <param name="parentId">Id of Parent for the new Content</param>
|
||||
/// <param name="contentTypeAlias">Alias of the <see cref="IContentType"/></param>
|
||||
/// <param name="userId">Optional id of the user creating the content</param>
|
||||
/// <returns><see cref="IContent"/></returns>
|
||||
IContent CreateContentWithIdentity(string name, int parentId, string contentTypeAlias, int userId = 0);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Linq;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Services
|
||||
|
||||
@@ -38,6 +38,13 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="userId">Id of the user issueing the save</param>
|
||||
void Save(IDataTypeDefinition dataTypeDefinition, int userId = 0);
|
||||
|
||||
/// <summary>
|
||||
/// Saves a collection of <see cref="IDataTypeDefinition"/>
|
||||
/// </summary>
|
||||
/// <param name="dataTypeDefinitions"><see cref="IDataTypeDefinition"/> to save</param>
|
||||
/// <param name="userId">Id of the user issueing the save</param>
|
||||
void Save(IEnumerable<IDataTypeDefinition> dataTypeDefinitions, int userId = 0);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes an <see cref="IDataTypeDefinition"/>
|
||||
/// </summary>
|
||||
@@ -75,5 +82,19 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="id">Id of the <see cref="IDataTypeDefinition"/> to retrieve prevalues from</param>
|
||||
/// <returns>An enumerable list of string values</returns>
|
||||
IEnumerable<string> GetPreValuesByDataTypeId(int id);
|
||||
|
||||
/// <summary>
|
||||
/// Saves a list of PreValues for a given DataTypeDefinition
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the DataTypeDefinition to save PreValues for</param>
|
||||
/// <param name="values">List of string values to save</param>
|
||||
void SavePreValues(int id, IEnumerable<string> values);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a specific PreValue by its Id
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the PreValue to retrieve the value from</param>
|
||||
/// <returns>PreValue as a string</returns>
|
||||
string GetPreValueAsString(int id);
|
||||
}
|
||||
}
|
||||
@@ -116,5 +116,12 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="template"><see cref="ITemplate"/> to validate</param>
|
||||
/// <returns>True if Script is valid, otherwise false</returns>
|
||||
bool ValidateTemplate(ITemplate template);
|
||||
|
||||
/// <summary>
|
||||
/// Saves a collection of <see cref="Template"/> objects
|
||||
/// </summary>
|
||||
/// <param name="templates">List of <see cref="Template"/> to save</param>
|
||||
/// <param name="userId">Optional id of the user</param>
|
||||
void SaveTemplate(IEnumerable<ITemplate> templates, int userId = 0);
|
||||
}
|
||||
}
|
||||
@@ -11,8 +11,13 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates an <see cref="IMedia"/> object using the alias of the <see cref="IMediaType"/>
|
||||
/// that this Media is based on.
|
||||
/// that this Media should based on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Note that using this method will simply return a new IMedia without any identity
|
||||
/// as it has not yet been persisted. It is intended as a shortcut to creating new media objects
|
||||
/// that does not invoke a save operation against the database.
|
||||
/// </remarks>
|
||||
/// <param name="name">Name of the Media object</param>
|
||||
/// <param name="parentId">Id of Parent for the new Media item</param>
|
||||
/// <param name="mediaTypeAlias">Alias of the <see cref="IMediaType"/></param>
|
||||
@@ -22,8 +27,13 @@ namespace Umbraco.Core.Services
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="IMedia"/> object using the alias of the <see cref="IMediaType"/>
|
||||
/// that this Media is based on.
|
||||
/// that this Media should based on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Note that using this method will simply return a new IMedia without any identity
|
||||
/// as it has not yet been persisted. It is intended as a shortcut to creating new media objects
|
||||
/// that does not invoke a save operation against the database.
|
||||
/// </remarks>
|
||||
/// <param name="name">Name of the Media object</param>
|
||||
/// <param name="parent">Parent <see cref="IMedia"/> for the new Media item</param>
|
||||
/// <param name="mediaTypeAlias">Alias of the <see cref="IMediaType"/></param>
|
||||
@@ -177,5 +187,52 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="deletePriorVersions">Boolean indicating whether to delete versions prior to the versionId</param>
|
||||
/// <param name="userId">Optional Id of the User deleting versions of a Content object</param>
|
||||
void DeleteVersion(int id, Guid versionId, bool deletePriorVersions, int userId = 0);
|
||||
|
||||
/// <summary>
|
||||
/// Gets an <see cref="IMedia"/> object from the path stored in the 'umbracoFile' property.
|
||||
/// </summary>
|
||||
/// <param name="mediaPath">Path of the media item to retreive (for example: /media/1024/koala_403x328.jpg)</param>
|
||||
/// <returns><see cref="IMedia"/></returns>
|
||||
IMedia GetMediaByPath(string mediaPath);
|
||||
|
||||
/// <summary>
|
||||
/// Sorts a collection of <see cref="IMedia"/> objects by updating the SortOrder according
|
||||
/// to the ordering of items in the passed in <see cref="SortedSet{T}"/>.
|
||||
/// </summary>
|
||||
/// <param name="items"></param>
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="raiseEvents"></param>
|
||||
/// <returns>True if sorting succeeded, otherwise False</returns>
|
||||
bool Sort(SortedSet<IMedia> items, int userId = 0, bool raiseEvents = true);
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="IMedia"/> object using the alias of the <see cref="IMediaType"/>
|
||||
/// that this Media should based on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method returns an <see cref="IMedia"/> object that has been persisted to the database
|
||||
/// and therefor has an identity.
|
||||
/// </remarks>
|
||||
/// <param name="name">Name of the Media object</param>
|
||||
/// <param name="parent">Parent <see cref="IMedia"/> for the new Media item</param>
|
||||
/// <param name="mediaTypeAlias">Alias of the <see cref="IMediaType"/></param>
|
||||
/// <param name="userId">Optional id of the user creating the media item</param>
|
||||
/// <returns><see cref="IMedia"/></returns>
|
||||
IMedia CreateMediaWithIdentity(string name, IMedia parent, string mediaTypeAlias, int userId = 0);
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="IMedia"/> object using the alias of the <see cref="IMediaType"/>
|
||||
/// that this Media should based on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method returns an <see cref="IMedia"/> object that has been persisted to the database
|
||||
/// and therefor has an identity.
|
||||
/// </remarks>
|
||||
/// <param name="name">Name of the Media object</param>
|
||||
/// <param name="parentId">Id of Parent for the new Media item</param>
|
||||
/// <param name="mediaTypeAlias">Alias of the <see cref="IMediaType"/></param>
|
||||
/// <param name="userId">Optional id of the user creating the media item</param>
|
||||
/// <returns><see cref="IMedia"/></returns>
|
||||
IMedia CreateMediaWithIdentity(string name, int parentId, string mediaTypeAlias, int userId = 0);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Xml.Linq;
|
||||
using Umbraco.Core.Auditing;
|
||||
using Umbraco.Core.Events;
|
||||
@@ -19,6 +20,9 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
private readonly IDatabaseUnitOfWorkProvider _uowProvider;
|
||||
private readonly RepositoryFactory _repositoryFactory;
|
||||
//Support recursive locks because some of the methods that require locking call other methods that require locking.
|
||||
//for example, the Move method needs to be locked but this calls the Save method which also needs to be locked.
|
||||
private static readonly ReaderWriterLockSlim Locker = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
|
||||
|
||||
public MediaService(RepositoryFactory repositoryFactory)
|
||||
: this(new PetaPocoUnitOfWorkProvider(), repositoryFactory)
|
||||
@@ -33,8 +37,13 @@ namespace Umbraco.Core.Services
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="IMedia"/> object using the alias of the <see cref="IMediaType"/>
|
||||
/// that this Media is based on.
|
||||
/// that this Media should based on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Note that using this method will simply return a new IMedia without any identity
|
||||
/// as it has not yet been persisted. It is intended as a shortcut to creating new media objects
|
||||
/// that does not invoke a save operation against the database.
|
||||
/// </remarks>
|
||||
/// <param name="name">Name of the Media object</param>
|
||||
/// <param name="parentId">Id of Parent for the new Media item</param>
|
||||
/// <param name="mediaTypeAlias">Alias of the <see cref="IMediaType"/></param>
|
||||
@@ -42,28 +51,14 @@ namespace Umbraco.Core.Services
|
||||
/// <returns><see cref="IMedia"/></returns>
|
||||
public IMedia CreateMedia(string name, int parentId, string mediaTypeAlias, int userId = 0)
|
||||
{
|
||||
IMediaType mediaType = null;
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMediaTypeRepository(uow))
|
||||
{
|
||||
var query = Query<IMediaType>.Builder.Where(x => x.Alias == mediaTypeAlias);
|
||||
var mediaTypes = repository.GetByQuery(query);
|
||||
|
||||
if (!mediaTypes.Any())
|
||||
throw new Exception(string.Format("No MediaType matching the passed in Alias: '{0}' was found",
|
||||
mediaTypeAlias));
|
||||
|
||||
mediaType = mediaTypes.First();
|
||||
|
||||
if (mediaType == null)
|
||||
throw new Exception(string.Format("MediaType matching the passed in Alias: '{0}' was null",
|
||||
mediaTypeAlias));
|
||||
}
|
||||
|
||||
var mediaType = FindMediaTypeByAlias(mediaTypeAlias);
|
||||
var media = new Models.Media(name, parentId, mediaType);
|
||||
|
||||
if (Creating.IsRaisedEventCancelled(new NewEventArgs<IMedia>(media, mediaTypeAlias, parentId), this))
|
||||
return media;
|
||||
if (Creating.IsRaisedEventCancelled(new NewEventArgs<IMedia>(media, mediaTypeAlias, parentId), this))
|
||||
{
|
||||
media.WasCancelled = true;
|
||||
return media;
|
||||
}
|
||||
|
||||
media.CreatorId = userId;
|
||||
|
||||
@@ -76,8 +71,13 @@ namespace Umbraco.Core.Services
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="IMedia"/> object using the alias of the <see cref="IMediaType"/>
|
||||
/// that this Media is based on.
|
||||
/// that this Media should based on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Note that using this method will simply return a new IMedia without any identity
|
||||
/// as it has not yet been persisted. It is intended as a shortcut to creating new media objects
|
||||
/// that does not invoke a save operation against the database.
|
||||
/// </remarks>
|
||||
/// <param name="name">Name of the Media object</param>
|
||||
/// <param name="parent">Parent <see cref="IMedia"/> for the new Media item</param>
|
||||
/// <param name="mediaTypeAlias">Alias of the <see cref="IMediaType"/></param>
|
||||
@@ -85,29 +85,14 @@ namespace Umbraco.Core.Services
|
||||
/// <returns><see cref="IMedia"/></returns>
|
||||
public IMedia CreateMedia(string name, IMedia parent, string mediaTypeAlias, int userId = 0)
|
||||
{
|
||||
IMediaType mediaType = null;
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMediaTypeRepository(uow))
|
||||
var mediaType = FindMediaTypeByAlias(mediaTypeAlias);
|
||||
var media = new Models.Media(name, parent, mediaType);
|
||||
if (Creating.IsRaisedEventCancelled(new NewEventArgs<IMedia>(media, mediaTypeAlias, parent), this))
|
||||
{
|
||||
var query = Query<IMediaType>.Builder.Where(x => x.Alias == mediaTypeAlias);
|
||||
var mediaTypes = repository.GetByQuery(query);
|
||||
|
||||
if (!mediaTypes.Any())
|
||||
throw new Exception(string.Format("No MediaType matching the passed in Alias: '{0}' was found",
|
||||
mediaTypeAlias));
|
||||
|
||||
mediaType = mediaTypes.First();
|
||||
|
||||
if (mediaType == null)
|
||||
throw new Exception(string.Format("MediaType matching the passed in Alias: '{0}' was null",
|
||||
mediaTypeAlias));
|
||||
media.WasCancelled = true;
|
||||
return media;
|
||||
}
|
||||
|
||||
var media = new Models.Media(name, parent, mediaType);
|
||||
|
||||
if (Creating.IsRaisedEventCancelled(new NewEventArgs<IMedia>(media, mediaTypeAlias, parent), this))
|
||||
return media;
|
||||
|
||||
media.CreatorId = userId;
|
||||
|
||||
Created.RaiseEvent(new NewEventArgs<IMedia>(media, false, mediaTypeAlias, parent), this);
|
||||
@@ -117,6 +102,94 @@ namespace Umbraco.Core.Services
|
||||
return media;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="IMedia"/> object using the alias of the <see cref="IMediaType"/>
|
||||
/// that this Media should based on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method returns an <see cref="IMedia"/> object that has been persisted to the database
|
||||
/// and therefor has an identity.
|
||||
/// </remarks>
|
||||
/// <param name="name">Name of the Media object</param>
|
||||
/// <param name="parentId">Id of Parent for the new Media item</param>
|
||||
/// <param name="mediaTypeAlias">Alias of the <see cref="IMediaType"/></param>
|
||||
/// <param name="userId">Optional id of the user creating the media item</param>
|
||||
/// <returns><see cref="IMedia"/></returns>
|
||||
public IMedia CreateMediaWithIdentity(string name, int parentId, string mediaTypeAlias, int userId = 0)
|
||||
{
|
||||
var mediaType = FindMediaTypeByAlias(mediaTypeAlias);
|
||||
var media = new Models.Media(name, parentId, mediaType);
|
||||
if (Creating.IsRaisedEventCancelled(new NewEventArgs<IMedia>(media, mediaTypeAlias, parentId), this))
|
||||
{
|
||||
media.WasCancelled = true;
|
||||
return media;
|
||||
}
|
||||
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMediaRepository(uow))
|
||||
{
|
||||
media.CreatorId = userId;
|
||||
repository.AddOrUpdate(media);
|
||||
uow.Commit();
|
||||
|
||||
var xml = media.ToXml();
|
||||
CreateAndSaveMediaXml(xml, media.Id, uow.Database);
|
||||
}
|
||||
}
|
||||
|
||||
Created.RaiseEvent(new NewEventArgs<IMedia>(media, false, mediaTypeAlias, parentId), this);
|
||||
|
||||
Audit.Add(AuditTypes.New, "", media.CreatorId, media.Id);
|
||||
|
||||
return media;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="IMedia"/> object using the alias of the <see cref="IMediaType"/>
|
||||
/// that this Media should based on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method returns an <see cref="IMedia"/> object that has been persisted to the database
|
||||
/// and therefor has an identity.
|
||||
/// </remarks>
|
||||
/// <param name="name">Name of the Media object</param>
|
||||
/// <param name="parent">Parent <see cref="IMedia"/> for the new Media item</param>
|
||||
/// <param name="mediaTypeAlias">Alias of the <see cref="IMediaType"/></param>
|
||||
/// <param name="userId">Optional id of the user creating the media item</param>
|
||||
/// <returns><see cref="IMedia"/></returns>
|
||||
public IMedia CreateMediaWithIdentity(string name, IMedia parent, string mediaTypeAlias, int userId = 0)
|
||||
{
|
||||
var mediaType = FindMediaTypeByAlias(mediaTypeAlias);
|
||||
var media = new Models.Media(name, parent, mediaType);
|
||||
if (Creating.IsRaisedEventCancelled(new NewEventArgs<IMedia>(media, mediaTypeAlias, parent), this))
|
||||
{
|
||||
media.WasCancelled = true;
|
||||
return media;
|
||||
}
|
||||
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMediaRepository(uow))
|
||||
{
|
||||
media.CreatorId = userId;
|
||||
repository.AddOrUpdate(media);
|
||||
uow.Commit();
|
||||
|
||||
var xml = media.ToXml();
|
||||
CreateAndSaveMediaXml(xml, media.Id, uow.Database);
|
||||
}
|
||||
}
|
||||
|
||||
Created.RaiseEvent(new NewEventArgs<IMedia>(media, false, mediaTypeAlias, parent), this);
|
||||
|
||||
Audit.Add(AuditTypes.New, "", media.CreatorId, media.Id);
|
||||
|
||||
return media;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an <see cref="IMedia"/> object by Id
|
||||
/// </summary>
|
||||
@@ -155,7 +228,7 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var repository = _repositoryFactory.CreateMediaRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
var query = Query<IMedia>.Builder.Where(x => x.Level == level);
|
||||
var query = Query<IMedia>.Builder.Where(x => x.Level == level && !x.Path.StartsWith("-21"));
|
||||
var contents = repository.GetByQuery(query);
|
||||
|
||||
return contents;
|
||||
@@ -283,6 +356,40 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an <see cref="IMedia"/> object from the path stored in the 'umbracoFile' property.
|
||||
/// </summary>
|
||||
/// <param name="mediaPath">Path of the media item to retreive (for example: /media/1024/koala_403x328.jpg)</param>
|
||||
/// <returns><see cref="IMedia"/></returns>
|
||||
public IMedia GetMediaByPath(string mediaPath)
|
||||
{
|
||||
var umbracoFileValue = mediaPath;
|
||||
var isResized = mediaPath.Contains("_") && mediaPath.Contains("x");
|
||||
|
||||
// If the image has been resized we strip the "_403x328" of the original "/media/1024/koala_403x328.jpg" url.
|
||||
if (isResized)
|
||||
{
|
||||
|
||||
var underscoreIndex = mediaPath.LastIndexOf('_');
|
||||
var dotIndex = mediaPath.LastIndexOf('.');
|
||||
umbracoFileValue = string.Concat(mediaPath.Substring(0, underscoreIndex), mediaPath.Substring(dotIndex));
|
||||
}
|
||||
|
||||
var sql = new Sql()
|
||||
.Select("*")
|
||||
.From<PropertyDataDto>()
|
||||
.InnerJoin<PropertyTypeDto>()
|
||||
.On<PropertyDataDto, PropertyTypeDto>(left => left.PropertyTypeId, right => right.Id)
|
||||
.Where<PropertyTypeDto>(x => x.Alias == "umbracoFile")
|
||||
.Where<PropertyDataDto>(x => x.VarChar == umbracoFileValue);
|
||||
|
||||
using (var uow = _uowProvider.GetUnitOfWork())
|
||||
{
|
||||
var propertyDataDto = uow.Database.Fetch<PropertyDataDto, PropertyTypeDto>(sql).FirstOrDefault();
|
||||
return propertyDataDto == null ? null : GetById(propertyDataDto.NodeId);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether an <see cref="IMedia"/> item has any children
|
||||
/// </summary>
|
||||
@@ -306,32 +413,35 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="userId">Id of the User moving the Media</param>
|
||||
public void Move(IMedia media, int parentId, int userId = 0)
|
||||
{
|
||||
//This ensures that the correct method is called if this method is used to Move to recycle bin.
|
||||
if (parentId == -21)
|
||||
{
|
||||
MoveToRecycleBin(media, userId);
|
||||
return;
|
||||
}
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
//This ensures that the correct method is called if this method is used to Move to recycle bin.
|
||||
if (parentId == -21)
|
||||
{
|
||||
MoveToRecycleBin(media, userId);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Moving.IsRaisedEventCancelled(new MoveEventArgs<IMedia>(media, parentId), this))
|
||||
return;
|
||||
if (Moving.IsRaisedEventCancelled(new MoveEventArgs<IMedia>(media, parentId), this))
|
||||
return;
|
||||
|
||||
media.ParentId = parentId;
|
||||
Save(media, userId);
|
||||
media.ParentId = parentId;
|
||||
Save(media, userId);
|
||||
|
||||
//Ensure that Path and Level is updated on children
|
||||
var children = GetChildren(media.Id);
|
||||
if (children.Any())
|
||||
{
|
||||
var parentPath = media.Path;
|
||||
var parentLevel = media.Level;
|
||||
var updatedDescendents = UpdatePathAndLevelOnChildren(children, parentPath, parentLevel);
|
||||
Save(updatedDescendents, userId);
|
||||
}
|
||||
//Ensure that Path and Level is updated on children
|
||||
var children = GetChildren(media.Id);
|
||||
if (children.Any())
|
||||
{
|
||||
var parentPath = media.Path;
|
||||
var parentLevel = media.Level;
|
||||
var updatedDescendents = UpdatePathAndLevelOnChildren(children, parentPath, parentLevel);
|
||||
Save(updatedDescendents, userId);
|
||||
}
|
||||
|
||||
Moved.RaiseEvent(new MoveEventArgs<IMedia>(media, false, parentId), this);
|
||||
Moved.RaiseEvent(new MoveEventArgs<IMedia>(media, false, parentId), this);
|
||||
|
||||
Audit.Add(AuditTypes.Move, "Move Media performed by user", userId, media.Id);
|
||||
Audit.Add(AuditTypes.Move, "Move Media performed by user", userId, media.Id);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -345,7 +455,7 @@ namespace Umbraco.Core.Services
|
||||
return;
|
||||
|
||||
//Find Descendants, which will be moved to the recycle bin along with the parent/grandparent.
|
||||
var descendants = GetDescendants(media).ToList();
|
||||
var descendants = GetDescendants(media).OrderBy(x => x.Level).ToList();
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMediaRepository(uow))
|
||||
@@ -378,8 +488,8 @@ namespace Umbraco.Core.Services
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMediaRepository(uow))
|
||||
{
|
||||
var query = Query<IMedia>.Builder.Where(x => x.Path.Contains("-21"));
|
||||
var contents = repository.GetByQuery(query).OrderByDescending(x => x.ParentId);
|
||||
var query = Query<IMedia>.Builder.Where(x => x.Trashed == true);
|
||||
var contents = repository.GetByQuery(query).OrderByDescending(x => x.Level);
|
||||
|
||||
foreach (var content in contents)
|
||||
{
|
||||
@@ -403,39 +513,49 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="mediaTypeId">Id of the <see cref="IMediaType"/></param>
|
||||
/// <param name="userId">Optional id of the user deleting the media</param>
|
||||
public void DeleteMediaOfType(int mediaTypeId, int userId = 0)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMediaRepository(uow))
|
||||
{
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
//NOTE What about media that has the contenttype as part of its composition?
|
||||
//The ContentType has to be removed from the composition somehow as it would otherwise break
|
||||
//Dbl.check+test that the ContentType's Id is removed from the ContentType2ContentType table
|
||||
var query = Query<IMedia>.Builder.Where(x => x.ContentTypeId == mediaTypeId);
|
||||
var contents = repository.GetByQuery(query);
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMediaRepository(uow))
|
||||
{
|
||||
//NOTE What about media that has the contenttype as part of its composition?
|
||||
//The ContentType has to be removed from the composition somehow as it would otherwise break
|
||||
//Dbl.check+test that the ContentType's Id is removed from the ContentType2ContentType table
|
||||
var query = Query<IMedia>.Builder.Where(x => x.ContentTypeId == mediaTypeId);
|
||||
var contents = repository.GetByQuery(query);
|
||||
|
||||
if (Deleting.IsRaisedEventCancelled(new DeleteEventArgs<IMedia>(contents), this))
|
||||
return;
|
||||
if (Deleting.IsRaisedEventCancelled(new DeleteEventArgs<IMedia>(contents), this))
|
||||
return;
|
||||
|
||||
foreach (var content in contents)
|
||||
{
|
||||
((Core.Models.Media)content).ChangeTrashedState(true);
|
||||
repository.AddOrUpdate(content);
|
||||
}
|
||||
foreach (var content in contents.OrderByDescending(x => x.ParentId))
|
||||
{
|
||||
//Look for children of current content and move that to trash before the current content is deleted
|
||||
var c = content;
|
||||
var childQuery = Query<IMedia>.Builder.Where(x => x.Path.StartsWith(c.Path));
|
||||
var children = repository.GetByQuery(childQuery);
|
||||
|
||||
uow.Commit();
|
||||
foreach (var child in children)
|
||||
{
|
||||
if (child.ContentType.Id != mediaTypeId)
|
||||
MoveToRecycleBin(child, userId);
|
||||
}
|
||||
|
||||
Deleted.RaiseEvent(new DeleteEventArgs<IMedia>(contents, false), this);
|
||||
}
|
||||
//Permantly delete the content
|
||||
Delete(content, userId);
|
||||
}
|
||||
}
|
||||
|
||||
Audit.Add(AuditTypes.Delete, "Delete Media items by Type performed by user", userId, -1);
|
||||
}
|
||||
Audit.Add(AuditTypes.Delete, "Delete Media items by Type performed by user", userId, -1);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Permanently deletes an <see cref="IMedia"/> object
|
||||
/// Permanently deletes an <see cref="IMedia"/> object as well as all of its Children.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Please note that this method will completely remove the Media from the database,
|
||||
/// but current not from the file system.
|
||||
/// as well as associated media files from the file system.
|
||||
/// </remarks>
|
||||
/// <param name="media">The <see cref="IMedia"/> to delete</param>
|
||||
/// <param name="userId">Id of the User deleting the Media</param>
|
||||
@@ -444,6 +564,13 @@ namespace Umbraco.Core.Services
|
||||
if (Deleting.IsRaisedEventCancelled(new DeleteEventArgs<IMedia>(media), this))
|
||||
return;
|
||||
|
||||
//Delete children before deleting the 'possible parent'
|
||||
var children = GetChildren(media.Id);
|
||||
foreach (var child in children)
|
||||
{
|
||||
Delete(child, userId);
|
||||
}
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMediaRepository(uow))
|
||||
{
|
||||
@@ -523,25 +650,24 @@ namespace Umbraco.Core.Services
|
||||
return;
|
||||
}
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMediaRepository(uow))
|
||||
{
|
||||
media.CreatorId = userId;
|
||||
repository.AddOrUpdate(media);
|
||||
uow.Commit();
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMediaRepository(uow))
|
||||
{
|
||||
media.CreatorId = userId;
|
||||
repository.AddOrUpdate(media);
|
||||
uow.Commit();
|
||||
|
||||
var xml = media.ToXml();
|
||||
var poco = new ContentXmlDto { NodeId = media.Id, Xml = xml.ToString(SaveOptions.None) };
|
||||
var exists = uow.Database.FirstOrDefault<ContentXmlDto>("WHERE nodeId = @Id", new { Id = media.Id }) != null;
|
||||
int result = exists
|
||||
? uow.Database.Update(poco)
|
||||
: Convert.ToInt32(uow.Database.Insert(poco));
|
||||
}
|
||||
var xml = media.ToXml();
|
||||
CreateAndSaveMediaXml(xml, media.Id, uow.Database);
|
||||
}
|
||||
}
|
||||
|
||||
if(raiseEvents)
|
||||
Saved.RaiseEvent(new SaveEventArgs<IMedia>(media, false), this);
|
||||
if (raiseEvents)
|
||||
Saved.RaiseEvent(new SaveEventArgs<IMedia>(media, false), this);
|
||||
|
||||
Audit.Add(AuditTypes.Save, "Save Media performed by user", media.CreatorId, media.Id);
|
||||
Audit.Add(AuditTypes.Save, "Save Media performed by user", userId, media.Id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -558,6 +684,7 @@ namespace Umbraco.Core.Services
|
||||
return;
|
||||
}
|
||||
|
||||
var mediaXml = new Dictionary<int, Lazy<XElement>>();
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMediaRepository(uow))
|
||||
{
|
||||
@@ -569,6 +696,11 @@ namespace Umbraco.Core.Services
|
||||
|
||||
//commit the whole lot in one go
|
||||
uow.Commit();
|
||||
|
||||
foreach (var media in medias)
|
||||
{
|
||||
CreateAndSaveMediaXml(media.ToXml(), media.Id, uow.Database);
|
||||
}
|
||||
}
|
||||
|
||||
if(raiseEvents)
|
||||
@@ -577,6 +709,67 @@ namespace Umbraco.Core.Services
|
||||
Audit.Add(AuditTypes.Save, "Save Media items performed by user", userId, -1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sorts a collection of <see cref="IMedia"/> objects by updating the SortOrder according
|
||||
/// to the ordering of items in the passed in <see cref="SortedSet{T}"/>.
|
||||
/// </summary>
|
||||
/// <param name="items"></param>
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="raiseEvents"></param>
|
||||
/// <returns>True if sorting succeeded, otherwise False</returns>
|
||||
public bool Sort(SortedSet<IMedia> items, int userId = 0, bool raiseEvents = true)
|
||||
{
|
||||
if (raiseEvents)
|
||||
{
|
||||
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IMedia>(items), this))
|
||||
return false;
|
||||
}
|
||||
|
||||
var shouldBeCached = new List<IMedia>();
|
||||
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMediaRepository(uow))
|
||||
{
|
||||
int i = 0;
|
||||
foreach (var media in items)
|
||||
{
|
||||
//If the current sort order equals that of the media
|
||||
//we don't need to update it, so just increment the sort order
|
||||
//and continue.
|
||||
if (media.SortOrder == i)
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
media.SortOrder = i;
|
||||
i++;
|
||||
|
||||
repository.AddOrUpdate(media);
|
||||
shouldBeCached.Add(media);
|
||||
}
|
||||
|
||||
uow.Commit();
|
||||
|
||||
foreach (var content in shouldBeCached)
|
||||
{
|
||||
//Create and Save ContentXml DTO
|
||||
var xml = content.ToXml();
|
||||
CreateAndSaveMediaXml(xml, content.Id, uow.Database);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (raiseEvents)
|
||||
Saved.RaiseEvent(new SaveEventArgs<IMedia>(items, false), this);
|
||||
|
||||
Audit.Add(AuditTypes.Sort, "Sorting Media performed by user", userId, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the Path and Level on a collection of <see cref="IMedia"/> objects
|
||||
/// based on the Parent's Path and Level.
|
||||
@@ -603,6 +796,35 @@ namespace Umbraco.Core.Services
|
||||
return list;
|
||||
}
|
||||
|
||||
private void CreateAndSaveMediaXml(XElement xml, int id, UmbracoDatabase db)
|
||||
{
|
||||
var poco = new ContentXmlDto { NodeId = id, Xml = xml.ToString(SaveOptions.None) };
|
||||
var exists = db.FirstOrDefault<ContentXmlDto>("WHERE nodeId = @Id", new { Id = id }) != null;
|
||||
int result = exists ? db.Update(poco) : Convert.ToInt32(db.Insert(poco));
|
||||
}
|
||||
|
||||
private IMediaType FindMediaTypeByAlias(string mediaTypeAlias)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMediaTypeRepository(uow))
|
||||
{
|
||||
var query = Query<IMediaType>.Builder.Where(x => x.Alias == mediaTypeAlias);
|
||||
var mediaTypes = repository.GetByQuery(query);
|
||||
|
||||
if (mediaTypes.Any() == false)
|
||||
throw new Exception(string.Format("No MediaType matching the passed in Alias: '{0}' was found",
|
||||
mediaTypeAlias));
|
||||
|
||||
var mediaType = mediaTypes.First();
|
||||
|
||||
if (mediaType == null)
|
||||
throw new Exception(string.Format("MediaType matching the passed in Alias: '{0}' was null",
|
||||
mediaTypeAlias));
|
||||
|
||||
return mediaType;
|
||||
}
|
||||
}
|
||||
|
||||
#region Event Handlers
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -0,0 +1,675 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Xml.Linq;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Querying;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
|
||||
namespace Umbraco.Core.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the Packaging Service, which provides import/export functionality for the Core models of the API
|
||||
/// using xml representation. This is primarily used by the Package functionality.
|
||||
/// </summary>
|
||||
public class PackagingService : IService
|
||||
{
|
||||
private readonly IContentService _contentService;
|
||||
private readonly IContentTypeService _contentTypeService;
|
||||
private readonly IMediaService _mediaService;
|
||||
private readonly IDataTypeService _dataTypeService;
|
||||
private readonly IFileService _fileService;
|
||||
private readonly RepositoryFactory _repositoryFactory;
|
||||
private readonly IDatabaseUnitOfWorkProvider _uowProvider;
|
||||
private Dictionary<string, IContentType> _importedContentTypes;
|
||||
|
||||
//Support recursive locks because some of the methods that require locking call other methods that require locking.
|
||||
//for example, the Move method needs to be locked but this calls the Save method which also needs to be locked.
|
||||
private static readonly ReaderWriterLockSlim Locker = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
|
||||
|
||||
public PackagingService(IContentService contentService, IContentTypeService contentTypeService, IMediaService mediaService, IDataTypeService dataTypeService, IFileService fileService, RepositoryFactory repositoryFactory, IDatabaseUnitOfWorkProvider uowProvider)
|
||||
{
|
||||
_contentService = contentService;
|
||||
_contentTypeService = contentTypeService;
|
||||
_mediaService = mediaService;
|
||||
_dataTypeService = dataTypeService;
|
||||
_fileService = fileService;
|
||||
_repositoryFactory = repositoryFactory;
|
||||
_uowProvider = uowProvider;
|
||||
|
||||
_importedContentTypes = new Dictionary<string, IContentType>();
|
||||
}
|
||||
|
||||
#region Content
|
||||
|
||||
/// <summary>
|
||||
/// Imports and saves package xml as <see cref="IContent"/>
|
||||
/// </summary>
|
||||
/// <param name="element">Xml to import</param>
|
||||
/// <param name="parentId">Optional parent Id for the content being imported</param>
|
||||
/// <param name="userId">Optional Id of the user performing the import</param>
|
||||
/// <returns>An enumrable list of generated content</returns>
|
||||
public IEnumerable<IContent> ImportContent(XElement element, int parentId = -1, int userId = 0)
|
||||
{
|
||||
var name = element.Name.LocalName;
|
||||
if (name.Equals("DocumentSet"))
|
||||
{
|
||||
//This is a regular deep-structured import
|
||||
var roots = from doc in element.Elements()
|
||||
where (string)doc.Attribute("isDoc") == ""
|
||||
select doc;
|
||||
|
||||
var contents = ParseDocumentRootXml(roots, parentId);
|
||||
if(contents.Any())
|
||||
_contentService.Save(contents, userId);
|
||||
|
||||
return contents;
|
||||
}
|
||||
|
||||
var attribute = element.Attribute("isDoc");
|
||||
if (attribute != null)
|
||||
{
|
||||
//This is a single doc import
|
||||
var elements = new List<XElement> { element };
|
||||
var contents = ParseDocumentRootXml(elements, parentId);
|
||||
if (contents.Any())
|
||||
_contentService.Save(contents, userId);
|
||||
|
||||
return contents;
|
||||
}
|
||||
|
||||
throw new ArgumentException(
|
||||
"The passed in XElement is not valid! It does not contain a root element called " +
|
||||
"'DocumentSet' (for structured imports) nor is the first element a Document (for single document import).");
|
||||
}
|
||||
|
||||
private IEnumerable<IContent> ParseDocumentRootXml(IEnumerable<XElement> roots, int parentId)
|
||||
{
|
||||
var contents = new List<IContent>();
|
||||
foreach (var root in roots)
|
||||
{
|
||||
bool isLegacySchema = root.Name.LocalName.ToLowerInvariant().Equals("node");
|
||||
string contentTypeAlias = isLegacySchema
|
||||
? root.Attribute("nodeTypeAlias").Value
|
||||
: root.Name.LocalName;
|
||||
|
||||
if (_importedContentTypes.ContainsKey(contentTypeAlias) == false)
|
||||
{
|
||||
var contentType = FindContentTypeByAlias(contentTypeAlias);
|
||||
_importedContentTypes.Add(contentTypeAlias, contentType);
|
||||
}
|
||||
|
||||
var content = CreateContentFromXml(root, _importedContentTypes[contentTypeAlias], null, parentId, isLegacySchema);
|
||||
contents.Add(content);
|
||||
|
||||
var children = from child in root.Elements()
|
||||
where (string)child.Attribute("isDoc") == ""
|
||||
select child;
|
||||
if (children.Any())
|
||||
contents.AddRange(CreateContentFromXml(children, content, isLegacySchema));
|
||||
}
|
||||
return contents;
|
||||
}
|
||||
|
||||
private IEnumerable<IContent> CreateContentFromXml(IEnumerable<XElement> children, IContent parent, bool isLegacySchema)
|
||||
{
|
||||
var list = new List<IContent>();
|
||||
foreach (var child in children)
|
||||
{
|
||||
string contentTypeAlias = isLegacySchema
|
||||
? child.Attribute("nodeTypeAlias").Value
|
||||
: child.Name.LocalName;
|
||||
|
||||
if (_importedContentTypes.ContainsKey(contentTypeAlias) == false)
|
||||
{
|
||||
var contentType = FindContentTypeByAlias(contentTypeAlias);
|
||||
_importedContentTypes.Add(contentTypeAlias, contentType);
|
||||
}
|
||||
|
||||
//Create and add the child to the list
|
||||
var content = CreateContentFromXml(child, _importedContentTypes[contentTypeAlias], parent, default(int), isLegacySchema);
|
||||
list.Add(content);
|
||||
|
||||
//Recursive call
|
||||
XElement child1 = child;
|
||||
var grandChildren = from grand in child1.Elements()
|
||||
where (string)grand.Attribute("isDoc") == ""
|
||||
select grand;
|
||||
|
||||
if (grandChildren.Any())
|
||||
list.AddRange(CreateContentFromXml(grandChildren, content, isLegacySchema));
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
private IContent CreateContentFromXml(XElement element, IContentType contentType, IContent parent, int parentId, bool isLegacySchema)
|
||||
{
|
||||
var id = element.Attribute("id").Value;
|
||||
var level = element.Attribute("level").Value;
|
||||
var sortOrder = element.Attribute("sortOrder").Value;
|
||||
var nodeName = element.Attribute("nodeName").Value;
|
||||
var path = element.Attribute("path").Value;
|
||||
var template = element.Attribute("template").Value;
|
||||
|
||||
var properties = from property in element.Elements()
|
||||
where property.Attribute("isDoc") == null
|
||||
select property;
|
||||
|
||||
IContent content = parent == null
|
||||
? new Content(nodeName, parentId, contentType)
|
||||
{
|
||||
Level = int.Parse(level),
|
||||
SortOrder = int.Parse(sortOrder)
|
||||
}
|
||||
: new Content(nodeName, parent, contentType)
|
||||
{
|
||||
Level = int.Parse(level),
|
||||
SortOrder = int.Parse(sortOrder)
|
||||
};
|
||||
|
||||
foreach (var property in properties)
|
||||
{
|
||||
string propertyTypeAlias = isLegacySchema ? property.Attribute("alias").Value : property.Name.LocalName;
|
||||
if (content.HasProperty(propertyTypeAlias))
|
||||
content.SetValue(propertyTypeAlias, property.Value);
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
internal XElement Export(IContent content, bool deep = false)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ContentTypes
|
||||
|
||||
/// <summary>
|
||||
/// Imports and saves package xml as <see cref="IContentType"/>
|
||||
/// </summary>
|
||||
/// <param name="element">Xml to import</param>
|
||||
/// <param name="userId">Optional id of the User performing the operation. Default is zero (admin).</param>
|
||||
/// <returns>An enumrable list of generated ContentTypes</returns>
|
||||
public IEnumerable<IContentType> ImportContentTypes(XElement element, int userId = 0)
|
||||
{
|
||||
return ImportContentTypes(element, true, userId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Imports and saves package xml as <see cref="IContentType"/>
|
||||
/// </summary>
|
||||
/// <param name="element">Xml to import</param>
|
||||
/// <param name="importStructure">Boolean indicating whether or not to import the </param>
|
||||
/// <param name="userId">Optional id of the User performing the operation. Default is zero (admin).</param>
|
||||
/// <returns>An enumrable list of generated ContentTypes</returns>
|
||||
public IEnumerable<IContentType> ImportContentTypes(XElement element, bool importStructure, int userId = 0)
|
||||
{
|
||||
var name = element.Name.LocalName;
|
||||
if (name.Equals("DocumentTypes") == false && name.Equals("DocumentType") == false)
|
||||
{
|
||||
throw new ArgumentException("The passed in XElement is not valid! It does not contain a root element called 'DocumentTypes' for multiple imports or 'DocumentType' for a single import.");
|
||||
}
|
||||
|
||||
_importedContentTypes = new Dictionary<string, IContentType>();
|
||||
var documentTypes = name.Equals("DocumentTypes")
|
||||
? (from doc in element.Elements("DocumentType") select doc).ToList()
|
||||
: new List<XElement> {element};
|
||||
//NOTE it might be an idea to sort the doctype XElements based on dependencies
|
||||
//before creating the doc types - should also allow for a better structure/inheritance support.
|
||||
foreach (var documentType in documentTypes)
|
||||
{
|
||||
var alias = documentType.Element("Info").Element("Alias").Value;
|
||||
if (_importedContentTypes.ContainsKey(alias) == false)
|
||||
{
|
||||
var contentType = _contentTypeService.GetContentType(alias);
|
||||
_importedContentTypes.Add(alias, contentType == null
|
||||
? CreateContentTypeFromXml(documentType)
|
||||
: UpdateContentTypeFromXml(documentType, contentType));
|
||||
}
|
||||
}
|
||||
|
||||
var list = _importedContentTypes.Select(x => x.Value).ToList();
|
||||
_contentTypeService.Save(list, userId);
|
||||
|
||||
if (importStructure)
|
||||
{
|
||||
var updatedContentTypes = new List<IContentType>();
|
||||
//Update the structure here - we can't do it untill all DocTypes have been created
|
||||
foreach (var documentType in documentTypes)
|
||||
{
|
||||
var alias = documentType.Element("Info").Element("Alias").Value;
|
||||
var structureElement = documentType.Element("Structure");
|
||||
//Ensure that we only update ContentTypes which has actual structure-elements
|
||||
if (structureElement == null || structureElement.Elements("DocumentType").Any() == false) continue;
|
||||
|
||||
var updated = UpdateContentTypesStructure(_importedContentTypes[alias], structureElement);
|
||||
updatedContentTypes.Add(updated);
|
||||
}
|
||||
//Update ContentTypes with a newly added structure/list of allowed children
|
||||
if (updatedContentTypes.Any())
|
||||
_contentTypeService.Save(updatedContentTypes, userId);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
private IContentType CreateContentTypeFromXml(XElement documentType)
|
||||
{
|
||||
var infoElement = documentType.Element("Info");
|
||||
|
||||
//Name of the master corresponds to the parent
|
||||
var masterElement = infoElement.Element("Master");
|
||||
IContentType parent = null;
|
||||
if (masterElement != null)
|
||||
{
|
||||
var masterAlias = masterElement.Value;
|
||||
parent = _importedContentTypes.ContainsKey(masterAlias)
|
||||
? _importedContentTypes[masterAlias]
|
||||
: _contentTypeService.GetContentType(masterAlias);
|
||||
}
|
||||
|
||||
var contentType = parent == null
|
||||
? new ContentType(-1)
|
||||
{
|
||||
Alias = infoElement.Element("Alias").Value
|
||||
}
|
||||
: new ContentType(parent)
|
||||
{
|
||||
Alias = infoElement.Element("Alias").Value
|
||||
};
|
||||
|
||||
if (parent != null)
|
||||
contentType.AddContentType(parent);
|
||||
|
||||
return UpdateContentTypeFromXml(documentType, contentType);
|
||||
}
|
||||
|
||||
private IContentType UpdateContentTypeFromXml(XElement documentType, IContentType contentType)
|
||||
{
|
||||
var infoElement = documentType.Element("Info");
|
||||
var defaultTemplateElement = infoElement.Element("DefaultTemplate");
|
||||
|
||||
contentType.Name = infoElement.Element("Name").Value;
|
||||
contentType.Icon = infoElement.Element("Icon").Value;
|
||||
contentType.Thumbnail = infoElement.Element("Thumbnail").Value;
|
||||
contentType.Description = infoElement.Element("Description").Value;
|
||||
//NOTE AllowAtRoot is a new property in the package xml so we need to verify it exists before using it.
|
||||
if (infoElement.Element("AllowAtRoot") != null)
|
||||
contentType.AllowedAsRoot = infoElement.Element("AllowAtRoot").Value.ToLowerInvariant().Equals("true");
|
||||
|
||||
UpdateContentTypesAllowedTemplates(contentType, infoElement.Element("AllowedTemplates"), defaultTemplateElement);
|
||||
UpdateContentTypesTabs(contentType, documentType.Element("Tabs"));
|
||||
UpdateContentTypesProperties(contentType, documentType.Element("GenericProperties"));
|
||||
|
||||
return contentType;
|
||||
}
|
||||
|
||||
private void UpdateContentTypesAllowedTemplates(IContentType contentType,
|
||||
XElement allowedTemplatesElement, XElement defaultTemplateElement)
|
||||
{
|
||||
if (allowedTemplatesElement != null && allowedTemplatesElement.Elements("Template").Any())
|
||||
{
|
||||
var allowedTemplates = contentType.AllowedTemplates.ToList();
|
||||
foreach (var templateElement in allowedTemplatesElement.Elements("Template"))
|
||||
{
|
||||
var alias = templateElement.Value;
|
||||
var template = _fileService.GetTemplate(alias);
|
||||
if (template != null)
|
||||
{
|
||||
if(allowedTemplates.Any(x => x.Id == template.Id)) continue;
|
||||
allowedTemplates.Add(template);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogHelper.Warn<PackagingService>(
|
||||
string.Format(
|
||||
"Packager: Error handling allowed templates. Template with alias '{0}' could not be found.",
|
||||
alias));
|
||||
}
|
||||
}
|
||||
|
||||
contentType.AllowedTemplates = allowedTemplates;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(defaultTemplateElement.Value) == false)
|
||||
{
|
||||
var defaultTemplate = _fileService.GetTemplate(defaultTemplateElement.Value);
|
||||
if (defaultTemplate != null)
|
||||
{
|
||||
contentType.SetDefaultTemplate(defaultTemplate);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogHelper.Warn<PackagingService>(
|
||||
string.Format(
|
||||
"Packager: Error handling default template. Default template with alias '{0}' could not be found.",
|
||||
defaultTemplateElement.Value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateContentTypesTabs(IContentType contentType, XElement tabElement)
|
||||
{
|
||||
if(tabElement == null)
|
||||
return;
|
||||
|
||||
var tabs = tabElement.Elements("Tab");
|
||||
foreach (var tab in tabs)
|
||||
{
|
||||
var id = tab.Element("Id").Value;//Do we need to use this for tracking?
|
||||
var caption = tab.Element("Caption").Value;
|
||||
if (contentType.PropertyGroups.Contains(caption) == false)
|
||||
{
|
||||
contentType.AddPropertyGroup(caption);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateContentTypesProperties(IContentType contentType, XElement genericPropertiesElement)
|
||||
{
|
||||
var properties = genericPropertiesElement.Elements("GenericProperty");
|
||||
foreach (var property in properties)
|
||||
{
|
||||
var dataTypeId = new Guid(property.Element("Type").Value);//The DataType's Control Id
|
||||
var dataTypeDefinitionId = new Guid(property.Element("Definition").Value);//Unique Id for a DataTypeDefinition
|
||||
|
||||
var dataTypeDefinition = _dataTypeService.GetDataTypeDefinitionById(dataTypeDefinitionId);
|
||||
//If no DataTypeDefinition with the guid from the xml wasn't found OR the ControlId on the DataTypeDefinition didn't match the DataType Id
|
||||
//We look up a DataTypeDefinition that matches
|
||||
if (dataTypeDefinition == null || dataTypeDefinition.ControlId != dataTypeId)
|
||||
{
|
||||
var dataTypeDefinitions = _dataTypeService.GetDataTypeDefinitionByControlId(dataTypeId);
|
||||
if (dataTypeDefinitions != null && dataTypeDefinitions.Any())
|
||||
{
|
||||
dataTypeDefinition = dataTypeDefinitions.First();
|
||||
}
|
||||
}
|
||||
|
||||
// For backwards compatibility, if no datatype with that ID can be found, we're letting this fail silently.
|
||||
// This means that the property will not be created.
|
||||
if(dataTypeDefinition == null)
|
||||
{
|
||||
LogHelper.Warn<PackagingService>(string.Format("Packager: Error handling creation of PropertyType '{0}'. Could not find DataTypeDefintion with unique id '{1}' nor one referencing the DataType with control id '{2}'. Did the package creator forget to package up custom datatypes?",
|
||||
property.Element("Name").Value, dataTypeDefinitionId, dataTypeId));
|
||||
continue;
|
||||
}
|
||||
|
||||
var propertyType = new PropertyType(dataTypeDefinition)
|
||||
{
|
||||
Alias = property.Element("Alias").Value,
|
||||
Name = property.Element("Name").Value,
|
||||
Description = property.Element("Description").Value,
|
||||
Mandatory = property.Element("Mandatory").Value.ToLowerInvariant().Equals("true"),
|
||||
ValidationRegExp = property.Element("Validation").Value
|
||||
};
|
||||
|
||||
var helpTextElement = property.Element("HelpText");
|
||||
if (helpTextElement != null)
|
||||
{
|
||||
propertyType.HelpText = helpTextElement.Value;
|
||||
}
|
||||
|
||||
var tab = property.Element("Tab").Value;
|
||||
if (string.IsNullOrEmpty(tab))
|
||||
{
|
||||
contentType.AddPropertyType(propertyType);
|
||||
}
|
||||
else
|
||||
{
|
||||
contentType.AddPropertyType(propertyType, tab);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IContentType UpdateContentTypesStructure(IContentType contentType, XElement structureElement)
|
||||
{
|
||||
var allowedChildren = contentType.AllowedContentTypes.ToList();
|
||||
int sortOrder = allowedChildren.Any() ? allowedChildren.Last().SortOrder : 0;
|
||||
foreach (var element in structureElement.Elements("DocumentType"))
|
||||
{
|
||||
var alias = element.Value;
|
||||
if (_importedContentTypes.ContainsKey(alias))
|
||||
{
|
||||
var allowedChild = _importedContentTypes[alias];
|
||||
if (allowedChild == null || allowedChildren.Any(x => x.Id.IsValueCreated && x.Id.Value == allowedChild.Id)) continue;
|
||||
|
||||
allowedChildren.Add(new ContentTypeSort(new Lazy<int>(() => allowedChild.Id), sortOrder, allowedChild.Alias));
|
||||
sortOrder++;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogHelper.Warn<PackagingService>(
|
||||
string.Format(
|
||||
"Packager: Error handling DocumentType structure. DocumentType with alias '{0}' could not be found and was not added to the structure for '{1}'.",
|
||||
alias, contentType.Alias));
|
||||
}
|
||||
}
|
||||
|
||||
contentType.AllowedContentTypes = allowedChildren;
|
||||
return contentType;
|
||||
}
|
||||
|
||||
private IContentType FindContentTypeByAlias(string contentTypeAlias)
|
||||
{
|
||||
using (var repository = _repositoryFactory.CreateContentTypeRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
var query = Query<IContentType>.Builder.Where(x => x.Alias == contentTypeAlias);
|
||||
var types = repository.GetByQuery(query);
|
||||
|
||||
if (!types.Any())
|
||||
throw new Exception(
|
||||
string.Format("No ContentType matching the passed in Alias: '{0}' was found",
|
||||
contentTypeAlias));
|
||||
|
||||
var contentType = types.First();
|
||||
|
||||
if (contentType == null)
|
||||
throw new Exception(string.Format("ContentType matching the passed in Alias: '{0}' was null",
|
||||
contentTypeAlias));
|
||||
|
||||
return contentType;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region DataTypes
|
||||
|
||||
/// <summary>
|
||||
/// Imports and saves package xml as <see cref="IDataTypeDefinition"/>
|
||||
/// </summary>
|
||||
/// <param name="element">Xml to import</param>
|
||||
/// <param name="userId"></param>
|
||||
/// <returns>An enumrable list of generated DataTypeDefinitions</returns>
|
||||
public IEnumerable<IDataTypeDefinition> ImportDataTypeDefinitions(XElement element, int userId = 0)
|
||||
{
|
||||
var name = element.Name.LocalName;
|
||||
if (name.Equals("DataTypes") == false && name.Equals("DataType") == false)
|
||||
{
|
||||
throw new ArgumentException("The passed in XElement is not valid! It does not contain a root element called 'DataTypes' for multiple imports or 'DataType' for a single import.");
|
||||
}
|
||||
|
||||
var dataTypes = new Dictionary<string, IDataTypeDefinition>();
|
||||
var dataTypeElements = name.Equals("DataTypes")
|
||||
? (from doc in element.Elements("DataType") select doc).ToList()
|
||||
: new List<XElement> {element.Element("DataType")};
|
||||
|
||||
foreach (var dataTypeElement in dataTypeElements)
|
||||
{
|
||||
var dataTypeDefinitionName = dataTypeElement.Attribute("Name").Value;
|
||||
var dataTypeId = new Guid(dataTypeElement.Attribute("Id").Value);
|
||||
var dataTypeDefinitionId = new Guid(dataTypeElement.Attribute("Definition").Value);
|
||||
var databaseTypeAttribute = dataTypeElement.Attribute("DatabaseType");
|
||||
|
||||
var definition = _dataTypeService.GetDataTypeDefinitionById(dataTypeDefinitionId);
|
||||
//If the datatypedefinition doesn't already exist we create a new new according to the one in the package xml
|
||||
if (definition == null)
|
||||
{
|
||||
var databaseType = databaseTypeAttribute != null
|
||||
? databaseTypeAttribute.Value.EnumParse<DataTypeDatabaseType>(true)
|
||||
: DataTypeDatabaseType.Ntext;
|
||||
var dataTypeDefinition = new DataTypeDefinition(-1, dataTypeId)
|
||||
{
|
||||
Key = dataTypeDefinitionId,
|
||||
Name = dataTypeDefinitionName,
|
||||
DatabaseType = databaseType
|
||||
};
|
||||
dataTypes.Add(dataTypeDefinitionName, dataTypeDefinition);
|
||||
}
|
||||
}
|
||||
|
||||
var list = dataTypes.Select(x => x.Value).ToList();
|
||||
if (list.Any())
|
||||
{
|
||||
_dataTypeService.Save(list, userId);
|
||||
|
||||
SavePrevaluesFromXml(list, dataTypeElements);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private void SavePrevaluesFromXml(List<IDataTypeDefinition> dataTypes, IEnumerable<XElement> dataTypeElements)
|
||||
{
|
||||
foreach (var dataTypeElement in dataTypeElements)
|
||||
{
|
||||
var prevaluesElement = dataTypeElement.Element("PreValues");
|
||||
if (prevaluesElement == null) continue;
|
||||
|
||||
var dataTypeDefinitionName = dataTypeElement.Attribute("Name").Value;
|
||||
var dataTypeDefinition = dataTypes.First(x => x.Name == dataTypeDefinitionName);
|
||||
|
||||
var values = prevaluesElement.Elements("PreValue").Select(prevalue => prevalue.Attribute("Value").Value).ToList();
|
||||
_dataTypeService.SavePreValues(dataTypeDefinition.Id, values);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Dictionary Items
|
||||
#endregion
|
||||
|
||||
#region Files
|
||||
#endregion
|
||||
|
||||
#region Languages
|
||||
#endregion
|
||||
|
||||
#region Macros
|
||||
#endregion
|
||||
|
||||
#region Media
|
||||
#endregion
|
||||
|
||||
#region MediaTypes
|
||||
#endregion
|
||||
|
||||
#region Package Manifest
|
||||
#endregion
|
||||
|
||||
#region Templates
|
||||
|
||||
/// <summary>
|
||||
/// Imports and saves package xml as <see cref="ITemplate"/>
|
||||
/// </summary>
|
||||
/// <param name="element">Xml to import</param>
|
||||
/// <param name="userId">Optional user id</param>
|
||||
/// <returns>An enumrable list of generated Templates</returns>
|
||||
public IEnumerable<ITemplate> ImportTemplates(XElement element, int userId = 0)
|
||||
{
|
||||
var name = element.Name.LocalName;
|
||||
if (name.Equals("Templates") == false && name.Equals("Template") == false)
|
||||
{
|
||||
throw new ArgumentException("The passed in XElement is not valid! It does not contain a root element called 'Templates' for multiple imports or 'Template' for a single import.");
|
||||
}
|
||||
|
||||
var templates = new List<ITemplate>();
|
||||
var templateElements = name.Equals("Templates")
|
||||
? (from doc in element.Elements("Template") select doc).ToList()
|
||||
: new List<XElement> { element.Element("Template") };
|
||||
|
||||
var fields = new List<TopologicalSorter.DependencyField<XElement>>();
|
||||
foreach (XElement tempElement in templateElements)
|
||||
{
|
||||
var dependencies = new List<string>();
|
||||
var elementCopy = tempElement;
|
||||
//Ensure that the Master of the current template is part of the import, otherwise we ignore this dependency as part of the dependency sorting.
|
||||
if (elementCopy.Element("Master") != null &&
|
||||
string.IsNullOrEmpty(elementCopy.Element("Master").Value) == false &&
|
||||
templateElements.Any(x => x.Element("Alias").Value == elementCopy.Element("Master").Value))
|
||||
{
|
||||
dependencies.Add(elementCopy.Element("Master").Value);
|
||||
}
|
||||
else if (elementCopy.Element("Master") != null &&
|
||||
string.IsNullOrEmpty(elementCopy.Element("Master").Value) == false &&
|
||||
templateElements.Any(x => x.Element("Alias").Value == elementCopy.Element("Master").Value) ==
|
||||
false)
|
||||
{
|
||||
LogHelper.Info<PackagingService>(string.Format("Template '{0}' has an invalid Master '{1}', so the reference has been ignored.", elementCopy.Element("Alias").Value, elementCopy.Element("Master").Value));
|
||||
}
|
||||
|
||||
var field = new TopologicalSorter.DependencyField<XElement>
|
||||
{
|
||||
Alias = elementCopy.Element("Alias").Value,
|
||||
Item = new Lazy<XElement>(() => elementCopy),
|
||||
DependsOn = dependencies.ToArray()
|
||||
};
|
||||
|
||||
fields.Add(field);
|
||||
}
|
||||
//Sort templates by dependencies to a potential master template
|
||||
var sortedElements = TopologicalSorter.GetSortedItems(fields);
|
||||
foreach (var templateElement in sortedElements)
|
||||
{
|
||||
var templateName = templateElement.Element("Name").Value;
|
||||
var alias = templateElement.Element("Alias").Value;
|
||||
var design = templateElement.Element("Design").Value;
|
||||
var masterElement = templateElement.Element("Master");
|
||||
|
||||
var isMasterPage = IsMasterPageSyntax(design);
|
||||
var path = isMasterPage ? MasterpagePath(alias) : ViewPath(alias);
|
||||
|
||||
var existingTemplate = _fileService.GetTemplate(alias) as Template;
|
||||
var template = existingTemplate ?? new Template(path, templateName, alias);
|
||||
template.Content = design;
|
||||
if (masterElement != null && string.IsNullOrEmpty(masterElement.Value) == false)
|
||||
{
|
||||
template.MasterTemplateAlias = masterElement.Value;
|
||||
var masterTemplate = templates.FirstOrDefault(x => x.Alias == masterElement.Value);
|
||||
if(masterTemplate != null)
|
||||
template.MasterTemplateId = new Lazy<int>(() => masterTemplate.Id);
|
||||
}
|
||||
templates.Add(template);
|
||||
}
|
||||
|
||||
if(templates.Any())
|
||||
_fileService.SaveTemplate(templates, userId);
|
||||
|
||||
return templates;
|
||||
}
|
||||
|
||||
private bool IsMasterPageSyntax(string code)
|
||||
{
|
||||
return Regex.IsMatch(code, @"<%@\s*Master", RegexOptions.IgnoreCase) ||
|
||||
code.InvariantContains("<umbraco:Item") || code.InvariantContains("<asp:") || code.InvariantContains("<umbraco:Macro");
|
||||
}
|
||||
|
||||
private string ViewPath(string alias)
|
||||
{
|
||||
return SystemDirectories.MvcViews + "/" + alias.Replace(" ", "") + ".cshtml";
|
||||
}
|
||||
|
||||
private string MasterpagePath(string alias)
|
||||
{
|
||||
return IOHelper.MapPath(SystemDirectories.Masterpages + "/" + alias.Replace(" ", "") + ".master");
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user