Compare commits
420 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a43e0eb5b8 | |||
| 3b05663597 | |||
| 191d744ec6 | |||
| 980cd20e4c | |||
| f04916c9a9 | |||
| 8fde65d417 | |||
| 8cca1b77b3 | |||
| 53e4308c29 | |||
| d10eff04a7 | |||
| 59c36ad70e | |||
| 7b8d526a8a | |||
| f69a017078 | |||
| 6f26f7b57c | |||
| bda2614290 | |||
| efc482511e | |||
| 40b90b8a58 | |||
| a009dfe2a1 | |||
| bc0b419288 | |||
| 806715594e | |||
| 41e87fca98 | |||
| f23c6c53cc | |||
| f2a97326fa | |||
| dd1983dc55 | |||
| 78cd51d333 | |||
| 28b6c5897f | |||
| baed852767 | |||
| 0762decd92 | |||
| 0b58c1c03c | |||
| 38c6a21896 | |||
| 15bff44ec1 | |||
| a626efa9b6 | |||
| 1f87470f89 | |||
| 54d2258634 | |||
| 25be0621b2 | |||
| 6fe3507099 | |||
| cba09ed817 | |||
| d5d00553b4 | |||
| 55750b534b | |||
| a31cb3b1df | |||
| fc44138d9e | |||
| 0cda994538 | |||
| 4b199a9166 | |||
| cfe6ac0486 | |||
| c52669fb05 | |||
| 753fe411c5 | |||
| f05c77dc78 | |||
| d1677d9d59 | |||
| 137685d883 | |||
| 266d8ba69a | |||
| c4a071523e | |||
| ca99319ead | |||
| f808aac4cd | |||
| 0553bd1f9f | |||
| 81360f629e | |||
| 1b3669787b | |||
| aa36c66f39 | |||
| 950cb1436a | |||
| 09e31d6595 | |||
| f9fc2619fa | |||
| 004d9ab3e6 | |||
| 5d8cfa5efb | |||
| 297f8e2a0b | |||
| 83584375c1 | |||
| 8ddfb5f6ad | |||
| 9387544865 | |||
| 66ddb21ef8 | |||
| d746ec6409 | |||
| e08322f6fe | |||
| de52f3ee93 | |||
| 9d19ed9463 | |||
| df62697477 | |||
| f0cacf0d52 | |||
| d501fcb679 | |||
| 3c15f9b57c | |||
| f5994d8442 | |||
| bfe5250138 | |||
| 3fa9219c27 | |||
| 4295cba915 | |||
| 6d66fc6cb8 | |||
| 4484f83caa | |||
| 3ada1770eb | |||
| cbf84566e2 | |||
| 294c2f4fba | |||
| 0b6f05e630 | |||
| 2170380f7b | |||
| a8ab7e4c35 | |||
| c20c9c638f | |||
| 43b2a2185e | |||
| 2423bdd623 | |||
| bcb90d64a5 | |||
| eca01b845c | |||
| dc5cf5ef6e | |||
| 7d448d0959 | |||
| 53fe02db7e | |||
| b2929ea50a | |||
| a03dd7b11e | |||
| 6d994f48ac | |||
| 8e1f7170c7 | |||
| 3fd1c49da7 | |||
| f0e8252e38 | |||
| ad06aded1b | |||
| be049f9093 | |||
| 64bbfb8cbc | |||
| 0ca52fcc60 | |||
| c53342ba4c | |||
| 25eea8d599 | |||
| 22498649b1 | |||
| 25ce7baa7d | |||
| b4fd2f6d46 | |||
| aba4a9b07c | |||
| 577d77cfab | |||
| 7ff50e2652 | |||
| e885384678 | |||
| 528209f8da | |||
| 056696d36f | |||
| 6cffa67518 | |||
| d2a285c120 | |||
| 153fe248a7 | |||
| 7fc4822bbe | |||
| d65bee76b2 | |||
| 385d6396b0 | |||
| 46858af1ed | |||
| 34163625fe | |||
| e53b388a5e | |||
| 4fb4af0b4f | |||
| 461f032777 | |||
| ab37f9ae35 | |||
| a3347c0037 | |||
| f3835d1ca3 | |||
| 8fae55e44e | |||
| a8ca3a89bd | |||
| 765f959f20 | |||
| 2cf90477ed | |||
| 6ca6a08233 | |||
| 0119f1eb1b | |||
| cd4f66e7c5 | |||
| d30c4791fe | |||
| 7ee9b9ebcc | |||
| b4caf109f7 | |||
| 0e8ffe528a | |||
| a8029d1dc5 | |||
| a1d5b61ae5 | |||
| 3fdc0e5361 | |||
| 6818ac4e50 | |||
| 710c8aa6ea | |||
| 4bfb8569c8 | |||
| df9a887032 | |||
| 1e0a4690fc | |||
| 52163494db | |||
| 8416764a83 | |||
| 2d3eb8c208 | |||
| aa84a3f7f2 | |||
| 3594693f4b | |||
| c573459626 | |||
| b99de245bf | |||
| 222723b8fe | |||
| f758b33da5 | |||
| eeb0e0026a | |||
| 082dacf737 | |||
| afc2fd9420 | |||
| ff6715d42a | |||
| b776675ac8 | |||
| 1e21671b62 | |||
| 59184981cb | |||
| 0632ffb93d | |||
| f8652d98fe | |||
| 034aa6d8f9 | |||
| 1484fba1ad | |||
| 82fc1a5304 | |||
| f0aab6ae81 | |||
| 174ff44e3b | |||
| b3c3e114ad | |||
| 60481e7e02 | |||
| 12de5d6ed3 | |||
| 9ac325c1a4 | |||
| 7f5457316a | |||
| 671c8715b0 | |||
| 8c257d39f9 | |||
| 76f040aef4 | |||
| 721f813d1e | |||
| 7ed5a6f706 | |||
| d6d630cb2c | |||
| 35a698cdc9 | |||
| 6c9e82e735 | |||
| f7ddb1ed49 | |||
| c0fd974cc1 | |||
| e9c4a031c9 | |||
| 988940095c | |||
| 123e65c55f | |||
| 08a049594c | |||
| a895a2a20a | |||
| a5e33e1e02 | |||
| e5e4e7b685 | |||
| a721f06ac8 | |||
| 88795b86fd | |||
| 378a544c1a | |||
| a159b50c05 | |||
| 3891e46549 | |||
| e7bcc642a9 | |||
| 39095b524c | |||
| 4983990d39 | |||
| 3b1bfe04f2 | |||
| 979fe46e9b | |||
| 0107a10145 | |||
| a38f0af49b | |||
| e9a496df4f | |||
| 2f6dada481 | |||
| 580123cb87 | |||
| de0e47d7ef | |||
| ff5dc324fe | |||
| 096c5ad69f | |||
| 83d1e9c76f | |||
| eba7582a97 | |||
| 0cf2a1fc2a | |||
| 77ee87178e | |||
| a6997a5cb7 | |||
| b40619634d | |||
| fc84a21f06 | |||
| 9137ce7cf4 | |||
| ff3fc5d825 | |||
| 9621403f79 | |||
| 3b9bf7b0f9 | |||
| 3882e1984d | |||
| 2245c88396 | |||
| 2e39c55d56 | |||
| e4e0bcf642 | |||
| 7537e4c6d6 | |||
| c410b6dc20 | |||
| 1e7e670df3 | |||
| da53ffe9f2 | |||
| 47f6401fcd | |||
| 33190ea5e1 | |||
| a06951afbd | |||
| b32ea68fd0 | |||
| eb2db791b8 | |||
| 158f4d0614 | |||
| 7a38970cf4 | |||
| 43d6c9a46d | |||
| 7f6d8b6bdd | |||
| 0b3eaf9c77 | |||
| 0fe8ff57a1 | |||
| 2642d74450 | |||
| 761b749f37 | |||
| 22fb7e1706 | |||
| 4ef9dbb9b4 | |||
| f716ba380c | |||
| 12b1168de9 | |||
| 01290f8174 | |||
| 26a7bf8187 | |||
| 439445aae4 | |||
| ba1d0fa193 | |||
| 0d79eaf3c5 | |||
| e747438a4b | |||
| 14f71c9059 | |||
| 97355bde6f | |||
| ed35f234de | |||
| 5154bcd2e9 | |||
| e3af8b4e5f | |||
| 3e8c1a426c | |||
| d7081dbc6b | |||
| 1d89702c2c | |||
| c874fa6507 | |||
| df26090d63 | |||
| 3050258fdc | |||
| ba387598ed | |||
| 3ff1b01e46 | |||
| 36e803713c | |||
| a3e7f644de | |||
| 84e990c239 | |||
| 911a1cf80b | |||
| ef493ef9af | |||
| 76a12f3f33 | |||
| 344a4cc485 | |||
| 5e1115218c | |||
| 71a28cbeaa | |||
| 4aa750694a | |||
| 5d89ab1e2a | |||
| 262aa3b8fe | |||
| 106d733d08 | |||
| a010448ad1 | |||
| 1586f1679a | |||
| 809badd1cf | |||
| da92ece774 | |||
| a531afb819 | |||
| 111df761aa | |||
| 1d6009e3c7 | |||
| 8dfeb1e616 | |||
| 5f9c7bb49c | |||
| 0c3b7c27a7 | |||
| f2293e01fa | |||
| 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 | |||
| 506d32f353 | |||
| 16746c8548 | |||
| fb994bdc11 | |||
| db4ed70d70 | |||
| e6ccd8a5b5 | |||
| a9781d79e2 | |||
| 7ae8b28466 | |||
| 29a4cb8b71 | |||
| abee79ca69 | |||
| d8ccf20840 | |||
| 9e10694ebb | |||
| ffb39de003 | |||
| 527375b238 | |||
| 1c5cd4e245 | |||
| a4ed0e266c | |||
| 1929f60ea8 | |||
| b9cc2efc8c | |||
| 63cae70ec3 | |||
| dd990b5df4 | |||
| eadb1bb194 | |||
| 30be665a40 | |||
| bad284515c | |||
| 5b660d95f1 | |||
| 106ac44e64 | |||
| 64bb7e1db0 | |||
| 25b9ca3b0e | |||
| b928170103 | |||
| e25ee246fb | |||
| 8e8ec41dae | |||
| fb34c4716a | |||
| 29bf61b1f2 | |||
| 9803309e34 | |||
| 3a539629dc | |||
| 74b970d586 | |||
| 518898b04b | |||
| a773e0a018 | |||
| 99fe89addc | |||
| 668d4f9f91 | |||
| efbc461da9 | |||
| 97d41f8998 | |||
| 8ef88dc955 | |||
| 90e73cb89f | |||
| dcd6477030 | |||
| e50bac7c9f | |||
| 13b73231de | |||
| 50a70c28df | |||
| 7d5589118f | |||
| 01bf0bcfa5 | |||
| 7dcfcaf339 | |||
| c39b698d4c | |||
| 103efbdc27 | |||
| 3d51dd767b | |||
| e22988e435 | |||
| 9736aaafaa | |||
| bf3fa20a53 | |||
| f936f8b0dd | |||
| 1bd20c9b06 | |||
| 099b713947 | |||
| 165d9c7dff | |||
| 6badfae849 | |||
| 9d0dbda3bd | |||
| df986c8254 | |||
| cd823db766 | |||
| 09400be6e0 | |||
| 7934ba7ec4 | |||
| 2f9de56968 | |||
| 49a61c5820 | |||
| 7edbc34e6c | |||
| 60b6608289 | |||
| 2dfdc1050b | |||
| 9e239f135d | |||
| 480b84a223 | |||
| e1c810c033 | |||
| 7a1e3b96b8 | |||
| 4abb9fff3e | |||
| 2490908401 | |||
| 4217949719 | |||
| fc68ba69e2 | |||
| 28892a7bb2 | |||
| 65cb6fbaff | |||
| 4b49f9779f | |||
| c5b6bb52e0 | |||
| efee4d0c0c | |||
| b89951dd11 | |||
| 70ad3edc1f | |||
| 9982a09826 | |||
| 83308c3d5f | |||
| 495b661263 | |||
| f2d7e3549d | |||
| 4201d678fa | |||
| ff6ee360da | |||
| 1f999d7e22 | |||
| be24075850 | |||
| 6148d63b02 | |||
| 3ed4da19c2 | |||
| a9df92b7a3 | |||
| 6e4d8b638e | |||
| 97f3f13aaa | |||
| 5110e0ec0e | |||
| edb84b3c97 |
@@ -27,5 +27,8 @@ ff3bb24ea0c915878396a6ae27f1ff164e8ac150 Release-6.0.0-beta
|
||||
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
|
||||
87cf618a39e38ec58df916d10e6a924de62ae37d release-6.1.0-beta
|
||||
0dee9964687ea51ea797984cf7cce3655d6a6558 release-6.0.4
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
@ECHO OFF
|
||||
SET release=6.1.0
|
||||
SET comment=beta
|
||||
SET comment=beta-2
|
||||
SET version=%release%
|
||||
|
||||
IF [%comment%] EQU [] (SET version=%release%) ELSE (SET version=%release%-%comment%)
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
<dependency id="Microsoft.AspNet.Mvc" version="[4.0.20710.0]" />
|
||||
<dependency id="Microsoft.AspNet.WebApi" version="4.0.20710.0" />
|
||||
<dependency id="Microsoft.AspNet.Mvc.FixedDisplayModes" version="1.0.0" />
|
||||
<dependency id="MiniProfiler" version="2.1.0" />
|
||||
</dependencies>
|
||||
</metadata>
|
||||
<files>
|
||||
@@ -63,8 +64,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
|
||||
@@ -123,6 +123,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
|
||||
@@ -163,7 +175,6 @@ namespace Umbraco.Core
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void AssertIsReady()
|
||||
{
|
||||
if (!this.IsReady)
|
||||
@@ -245,7 +256,7 @@ namespace Umbraco.Core
|
||||
this.ApplicationCache = null;
|
||||
if (_databaseContext != null) //need to check the internal field here
|
||||
{
|
||||
if (DatabaseContext.Database != null)
|
||||
if (DatabaseContext.IsDatabaseConfigured)
|
||||
{
|
||||
DatabaseContext.Database.Dispose();
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// A case-insensitive configuration converter for enumerations.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the enumeration.</typeparam>
|
||||
internal class CaseInsensitiveEnumConfigConverter<T> : ConfigurationConverterBase
|
||||
public class CaseInsensitiveEnumConfigConverter<T> : ConfigurationConverterBase
|
||||
where T : struct
|
||||
{
|
||||
public override object ConvertFrom(ITypeDescriptorContext ctx, CultureInfo ci, object data)
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Indicates the configuration key for a section or a group.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
|
||||
internal sealed class ConfigurationKeyAttribute : Attribute
|
||||
public sealed class ConfigurationKeyAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ConfigurationKeyAttribute"/> class with a configuration key.
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// <para>The <c>UmbracoSettings.For{T}</c> method will return a section, either one that
|
||||
/// is in the configuration file, or a section that was created with default values.</para>
|
||||
/// </remarks>
|
||||
internal abstract class UmbracoConfigurationSection : ConfigurationSection
|
||||
public abstract class UmbracoConfigurationSection : ConfigurationSection
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the section actually is in the configuration file.
|
||||
|
||||
@@ -135,7 +135,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// </summary>
|
||||
/// <param name="key">The xpath query to the specific node.</param>
|
||||
/// <returns>If found, it returns the specific configuration xml node.</returns>
|
||||
public static XmlNode GetKeyAsNode(string key)
|
||||
internal static XmlNode GetKeyAsNode(string key)
|
||||
{
|
||||
if (key == null)
|
||||
throw new ArgumentException("Key cannot be null");
|
||||
@@ -150,7 +150,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// </summary>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <returns></returns>
|
||||
public static string GetKey(string key)
|
||||
internal static string GetKey(string key)
|
||||
{
|
||||
EnsureSettingsDocument();
|
||||
|
||||
@@ -187,7 +187,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// <value>
|
||||
/// <c>true</c> if new directories are allowed otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public static bool UploadAllowDirectories
|
||||
internal static bool UploadAllowDirectories
|
||||
{
|
||||
get { return bool.Parse(GetKey("/settings/content/UploadAllowDirectories")); }
|
||||
}
|
||||
@@ -214,7 +214,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets a value indicating whether logging is enabled in umbracoSettings.config (/settings/logging/enableLogging).
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if logging is enabled; otherwise, <c>false</c>.</value>
|
||||
public static bool EnableLogging
|
||||
internal static bool EnableLogging
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -229,7 +229,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets a value indicating whether logging happens async.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if async logging is enabled; otherwise, <c>false</c>.</value>
|
||||
public static bool EnableAsyncLogging
|
||||
internal static bool EnableAsyncLogging
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -244,7 +244,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// <summary>
|
||||
/// Gets the assembly of an external logger that can be used to store log items in 3rd party systems
|
||||
/// </summary>
|
||||
public static string ExternalLoggerAssembly
|
||||
internal static string ExternalLoggerAssembly
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -256,7 +256,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// <summary>
|
||||
/// Gets the type of an external logger that can be used to store log items in 3rd party systems
|
||||
/// </summary>
|
||||
public static string ExternalLoggerType
|
||||
internal static string ExternalLoggerType
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -268,7 +268,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// <summary>
|
||||
/// Long Audit Trail to external log too
|
||||
/// </summary>
|
||||
public static bool ExternalLoggerLogAuditTrail
|
||||
internal static bool ExternalLoggerLogAuditTrail
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -287,7 +287,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// <summary>
|
||||
/// Keep user alive as long as they have their browser open? Default is true
|
||||
/// </summary>
|
||||
public static bool KeepUserLoggedIn
|
||||
internal static bool KeepUserLoggedIn
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -302,7 +302,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// <summary>
|
||||
/// Enables the experimental canvas (live) editing on the frontend of the website
|
||||
/// </summary>
|
||||
public static bool EnableCanvasEditing
|
||||
internal static bool EnableCanvasEditing
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -317,7 +317,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// <summary>
|
||||
/// Show disabled users in the tree in the Users section in the backoffice
|
||||
/// </summary>
|
||||
public static bool HideDisabledUsersInBackoffice
|
||||
internal static bool HideDisabledUsersInBackoffice
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -333,7 +333,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets a value indicating whether the logs will be auto cleaned
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if logs are to be automatically cleaned; otherwise, <c>false</c></value>
|
||||
public static bool AutoCleanLogs
|
||||
internal static bool AutoCleanLogs
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -348,7 +348,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// <summary>
|
||||
/// Gets the value indicating the log cleaning frequency (in miliseconds)
|
||||
/// </summary>
|
||||
public static int CleaningMiliseconds
|
||||
internal static int CleaningMiliseconds
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -360,7 +360,7 @@ namespace Umbraco.Core.Configuration
|
||||
}
|
||||
}
|
||||
|
||||
public static int MaxLogAge
|
||||
internal static int MaxLogAge
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -376,7 +376,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets the disabled log types.
|
||||
/// </summary>
|
||||
/// <value>The disabled log types.</value>
|
||||
public static XmlNode DisabledLogTypes
|
||||
internal static XmlNode DisabledLogTypes
|
||||
{
|
||||
get { return GetKeyAsNode("/settings/logging/disabledLogTypes"); }
|
||||
}
|
||||
@@ -385,7 +385,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets the package server url.
|
||||
/// </summary>
|
||||
/// <value>The package server url.</value>
|
||||
public static string PackageServer
|
||||
internal static string PackageServer
|
||||
{
|
||||
get { return "packages.umbraco.org"; }
|
||||
}
|
||||
@@ -396,15 +396,14 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets a value indicating whether umbraco will use domain prefixes.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if umbraco will use domain prefixes; otherwise, <c>false</c>.</value>
|
||||
// TODO rename as EnforceAbsoluteUrls
|
||||
public static bool UseDomainPrefixes
|
||||
internal static bool UseDomainPrefixes
|
||||
{
|
||||
get
|
||||
{
|
||||
// default: false
|
||||
return _useDomainPrefixes ?? GetKeyValue("/settings/requestHandler/useDomainPrefixes", false);
|
||||
}
|
||||
internal set
|
||||
/*internal*/ set
|
||||
{
|
||||
// for unit tests only
|
||||
_useDomainPrefixes = value;
|
||||
@@ -417,7 +416,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// This will add a trailing slash (/) to urls when in directory url mode
|
||||
/// NOTICE: This will always return false if Directory Urls in not active
|
||||
/// </summary>
|
||||
public static bool AddTrailingSlash
|
||||
internal static bool AddTrailingSlash
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -425,7 +424,7 @@ namespace Umbraco.Core.Configuration
|
||||
return GlobalSettings.UseDirectoryUrls
|
||||
&& (_addTrailingSlash ?? GetKeyValue("/settings/requestHandler/addTrailingSlash", false));
|
||||
}
|
||||
internal set
|
||||
/*internal*/ set
|
||||
{
|
||||
// for unit tests only
|
||||
_addTrailingSlash = value;
|
||||
@@ -436,7 +435,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets a value indicating whether umbraco will use ASP.NET MasterPages for rendering instead of its propriatary templating system.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if umbraco will use ASP.NET MasterPages; otherwise, <c>false</c>.</value>
|
||||
public static bool UseAspNetMasterPages
|
||||
internal static bool UseAspNetMasterPages
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -458,7 +457,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets a value indicating whether umbraco will attempt to load any skins to override default template files
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if umbraco will override templates with skins if present and configured <c>false</c>.</value>
|
||||
public static bool EnableTemplateFolders
|
||||
internal static bool EnableTemplateFolders
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -482,7 +481,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// <summary>
|
||||
/// razor DynamicNode typecasting detects XML and returns DynamicXml - Root elements that won't convert to DynamicXml
|
||||
/// </summary>
|
||||
public static IEnumerable<string> NotDynamicXmlDocumentElements
|
||||
internal static IEnumerable<string> NotDynamicXmlDocumentElements
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -571,7 +570,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// <value>
|
||||
/// <c>true</c> if umbraco will clone XML cache on publish; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public static bool CloneXmlCacheOnPublish
|
||||
internal static bool CloneXmlCacheOnPublish
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -593,7 +592,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets a value indicating whether rich text editor content should be parsed by tidy.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if content is parsed; otherwise, <c>false</c>.</value>
|
||||
public static bool TidyEditorContent
|
||||
internal static bool TidyEditorContent
|
||||
{
|
||||
get { return bool.Parse(GetKey("/settings/content/TidyEditorContent")); }
|
||||
}
|
||||
@@ -602,7 +601,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets the encoding type for the tidyied content.
|
||||
/// </summary>
|
||||
/// <value>The encoding type as string.</value>
|
||||
public static string TidyCharEncoding
|
||||
internal static string TidyCharEncoding
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -619,12 +618,12 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets the property context help option, this can either be 'text', 'icon' or 'none'
|
||||
/// </summary>
|
||||
/// <value>The property context help option.</value>
|
||||
public static string PropertyContextHelpOption
|
||||
internal static string PropertyContextHelpOption
|
||||
{
|
||||
get { return GetKey("/settings/content/PropertyContextHelpOption").ToLower(); }
|
||||
}
|
||||
|
||||
public static string DefaultBackofficeProvider
|
||||
internal static string DefaultBackofficeProvider
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -641,14 +640,14 @@ namespace Umbraco.Core.Configuration
|
||||
/// <summary>
|
||||
/// Whether to force safe aliases (no spaces, no special characters) at businesslogic level on contenttypes and propertytypes
|
||||
/// </summary>
|
||||
public static bool ForceSafeAliases
|
||||
internal static bool ForceSafeAliases
|
||||
{
|
||||
get
|
||||
{
|
||||
// default: true
|
||||
return _forceSafeAliases ?? GetKeyValue("/settings/content/ForceSafeAliases", true);
|
||||
}
|
||||
internal set
|
||||
/*internal*/ set
|
||||
{
|
||||
// used for unit testing
|
||||
_forceSafeAliases = value;
|
||||
@@ -673,11 +672,23 @@ namespace Umbraco.Core.Configuration
|
||||
get { return GetKeyValue("/settings/web.routing/@internalRedirectPreservesTemplate", false); }
|
||||
}
|
||||
|
||||
/// <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>
|
||||
/// <value>The allowed image file types.</value>
|
||||
public static string ImageFileTypes
|
||||
internal static string ImageFileTypes
|
||||
{
|
||||
get { return GetKey("/settings/content/imaging/imageFileTypes").ToLowerInvariant(); }
|
||||
}
|
||||
@@ -686,7 +697,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets the allowed script file types.
|
||||
/// </summary>
|
||||
/// <value>The allowed script file types.</value>
|
||||
public static string ScriptFileTypes
|
||||
internal static string ScriptFileTypes
|
||||
{
|
||||
get { return GetKey("/settings/content/scripteditor/scriptFileTypes"); }
|
||||
}
|
||||
@@ -697,14 +708,14 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets the duration in seconds to cache queries to umbraco library member and media methods
|
||||
/// Default is 1800 seconds (30 minutes)
|
||||
/// </summary>
|
||||
public static int UmbracoLibraryCacheDuration
|
||||
internal static int UmbracoLibraryCacheDuration
|
||||
{
|
||||
get
|
||||
{
|
||||
// default: 1800
|
||||
return _umbracoLibraryCacheDuration ?? GetKeyValue("/settings/content/UmbracoLibraryCacheDuration", 1800);
|
||||
}
|
||||
internal set
|
||||
/*internal*/ set
|
||||
{
|
||||
// for unit tests only
|
||||
_umbracoLibraryCacheDuration = value;
|
||||
@@ -715,7 +726,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets the path to the scripts folder used by the script editor.
|
||||
/// </summary>
|
||||
/// <value>The script folder path.</value>
|
||||
public static string ScriptFolderPath
|
||||
internal static string ScriptFolderPath
|
||||
{
|
||||
get { return GetKey("/settings/content/scripteditor/scriptFolderPath"); }
|
||||
}
|
||||
@@ -723,7 +734,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// <summary>
|
||||
/// Enabled or disable the script/code editor
|
||||
/// </summary>
|
||||
public static bool ScriptDisableEditor
|
||||
internal static bool ScriptDisableEditor
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -741,7 +752,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// ex: existingnodename.aspx would become existingnodename(1).aspx if a node with the same name is found
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if umbraco ensures unique node naming; otherwise, <c>false</c>.</value>
|
||||
public static bool EnsureUniqueNaming
|
||||
internal static bool EnsureUniqueNaming
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -760,7 +771,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets the notification email sender.
|
||||
/// </summary>
|
||||
/// <value>The notification email sender.</value>
|
||||
public static string NotificationEmailSender
|
||||
internal static string NotificationEmailSender
|
||||
{
|
||||
get { return GetKey("/settings/content/notifications/email"); }
|
||||
}
|
||||
@@ -771,7 +782,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// <value>
|
||||
/// <c>true</c> if html notification-emails are disabled; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public static bool NotificationDisableHtmlEmail
|
||||
internal static bool NotificationDisableHtmlEmail
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -784,12 +795,12 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets the allowed attributes on images.
|
||||
/// </summary>
|
||||
/// <value>The allowed attributes on images.</value>
|
||||
public static string ImageAllowedAttributes
|
||||
internal static string ImageAllowedAttributes
|
||||
{
|
||||
get { return GetKey("/settings/content/imaging/allowedAttributes"); }
|
||||
}
|
||||
|
||||
public static XmlNode ImageAutoFillImageProperties
|
||||
internal static XmlNode ImageAutoFillImageProperties
|
||||
{
|
||||
get { return GetKeyAsNode("/settings/content/imaging/autoFillImageProperties"); }
|
||||
}
|
||||
@@ -798,7 +809,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets the scheduled tasks as XML
|
||||
/// </summary>
|
||||
/// <value>The scheduled tasks.</value>
|
||||
public static XmlNode ScheduledTasks
|
||||
internal static XmlNode ScheduledTasks
|
||||
{
|
||||
get { return GetKeyAsNode("/settings/scheduledTasks"); }
|
||||
}
|
||||
@@ -807,7 +818,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets a list of characters that will be replaced when generating urls
|
||||
/// </summary>
|
||||
/// <value>The URL replacement characters.</value>
|
||||
public static XmlNode UrlReplaceCharacters
|
||||
internal static XmlNode UrlReplaceCharacters
|
||||
{
|
||||
get { return GetKeyAsNode("/settings/requestHandler/urlReplacing"); }
|
||||
}
|
||||
@@ -815,7 +826,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// <summary>
|
||||
/// Whether to replace double dashes from url (ie my--story----from--dash.aspx caused by multiple url replacement chars
|
||||
/// </summary>
|
||||
public static bool RemoveDoubleDashesFromUrlReplacing
|
||||
internal static bool RemoveDoubleDashesFromUrlReplacing
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -836,7 +847,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Used for load-balancing high-traffic sites.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if umbraco uses distributed calls; otherwise, <c>false</c>.</value>
|
||||
public static bool UseDistributedCalls
|
||||
internal static bool UseDistributedCalls
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -856,7 +867,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets the ID of the user with access rights to perform the distributed calls.
|
||||
/// </summary>
|
||||
/// <value>The distributed call user.</value>
|
||||
public static int DistributedCallUser
|
||||
internal static int DistributedCallUser
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -874,7 +885,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// <summary>
|
||||
/// Gets the html injected into a (x)html page if Umbraco is running in preview mode
|
||||
/// </summary>
|
||||
public static string PreviewBadge
|
||||
internal static string PreviewBadge
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -895,7 +906,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// and update their content cache accordingly, ensuring a consistent cache on all servers
|
||||
/// </summary>
|
||||
/// <value>The distribution servers.</value>
|
||||
public static XmlNode DistributionServers
|
||||
internal static XmlNode DistributionServers
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -915,7 +926,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// A help page configuration specify language, user type, application, application url and
|
||||
/// the target help page url.
|
||||
/// </summary>
|
||||
public static XmlNode HelpPages
|
||||
internal static XmlNode HelpPages
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -937,7 +948,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// All packages installed from a repository gets the repository alias included in the install information
|
||||
/// </summary>
|
||||
/// <value>The repository servers.</value>
|
||||
public static XmlNode Repositories
|
||||
internal static XmlNode Repositories
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -960,7 +971,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// <value>
|
||||
/// <c>true</c> if umbraco will use the viewstate mover module; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public static bool UseViewstateMoverModule
|
||||
internal static bool UseViewstateMoverModule
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -982,7 +993,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Tells us whether the Xml Content cache is disabled or not
|
||||
/// Default is enabled
|
||||
/// </summary>
|
||||
public static bool IsXmlContentCacheDisabled
|
||||
internal static bool IsXmlContentCacheDisabled
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -1007,7 +1018,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Makes it possible to updates environments by syncing the umbraco.config file across instances
|
||||
/// Relates to http://umbraco.codeplex.com/workitem/30722
|
||||
/// </summary>
|
||||
public static bool XmlContentCheckForDiskChanges
|
||||
internal static bool XmlContentCheckForDiskChanges
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -1032,7 +1043,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// If disabled, only documents will generate data.
|
||||
/// This feature is useful if anyone would like to see how data looked at a given time
|
||||
/// </summary>
|
||||
public static bool EnableGlobalPreviewStorage
|
||||
internal static bool EnableGlobalPreviewStorage
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -1060,14 +1071,14 @@ namespace Umbraco.Core.Configuration
|
||||
/// <value>
|
||||
/// <c>true</c> if yes, use the old node/data model; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public static bool UseLegacyXmlSchema
|
||||
internal static bool UseLegacyXmlSchema
|
||||
{
|
||||
get
|
||||
{
|
||||
// default: true
|
||||
return _useLegacySchema ?? GetKeyValue("/settings/content/UseLegacyXmlSchema", false);
|
||||
}
|
||||
internal set
|
||||
/*internal*/ set
|
||||
{
|
||||
// used for unit testing
|
||||
_useLegacySchema = value;
|
||||
@@ -1075,7 +1086,7 @@ namespace Umbraco.Core.Configuration
|
||||
}
|
||||
|
||||
[Obsolete("This setting is not used anymore, the only file extensions that are supported are .cs and .vb files")]
|
||||
public static IEnumerable<string> AppCodeFileExtensionsList
|
||||
internal static IEnumerable<string> AppCodeFileExtensionsList
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -1086,7 +1097,7 @@ namespace Umbraco.Core.Configuration
|
||||
}
|
||||
|
||||
[Obsolete("This setting is not used anymore, the only file extensions that are supported are .cs and .vb files")]
|
||||
public static XmlNode AppCodeFileExtensions
|
||||
internal static XmlNode AppCodeFileExtensions
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -1108,7 +1119,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Tells us whether the Xml to always update disk cache, when changes are made to content
|
||||
/// Default is enabled
|
||||
/// </summary>
|
||||
public static bool ContinouslyUpdateXmlDiskCache
|
||||
internal static bool ContinouslyUpdateXmlDiskCache
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -1134,7 +1145,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// have a splash page
|
||||
/// Default is disabled
|
||||
/// </summary>
|
||||
public static bool EnableSplashWhileLoading
|
||||
internal static bool EnableSplashWhileLoading
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -1155,7 +1166,7 @@ namespace Umbraco.Core.Configuration
|
||||
}
|
||||
|
||||
private static bool? _resolveUrlsFromTextString;
|
||||
public static bool ResolveUrlsFromTextString
|
||||
internal static bool ResolveUrlsFromTextString
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -1192,7 +1203,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// is used instead of the masterpages editor
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if umbraco defaults to using MVC views for templating, otherwise <c>false</c>.</value>
|
||||
public static RenderingEngine DefaultRenderingEngine
|
||||
internal static RenderingEngine DefaultRenderingEngine
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -1233,7 +1244,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// - 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
|
||||
internal static MacroErrorBehaviour MacroErrorBehaviour
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -1268,7 +1279,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// - 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
|
||||
internal static IconPickerBehaviour IconPickerBehaviour
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -1504,7 +1515,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the UmbracoConfigurationSectiont.</typeparam>
|
||||
/// <returns>The UmbracoConfigurationSection of the specified type.</returns>
|
||||
internal static T For<T>()
|
||||
public static T For<T>()
|
||||
where T : UmbracoConfigurationSection, new()
|
||||
{
|
||||
var sectionType = typeof (T);
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets the version comment (like beta or RC).
|
||||
/// </summary>
|
||||
/// <value>The version comment.</value>
|
||||
public static string CurrentComment { get { return "beta"; } }
|
||||
public static string CurrentComment { get { return "beta-2"; } }
|
||||
|
||||
// Get the version of the umbraco.dll by looking at a class in that dll
|
||||
// Had to do it like this due to medium trust issues, see: http://haacked.com/archive/2010/11/04/assembly-location-and-medium-trust.aspx
|
||||
|
||||
@@ -158,7 +158,7 @@ namespace Umbraco.Core
|
||||
.ForEach(x => x.OnApplicationStarted(UmbracoApplication, ApplicationContext));
|
||||
|
||||
//Now, startup all of our legacy startup handler
|
||||
ApplicationEventsResolver.Current.InstantiateLegacyStartupHanlders();
|
||||
ApplicationEventsResolver.Current.InstantiateLegacyStartupHandlers();
|
||||
|
||||
if (afterComplete != null)
|
||||
{
|
||||
@@ -223,9 +223,6 @@ namespace Umbraco.Core
|
||||
ActionsResolver.Current = new ActionsResolver(
|
||||
() => PluginManager.Current.ResolveActions());
|
||||
|
||||
MacroPropertyTypeResolver.Current = new MacroPropertyTypeResolver(
|
||||
PluginManager.Current.ResolveMacroPropertyTypes());
|
||||
|
||||
//the database migration objects
|
||||
MigrationResolver.Current = new MigrationResolver(
|
||||
() => PluginManager.Current.ResolveMigrationTypes());
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.ObjectResolution;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// A resolver to return all <see cref="IMacroPropertyType"/> objects
|
||||
/// </summary>
|
||||
internal sealed class MacroPropertyTypeResolver : ManyObjectsResolverBase<MacroPropertyTypeResolver, IMacroPropertyType>
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="macroPropertyTypes"></param>
|
||||
internal MacroPropertyTypeResolver(IEnumerable<Type> macroPropertyTypes)
|
||||
: base(macroPropertyTypes)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="IMacroPropertyType"/> implementations.
|
||||
/// </summary>
|
||||
public IEnumerable<IMacroPropertyType> MacroPropertyTypes
|
||||
{
|
||||
get
|
||||
{
|
||||
return Values;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Macros.PropertyTypes
|
||||
{
|
||||
internal class ContentAll : IMacroPropertyType
|
||||
{
|
||||
public string Alias
|
||||
{
|
||||
get { return "contentAll"; }
|
||||
}
|
||||
|
||||
public string RenderingAssembly
|
||||
{
|
||||
get { return "umbraco.macroRenderings"; }
|
||||
}
|
||||
|
||||
public string RenderingType
|
||||
{
|
||||
get { return "content"; }
|
||||
}
|
||||
|
||||
public MacroPropertyTypeBaseTypes BaseType
|
||||
{
|
||||
get { return MacroPropertyTypeBaseTypes.Int32; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Macros.PropertyTypes
|
||||
{
|
||||
internal class ContentPicker : IMacroPropertyType
|
||||
{
|
||||
public string Alias
|
||||
{
|
||||
get { return "contentPicker"; }
|
||||
}
|
||||
|
||||
public string RenderingAssembly
|
||||
{
|
||||
get { return "umbraco.macroRenderings"; }
|
||||
}
|
||||
|
||||
public string RenderingType
|
||||
{
|
||||
get { return "content"; }
|
||||
}
|
||||
|
||||
public MacroPropertyTypeBaseTypes BaseType
|
||||
{
|
||||
get { return MacroPropertyTypeBaseTypes.Int32; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Macros.PropertyTypes
|
||||
{
|
||||
internal class ContentRandom : IMacroPropertyType
|
||||
{
|
||||
public string Alias
|
||||
{
|
||||
get { return "contentRandom"; }
|
||||
}
|
||||
|
||||
public string RenderingAssembly
|
||||
{
|
||||
get { return "umbraco.macroRenderings"; }
|
||||
}
|
||||
|
||||
public string RenderingType
|
||||
{
|
||||
get { return "content"; }
|
||||
}
|
||||
|
||||
public MacroPropertyTypeBaseTypes BaseType
|
||||
{
|
||||
get { return MacroPropertyTypeBaseTypes.Int32; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Macros.PropertyTypes
|
||||
{
|
||||
internal class ContentStubs : IMacroPropertyType
|
||||
{
|
||||
public string Alias
|
||||
{
|
||||
get { return "contentStubs"; }
|
||||
}
|
||||
|
||||
public string RenderingAssembly
|
||||
{
|
||||
get { return "umbraco.macroRenderings"; }
|
||||
}
|
||||
|
||||
public string RenderingType
|
||||
{
|
||||
get { return "content"; }
|
||||
}
|
||||
|
||||
public MacroPropertyTypeBaseTypes BaseType
|
||||
{
|
||||
get { return MacroPropertyTypeBaseTypes.Int32; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Macros.PropertyTypes
|
||||
{
|
||||
internal class ContentTree : IMacroPropertyType
|
||||
{
|
||||
public string Alias
|
||||
{
|
||||
get { return "contentTree"; }
|
||||
}
|
||||
|
||||
public string RenderingAssembly
|
||||
{
|
||||
get { return "umbraco.macroRenderings"; }
|
||||
}
|
||||
|
||||
public string RenderingType
|
||||
{
|
||||
get { return "content"; }
|
||||
}
|
||||
|
||||
public MacroPropertyTypeBaseTypes BaseType
|
||||
{
|
||||
get { return MacroPropertyTypeBaseTypes.Int32; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Macros.PropertyTypes
|
||||
{
|
||||
internal class ContentType : IMacroPropertyType
|
||||
{
|
||||
public string Alias
|
||||
{
|
||||
get { return "contentType"; }
|
||||
}
|
||||
|
||||
public string RenderingAssembly
|
||||
{
|
||||
get { return "umbraco.macroRenderings"; }
|
||||
}
|
||||
|
||||
public string RenderingType
|
||||
{
|
||||
get { return "contentTypeSingle"; }
|
||||
}
|
||||
|
||||
public MacroPropertyTypeBaseTypes BaseType
|
||||
{
|
||||
get { return MacroPropertyTypeBaseTypes.Int32; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Macros.PropertyTypes
|
||||
{
|
||||
internal class ContentTypeMultiple : IMacroPropertyType
|
||||
{
|
||||
public string Alias
|
||||
{
|
||||
get { return "contentTypeMultiple"; }
|
||||
}
|
||||
|
||||
public string RenderingAssembly
|
||||
{
|
||||
get { return "umbraco.macroRenderings"; }
|
||||
}
|
||||
|
||||
public string RenderingType
|
||||
{
|
||||
get { return "contentTypeMultiple"; }
|
||||
}
|
||||
|
||||
public MacroPropertyTypeBaseTypes BaseType
|
||||
{
|
||||
get { return MacroPropertyTypeBaseTypes.Int32; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Macros.PropertyTypes
|
||||
{
|
||||
internal class MediaCurrent : IMacroPropertyType
|
||||
{
|
||||
public string Alias
|
||||
{
|
||||
get { return "mediaCurrent"; }
|
||||
}
|
||||
|
||||
public string RenderingAssembly
|
||||
{
|
||||
get { return "umbraco.macroRenderings"; }
|
||||
}
|
||||
|
||||
public string RenderingType
|
||||
{
|
||||
get { return "media"; }
|
||||
}
|
||||
|
||||
public MacroPropertyTypeBaseTypes BaseType
|
||||
{
|
||||
get { return MacroPropertyTypeBaseTypes.Int32; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Macros.PropertyTypes
|
||||
{
|
||||
internal class Number : IMacroPropertyType
|
||||
{
|
||||
public string Alias
|
||||
{
|
||||
get { return "number"; }
|
||||
}
|
||||
|
||||
public string RenderingAssembly
|
||||
{
|
||||
get { return "umbraco.macroRenderings"; }
|
||||
}
|
||||
|
||||
public string RenderingType
|
||||
{
|
||||
get { return "numeric"; }
|
||||
}
|
||||
|
||||
public MacroPropertyTypeBaseTypes BaseType
|
||||
{
|
||||
get { return MacroPropertyTypeBaseTypes.Int32; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Macros.PropertyTypes
|
||||
{
|
||||
internal class PropertyTypePicker : IMacroPropertyType
|
||||
{
|
||||
public string Alias
|
||||
{
|
||||
get { return "propertyTypePicker"; }
|
||||
}
|
||||
|
||||
public string RenderingAssembly
|
||||
{
|
||||
get { return "umbraco.macroRenderings"; }
|
||||
}
|
||||
|
||||
public string RenderingType
|
||||
{
|
||||
get { return "propertyTypePicker"; }
|
||||
}
|
||||
|
||||
public MacroPropertyTypeBaseTypes BaseType
|
||||
{
|
||||
get { return MacroPropertyTypeBaseTypes.String; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Macros.PropertyTypes
|
||||
{
|
||||
internal class PropertyTypePickerMultiple : IMacroPropertyType
|
||||
{
|
||||
public string Alias
|
||||
{
|
||||
get { return "propertyTypePickerMultiple"; }
|
||||
}
|
||||
|
||||
public string RenderingAssembly
|
||||
{
|
||||
get { return "umbraco.macroRenderings"; }
|
||||
}
|
||||
|
||||
public string RenderingType
|
||||
{
|
||||
get { return "propertyTypePickerMultiple"; }
|
||||
}
|
||||
|
||||
public MacroPropertyTypeBaseTypes BaseType
|
||||
{
|
||||
get { return MacroPropertyTypeBaseTypes.String; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Macros.PropertyTypes
|
||||
{
|
||||
internal class TabPicker : IMacroPropertyType
|
||||
{
|
||||
public string Alias
|
||||
{
|
||||
get { return "tabPicker"; }
|
||||
}
|
||||
|
||||
public string RenderingAssembly
|
||||
{
|
||||
get { return "umbraco.macroRenderings"; }
|
||||
}
|
||||
|
||||
public string RenderingType
|
||||
{
|
||||
get { return "tabPicker"; }
|
||||
}
|
||||
|
||||
public MacroPropertyTypeBaseTypes BaseType
|
||||
{
|
||||
get { return MacroPropertyTypeBaseTypes.String; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Macros.PropertyTypes
|
||||
{
|
||||
internal class TabPickerMultiple : IMacroPropertyType
|
||||
{
|
||||
public string Alias
|
||||
{
|
||||
get { return "tabPickerMultiple"; }
|
||||
}
|
||||
|
||||
public string RenderingAssembly
|
||||
{
|
||||
get { return "umbraco.macroRenderings"; }
|
||||
}
|
||||
|
||||
public string RenderingType
|
||||
{
|
||||
get { return "tabPickerMultiple"; }
|
||||
}
|
||||
|
||||
public MacroPropertyTypeBaseTypes BaseType
|
||||
{
|
||||
get { return MacroPropertyTypeBaseTypes.String; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Macros.PropertyTypes
|
||||
{
|
||||
internal class Text : IMacroPropertyType
|
||||
{
|
||||
public string Alias
|
||||
{
|
||||
get { return "text"; }
|
||||
}
|
||||
|
||||
public string RenderingAssembly
|
||||
{
|
||||
get { return "umbraco.macroRenderings"; }
|
||||
}
|
||||
|
||||
public string RenderingType
|
||||
{
|
||||
get { return "text"; }
|
||||
}
|
||||
|
||||
public MacroPropertyTypeBaseTypes BaseType
|
||||
{
|
||||
get { return MacroPropertyTypeBaseTypes.String; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Macros.PropertyTypes
|
||||
{
|
||||
internal class TextMultiLine : IMacroPropertyType
|
||||
{
|
||||
public string Alias
|
||||
{
|
||||
get { return "textMultiLine"; }
|
||||
}
|
||||
|
||||
public string RenderingAssembly
|
||||
{
|
||||
get { return "umbraco.macroRenderings"; }
|
||||
}
|
||||
|
||||
public string RenderingType
|
||||
{
|
||||
get { return "textMultiple"; }
|
||||
}
|
||||
|
||||
public MacroPropertyTypeBaseTypes BaseType
|
||||
{
|
||||
get { return MacroPropertyTypeBaseTypes.String; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Macros.PropertyTypes
|
||||
{
|
||||
internal class YesNoBool : IMacroPropertyType
|
||||
{
|
||||
public string Alias
|
||||
{
|
||||
get { return "bool"; }
|
||||
}
|
||||
|
||||
public string RenderingAssembly
|
||||
{
|
||||
get { return "umbraco.macroRenderings"; }
|
||||
}
|
||||
|
||||
public string RenderingType
|
||||
{
|
||||
get { return "yesNo"; }
|
||||
}
|
||||
|
||||
public MacroPropertyTypeBaseTypes BaseType
|
||||
{
|
||||
get { return MacroPropertyTypeBaseTypes.Boolean; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
@@ -16,12 +15,22 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
private int _defaultTemplate;
|
||||
private IEnumerable<ITemplate> _allowedTemplates;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Constuctor for creating a ContentType with the parent's id.
|
||||
/// </summary>
|
||||
/// <remarks>You usually only want to use this for creating ContentTypes at the root.</remarks>
|
||||
/// <param name="parentId"></param>
|
||||
public ContentType(int parentId) : base(parentId)
|
||||
{
|
||||
_allowedTemplates = new List<ITemplate>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constuctor for creating a ContentType with the parent as an inherited type.
|
||||
/// </summary>
|
||||
/// <remarks>Use this to ensure inheritance from parent.</remarks>
|
||||
/// <param name="parent"></param>
|
||||
public ContentType(IContentType parent) : base(parent)
|
||||
{
|
||||
_allowedTemplates = new List<ITemplate>();
|
||||
@@ -152,14 +161,24 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
base.ResetDirtyProperties();
|
||||
|
||||
//loop through each property group to reset the property types
|
||||
var propertiesReset = new List<int>();
|
||||
|
||||
foreach (var propertyGroup in PropertyGroups)
|
||||
{
|
||||
propertyGroup.ResetDirtyProperties();
|
||||
foreach (var propertyType in propertyGroup.PropertyTypes)
|
||||
{
|
||||
{
|
||||
propertyType.ResetDirtyProperties();
|
||||
propertiesReset.Add(propertyType.Id);
|
||||
}
|
||||
}
|
||||
//then loop through our property type collection since some might not exist on a property group
|
||||
//but don't re-reset ones we've already done.
|
||||
foreach (var propertyType in PropertyTypes.Where(x => propertiesReset.Contains(x.Id) == false))
|
||||
{
|
||||
propertyType.ResetDirtyProperties();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -20,8 +20,10 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
}
|
||||
|
||||
protected ContentTypeCompositionBase(IContentTypeBase parent) : base(parent)
|
||||
protected ContentTypeCompositionBase(IContentTypeComposition parent)
|
||||
: base(parent)
|
||||
{
|
||||
AddContentType(parent);
|
||||
}
|
||||
|
||||
private static readonly PropertyInfo ContentTypeCompositionSelector =
|
||||
|
||||
@@ -171,19 +171,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,94 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a Macro
|
||||
/// </summary>
|
||||
internal interface IMacro : IAggregateRoot
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the alias of the Macro
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
string Alias { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the Macro
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a boolean indicating whether the Macro can be used in an Editor
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
bool UseInEditor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Cache Duration for the Macro
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
int CacheDuration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a boolean indicating whether the Macro should be Cached by Page
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
bool CacheByPage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a boolean indicating whether the Macro should be Cached Personally
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
bool CacheByMember { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a boolean indicating whether the Macro should be rendered in an Editor
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
bool DontRender { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the path to the script file in use
|
||||
/// </summary>
|
||||
/// <remarks>Optional: Can only be one of three Script, Python or Xslt</remarks>
|
||||
[DataMember]
|
||||
string ScriptFile { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the assembly, which should be used by the Macro
|
||||
/// </summary>
|
||||
/// <remarks>Will usually only be filled if the ScriptFile is a Usercontrol</remarks>
|
||||
[DataMember]
|
||||
string ScriptAssembly { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or set the path to the Python file in use
|
||||
/// </summary>
|
||||
/// <remarks>Optional: Can only be one of three Script, Python or Xslt</remarks>
|
||||
[DataMember]
|
||||
string Python { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the path to the Xslt file in use
|
||||
/// </summary>
|
||||
/// <remarks>Optional: Can only be one of three Script, Python or Xslt</remarks>
|
||||
[DataMember]
|
||||
string Xslt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a list of Macro Properties
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
List<IMacroProperty> Properties { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns an enum <see cref="MacroTypes"/> based on the properties on the Macro
|
||||
/// </summary>
|
||||
/// <returns><see cref="MacroTypes"/></returns>
|
||||
MacroTypes MacroType();
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a Property for a Macro
|
||||
/// </summary>
|
||||
internal interface IMacroProperty : IValueObject
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the Alias of the Property
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
string Alias { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Name of the Property
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Sort Order of the Property
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
int SortOrder { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Type for this Property
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The MacroPropertyTypes acts as a plugin for Macros.
|
||||
/// All types was previously contained in the database, but has been ported to code.
|
||||
/// </remarks>
|
||||
[DataMember]
|
||||
IMacroPropertyType PropertyType { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a PropertyType (plugin) for a Macro
|
||||
/// </summary>
|
||||
internal interface IMacroPropertyType
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the unique Alias of the Property Type
|
||||
/// </summary>
|
||||
string Alias { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the Assembly used to render the Property Type
|
||||
/// </summary>
|
||||
string RenderingAssembly { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the Type used to render the Property Type
|
||||
/// </summary>
|
||||
string RenderingType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Base Type for storing the PropertyType (Int32, String, Boolean)
|
||||
/// </summary>
|
||||
MacroPropertyTypeBaseTypes BaseType { get; }
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
|
||||
@@ -1,290 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a Macro
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[DataContract(IsReference = true)]
|
||||
internal class Macro : Entity, IMacro
|
||||
{
|
||||
private string _alias;
|
||||
private string _name;
|
||||
private bool _useInEditor;
|
||||
private int _cacheDuration;
|
||||
private bool _cacheByPage;
|
||||
private bool _cacheByMember;
|
||||
private bool _dontRender;
|
||||
private string _scriptFile;
|
||||
private string _scriptAssembly;
|
||||
private string _python;
|
||||
private string _xslt;
|
||||
private List<IMacroProperty> _properties;
|
||||
|
||||
private static readonly PropertyInfo AliasSelector = ExpressionHelper.GetPropertyInfo<Macro, string>(x => x.Alias);
|
||||
private static readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo<Macro, string>(x => x.Name);
|
||||
private static readonly PropertyInfo UseInEditorSelector = ExpressionHelper.GetPropertyInfo<Macro, bool>(x => x.UseInEditor);
|
||||
private static readonly PropertyInfo CacheDurationSelector = ExpressionHelper.GetPropertyInfo<Macro, int>(x => x.CacheDuration);
|
||||
private static readonly PropertyInfo CacheByPageSelector = ExpressionHelper.GetPropertyInfo<Macro, bool>(x => x.CacheByPage);
|
||||
private static readonly PropertyInfo CacheByMemberSelector = ExpressionHelper.GetPropertyInfo<Macro, bool>(x => x.CacheByMember);
|
||||
private static readonly PropertyInfo DontRenderSelector = ExpressionHelper.GetPropertyInfo<Macro, bool>(x => x.DontRender);
|
||||
private static readonly PropertyInfo ScriptFileSelector = ExpressionHelper.GetPropertyInfo<Macro, string>(x => x.ScriptFile);
|
||||
private static readonly PropertyInfo ScriptAssemblySelector = ExpressionHelper.GetPropertyInfo<Macro, string>(x => x.ScriptAssembly);
|
||||
private static readonly PropertyInfo PythonSelector = ExpressionHelper.GetPropertyInfo<Macro, string>(x => x.Python);
|
||||
private static readonly PropertyInfo XsltSelector = ExpressionHelper.GetPropertyInfo<Macro, string>(x => x.Xslt);
|
||||
private static readonly PropertyInfo PropertiesSelector = ExpressionHelper.GetPropertyInfo<Macro, List<IMacroProperty>>(x => x.Properties);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the alias of the Macro
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public string Alias
|
||||
{
|
||||
get { return _alias; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_alias = value;
|
||||
return _alias;
|
||||
}, _alias, AliasSelector);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the Macro
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public string Name
|
||||
{
|
||||
get { return _name; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_name = value;
|
||||
return _name;
|
||||
}, _name, NameSelector);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a boolean indicating whether the Macro can be used in an Editor
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public bool UseInEditor
|
||||
{
|
||||
get { return _useInEditor; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_useInEditor = value;
|
||||
return _useInEditor;
|
||||
}, _useInEditor, UseInEditorSelector);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Cache Duration for the Macro
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public int CacheDuration
|
||||
{
|
||||
get { return _cacheDuration; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_cacheDuration = value;
|
||||
return _cacheDuration;
|
||||
}, _cacheDuration, CacheDurationSelector);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a boolean indicating whether the Macro should be Cached by Page
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public bool CacheByPage
|
||||
{
|
||||
get { return _cacheByPage; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_cacheByPage = value;
|
||||
return _cacheByPage;
|
||||
}, _cacheByPage, CacheByPageSelector);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a boolean indicating whether the Macro should be Cached Personally
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public bool CacheByMember
|
||||
{
|
||||
get { return _cacheByMember; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_cacheByMember = value;
|
||||
return _cacheByMember;
|
||||
}, _cacheByMember, CacheByMemberSelector);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a boolean indicating whether the Macro should be rendered in an Editor
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public bool DontRender
|
||||
{
|
||||
get { return _dontRender; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_dontRender = value;
|
||||
return _dontRender;
|
||||
}, _dontRender, DontRenderSelector);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the path to the script file in use
|
||||
/// </summary>
|
||||
/// <remarks>Optional: Can only be one of three Script, Python or Xslt</remarks>
|
||||
[DataMember]
|
||||
public string ScriptFile
|
||||
{
|
||||
get { return _scriptFile; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_scriptFile = value;
|
||||
return _scriptFile;
|
||||
}, _scriptFile, ScriptFileSelector);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the assembly, which should be used by the Macro
|
||||
/// </summary>
|
||||
/// <remarks>Will usually only be filled if the ScriptFile is a Usercontrol</remarks>
|
||||
[DataMember]
|
||||
public string ScriptAssembly
|
||||
{
|
||||
get { return _scriptAssembly; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_scriptAssembly = value;
|
||||
return _scriptAssembly;
|
||||
}, _scriptAssembly, ScriptAssemblySelector);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or set the path to the Python file in use
|
||||
/// </summary>
|
||||
/// <remarks>Optional: Can only be one of three Script, Python or Xslt</remarks>
|
||||
[DataMember]
|
||||
public string Python
|
||||
{
|
||||
get { return _python; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_python = value;
|
||||
return _python;
|
||||
}, _python, PythonSelector);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the path to the Xslt file in use
|
||||
/// </summary>
|
||||
/// <remarks>Optional: Can only be one of three Script, Python or Xslt</remarks>
|
||||
[DataMember]
|
||||
public string Xslt
|
||||
{
|
||||
get { return _xslt; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_xslt = value;
|
||||
return _xslt;
|
||||
}, _xslt, XsltSelector);
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: This needs to be changed to a custom collection class so we can track the dirtyness of each property!
|
||||
/// <summary>
|
||||
/// Gets or sets a list of Macro Properties
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public List<IMacroProperty> Properties
|
||||
{
|
||||
get { return _properties; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_properties = value;
|
||||
return _properties;
|
||||
}, _properties, PropertiesSelector);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overridden this method in order to set a random Id
|
||||
/// </summary>
|
||||
internal override void AddingEntity()
|
||||
{
|
||||
base.AddingEntity();
|
||||
|
||||
var random = new Random();
|
||||
Id = random.Next(10000, int.MaxValue);
|
||||
|
||||
Key = Alias.EncodeAsGuid();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an enum <see cref="MacroTypes"/> based on the properties on the Macro
|
||||
/// </summary>
|
||||
/// <returns><see cref="MacroTypes"/></returns>
|
||||
public MacroTypes MacroType()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(Xslt))
|
||||
return MacroTypes.Xslt;
|
||||
|
||||
if (!string.IsNullOrEmpty(Python))
|
||||
return MacroTypes.Python;
|
||||
|
||||
if (!string.IsNullOrEmpty(ScriptFile))
|
||||
return MacroTypes.Script;
|
||||
|
||||
if (!string.IsNullOrEmpty(ScriptFile) && ScriptFile.ToLower().IndexOf(".ascx", StringComparison.InvariantCultureIgnoreCase) > -1)
|
||||
{
|
||||
return MacroTypes.UserControl;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(ScriptFile) && !string.IsNullOrEmpty(ScriptAssembly))
|
||||
return MacroTypes.CustomControl;
|
||||
|
||||
return MacroTypes.Unknown;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a Macro Property
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[DataContract(IsReference = true)]
|
||||
internal class MacroProperty : TracksChangesEntityBase, IMacroProperty, IRememberBeingDirty
|
||||
{
|
||||
private string _alias;
|
||||
private string _name;
|
||||
private int _sortOrder;
|
||||
private IMacroPropertyType _propertyType;
|
||||
|
||||
private static readonly PropertyInfo AliasSelector = ExpressionHelper.GetPropertyInfo<MacroProperty, string>(x => x.Alias);
|
||||
private static readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo<MacroProperty, string>(x => x.Name);
|
||||
private static readonly PropertyInfo SortOrderSelector = ExpressionHelper.GetPropertyInfo<MacroProperty, int>(x => x.SortOrder);
|
||||
private static readonly PropertyInfo PropertyTypeSelector = ExpressionHelper.GetPropertyInfo<MacroProperty, IMacroPropertyType>(x => x.PropertyType);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Alias of the Property
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public string Alias
|
||||
{
|
||||
get { return _alias; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_alias = value;
|
||||
return _alias;
|
||||
}, _alias, AliasSelector);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Name of the Property
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public string Name
|
||||
{
|
||||
get { return _name; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_name = value;
|
||||
return _name;
|
||||
}, _name, NameSelector);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Sort Order of the Property
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public int SortOrder
|
||||
{
|
||||
get { return _sortOrder; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_sortOrder = value;
|
||||
return _sortOrder;
|
||||
}, _sortOrder, SortOrderSelector);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Type for this Property
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The MacroPropertyTypes acts as a plugin for Macros.
|
||||
/// All types was previously contained in the database, but has been ported to code.
|
||||
/// </remarks>
|
||||
[DataMember]
|
||||
public IMacroPropertyType PropertyType
|
||||
|
||||
{
|
||||
get { return _propertyType; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_propertyType = value;
|
||||
return _propertyType;
|
||||
}, _propertyType, PropertyTypeSelector);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Enum for the three allowed BaseTypes
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[DataContract(IsReference = true)]
|
||||
internal enum MacroPropertyTypeBaseTypes
|
||||
{
|
||||
[EnumMember]
|
||||
Int32,
|
||||
[EnumMember]
|
||||
Boolean,
|
||||
[EnumMember]
|
||||
String
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Enum for the various types of Macros
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[DataContract(IsReference = true)]
|
||||
internal enum MacroTypes
|
||||
{
|
||||
[EnumMember]
|
||||
Xslt = 1,
|
||||
[EnumMember]
|
||||
CustomControl = 2,
|
||||
[EnumMember]
|
||||
UserControl = 3,
|
||||
[EnumMember]
|
||||
Unknown = 4,
|
||||
[EnumMember]
|
||||
Python = 5,
|
||||
[EnumMember]
|
||||
Script = 6
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
@@ -11,10 +10,20 @@ namespace Umbraco.Core.Models
|
||||
[DataContract(IsReference = true)]
|
||||
public class MediaType : ContentTypeCompositionBase, IMediaType
|
||||
{
|
||||
/// <summary>
|
||||
/// Constuctor for creating a MediaType with the parent's id.
|
||||
/// </summary>
|
||||
/// <remarks>You usually only want to use this for creating MediaTypes at the root.</remarks>
|
||||
/// <param name="parentId"></param>
|
||||
public MediaType(int parentId) : base(parentId)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constuctor for creating a MediaType with the parent as an inherited type.
|
||||
/// </summary>
|
||||
/// <remarks>Use this to ensure inheritance from parent.</remarks>
|
||||
/// <param name="parent"></param>
|
||||
public MediaType(IMediaType parent) : base(parent)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ 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;
|
||||
@@ -34,22 +33,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);
|
||||
@@ -206,6 +195,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; }
|
||||
@@ -240,7 +230,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
|
||||
@@ -252,7 +242,6 @@ namespace Umbraco.Core.Models
|
||||
}, _validationRegExp, ValidationRegExpSelector);
|
||||
}
|
||||
}
|
||||
//Note that Validation should eventually come from PropertyEditors like in v5
|
||||
|
||||
/// <summary>
|
||||
/// Create a new Property object from a "raw" database value.
|
||||
|
||||
@@ -94,5 +94,10 @@ namespace Umbraco.Core.Models
|
||||
}, _isActive, IsActiveSelector);
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "(" + ServerAddress + ", " + ComputerName + ", IsActive = " + IsActive + ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -45,12 +45,8 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
base.Path = path;
|
||||
ParentId = -1;
|
||||
Key = name.EncodeAsGuid();
|
||||
_name = name.Replace("/", ".").Replace("\\", "");
|
||||
_alias = alias.ToSafeAlias();
|
||||
|
||||
CreateDate = DateTime.Now;
|
||||
UpdateDate = DateTime.Now;
|
||||
}
|
||||
|
||||
[DataMember]
|
||||
@@ -199,5 +195,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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@ using System.Xml;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
internal static class ObjectExtensions
|
||||
public static class ObjectExtensions
|
||||
{
|
||||
|
||||
//private static readonly ConcurrentDictionary<Type, Func<object>> ObjectFactoryCache = new ConcurrentDictionary<Type, Func<object>>();
|
||||
@@ -36,7 +36,7 @@ namespace Umbraco.Core
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="input">The input.</param>
|
||||
/// <returns></returns>
|
||||
public static T SafeCast<T>(this object input)
|
||||
internal static T SafeCast<T>(this object input)
|
||||
{
|
||||
if (ReferenceEquals(null, input) || ReferenceEquals(default(T), input)) return default(T);
|
||||
if (input is T) return (T)input;
|
||||
@@ -165,7 +165,7 @@ namespace Umbraco.Core
|
||||
return Attempt<object>.False;
|
||||
}
|
||||
|
||||
public static void CheckThrowObjectDisposed(this IDisposable disposable, bool isDisposed, string objectname)
|
||||
internal static void CheckThrowObjectDisposed(this IDisposable disposable, bool isDisposed, string objectname)
|
||||
{
|
||||
//TODO: Localise this exception
|
||||
if (isDisposed)
|
||||
@@ -246,7 +246,7 @@ namespace Umbraco.Core
|
||||
/// <param name="o"></param>
|
||||
/// <param name="ignoreProperties"></param>
|
||||
/// <returns></returns>
|
||||
public static IDictionary<string, TVal> ToDictionary<T, TProperty, TVal>(this T o,
|
||||
internal static IDictionary<string, TVal> ToDictionary<T, TProperty, TVal>(this T o,
|
||||
params Expression<Func<T, TProperty>>[] ignoreProperties)
|
||||
{
|
||||
return o.ToDictionary<TVal>(ignoreProperties.Select(e => o.GetPropertyInfo(e)).Select(propInfo => propInfo.Name).ToArray());
|
||||
@@ -258,7 +258,7 @@ namespace Umbraco.Core
|
||||
/// <param name="o"></param>
|
||||
/// <param name="ignoreProperties">Properties to ignore</param>
|
||||
/// <returns></returns>
|
||||
public static IDictionary<string, TVal> ToDictionary<TVal>(this object o, params string[] ignoreProperties)
|
||||
internal static IDictionary<string, TVal> ToDictionary<TVal>(this object o, params string[] ignoreProperties)
|
||||
{
|
||||
if (o != null)
|
||||
{
|
||||
@@ -277,7 +277,7 @@ namespace Umbraco.Core
|
||||
return new Dictionary<string, TVal>();
|
||||
}
|
||||
|
||||
public static string ToDebugString(this object obj, int levels = 0)
|
||||
internal static string ToDebugString(this object obj, int levels = 0)
|
||||
{
|
||||
if (obj == null) return "{null}";
|
||||
try
|
||||
@@ -346,7 +346,7 @@ namespace Umbraco.Core
|
||||
/// <param name="value"></param>
|
||||
/// <param name="type"></param>
|
||||
/// <returns></returns>
|
||||
public static Attempt<string> TryConvertToXmlString(this object value, Type type)
|
||||
internal static Attempt<string> TryConvertToXmlString(this object value, Type type)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -365,7 +365,7 @@ namespace Umbraco.Core
|
||||
/// <param name="value"></param>
|
||||
/// <param name="type">The Type can only be a primitive type or Guid and byte[] otherwise an exception is thrown</param>
|
||||
/// <returns></returns>
|
||||
public static string ToXmlString(this object value, Type type)
|
||||
internal static string ToXmlString(this object value, Type type)
|
||||
{
|
||||
if (type == typeof(string)) return ((string)value).IsNullOrWhiteSpace() ? "" : (string)value;
|
||||
if (type == typeof(bool)) return XmlConvert.ToString((bool)value);
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace Umbraco.Core.ObjectResolution
|
||||
/// <summary>
|
||||
/// Create instances of all of the legacy startup handlers
|
||||
/// </summary>
|
||||
public void InstantiateLegacyStartupHanlders()
|
||||
public void InstantiateLegacyStartupHandlers()
|
||||
{
|
||||
//this will instantiate them all
|
||||
var handlers = _legacyResolver.LegacyStartupHandlers;
|
||||
|
||||
@@ -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,29 +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(_connectionString) == 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(_connectionString) == false &&
|
||||
string.IsNullOrEmpty(_providerName) == false
|
||||
string.IsNullOrEmpty(_connectionString) == false && string.IsNullOrEmpty(_providerName) == false
|
||||
? new UmbracoDatabase(_connectionString, _providerName)
|
||||
: new UmbracoDatabase(_connectionStringName));
|
||||
}
|
||||
@@ -88,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
|
||||
};
|
||||
//on initial construction we don't want to have dirty properties tracked
|
||||
// http://issues.umbraco.org/issue/U4-1946
|
||||
|
||||
@@ -11,6 +11,8 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
private readonly IContentTypeComposition _contentType;
|
||||
private readonly Guid _version;
|
||||
private readonly int _id;
|
||||
private readonly DateTime _createDate;
|
||||
private readonly DateTime _updateDate;
|
||||
|
||||
public PropertyFactory(IContentTypeComposition contentType, Guid version, int id)
|
||||
{
|
||||
@@ -19,6 +21,15 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
_id = id;
|
||||
}
|
||||
|
||||
public PropertyFactory(IContentTypeComposition contentType, Guid version, int id, DateTime createDate, DateTime updateDate)
|
||||
{
|
||||
_contentType = contentType;
|
||||
_version = version;
|
||||
_id = id;
|
||||
_createDate = createDate;
|
||||
_updateDate = updateDate;
|
||||
}
|
||||
|
||||
#region Implementation of IEntityFactory<IContent,PropertyDataDto>
|
||||
|
||||
public IEnumerable<Property> BuildEntity(IEnumerable<PropertyDataDto> dtos)
|
||||
@@ -34,6 +45,8 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
propertyDataDto.VersionId.Value,
|
||||
propertyDataDto.Id);
|
||||
//on initial construction we don't want to have dirty properties tracked
|
||||
property.CreateDate = _createDate;
|
||||
property.UpdateDate = _updateDate;
|
||||
// http://issues.umbraco.org/issue/U4-1946
|
||||
property.ResetDirtyProperties(false);
|
||||
properties.Add(property);
|
||||
|
||||
@@ -9,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)
|
||||
@@ -58,7 +67,9 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
Mandatory = typeDto.Mandatory,
|
||||
SortOrder = typeDto.SortOrder,
|
||||
ValidationRegExp = typeDto.ValidationRegExp,
|
||||
PropertyGroupId = new Lazy<int>(() => tempGroupDto.Id)
|
||||
PropertyGroupId = new Lazy<int>(() => tempGroupDto.Id),
|
||||
CreateDate = _createDate,
|
||||
UpdateDate = _updateDate
|
||||
};
|
||||
//on initial construction we don't want to have dirty properties tracked
|
||||
// http://issues.umbraco.org/issue/U4-1946
|
||||
|
||||
@@ -55,27 +55,29 @@ 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)},
|
||||
{41, typeof (ServerRegistrationDto)}
|
||||
};
|
||||
#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);
|
||||
|
||||
@@ -401,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);
|
||||
@@ -437,7 +455,7 @@ 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);
|
||||
|
||||
//on initial construction we don't want to have dirty properties tracked
|
||||
// http://issues.umbraco.org/issue/U4-1946
|
||||
@@ -445,7 +463,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
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("*")
|
||||
@@ -456,7 +474,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);
|
||||
|
||||
@@ -326,7 +326,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("*")
|
||||
@@ -340,12 +340,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("*")
|
||||
@@ -371,7 +371,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
|
||||
|
||||
@@ -51,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())
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the Macro Repository, which exposes CRUD operations for <see cref="IMacro"/>
|
||||
/// </summary>
|
||||
/// <remarks>Uses string Alias as the Id type</remarks>
|
||||
internal interface IMacroRepository : IRepositoryQueryable<string, IMacro>
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Persistence.Caching;
|
||||
using Umbraco.Core.Persistence.Querying;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
using Umbraco.Core.Serialization;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the Macro Repository
|
||||
/// </summary>
|
||||
internal class MacroRepository : RepositoryBase<string, IMacro>, IMacroRepository
|
||||
{
|
||||
private IFileSystem _fileSystem;
|
||||
private SerializationService _serializationService;
|
||||
|
||||
public MacroRepository(IUnitOfWork work)
|
||||
: base(work)
|
||||
{
|
||||
EnsureDependencies();
|
||||
}
|
||||
|
||||
public MacroRepository(IUnitOfWork work, IRepositoryCacheProvider cache)
|
||||
: base(work, cache)
|
||||
{
|
||||
EnsureDependencies();
|
||||
}
|
||||
|
||||
private void EnsureDependencies()
|
||||
{
|
||||
_fileSystem = new PhysicalFileSystem("~/App_Data/Macros");
|
||||
var jsonSerializer = new JsonNetSerializer();
|
||||
_serializationService = new SerializationService(jsonSerializer);
|
||||
}
|
||||
|
||||
#region Overrides of RepositoryBase<string,IMacro>
|
||||
|
||||
protected override IMacro PerformGet(string id)
|
||||
{
|
||||
var name = string.Concat(id, ".macro");
|
||||
Stream file = _fileSystem.OpenFile(name);
|
||||
var o = _serializationService.FromStream(file, typeof(Macro));
|
||||
var macro = o as IMacro;
|
||||
|
||||
//on initial construction we don't want to have dirty properties tracked
|
||||
// http://issues.umbraco.org/issue/U4-1946
|
||||
if(macro != null)
|
||||
((Entity)macro).ResetDirtyProperties(false);
|
||||
|
||||
return macro;
|
||||
}
|
||||
|
||||
protected override IEnumerable<IMacro> PerformGetAll(params string[] ids)
|
||||
{
|
||||
if (ids.Any())
|
||||
{
|
||||
foreach (var id in ids)
|
||||
{
|
||||
yield return Get(id);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var files = _fileSystem.GetFiles("", "*.macro");
|
||||
foreach (var file in files)
|
||||
{
|
||||
yield return Get(file.Replace(".macro", ""));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override IEnumerable<IMacro> PerformGetByQuery(IQuery<IMacro> query)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected override bool PerformExists(string id)
|
||||
{
|
||||
var name = string.Concat(id, ".macro");
|
||||
return _fileSystem.FileExists(name);
|
||||
}
|
||||
|
||||
protected override int PerformCount(IQuery<IMacro> query)
|
||||
{
|
||||
var files = _fileSystem.GetFiles("", "*.macro");
|
||||
return files.Count();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Overrides of IUnitOfWorkRepository
|
||||
|
||||
protected override void PersistNewItem(IMacro entity)
|
||||
{
|
||||
((Macro)entity).AddingEntity();
|
||||
|
||||
var name = string.Concat(entity.Alias, ".macro");
|
||||
var json = _serializationService.ToStream(entity);
|
||||
_fileSystem.AddFile(name, json.ResultStream, true);
|
||||
|
||||
((ICanBeDirty)entity).ResetDirtyProperties();
|
||||
}
|
||||
|
||||
protected override void PersistUpdatedItem(IMacro entity)
|
||||
{
|
||||
((Macro)entity).UpdatingEntity();
|
||||
|
||||
var name = string.Concat(entity.Alias, ".macro");
|
||||
var json = _serializationService.ToStream(entity);
|
||||
_fileSystem.AddFile(name, json.ResultStream, true);
|
||||
|
||||
((ICanBeDirty)entity).ResetDirtyProperties();
|
||||
}
|
||||
|
||||
protected override void PersistDeletedItem(IMacro entity)
|
||||
{
|
||||
var name = string.Concat(entity.Alias, ".macro");
|
||||
if (_fileSystem.FileExists(name))
|
||||
{
|
||||
_fileSystem.DeleteFile(name);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
//on initial construction we don't want to have dirty properties tracked
|
||||
// http://issues.umbraco.org/issue/U4-1946
|
||||
@@ -120,6 +120,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",
|
||||
@@ -157,7 +159,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);
|
||||
|
||||
//on initial construction we don't want to have dirty properties tracked
|
||||
// http://issues.umbraco.org/issue/U4-1946
|
||||
@@ -342,7 +344,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("*")
|
||||
@@ -353,7 +355,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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
};
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
};
|
||||
@@ -75,7 +74,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
}
|
||||
else
|
||||
{
|
||||
var files = FileSystem.GetFiles("", "*");
|
||||
var files = FindAllFiles("");
|
||||
foreach (var file in files)
|
||||
{
|
||||
yield return Get(file);
|
||||
|
||||
@@ -191,6 +191,8 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
//Save to db
|
||||
var template = entity as Template;
|
||||
template.AddingEntity();
|
||||
|
||||
var factory = new TemplateFactory(NodeObjectTypeId);
|
||||
var dto = factory.BuildDto(template);
|
||||
|
||||
@@ -259,6 +261,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
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);
|
||||
|
||||
|
||||
@@ -76,13 +76,6 @@ namespace Umbraco.Core.Persistence
|
||||
InMemoryCacheProvider.Current);
|
||||
}
|
||||
|
||||
internal virtual IMacroRepository CreateMacroRepository(IUnitOfWork uow)
|
||||
{
|
||||
return new MacroRepository(
|
||||
uow,
|
||||
InMemoryCacheProvider.Current);
|
||||
}
|
||||
|
||||
public virtual IMediaRepository CreateMediaRepository(IDatabaseUnitOfWork uow)
|
||||
{
|
||||
return new MediaRepository(
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
using StackExchange.Profiling;
|
||||
using Umbraco.Core.Logging;
|
||||
|
||||
namespace Umbraco.Core.Persistence
|
||||
@@ -40,6 +41,13 @@ namespace Umbraco.Core.Persistence
|
||||
{
|
||||
}
|
||||
|
||||
public override IDbConnection OnConnectionOpened(IDbConnection connection)
|
||||
{
|
||||
// wrap the connection with a profiling connection that tracks timings
|
||||
return new StackExchange.Profiling.Data.ProfiledDbConnection(connection as DbConnection, MiniProfiler.Current);
|
||||
}
|
||||
|
||||
|
||||
public override void OnException(Exception x)
|
||||
{
|
||||
LogHelper.Info<UmbracoDatabase>(x.StackTrace);
|
||||
|
||||
@@ -487,15 +487,6 @@ namespace Umbraco.Core
|
||||
return ResolveTypes<IAction>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all available IMacroPropertyTypes in application
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
internal IEnumerable<Type> ResolveMacroPropertyTypes()
|
||||
{
|
||||
return ResolveTypes<IMacroPropertyType>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all mapper types that have a MapperFor attribute defined
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using StackExchange.Profiling;
|
||||
|
||||
namespace Umbraco.Core.Profiling
|
||||
{
|
||||
public class Profiler
|
||||
{
|
||||
private static Profiler _instance;
|
||||
|
||||
private Profiler()
|
||||
{
|
||||
}
|
||||
|
||||
public string Render()
|
||||
{
|
||||
return MiniProfiler.RenderIncludes().ToString();
|
||||
}
|
||||
|
||||
public IDisposable Step(string name)
|
||||
{
|
||||
return MiniProfiler.Current.Step(name);
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
MiniProfiler.Start();
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
MiniProfiler.Stop();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static Profiler Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_instance == null)
|
||||
{
|
||||
_instance = new Profiler();
|
||||
}
|
||||
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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")]
|
||||
@@ -41,4 +41,5 @@ using System.Security.Permissions;
|
||||
[assembly: InternalsVisibleTo("UmbracoExamine")]
|
||||
[assembly: InternalsVisibleTo("Umbraco.Courier.Persistence")]
|
||||
|
||||
[assembly: InternalsVisibleTo("Concorde.Sync")]
|
||||
[assembly: InternalsVisibleTo("Concorde.Sync")]
|
||||
[assembly: InternalsVisibleTo("Umbraco.Belle")]
|
||||
@@ -22,37 +22,14 @@ namespace Umbraco.Core
|
||||
/// </remarks>
|
||||
internal class PublishedContentHelper : ApplicationEventHandler
|
||||
{
|
||||
|
||||
#region event handlers to ensure that the cache is cleared when content types change
|
||||
protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
|
||||
{
|
||||
ContentTypeService.SavedContentType += ContentTypeServiceSavedContentType;
|
||||
ContentTypeService.SavedMediaType += ContentTypeServiceSavedMediaType;
|
||||
ContentTypeService.DeletedContentType += ContentTypeServiceDeletedContentType;
|
||||
ContentTypeService.DeletedMediaType += ContentTypeServiceDeletedMediaType;
|
||||
}
|
||||
|
||||
static void ContentTypeServiceDeletedMediaType(IContentTypeService sender, Events.DeleteEventArgs<Models.IMediaType> e)
|
||||
/// <summary>
|
||||
/// Used to invalidate the cache from the ICacherefresher
|
||||
/// </summary>
|
||||
internal static void ClearPropertyTypeCache()
|
||||
{
|
||||
PropertyTypeCache.Clear();
|
||||
}
|
||||
|
||||
static void ContentTypeServiceDeletedContentType(IContentTypeService sender, Events.DeleteEventArgs<Models.IContentType> e)
|
||||
{
|
||||
PropertyTypeCache.Clear();
|
||||
}
|
||||
|
||||
static void ContentTypeServiceSavedMediaType(IContentTypeService sender, Events.SaveEventArgs<Models.IMediaType> e)
|
||||
{
|
||||
PropertyTypeCache.Clear();
|
||||
}
|
||||
|
||||
static void ContentTypeServiceSavedContentType(IContentTypeService sender, Events.SaveEventArgs<Models.IContentType> e)
|
||||
{
|
||||
PropertyTypeCache.Clear();
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// This callback is used only for unit tests which enables us to return any data we want and not rely on having the data in a database
|
||||
/// </summary>
|
||||
@@ -77,11 +54,16 @@ namespace Umbraco.Core
|
||||
{
|
||||
var result = applicationContext.Services.ContentTypeService.GetContentType(docTypeAlias);
|
||||
if (result == null) return Guid.Empty;
|
||||
if (!result.PropertyTypes.Any(x => x.Alias.InvariantEquals(propertyAlias)))
|
||||
|
||||
//SD: we need to check for 'any' here because the collection is backed by KeyValuePair which is a struct
|
||||
// and can never be null so FirstOrDefault doesn't actually work. Have told Seb and Morten about thsi
|
||||
// issue.
|
||||
if (!result.CompositionPropertyTypes.Any(x => x.Alias.InvariantEquals(propertyAlias)))
|
||||
{
|
||||
return Guid.Empty;
|
||||
}
|
||||
var property = result.PropertyTypes.FirstOrDefault(x => x.Alias.InvariantEquals(propertyAlias));
|
||||
var property = result.CompositionPropertyTypes.FirstOrDefault(x => x.Alias.InvariantEquals(propertyAlias));
|
||||
//as per above, this will never be null but we'll keep the check here anyways.
|
||||
if (property == null) return Guid.Empty;
|
||||
return property.DataTypeId;
|
||||
});
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -144,7 +144,7 @@ namespace Umbraco.Core.Services
|
||||
/// if they are required to be updated.
|
||||
/// </summary>
|
||||
/// <param name="contentTypes">A tuple of a content type and a boolean indicating if it is new (HasIdentity was false before committing)</param>
|
||||
private void UpdateContentXmlStructure(params IContentType[] contentTypes)
|
||||
private void UpdateContentXmlStructure(params IContentTypeBase[] contentTypes)
|
||||
{
|
||||
|
||||
var toUpdate = new List<IContentTypeBase>();
|
||||
@@ -152,43 +152,71 @@ namespace Umbraco.Core.Services
|
||||
foreach (var contentType in contentTypes)
|
||||
{
|
||||
//we need to determine if we need to refresh the xml content in the database. This is to be done when:
|
||||
// - the item is not new (already existed in the db)
|
||||
// - a content type changes it's alias
|
||||
// - if a content type has it's property removed
|
||||
// - the item is not new (already existed in the db) AND
|
||||
// - a content type changes it's alias OR
|
||||
// - if a content type has it's property removed OR
|
||||
// - if a content type has a property whose alias has changed
|
||||
//here we need to check if the alias of the content type changed or if one of the properties was removed.
|
||||
var dirty = contentType as IRememberBeingDirty;
|
||||
if (dirty != null
|
||||
&& !dirty.WasPropertyDirty("HasIdentity") //ensure it's now 'new'
|
||||
&& (dirty.WasPropertyDirty("Alias") || dirty.WasPropertyDirty("HasPropertyTypeBeenRemoved")))
|
||||
if (dirty == null) continue;
|
||||
|
||||
//check if any property types have changed their aliases (and not new property types)
|
||||
var hasAnyPropertiesChangedAlias = contentType.PropertyTypes.Any(propType =>
|
||||
{
|
||||
var dirtyProperty = propType as IRememberBeingDirty;
|
||||
if (dirtyProperty == null) return false;
|
||||
return dirtyProperty.WasPropertyDirty("HasIdentity") == false //ensure it's not 'new'
|
||||
&& dirtyProperty.WasPropertyDirty("Alias"); //alias has changed
|
||||
});
|
||||
|
||||
if (dirty.WasPropertyDirty("HasIdentity") == false //ensure it's not 'new'
|
||||
&& (dirty.WasPropertyDirty("Alias") || dirty.WasPropertyDirty("HasPropertyTypeBeenRemoved") || hasAnyPropertiesChangedAlias))
|
||||
{
|
||||
//if the alias was changed then we only need to update the xml structures for content of the current content type.
|
||||
//if a property was deleted then we need to update the xml structures for any content of the current content type
|
||||
// and any of the content type's child content types.
|
||||
if (dirty.WasPropertyDirty("Alias") && !dirty.WasPropertyDirty("HasPropertyTypeBeenRemoved"))
|
||||
//If the alias was changed then we only need to update the xml structures for content of the current content type.
|
||||
//If a property was deleted or a property alias was changed then we need to update the xml structures for any
|
||||
// content of the current content type and any of the content type's child content types.
|
||||
if (dirty.WasPropertyDirty("Alias")
|
||||
&& dirty.WasPropertyDirty("HasPropertyTypeBeenRemoved") == false && hasAnyPropertiesChangedAlias == false)
|
||||
{
|
||||
//if only the alias changed then only update the current content type
|
||||
toUpdate.Add(contentType);
|
||||
}
|
||||
else
|
||||
{
|
||||
//if a property was deleted (and maybe the alias changed too), then update all content of the current content type
|
||||
//if a property was deleted or alias changed, then update all content of the current content type
|
||||
// and all of it's desscendant doc types.
|
||||
toUpdate.AddRange(contentType.DescendantsAndSelf());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var typedContentService = _contentService as ContentService;
|
||||
if (typedContentService != null && toUpdate.Any())
|
||||
if (toUpdate.Any())
|
||||
{
|
||||
typedContentService.RePublishAll(toUpdate.Select(x => x.Id).ToArray());
|
||||
var firstType = toUpdate.First();
|
||||
//if it is a content type then call the rebuilding methods or content
|
||||
if (firstType is IContentType)
|
||||
{
|
||||
var typedContentService = _contentService as ContentService;
|
||||
if (typedContentService != null)
|
||||
{
|
||||
typedContentService.RePublishAll(toUpdate.Select(x => x.Id).ToArray());
|
||||
}
|
||||
else
|
||||
{
|
||||
//this should never occur, the content service should always be typed but we'll check anyways.
|
||||
_contentService.RePublishAll();
|
||||
}
|
||||
}
|
||||
else if (firstType is IMediaType)
|
||||
{
|
||||
//if it is a media type then call the rebuilding methods for media
|
||||
var typedContentService = _mediaService as MediaService;
|
||||
if (typedContentService != null)
|
||||
{
|
||||
typedContentService.RebuildXmlStructures(toUpdate.Select(x => x.Id).ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (toUpdate.Any())
|
||||
{
|
||||
//this should never occur, the content service should always be typed but we'll check anyways.
|
||||
_contentService.RePublishAll();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -246,7 +274,7 @@ namespace Umbraco.Core.Services
|
||||
uow.Commit();
|
||||
}
|
||||
|
||||
UpdateContentXmlStructure(asArray);
|
||||
UpdateContentXmlStructure(asArray.Cast<IContentTypeBase>().ToArray());
|
||||
}
|
||||
SavedContentType.RaiseEvent(new SaveEventArgs<IContentType>(asArray, false), this);
|
||||
Audit.Add(AuditTypes.Save, string.Format("Save ContentTypes performed by user"), userId, -1);
|
||||
@@ -400,17 +428,22 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
if (SavingMediaType.IsRaisedEventCancelled(new SaveEventArgs<IMediaType>(mediaType), this))
|
||||
return;
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMediaTypeRepository(uow))
|
||||
{
|
||||
mediaType.CreatorId = userId;
|
||||
repository.AddOrUpdate(mediaType);
|
||||
uow.Commit();
|
||||
|
||||
SavedMediaType.RaiseEvent(new SaveEventArgs<IMediaType>(mediaType, false), this);
|
||||
}
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMediaTypeRepository(uow))
|
||||
{
|
||||
mediaType.CreatorId = userId;
|
||||
repository.AddOrUpdate(mediaType);
|
||||
uow.Commit();
|
||||
|
||||
}
|
||||
|
||||
UpdateContentXmlStructure(mediaType);
|
||||
}
|
||||
|
||||
SavedMediaType.RaiseEvent(new SaveEventArgs<IMediaType>(mediaType, false), this);
|
||||
Audit.Add(AuditTypes.Save, string.Format("Save MediaType performed by user"), userId, mediaType.Id);
|
||||
}
|
||||
|
||||
@@ -426,22 +459,26 @@ namespace Umbraco.Core.Services
|
||||
if (SavingMediaType.IsRaisedEventCancelled(new SaveEventArgs<IMediaType>(asArray), this))
|
||||
return;
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMediaTypeRepository(uow))
|
||||
{
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMediaTypeRepository(uow))
|
||||
{
|
||||
|
||||
foreach (var mediaType in asArray)
|
||||
{
|
||||
mediaType.CreatorId = userId;
|
||||
repository.AddOrUpdate(mediaType);
|
||||
}
|
||||
foreach (var mediaType in asArray)
|
||||
{
|
||||
mediaType.CreatorId = userId;
|
||||
repository.AddOrUpdate(mediaType);
|
||||
}
|
||||
|
||||
//save it all in one go
|
||||
uow.Commit();
|
||||
//save it all in one go
|
||||
uow.Commit();
|
||||
}
|
||||
|
||||
SavedMediaType.RaiseEvent(new SaveEventArgs<IMediaType>(asArray, false), this);
|
||||
}
|
||||
UpdateContentXmlStructure(asArray.Cast<IContentTypeBase>().ToArray());
|
||||
}
|
||||
|
||||
SavedMediaType.RaiseEvent(new SaveEventArgs<IMediaType>(asArray, false), this);
|
||||
Audit.Add(AuditTypes.Save, string.Format("Save MediaTypes performed by user"), userId, -1);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ using Umbraco.Core.Persistence.UnitOfWork;
|
||||
|
||||
namespace Umbraco.Core.Services
|
||||
{
|
||||
internal class EntityService : IService
|
||||
public class EntityService : IService
|
||||
{
|
||||
private readonly IDatabaseUnitOfWorkProvider _uowProvider;
|
||||
private readonly RepositoryFactory _repositoryFactory;
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the ContentService, which is an easy access to operations involving <see cref="IMacro"/>
|
||||
/// </summary>
|
||||
internal interface IMacroService : IService
|
||||
{
|
||||
//TODO Possibly create import macro method and ToXml?
|
||||
|
||||
/// <summary>
|
||||
/// Gets an <see cref="IMacro"/> object by its alias
|
||||
/// </summary>
|
||||
/// <param name="alias">Alias to retrieve an <see cref="IMacro"/> for</param>
|
||||
/// <returns>An <see cref="IMacro"/> object</returns>
|
||||
IMacro GetByAlias(string alias);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list all available <see cref="IMacro"/> objects
|
||||
/// </summary>
|
||||
/// <param name="aliases">Optional array of aliases to limit the results</param>
|
||||
/// <returns>An enumerable list of <see cref="IMacro"/> objects</returns>
|
||||
IEnumerable<IMacro> GetAll(params string[] aliases);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes an <see cref="IMacro"/>
|
||||
/// </summary>
|
||||
/// <param name="macro"><see cref="IMacro"/> to delete</param>
|
||||
/// <param name="userId">Optional id of the user deleting the macro</param>
|
||||
void Delete(IMacro macro, int userId = 0);
|
||||
|
||||
/// <summary>
|
||||
/// Saves an <see cref="IMacro"/>
|
||||
/// </summary>
|
||||
/// <param name="macro"><see cref="IMacro"/> to save</param>
|
||||
/// <param name="userId">Optional id of the user saving the macro</param>
|
||||
void Save(IMacro macro, int userId = 0);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list all available <see cref="IMacroPropertyType"/> plugins
|
||||
/// </summary>
|
||||
/// <returns>An enumerable list of <see cref="IMacroPropertyType"/> objects</returns>
|
||||
IEnumerable<IMacroPropertyType> GetMacroPropertyTypes();
|
||||
|
||||
/// <summary>
|
||||
/// Gets an <see cref="IMacroPropertyType"/> by its alias
|
||||
/// </summary>
|
||||
/// <param name="alias">Alias to retrieve an <see cref="IMacroPropertyType"/> for</param>
|
||||
/// <returns>An <see cref="IMacroPropertyType"/> object</returns>
|
||||
IMacroPropertyType GetMacroPropertyTypeByAlias(string alias);
|
||||
}
|
||||
}
|
||||
@@ -1,168 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Auditing;
|
||||
using Umbraco.Core.Events;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
|
||||
namespace Umbraco.Core.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the Macro Service, which is an easy access to operations involving <see cref="IMacro"/>
|
||||
/// </summary>
|
||||
internal class MacroService : IMacroService
|
||||
{
|
||||
private readonly RepositoryFactory _repositoryFactory;
|
||||
private readonly IUnitOfWorkProvider _uowProvider;
|
||||
|
||||
public MacroService()
|
||||
: this(new RepositoryFactory())
|
||||
{
|
||||
}
|
||||
|
||||
public MacroService(RepositoryFactory repositoryFactory)
|
||||
: this(new FileUnitOfWorkProvider(), repositoryFactory)
|
||||
{
|
||||
}
|
||||
|
||||
public MacroService(IUnitOfWorkProvider provider)
|
||||
: this(provider, new RepositoryFactory())
|
||||
{
|
||||
}
|
||||
|
||||
public MacroService(IUnitOfWorkProvider provider, RepositoryFactory repositoryFactory) : this(provider, repositoryFactory, false)
|
||||
{
|
||||
}
|
||||
|
||||
public MacroService(IUnitOfWorkProvider provider, RepositoryFactory repositoryFactory, bool ensureCachedMacros)
|
||||
{
|
||||
_uowProvider = provider;
|
||||
_repositoryFactory = repositoryFactory;
|
||||
|
||||
if(ensureCachedMacros)
|
||||
EnsureMacroCache();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures the macro cache by getting all macros
|
||||
/// from the repository and thus caching them.
|
||||
/// </summary>
|
||||
private void EnsureMacroCache()
|
||||
{
|
||||
IEnumerable<IMacro> macros = GetAll();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an <see cref="IMacro"/> object by its alias
|
||||
/// </summary>
|
||||
/// <param name="alias">Alias to retrieve an <see cref="IMacro"/> for</param>
|
||||
/// <returns>An <see cref="IMacro"/> object</returns>
|
||||
public IMacro GetByAlias(string alias)
|
||||
{
|
||||
using (var repository = _repositoryFactory.CreateMacroRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
return repository.Get(alias);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list all available <see cref="IMacro"/> objects
|
||||
/// </summary>
|
||||
/// <param name="aliases">Optional array of aliases to limit the results</param>
|
||||
/// <returns>An enumerable list of <see cref="IMacro"/> objects</returns>
|
||||
public IEnumerable<IMacro> GetAll(params string[] aliases)
|
||||
{
|
||||
using (var repository = _repositoryFactory.CreateMacroRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
return repository.GetAll(aliases);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes an <see cref="IMacro"/>
|
||||
/// </summary>
|
||||
/// <param name="macro"><see cref="IMacro"/> to delete</param>
|
||||
/// <param name="userId">Optional id of the user deleting the macro</param>
|
||||
public void Delete(IMacro macro, int userId = 0)
|
||||
{
|
||||
if (Deleting.IsRaisedEventCancelled(new DeleteEventArgs<IMacro>(macro), this))
|
||||
return;
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMacroRepository(uow))
|
||||
{
|
||||
repository.Delete(macro);
|
||||
uow.Commit();
|
||||
|
||||
Deleted.RaiseEvent(new DeleteEventArgs<IMacro>(macro, false), this);
|
||||
}
|
||||
|
||||
Audit.Add(AuditTypes.Delete, "Delete Macro performed by user", userId, -1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves an <see cref="IMacro"/>
|
||||
/// </summary>
|
||||
/// <param name="macro"><see cref="IMacro"/> to save</param>
|
||||
/// <param name="userId">Optional Id of the user deleting the macro</param>
|
||||
public void Save(IMacro macro, int userId = 0)
|
||||
{
|
||||
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IMacro>(macro), this))
|
||||
return;
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMacroRepository(uow))
|
||||
{
|
||||
repository.AddOrUpdate(macro);
|
||||
uow.Commit();
|
||||
|
||||
Saved.RaiseEvent(new SaveEventArgs<IMacro>(macro, false), this);
|
||||
}
|
||||
|
||||
Audit.Add(AuditTypes.Save, "Save Macro performed by user", userId, -1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list all available <see cref="IMacroPropertyType"/> plugins
|
||||
/// </summary>
|
||||
/// <returns>An enumerable list of <see cref="IMacroPropertyType"/> objects</returns>
|
||||
public IEnumerable<IMacroPropertyType> GetMacroPropertyTypes()
|
||||
{
|
||||
return MacroPropertyTypeResolver.Current.MacroPropertyTypes;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an <see cref="IMacroPropertyType"/> by its alias
|
||||
/// </summary>
|
||||
/// <param name="alias">Alias to retrieve an <see cref="IMacroPropertyType"/> for</param>
|
||||
/// <returns>An <see cref="IMacroPropertyType"/> object</returns>
|
||||
public IMacroPropertyType GetMacroPropertyTypeByAlias(string alias)
|
||||
{
|
||||
return MacroPropertyTypeResolver.Current.MacroPropertyTypes.FirstOrDefault(x => x.Alias == alias);
|
||||
}
|
||||
|
||||
#region Event Handlers
|
||||
/// <summary>
|
||||
/// Occurs before Delete
|
||||
/// </summary>
|
||||
public static event TypedEventHandler<IMacroService, DeleteEventArgs<IMacro>> Deleting;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs after Delete
|
||||
/// </summary>
|
||||
public static event TypedEventHandler<IMacroService, DeleteEventArgs<IMacro>> Deleted;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs before Save
|
||||
/// </summary>
|
||||
public static event TypedEventHandler<IMacroService, SaveEventArgs<IMacro>> Saving;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs after Save
|
||||
/// </summary>
|
||||
public static event TypedEventHandler<IMacroService, SaveEventArgs<IMacro>> Saved;
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -446,7 +446,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))
|
||||
@@ -479,8 +479,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)
|
||||
{
|
||||
@@ -542,11 +542,11 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
|
||||
/// <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>
|
||||
@@ -555,6 +555,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))
|
||||
{
|
||||
@@ -691,6 +698,72 @@ namespace Umbraco.Core.Services
|
||||
Audit.Add(AuditTypes.Save, "Save Media items performed by user", userId, -1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rebuilds all xml content in the cmsContentXml table for all media
|
||||
/// </summary>
|
||||
/// <param name="contentTypeIds">
|
||||
/// Only rebuild the xml structures for the content type ids passed in, if none then rebuilds the structures
|
||||
/// for all media
|
||||
/// </param>
|
||||
/// <returns>True if publishing succeeded, otherwise False</returns>
|
||||
internal void RebuildXmlStructures(params int[] contentTypeIds)
|
||||
{
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
var list = new List<IMedia>();
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateContentRepository(uow))
|
||||
{
|
||||
if (contentTypeIds.Any() == false)
|
||||
{
|
||||
//Remove all media records from the cmsContentXml table (DO NOT REMOVE Content/Members!)
|
||||
uow.Database.Execute(@"DELETE FROM cmsContentXml WHERE nodeId IN
|
||||
(SELECT DISTINCT cmsContentXml.nodeId FROM cmsContentXml
|
||||
INNER JOIN umbracoNode ON cmsContentXml.nodeId = umbracoNode.id
|
||||
WHERE nodeObjectType = @nodeObjectType)",
|
||||
new {nodeObjectType = Constants.ObjectTypes.Media});
|
||||
|
||||
// Consider creating a Path query instead of recursive method:
|
||||
// var query = Query<IContent>.Builder.Where(x => x.Path.StartsWith("-1"));
|
||||
var rootMedia = GetRootMedia();
|
||||
foreach (var media in rootMedia)
|
||||
{
|
||||
list.Add(media);
|
||||
list.AddRange(GetDescendants(media));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var id in contentTypeIds)
|
||||
{
|
||||
//first we'll clear out the data from the cmsContentXml table for this type
|
||||
uow.Database.Execute(@"delete from cmsContentXml where nodeId in
|
||||
(SELECT DISTINCT cmsContentXml.nodeId FROM cmsContentXml
|
||||
INNER JOIN umbracoNode ON cmsContentXml.nodeId = umbracoNode.id
|
||||
INNER JOIN cmsContent ON cmsContent.nodeId = umbracoNode.id
|
||||
WHERE nodeObjectType = @nodeObjectType AND cmsContent.contentType = @contentTypeId)",
|
||||
new {contentTypeId = id, nodeObjectType = Constants.ObjectTypes.Media});
|
||||
|
||||
//now get all media objects of this type and add to the list
|
||||
list.AddRange(GetMediaOfMediaType(id));
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var c in list)
|
||||
{
|
||||
//generate the xml
|
||||
var xml = c.ToXml();
|
||||
//create the dto to insert
|
||||
var poco = new ContentXmlDto { NodeId = c.Id, Xml = xml.ToString(SaveOptions.None) };
|
||||
//insert it into the database
|
||||
uow.Database.Insert(poco);
|
||||
}
|
||||
}
|
||||
Audit.Add(AuditTypes.Publish, "RebuildXmlStructures completed, the xml has been regenerated in the database", 0, -1);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the Path and Level on a collection of <see cref="IMedia"/> objects
|
||||
/// based on the Parent's Path and Level.
|
||||
|
||||
@@ -65,7 +65,7 @@ namespace Umbraco.Core.Services
|
||||
select doc;
|
||||
|
||||
var contents = ParseDocumentRootXml(roots, parentId);
|
||||
if(contents.Any())
|
||||
if (contents.Any())
|
||||
_contentService.Save(contents, userId);
|
||||
|
||||
return contents;
|
||||
@@ -196,9 +196,21 @@ namespace Umbraco.Core.Services
|
||||
/// Imports and saves package xml as <see cref="IContentType"/>
|
||||
/// </summary>
|
||||
/// <param name="element">Xml to import</param>
|
||||
/// <param name="userId"></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)
|
||||
@@ -209,7 +221,7 @@ namespace Umbraco.Core.Services
|
||||
_importedContentTypes = new Dictionary<string, IContentType>();
|
||||
var documentTypes = name.Equals("DocumentTypes")
|
||||
? (from doc in element.Elements("DocumentType") select doc).ToList()
|
||||
: new List<XElement> {element};
|
||||
: 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)
|
||||
@@ -227,22 +239,25 @@ namespace Umbraco.Core.Services
|
||||
var list = _importedContentTypes.Select(x => x.Value).ToList();
|
||||
_contentTypeService.Save(list, userId);
|
||||
|
||||
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)
|
||||
if (importStructure)
|
||||
{
|
||||
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 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);
|
||||
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);
|
||||
}
|
||||
//Update ContentTypes with a newly added structure/list of allowed children
|
||||
if(updatedContentTypes.Any())
|
||||
_contentTypeService.Save(updatedContentTypes, userId);
|
||||
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
@@ -342,7 +357,7 @@ namespace Umbraco.Core.Services
|
||||
|
||||
private void UpdateContentTypesTabs(IContentType contentType, XElement tabElement)
|
||||
{
|
||||
if(tabElement == null)
|
||||
if (tabElement == null)
|
||||
return;
|
||||
|
||||
var tabs = tabElement.Elements("Tab");
|
||||
@@ -376,10 +391,10 @@ namespace Umbraco.Core.Services
|
||||
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)
|
||||
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));
|
||||
@@ -388,7 +403,7 @@ namespace Umbraco.Core.Services
|
||||
|
||||
var propertyType = new PropertyType(dataTypeDefinition)
|
||||
{
|
||||
Alias = property.Element("Alias").Value,
|
||||
Alias = property.Element("Alias").Value,
|
||||
Name = property.Element("Name").Value,
|
||||
Description = property.Element("Description").Value,
|
||||
Mandatory = property.Element("Mandatory").Value.ToLowerInvariant().Equals("true"),
|
||||
@@ -423,7 +438,7 @@ namespace Umbraco.Core.Services
|
||||
if (_importedContentTypes.ContainsKey(alias))
|
||||
{
|
||||
var allowedChild = _importedContentTypes[alias];
|
||||
if(allowedChild == null || allowedChildren.Any(x => x.Alias == alias)) continue;
|
||||
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++;
|
||||
@@ -484,7 +499,7 @@ namespace Umbraco.Core.Services
|
||||
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")};
|
||||
: new List<XElement> { element.Element("DataType") };
|
||||
|
||||
foreach (var dataTypeElement in dataTypeElements)
|
||||
{
|
||||
@@ -582,24 +597,26 @@ namespace Umbraco.Core.Services
|
||||
foreach (XElement tempElement in templateElements)
|
||||
{
|
||||
var dependencies = new List<string>();
|
||||
if (tempElement.Element("Master") != null &&
|
||||
string.IsNullOrEmpty(tempElement.Element("Master").Value) == false &&
|
||||
templateElements.Any(x => x.Element("Alias").Value == tempElement.Element("Master").Value))
|
||||
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(tempElement.Element("Master").Value);
|
||||
dependencies.Add(elementCopy.Element("Master").Value);
|
||||
}
|
||||
else if (tempElement.Element("Master") != null &&
|
||||
string.IsNullOrEmpty(tempElement.Element("Master").Value) == false &&
|
||||
templateElements.Any(x => x.Element("Alias").Value == tempElement.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.", tempElement.Element("Alias").Value, tempElement.Element("Master").Value));
|
||||
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 = tempElement.Element("Alias").Value,
|
||||
Item = new Lazy<XElement>(() => tempElement),
|
||||
Alias = elementCopy.Element("Alias").Value,
|
||||
Item = new Lazy<XElement>(() => elementCopy),
|
||||
DependsOn = dependencies.ToArray()
|
||||
};
|
||||
|
||||
@@ -617,18 +634,20 @@ namespace Umbraco.Core.Services
|
||||
var isMasterPage = IsMasterPageSyntax(design);
|
||||
var path = isMasterPage ? MasterpagePath(alias) : ViewPath(alias);
|
||||
|
||||
var template = new Template(path, templateName, alias) { Content = design };
|
||||
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)
|
||||
if (masterTemplate != null)
|
||||
template.MasterTemplateId = new Lazy<int>(() => masterTemplate.Id);
|
||||
}
|
||||
templates.Add(template);
|
||||
}
|
||||
|
||||
if(templates.Any())
|
||||
if (templates.Any())
|
||||
_fileService.SaveTemplate(templates, userId);
|
||||
|
||||
return templates;
|
||||
|
||||
@@ -0,0 +1,469 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Querying;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
|
||||
namespace Umbraco.Core.Services
|
||||
{
|
||||
public class RelationService
|
||||
{
|
||||
private readonly IDatabaseUnitOfWorkProvider _uowProvider;
|
||||
private readonly RepositoryFactory _repositoryFactory;
|
||||
private readonly EntityService _entityService;
|
||||
|
||||
public RelationService(IDatabaseUnitOfWorkProvider uowProvider, RepositoryFactory repositoryFactory,
|
||||
EntityService entityService)
|
||||
{
|
||||
_uowProvider = uowProvider;
|
||||
_repositoryFactory = repositoryFactory;
|
||||
_entityService = entityService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="Relation"/> by its Id
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the <see cref="Relation"/></param>
|
||||
/// <returns>A <see cref="Relation"/> object</returns>
|
||||
public Relation GetById(int id)
|
||||
{
|
||||
using (var repository = _repositoryFactory.CreateRelationRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
return repository.Get(id);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="RelationType"/> by its Id
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the <see cref="RelationType"/></param>
|
||||
/// <returns>A <see cref="RelationType"/> object</returns>
|
||||
public RelationType GetRelationTypeById(int id)
|
||||
{
|
||||
using (var repository = _repositoryFactory.CreateRelationTypeRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
return repository.Get(id);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="RelationType"/> by its Alias
|
||||
/// </summary>
|
||||
/// <param name="alias">Alias of the <see cref="RelationType"/></param>
|
||||
/// <returns>A <see cref="RelationType"/> object</returns>
|
||||
public RelationType GetRelationTypeByAlias(string alias)
|
||||
{
|
||||
using (var repository = _repositoryFactory.CreateRelationTypeRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
var query = new Query<RelationType>().Where(x => x.Alias == alias);
|
||||
return repository.GetByQuery(query).FirstOrDefault();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all <see cref="Relation"/> objects
|
||||
/// </summary>
|
||||
/// <param name="ids">Optional array of integer ids to return relations for</param>
|
||||
/// <returns>An enumerable list of <see cref="Relation"/> objects</returns>
|
||||
public IEnumerable<Relation> GetAllRelations(params int[] ids)
|
||||
{
|
||||
using (var repository = _repositoryFactory.CreateRelationRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
return repository.GetAll(ids);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all <see cref="Relation"/> objects by their <see cref="RelationType"/>
|
||||
/// </summary>
|
||||
/// <param name="relationType"><see cref="RelationType"/> to retrieve Relations for</param>
|
||||
/// <returns>An enumerable list of <see cref="Relation"/> objects</returns>
|
||||
public IEnumerable<Relation> GetAllRelationsByRelationType(RelationType relationType)
|
||||
{
|
||||
return GetAllRelationsByRelationType(relationType.Id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all <see cref="Relation"/> objects by their <see cref="RelationType"/>'s Id
|
||||
/// </summary>
|
||||
/// <param name="relationTypeId">Id of the <see cref="RelationType"/> to retrieve Relations for</param>
|
||||
/// <returns>An enumerable list of <see cref="Relation"/> objects</returns>
|
||||
public IEnumerable<Relation> GetAllRelationsByRelationType(int relationTypeId)
|
||||
{
|
||||
using (var repository = _repositoryFactory.CreateRelationRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
var query = new Query<Relation>().Where(x => x.RelationTypeId == relationTypeId);
|
||||
return repository.GetByQuery(query);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all <see cref="Relation"/> objects
|
||||
/// </summary>
|
||||
/// <param name="ids">Optional array of integer ids to return relationtypes for</param>
|
||||
/// <returns>An enumerable list of <see cref="RelationType"/> objects</returns>
|
||||
public IEnumerable<RelationType> GetAllRelationTypes(params int[] ids)
|
||||
{
|
||||
using (var repository = _repositoryFactory.CreateRelationTypeRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
return repository.GetAll(ids);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of <see cref="Relation"/> objects by their parent Id
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the parent to retrieve relations for</param>
|
||||
/// <returns>An enumerable list of <see cref="Relation"/> objects</returns>
|
||||
public IEnumerable<Relation> GetByParentId(int id)
|
||||
{
|
||||
using (var repository = _repositoryFactory.CreateRelationRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
var query = new Query<Relation>().Where(x => x.ParentId == id);
|
||||
return repository.GetByQuery(query);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of <see cref="Relation"/> objects by their child Id
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the child to retrieve relations for</param>
|
||||
/// <returns>An enumerable list of <see cref="Relation"/> objects</returns>
|
||||
public IEnumerable<Relation> GetByChildId(int id)
|
||||
{
|
||||
using (var repository = _repositoryFactory.CreateRelationRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
var query = new Query<Relation>().Where(x => x.ChildId == id);
|
||||
return repository.GetByQuery(query);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of <see cref="Relation"/> objects by the Name of the <see cref="RelationType"/>
|
||||
/// </summary>
|
||||
/// <param name="relationTypeName">Name of the <see cref="RelationType"/> to retrieve Relations for</param>
|
||||
/// <returns>An enumerable list of <see cref="Relation"/> objects</returns>
|
||||
public IEnumerable<Relation> GetByRelationTypeName(string relationTypeName)
|
||||
{
|
||||
List<int> relationTypeIds = null;
|
||||
using (var repository = _repositoryFactory.CreateRelationTypeRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
var query = new Query<RelationType>().Where(x => x.Name == relationTypeName);
|
||||
var relationTypes = repository.GetByQuery(query);
|
||||
if (relationTypes.Any())
|
||||
{
|
||||
relationTypeIds = relationTypes.Select(x => x.Id).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
if (relationTypeIds == null)
|
||||
return Enumerable.Empty<Relation>();
|
||||
|
||||
return GetRelationsByListOfTypeIds(relationTypeIds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of <see cref="Relation"/> objects by the Alias of the <see cref="RelationType"/>
|
||||
/// </summary>
|
||||
/// <param name="relationTypeAlias">Alias of the <see cref="RelationType"/> to retrieve Relations for</param>
|
||||
/// <returns>An enumerable list of <see cref="Relation"/> objects</returns>
|
||||
public IEnumerable<Relation> GetByRelationTypeAlias(string relationTypeAlias)
|
||||
{
|
||||
List<int> relationTypeIds = null;
|
||||
using (var repository = _repositoryFactory.CreateRelationTypeRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
var query = new Query<RelationType>().Where(x => x.Alias == relationTypeAlias);
|
||||
var relationTypes = repository.GetByQuery(query);
|
||||
if (relationTypes.Any())
|
||||
{
|
||||
relationTypeIds = relationTypes.Select(x => x.Id).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
if (relationTypeIds == null)
|
||||
return Enumerable.Empty<Relation>();
|
||||
|
||||
return GetRelationsByListOfTypeIds(relationTypeIds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of <see cref="Relation"/> objects by the Id of the <see cref="RelationType"/>
|
||||
/// </summary>
|
||||
/// <param name="relationTypeId">Id of the <see cref="RelationType"/> to retrieve Relations for</param>
|
||||
/// <returns>An enumerable list of <see cref="Relation"/> objects</returns>
|
||||
public IEnumerable<Relation> GetByRelationTypeId(int relationTypeId)
|
||||
{
|
||||
using (var repository = _repositoryFactory.CreateRelationRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
var query = new Query<Relation>().Where(x => x.RelationTypeId == relationTypeId);
|
||||
return repository.GetByQuery(query);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Child object from a Relation as an <see cref="IUmbracoEntity"/>
|
||||
/// </summary>
|
||||
/// <param name="relation">Relation to retrieve child object from</param>
|
||||
/// <param name="loadBaseType">Optional bool to load the complete object graph when set to <c>False</c></param>
|
||||
/// <returns>An <see cref="IUmbracoEntity"/></returns>
|
||||
public IUmbracoEntity GetChildEntityFromRelation(Relation relation, bool loadBaseType = false)
|
||||
{
|
||||
var objectType = UmbracoObjectTypesExtensions.GetUmbracoObjectType(relation.RelationType.ChildObjectType);
|
||||
return _entityService.Get(relation.ChildId, objectType, loadBaseType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Parent object from a Relation as an <see cref="IUmbracoEntity"/>
|
||||
/// </summary>
|
||||
/// <param name="relation">Relation to retrieve parent object from</param>
|
||||
/// <param name="loadBaseType">Optional bool to load the complete object graph when set to <c>False</c></param>
|
||||
/// <returns>An <see cref="IUmbracoEntity"/></returns>
|
||||
public IUmbracoEntity GetParentEntityFromRelation(Relation relation, bool loadBaseType = false)
|
||||
{
|
||||
var objectType = UmbracoObjectTypesExtensions.GetUmbracoObjectType(relation.RelationType.ParentObjectType);
|
||||
return _entityService.Get(relation.ParentId, objectType, loadBaseType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Parent and Child objects from a Relation as a <see cref="Tuple"/>"/> with <see cref="IUmbracoEntity"/>.
|
||||
/// </summary>
|
||||
/// <param name="relation">Relation to retrieve parent and child object from</param>
|
||||
/// <param name="loadBaseType">Optional bool to load the complete object graph when set to <c>False</c></param>
|
||||
/// <returns>Returns a Tuple with Parent (item1) and Child (item2)</returns>
|
||||
public Tuple<IUmbracoEntity, IUmbracoEntity> GetEntitiesFromRelation(Relation relation, bool loadBaseType = false)
|
||||
{
|
||||
var childObjectType = UmbracoObjectTypesExtensions.GetUmbracoObjectType(relation.RelationType.ChildObjectType);
|
||||
var parentObjectType = UmbracoObjectTypesExtensions.GetUmbracoObjectType(relation.RelationType.ParentObjectType);
|
||||
|
||||
var child = _entityService.Get(relation.ChildId, childObjectType, loadBaseType);
|
||||
var parent = _entityService.Get(relation.ParentId, parentObjectType, loadBaseType);
|
||||
|
||||
return new Tuple<IUmbracoEntity, IUmbracoEntity>(parent, child);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Child objects from a list of Relations as a list of <see cref="IUmbracoEntity"/> objects.
|
||||
/// </summary>
|
||||
/// <param name="relations">List of relations to retrieve child objects from</param>
|
||||
/// <param name="loadBaseType">Optional bool to load the complete object graph when set to <c>False</c></param>
|
||||
/// <returns>An enumerable list of <see cref="IUmbracoEntity"/></returns>
|
||||
public IEnumerable<IUmbracoEntity> GetChildEntitiesFromRelations(IEnumerable<Relation> relations, bool loadBaseType = false)
|
||||
{
|
||||
foreach (var relation in relations)
|
||||
{
|
||||
var objectType = UmbracoObjectTypesExtensions.GetUmbracoObjectType(relation.RelationType.ChildObjectType);
|
||||
yield return _entityService.Get(relation.ChildId, objectType, loadBaseType);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Parent objects from a list of Relations as a list of <see cref="IUmbracoEntity"/> objects.
|
||||
/// </summary>
|
||||
/// <param name="relations">List of relations to retrieve parent objects from</param>
|
||||
/// <param name="loadBaseType">Optional bool to load the complete object graph when set to <c>False</c></param>
|
||||
/// <returns>An enumerable list of <see cref="IUmbracoEntity"/></returns>
|
||||
public IEnumerable<IUmbracoEntity> GetParentEntitiesFromRelations(IEnumerable<Relation> relations,
|
||||
bool loadBaseType = false)
|
||||
{
|
||||
foreach (var relation in relations)
|
||||
{
|
||||
var objectType = UmbracoObjectTypesExtensions.GetUmbracoObjectType(relation.RelationType.ParentObjectType);
|
||||
yield return _entityService.Get(relation.ParentId, objectType, loadBaseType);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Parent and Child objects from a list of Relations as a list of <see cref="IUmbracoEntity"/> objects.
|
||||
/// </summary>
|
||||
/// <param name="relations">List of relations to retrieve parent and child objects from</param>
|
||||
/// <param name="loadBaseType">Optional bool to load the complete object graph when set to <c>False</c></param>
|
||||
/// <returns>An enumerable list of <see cref="Tuple"/> with <see cref="IUmbracoEntity"/></returns>
|
||||
public IEnumerable<Tuple<IUmbracoEntity, IUmbracoEntity>> GetEntitiesFromRelations(
|
||||
IEnumerable<Relation> relations,
|
||||
bool loadBaseType = false)
|
||||
{
|
||||
foreach (var relation in relations)
|
||||
{
|
||||
var childObjectType = UmbracoObjectTypesExtensions.GetUmbracoObjectType(relation.RelationType.ChildObjectType);
|
||||
var parentObjectType = UmbracoObjectTypesExtensions.GetUmbracoObjectType(relation.RelationType.ParentObjectType);
|
||||
|
||||
var child = _entityService.Get(relation.ChildId, childObjectType, loadBaseType);
|
||||
var parent = _entityService.Get(relation.ParentId, parentObjectType, loadBaseType);
|
||||
|
||||
yield return new Tuple<IUmbracoEntity, IUmbracoEntity>(parent, child);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Relates two objects that are based on the <see cref="IUmbracoEntity"/> interface.
|
||||
/// </summary>
|
||||
/// <param name="parent">Parent entity</param>
|
||||
/// <param name="child">Child entity</param>
|
||||
/// <param name="relationType">The type of relation to create</param>
|
||||
/// <returns>The created <see cref="Relation"/></returns>
|
||||
public Relation Relate(IUmbracoEntity parent, IUmbracoEntity child, RelationType relationType)
|
||||
{
|
||||
//Ensure that the RelationType has an indentity before using it to relate two entities
|
||||
if(relationType.HasIdentity == false)
|
||||
Save(relationType);
|
||||
|
||||
var relation = new Relation(parent.Id, child.Id, relationType);
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateRelationRepository(uow))
|
||||
{
|
||||
repository.AddOrUpdate(relation);
|
||||
uow.Commit();
|
||||
|
||||
return relation;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Relates two objects that are based on the <see cref="IUmbracoEntity"/> interface.
|
||||
/// </summary>
|
||||
/// <param name="parent">Parent entity</param>
|
||||
/// <param name="child">Child entity</param>
|
||||
/// <param name="relationTypeAlias">Alias of the type of relation to create</param>
|
||||
/// <returns>The created <see cref="Relation"/></returns>
|
||||
public Relation Relate(IUmbracoEntity parent, IUmbracoEntity child, string relationTypeAlias)
|
||||
{
|
||||
var relationType = GetRelationTypeByAlias(relationTypeAlias);
|
||||
if(relationType == null || string.IsNullOrEmpty(relationType.Alias))
|
||||
throw new ArgumentNullException(string.Format("No RelationType with Alias '{0}' exists.", relationTypeAlias));
|
||||
|
||||
var relation = new Relation(parent.Id, child.Id, relationType);
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateRelationRepository(uow))
|
||||
{
|
||||
repository.AddOrUpdate(relation);
|
||||
uow.Commit();
|
||||
|
||||
return relation;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether any relations exists for the passed in <see cref="RelationType"/>.
|
||||
/// </summary>
|
||||
/// <param name="relationType"><see cref="RelationType"/> to check for relations</param>
|
||||
/// <returns>Returns <c>True</c> if any relations exists for the given <see cref="RelationType"/>, otherwise <c>False</c></returns>
|
||||
public bool HasRelations(RelationType relationType)
|
||||
{
|
||||
using (var repository = _repositoryFactory.CreateRelationRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
var query = new Query<Relation>().Where(x => x.RelationTypeId == relationType.Id);
|
||||
return repository.GetByQuery(query).Any();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether any relations exists for the passed in Id.
|
||||
/// </summary>
|
||||
/// <param name="id">Id of an object to check relations for</param>
|
||||
/// <returns>Returns <c>True</c> if any relations exists with the given Id, otherwise <c>False</c></returns>
|
||||
public bool IsRelated(int id)
|
||||
{
|
||||
using (var repository = _repositoryFactory.CreateRelationRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
var query = new Query<Relation>().Where(x => x.ParentId == id || x.ChildId == id);
|
||||
return repository.GetByQuery(query).Any();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves a <see cref="Relation"/>
|
||||
/// </summary>
|
||||
/// <param name="relation">Relation to save</param>
|
||||
public void Save(Relation relation)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateRelationRepository(uow))
|
||||
{
|
||||
repository.AddOrUpdate(relation);
|
||||
uow.Commit();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves a <see cref="RelationType"/>
|
||||
/// </summary>
|
||||
/// <param name="relationType">RelationType to Save</param>
|
||||
public void Save(RelationType relationType)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateRelationTypeRepository(uow))
|
||||
{
|
||||
repository.AddOrUpdate(relationType);
|
||||
uow.Commit();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a <see cref="Relation"/>
|
||||
/// </summary>
|
||||
/// <param name="relation">Relation to Delete</param>
|
||||
public void Delete(Relation relation)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateRelationRepository(uow))
|
||||
{
|
||||
repository.Delete(relation);
|
||||
uow.Commit();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a <see cref="RelationType"/>
|
||||
/// </summary>
|
||||
/// <param name="relationType">RelationType to Delete</param>
|
||||
public void Delete(RelationType relationType)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateRelationTypeRepository(uow))
|
||||
{
|
||||
repository.Delete(relationType);
|
||||
uow.Commit();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes all <see cref="Relation"/> objects based on the passed in <see cref="RelationType"/>
|
||||
/// </summary>
|
||||
/// <param name="relationType"><see cref="RelationType"/> to Delete Relations for</param>
|
||||
public void DeleteRelationsOfType(RelationType relationType)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateRelationRepository(uow))
|
||||
{
|
||||
var query = new Query<Relation>().Where(x => x.RelationTypeId == relationType.Id);
|
||||
var list = repository.GetByQuery(query).ToList();
|
||||
|
||||
foreach (var relation in list)
|
||||
{
|
||||
repository.Delete(relation);
|
||||
}
|
||||
uow.Commit();
|
||||
}
|
||||
}
|
||||
|
||||
#region Private Methods
|
||||
private IEnumerable<Relation> GetRelationsByListOfTypeIds(IEnumerable<int> relationTypeIds)
|
||||
{
|
||||
var relations = new List<Relation>();
|
||||
using (var repository = _repositoryFactory.CreateRelationRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
foreach (var relationTypeId in relationTypeIds)
|
||||
{
|
||||
int id = relationTypeId;
|
||||
var query = new Query<Relation>().Where(x => x.RelationTypeId == id);
|
||||
relations.AddRange(repository.GetByQuery(query).ToList());
|
||||
}
|
||||
}
|
||||
return relations;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,6 @@ namespace Umbraco.Core.Services
|
||||
private Lazy<ContentService> _contentService;
|
||||
private Lazy<UserService> _userService;
|
||||
private Lazy<MediaService> _mediaService;
|
||||
private Lazy<MacroService> _macroService;
|
||||
private Lazy<ContentTypeService> _contentTypeService;
|
||||
private Lazy<DataTypeService> _dataTypeService;
|
||||
private Lazy<FileService> _fileService;
|
||||
@@ -23,6 +22,7 @@ namespace Umbraco.Core.Services
|
||||
private Lazy<PackagingService> _packagingService;
|
||||
private Lazy<ServerRegistrationService> _serverRegistrationService;
|
||||
private Lazy<EntityService> _entityService;
|
||||
private Lazy<RelationService> _relationService;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
@@ -62,9 +62,6 @@ namespace Umbraco.Core.Services
|
||||
if(_mediaService == null)
|
||||
_mediaService = new Lazy<MediaService>(() => new MediaService(provider, repositoryFactory.Value));
|
||||
|
||||
if(_macroService == null)
|
||||
_macroService = new Lazy<MacroService>(() => new MacroService(fileProvider, repositoryFactory.Value));
|
||||
|
||||
if(_contentTypeService == null)
|
||||
_contentTypeService = new Lazy<ContentTypeService>(() => new ContentTypeService(provider, repositoryFactory.Value, _contentService.Value, _mediaService.Value));
|
||||
|
||||
@@ -82,6 +79,9 @@ namespace Umbraco.Core.Services
|
||||
|
||||
if (_entityService == null)
|
||||
_entityService = new Lazy<EntityService>(() => new EntityService(provider, repositoryFactory.Value, _contentService.Value, _contentTypeService.Value, _mediaService.Value, _dataTypeService.Value));
|
||||
|
||||
if(_relationService == null)
|
||||
_relationService = new Lazy<RelationService>(() => new RelationService(provider, repositoryFactory.Value, _entityService.Value));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -95,11 +95,19 @@ namespace Umbraco.Core.Services
|
||||
/// <summary>
|
||||
/// Gets the <see cref="EntityService"/>
|
||||
/// </summary>
|
||||
internal EntityService EntityService
|
||||
public EntityService EntityService
|
||||
{
|
||||
get { return _entityService.Value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="RelationService"/>
|
||||
/// </summary>
|
||||
public RelationService RelationService
|
||||
{
|
||||
get { return _relationService.Value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="IContentService"/>
|
||||
/// </summary>
|
||||
@@ -156,14 +164,6 @@ namespace Umbraco.Core.Services
|
||||
get { return _packagingService.Value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="IMacroService"/>
|
||||
/// </summary>
|
||||
internal IMacroService MacroService
|
||||
{
|
||||
get { return _macroService.Value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="IMacroService"/>
|
||||
/// </summary>
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
[UmbracoWillObsolete("This enumeration should be removed. Use Umbraco.Core.Strings.CleanStringType instead.")]
|
||||
public enum StringAliasCaseType
|
||||
{
|
||||
PascalCase,
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace Umbraco.Core.Strings
|
||||
/// <summary>
|
||||
/// Flag mask for casing.
|
||||
/// </summary>
|
||||
CaseMask = 0x1f, // 0xff - 8 possible values
|
||||
CaseMask = 0x3f, // 0xff - 8 possible values
|
||||
|
||||
/// <summary>
|
||||
/// Flag mask for encoding.
|
||||
@@ -59,6 +59,13 @@ namespace Umbraco.Core.Strings
|
||||
/// </summary>
|
||||
UpperCase = 0x10,
|
||||
|
||||
/// <summary>
|
||||
/// Umbraco "safe alias" case.
|
||||
/// </summary>
|
||||
/// <remarks>This is for backward compatibility. Casing is unchanged within terms,
|
||||
/// and is pascal otherwise.</remarks>
|
||||
UmbracoCase = 0x20,
|
||||
|
||||
/// <summary>
|
||||
/// Unicode encoding.
|
||||
/// </summary>
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Umbraco.Core.Strings
|
||||
/// <para>Full-unicode support is probably not so good.</para>
|
||||
/// <para>NOTE: pre-filters run _before_ the string is re-encoded.</para>
|
||||
/// </remarks>
|
||||
internal class DefaultShortStringHelper : IShortStringHelper
|
||||
public class DefaultShortStringHelper : IShortStringHelper
|
||||
{
|
||||
#region Ctor and vars
|
||||
|
||||
@@ -119,7 +119,7 @@ namespace Umbraco.Core.Strings
|
||||
bool breakTermsOnUpper = true, bool allowLeadingDigits = false, bool allowUnderscoreInTerm = false)
|
||||
{
|
||||
EnsureNotFrozen();
|
||||
if (!_configs.ContainsKey(culture))
|
||||
if (_configs.ContainsKey(culture) == false)
|
||||
_configs[culture] = new Dictionary<CleanStringType, HelperConfig>();
|
||||
_configs[culture][stringRole] = new HelperConfig(preFilter, breakTermsOnUpper, allowLeadingDigits, allowUnderscoreInTerm);
|
||||
return this;
|
||||
@@ -144,10 +144,23 @@ namespace Umbraco.Core.Strings
|
||||
}
|
||||
|
||||
public Func<string, string> PreFilter { get; private set; }
|
||||
|
||||
// indicate whether an uppercase within a term eg "fooBar" is to break
|
||||
// into a new term, or to be considered as part of the current term
|
||||
public bool BreakTermsOnUpper { get; private set; }
|
||||
|
||||
// indicates whether it is legal to have leading digits, or whether they
|
||||
// should be stripped as any other illegal character
|
||||
public bool AllowLeadingDigits { get; private set; }
|
||||
|
||||
// indicates whether underscore is a valid character in a term or is
|
||||
// to be considered as a separator
|
||||
public bool AllowUnderscoreInTerm { get; private set; }
|
||||
|
||||
// indicates whether acronyms parsing is greedy ie whether "FOObar" is
|
||||
// "FOO" + "bar" (greedy) or "FO" + "Obar" (non-greedy)
|
||||
public bool GreedyAcronyms { get { return false; } }
|
||||
|
||||
public static readonly HelperConfig Empty = new HelperConfig();
|
||||
}
|
||||
|
||||
@@ -237,9 +250,9 @@ function validateSafeAlias(id, value, immediate, callback) {{
|
||||
/// <para>The string will be cleaned in the context of the default culture.</para>
|
||||
/// <para>Safe aliases are Ascii only.</para>
|
||||
/// </remarks>
|
||||
public string CleanStringForSafeAlias(string text)
|
||||
public virtual string CleanStringForSafeAlias(string text)
|
||||
{
|
||||
return CleanString(text, CleanStringType.Ascii | CleanStringType.CamelCase | CleanStringType.Alias);
|
||||
return CleanString(text, CleanStringType.Ascii | CleanStringType.UmbracoCase | CleanStringType.Alias);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -251,9 +264,9 @@ function validateSafeAlias(id, value, immediate, callback) {{
|
||||
/// <remarks>
|
||||
/// <para>Safe aliases are Ascii only.</para>
|
||||
/// </remarks>
|
||||
public string CleanStringForSafeAlias(string text, CultureInfo culture)
|
||||
public virtual string CleanStringForSafeAlias(string text, CultureInfo culture)
|
||||
{
|
||||
return CleanString(text, CleanStringType.Ascii | CleanStringType.CamelCase | CleanStringType.Alias, culture);
|
||||
return CleanString(text, CleanStringType.Ascii | CleanStringType.UmbracoCase | CleanStringType.Alias, culture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -265,7 +278,7 @@ function validateSafeAlias(id, value, immediate, callback) {{
|
||||
/// <para>The string will be cleaned in the context of the default culture.</para>
|
||||
/// <para>Url segments are Ascii only (no accents...).</para>
|
||||
/// </remarks>
|
||||
public string CleanStringForUrlSegment(string text)
|
||||
public virtual string CleanStringForUrlSegment(string text)
|
||||
{
|
||||
return CleanString(text, CleanStringType.Ascii | CleanStringType.LowerCase | CleanStringType.Url, '-');
|
||||
}
|
||||
@@ -279,7 +292,7 @@ function validateSafeAlias(id, value, immediate, callback) {{
|
||||
/// <remarks>
|
||||
/// <para>Url segments are Ascii only (no accents...).</para>
|
||||
/// </remarks>
|
||||
public string CleanStringForUrlSegment(string text, CultureInfo culture)
|
||||
public virtual string CleanStringForUrlSegment(string text, CultureInfo culture)
|
||||
{
|
||||
return CleanString(text, CleanStringType.Ascii | CleanStringType.LowerCase | CleanStringType.Url, '-', culture);
|
||||
}
|
||||
@@ -402,7 +415,7 @@ function validateSafeAlias(id, value, immediate, callback) {{
|
||||
/// <param name="separator">The separator.</param>
|
||||
/// <param name="culture">The culture.</param>
|
||||
/// <returns>The clean string.</returns>
|
||||
public string CleanString(string text, CleanStringType stringType, char separator, CultureInfo culture)
|
||||
public virtual string CleanString(string text, CleanStringType stringType, char separator, CultureInfo culture)
|
||||
{
|
||||
var config = GetConfig(stringType & CleanStringType.RoleMask, culture);
|
||||
return CleanString(text, stringType, separator, culture, config);
|
||||
@@ -678,10 +691,9 @@ function validateSafeAlias(id, value, immediate, callback) {{
|
||||
// then we cannot break words on uppercase chars
|
||||
var input = text;
|
||||
|
||||
// because we shouldn't be adding any extra char
|
||||
// it's faster to use an array than a StringBuilder
|
||||
var ilen = input.Length;
|
||||
var output = new char[ilen];
|
||||
var output = new char[ilen * 2]; // twice the length should be OK in all cases
|
||||
|
||||
//var termFilter = config.TermFilter;
|
||||
|
||||
@@ -697,7 +709,7 @@ function validateSafeAlias(id, value, immediate, callback) {{
|
||||
switch (state)
|
||||
{
|
||||
case StateBreak:
|
||||
if (isTerm && (opos > 0 || (!isUnder && (config.AllowLeadingDigits || !isDigit))))
|
||||
if (isTerm && (opos > 0 || (isUnder == false && (config.AllowLeadingDigits || isDigit == false))))
|
||||
{
|
||||
ipos = i;
|
||||
if (opos > 0 && separator != char.MinValue)
|
||||
@@ -707,7 +719,7 @@ function validateSafeAlias(id, value, immediate, callback) {{
|
||||
break;
|
||||
|
||||
case StateWord:
|
||||
if (!isTerm || (config.BreakTermsOnUpper && isUpper))
|
||||
if (isTerm == false || (config.BreakTermsOnUpper && isUpper))
|
||||
{
|
||||
CopyUtf8Term(input, ipos, output, ref opos, i - ipos, caseType, culture, /*termFilter,*/ false);
|
||||
ipos = i;
|
||||
@@ -718,8 +730,10 @@ function validateSafeAlias(id, value, immediate, callback) {{
|
||||
break;
|
||||
|
||||
case StateAcronym:
|
||||
if (!isTerm || isLower || isDigit)
|
||||
if (isTerm == false || isLower || isDigit)
|
||||
{
|
||||
if (isLower && config.GreedyAcronyms == false)
|
||||
i -= 1;
|
||||
CopyUtf8Term(input, ipos, output, ref opos, i - ipos, caseType, culture, /*termFilter,*/ true);
|
||||
ipos = i;
|
||||
state = isTerm ? StateWord : StateBreak;
|
||||
@@ -780,9 +794,9 @@ function validateSafeAlias(id, value, immediate, callback) {{
|
||||
|
||||
if (isAcronym)
|
||||
{
|
||||
if (caseType == CleanStringType.CamelCase && len <= 2 && opos > 0)
|
||||
caseType = CleanStringType.Unchanged;
|
||||
else if (caseType == CleanStringType.PascalCase && len <= 2)
|
||||
if ((caseType == CleanStringType.CamelCase && len <= 2 && opos > 0) ||
|
||||
(caseType == CleanStringType.PascalCase && len <= 2) ||
|
||||
(caseType == CleanStringType.UmbracoCase))
|
||||
caseType = CleanStringType.Unchanged;
|
||||
}
|
||||
|
||||
@@ -822,6 +836,14 @@ function validateSafeAlias(id, value, immediate, callback) {{
|
||||
opos += len - 1;
|
||||
break;
|
||||
|
||||
case CleanStringType.UmbracoCase:
|
||||
c = term[ipos++];
|
||||
output[opos] = opos++ == 0 ? c : char.ToUpper(c, culture);
|
||||
if (len > 1)
|
||||
term.CopyTo(ipos, output, opos, len - 1);
|
||||
opos += len - 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException("caseType");
|
||||
}
|
||||
@@ -838,7 +860,7 @@ function validateSafeAlias(id, value, immediate, callback) {{
|
||||
/// <param name="separator">The separator, which defaults to a whitespace.</param>
|
||||
/// <returns>The splitted text.</returns>
|
||||
/// <remarks>Supports Utf8 and Ascii strings, not Unicode strings.</remarks>
|
||||
public string SplitPascalCasing(string text, char separator)
|
||||
public virtual string SplitPascalCasing(string text, char separator)
|
||||
{
|
||||
// be safe
|
||||
if (text == null)
|
||||
@@ -892,7 +914,7 @@ function validateSafeAlias(id, value, immediate, callback) {{
|
||||
/// <returns>The filtered string.</returns>
|
||||
/// <remarks>If <paramref name="stringType"/> is not <c>Unicode</c> then non-utf8 characters are
|
||||
/// removed. If it is <c>Ascii</c> we try to do some intelligent replacement of accents, etc.</remarks>
|
||||
public string Recode(string text, CleanStringType stringType)
|
||||
public virtual string Recode(string text, CleanStringType stringType)
|
||||
{
|
||||
// be safe
|
||||
if (text == null)
|
||||
@@ -939,7 +961,7 @@ function validateSafeAlias(id, value, immediate, callback) {{
|
||||
/// <param name="text">The string to filter.</param>
|
||||
/// <param name="replacements">The replacements definition.</param>
|
||||
/// <returns>The filtered string.</returns>
|
||||
public string ReplaceMany(string text, IDictionary<string, string> replacements)
|
||||
public virtual string ReplaceMany(string text, IDictionary<string, string> replacements)
|
||||
{
|
||||
// be safe
|
||||
if (text == null)
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace Umbraco.Core.Strings
|
||||
/// <summary>
|
||||
/// Default implementation of IUrlSegmentProvider.
|
||||
/// </summary>
|
||||
internal class DefaultUrlSegmentProvider : IUrlSegmentProvider
|
||||
public class DefaultUrlSegmentProvider : IUrlSegmentProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the default url segment for a specified content.
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace Umbraco.Core.Strings
|
||||
/// Provides string functions for short strings such as aliases or url segments.
|
||||
/// </summary>
|
||||
/// <remarks>Not necessarily optimized to work on large bodies of text.</remarks>
|
||||
internal interface IShortStringHelper
|
||||
public interface IShortStringHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Freezes the helper so it can prevents its configuration from being modified.
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace Umbraco.Core.Strings
|
||||
/// Provides url segments for content.
|
||||
/// </summary>
|
||||
/// <remarks>Url segments should comply with IETF RFCs regarding content, encoding, etc.</remarks>
|
||||
internal interface IUrlSegmentProvider
|
||||
public interface IUrlSegmentProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the default url segment for a specified content.
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace Umbraco.Core.Strings
|
||||
/// <summary>
|
||||
/// Resolves the IShortStringHelper object
|
||||
/// </summary>
|
||||
internal sealed class ShortStringHelperResolver : SingleObjectResolverBase<ShortStringHelperResolver, IShortStringHelper>
|
||||
public sealed class ShortStringHelperResolver : SingleObjectResolverBase<ShortStringHelperResolver, IShortStringHelper>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ShortStringHelperResolver"/> class with an instance of a helper.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/// <summary>
|
||||
/// Provides extension methods to StringAliasCaseType to facilitate migration to CleanStringType.
|
||||
/// </summary>
|
||||
internal static class StringAliasCaseTypeExtensions
|
||||
public static class StringAliasCaseTypeExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the CleanStringType value corresponding to the StringAliasCaseType value.
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace Umbraco.Core.Strings
|
||||
/// <summary>
|
||||
/// Resolves IUrlSegmentProvider objects.
|
||||
/// </summary>
|
||||
internal sealed class UrlSegmentProviderResolver : ManyObjectsResolverBase<UrlSegmentProviderResolver, IUrlSegmentProvider>
|
||||
public sealed class UrlSegmentProviderResolver : ManyObjectsResolverBase<UrlSegmentProviderResolver, IUrlSegmentProvider>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UrlSegmentProviderResolver"/> class with an initial list of provider types.
|
||||
|
||||
@@ -24,6 +24,11 @@ namespace Umbraco.Core.Sync
|
||||
}
|
||||
|
||||
public string ServerAddress { get; private set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return ServerAddress;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -19,11 +19,12 @@ namespace Umbraco.Core.Sync
|
||||
{
|
||||
private readonly Func<Tuple<string, string>> _getUserNamePasswordDelegate;
|
||||
private volatile bool _hasResolvedDelegate = false;
|
||||
private readonly object _locker = new object();
|
||||
private string _login;
|
||||
private string _password;
|
||||
private readonly object _locker = new object();
|
||||
private bool _useDistributedCalls;
|
||||
|
||||
protected string Login { get; private set; }
|
||||
protected string Password{ get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Without a username/password all distribuion will be disabled
|
||||
/// </summary>
|
||||
@@ -38,13 +39,24 @@ namespace Umbraco.Core.Sync
|
||||
/// <param name="login"></param>
|
||||
/// <param name="password"></param>
|
||||
internal DefaultServerMessenger(string login, string password)
|
||||
: this(login, password, UmbracoSettings.UseDistributedCalls)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the username/password and whether or not to use distributed calls
|
||||
/// </summary>
|
||||
/// <param name="login"></param>
|
||||
/// <param name="password"></param>
|
||||
/// <param name="useDistributedCalls"></param>
|
||||
internal DefaultServerMessenger(string login, string password, bool useDistributedCalls)
|
||||
{
|
||||
if (login == null) throw new ArgumentNullException("login");
|
||||
if (password == null) throw new ArgumentNullException("password");
|
||||
|
||||
_useDistributedCalls = UmbracoSettings.UseDistributedCalls;
|
||||
_login = login;
|
||||
_password = password;
|
||||
_useDistributedCalls = useDistributedCalls;
|
||||
Login = login;
|
||||
Password = password;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -137,6 +149,10 @@ namespace Umbraco.Core.Sync
|
||||
{
|
||||
if (refresher == null) throw new ArgumentNullException("refresher");
|
||||
|
||||
LogHelper.Debug<DefaultServerMessenger>("Invoking refresher {0} on single server instance, message type {1}",
|
||||
() => refresher.GetType(),
|
||||
() => dispatchType);
|
||||
|
||||
var stronglyTypedRefresher = refresher as ICacheRefresher<T>;
|
||||
|
||||
foreach (var instance in instances)
|
||||
@@ -202,22 +218,22 @@ namespace Umbraco.Core.Sync
|
||||
var result = _getUserNamePasswordDelegate();
|
||||
if (result == null)
|
||||
{
|
||||
_login = null;
|
||||
_password = null;
|
||||
Login = null;
|
||||
Password = null;
|
||||
_useDistributedCalls = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
_login = result.Item1;
|
||||
_password = result.Item2;
|
||||
Login = result.Item1;
|
||||
Password = result.Item2;
|
||||
_useDistributedCalls = UmbracoSettings.UseDistributedCalls;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.Error<DefaultServerMessenger>("Could not resolve username/password delegate, server distribution will be disabled", ex);
|
||||
_login = null;
|
||||
_password = null;
|
||||
Login = null;
|
||||
Password = null;
|
||||
_useDistributedCalls = false;
|
||||
}
|
||||
}
|
||||
@@ -225,10 +241,14 @@ namespace Umbraco.Core.Sync
|
||||
}
|
||||
}
|
||||
|
||||
private void InvokeMethodOnRefresherInstance(ICacheRefresher refresher, MessageType dispatchType, IEnumerable<object> ids = null, string jsonPayload = null)
|
||||
protected void InvokeMethodOnRefresherInstance(ICacheRefresher refresher, MessageType dispatchType, IEnumerable<object> ids = null, string jsonPayload = null)
|
||||
{
|
||||
if (refresher == null) throw new ArgumentNullException("refresher");
|
||||
|
||||
LogHelper.Debug<DefaultServerMessenger>("Invoking refresher {0} on single server instance, message type {1}",
|
||||
() => refresher.GetType(),
|
||||
() => dispatchType);
|
||||
|
||||
//if it is a refresh all we'll do it here since ids will be null or empty
|
||||
if (dispatchType == MessageType.RefreshAll)
|
||||
{
|
||||
@@ -289,6 +309,8 @@ namespace Umbraco.Core.Sync
|
||||
if (servers == null) throw new ArgumentNullException("servers");
|
||||
if (refresher == null) throw new ArgumentNullException("refresher");
|
||||
|
||||
EnsureLazyUsernamePasswordDelegateResolved();
|
||||
|
||||
//Now, check if we are using Distrubuted calls. If there are no servers in the list then we
|
||||
// can definitely not distribute.
|
||||
if (!_useDistributedCalls || !servers.Any())
|
||||
@@ -317,7 +339,9 @@ namespace Umbraco.Core.Sync
|
||||
{
|
||||
throw new ArgumentException("The id must be either an int or a Guid");
|
||||
}
|
||||
|
||||
|
||||
EnsureLazyUsernamePasswordDelegateResolved();
|
||||
|
||||
//Now, check if we are using Distrubuted calls. If there are no servers in the list then we
|
||||
// can definitely not distribute.
|
||||
if (!_useDistributedCalls || !servers.Any())
|
||||
@@ -327,7 +351,13 @@ namespace Umbraco.Core.Sync
|
||||
return;
|
||||
}
|
||||
|
||||
EnsureLazyUsernamePasswordDelegateResolved();
|
||||
LogHelper.Debug<DefaultServerMessenger>(
|
||||
"Performing distributed call for refresher {0}, message type: {1}, servers: {2}, ids: {3}, json: {4}",
|
||||
refresher.GetType,
|
||||
() => dispatchType,
|
||||
() => string.Join(";", servers.Select(x => x.ToString())),
|
||||
() => ids == null ? "" : string.Join(";", ids.Select(x => x.ToString())),
|
||||
() => jsonPayload ?? "");
|
||||
|
||||
PerformDistributedCall(servers, refresher, dispatchType, ids, arrayType, jsonPayload);
|
||||
}
|
||||
@@ -385,12 +415,12 @@ namespace Umbraco.Core.Sync
|
||||
case MessageType.RefreshByJson:
|
||||
asyncResultsList.Add(
|
||||
cacheRefresher.BeginRefreshByJson(
|
||||
refresher.UniqueIdentifier, jsonPayload, _login, _password, null, null));
|
||||
refresher.UniqueIdentifier, jsonPayload, Login, Password, null, null));
|
||||
break;
|
||||
case MessageType.RefreshAll:
|
||||
asyncResultsList.Add(
|
||||
cacheRefresher.BeginRefreshAll(
|
||||
refresher.UniqueIdentifier, _login, _password, null, null));
|
||||
refresher.UniqueIdentifier, Login, Password, null, null));
|
||||
break;
|
||||
case MessageType.RefreshById:
|
||||
if (idArrayType == null)
|
||||
@@ -403,7 +433,7 @@ namespace Umbraco.Core.Sync
|
||||
var serializer = new JavaScriptSerializer();
|
||||
var jsonIds = serializer.Serialize(ids.Cast<int>().ToArray());
|
||||
//we support bulk loading of Integers
|
||||
var result = cacheRefresher.BeginRefreshByIds(refresher.UniqueIdentifier, jsonIds, _login, _password, null, null);
|
||||
var result = cacheRefresher.BeginRefreshByIds(refresher.UniqueIdentifier, jsonIds, Login, Password, null, null);
|
||||
asyncResultsList.Add(result);
|
||||
}
|
||||
else
|
||||
@@ -412,7 +442,7 @@ namespace Umbraco.Core.Sync
|
||||
//so we'll just iterate
|
||||
asyncResultsList.AddRange(
|
||||
ids.Select(i => cacheRefresher.BeginRefreshByGuid(
|
||||
refresher.UniqueIdentifier, (Guid)i, _login, _password, null, null)));
|
||||
refresher.UniqueIdentifier, (Guid)i, Login, Password, null, null)));
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -420,7 +450,7 @@ namespace Umbraco.Core.Sync
|
||||
//we don't currently support bulk removing so we'll iterate
|
||||
asyncResultsList.AddRange(
|
||||
ids.Select(i => cacheRefresher.BeginRemoveById(
|
||||
refresher.UniqueIdentifier, (int)i, _login, _password, null, null)));
|
||||
refresher.UniqueIdentifier, (int)i, Login, Password, null, null)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,12 @@ using System.Linq;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
internal class TopologicalSorter
|
||||
/// <summary>
|
||||
/// Topological Sort algorithm for sorting items based on dependencies.
|
||||
/// Use the static method TopologicalSorter.GetSortedItems for a convenient
|
||||
/// way of sorting a list of items with dependencies between them.
|
||||
/// </summary>
|
||||
public class TopologicalSorter
|
||||
{
|
||||
private readonly int[] _vertices; // list of vertices
|
||||
private readonly int[,] _matrix; // adjacency matrix
|
||||
@@ -109,8 +114,9 @@ namespace Umbraco.Core
|
||||
|
||||
#endregion
|
||||
|
||||
#region Internal Staic methods
|
||||
internal static IEnumerable<T> GetSortedItems<T>(List<DependencyField<T>> fields) where T : class
|
||||
#region Static methods
|
||||
|
||||
public static IEnumerable<T> GetSortedItems<T>(List<DependencyField<T>> fields) where T : class
|
||||
{
|
||||
int[] sortOrder = GetTopologicalSortOrder(fields);
|
||||
var list = new List<T>();
|
||||
@@ -155,9 +161,10 @@ namespace Umbraco.Core
|
||||
int[] result = g.Sort();
|
||||
return result;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
internal class DependencyField<T> where T : class
|
||||
public class DependencyField<T> where T : class
|
||||
{
|
||||
public DependencyField()
|
||||
{
|
||||
|
||||
+179
-65
@@ -19,8 +19,6 @@ using Umbraco.Core.IO;
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
|
||||
//TODO: Get the App_Code stuff in here from the old one
|
||||
|
||||
/// <summary>
|
||||
/// A utility class to find all classes of a certain type by reflection in the current bin folder
|
||||
/// of the web application.
|
||||
@@ -175,7 +173,8 @@ namespace Umbraco.Core
|
||||
{
|
||||
try
|
||||
{
|
||||
var foundAssembly = safeDomainAssemblies.FirstOrDefault(a => a.GetAssemblyFile() == assemblyName.GetAssemblyFile());
|
||||
var foundAssembly =
|
||||
safeDomainAssemblies.FirstOrDefault(a => a.GetAssemblyFile() == assemblyName.GetAssemblyFile());
|
||||
if (foundAssembly != null)
|
||||
{
|
||||
binFolderAssemblies.Add(foundAssembly);
|
||||
@@ -268,7 +267,7 @@ namespace Umbraco.Core
|
||||
"umbraco.interfaces,",
|
||||
"umbraco.providers,",
|
||||
"Umbraco.Web.UI,",
|
||||
"umbraco.webservices",
|
||||
"umbraco.webservices",
|
||||
"Lucene.",
|
||||
"Examine,",
|
||||
"Examine.",
|
||||
@@ -280,36 +279,66 @@ namespace Umbraco.Core
|
||||
"CookComputing."
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Finds any classes derived from the type T that contain the attribute TAttribute
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <typeparam name="TAttribute"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesOfTypeWithAttribute<T, TAttribute>()
|
||||
where TAttribute : Attribute
|
||||
{
|
||||
return FindClassesOfTypeWithAttribute<T, TAttribute>(GetAssembliesWithKnownExclusions(), true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds any classes derived from the type T that contain the attribute TAttribute
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <typeparam name="TAttribute"></typeparam>
|
||||
/// <param name="assemblies"></param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesOfTypeWithAttribute<T, TAttribute>(IEnumerable<Assembly> assemblies)
|
||||
where TAttribute : Attribute
|
||||
{
|
||||
return FindClassesOfTypeWithAttribute<T, TAttribute>(assemblies, true);
|
||||
}
|
||||
|
||||
public static IEnumerable<Type> FindClassesOfTypeWithAttribute<T, TAttribute>(IEnumerable<Assembly> assemblies, bool onlyConcreteClasses)
|
||||
where TAttribute : Attribute
|
||||
/// <summary>
|
||||
/// Finds any classes derived from the type T that contain the attribute TAttribute
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <typeparam name="TAttribute"></typeparam>
|
||||
/// <param name="assemblies"></param>
|
||||
/// <param name="onlyConcreteClasses"></param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesOfTypeWithAttribute<T, TAttribute>(
|
||||
IEnumerable<Assembly> assemblies,
|
||||
bool onlyConcreteClasses)
|
||||
where TAttribute : Attribute
|
||||
{
|
||||
return FindClassesOfTypeWithAttribute<TAttribute>(typeof (T), assemblies, onlyConcreteClasses);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds any classes derived from the assignTypeFrom Type that contain the attribute TAttribute
|
||||
/// </summary>
|
||||
/// <typeparam name="TAttribute"></typeparam>
|
||||
/// <param name="assignTypeFrom"></param>
|
||||
/// <param name="assemblies"></param>
|
||||
/// <param name="onlyConcreteClasses"></param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesOfTypeWithAttribute<TAttribute>(
|
||||
Type assignTypeFrom,
|
||||
IEnumerable<Assembly> assemblies,
|
||||
bool onlyConcreteClasses)
|
||||
where TAttribute : Attribute
|
||||
{
|
||||
if (assemblies == null) throw new ArgumentNullException("assemblies");
|
||||
|
||||
var l = new List<Type>();
|
||||
foreach(var a in assemblies)
|
||||
{
|
||||
var types = from t in GetTypesWithFormattedException(a)
|
||||
where !t.IsInterface
|
||||
&& typeof (T).IsAssignableFrom(t)
|
||||
&& t.GetCustomAttributes<TAttribute>(false).Any()
|
||||
&& (!onlyConcreteClasses || (t.IsClass && !t.IsAbstract))
|
||||
select t;
|
||||
l.AddRange(types);
|
||||
}
|
||||
|
||||
return l;
|
||||
|
||||
return GetClasses(assignTypeFrom, assemblies, onlyConcreteClasses,
|
||||
//the additional filter will ensure that any found types also have the attribute applied.
|
||||
t => t.GetCustomAttributes<TAttribute>(false).Any());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -333,7 +362,7 @@ namespace Umbraco.Core
|
||||
{
|
||||
if (assemblies == null) throw new ArgumentNullException("assemblies");
|
||||
|
||||
return GetAssignablesFromType<T>(assemblies, onlyConcreteClasses);
|
||||
return GetClasses(typeof(T), assemblies, onlyConcreteClasses);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -360,32 +389,50 @@ namespace Umbraco.Core
|
||||
return FindClassesWithAttribute(typeof(T), assemblies, onlyConcreteClasses);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the classes with attribute.
|
||||
/// </summary>
|
||||
/// <param name="type">The attribute type </param>
|
||||
/// <param name="assemblies">The assemblies.</param>
|
||||
/// <param name="onlyConcreteClasses">if set to <c>true</c> only concrete classes.</param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesWithAttribute(Type type, IEnumerable<Assembly> assemblies, bool onlyConcreteClasses)
|
||||
{
|
||||
if (assemblies == null) throw new ArgumentNullException("assemblies");
|
||||
if (!TypeHelper.IsTypeAssignableFrom<Attribute>(type))
|
||||
throw new ArgumentException("The type specified: " + type + " is not an Attribute type");
|
||||
/// <summary>
|
||||
/// Finds any classes with the attribute.
|
||||
/// </summary>
|
||||
/// <param name="attributeType">The attribute type </param>
|
||||
/// <param name="assemblies">The assemblies.</param>
|
||||
/// <param name="onlyConcreteClasses">if set to <c>true</c> only concrete classes.</param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesWithAttribute(
|
||||
Type attributeType,
|
||||
IEnumerable<Assembly> assemblies,
|
||||
bool onlyConcreteClasses)
|
||||
{
|
||||
if (assemblies == null) throw new ArgumentNullException("assemblies");
|
||||
|
||||
var l = new List<Type>();
|
||||
foreach (var a in assemblies)
|
||||
{
|
||||
var types = from t in GetTypesWithFormattedException(a)
|
||||
where !t.IsInterface && t.GetCustomAttributes(type, false).Any() && (!onlyConcreteClasses || (t.IsClass && !t.IsAbstract))
|
||||
select t;
|
||||
l.AddRange(types);
|
||||
}
|
||||
if (TypeHelper.IsTypeAssignableFrom<Attribute>(attributeType) == false)
|
||||
throw new ArgumentException("The type specified: " + attributeType + " is not an Attribute type");
|
||||
|
||||
return l;
|
||||
}
|
||||
var foundAssignableTypes = new List<Type>();
|
||||
|
||||
/// <summary>
|
||||
var assemblyList = assemblies.ToArray();
|
||||
|
||||
//find all assembly references that are referencing the attribute type's assembly since we
|
||||
//should only be scanning those assemblies because any other assembly will definitely not
|
||||
//contain a class that has this attribute.
|
||||
var referencedAssemblies = TypeHelper.GetReferencedAssemblies(attributeType, assemblyList);
|
||||
|
||||
foreach (var a in referencedAssemblies)
|
||||
{
|
||||
//get all types in the assembly that are sub types of the current type
|
||||
var allTypes = GetTypesWithFormattedException(a).ToArray();
|
||||
|
||||
var types = allTypes.Where(t => TypeHelper.IsNonStaticClass(t)
|
||||
&& (onlyConcreteClasses == false || t.IsAbstract == false)
|
||||
//the type must have this attribute
|
||||
&& t.GetCustomAttributes(attributeType, false).Any());
|
||||
|
||||
foundAssignableTypes.AddRange(types);
|
||||
}
|
||||
|
||||
return foundAssignableTypes;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Finds the classes with attribute.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
@@ -411,29 +458,96 @@ namespace Umbraco.Core
|
||||
|
||||
#region Private methods
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of assignables of type T from a collection of assemblies
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="assemblies"></param>
|
||||
/// <param name="onlyConcreteClasses"></param>
|
||||
/// <returns></returns>
|
||||
private static IEnumerable<Type> GetAssignablesFromType<T>(IEnumerable<Assembly> assemblies, bool onlyConcreteClasses)
|
||||
/// <summary>
|
||||
/// Finds types that are assignable from the assignTypeFrom parameter and will scan for these types in the assembly
|
||||
/// list passed in, however we will only scan assemblies that have a reference to the assignTypeFrom Type or any type
|
||||
/// deriving from the base type.
|
||||
/// </summary>
|
||||
/// <param name="assignTypeFrom"></param>
|
||||
/// <param name="assemblies"></param>
|
||||
/// <param name="onlyConcreteClasses"></param>
|
||||
/// <param name="additionalFilter">An additional filter to apply for what types will actually be included in the return value</param>
|
||||
/// <returns></returns>
|
||||
private static IEnumerable<Type> GetClasses(
|
||||
Type assignTypeFrom,
|
||||
IEnumerable<Assembly> assemblies,
|
||||
bool onlyConcreteClasses,
|
||||
Func<Type, bool> additionalFilter = null)
|
||||
{
|
||||
return GetTypes(typeof(T), assemblies, onlyConcreteClasses);
|
||||
}
|
||||
//the default filter will always return true.
|
||||
if (additionalFilter == null)
|
||||
{
|
||||
additionalFilter = type => true;
|
||||
}
|
||||
|
||||
var foundAssignableTypes = new List<Type>();
|
||||
|
||||
var assemblyList = assemblies.ToArray();
|
||||
|
||||
//find all assembly references that are referencing the current type's assembly since we
|
||||
//should only be scanning those assemblies because any other assembly will definitely not
|
||||
//contain sub type's of the one we're currently looking for
|
||||
var referencedAssemblies = TypeHelper.GetReferencedAssemblies(assignTypeFrom, assemblyList);
|
||||
|
||||
//get a list of non-referenced assemblies (we'll use this when we recurse below)
|
||||
var otherAssemblies = assemblyList.Where(x => referencedAssemblies.Contains(x) == false).ToArray();
|
||||
|
||||
//loop through the referenced assemblies
|
||||
foreach (var a in referencedAssemblies)
|
||||
{
|
||||
//get all types in the assembly that are sub types of the current type
|
||||
var allSubTypes = GetTypesWithFormattedException(a)
|
||||
.Where(assignTypeFrom.IsAssignableFrom)
|
||||
.ToArray();
|
||||
|
||||
//now filter the types based on the onlyConcreteClasses flag, not interfaces, not static classes
|
||||
var filteredTypes = allSubTypes
|
||||
.Where(t => (TypeHelper.IsNonStaticClass(t)
|
||||
&& (onlyConcreteClasses == false || t.IsAbstract == false)
|
||||
&& additionalFilter(t)))
|
||||
.ToArray();
|
||||
|
||||
//add the types to our list to return
|
||||
foundAssignableTypes.AddRange(filteredTypes);
|
||||
|
||||
//now we need to include types that may be inheriting from sub classes of the type being searched for
|
||||
//so we will search in assemblies that reference those types too.
|
||||
foreach (var subTypesInAssembly in allSubTypes.GroupBy(x => x.Assembly))
|
||||
{
|
||||
|
||||
//So that we are not scanning too much, we need to group the sub types:
|
||||
// * if there is more than 1 sub type in the same assembly then we should only search on the 'lowest base' type.
|
||||
// * We should also not search for sub types if the type is sealed since you cannot inherit from a sealed class
|
||||
// * We should not search for sub types if the type is static since you cannot inherit from them.
|
||||
var subTypeList = subTypesInAssembly
|
||||
.Where(t => t.IsSealed == false && TypeHelper.IsStaticClass(t) == false)
|
||||
.ToArray();
|
||||
|
||||
var baseClassAttempt = TypeHelper.GetLowestBaseType(subTypeList);
|
||||
|
||||
//if there's a base class amongst the types then we'll only search for that type.
|
||||
//otherwise we'll have to search for all of them.
|
||||
var subTypesToSearch = new List<Type>();
|
||||
if (baseClassAttempt.Success)
|
||||
{
|
||||
subTypesToSearch.Add(baseClassAttempt.Result);
|
||||
}
|
||||
else
|
||||
{
|
||||
subTypesToSearch.AddRange(subTypeList);
|
||||
}
|
||||
|
||||
foreach (var typeToSearch in subTypesToSearch)
|
||||
{
|
||||
//recursively find the types inheriting from this sub type in the other non-scanned assemblies.
|
||||
var foundTypes = GetClasses(typeToSearch, otherAssemblies, onlyConcreteClasses);
|
||||
foundAssignableTypes.AddRange(foundTypes);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static IEnumerable<Type> GetTypes(Type assignTypeFrom, IEnumerable<Assembly> assemblies, bool onlyConcreteClasses)
|
||||
{
|
||||
var l = new List<Type>();
|
||||
foreach (var a in assemblies)
|
||||
{
|
||||
var types = from t in GetTypesWithFormattedException(a)
|
||||
where !t.IsInterface && assignTypeFrom.IsAssignableFrom(t) && (!onlyConcreteClasses || (t.IsClass && !t.IsAbstract))
|
||||
select t;
|
||||
l.AddRange(types);
|
||||
}
|
||||
return l;
|
||||
return foundAssignableTypes;
|
||||
}
|
||||
|
||||
private static IEnumerable<Type> GetTypesWithFormattedException(Assembly a)
|
||||
@@ -452,7 +566,7 @@ namespace Umbraco.Core
|
||||
sb.AppendLine("Could not load types from assembly " + a.FullName + ", errors:");
|
||||
foreach (var loaderException in ex.LoaderExceptions.WhereNotNull())
|
||||
{
|
||||
sb.AppendLine("Exception: " + loaderException.ToString());
|
||||
sb.AppendLine("Exception: " + loaderException);
|
||||
}
|
||||
throw new ReflectionTypeLoadException(ex.Types, ex.LoaderExceptions, sb.ToString());
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
@@ -15,6 +16,109 @@ namespace Umbraco.Core
|
||||
private static readonly ConcurrentDictionary<Type, FieldInfo[]> GetFieldsCache = new ConcurrentDictionary<Type, FieldInfo[]>();
|
||||
private static readonly ConcurrentDictionary<Tuple<Type, bool, bool, bool>, PropertyInfo[]> GetPropertiesCache = new ConcurrentDictionary<Tuple<Type, bool, bool, bool>, PropertyInfo[]>();
|
||||
|
||||
/// <summary>
|
||||
/// Find all assembly references that are referencing the assignTypeFrom Type's assembly found in the assemblyList
|
||||
/// </summary>
|
||||
/// <param name="assignTypeFrom"></param>
|
||||
/// <param name="assemblies"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// If the assembly of the assignTypeFrom Type is in the App_Code assembly, then we return nothing since things cannot
|
||||
/// reference that assembly, same with the global.asax assembly.
|
||||
/// </remarks>
|
||||
public static Assembly[] GetReferencedAssemblies(Type assignTypeFrom, IEnumerable<Assembly> assemblies)
|
||||
{
|
||||
//check if it is the app_code assembly.
|
||||
//check if it is App_global.asax assembly
|
||||
if (assignTypeFrom.Assembly.IsAppCodeAssembly() || assignTypeFrom.Assembly.IsGlobalAsaxAssembly())
|
||||
{
|
||||
return Enumerable.Empty<Assembly>().ToArray();
|
||||
}
|
||||
|
||||
//find all assembly references that are referencing the current type's assembly since we
|
||||
//should only be scanning those assemblies because any other assembly will definitely not
|
||||
//contain sub type's of the one we're currently looking for
|
||||
return assemblies
|
||||
.Where(assembly =>
|
||||
assembly == assignTypeFrom.Assembly || HasReferenceToAssemblyWithName(assembly, assignTypeFrom.Assembly.GetName().Name))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// checks if the assembly has a reference with the same name as the expected assembly name.
|
||||
/// </summary>
|
||||
/// <param name="assembly"></param>
|
||||
/// <param name="expectedAssemblyName"></param>
|
||||
/// <returns></returns>
|
||||
private static bool HasReferenceToAssemblyWithName(Assembly assembly, string expectedAssemblyName)
|
||||
{
|
||||
return assembly
|
||||
.GetReferencedAssemblies()
|
||||
.Select(a => a.Name)
|
||||
.Contains(expectedAssemblyName, StringComparer.Ordinal);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the type is a class and is not static
|
||||
/// </summary>
|
||||
/// <param name="t"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsNonStaticClass(Type t)
|
||||
{
|
||||
return t.IsClass && IsStaticClass(t) == false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the type is a static class
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// In IL a static class is abstract and sealed
|
||||
/// see: http://stackoverflow.com/questions/1175888/determine-if-a-type-is-static
|
||||
/// </remarks>
|
||||
public static bool IsStaticClass(Type type)
|
||||
{
|
||||
return type.IsAbstract && type.IsSealed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds a lowest base class amongst a collection of types
|
||||
/// </summary>
|
||||
/// <param name="types"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// The term 'lowest' refers to the most base class of the type collection.
|
||||
/// If a base type is not found amongst the type collection then an invalid attempt is returned.
|
||||
/// </remarks>
|
||||
public static Attempt<Type> GetLowestBaseType(params Type[] types)
|
||||
{
|
||||
if (types.Length == 0)
|
||||
{
|
||||
return Attempt<Type>.False;
|
||||
}
|
||||
if (types.Length == 1)
|
||||
{
|
||||
return new Attempt<Type>(true, types[0]);
|
||||
}
|
||||
|
||||
foreach (var curr in types)
|
||||
{
|
||||
var others = types.Except(new[] {curr});
|
||||
|
||||
//is the curr type a common denominator for all others ?
|
||||
var isBase = others.All(curr.IsAssignableFrom);
|
||||
|
||||
//if this type is the base for all others
|
||||
if (isBase)
|
||||
{
|
||||
return new Attempt<Type>(true, curr);
|
||||
}
|
||||
}
|
||||
|
||||
return Attempt<Type>.False;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the type <paramref name="implementation"/> is assignable from the specified implementation <typeparamref name="TContract"/>,
|
||||
/// and caches the result across the application using a <see cref="ConcurrentDictionary{TKey,TValue}"/>.
|
||||
|
||||
@@ -42,6 +42,9 @@
|
||||
<Private>True</Private>
|
||||
<HintPath>..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="MiniProfiler">
|
||||
<HintPath>..\packages\MiniProfiler.2.1.0\lib\net40\MiniProfiler.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json">
|
||||
<HintPath>..\packages\Newtonsoft.Json.4.5.11\lib\net40\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
@@ -157,7 +160,6 @@
|
||||
<Compile Include="Events\SaveEventArgs.cs" />
|
||||
<Compile Include="Events\SendToPublishEventArgs.cs" />
|
||||
<Compile Include="IApplicationEventHandler.cs" />
|
||||
<Compile Include="MacroPropertyTypeResolver.cs" />
|
||||
<Compile Include="Media\MediaSubfolderCounter.cs" />
|
||||
<Compile Include="Models\ContentBase.cs" />
|
||||
<Compile Include="Models\ContentExtensions.cs" />
|
||||
@@ -468,7 +470,6 @@
|
||||
<Compile Include="Persistence\Repositories\Interfaces\IDataTypeDefinitionRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\Interfaces\IDictionaryRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\Interfaces\ILanguageRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\Interfaces\IMacroRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\Interfaces\IMediaRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\Interfaces\IMediaTypeRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\Interfaces\IRelationRepository.cs" />
|
||||
@@ -483,7 +484,6 @@
|
||||
<Compile Include="Persistence\Repositories\Interfaces\IUserRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\Interfaces\IUserTypeRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\LanguageRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\MacroRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\MediaRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\MediaTypeRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\PetaPocoRepositoryBase.cs" />
|
||||
@@ -521,6 +521,7 @@
|
||||
<Compile Include="Persistence\UnitOfWork\IUnitOfWorkRepository.cs" />
|
||||
<Compile Include="Persistence\UnitOfWork\PetaPocoUnitOfWork.cs" />
|
||||
<Compile Include="Persistence\UnitOfWork\PetaPocoUnitOfWorkProvider.cs" />
|
||||
<Compile Include="Profiling\Profiler.cs" />
|
||||
<Compile Include="PropertyEditors\Attributes\PropertyEditorAttribute.cs" />
|
||||
<Compile Include="PropertyEditors\Attributes\ShowLabelAttribute.cs" />
|
||||
<Compile Include="PropertyEditors\BlankPreValueModel.cs" />
|
||||
@@ -547,23 +548,7 @@
|
||||
<Compile Include="IO\FileSystemProviderAttribute.cs" />
|
||||
<Compile Include="IO\FileSystemExtensions.cs" />
|
||||
<Compile Include="IO\MediaFileSystem.cs" />
|
||||
<Compile Include="Macros\PropertyTypes\ContentAll.cs" />
|
||||
<Compile Include="Macros\PropertyTypes\ContentPicker.cs" />
|
||||
<Compile Include="Macros\PropertyTypes\ContentRandom.cs" />
|
||||
<Compile Include="Macros\PropertyTypes\ContentStubs.cs" />
|
||||
<Compile Include="Macros\PropertyTypes\ContentTree.cs" />
|
||||
<Compile Include="Macros\PropertyTypes\ContentType.cs" />
|
||||
<Compile Include="Macros\PropertyTypes\ContentTypeMultiple.cs" />
|
||||
<Compile Include="Macros\PropertyTypes\MediaCurrent.cs" />
|
||||
<Compile Include="Macros\PropertyTypes\Number.cs" />
|
||||
<Compile Include="Macros\PropertyTypes\PropertyTypePicker.cs" />
|
||||
<Compile Include="Macros\PropertyTypes\PropertyTypePickerMultiple.cs" />
|
||||
<Compile Include="Macros\PropertyTypes\TabPicker.cs" />
|
||||
<Compile Include="Macros\PropertyTypes\TabPickerMultiple.cs" />
|
||||
<Compile Include="Macros\PropertyTypes\Text.cs" />
|
||||
<Compile Include="Macros\PropertyTypes\TextMultiLine.cs" />
|
||||
<Compile Include="Macros\MacroTagParser.cs" />
|
||||
<Compile Include="Macros\PropertyTypes\YesNoBool.cs" />
|
||||
<Compile Include="Mandate.cs" />
|
||||
<Compile Include="Models\Content.cs" />
|
||||
<Compile Include="Models\ContentStatus.cs" />
|
||||
@@ -580,15 +565,8 @@
|
||||
<Compile Include="Models\IContentType.cs" />
|
||||
<Compile Include="Models\IContentTypeBase.cs" />
|
||||
<Compile Include="Models\IContentTypeComposition.cs" />
|
||||
<Compile Include="Models\IMacro.cs" />
|
||||
<Compile Include="Models\IMacroProperty.cs" />
|
||||
<Compile Include="Models\IMacroPropertyType.cs" />
|
||||
<Compile Include="Models\IMedia.cs" />
|
||||
<Compile Include="Models\IMediaType.cs" />
|
||||
<Compile Include="Models\Macro.cs" />
|
||||
<Compile Include="Models\MacroProperty.cs" />
|
||||
<Compile Include="Models\MacroPropertyTypeBaseTypes.cs" />
|
||||
<Compile Include="Models\MacroTypes.cs" />
|
||||
<Compile Include="Models\Property.cs" />
|
||||
<Compile Include="Models\PropertyCollection.cs" />
|
||||
<Compile Include="Models\PropertyGroup.cs" />
|
||||
@@ -702,13 +680,12 @@
|
||||
<Compile Include="Services\IDataTypeService.cs" />
|
||||
<Compile Include="Services\IFileService.cs" />
|
||||
<Compile Include="Services\ILocalizationService.cs" />
|
||||
<Compile Include="Services\IMacroService.cs" />
|
||||
<Compile Include="Services\IMediaService.cs" />
|
||||
<Compile Include="Services\IService.cs" />
|
||||
<Compile Include="Services\IUserService.cs" />
|
||||
<Compile Include="Services\LocalizationService.cs" />
|
||||
<Compile Include="Services\MacroService.cs" />
|
||||
<Compile Include="Services\MediaService.cs" />
|
||||
<Compile Include="Services\RelationService.cs" />
|
||||
<Compile Include="Services\ServerRegistrationService.cs" />
|
||||
<Compile Include="Services\PackagingService.cs" />
|
||||
<Compile Include="Services\ServiceContext.cs" />
|
||||
@@ -793,6 +770,7 @@
|
||||
<Compile Include="Xml\XmlNamespaces.cs" />
|
||||
<Compile Include="Xml\XmlNodeListFactory.cs" />
|
||||
<Compile Include="Xml\XmlNodeExtensions.cs" />
|
||||
<Compile Include="Xml\XPathNavigatorExtensions.cs" />
|
||||
<Compile Include="Xml\XPathVariable.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -4,6 +4,9 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
using System.Web.Hosting;
|
||||
using System.Web.Mvc;
|
||||
using StackExchange.Profiling;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
|
||||
namespace Umbraco.Core
|
||||
@@ -27,6 +30,9 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
internal void StartApplication(object sender, EventArgs e)
|
||||
{
|
||||
//don't output the MVC version header (security)
|
||||
MvcHandler.DisableMvcResponseHeader = true;
|
||||
|
||||
//boot up the application
|
||||
GetBootManager()
|
||||
.Initialize()
|
||||
@@ -44,6 +50,24 @@ namespace Umbraco.Core
|
||||
StartApplication(sender, e);
|
||||
}
|
||||
|
||||
protected void Application_BeginRequest()
|
||||
{
|
||||
if (GlobalSettings.DebugMode)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(Request["umbDebug"]))
|
||||
Umbraco.Core.Profiling.Profiler.Instance.Start();
|
||||
}
|
||||
}
|
||||
|
||||
protected void Application_EndRequest()
|
||||
{
|
||||
if (GlobalSettings.DebugMode)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(Request["umbDebug"]))
|
||||
Umbraco.Core.Profiling.Profiler.Instance.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Developers can override this method to modify objects on startup
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
using System.Xml.XPath;
|
||||
|
||||
namespace Umbraco.Core.Xml
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides extensions to XPathNavigator.
|
||||
/// </summary>
|
||||
internal static class XPathNavigatorExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Selects a node set, using the specified XPath expression.
|
||||
/// </summary>
|
||||
/// <param name="navigator">A source XPathNavigator.</param>
|
||||
/// <param name="expression">An XPath expression.</param>
|
||||
/// <param name="variables">A set of XPathVariables.</param>
|
||||
/// <returns>An iterator over the nodes matching the specified expression.</returns>
|
||||
public static XPathNodeIterator Select(this XPathNavigator navigator, string expression, params XPathVariable[] variables)
|
||||
{
|
||||
if (variables == null || variables.Length == 0 || variables[0] == null)
|
||||
return navigator.Select(expression);
|
||||
|
||||
// Reflector shows that the standard XPathNavigator.Compile method just does
|
||||
// return XPathExpression.Compile(xpath);
|
||||
// only difference is, XPathNavigator.Compile is virtual so it could be overriden
|
||||
// by a class inheriting from XPathNavigator... there does not seem to be any
|
||||
// doing it in the Framework, though... so we'll assume it's much cleaner to use
|
||||
// the static compile:
|
||||
var compiled = XPathExpression.Compile(expression);
|
||||
|
||||
var context = new DynamicContext();
|
||||
foreach (var variable in variables)
|
||||
context.AddVariable(variable.Name, variable.Value);
|
||||
compiled.SetContext(context);
|
||||
return navigator.Select(compiled);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Selects a node set, using the specified XPath expression.
|
||||
/// </summary>
|
||||
/// <param name="navigator">A source XPathNavigator.</param>
|
||||
/// <param name="expression">An XPath expression.</param>
|
||||
/// <param name="variables">A set of XPathVariables.</param>
|
||||
/// <returns>An iterator over the nodes matching the specified expression.</returns>
|
||||
public static XPathNodeIterator Select(this XPathNavigator navigator, XPathExpression expression, params XPathVariable[] variables)
|
||||
{
|
||||
if (variables == null || variables.Length == 0 || variables[0] == null)
|
||||
return navigator.Select(expression);
|
||||
|
||||
var compiled = expression.Clone(); // clone for thread-safety
|
||||
var context = new DynamicContext();
|
||||
foreach (var variable in variables)
|
||||
context.AddVariable(variable.Name, variable.Value);
|
||||
compiled.SetContext(context);
|
||||
return navigator.Select(compiled);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,18 +7,11 @@ using System.Xml.XPath;
|
||||
|
||||
namespace Umbraco.Core.Xml
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides extensions to XmlNode.
|
||||
/// </summary>
|
||||
internal static class XmlNodeExtensions
|
||||
{
|
||||
static XPathNodeIterator Select(string expression, XPathNavigator source, params XPathVariable[] variables)
|
||||
{
|
||||
var expr = source.Compile(expression);
|
||||
var context = new DynamicContext();
|
||||
foreach (var variable in variables)
|
||||
context.AddVariable(variable.Name, variable.Value);
|
||||
expr.SetContext(context);
|
||||
return source.Select(expr);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Selects a list of XmlNode matching an XPath expression.
|
||||
/// </summary>
|
||||
@@ -37,6 +30,24 @@ namespace Umbraco.Core.Xml
|
||||
return SelectNodes(source, expression, av);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Selects a list of XmlNode matching an XPath expression.
|
||||
/// </summary>
|
||||
/// <param name="source">A source XmlNode.</param>
|
||||
/// <param name="expression">An XPath expression.</param>
|
||||
/// <param name="variables">A set of XPathVariables.</param>
|
||||
/// <returns>The list of XmlNode matching the XPath expression.</returns>
|
||||
/// <remarks>
|
||||
/// <para>If <param name="variables" /> is <c>null</c>, or is empty, or contains only one single
|
||||
/// value which itself is <c>null</c>, then variables are ignored.</para>
|
||||
/// <para>The XPath expression should reference variables as <c>$var</c>.</para>
|
||||
/// </remarks>
|
||||
public static XmlNodeList SelectNodes(this XmlNode source, XPathExpression expression, IEnumerable<XPathVariable> variables)
|
||||
{
|
||||
var av = variables == null ? null : variables.ToArray();
|
||||
return SelectNodes(source, expression, av);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Selects a list of XmlNode matching an XPath expression.
|
||||
/// </summary>
|
||||
@@ -54,10 +65,31 @@ namespace Umbraco.Core.Xml
|
||||
if (variables == null || variables.Length == 0 || variables[0] == null)
|
||||
return source.SelectNodes(expression);
|
||||
|
||||
var iterator = Select(expression, source.CreateNavigator(), variables);
|
||||
var iterator = source.CreateNavigator().Select(expression, variables);
|
||||
return XmlNodeListFactory.CreateNodeList(iterator);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Selects a list of XmlNode matching an XPath expression.
|
||||
/// </summary>
|
||||
/// <param name="source">A source XmlNode.</param>
|
||||
/// <param name="expression">An XPath expression.</param>
|
||||
/// <param name="variables">A set of XPathVariables.</param>
|
||||
/// <returns>The list of XmlNode matching the XPath expression.</returns>
|
||||
/// <remarks>
|
||||
/// <para>If <param name="variables" /> is <c>null</c>, or is empty, or contains only one single
|
||||
/// value which itself is <c>null</c>, then variables are ignored.</para>
|
||||
/// <para>The XPath expression should reference variables as <c>$var</c>.</para>
|
||||
/// </remarks>
|
||||
public static XmlNodeList SelectNodes(this XmlNode source, XPathExpression expression, params XPathVariable[] variables)
|
||||
{
|
||||
if (variables == null || variables.Length == 0 || variables[0] == null)
|
||||
return source.SelectNodes(expression);
|
||||
|
||||
var iterator = source.CreateNavigator().Select(expression, variables);
|
||||
return XmlNodeListFactory.CreateNodeList(iterator);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Selects the first XmlNode that matches an XPath expression.
|
||||
/// </summary>
|
||||
@@ -75,7 +107,25 @@ namespace Umbraco.Core.Xml
|
||||
var av = variables == null ? null : variables.ToArray();
|
||||
return SelectSingleNode(source, expression, av);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Selects the first XmlNode that matches an XPath expression.
|
||||
/// </summary>
|
||||
/// <param name="source">A source XmlNode.</param>
|
||||
/// <param name="expression">An XPath expression.</param>
|
||||
/// <param name="variables">A set of XPathVariables.</param>
|
||||
/// <returns>The first XmlNode that matches the XPath expression.</returns>
|
||||
/// <remarks>
|
||||
/// <para>If <param name="variables" /> is <c>null</c>, or is empty, or contains only one single
|
||||
/// value which itself is <c>null</c>, then variables are ignored.</para>
|
||||
/// <para>The XPath expression should reference variables as <c>$var</c>.</para>
|
||||
/// </remarks>
|
||||
public static XmlNode SelectSingleNode(this XmlNode source, XPathExpression expression, IEnumerable<XPathVariable> variables)
|
||||
{
|
||||
var av = variables == null ? null : variables.ToArray();
|
||||
return SelectSingleNode(source, expression, av);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Selects the first XmlNode that matches an XPath expression.
|
||||
/// </summary>
|
||||
@@ -95,5 +145,25 @@ namespace Umbraco.Core.Xml
|
||||
|
||||
return SelectNodes(source, expression, variables).Cast<XmlNode>().FirstOrDefault();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Selects the first XmlNode that matches an XPath expression.
|
||||
/// </summary>
|
||||
/// <param name="source">A source XmlNode.</param>
|
||||
/// <param name="expression">An XPath expression.</param>
|
||||
/// <param name="variables">A set of XPathVariables.</param>
|
||||
/// <returns>The first XmlNode that matches the XPath expression.</returns>
|
||||
/// <remarks>
|
||||
/// <para>If <param name="variables" /> is <c>null</c>, or is empty, or contains only one single
|
||||
/// value which itself is <c>null</c>, then variables are ignored.</para>
|
||||
/// <para>The XPath expression should reference variables as <c>$var</c>.</para>
|
||||
/// </remarks>
|
||||
public static XmlNode SelectSingleNode(this XmlNode source, XPathExpression expression, params XPathVariable[] variables)
|
||||
{
|
||||
if (variables == null || variables.Length == 0 || variables[0] == null)
|
||||
return source.SelectSingleNode(expression);
|
||||
|
||||
return SelectNodes(source, expression, variables).Cast<XmlNode>().FirstOrDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user