Compare commits
409 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9a06c3a5ff | |||
| 44102df36f | |||
| 617a91c57e | |||
| cb0e5414b9 | |||
| 22cef52261 | |||
| 41e419a49e | |||
| efbe97a01d | |||
| 0babb7f28a | |||
| 5ba801386c | |||
| 8c998fd4e6 | |||
| 88f332f5c7 | |||
| a1b9842215 | |||
| d300bf8d6d | |||
| 78e66ce25f | |||
| dcc0374464 | |||
| a95afa610f | |||
| 13e2112c3c | |||
| cf10f5f0ee | |||
| ca00246236 | |||
| d71b8a139f | |||
| 6bf0d6e175 | |||
| 7a0c6ab975 | |||
| 49d5005453 | |||
| f2db0fe80e | |||
| 9917fb20ca | |||
| e71e9d7efb | |||
| 93cd03da28 | |||
| 1dade7bfd2 | |||
| c3b1aa36b8 | |||
| 9cc466775d | |||
| d0a91bf98b | |||
| 085c06e043 | |||
| 1e45f85f7c | |||
| a0785f2e0d | |||
| 583302faa2 | |||
| 4404ce94c5 | |||
| 86bc701511 | |||
| a86902bd91 | |||
| 7bdf76ffa7 | |||
| 528656a337 | |||
| 5ef46ad8df | |||
| 168dc0e5da | |||
| 5a1fc91f3e | |||
| 5e6b5a5cc1 | |||
| 7213e3a6a0 | |||
| 217ca62ea0 | |||
| d216d5755c | |||
| 8db748b738 | |||
| 300c9aa258 | |||
| f7097d571c | |||
| b151c39c3b | |||
| 542406c402 | |||
| c44b903261 | |||
| c68d7a33ca | |||
| 2773102441 | |||
| ef0d6eff2c | |||
| 1efad78214 | |||
| 46b2d8a4aa | |||
| 7a5cb7058b | |||
| c1c2339827 | |||
| 0e273d1a08 | |||
| 125c378274 | |||
| ca80a0cddc | |||
| 21707f9e08 | |||
| d8cfd8f12e | |||
| 08150c05e9 | |||
| 688f8c4170 | |||
| 31cbb79ede | |||
| 305ce84ef5 | |||
| c6d7056a64 | |||
| 7db1055a0d | |||
| d625388786 | |||
| fa1663ed51 | |||
| ca0de5acd3 | |||
| 27168722ab | |||
| 6dbeba0763 | |||
| 00e0f83c8e | |||
| 68ba0ca1e2 | |||
| b22e9d0911 | |||
| 6a59a90964 | |||
| 26a042f291 | |||
| 136b3db098 | |||
| 21f46d0a3c | |||
| 7fafea2370 | |||
| 86c37c7f6d | |||
| 7dd9f3e766 | |||
| 6c91d54372 | |||
| 1ccc8cc161 | |||
| c5e7e1e39e | |||
| db2a35dbce | |||
| 3d006f1e08 | |||
| e0c891719f | |||
| 89a14c13e5 | |||
| ca9aa21c7b | |||
| c0eaeb3168 | |||
| 74e16c0f8d | |||
| f8fac9f84e | |||
| 83ce359234 | |||
| 2c64f91b25 | |||
| e702fe2877 | |||
| 9d55656ae9 | |||
| d57de05453 | |||
| 11e4bf5de8 | |||
| 82661d9af4 | |||
| 56cff6bba8 | |||
| 6b289e1a7d | |||
| 50d7114209 | |||
| 91fa583f62 | |||
| 23d91fd350 | |||
| d4714e1580 | |||
| 2b22e6a784 | |||
| 59840926c8 | |||
| 338c7cc5a6 | |||
| 77850aea18 | |||
| 895f0a9dfe | |||
| ec03a3dc42 | |||
| 5a4dbba21b | |||
| 04546dd827 | |||
| 4ecf1f919e | |||
| bdc4e1ae6a | |||
| 3cb05870af | |||
| 95b0c342bb | |||
| 3a5584a1c1 | |||
| b425edbb45 | |||
| b403283368 | |||
| cb1d347769 | |||
| 4d0a2c85b7 | |||
| e1957b895f | |||
| 84de083d52 | |||
| 6ccb822cb5 | |||
| c94338d2b6 | |||
| 3ba001164f | |||
| a8c0367492 | |||
| 91646212fd | |||
| 4c9b2f552a | |||
| c696c62185 | |||
| 0dfbb95033 | |||
| 17969e4537 | |||
| 3395445d7c | |||
| 374fdcf29e | |||
| bcb19eea35 | |||
| da00ad1444 | |||
| 7bc52b3948 | |||
| a77aec4156 | |||
| f7f3dccfc8 | |||
| ab3469d703 | |||
| c78ea90cf5 | |||
| 3de0b85ae3 | |||
| 87b51d1418 | |||
| 8ea1af56ab | |||
| 219eb61194 | |||
| 1d3279fe07 | |||
| 88bb796f4d | |||
| 97878ac25a | |||
| c87e880b64 | |||
| e28ba446a0 | |||
| c645a2cf15 | |||
| 5fb8d990f8 | |||
| 8626e4337f | |||
| 0f22c41eee | |||
| e73fda14b5 | |||
| a04df8070a | |||
| 60c1052db1 | |||
| dd041a6f09 | |||
| 733aab6eb5 | |||
| 1e6d50a86b | |||
| 0445588c6b | |||
| 4d316cf0ce | |||
| 864650193a | |||
| cfa7b0a092 | |||
| 5726420848 | |||
| cc57cd6eb7 | |||
| 193eb259a6 | |||
| 6db18d83be | |||
| ca752f74bc | |||
| b840a0992c | |||
| 51997d0651 | |||
| 9482104ec5 | |||
| 7053c175f8 | |||
| b2116480fc | |||
| caef6cc623 | |||
| 280ad246ab | |||
| 43e0ef2472 | |||
| 44cfe5da84 | |||
| d5fd266b19 | |||
| 5768992ccc | |||
| 81aae79b42 | |||
| 9edbb3fc26 | |||
| 7fdd2bcdfc | |||
| ba90fdeb56 | |||
| d6bae1b58f | |||
| ef53db52f7 | |||
| 863b97039c | |||
| 1a1adbf647 | |||
| 5c745565da | |||
| 5dec54badb | |||
| e5e725b376 | |||
| f0f25c67c6 | |||
| da8c0726b1 | |||
| 2fbb9721fa | |||
| de6ffd456c | |||
| 5b3ff58ad8 | |||
| 9a4c1972b2 | |||
| b993ce953b | |||
| dde0f1aa36 | |||
| 3fd6754057 | |||
| 8fbb459233 | |||
| cb6f934792 | |||
| 7adbecf9a1 | |||
| 2fdf148610 | |||
| 9d9e5e8274 | |||
| 89895dd592 | |||
| f9252372ea | |||
| 02a2178029 | |||
| ee775a2fde | |||
| 22af206626 | |||
| 67e109c0e6 | |||
| 8a4d85771b | |||
| 4688ac104e | |||
| 032dbe5bf5 | |||
| a7695163b9 | |||
| cb4569677e | |||
| 4be704b968 | |||
| b7a5cb046a | |||
| eb52dafb33 | |||
| af382c171b | |||
| 54fdfdd639 | |||
| c4c99ef0b8 | |||
| 0bd233815e | |||
| 4c9fd4029f | |||
| 3d65afabbf | |||
| ef9bf155ef | |||
| e947f661a9 | |||
| 0eb8ebd82e | |||
| bc76fa8687 | |||
| 8681d535f2 | |||
| 6d81705ece | |||
| b433af8611 | |||
| b0f4d0e16b | |||
| 2f24dfb8f0 | |||
| ad63050078 | |||
| 552c2ed4dc | |||
| d7e522132e | |||
| ca7c43d944 | |||
| c35e842391 | |||
| dae20cc986 | |||
| c466514e7f | |||
| 5e2aa7fa68 | |||
| 11ccc88bc8 | |||
| c83009c879 | |||
| d6b9b41776 | |||
| 508a4c32b4 | |||
| dbf2538aae | |||
| 5293b3bcc7 | |||
| 940caba2c4 | |||
| e31daef4fa | |||
| 7984626433 | |||
| ffa557b097 | |||
| 9236bcbcd8 | |||
| 1b875b0c67 | |||
| ecce68da0a | |||
| e27a882d2b | |||
| c7ae379fd1 | |||
| 8ad13f6853 | |||
| e4ae40c2fe | |||
| be61270e42 | |||
| bd00b532eb | |||
| ebc9478f2d | |||
| ab72808a10 | |||
| 068e82172a | |||
| 45988d4f0c | |||
| db330b3223 | |||
| 03fd06cfa7 | |||
| 775148d241 | |||
| 8e65ecdc4a | |||
| 6a43dd41c6 | |||
| 82ae6a1aef | |||
| a127683d92 | |||
| 06f3f4b191 | |||
| a2f45a38f7 | |||
| 4b966ebe91 | |||
| da9e87d0ab | |||
| 84a206ce5e | |||
| 3c3c31c36e | |||
| 585f8e07f7 | |||
| f7c0e02bfd | |||
| e767eaa08b | |||
| ef32eda874 | |||
| 01ccf8a6a6 | |||
| c27ca1fb0d | |||
| 68e287cf12 | |||
| ad6946aa26 | |||
| 42d7c83a6d | |||
| 1a435148d8 | |||
| de348a9946 | |||
| 791e6a5f92 | |||
| 1f6f8df5b5 | |||
| 7f5eff6e53 | |||
| d885265818 | |||
| be6140a38b | |||
| 8ee05063a2 | |||
| 7920383904 | |||
| 1a3d9e27f4 | |||
| 2654f9189f | |||
| d7453b5a6e | |||
| 5ed8ceb85e | |||
| b7ea0840a9 | |||
| 6b65f1c197 | |||
| bc7dc8629e | |||
| d3c2b0a247 | |||
| 464711d3c8 | |||
| b15fd4496a | |||
| b3ea0c83f9 | |||
| c1aefe0686 | |||
| 907dd8092a | |||
| 7b5568ecb4 | |||
| 2fd383960d | |||
| 33f76d25f7 | |||
| a2c5c35394 | |||
| c0616a37bf | |||
| da4be3be65 | |||
| 08c4a75af7 | |||
| 047eb893eb | |||
| 308c381e17 | |||
| e99309aa2f | |||
| 917a2b78dd | |||
| e559a6d485 | |||
| 160518e977 | |||
| f985725118 | |||
| 5ec67ab3fd | |||
| 993513b138 | |||
| 7f75802e4e | |||
| 5eb330b7d7 | |||
| ce618d289b | |||
| 2191d33844 | |||
| 92a507bc87 | |||
| 1b844421fc | |||
| df9c6baed7 | |||
| 53357b0582 | |||
| 1164f1cdbb | |||
| 7f05b80a22 | |||
| 20239a9b71 | |||
| 70a0bbbe61 | |||
| c4b07cc3ae | |||
| 771935b8a5 | |||
| 73bb401f81 | |||
| 8ccbe4c1e4 | |||
| cf3343749f | |||
| 079df4a8b7 | |||
| 7612884705 | |||
| 74dc2d80fd | |||
| 647ebee34d | |||
| bc444847f4 | |||
| 24d9c60bdf | |||
| b5c2fc82bb | |||
| a50256d381 | |||
| 290f34f034 | |||
| 92f609ff71 | |||
| 7e6f7f8a2b | |||
| c5419e700b | |||
| cb09094632 | |||
| 72404e68a0 | |||
| 2c451c5cfe | |||
| af7f83f0f6 | |||
| 5b3c2178a2 | |||
| 145f789631 | |||
| e27e95cb1a | |||
| cdbc3fa8cd | |||
| 6feb7b222f | |||
| 8b299a070f | |||
| 782193b17a | |||
| 4b945f355a | |||
| 3cf8ef9513 | |||
| 65654de06a | |||
| 2334596bf3 | |||
| 1d664bce52 | |||
| 9a515de43f | |||
| b55d065d45 | |||
| 83db63c5a8 | |||
| 1fb0b95428 | |||
| 53e23f09dc | |||
| 9e781173fc | |||
| fead30db38 | |||
| d8811d6b46 | |||
| dd40dd964c | |||
| bc51a98cfd | |||
| 75e375ff54 | |||
| 1a29a3237d | |||
| 8d8bb4e237 | |||
| 6772b1de35 | |||
| ea13989b7e | |||
| 78bc38fe1b | |||
| edb0a934a1 | |||
| f726dd59bf | |||
| 9589500412 | |||
| 1c3b870ad2 | |||
| 6a5002495c | |||
| b3938cd7b2 | |||
| 3ce3a6f6ea | |||
| b03e9f8fd5 | |||
| 1e73bb12ac | |||
| 662bf16a4f | |||
| 26d450ad9a | |||
| bab4c7715d | |||
| 27f121f25c | |||
| b199f4072c | |||
| 53928c02f8 | |||
| 756d554b47 | |||
| fb4de621c0 |
@@ -125,22 +125,12 @@ IF NOT EXIST "%nuGetExecutable%" (
|
||||
powershell -Command "(New-Object Net.WebClient).DownloadFile('https://dist.nuget.org/win-x86-commandline/latest/nuget.exe', '%nuGetExecutable%')"
|
||||
)
|
||||
|
||||
:: We need 7za.exe for BuildBelle.bat
|
||||
IF NOT EXIST "%toolsFolder%7za.exe" (
|
||||
ECHO 7zip not found - fetching now
|
||||
"%nuGetExecutable%" install 7-Zip.CommandLine -OutputDirectory tools -Verbosity quiet
|
||||
)
|
||||
|
||||
:: We need vswhere.exe for VS2017+
|
||||
IF NOT EXIST "%toolsFolder%vswhere.exe" (
|
||||
ECHO vswhere not found - fetching now
|
||||
"%nuGetExecutable%" install vswhere -OutputDirectory tools -Verbosity quiet
|
||||
)
|
||||
|
||||
:: Put 7za.exe and vswhere.exe in a predictable path (not version specific)
|
||||
FOR /f "delims=" %%A in ('dir "%toolsFolder%7-Zip.CommandLine.*" /b') DO SET "sevenZipExePath=%toolsFolder%%%A\"
|
||||
MOVE "%sevenZipExePath%tools\7za.exe" "%toolsFolder%7za.exe"
|
||||
|
||||
FOR /f "delims=" %%A in ('dir "%toolsFolder%vswhere.*" /b') DO SET "vswhereExePath=%toolsFolder%%%A\"
|
||||
MOVE "%vswhereExePath%tools\vswhere.exe" "%toolsFolder%vswhere.exe"
|
||||
|
||||
|
||||
+16
-7
@@ -8,6 +8,22 @@ ECHO Current folder: %CD%
|
||||
SET nodeFileName=node-v6.9.1-win-x86.7z
|
||||
SET nodeExtractFolder=%toolsFolder%node.js.691
|
||||
|
||||
SET nuGetExecutable=%CD%\tools\nuget.exe
|
||||
IF NOT EXIST "%nuGetExecutable%" (
|
||||
ECHO Downloading https://dist.nuget.org/win-x86-commandline/latest/nuget.exe to %nuGetExecutable%
|
||||
powershell -Command "(New-Object Net.WebClient).DownloadFile('https://dist.nuget.org/win-x86-commandline/latest/nuget.exe', '%nuGetExecutable%')"
|
||||
)
|
||||
|
||||
:: We need 7za.exe for BuildBelle.bat
|
||||
IF NOT EXIST "%toolsFolder%7za.exe" (
|
||||
ECHO 7zip not found - fetching now
|
||||
"%nuGetExecutable%" install 7-Zip.CommandLine -OutputDirectory tools -Verbosity quiet
|
||||
)
|
||||
|
||||
:: Put 7za.exe and vswhere.exe in a predictable path (not version specific)
|
||||
FOR /f "delims=" %%A in ('dir "%toolsFolder%7-Zip.CommandLine.*" /b') DO SET "sevenZipExePath=%toolsFolder%%%A\"
|
||||
MOVE "%sevenZipExePath%tools\7za.exe" "%toolsFolder%7za.exe"
|
||||
|
||||
IF NOT EXIST "%nodeExtractFolder%" (
|
||||
ECHO Downloading http://nodejs.org/dist/v6.9.1/%nodeFileName% to %toolsFolder%%nodeFileName%
|
||||
powershell -Command "(New-Object Net.WebClient).DownloadFile('http://nodejs.org/dist/v6.9.1/%nodeFileName%', '%toolsFolder%%nodeFileName%')"
|
||||
@@ -16,13 +32,6 @@ IF NOT EXIST "%nodeExtractFolder%" (
|
||||
)
|
||||
FOR /f "delims=" %%A in ('dir "%nodeExtractFolder%\node*" /b') DO SET "nodePath=%nodeExtractFolder%\%%A"
|
||||
|
||||
|
||||
SET nuGetExecutable=%CD%\tools\nuget.exe
|
||||
IF NOT EXIST "%nuGetExecutable%" (
|
||||
ECHO Downloading https://dist.nuget.org/win-x86-commandline/latest/nuget.exe to %nuGetExecutable%
|
||||
powershell -Command "(New-Object Net.WebClient).DownloadFile('https://dist.nuget.org/win-x86-commandline/latest/nuget.exe', '%nuGetExecutable%')"
|
||||
)
|
||||
|
||||
SET drive=%CD:~0,2%
|
||||
SET nuGetFolder=%drive%\packages\
|
||||
FOR /f "delims=" %%A in ('dir "%nuGetFolder%npm.*" /b') DO SET "npmPath=%nuGetFolder%%%A\"
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
<dependency id="ClientDependency-Mvc5" version="[1.8.0.0, 2.0.0)" />
|
||||
<dependency id="AutoMapper" version="[3.3.1, 4.0.0)" />
|
||||
<dependency id="Newtonsoft.Json" version="[10.0.2, 11.0.0)" />
|
||||
<dependency id="Examine" version="[0.1.82, 1.0.0)" />
|
||||
<dependency id="Examine" version="[0.1.83, 1.0.0)" />
|
||||
<dependency id="ImageProcessor" version="[2.5.3, 3.0.0)" />
|
||||
<dependency id="ImageProcessor.Web" version="[4.8.3, 5.0.0)" />
|
||||
<dependency id="semver" version="[1.1.2, 3.0.0)" />
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
# Usage: on line 2 put the release version, on line 3 put the version comment (example: beta)
|
||||
7.6.2
|
||||
7.6.6
|
||||
+2
-2
@@ -11,5 +11,5 @@ using System.Resources;
|
||||
|
||||
[assembly: AssemblyVersion("1.0.*")]
|
||||
|
||||
[assembly: AssemblyFileVersion("7.6.2")]
|
||||
[assembly: AssemblyInformationalVersion("7.6.2")]
|
||||
[assembly: AssemblyFileVersion("7.6.6")]
|
||||
[assembly: AssemblyInformationalVersion("7.6.6")]
|
||||
@@ -23,12 +23,12 @@ namespace Umbraco.Core
|
||||
: base(serviceProvider, logger, packageActions)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="IPackageAction"/> implementations.
|
||||
/// </summary>
|
||||
public IEnumerable<IAction> Actions
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="IAction"/> implementations.
|
||||
/// </summary>
|
||||
public IEnumerable<IAction> Actions
|
||||
{
|
||||
get
|
||||
{
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace Umbraco.Core
|
||||
/// <param name="cache"></param>
|
||||
[Obsolete("Use the other constructor specifying a ProfilingLogger instead")]
|
||||
public ApplicationContext(DatabaseContext dbContext, ServiceContext serviceContext, CacheHelper cache)
|
||||
: this(dbContext, serviceContext, cache,
|
||||
: this(dbContext, serviceContext, cache,
|
||||
new ProfilingLogger(LoggerResolver.Current.Logger, ProfilerResolver.Current.Profiler))
|
||||
{
|
||||
}
|
||||
@@ -89,7 +89,7 @@ namespace Umbraco.Core
|
||||
/// <param name="replaceContext">If set to true and the singleton is already set, it will be replaced</param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// This is NOT thread safe
|
||||
/// This is NOT thread safe
|
||||
/// </remarks>
|
||||
public static ApplicationContext EnsureContext(ApplicationContext appContext, bool replaceContext)
|
||||
{
|
||||
@@ -107,14 +107,14 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
/// <param name="cache"></param>
|
||||
/// <param name="replaceContext">
|
||||
/// If set to true will replace the current singleton instance - This should only be used for unit tests or on app
|
||||
/// If set to true will replace the current singleton instance - This should only be used for unit tests or on app
|
||||
/// startup if for some reason the boot manager is not the umbraco boot manager.
|
||||
/// </param>
|
||||
/// <param name="dbContext"></param>
|
||||
/// <param name="serviceContext"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// This is NOT thread safe
|
||||
/// This is NOT thread safe
|
||||
/// </remarks>
|
||||
[Obsolete("Use the other method specifying an ProfilingLogger instead")]
|
||||
public static ApplicationContext EnsureContext(DatabaseContext dbContext, ServiceContext serviceContext, CacheHelper cache, bool replaceContext)
|
||||
@@ -135,14 +135,14 @@ namespace Umbraco.Core
|
||||
/// <param name="cache"></param>
|
||||
/// <param name="logger"></param>
|
||||
/// <param name="replaceContext">
|
||||
/// If set to true will replace the current singleton instance - This should only be used for unit tests or on app
|
||||
/// If set to true will replace the current singleton instance - This should only be used for unit tests or on app
|
||||
/// startup if for some reason the boot manager is not the umbraco boot manager.
|
||||
/// </param>
|
||||
/// <param name="dbContext"></param>
|
||||
/// <param name="serviceContext"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// This is NOT thread safe
|
||||
/// This is NOT thread safe
|
||||
/// </remarks>
|
||||
public static ApplicationContext EnsureContext(DatabaseContext dbContext, ServiceContext serviceContext, CacheHelper cache, ProfilingLogger logger, bool replaceContext)
|
||||
{
|
||||
@@ -175,7 +175,7 @@ namespace Umbraco.Core
|
||||
public CacheHelper ApplicationCache { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Exposes the global ProfilingLogger - this should generally not be accessed via the UmbracoContext and should normally just be exposed
|
||||
/// Exposes the global ProfilingLogger - this should generally not be accessed via the UmbracoContext and should normally just be exposed
|
||||
/// on most base classes or injected with IoC
|
||||
/// </summary>
|
||||
public ProfilingLogger ProfilingLogger { get; private set; }
|
||||
@@ -213,7 +213,7 @@ namespace Umbraco.Core
|
||||
// GlobalSettings.CurrentVersion returns the hard-coded "current version"
|
||||
// the system is configured if they match
|
||||
// if they don't, install runs, updates web.config (presumably) and updates GlobalSettings.ConfiguredStatus
|
||||
|
||||
|
||||
public bool IsConfigured
|
||||
{
|
||||
get { return _configured.Value; }
|
||||
@@ -226,8 +226,8 @@ namespace Umbraco.Core
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsConfigured == false
|
||||
&& DatabaseContext != null
|
||||
if (IsConfigured == false
|
||||
&& DatabaseContext != null
|
||||
&& DatabaseContext.IsDatabaseConfigured)
|
||||
{
|
||||
var schemaresult = DatabaseContext.ValidateDatabaseSchema();
|
||||
@@ -274,12 +274,12 @@ namespace Umbraco.Core
|
||||
|
||||
private Lazy<bool> _configured;
|
||||
internal MainDom MainDom { get; private set; }
|
||||
|
||||
|
||||
private void Init()
|
||||
{
|
||||
MainDom = new MainDom(ProfilingLogger.Logger);
|
||||
MainDom.Acquire();
|
||||
|
||||
|
||||
//Create the lazy value to resolve whether or not the application is 'configured'
|
||||
_configured = new Lazy<bool>(() =>
|
||||
{
|
||||
@@ -289,7 +289,7 @@ namespace Umbraco.Core
|
||||
var currentVersion = UmbracoVersion.GetSemanticVersion();
|
||||
|
||||
var ok =
|
||||
//we are not configured if this is null
|
||||
//we are not configured if this is null
|
||||
string.IsNullOrWhiteSpace(configStatus) == false
|
||||
//they must match
|
||||
&& configStatus == currentVersion;
|
||||
@@ -303,7 +303,7 @@ namespace Umbraco.Core
|
||||
var found = Services.MigrationEntryService.FindEntry(Constants.System.UmbracoMigrationName, UmbracoVersion.GetSemanticVersion());
|
||||
if (found == null)
|
||||
{
|
||||
//we haven't executed this migration in this environment, so even though the config versions match,
|
||||
//we haven't executed this migration in this environment, so even though the config versions match,
|
||||
// this db has not been updated.
|
||||
ProfilingLogger.Logger.Debug<ApplicationContext>(string.Format("The migration for version: '{0} has not been executed, there is no record in the database", currentVersion.ToSemanticString()));
|
||||
ok = false;
|
||||
@@ -323,7 +323,7 @@ namespace Umbraco.Core
|
||||
return false;
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private string ConfigurationStatus
|
||||
@@ -338,7 +338,7 @@ namespace Umbraco.Core
|
||||
{
|
||||
return String.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void AssertIsNotReady()
|
||||
@@ -363,7 +363,7 @@ namespace Umbraco.Core
|
||||
}
|
||||
internal set { _databaseContext = value; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current ServiceContext
|
||||
/// </summary>
|
||||
@@ -417,7 +417,7 @@ namespace Umbraco.Core
|
||||
ResolverCollection.ResetAll();
|
||||
//reset resolution itself (though this should be taken care of by resetting any of the resolvers above)
|
||||
Resolution.Reset();
|
||||
|
||||
|
||||
//reset the instance objects
|
||||
this.ApplicationCache = null;
|
||||
if (_databaseContext != null) //need to check the internal field here
|
||||
@@ -430,14 +430,14 @@ namespace Umbraco.Core
|
||||
/*
|
||||
if (DatabaseContext.IsDatabaseConfigured && DatabaseContext.Database != null)
|
||||
{
|
||||
DatabaseContext.Database.Dispose();
|
||||
}
|
||||
*/
|
||||
DatabaseContext.Database.Dispose();
|
||||
}
|
||||
*/
|
||||
}
|
||||
this.DatabaseContext = null;
|
||||
this.Services = null;
|
||||
this._isReady = false; //set the internal field
|
||||
|
||||
|
||||
// Indicate that the instance has been disposed.
|
||||
_disposed = true;
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ namespace Umbraco.Core.Cache
|
||||
public const string DataTypeCacheKey = "UmbracoDataTypeDefinition";
|
||||
public const string DataTypePreValuesCacheKey = "UmbracoPreVal";
|
||||
|
||||
public const string IdToKeyCacheKey = "UI2K";
|
||||
public const string KeyToIdCacheKey = "UK2I";
|
||||
public const string IdToKeyCacheKey = "UI2K__";
|
||||
public const string KeyToIdCacheKey = "UK2I__";
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,8 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
|
||||
bool ConvertUrlsToAscii { get; }
|
||||
|
||||
bool TryConvertUrlsToAscii { get; }
|
||||
|
||||
IEnumerable<IChar> CharCollection { get; }
|
||||
}
|
||||
}
|
||||
@@ -111,7 +111,12 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
|
||||
bool IRequestHandlerSection.ConvertUrlsToAscii
|
||||
{
|
||||
get { return UrlReplacing.ConvertUrlsToAscii; }
|
||||
get { return UrlReplacing.ConvertUrlsToAscii.InvariantEquals("true"); }
|
||||
}
|
||||
|
||||
bool IRequestHandlerSection.TryConvertUrlsToAscii
|
||||
{
|
||||
get { return UrlReplacing.ConvertUrlsToAscii.InvariantEquals("try"); }
|
||||
}
|
||||
|
||||
IEnumerable<IChar> IRequestHandlerSection.CharCollection
|
||||
|
||||
@@ -11,10 +11,10 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
get { return (bool) base["removeDoubleDashes"]; }
|
||||
}
|
||||
|
||||
[ConfigurationProperty("toAscii", DefaultValue = false)]
|
||||
internal bool ConvertUrlsToAscii
|
||||
[ConfigurationProperty("toAscii", DefaultValue = "false")]
|
||||
internal string ConvertUrlsToAscii
|
||||
{
|
||||
get { return (bool)base["toAscii"]; }
|
||||
get { return (string) base["toAscii"]; }
|
||||
}
|
||||
|
||||
[ConfigurationCollection(typeof(CharCollection), AddItemName = "char")]
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
public class UmbracoVersion
|
||||
{
|
||||
private static readonly Version Version = new Version("7.6.2");
|
||||
private static readonly Version Version = new Version("7.6.6");
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current version of Umbraco.
|
||||
@@ -33,9 +33,9 @@ namespace Umbraco.Core.Configuration
|
||||
public static SemVersion GetSemanticVersion()
|
||||
{
|
||||
return new SemVersion(
|
||||
Current.Major,
|
||||
Current.Major,
|
||||
Current.Minor,
|
||||
Current.Build,
|
||||
Current.Build,
|
||||
CurrentComment.IsNullOrWhiteSpace() ? null : CurrentComment,
|
||||
Current.Revision > 0 ? Current.Revision.ToInvariantString() : null);
|
||||
}
|
||||
|
||||
@@ -212,6 +212,16 @@ namespace Umbraco.Core
|
||||
/// Guid for a Forms DataSource.
|
||||
/// </summary>
|
||||
public static readonly Guid FormsDataSourceGuid = new Guid(FormsDataSource);
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Language.
|
||||
/// </summary>
|
||||
public const string Language = "6B05D05B-EC78-49BE-A4E4-79E274F07A77";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Forms DataSource.
|
||||
/// </summary>
|
||||
public static readonly Guid LanguageGuid = new Guid(Language);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,8 @@ namespace Umbraco.Core
|
||||
public const string BackOfficeTokenAuthenticationType = "UmbracoBackOfficeToken";
|
||||
public const string BackOfficeTwoFactorAuthenticationType = "UmbracoTwoFactorCookie";
|
||||
|
||||
internal const string EmptyPasswordPrefix = "___UIDEMPTYPWORD__";
|
||||
|
||||
/// <summary>
|
||||
/// The prefix used for external identity providers for their authentication type
|
||||
/// </summary>
|
||||
|
||||
@@ -2,7 +2,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Security.Permissions;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Core.Events
|
||||
{
|
||||
@@ -13,6 +12,9 @@ namespace Umbraco.Core.Events
|
||||
public class CancellableEventArgs : EventArgs, IEquatable<CancellableEventArgs>
|
||||
{
|
||||
private bool _cancel;
|
||||
private Dictionary<string, object> _eventState;
|
||||
|
||||
private static readonly ReadOnlyDictionary<string, object> EmptyAdditionalData = new ReadOnlyDictionary<string, object>(new Dictionary<string, object>());
|
||||
|
||||
public CancellableEventArgs(bool canCancel, EventMessages messages, IDictionary<string, object> additionalData)
|
||||
{
|
||||
@@ -26,7 +28,7 @@ namespace Umbraco.Core.Events
|
||||
if (eventMessages == null) throw new ArgumentNullException("eventMessages");
|
||||
CanCancel = canCancel;
|
||||
Messages = eventMessages;
|
||||
AdditionalData = new ReadOnlyDictionary<string, object>(new Dictionary<string, object>());
|
||||
AdditionalData = EmptyAdditionalData;
|
||||
}
|
||||
|
||||
public CancellableEventArgs(bool canCancel)
|
||||
@@ -34,18 +36,16 @@ namespace Umbraco.Core.Events
|
||||
CanCancel = canCancel;
|
||||
//create a standalone messages
|
||||
Messages = new EventMessages();
|
||||
AdditionalData = new ReadOnlyDictionary<string, object>(new Dictionary<string, object>());
|
||||
AdditionalData = EmptyAdditionalData;
|
||||
}
|
||||
|
||||
public CancellableEventArgs(EventMessages eventMessages)
|
||||
: this(true, eventMessages)
|
||||
{
|
||||
}
|
||||
{ }
|
||||
|
||||
public CancellableEventArgs()
|
||||
: this(true)
|
||||
{
|
||||
}
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Flag to determine if this instance will support being cancellable
|
||||
@@ -95,10 +95,19 @@ namespace Umbraco.Core.Events
|
||||
/// In some cases raised evens might need to contain additional arbitrary readonly data which can be read by event subscribers
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This allows for a bit of flexibility in our event raising - it's not pretty but we need to maintain backwards compatibility
|
||||
/// This allows for a bit of flexibility in our event raising - it's not pretty but we need to maintain backwards compatibility
|
||||
/// so we cannot change the strongly typed nature for some events.
|
||||
/// </remarks>
|
||||
public ReadOnlyDictionary<string, object> AdditionalData { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// This can be used by event subscribers to store state in the event args so they easily deal with custom state data between a starting ("ing")
|
||||
/// event and an ending ("ed") event
|
||||
/// </summary>
|
||||
public IDictionary<string, object> EventState
|
||||
{
|
||||
get { return _eventState ?? (_eventState = new Dictionary<string, object>()); }
|
||||
}
|
||||
|
||||
public bool Equals(CancellableEventArgs other)
|
||||
{
|
||||
@@ -111,13 +120,13 @@ namespace Umbraco.Core.Events
|
||||
{
|
||||
if (ReferenceEquals(null, obj)) return false;
|
||||
if (ReferenceEquals(this, obj)) return true;
|
||||
if (obj.GetType() != this.GetType()) return false;
|
||||
if (obj.GetType() != GetType()) return false;
|
||||
return Equals((CancellableEventArgs) obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return (AdditionalData != null ? AdditionalData.GetHashCode() : 0);
|
||||
return AdditionalData != null ? AdditionalData.GetHashCode() : 0;
|
||||
}
|
||||
|
||||
public static bool operator ==(CancellableEventArgs left, CancellableEventArgs right)
|
||||
@@ -127,7 +136,7 @@ namespace Umbraco.Core.Events
|
||||
|
||||
public static bool operator !=(CancellableEventArgs left, CancellableEventArgs right)
|
||||
{
|
||||
return !Equals(left, right);
|
||||
return Equals(left, right) == false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -99,7 +99,8 @@ namespace Umbraco.Core.Events
|
||||
/// </summary>
|
||||
public IEnumerable<TEntity> DeletedEntities
|
||||
{
|
||||
get { return EventObject; }
|
||||
get { return EventObject; }
|
||||
internal set { EventObject = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -4,7 +4,7 @@ using Umbraco.Core.Packaging.Models;
|
||||
|
||||
namespace Umbraco.Core.Events
|
||||
{
|
||||
internal class ImportPackageEventArgs<TEntity> : CancellableEnumerableObjectEventArgs<TEntity>, IEquatable<ImportPackageEventArgs<TEntity>>
|
||||
public class ImportPackageEventArgs<TEntity> : CancellableEnumerableObjectEventArgs<TEntity>, IEquatable<ImportPackageEventArgs<TEntity>>
|
||||
{
|
||||
private readonly MetaData _packageMetaData;
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace Umbraco.Core.Events
|
||||
public bool Equals(ImportPackageEventArgs<TEntity> other)
|
||||
{
|
||||
if (ReferenceEquals(null, other)) return false;
|
||||
if (ReferenceEquals(this, other)) return true;
|
||||
if (ReferenceEquals(this, other)) return true;
|
||||
//TODO: MetaData for package metadata has no equality operators :/
|
||||
return base.Equals(other) && _packageMetaData.Equals(other._packageMetaData);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ namespace Umbraco.Core.Events
|
||||
{
|
||||
public class MoveEventArgs<TEntity> : CancellableObjectEventArgs<TEntity>, IEquatable<MoveEventArgs<TEntity>>
|
||||
{
|
||||
private IEnumerable<MoveEventInfo<TEntity>> _moveInfoCollection;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor accepting a collection of MoveEventInfo objects
|
||||
/// </summary>
|
||||
@@ -107,7 +109,24 @@ namespace Umbraco.Core.Events
|
||||
/// <summary>
|
||||
/// Gets all MoveEventInfo objects used to create the object
|
||||
/// </summary>
|
||||
public IEnumerable<MoveEventInfo<TEntity>> MoveInfoCollection { get; private set; }
|
||||
public IEnumerable<MoveEventInfo<TEntity>> MoveInfoCollection
|
||||
{
|
||||
get { return _moveInfoCollection; }
|
||||
set
|
||||
{
|
||||
var first = value.FirstOrDefault();
|
||||
if (first == null)
|
||||
{
|
||||
throw new InvalidOperationException("MoveInfoCollection must have at least one item");
|
||||
}
|
||||
|
||||
_moveInfoCollection = value;
|
||||
|
||||
//assign the legacy props
|
||||
EventObject = first.Entity;
|
||||
ParentId = first.NewParentId;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The entity being moved
|
||||
|
||||
@@ -107,7 +107,7 @@ namespace Umbraco.Core.Events
|
||||
/// <summary>
|
||||
/// Boolean indicating whether the Recycle Bin was emptied successfully
|
||||
/// </summary>
|
||||
public bool RecycleBinEmptiedSuccessfully { get; private set; }
|
||||
public bool RecycleBinEmptiedSuccessfully { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Boolean indicating whether this event was fired for the Content's Recycle Bin.
|
||||
|
||||
@@ -3,7 +3,7 @@ using Umbraco.Core.Packaging.Models;
|
||||
|
||||
namespace Umbraco.Core.Events
|
||||
{
|
||||
internal class UninstallPackageEventArgs<TEntity> : CancellableObjectEventArgs<IEnumerable<TEntity>>
|
||||
public class UninstallPackageEventArgs<TEntity> : CancellableObjectEventArgs<IEnumerable<TEntity>>
|
||||
{
|
||||
private readonly MetaData _packageMetaData;
|
||||
|
||||
|
||||
@@ -2,17 +2,19 @@
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to create a hash code from multiple objects.
|
||||
/// Used to create a .NET HashCode from multiple objects.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// .Net has a class the same as this: System.Web.Util.HashCodeCombiner and of course it works for all sorts of things
|
||||
/// which we've not included here as we just need a quick easy class for this in order to create a unique
|
||||
/// hash of directories/files to see if they have changed.
|
||||
///
|
||||
/// NOTE: It's probably best to not relying on the hashing result across AppDomains! If you need a constant/reliable hash value
|
||||
/// between AppDomains use SHA1. This is perfect for hashing things in a very fast way for a single AppDomain.
|
||||
/// </remarks>
|
||||
internal class HashCodeCombiner
|
||||
{
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to generate a string hash using crypto libraries over multiple objects
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This should be used to generate a reliable hash that survives AppDomain restarts.
|
||||
/// This will use the crypto libs to generate the hash and will try to ensure that
|
||||
/// strings, etc... are not re-allocated so it's not consuming much memory.
|
||||
/// </remarks>
|
||||
internal class HashGenerator : DisposableObject
|
||||
{
|
||||
public HashGenerator()
|
||||
{
|
||||
_writer = new StreamWriter(_ms, Encoding.Unicode, 1024, leaveOpen: true);
|
||||
}
|
||||
|
||||
private readonly MemoryStream _ms = new MemoryStream();
|
||||
private StreamWriter _writer;
|
||||
|
||||
internal void AddInt(int i)
|
||||
{
|
||||
_writer.Write(i);
|
||||
}
|
||||
|
||||
internal void AddLong(long i)
|
||||
{
|
||||
_writer.Write(i);
|
||||
}
|
||||
|
||||
internal void AddObject(object o)
|
||||
{
|
||||
_writer.Write(o);
|
||||
}
|
||||
|
||||
internal void AddDateTime(DateTime d)
|
||||
{
|
||||
_writer.Write(d.Ticks);;
|
||||
}
|
||||
|
||||
internal void AddString(string s)
|
||||
{
|
||||
if (s != null)
|
||||
_writer.Write(s);
|
||||
}
|
||||
|
||||
internal void AddCaseInsensitiveString(string s)
|
||||
{
|
||||
//I've tried to no allocate a new string with this which can be done if we use the CompareInfo.GetSortKey method which will create a new
|
||||
//byte array that we can use to write to the output, however this also allocates new objects so i really don't think the performance
|
||||
//would be much different. In any case, i'll leave this here for reference. We could write the bytes out based on the sort key,
|
||||
//this is how we could deal with case insensitivity without allocating another string
|
||||
//for reference see: https://stackoverflow.com/a/10452967/694494
|
||||
//we could go a step further and s.Normalize() but we're not really dealing with crazy unicode with this class so far.
|
||||
|
||||
if (s != null)
|
||||
_writer.Write(s.ToUpperInvariant());
|
||||
}
|
||||
|
||||
internal void AddFileSystemItem(FileSystemInfo f)
|
||||
{
|
||||
//if it doesn't exist, don't proceed.
|
||||
if (f.Exists == false)
|
||||
return;
|
||||
|
||||
AddCaseInsensitiveString(f.FullName);
|
||||
AddDateTime(f.CreationTimeUtc);
|
||||
AddDateTime(f.LastWriteTimeUtc);
|
||||
|
||||
//check if it is a file or folder
|
||||
var fileInfo = f as FileInfo;
|
||||
if (fileInfo != null)
|
||||
{
|
||||
AddLong(fileInfo.Length);
|
||||
}
|
||||
|
||||
var dirInfo = f as DirectoryInfo;
|
||||
if (dirInfo != null)
|
||||
{
|
||||
foreach (var d in dirInfo.GetFiles())
|
||||
{
|
||||
AddFile(d);
|
||||
}
|
||||
foreach (var s in dirInfo.GetDirectories())
|
||||
{
|
||||
AddFolder(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void AddFile(FileInfo f)
|
||||
{
|
||||
AddFileSystemItem(f);
|
||||
}
|
||||
|
||||
internal void AddFolder(DirectoryInfo d)
|
||||
{
|
||||
AddFileSystemItem(d);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the generated hash output of all added objects
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
internal string GenerateHash()
|
||||
{
|
||||
//flush,close,dispose the writer,then create a new one since it's possible to keep adding after GenerateHash is called.
|
||||
|
||||
_writer.Flush();
|
||||
_writer.Close();
|
||||
_writer.Dispose();
|
||||
_writer = new StreamWriter(_ms, Encoding.UTF8, 1024, leaveOpen: true);
|
||||
|
||||
var hashType = CryptoConfig.AllowOnlyFipsAlgorithms ? "SHA1" : "MD5";
|
||||
|
||||
//create an instance of the correct hashing provider based on the type passed in
|
||||
var hasher = HashAlgorithm.Create(hashType);
|
||||
if (hasher == null) throw new InvalidOperationException("No hashing type found by name " + hashType);
|
||||
using (hasher)
|
||||
{
|
||||
var buffer = _ms.GetBuffer();
|
||||
//get the hashed values created by our selected provider
|
||||
var hashedByteArray = hasher.ComputeHash(buffer);
|
||||
|
||||
//create a StringBuilder object
|
||||
var stringBuilder = new StringBuilder();
|
||||
|
||||
//loop to each each byte
|
||||
foreach (var b in hashedByteArray)
|
||||
{
|
||||
//append it to our StringBuilder
|
||||
stringBuilder.Append(b.ToString("x2"));
|
||||
}
|
||||
|
||||
//return the hashed value
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void DisposeResources()
|
||||
{
|
||||
_writer.Close();
|
||||
_writer.Dispose();
|
||||
_ms.Close();
|
||||
_ms.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,8 @@ namespace Umbraco.Core.IO
|
||||
|
||||
private ShadowWrapper _macroPartialFileSystem;
|
||||
private ShadowWrapper _partialViewsFileSystem;
|
||||
private ShadowWrapper _macroScriptsFileSystem;
|
||||
private ShadowWrapper _userControlsFileSystem;
|
||||
private ShadowWrapper _stylesheetsFileSystem;
|
||||
private ShadowWrapper _scriptsFileSystem;
|
||||
private ShadowWrapper _xsltFileSystem;
|
||||
@@ -61,6 +63,8 @@ namespace Umbraco.Core.IO
|
||||
{
|
||||
var macroPartialFileSystem = new PhysicalFileSystem(SystemDirectories.MacroPartials);
|
||||
var partialViewsFileSystem = new PhysicalFileSystem(SystemDirectories.PartialViews);
|
||||
var macroScriptsFileSystem = new PhysicalFileSystem(SystemDirectories.MacroScripts);
|
||||
var userControlsFileSystem = new PhysicalFileSystem(SystemDirectories.UserControls);
|
||||
var stylesheetsFileSystem = new PhysicalFileSystem(SystemDirectories.Css);
|
||||
var scriptsFileSystem = new PhysicalFileSystem(SystemDirectories.Scripts);
|
||||
var xsltFileSystem = new PhysicalFileSystem(SystemDirectories.Xslt);
|
||||
@@ -69,6 +73,8 @@ namespace Umbraco.Core.IO
|
||||
|
||||
_macroPartialFileSystem = new ShadowWrapper(macroPartialFileSystem, "Views/MacroPartials", ScopeProvider);
|
||||
_partialViewsFileSystem = new ShadowWrapper(partialViewsFileSystem, "Views/Partials", ScopeProvider);
|
||||
_macroScriptsFileSystem = new ShadowWrapper(macroScriptsFileSystem, "macroScripts", ScopeProvider);
|
||||
_userControlsFileSystem = new ShadowWrapper(userControlsFileSystem, "usercontrols", ScopeProvider);
|
||||
_stylesheetsFileSystem = new ShadowWrapper(stylesheetsFileSystem, "css", ScopeProvider);
|
||||
_scriptsFileSystem = new ShadowWrapper(scriptsFileSystem, "scripts", ScopeProvider);
|
||||
_xsltFileSystem = new ShadowWrapper(xsltFileSystem, "xslt", ScopeProvider);
|
||||
@@ -85,6 +91,10 @@ namespace Umbraco.Core.IO
|
||||
|
||||
public IFileSystem2 MacroPartialsFileSystem { get { return _macroPartialFileSystem; } }
|
||||
public IFileSystem2 PartialViewsFileSystem { get { return _partialViewsFileSystem; } }
|
||||
// Legacy /macroScripts folder
|
||||
public IFileSystem2 MacroScriptsFileSystem { get { return _macroScriptsFileSystem; } }
|
||||
// Legacy /usercontrols folder
|
||||
public IFileSystem2 UserControlsFileSystem { get { return _userControlsFileSystem; } }
|
||||
public IFileSystem2 StylesheetsFileSystem { get { return _stylesheetsFileSystem; } }
|
||||
public IFileSystem2 ScriptsFileSystem { get { return _scriptsFileSystem; } }
|
||||
public IFileSystem2 XsltFileSystem { get { return _xsltFileSystem; } }
|
||||
@@ -252,13 +262,15 @@ namespace Umbraco.Core.IO
|
||||
internal ICompletable Shadow(Guid id)
|
||||
{
|
||||
var typed = _wrappers.ToArray();
|
||||
var wrappers = new ShadowWrapper[typed.Length + 7];
|
||||
var wrappers = new ShadowWrapper[typed.Length + 9];
|
||||
var i = 0;
|
||||
while (i < typed.Length) wrappers[i] = typed[i++];
|
||||
wrappers[i++] = _macroPartialFileSystem;
|
||||
wrappers[i++] = _macroScriptsFileSystem;
|
||||
wrappers[i++] = _partialViewsFileSystem;
|
||||
wrappers[i++] = _stylesheetsFileSystem;
|
||||
wrappers[i++] = _scriptsFileSystem;
|
||||
wrappers[i++] = _userControlsFileSystem;
|
||||
wrappers[i++] = _xsltFileSystem;
|
||||
wrappers[i++] = _masterPagesFileSystem;
|
||||
wrappers[i] = _mvcViewsFileSystem;
|
||||
|
||||
@@ -97,6 +97,8 @@ namespace Umbraco.Core.IO
|
||||
|
||||
public static string MapPath(string path, bool useHttpContext)
|
||||
{
|
||||
if (path == null) throw new ArgumentNullException("path");
|
||||
|
||||
// Check if the path is already mapped
|
||||
if ((path.Length >= 2 && path[1] == Path.VolumeSeparatorChar)
|
||||
|| path.StartsWith(@"\\")) //UNC Paths start with "\\". If the site is running off a network drive mapped paths will look like "\\Whatever\Boo\Bar"
|
||||
|
||||
@@ -264,7 +264,7 @@ namespace Umbraco.Core.Models
|
||||
/// <returns><see cref="Property"/> Value as an <see cref="object"/></returns>
|
||||
public virtual object GetValue(string propertyTypeAlias)
|
||||
{
|
||||
return Properties[propertyTypeAlias].Value;
|
||||
return Properties.Contains(propertyTypeAlias) ? Properties[propertyTypeAlias].Value : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -275,8 +275,13 @@ namespace Umbraco.Core.Models
|
||||
/// <returns><see cref="Property"/> Value as a <see cref="TPassType"/></returns>
|
||||
public virtual TPassType GetValue<TPassType>(string propertyTypeAlias)
|
||||
{
|
||||
if (Properties.Contains(propertyTypeAlias) == false)
|
||||
{
|
||||
return default(TPassType);
|
||||
}
|
||||
|
||||
var convertAttempt = Properties[propertyTypeAlias].Value.TryConvertTo<TPassType>();
|
||||
return convertAttempt.Success ? convertAttempt.Result : default(TPassType);
|
||||
return convertAttempt.Success ? convertAttempt.Result : default(TPassType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
public interface IUserControl : IFile
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -42,7 +42,7 @@ namespace Umbraco.Core.Models.Identity
|
||||
|
||||
private string GetPasswordHash(string storedPass)
|
||||
{
|
||||
return storedPass.StartsWith("___UIDEMPTYPWORD__") ? null : storedPass;
|
||||
return storedPass.StartsWith(Constants.Security.EmptyPasswordPrefix) ? null : storedPass;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -109,6 +109,30 @@ namespace Umbraco.Core.Models
|
||||
IsApproved = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for creating a Member object
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="email"></param>
|
||||
/// <param name="username"></param>
|
||||
/// <param name="rawPasswordValue">
|
||||
/// The password value passed in to this parameter should be the encoded/encrypted/hashed format of the member's password
|
||||
/// </param>
|
||||
/// <param name="contentType"></param>
|
||||
/// <param name="isApproved"></param>
|
||||
public Member(string name, string email, string username, string rawPasswordValue, IMemberType contentType, bool isApproved)
|
||||
: base(name, -1, contentType, new PropertyCollection())
|
||||
{
|
||||
Mandate.ParameterNotNull(contentType, "contentType");
|
||||
|
||||
_contentTypeAlias = contentType.Alias;
|
||||
_contentType = contentType;
|
||||
_email = email;
|
||||
_username = username;
|
||||
_rawPasswordValue = rawPasswordValue;
|
||||
IsApproved = isApproved;
|
||||
}
|
||||
|
||||
private static readonly Lazy<PropertySelectors> Ps = new Lazy<PropertySelectors>();
|
||||
|
||||
private class PropertySelectors
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
{
|
||||
Unknown = 0, // default
|
||||
PartialView = 1,
|
||||
PartialViewMacro = 2
|
||||
PartialViewMacro = 2,
|
||||
MacroScript = 3
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,6 +178,13 @@ namespace Umbraco.Core.Models
|
||||
/// </summary>
|
||||
[UmbracoObjectType(Constants.ObjectTypes.FormsDataSource)]
|
||||
[FriendlyName("DataSource")]
|
||||
FormsDataSource
|
||||
FormsDataSource,
|
||||
|
||||
/// <summary>
|
||||
/// Language
|
||||
/// </summary>
|
||||
[UmbracoObjectType(Constants.ObjectTypes.Language)]
|
||||
[FriendlyName("Language")]
|
||||
Language
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a UserControl file
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[DataContract(IsReference = true)]
|
||||
public class UserControl : File, IUserControl
|
||||
{
|
||||
public UserControl(string path)
|
||||
: this(path, (Func<File, string>)null)
|
||||
{ }
|
||||
|
||||
internal UserControl(string path, Func<File, string> getFileContent)
|
||||
: base(path, getFileContent)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the current entity has an identity, which in this case is a path/name.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Overrides the default Entity identity check.
|
||||
/// </remarks>
|
||||
public override bool HasIdentity
|
||||
{
|
||||
get { return string.IsNullOrEmpty(Path) == false; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
@@ -12,7 +13,7 @@ namespace Umbraco.Core.Models
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="textService"></param>
|
||||
/// <returns></returns>
|
||||
/// <returns></returns>
|
||||
public static CultureInfo GetUserCulture(this IUser user, ILocalizedTextService textService)
|
||||
{
|
||||
if (user == null) throw new ArgumentNullException("user");
|
||||
@@ -34,7 +35,7 @@ namespace Umbraco.Core.Models
|
||||
catch (CultureNotFoundException)
|
||||
{
|
||||
//return the default one
|
||||
return CultureInfo.GetCultureInfo("en");
|
||||
return CultureInfo.GetCultureInfo(GlobalSettings.DefaultUILanguage);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace Umbraco.Core.Packaging.Models
|
||||
{
|
||||
[Serializable]
|
||||
[DataContract(IsReference = true)]
|
||||
internal class InstallationSummary
|
||||
public class InstallationSummary
|
||||
{
|
||||
public MetaData MetaData { get; set; }
|
||||
public IEnumerable<IDataTypeDefinition> DataTypesInstalled { get; set; }
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace Umbraco.Core.Packaging.Models
|
||||
{
|
||||
[Serializable]
|
||||
[DataContract(IsReference = true)]
|
||||
internal class MetaData
|
||||
public class MetaData
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Version { get; set; }
|
||||
|
||||
@@ -4,7 +4,7 @@ using System.Xml.Linq;
|
||||
|
||||
namespace Umbraco.Core.Packaging.Models
|
||||
{
|
||||
internal enum ActionRunAt
|
||||
public enum ActionRunAt
|
||||
{
|
||||
Undefined = 0,
|
||||
Install,
|
||||
@@ -13,7 +13,7 @@ namespace Umbraco.Core.Packaging.Models
|
||||
|
||||
[Serializable]
|
||||
[DataContract(IsReference = true)]
|
||||
internal class PackageAction
|
||||
public class PackageAction
|
||||
{
|
||||
private ActionRunAt _runAt;
|
||||
private bool? _undo;
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace Umbraco.Core.Packaging.Models
|
||||
{
|
||||
[Serializable]
|
||||
[DataContract(IsReference = true)]
|
||||
internal class UninstallationSummary
|
||||
public class UninstallationSummary
|
||||
{
|
||||
public MetaData MetaData { get; set; }
|
||||
public IEnumerable<IDataTypeDefinition> DataTypesUninstalled { get; set; }
|
||||
|
||||
+34
-4
@@ -2,6 +2,7 @@
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence.DatabaseAnnotations;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZero
|
||||
@@ -16,7 +17,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
var exists = Context.Database.FirstOrDefault<RelationTypeDto>("WHERE alias=@alias", new {alias = Constants.Conventions.RelationTypes.RelateParentDocumentOnDeleteAlias});
|
||||
var exists = Context.Database.FirstOrDefault<RelationTypeDtoCapture>("WHERE alias=@alias", new {alias = Constants.Conventions.RelationTypes.RelateParentDocumentOnDeleteAlias});
|
||||
if (exists == null)
|
||||
{
|
||||
Insert.IntoTable("umbracoRelationType").Row(new
|
||||
@@ -28,13 +29,42 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe
|
||||
alias = Constants.Conventions.RelationTypes.RelateParentDocumentOnDeleteAlias
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
{ }
|
||||
|
||||
// need to capture the DTO as it is modified in later migrations
|
||||
|
||||
[TableName("umbracoRelationType")]
|
||||
[PrimaryKey("id")]
|
||||
[ExplicitColumns]
|
||||
internal class RelationTypeDtoCapture
|
||||
{
|
||||
public const int NodeIdSeed = 3;
|
||||
|
||||
[Column("id")]
|
||||
[PrimaryKeyColumn(IdentitySeed = NodeIdSeed)]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Column("dual")]
|
||||
public bool Dual { get; set; }
|
||||
|
||||
[Column("parentObjectType")]
|
||||
public Guid ParentObjectType { get; set; }
|
||||
|
||||
[Column("childObjectType")]
|
||||
public Guid ChildObjectType { get; set; }
|
||||
|
||||
[Column("name")]
|
||||
[Index(IndexTypes.UniqueNonClustered, Name = "IX_umbracoRelationType_name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[Column("alias")]
|
||||
[NullSetting(NullSetting = NullSettings.Null)]
|
||||
[Length(100)]
|
||||
[Index(IndexTypes.UniqueNonClustered, Name = "IX_umbracoRelationType_alias")]
|
||||
public string Alias { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
-21
@@ -1,5 +1,4 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
@@ -11,15 +10,11 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe
|
||||
{
|
||||
public UpdateUniqueIdToHaveCorrectIndexType(ISqlSyntaxProvider sqlSyntax, ILogger logger)
|
||||
: base(sqlSyntax, logger)
|
||||
{
|
||||
}
|
||||
{ }
|
||||
|
||||
//see: http://issues.umbraco.org/issue/U4-6188, http://issues.umbraco.org/issue/U4-6187
|
||||
public override void Up()
|
||||
{
|
||||
|
||||
|
||||
var dbIndexes = SqlSyntax.GetDefinedIndexes(Context.Database)
|
||||
var indexes = SqlSyntax.GetDefinedIndexes(Context.Database)
|
||||
.Select(x => new DbIndexDefinition()
|
||||
{
|
||||
TableName = x.Item1,
|
||||
@@ -28,24 +23,19 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe
|
||||
IsUnique = x.Item4
|
||||
}).ToArray();
|
||||
|
||||
//must be non-nullable
|
||||
// drop the index if it exists
|
||||
if (indexes.Any(x => x.IndexName.InvariantEquals("IX_umbracoNodeUniqueID")))
|
||||
Delete.Index("IX_umbracoNodeUniqueID").OnTable("umbracoNode");
|
||||
|
||||
// set uniqueID to be non-nullable
|
||||
// the index *must* be dropped else 'one or more objects access this column' exception
|
||||
Alter.Table("umbracoNode").AlterColumn("uniqueID").AsGuid().NotNullable();
|
||||
|
||||
//make sure it already exists
|
||||
if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_umbracoNodeUniqueID")))
|
||||
{
|
||||
Delete.Index("IX_umbracoNodeUniqueID").OnTable("umbracoNode");
|
||||
}
|
||||
//make sure it doesn't already exist
|
||||
if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_umbracoNode_uniqueID")) == false)
|
||||
{
|
||||
//must be a uniqe index
|
||||
Create.Index("IX_umbracoNode_uniqueID").OnTable("umbracoNode").OnColumn("uniqueID").Unique();
|
||||
}
|
||||
// create the index
|
||||
Create.Index("IX_umbracoNode_uniqueID").OnTable("umbracoNode").OnColumn("uniqueID").Unique();
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
{
|
||||
}
|
||||
{ }
|
||||
}
|
||||
}
|
||||
-46
@@ -1,46 +0,0 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenTwoZero
|
||||
{
|
||||
[Migration("7.2.0", 3, Constants.System.UmbracoMigrationName)]
|
||||
public class AddIndexToUmbracoNodeTable : MigrationBase
|
||||
{
|
||||
private readonly bool _skipIndexCheck;
|
||||
|
||||
internal AddIndexToUmbracoNodeTable(ISqlSyntaxProvider sqlSyntax, ILogger logger, bool skipIndexCheck) : base(sqlSyntax, logger)
|
||||
{
|
||||
_skipIndexCheck = skipIndexCheck;
|
||||
}
|
||||
|
||||
public AddIndexToUmbracoNodeTable(ISqlSyntaxProvider sqlSyntax, ILogger logger) : base(sqlSyntax, logger)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
var dbIndexes = _skipIndexCheck ? new DbIndexDefinition[] { } : SqlSyntax.GetDefinedIndexes(Context.Database)
|
||||
.Select(x => new DbIndexDefinition
|
||||
{
|
||||
TableName = x.Item1,
|
||||
IndexName = x.Item2,
|
||||
ColumnName = x.Item3,
|
||||
IsUnique = x.Item4
|
||||
}).ToArray();
|
||||
|
||||
//make sure it doesn't already exist
|
||||
if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_umbracoNodeUniqueID")) == false)
|
||||
{
|
||||
Create.Index("IX_umbracoNodeUniqueID").OnTable("umbracoNode").OnColumn("uniqueID").Ascending().WithOptions().NonClustered();
|
||||
}
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
{
|
||||
Delete.Index("IX_umbracoNodeUniqueID").OnTable("umbracoNode");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -81,7 +81,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
s.Where<DocumentDto>(x => x.Newest, SqlSyntax);
|
||||
return s;
|
||||
};
|
||||
|
||||
|
||||
var sqlBaseFull = GetBaseQuery(BaseQueryType.FullMultiple);
|
||||
var sqlBaseIds = GetBaseQuery(BaseQueryType.Ids);
|
||||
|
||||
@@ -107,7 +107,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
return ProcessQuery(translate(translatorFull), new PagingSqlQuery(translate(translatorIds)));
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region Overrides of PetaPocoRepositoryBase<IContent>
|
||||
|
||||
@@ -142,8 +142,8 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
//The only reason we apply this left outer join is to be able to pull back the DocumentPublishedReadOnlyDto
|
||||
//information with the entire data set, so basically this will get both the latest document and also it's published
|
||||
//version if it has one. When performing a count or when retrieving Ids like in paging, this is unecessary
|
||||
//and causes huge performance overhead for the SQL server, especially when sorting the result.
|
||||
//version if it has one. When performing a count or when retrieving Ids like in paging, this is unecessary
|
||||
//and causes huge performance overhead for the SQL server, especially when sorting the result.
|
||||
//We also don't include this outer join when querying for multiple entities since it is much faster to fetch this information
|
||||
//in a separate query. For a single entity this is ok.
|
||||
|
||||
@@ -234,7 +234,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
};
|
||||
|
||||
var baseId = 0;
|
||||
|
||||
|
||||
while (true)
|
||||
{
|
||||
// get the next group of nodes
|
||||
@@ -284,7 +284,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
}
|
||||
|
||||
xmlIdsQuery.Where<NodeDto>(dto => dto.NodeObjectType == docObjectType, SqlSyntax);
|
||||
|
||||
|
||||
var allXmlIds = Database.Fetch<int>(xmlIdsQuery);
|
||||
|
||||
var toRemove = allXmlIds.Except(allContentIds).ToArray();
|
||||
@@ -293,9 +293,9 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
foreach (var idGroup in toRemove.InGroupsOf(2000))
|
||||
{
|
||||
Database.Execute("DELETE FROM cmsContentXml WHERE nodeId IN (@ids)", new { ids = idGroup });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public override IEnumerable<IContent> GetAllVersions(int id)
|
||||
@@ -308,7 +308,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
var sqlFull = translate(GetBaseQuery(BaseQueryType.FullMultiple));
|
||||
var sqlIds = translate(GetBaseQuery(BaseQueryType.Ids));
|
||||
|
||||
|
||||
return ProcessQuery(sqlFull, new PagingSqlQuery(sqlIds), true, includeAllVersions:true);
|
||||
}
|
||||
|
||||
@@ -388,7 +388,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
protected override void PersistDeletedItem(IContent entity)
|
||||
{
|
||||
//We need to clear out all access rules but we need to do this in a manual way since
|
||||
//We need to clear out all access rules but we need to do this in a manual way since
|
||||
// nothing in that table is joined to a content id
|
||||
var subQuery = new Sql()
|
||||
.Select("umbracoAccessRule.accessId")
|
||||
@@ -449,7 +449,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
entity.Level = level;
|
||||
|
||||
//Assign the same permissions to it as the parent node
|
||||
// http://issues.umbraco.org/issue/U4-2161
|
||||
// http://issues.umbraco.org/issue/U4-2161
|
||||
var permissionsRepo = new PermissionRepository<IContent>(UnitOfWork, _cacheHelper, SqlSyntax);
|
||||
var parentPermissions = permissionsRepo.GetPermissionsForEntity(entity.ParentId).ToArray();
|
||||
//if there are parent permissions then assign them, otherwise leave null and permissions will become the
|
||||
@@ -516,7 +516,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
VersionDate = dto.UpdateDate,
|
||||
Newest = true,
|
||||
NodeId = dto.NodeId,
|
||||
Published = true
|
||||
Published = true
|
||||
};
|
||||
((Content) entity).PublishedVersionGuid = dto.VersionId;
|
||||
((Content) entity).PublishedDate = dto.UpdateDate;
|
||||
@@ -636,9 +636,12 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
//In order to update the ContentVersion we need to retrieve its primary key id
|
||||
var contentVerDto = Database.SingleOrDefault<ContentVersionDto>("WHERE VersionId = @Version", new { Version = entity.Version });
|
||||
contentVersionDto.Id = contentVerDto.Id;
|
||||
|
||||
Database.Update(contentVersionDto);
|
||||
if (contentVerDto != null)
|
||||
{
|
||||
contentVersionDto.Id = contentVerDto.Id;
|
||||
Database.Update(contentVersionDto);
|
||||
}
|
||||
|
||||
Database.Update(dto);
|
||||
}
|
||||
|
||||
@@ -742,7 +745,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
return ProcessQuery(translate(translatorFull), new PagingSqlQuery(translate(translatorIds)), true);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// This builds the Xml document used for the XML cache
|
||||
/// </summary>
|
||||
@@ -841,7 +844,7 @@ order by umbracoNode.{2}, umbracoNode.parentID, umbracoNode.sortOrder",
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <param name="permission"></param>
|
||||
/// <param name="userIds"></param>
|
||||
/// <param name="userIds"></param>
|
||||
public void AssignEntityPermission(IContent entity, char permission, IEnumerable<int> userIds)
|
||||
{
|
||||
var repo = new PermissionRepository<IContent>(UnitOfWork, _cacheHelper, SqlSyntax);
|
||||
@@ -899,9 +902,9 @@ order by umbracoNode.{2}, umbracoNode.parentID, umbracoNode.sortOrder",
|
||||
string orderBy, Direction orderDirection, bool orderBySystemField, IQuery<IContent> filter = null)
|
||||
{
|
||||
|
||||
//NOTE: This uses the GetBaseQuery method but that does not take into account the required 'newest' field which is
|
||||
//NOTE: This uses the GetBaseQuery method but that does not take into account the required 'newest' field which is
|
||||
// what we always require for a paged result, so we'll ensure it's included in the filter
|
||||
|
||||
|
||||
var filterSql = new Sql().Append("AND (cmsDocument.newest = 1)");
|
||||
if (filter != null)
|
||||
{
|
||||
@@ -910,7 +913,7 @@ order by umbracoNode.{2}, umbracoNode.parentID, umbracoNode.sortOrder",
|
||||
filterSql.Append(string.Format("AND ({0})", filterClaus.Item1), filterClaus.Item2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Func<Tuple<string, object[]>> filterCallback = () => new Tuple<string, object[]>(filterSql.SQL, filterSql.Arguments);
|
||||
|
||||
return GetPagedResultsByQuery<DocumentDto>(query, pageIndex, pageSize, out totalRecords,
|
||||
@@ -957,7 +960,7 @@ order by umbracoNode.{2}, umbracoNode.parentID, umbracoNode.sortOrder",
|
||||
/// </param>
|
||||
/// <param name="withCache"></param>
|
||||
/// <param name="includeAllVersions">
|
||||
/// Generally when querying for content we only want to return the most recent version of the content item, however in some cases like when
|
||||
/// Generally when querying for content we only want to return the most recent version of the content item, however in some cases like when
|
||||
/// we want to return all versions of a content item, we can't simply return the latest
|
||||
/// </param>
|
||||
/// <returns></returns>
|
||||
@@ -966,7 +969,7 @@ order by umbracoNode.{2}, umbracoNode.parentID, umbracoNode.sortOrder",
|
||||
// fetch returns a list so it's ok to iterate it in this method
|
||||
var dtos = Database.Fetch<DocumentDto, ContentVersionDto, ContentDto, NodeDto>(sqlFull);
|
||||
if (dtos.Count == 0) return Enumerable.Empty<IContent>();
|
||||
|
||||
|
||||
//Go and get all of the published version data separately for this data, this is because when we are querying
|
||||
//for multiple content items we don't include the outer join to fetch this data in the same query because
|
||||
//it is insanely slow. Instead we just fetch the published version data separately in one query.
|
||||
@@ -978,7 +981,7 @@ order by umbracoNode.{2}, umbracoNode.parentID, umbracoNode.sortOrder",
|
||||
if (parsedOriginalSql.InvariantContains("ORDER BY "))
|
||||
{
|
||||
parsedOriginalSql = parsedOriginalSql.Substring(0, parsedOriginalSql.LastIndexOf("ORDER BY ", StringComparison.Ordinal));
|
||||
}
|
||||
}
|
||||
|
||||
//order by update date DESC, if there is corrupted published flags we only want the latest!
|
||||
var publishedSql = new Sql(@"SELECT cmsDocument.nodeId, cmsDocument.published, cmsDocument.versionId, cmsDocument.updateDate, cmsDocument.newest
|
||||
@@ -1004,12 +1007,12 @@ ORDER BY cmsContentVersion.id DESC
|
||||
var content = new List<Tuple<IContent, bool>>();
|
||||
var defs = new DocumentDefinitionCollection(includeAllVersions);
|
||||
var templateIds = new List<int>();
|
||||
|
||||
|
||||
//track the looked up content types, even though the content types are cached
|
||||
// they still need to be deep cloned out of the cache and we don't want to add
|
||||
// the overhead of deep cloning them on every item in this loop
|
||||
var contentTypes = new Dictionary<int, IContentType>();
|
||||
|
||||
|
||||
foreach (var dto in dtos)
|
||||
{
|
||||
DocumentPublishedReadOnlyDto publishedDto;
|
||||
@@ -1119,33 +1122,12 @@ ORDER BY cmsContentVersion.id DESC
|
||||
if (EnsureUniqueNaming == false)
|
||||
return nodeName;
|
||||
|
||||
var sql = new Sql();
|
||||
sql.Select("*")
|
||||
.From<NodeDto>()
|
||||
.Where<NodeDto>(x => x.NodeObjectType == NodeObjectTypeId && x.ParentId == parentId && x.Text.StartsWith(nodeName));
|
||||
var names = Database.Fetch<SimilarNodeName>("SELECT id, text AS name FROM umbracoNode WHERE nodeObjectType=@objectType AND parentId=@parentId",
|
||||
new { objectType = NodeObjectTypeId, parentId });
|
||||
|
||||
int uniqueNumber = 1;
|
||||
var currentName = nodeName;
|
||||
|
||||
var dtos = Database.Fetch<NodeDto>(sql);
|
||||
if (dtos.Any())
|
||||
{
|
||||
var results = dtos.OrderBy(x => x.Text, new SimilarNodeNameComparer());
|
||||
foreach (var dto in results)
|
||||
{
|
||||
if (id != 0 && id == dto.NodeId) continue;
|
||||
|
||||
if (dto.Text.ToLowerInvariant().Equals(currentName.ToLowerInvariant()))
|
||||
{
|
||||
currentName = nodeName + string.Format(" ({0})", uniqueNumber);
|
||||
uniqueNumber++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return currentName;
|
||||
return SimilarNodeName.GetUniqueName(names, id, nodeName);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Dispose disposable properties
|
||||
/// </summary>
|
||||
|
||||
@@ -450,33 +450,10 @@ AND umbracoNode.id <> @id",
|
||||
|
||||
private string EnsureUniqueNodeName(string nodeName, int id = 0)
|
||||
{
|
||||
var names = Database.Fetch<SimilarNodeName>("SELECT id, text AS name FROM umbracoNode WHERE nodeObjectType=@objectType",
|
||||
new { objectType = NodeObjectTypeId });
|
||||
|
||||
|
||||
var sql = new Sql();
|
||||
sql.Select("*")
|
||||
.From<NodeDto>(SqlSyntax)
|
||||
.Where<NodeDto>(x => x.NodeObjectType == NodeObjectTypeId && x.Text.StartsWith(nodeName));
|
||||
|
||||
int uniqueNumber = 1;
|
||||
var currentName = nodeName;
|
||||
|
||||
var dtos = Database.Fetch<NodeDto>(sql);
|
||||
if (dtos.Any())
|
||||
{
|
||||
var results = dtos.OrderBy(x => x.Text, new SimilarNodeNameComparer());
|
||||
foreach (var dto in results)
|
||||
{
|
||||
if (id != 0 && id == dto.NodeId) continue;
|
||||
|
||||
if (dto.Text.ToLowerInvariant().Equals(currentName.ToLowerInvariant()))
|
||||
{
|
||||
currentName = nodeName + string.Format(" ({0})", uniqueNumber);
|
||||
uniqueNumber++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return currentName;
|
||||
return SimilarNodeName.GetUniqueName(names, id, nodeName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -260,6 +260,19 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
return GetByQuery(query);
|
||||
}
|
||||
|
||||
public Dictionary<string, Guid> GetDictionaryItemKeyMap()
|
||||
{
|
||||
var columns = new[] { "key", "id" }.Select(x => (object) SqlSyntax.GetQuotedColumnName(x)).ToArray();
|
||||
var sql = new Sql().Select(columns).From<DictionaryDto>(SqlSyntax);
|
||||
return Database.Fetch<DictionaryItemKeyIdDto>(sql).ToDictionary(x => x.Key, x => x.Id);
|
||||
}
|
||||
|
||||
private class DictionaryItemKeyIdDto
|
||||
{
|
||||
public string Key { get; set; }
|
||||
public Guid Id { get; set; }
|
||||
}
|
||||
|
||||
public IEnumerable<IDictionaryItem> GetDictionaryItemDescendants(Guid? parentId)
|
||||
{
|
||||
//This methods will look up children at each level, since we do not store a path for dictionary (ATM), we need to do a recursive
|
||||
|
||||
@@ -9,5 +9,6 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
IDictionaryItem Get(Guid uniqueId);
|
||||
IDictionaryItem Get(string key);
|
||||
IEnumerable<IDictionaryItem> GetDictionaryItemDescendants(Guid? parentId);
|
||||
Dictionary<string, Guid> GetDictionaryItemKeyMap();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using System.IO;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
public interface IUserControlRepository : IRepository<string, UserControl>
|
||||
{
|
||||
bool ValidateUserControl(UserControl userControl);
|
||||
Stream GetFileContentStream(string filepath);
|
||||
void SetFileContent(string filepath, Stream content);
|
||||
long GetFileSize(string filepath);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
internal class MacroScriptRepository : PartialViewRepository
|
||||
{
|
||||
public MacroScriptRepository(IUnitOfWork work, IFileSystem fileSystem)
|
||||
: base(work, fileSystem)
|
||||
{ }
|
||||
|
||||
protected override PartialViewType ViewType { get { return PartialViewType.MacroScript; } }
|
||||
}
|
||||
}
|
||||
@@ -584,31 +584,10 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
if (EnsureUniqueNaming == false)
|
||||
return nodeName;
|
||||
|
||||
var sql = new Sql();
|
||||
sql.Select("*")
|
||||
.From<NodeDto>()
|
||||
.Where<NodeDto>(x => x.NodeObjectType == NodeObjectTypeId && x.ParentId == parentId && x.Text.StartsWith(nodeName));
|
||||
var names = Database.Fetch<SimilarNodeName>("SELECT id, text AS name FROM umbracoNode WHERE nodeObjectType=@objectType AND parentId=@parentId",
|
||||
new { objectType = NodeObjectTypeId, parentId });
|
||||
|
||||
int uniqueNumber = 1;
|
||||
var currentName = nodeName;
|
||||
|
||||
var dtos = Database.Fetch<NodeDto>(sql);
|
||||
if (dtos.Any())
|
||||
{
|
||||
var results = dtos.OrderBy(x => x.Text, new SimilarNodeNameComparer());
|
||||
foreach (var dto in results)
|
||||
{
|
||||
if (id != 0 && id == dto.NodeId) continue;
|
||||
|
||||
if (dto.Text.ToLowerInvariant().Equals(currentName.ToLowerInvariant()))
|
||||
{
|
||||
currentName = nodeName + string.Format(" ({0})", uniqueNumber);
|
||||
uniqueNumber++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return currentName;
|
||||
return SimilarNodeName.GetUniqueName(names, id, nodeName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -184,30 +184,16 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
public IEnumerable<IMemberGroup> GetMemberGroupsForMember(string username)
|
||||
{
|
||||
//find the member by username
|
||||
var memberSql = new Sql();
|
||||
var memberObjectType = new Guid(Constants.ObjectTypes.Member);
|
||||
var sql = new Sql()
|
||||
.Select("un.*")
|
||||
.From("umbracoNode AS un")
|
||||
.InnerJoin("cmsMember2MemberGroup")
|
||||
.On("un.id = cmsMember2MemberGroup.MemberGroup")
|
||||
.LeftJoin("(SELECT umbracoNode.id, cmsMember.LoginName FROM umbracoNode INNER JOIN cmsMember ON umbracoNode.id = cmsMember.nodeId) AS member")
|
||||
.On("member.id = cmsMember2MemberGroup.Member")
|
||||
.Where("un.nodeObjectType=@objectType", new {objectType = NodeObjectTypeId })
|
||||
.Where("member.LoginName=@loginName", new {loginName = username});
|
||||
|
||||
memberSql.Select("umbracoNode.id")
|
||||
.From<NodeDto>()
|
||||
.InnerJoin<MemberDto>()
|
||||
.On<NodeDto, MemberDto>(dto => dto.NodeId, dto => dto.NodeId)
|
||||
.Where<NodeDto>(x => x.NodeObjectType == memberObjectType)
|
||||
.Where<MemberDto>(x => x.LoginName == username);
|
||||
var memberIdUsername = Database.Fetch<int?>(memberSql).FirstOrDefault();
|
||||
if (memberIdUsername.HasValue == false)
|
||||
{
|
||||
return Enumerable.Empty<IMemberGroup>();
|
||||
}
|
||||
|
||||
var sql = new Sql();
|
||||
sql.Select("umbracoNode.*")
|
||||
.From<NodeDto>()
|
||||
.InnerJoin<Member2MemberGroupDto>()
|
||||
.On<NodeDto, Member2MemberGroupDto>(dto => dto.NodeId, dto => dto.MemberGroup)
|
||||
.Where<NodeDto>(x => x.NodeObjectType == NodeObjectTypeId)
|
||||
.Where<Member2MemberGroupDto>(x => x.Member == memberIdUsername.Value);
|
||||
|
||||
return Database.Fetch<NodeDto>(sql)
|
||||
.DistinctBy(dto => dto.NodeId)
|
||||
.Select(x => _modelFactory.BuildEntity(x));
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.AspNet.Identity;
|
||||
using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
@@ -230,7 +231,19 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
Database.Insert(dto.ContentVersionDto);
|
||||
|
||||
//Create the first entry in cmsMember
|
||||
dto.NodeId = nodeDto.NodeId;
|
||||
dto.NodeId = nodeDto.NodeId;
|
||||
|
||||
//if the password is empty, generate one with the special prefix
|
||||
//this will hash the guid with a salt so should be nicely random
|
||||
if (entity.RawPasswordValue.IsNullOrWhiteSpace())
|
||||
{
|
||||
var aspHasher = new PasswordHasher();
|
||||
dto.Password = Constants.Security.EmptyPasswordPrefix +
|
||||
aspHasher.HashPassword(Guid.NewGuid().ToString("N"));
|
||||
//re-assign
|
||||
entity.RawPasswordValue = dto.Password;
|
||||
}
|
||||
|
||||
Database.Insert(dto);
|
||||
|
||||
//Create the PropertyData for this version - cmsPropertyData
|
||||
|
||||
@@ -42,6 +42,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
//Construct and execute delete statements for all trashed items by 'nodeObjectType'
|
||||
var deletes = new List<string>
|
||||
{
|
||||
FormatDeleteStatement("cmsTask", "nodeId"),
|
||||
FormatDeleteStatement("umbracoUser2NodeNotify", "nodeId"),
|
||||
FormatDeleteStatement("umbracoUser2NodePermission", "nodeId"),
|
||||
@"DELETE FROM umbracoAccessRule WHERE umbracoAccessRule.accessId IN (
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
internal class SimilarNodeName
|
||||
{
|
||||
private int _numPos = -2;
|
||||
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
|
||||
// cached - reused
|
||||
public int NumPos
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_numPos != -2) return _numPos;
|
||||
|
||||
var name = Name;
|
||||
|
||||
if (name[name.Length - 1] != ')')
|
||||
return _numPos = -1;
|
||||
|
||||
var pos = name.LastIndexOf('(');
|
||||
if (pos < 2 || pos == name.Length - 2) // < 2 and not < 0, because we want at least "x ("
|
||||
return _numPos = -1;
|
||||
|
||||
return _numPos = pos;
|
||||
}
|
||||
}
|
||||
|
||||
// not cached - used only once
|
||||
public int NumVal
|
||||
{
|
||||
get
|
||||
{
|
||||
if (NumPos < 0)
|
||||
throw new InvalidOperationException();
|
||||
int num;
|
||||
if (int.TryParse(Name.Substring(NumPos + 1, Name.Length - 2 - NumPos), out num))
|
||||
return num;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// compare without allocating, nor parsing integers
|
||||
internal class Comparer : IComparer<SimilarNodeName>
|
||||
{
|
||||
public int Compare(SimilarNodeName x, SimilarNodeName y)
|
||||
{
|
||||
if (x == null) throw new ArgumentNullException("x");
|
||||
if (y == null) throw new ArgumentNullException("y");
|
||||
|
||||
var xpos = x.NumPos;
|
||||
var ypos = y.NumPos;
|
||||
|
||||
var xname = x.Name;
|
||||
var yname = y.Name;
|
||||
|
||||
if (xpos < 0 || ypos < 0 || xpos != ypos)
|
||||
return string.Compare(xname, yname, StringComparison.Ordinal);
|
||||
|
||||
// compare the part before (number)
|
||||
var n = string.Compare(xname, 0, yname, 0, xpos, StringComparison.Ordinal);
|
||||
if (n != 0)
|
||||
return n;
|
||||
|
||||
// compare (number) lengths
|
||||
var diff = xname.Length - yname.Length;
|
||||
if (diff != 0) return diff < 0 ? -1 : +1;
|
||||
|
||||
// actually compare (number)
|
||||
var i = xpos;
|
||||
while (i < xname.Length - 1)
|
||||
{
|
||||
if (xname[i] != yname[i])
|
||||
return xname[i] < yname[i] ? -1 : +1;
|
||||
i++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// gets a unique name
|
||||
public static string GetUniqueName(IEnumerable<SimilarNodeName> names, int nodeId, string nodeName)
|
||||
{
|
||||
var uniqueNumber = 1;
|
||||
var uniqueing = false;
|
||||
foreach (var name in names.OrderBy(x => x, new Comparer()))
|
||||
{
|
||||
// ignore self
|
||||
if (nodeId != 0 && name.Id == nodeId) continue;
|
||||
|
||||
if (uniqueing)
|
||||
{
|
||||
if (name.NumPos > 0 && name.Name.StartsWith(nodeName) && name.NumVal == uniqueNumber)
|
||||
uniqueNumber++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
else if (name.Name.InvariantEquals(nodeName))
|
||||
{
|
||||
uniqueing = true;
|
||||
}
|
||||
}
|
||||
|
||||
return uniqueing ? string.Concat(nodeName, " (", uniqueNumber.ToString(), ")") : nodeName;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
/// <summary>
|
||||
/// Comparer that takes into account the duplicate index of a node name
|
||||
/// This is needed as a normal alphabetic sort would go Page (1), Page (10), Page (2) etc.
|
||||
/// </summary>
|
||||
internal class SimilarNodeNameComparer : IComparer<string>
|
||||
{
|
||||
public int Compare(string x, string y)
|
||||
{
|
||||
if (x.LastIndexOf('(') != -1 && x.LastIndexOf(')') == x.Length - 1 && y.LastIndexOf(')') == y.Length - 1)
|
||||
{
|
||||
if (x.ToLower().Substring(0, x.LastIndexOf('(')) == y.ToLower().Substring(0, y.LastIndexOf('(')))
|
||||
{
|
||||
int xDuplicateIndex = ExtractDuplicateIndex(x);
|
||||
int yDuplicateIndex = ExtractDuplicateIndex(y);
|
||||
|
||||
if (xDuplicateIndex != 0 && yDuplicateIndex != 0)
|
||||
{
|
||||
return xDuplicateIndex.CompareTo(yDuplicateIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
return String.Compare(x.ToLower(), y.ToLower(), StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
private int ExtractDuplicateIndex(string text)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
if (text.LastIndexOf('(') != -1 && text.LastIndexOf('(') < text.Length - 2)
|
||||
{
|
||||
int startPos = text.LastIndexOf('(') + 1;
|
||||
int length = text.Length - 1 - startPos;
|
||||
|
||||
int.TryParse(text.Substring(startPos, length), out index);
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the UserControl Repository
|
||||
/// </summary>
|
||||
internal class UserControlRepository : FileRepository<string, UserControl>, IUserControlRepository
|
||||
{
|
||||
public UserControlRepository(IUnitOfWork work, IFileSystem fileSystem)
|
||||
: base(work, fileSystem)
|
||||
{
|
||||
}
|
||||
|
||||
public override UserControl Get(string id)
|
||||
{
|
||||
var path = FileSystem.GetRelativePath(id);
|
||||
|
||||
path = path.EnsureEndsWith(".ascx");
|
||||
|
||||
if (FileSystem.FileExists(path) == false)
|
||||
return null;
|
||||
|
||||
var created = FileSystem.GetCreated(path).UtcDateTime;
|
||||
var updated = FileSystem.GetLastModified(path).UtcDateTime;
|
||||
|
||||
var userControl = new UserControl(path, file => GetFileContent(file.OriginalPath))
|
||||
{
|
||||
Key = path.EncodeAsGuid(),
|
||||
CreateDate = created,
|
||||
UpdateDate = updated,
|
||||
Id = path.GetHashCode(),
|
||||
VirtualPath = FileSystem.GetUrl(path)
|
||||
};
|
||||
|
||||
//on initial construction we don't want to have dirty properties tracked
|
||||
// http://issues.umbraco.org/issue/U4-1946
|
||||
userControl.ResetDirtyProperties(false);
|
||||
|
||||
return userControl;
|
||||
}
|
||||
|
||||
public override void AddOrUpdate(UserControl entity)
|
||||
{
|
||||
base.AddOrUpdate(entity);
|
||||
|
||||
// ensure that from now on, content is lazy-loaded
|
||||
if (entity.GetFileContent == null)
|
||||
entity.GetFileContent = file => GetFileContent(file.OriginalPath);
|
||||
}
|
||||
|
||||
public override IEnumerable<UserControl> GetAll(params string[] ids)
|
||||
{
|
||||
ids = ids
|
||||
.Select(x => StringExtensions.EnsureEndsWith(x, ".ascx"))
|
||||
.Distinct()
|
||||
.ToArray();
|
||||
|
||||
if (ids.Any())
|
||||
{
|
||||
foreach (var id in ids)
|
||||
{
|
||||
yield return Get(id);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var files = FindAllFiles("", "*.ascx");
|
||||
foreach (var file in files)
|
||||
{
|
||||
yield return Get(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of all <see cref="UserControl"/> that exist at the relative path specified.
|
||||
/// </summary>
|
||||
/// <param name="rootPath">
|
||||
/// If null or not specified, will return the UserControl files at the root path relative to the IFileSystem
|
||||
/// </param>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<UserControl> GetUserControlsAtPath(string rootPath = null)
|
||||
{
|
||||
return FileSystem.GetFiles(rootPath ?? string.Empty, "*.ascx").Select(Get);
|
||||
}
|
||||
|
||||
private static readonly List<string> ValidExtensions = new List<string> { "ascx" };
|
||||
|
||||
public bool ValidateUserControl(UserControl userControl)
|
||||
{
|
||||
// get full path
|
||||
string fullPath;
|
||||
try
|
||||
{
|
||||
// may throw for security reasons
|
||||
fullPath = FileSystem.GetFullPath(userControl.Path);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// validate path and extension
|
||||
var validDir = SystemDirectories.UserControls;
|
||||
var isValidPath = IOHelper.VerifyEditPath(fullPath, validDir);
|
||||
var isValidExtension = IOHelper.VerifyFileExtension(userControl.Path, ValidExtensions);
|
||||
return isValidPath && isValidExtension;
|
||||
}
|
||||
|
||||
public Stream GetFileContentStream(string filepath)
|
||||
{
|
||||
if (FileSystem.FileExists(filepath) == false) return null;
|
||||
|
||||
try
|
||||
{
|
||||
return FileSystem.OpenFile(filepath);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null; // deal with race conds
|
||||
}
|
||||
}
|
||||
|
||||
public void SetFileContent(string filepath, Stream content)
|
||||
{
|
||||
FileSystem.AddFile(filepath, content, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -231,6 +231,18 @@ namespace Umbraco.Core.Persistence
|
||||
return new PartialViewMacroRepository(uow, FileSystemProviderManager.Current.MacroPartialsFileSystem);
|
||||
}
|
||||
|
||||
[Obsolete("MacroScripts are obsolete - this is for backwards compatibility with upgraded sites.")]
|
||||
internal virtual IPartialViewRepository CreateMacroScriptRepository(IUnitOfWork uow)
|
||||
{
|
||||
return new MacroScriptRepository(uow, FileSystemProviderManager.Current.MacroScriptsFileSystem);
|
||||
}
|
||||
|
||||
[Obsolete("UserControls are obsolete - this is for backwards compatibility with upgraded sites.")]
|
||||
internal virtual IUserControlRepository CreateUserControlRepository(IUnitOfWork uow)
|
||||
{
|
||||
return new UserControlRepository(uow, FileSystemProviderManager.Current.UserControlsFileSystem);
|
||||
}
|
||||
|
||||
public virtual IStylesheetRepository CreateStylesheetRepository(IUnitOfWork uow)
|
||||
{
|
||||
return new StylesheetRepository(uow, FileSystemProviderManager.Current.StylesheetsFileSystem);
|
||||
|
||||
@@ -44,8 +44,8 @@ namespace Umbraco.Core
|
||||
private readonly object _typesLock = new object();
|
||||
private readonly Dictionary<TypeListKey, TypeList> _types = new Dictionary<TypeListKey, TypeList>();
|
||||
|
||||
private long _cachedAssembliesHash = -1;
|
||||
private long _currentAssembliesHash = -1;
|
||||
private string _cachedAssembliesHash = null;
|
||||
private string _currentAssembliesHash = null;
|
||||
private IEnumerable<Assembly> _assemblies;
|
||||
private bool _reportedChange;
|
||||
|
||||
@@ -75,9 +75,9 @@ namespace Umbraco.Core
|
||||
|
||||
if (detectChanges)
|
||||
{
|
||||
//first check if the cached hash is 0, if it is then we ne
|
||||
//first check if the cached hash is string.Empty, if it is then we need
|
||||
//do the check if they've changed
|
||||
RequiresRescanning = (CachedAssembliesHash != CurrentAssembliesHash) || CachedAssembliesHash == 0;
|
||||
RequiresRescanning = (CachedAssembliesHash != CurrentAssembliesHash) || CachedAssembliesHash == string.Empty;
|
||||
//if they have changed, we need to write the new file
|
||||
if (RequiresRescanning)
|
||||
{
|
||||
@@ -180,23 +180,20 @@ namespace Umbraco.Core
|
||||
/// <summary>
|
||||
/// Gets the currently cached hash value of the scanned assemblies.
|
||||
/// </summary>
|
||||
/// <value>The cached hash value, or 0 if no cache is found.</value>
|
||||
internal long CachedAssembliesHash
|
||||
/// <value>The cached hash value, or string.Empty if no cache is found.</value>
|
||||
internal string CachedAssembliesHash
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_cachedAssembliesHash != -1)
|
||||
if (_cachedAssembliesHash != null)
|
||||
return _cachedAssembliesHash;
|
||||
|
||||
var filePath = GetPluginHashFilePath();
|
||||
if (File.Exists(filePath) == false) return 0;
|
||||
if (File.Exists(filePath) == false) return string.Empty;
|
||||
|
||||
var hash = File.ReadAllText(filePath, Encoding.UTF8);
|
||||
|
||||
long val;
|
||||
if (long.TryParse(hash, out val) == false) return 0;
|
||||
|
||||
_cachedAssembliesHash = val;
|
||||
|
||||
_cachedAssembliesHash = hash;
|
||||
return _cachedAssembliesHash;
|
||||
}
|
||||
}
|
||||
@@ -205,11 +202,11 @@ namespace Umbraco.Core
|
||||
/// Gets the current assemblies hash based on creating a hash from the assemblies in various places.
|
||||
/// </summary>
|
||||
/// <value>The current hash.</value>
|
||||
internal long CurrentAssembliesHash
|
||||
internal string CurrentAssembliesHash
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_currentAssembliesHash != -1)
|
||||
if (_currentAssembliesHash != null)
|
||||
return _currentAssembliesHash;
|
||||
|
||||
_currentAssembliesHash = GetFileHash(new List<Tuple<FileSystemInfo, bool>>
|
||||
@@ -245,41 +242,40 @@ namespace Umbraco.Core
|
||||
/// <returns>The hash.</returns>
|
||||
/// <remarks>Each file is a tuple containing the FileInfo object and a boolean which indicates whether to hash the
|
||||
/// file properties (false) or the file contents (true).</remarks>
|
||||
internal static long GetFileHash(IEnumerable<Tuple<FileSystemInfo, bool>> filesAndFolders, ProfilingLogger logger)
|
||||
internal static string GetFileHash(IEnumerable<Tuple<FileSystemInfo, bool>> filesAndFolders, ProfilingLogger logger)
|
||||
{
|
||||
using (logger.TraceDuration<PluginManager>("Determining hash of code files on disk", "Hash determined"))
|
||||
{
|
||||
var hashCombiner = new HashCodeCombiner();
|
||||
|
||||
{
|
||||
// get the distinct file infos to hash
|
||||
var uniqInfos = new HashSet<string>();
|
||||
var uniqContent = new HashSet<string>();
|
||||
|
||||
foreach (var fileOrFolder in filesAndFolders)
|
||||
using (var generator = new HashGenerator())
|
||||
{
|
||||
var info = fileOrFolder.Item1;
|
||||
if (fileOrFolder.Item2)
|
||||
foreach (var fileOrFolder in filesAndFolders)
|
||||
{
|
||||
// add each unique file's contents to the hash
|
||||
// normalize the content for cr/lf and case-sensitivity
|
||||
|
||||
if (uniqContent.Contains(info.FullName)) continue;
|
||||
uniqContent.Add(info.FullName);
|
||||
if (File.Exists(info.FullName) == false) continue;
|
||||
var content = RemoveCrLf(File.ReadAllText(info.FullName));
|
||||
hashCombiner.AddCaseInsensitiveString(content);
|
||||
var info = fileOrFolder.Item1;
|
||||
if (fileOrFolder.Item2)
|
||||
{
|
||||
// add each unique file's contents to the hash
|
||||
// normalize the content for cr/lf and case-sensitivity
|
||||
if (uniqContent.Add(info.FullName))
|
||||
{
|
||||
if (File.Exists(info.FullName) == false) continue;
|
||||
var content = RemoveCrLf(File.ReadAllText(info.FullName));
|
||||
generator.AddCaseInsensitiveString(content);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// add each unique folder/file to the hash
|
||||
if (uniqInfos.Add(info.FullName))
|
||||
{
|
||||
generator.AddFileSystemItem(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// add each unique folder/file to the hash
|
||||
|
||||
if (uniqInfos.Contains(info.FullName)) continue;
|
||||
uniqInfos.Add(info.FullName);
|
||||
hashCombiner.AddFileSystemItem(info);
|
||||
}
|
||||
}
|
||||
|
||||
return ConvertHashToInt64(hashCombiner.GetCombinedHashCode());
|
||||
return generator.GenerateHash();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -303,39 +299,33 @@ namespace Umbraco.Core
|
||||
/// <param name="filesAndFolders">A collection of files.</param>
|
||||
/// <param name="logger">A profiling logger.</param>
|
||||
/// <returns>The hash.</returns>
|
||||
internal static long GetFileHash(IEnumerable<FileSystemInfo> filesAndFolders, ProfilingLogger logger)
|
||||
internal static string GetFileHash(IEnumerable<FileSystemInfo> filesAndFolders, ProfilingLogger logger)
|
||||
{
|
||||
using (logger.TraceDuration<PluginManager>("Determining hash of code files on disk", "Hash determined"))
|
||||
{
|
||||
var hashCombiner = new HashCodeCombiner();
|
||||
|
||||
// get the distinct file infos to hash
|
||||
var uniqInfos = new HashSet<string>();
|
||||
|
||||
foreach (var fileOrFolder in filesAndFolders)
|
||||
using (var generator = new HashGenerator())
|
||||
{
|
||||
if (uniqInfos.Contains(fileOrFolder.FullName)) continue;
|
||||
uniqInfos.Add(fileOrFolder.FullName);
|
||||
hashCombiner.AddFileSystemItem(fileOrFolder);
|
||||
}
|
||||
// get the distinct file infos to hash
|
||||
var uniqInfos = new HashSet<string>();
|
||||
|
||||
return ConvertHashToInt64(hashCombiner.GetCombinedHashCode());
|
||||
foreach (var fileOrFolder in filesAndFolders)
|
||||
{
|
||||
if (uniqInfos.Contains(fileOrFolder.FullName)) continue;
|
||||
uniqInfos.Add(fileOrFolder.FullName);
|
||||
generator.AddFileSystemItem(fileOrFolder);
|
||||
}
|
||||
return generator.GenerateHash();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a string hash value into an Int64.
|
||||
/// </summary>
|
||||
internal static long ConvertHashToInt64(string val)
|
||||
{
|
||||
long outVal;
|
||||
return long.TryParse(val, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out outVal) ? outVal : 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Cache
|
||||
|
||||
private const int ListFileOpenReadTimeout = 4000; // milliseconds
|
||||
private const int ListFileOpenWriteTimeout = 2000; // milliseconds
|
||||
|
||||
/// <summary>
|
||||
/// Attemps to retrieve the list of types from the cache.
|
||||
/// </summary>
|
||||
@@ -381,7 +371,7 @@ namespace Umbraco.Core
|
||||
if (File.Exists(filePath) == false)
|
||||
return cache;
|
||||
|
||||
using (var stream = File.OpenRead(filePath))
|
||||
using (var stream = GetFileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, ListFileOpenReadTimeout))
|
||||
using (var reader = new StreamReader(stream))
|
||||
{
|
||||
while (true)
|
||||
@@ -451,7 +441,7 @@ namespace Umbraco.Core
|
||||
{
|
||||
var filePath = GetPluginListFilePath();
|
||||
|
||||
using (var stream = File.Open(filePath, FileMode.Create, FileAccess.ReadWrite))
|
||||
using (var stream = GetFileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, ListFileOpenWriteTimeout))
|
||||
using (var writer = new StreamWriter(stream))
|
||||
{
|
||||
foreach (var typeList in _types.Values)
|
||||
@@ -471,7 +461,28 @@ namespace Umbraco.Core
|
||||
// at the moment we write the cache to disk every time we update it. ideally we defer the writing
|
||||
// since all the updates are going to happen in a row when Umbraco starts. that being said, the
|
||||
// file is small enough, so it is not a priority.
|
||||
WriteCache();
|
||||
WriteCache();
|
||||
}
|
||||
|
||||
private static Stream GetFileStream(string path, FileMode fileMode, FileAccess fileAccess, FileShare fileShare, int timeoutMilliseconds)
|
||||
{
|
||||
const int pauseMilliseconds = 250;
|
||||
var attempts = timeoutMilliseconds / pauseMilliseconds;
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new FileStream(path, fileMode, fileAccess, fileShare);
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (--attempts == 0)
|
||||
throw;
|
||||
|
||||
LogHelper.Debug<PluginManager>(string.Format("Attempted to get filestream for file {0} failed, {1} attempts left, pausing for {2} milliseconds", path, attempts, pauseMilliseconds));
|
||||
Thread.Sleep(pauseMilliseconds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -39,7 +39,6 @@ using System.Security.Permissions;
|
||||
[assembly: InternalsVisibleTo("UmbracoExamine")]
|
||||
|
||||
[assembly: InternalsVisibleTo("Concorde.Sync")]
|
||||
[assembly: InternalsVisibleTo("Umbraco.VisualStudio")]
|
||||
[assembly: InternalsVisibleTo("Umbraco.Courier.Core")]
|
||||
[assembly: InternalsVisibleTo("Umbraco.Courier.Persistence")]
|
||||
|
||||
@@ -52,4 +51,8 @@ using System.Security.Permissions;
|
||||
[assembly: InternalsVisibleTo("Umbraco.Forms.Web")]
|
||||
|
||||
//allow this to be mocked in our unit tests
|
||||
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
|
||||
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
|
||||
|
||||
//allow custom unit-testing code to access internals through custom adapters
|
||||
[assembly: InternalsVisibleTo("Umbraco.VisualStudio")] // backwards compat.
|
||||
[assembly: InternalsVisibleTo("Umbraco.UnitTesting.Adapter")] // new, more imperative name
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace Umbraco.Core.PropertyEditors
|
||||
|
||||
public PropertyEditorAttribute(string alias, string name)
|
||||
{
|
||||
Mandate.ParameterNotNullOrEmpty(alias, "id");
|
||||
Mandate.ParameterNotNullOrEmpty(alias, "alias");
|
||||
Mandate.ParameterNotNullOrEmpty(name, "name");
|
||||
|
||||
Alias = alias;
|
||||
@@ -82,4 +82,4 @@ namespace Umbraco.Core.PropertyEditors
|
||||
/// </summary>
|
||||
public string Group { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -293,7 +293,7 @@ namespace Umbraco.Core.PropertyEditors
|
||||
//swallow this exception, we thought it was json but it really isn't so continue returning a string
|
||||
}
|
||||
}
|
||||
return property.Value.ToString();
|
||||
return asString;
|
||||
case DataTypeDatabaseType.Integer:
|
||||
case DataTypeDatabaseType.Decimal:
|
||||
//Decimals need to be formatted with invariant culture (dots, not commas)
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
if (sourceString != null)
|
||||
{
|
||||
decimal d;
|
||||
return (decimal.TryParse(sourceString, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out d)) ? d : 0M;
|
||||
return (decimal.TryParse(sourceString, NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign, CultureInfo.InvariantCulture, out d)) ? d : 0M;
|
||||
}
|
||||
|
||||
// in the database an a decimal is an a decimal
|
||||
|
||||
@@ -93,7 +93,7 @@ namespace Umbraco.Core.Security
|
||||
{
|
||||
//this will hash the guid with a salt so should be nicely random
|
||||
var aspHasher = new PasswordHasher();
|
||||
member.RawPasswordValue = "___UIDEMPTYPWORD__" +
|
||||
member.RawPasswordValue = Constants.Security.EmptyPasswordPrefix +
|
||||
aspHasher.HashPassword(Guid.NewGuid().ToString("N"));
|
||||
|
||||
}
|
||||
@@ -494,7 +494,7 @@ namespace Umbraco.Core.Security
|
||||
|
||||
//the stamp cannot be null, so if it is currently null then we'll just return a hash of the password
|
||||
return Task.FromResult(user.SecurityStamp.IsNullOrWhiteSpace()
|
||||
? user.PasswordHash.ToMd5()
|
||||
? user.PasswordHash.GenerateHash()
|
||||
: user.SecurityStamp);
|
||||
}
|
||||
|
||||
|
||||
@@ -64,6 +64,19 @@ namespace Umbraco.Core.Security
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the raw password value for a given user
|
||||
/// </summary>
|
||||
/// <param name="username"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// By default this will return an invalid attempt, inheritors will need to override this to support it
|
||||
/// </remarks>
|
||||
protected virtual Attempt<string> GetRawPassword(string username)
|
||||
{
|
||||
return Attempt<string>.Fail();
|
||||
}
|
||||
|
||||
private string _applicationName;
|
||||
private bool _enablePasswordReset;
|
||||
@@ -299,7 +312,7 @@ namespace Umbraco.Core.Security
|
||||
/// Processes a request to update the password for a membership user.
|
||||
/// </summary>
|
||||
/// <param name="username">The user to update the password for.</param>
|
||||
/// <param name="oldPassword">This property is ignore for this provider</param>
|
||||
/// <param name="oldPassword">Required to change a user password if the user is not new and AllowManuallyChangingPassword is false</param>
|
||||
/// <param name="newPassword">The new password for the specified user.</param>
|
||||
/// <returns>
|
||||
/// true if the password was updated successfully; otherwise, false.
|
||||
@@ -309,10 +322,17 @@ namespace Umbraco.Core.Security
|
||||
/// </remarks>
|
||||
public override bool ChangePassword(string username, string oldPassword, string newPassword)
|
||||
{
|
||||
string rawPasswordValue = string.Empty;
|
||||
if (oldPassword.IsNullOrWhiteSpace() && AllowManuallyChangingPassword == false)
|
||||
{
|
||||
//If the old password is empty and AllowManuallyChangingPassword is false, than this provider cannot just arbitrarily change the password
|
||||
throw new NotSupportedException("This provider does not support manually changing the password");
|
||||
{
|
||||
//we need to lookup the member since this could be a brand new member without a password set
|
||||
var rawPassword = GetRawPassword(username);
|
||||
rawPasswordValue = rawPassword.Success ? rawPassword.Result : string.Empty;
|
||||
if (rawPassword.Success == false || rawPasswordValue.StartsWith(Constants.Security.EmptyPasswordPrefix) == false)
|
||||
{
|
||||
//If the old password is empty and AllowManuallyChangingPassword is false, than this provider cannot just arbitrarily change the password
|
||||
throw new NotSupportedException("This provider does not support manually changing the password");
|
||||
}
|
||||
}
|
||||
|
||||
var args = new ValidatePasswordEventArgs(username, newPassword, false);
|
||||
@@ -325,10 +345,14 @@ namespace Umbraco.Core.Security
|
||||
throw new MembershipPasswordException("Change password canceled due to password validation failure.");
|
||||
}
|
||||
|
||||
//Special case to allow changing password without validating existing credentials
|
||||
//This is used during installation only
|
||||
if (AllowManuallyChangingPassword == false && ApplicationContext.Current != null
|
||||
&& ApplicationContext.Current.IsConfigured == false && oldPassword == "default")
|
||||
//Special cases to allow changing password without validating existing credentials
|
||||
// * the member is new and doesn't have a password set
|
||||
// * during installation to set the admin password
|
||||
if (AllowManuallyChangingPassword == false
|
||||
&& (rawPasswordValue.StartsWith(Constants.Security.EmptyPasswordPrefix)
|
||||
|| (ApplicationContext.Current != null
|
||||
&& ApplicationContext.Current.IsConfigured == false
|
||||
&& oldPassword == "default")))
|
||||
{
|
||||
return PerformChangePassword(username, oldPassword, newPassword);
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ namespace Umbraco.Core.Services
|
||||
private readonly EntityXmlSerializer _entitySerializer = new EntityXmlSerializer();
|
||||
private readonly IDataTypeService _dataTypeService;
|
||||
private readonly IUserService _userService;
|
||||
private readonly IdkMap _idkMap;
|
||||
|
||||
//Support recursive locks because some of the methods that require locking call other methods that require locking.
|
||||
//for example, the Move method needs to be locked but this calls the Save method which also needs to be locked.
|
||||
@@ -43,7 +44,8 @@ namespace Umbraco.Core.Services
|
||||
ILogger logger,
|
||||
IEventMessagesFactory eventMessagesFactory,
|
||||
IDataTypeService dataTypeService,
|
||||
IUserService userService)
|
||||
IUserService userService,
|
||||
IdkMap idkMap)
|
||||
: base(provider, repositoryFactory, logger, eventMessagesFactory)
|
||||
{
|
||||
if (dataTypeService == null) throw new ArgumentNullException("dataTypeService");
|
||||
@@ -51,6 +53,7 @@ namespace Umbraco.Core.Services
|
||||
_publishingStrategy = new PublishingStrategy(UowProvider.ScopeProvider, eventMessagesFactory, logger);
|
||||
_dataTypeService = dataTypeService;
|
||||
_userService = userService;
|
||||
_idkMap = idkMap;
|
||||
}
|
||||
|
||||
#region Static Queries
|
||||
@@ -163,7 +166,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(Creating, this, new NewEventArgs<IContent>(content, contentTypeAlias, parentId)))
|
||||
var newEventArgs = new NewEventArgs<IContent>(content, contentTypeAlias, parentId);
|
||||
if (uow.Events.DispatchCancelable(Creating, this, newEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
content.WasCancelled = true;
|
||||
@@ -172,8 +176,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
content.CreatorId = userId;
|
||||
content.WriterId = userId;
|
||||
|
||||
uow.Events.Dispatch(Created, this, new NewEventArgs<IContent>(content, false, contentTypeAlias, parentId));
|
||||
newEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Created, this, newEventArgs);
|
||||
|
||||
Audit(uow, AuditType.New, string.Format("Content '{0}' was created", name), content.CreatorId, content.Id);
|
||||
uow.Commit();
|
||||
@@ -206,7 +210,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(Creating, this, new NewEventArgs<IContent>(content, contentTypeAlias, parent)))
|
||||
var newEventArgs = new NewEventArgs<IContent>(content, contentTypeAlias, parent);
|
||||
if (uow.Events.DispatchCancelable(Creating, this, newEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
content.WasCancelled = true;
|
||||
@@ -215,8 +220,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
content.CreatorId = userId;
|
||||
content.WriterId = userId;
|
||||
|
||||
uow.Events.Dispatch(Created, this, new NewEventArgs<IContent>(content, false, contentTypeAlias, parent));
|
||||
newEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Created, this, newEventArgs);
|
||||
|
||||
Audit(uow, AuditType.New, string.Format("Content '{0}' was created", name), content.CreatorId, content.Id);
|
||||
uow.Commit();
|
||||
@@ -247,14 +252,16 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
//NOTE: I really hate the notion of these Creating/Created events - they are so inconsistent, I've only just found
|
||||
// out that in these 'WithIdentity' methods, the Saving/Saved events were not fired, wtf. Anyways, they're added now.
|
||||
if (uow.Events.DispatchCancelable(Creating, this, new NewEventArgs<IContent>(content, contentTypeAlias, parentId)))
|
||||
var newEventArgs = new NewEventArgs<IContent>(content, contentTypeAlias, parentId);
|
||||
if (uow.Events.DispatchCancelable(Creating, this, newEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
content.WasCancelled = true;
|
||||
return content;
|
||||
}
|
||||
|
||||
if (uow.Events.DispatchCancelable(Saving, this, new SaveEventArgs<IContent>(content)))
|
||||
var saveEventArgs = new SaveEventArgs<IContent>(content);
|
||||
if (uow.Events.DispatchCancelable(Saving, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
content.WasCancelled = true;
|
||||
@@ -267,9 +274,10 @@ namespace Umbraco.Core.Services
|
||||
|
||||
repository.AddOrUpdate(content);
|
||||
repository.AddOrUpdatePreviewXml(content, c => _entitySerializer.Serialize(this, _dataTypeService, _userService, c));
|
||||
|
||||
uow.Events.Dispatch(Saved, this, new SaveEventArgs<IContent>(content, false));
|
||||
uow.Events.Dispatch(Created, this, new NewEventArgs<IContent>(content, false, contentTypeAlias, parentId));
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Saved, this, saveEventArgs);
|
||||
newEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Created, this, newEventArgs);
|
||||
|
||||
Audit(uow, AuditType.New, string.Format("Content '{0}' was created with Id {1}", name, content.Id), content.CreatorId, content.Id);
|
||||
uow.Commit();
|
||||
@@ -302,14 +310,16 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
//NOTE: I really hate the notion of these Creating/Created events - they are so inconsistent, I've only just found
|
||||
// out that in these 'WithIdentity' methods, the Saving/Saved events were not fired, wtf. Anyways, they're added now.
|
||||
if (uow.Events.DispatchCancelable(Creating, this, new NewEventArgs<IContent>(content, contentTypeAlias, parent)))
|
||||
var newEventArgs = new NewEventArgs<IContent>(content, contentTypeAlias, parent);
|
||||
if (uow.Events.DispatchCancelable(Creating, this, newEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
content.WasCancelled = true;
|
||||
return content;
|
||||
}
|
||||
|
||||
if (uow.Events.DispatchCancelable(Saving, this, new SaveEventArgs<IContent>(content)))
|
||||
var saveEventArgs = new SaveEventArgs<IContent>(content);
|
||||
if (uow.Events.DispatchCancelable(Saving, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
content.WasCancelled = true;
|
||||
@@ -322,9 +332,10 @@ namespace Umbraco.Core.Services
|
||||
|
||||
repository.AddOrUpdate(content);
|
||||
repository.AddOrUpdatePreviewXml(content, c => _entitySerializer.Serialize(this, _dataTypeService, _userService, c));
|
||||
|
||||
uow.Events.Dispatch(Saved, this, new SaveEventArgs<IContent>(content, false));
|
||||
uow.Events.Dispatch(Created, this, new NewEventArgs<IContent>(content, false, contentTypeAlias, parent));
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Saved, this, saveEventArgs);
|
||||
newEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Created, this, newEventArgs);
|
||||
|
||||
Audit(uow, AuditType.New, string.Format("Content '{0}' was created with Id {1}", name, content.Id), content.CreatorId, content.Id);
|
||||
uow.Commit();
|
||||
@@ -382,13 +393,13 @@ namespace Umbraco.Core.Services
|
||||
/// <returns><see cref="IContent"/></returns>
|
||||
public IContent GetById(Guid key)
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
|
||||
{
|
||||
var repository = RepositoryFactory.CreateContentRepository(uow);
|
||||
var query = Query<IContent>.Builder.Where(x => x.Key == key);
|
||||
var contents = repository.GetByQuery(query);
|
||||
return contents.SingleOrDefault();
|
||||
}
|
||||
// the repository implements a cache policy on int identifiers, not guids,
|
||||
// and we are not changing it now, but we still would like to rely on caching
|
||||
// instead of running a full query against the database, so relying on the
|
||||
// id-key map, which is fast.
|
||||
|
||||
var a = _idkMap.GetIdForKey(key, UmbracoObjectTypes.Document);
|
||||
return a.Success ? GetById(a.Result) : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1015,14 +1026,16 @@ namespace Umbraco.Core.Services
|
||||
//see: http://issues.umbraco.org/issue/U4-9336
|
||||
content.EnsureValidPath(Logger, entity => GetById(entity.ParentId), QuickUpdate);
|
||||
var originalPath = content.Path;
|
||||
if (uow.Events.DispatchCancelable(Trashing, this, new MoveEventArgs<IContent>(evtMsgs, new MoveEventInfo<IContent>(content, originalPath, Constants.System.RecycleBinContent)), "Trashing"))
|
||||
var moveEventInfo = new MoveEventInfo<IContent>(content, originalPath, Constants.System.RecycleBinContent);
|
||||
var moveEventArgs = new MoveEventArgs<IContent>(evtMsgs, moveEventInfo);
|
||||
if (uow.Events.DispatchCancelable(Trashing, this, moveEventArgs, "Trashing"))
|
||||
{
|
||||
uow.Commit();
|
||||
return OperationStatus.Cancelled(evtMsgs);
|
||||
}
|
||||
var moveInfo = new List<MoveEventInfo<IContent>>
|
||||
{
|
||||
new MoveEventInfo<IContent>(content, originalPath, Constants.System.RecycleBinContent)
|
||||
moveEventInfo
|
||||
};
|
||||
|
||||
//get descendents to process of the content item that is being moved to trash - must be done before changing the state below
|
||||
@@ -1049,11 +1062,13 @@ namespace Umbraco.Core.Services
|
||||
descendant.WriterId = userId;
|
||||
descendant.ChangeTrashedState(true, descendant.ParentId);
|
||||
repository.AddOrUpdate(descendant);
|
||||
|
||||
|
||||
moveInfo.Add(new MoveEventInfo<IContent>(descendant, descendant.Path, descendant.ParentId));
|
||||
}
|
||||
|
||||
uow.Events.Dispatch(Trashed, this, new MoveEventArgs<IContent>(false, evtMsgs, moveInfo.ToArray()), "Trashed");
|
||||
moveEventArgs.CanCancel = false;
|
||||
moveEventArgs.MoveInfoCollection = moveInfo;
|
||||
uow.Events.Dispatch(Trashed, this, moveEventArgs, "Trashed");
|
||||
|
||||
Audit(uow, AuditType.Move, "Move Content to Recycle Bin performed by user", userId, content.Id);
|
||||
uow.Commit();
|
||||
@@ -1180,7 +1195,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (raiseEvents && uow.Events.DispatchCancelable(Saving, this, new SaveEventArgs<IContent>(asArray, evtMsgs)))
|
||||
var saveEventArgs = new SaveEventArgs<IContent>(asArray, evtMsgs);
|
||||
if (raiseEvents && uow.Events.DispatchCancelable(Saving, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return OperationStatus.Cancelled(evtMsgs);
|
||||
@@ -1221,7 +1237,10 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
|
||||
if (raiseEvents)
|
||||
uow.Events.Dispatch(Saved, this, new SaveEventArgs<IContent>(asArray, false, evtMsgs));
|
||||
{
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Saved, this, saveEventArgs);
|
||||
}
|
||||
|
||||
Audit(uow, AuditType.Save, "Bulk Save content performed by user", userId == -1 ? 0 : userId, Constants.System.Root);
|
||||
uow.Commit();
|
||||
@@ -1247,7 +1266,8 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(Deleting, this, new DeleteEventArgs<IContent>(content, evtMsgs), "Deleting"))
|
||||
var deleteEventArgs = new DeleteEventArgs<IContent>(content, evtMsgs);
|
||||
if (uow.Events.DispatchCancelable(Deleting, this, deleteEventArgs, "Deleting"))
|
||||
{
|
||||
uow.Commit();
|
||||
return OperationStatus.Cancelled(evtMsgs);
|
||||
@@ -1270,8 +1290,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
repository.Delete(content);
|
||||
|
||||
var args = new DeleteEventArgs<IContent>(content, false, evtMsgs);
|
||||
uow.Events.Dispatch(Deleted, this, args, "Deleted");
|
||||
deleteEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Deleted, this, deleteEventArgs, "Deleted");
|
||||
|
||||
Audit(uow, AuditType.Delete, "Delete Content performed by user", userId, content.Id);
|
||||
uow.Commit();
|
||||
@@ -1399,7 +1419,8 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(DeletingVersions, this, new DeleteRevisionsEventArgs(id, dateToRetain: versionDate), "DeletingVersions"))
|
||||
var deleteRevisionsEventArgs = new DeleteRevisionsEventArgs(id, dateToRetain: versionDate);
|
||||
if (uow.Events.DispatchCancelable(DeletingVersions, this, deleteRevisionsEventArgs, "DeletingVersions"))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
@@ -1407,8 +1428,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
var repository = RepositoryFactory.CreateContentRepository(uow);
|
||||
repository.DeleteVersions(id, versionDate);
|
||||
|
||||
uow.Events.Dispatch(DeletedVersions, this, new DeleteRevisionsEventArgs(id, false, dateToRetain: versionDate), "DeletedVersions");
|
||||
deleteRevisionsEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(DeletedVersions, this, deleteRevisionsEventArgs, "DeletedVersions");
|
||||
|
||||
Audit(uow, AuditType.Delete, "Delete Content by version date performed by user", userId, Constants.System.Root);
|
||||
uow.Commit();
|
||||
@@ -1487,7 +1508,9 @@ namespace Umbraco.Core.Services
|
||||
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(Moving, this, new MoveEventArgs<IContent>(new MoveEventInfo<IContent>(content, content.Path, parentId)), "Moving"))
|
||||
var moveEventInfo = new MoveEventInfo<IContent>(content, content.Path, parentId);
|
||||
var moveEventArgs = new MoveEventArgs<IContent>(moveEventInfo);
|
||||
if (uow.Events.DispatchCancelable(Moving, this, moveEventArgs, "Moving"))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
@@ -1499,7 +1522,9 @@ namespace Umbraco.Core.Services
|
||||
//call private method that does the recursive moving
|
||||
PerformMove(content, parentId, userId, moveInfo);
|
||||
|
||||
uow.Events.Dispatch(Moved, this, new MoveEventArgs<IContent>(false, moveInfo.ToArray()), "Moved");
|
||||
moveEventArgs.MoveInfoCollection = moveInfo;
|
||||
moveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Moved, this, moveEventArgs, "Moved");
|
||||
|
||||
Audit(uow, AuditType.Move, "Move Content performed by user", userId, content.Id);
|
||||
uow.Commit();
|
||||
@@ -1528,15 +1553,17 @@ namespace Umbraco.Core.Services
|
||||
|
||||
var files = ((ContentRepository)repository).GetFilesInRecycleBinForUploadField();
|
||||
|
||||
if (uow.Events.DispatchCancelable(EmptyingRecycleBin, this, new RecycleBinEventArgs(nodeObjectType, entities, files)))
|
||||
var recycleBinEventArgs = new RecycleBinEventArgs(nodeObjectType, entities, files);
|
||||
if (uow.Events.DispatchCancelable(EmptyingRecycleBin, this, recycleBinEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
}
|
||||
|
||||
var success = repository.EmptyRecycleBin();
|
||||
|
||||
uow.Events.Dispatch(EmptiedRecycleBin, this, new RecycleBinEventArgs(nodeObjectType, entities, files, success));
|
||||
recycleBinEventArgs.CanCancel = false;
|
||||
recycleBinEventArgs.RecycleBinEmptiedSuccessfully = success;
|
||||
uow.Events.Dispatch(EmptiedRecycleBin, this, recycleBinEventArgs);
|
||||
|
||||
Audit(uow, AuditType.Delete, "Empty Content Recycle Bin performed by user", 0, Constants.System.RecycleBinContent);
|
||||
uow.Commit();
|
||||
@@ -1583,7 +1610,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(Copying, this, new CopyEventArgs<IContent>(content, copy, parentId)))
|
||||
var copyEventArgs = new CopyEventArgs<IContent>(content, copy, true, parentId, relateToOriginal);
|
||||
if (uow.Events.DispatchCancelable(Copying, this, copyEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return null;
|
||||
@@ -1624,7 +1652,8 @@ namespace Umbraco.Core.Services
|
||||
Copy(child, copy.Id, relateToOriginal, true, userId);
|
||||
}
|
||||
}
|
||||
uow.Events.Dispatch(Copied, this, new CopyEventArgs<IContent>(content, copy, false, parentId, relateToOriginal));
|
||||
copyEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Copied, this, copyEventArgs);
|
||||
Audit(uow, AuditType.Copy, "Copy Content performed by user", content.WriterId, content.Id);
|
||||
uow.Commit();
|
||||
}
|
||||
@@ -1644,7 +1673,8 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(SendingToPublish, this, new SendToPublishEventArgs<IContent>(content)))
|
||||
var sendToPublishEventArgs = new SendToPublishEventArgs<IContent>(content);
|
||||
if (uow.Events.DispatchCancelable(SendingToPublish, this, sendToPublishEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return false;
|
||||
@@ -1652,8 +1682,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
//Save before raising event
|
||||
Save(content, userId);
|
||||
|
||||
uow.Events.Dispatch(SentToPublish, this, new SendToPublishEventArgs<IContent>(content, false));
|
||||
sendToPublishEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(SentToPublish, this, sendToPublishEventArgs);
|
||||
|
||||
Audit(uow, AuditType.SendToPublish, "Send to Publish performed by user", content.WriterId, content.Id);
|
||||
uow.Commit();
|
||||
@@ -1680,7 +1710,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(RollingBack, this, new RollbackEventArgs<IContent>(content)))
|
||||
var rollbackEventArgs = new RollbackEventArgs<IContent>(content);
|
||||
if (uow.Events.DispatchCancelable(RollingBack, this, rollbackEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return content;
|
||||
@@ -1694,8 +1725,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
repository.AddOrUpdate(content);
|
||||
repository.AddOrUpdatePreviewXml(content, c => _entitySerializer.Serialize(this, _dataTypeService, _userService, c));
|
||||
|
||||
uow.Events.Dispatch(RolledBack, this, new RollbackEventArgs<IContent>(content, false));
|
||||
rollbackEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(RolledBack, this, rollbackEventArgs);
|
||||
|
||||
Audit(uow, AuditType.RollBack, "Content rollback performed by user", content.WriterId, content.Id);
|
||||
uow.Commit();
|
||||
@@ -1726,7 +1757,8 @@ namespace Umbraco.Core.Services
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
var asArray = items.ToArray();
|
||||
if (raiseEvents && uow.Events.DispatchCancelable(Saving, this, new SaveEventArgs<IContent>(asArray)))
|
||||
var saveEventArgs = new SaveEventArgs<IContent>(asArray);
|
||||
if (raiseEvents && uow.Events.DispatchCancelable(Saving, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return false;
|
||||
@@ -1771,7 +1803,10 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
|
||||
if (raiseEvents)
|
||||
uow.Events.Dispatch(Saved, this, new SaveEventArgs<IContent>(asArray, false));
|
||||
{
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Saved, this, saveEventArgs);
|
||||
}
|
||||
|
||||
if (shouldBePublished.Any())
|
||||
{
|
||||
@@ -2135,7 +2170,8 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (raiseEvents && uow.Events.DispatchCancelable(Saving, this, new SaveEventArgs<IContent>(content, evtMsgs)))
|
||||
var saveEventArgs = new SaveEventArgs<IContent>(content, evtMsgs);
|
||||
if (raiseEvents && uow.Events.DispatchCancelable(Saving, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return Attempt.Fail(new PublishStatus(content, PublishStatusType.FailedCancelledByEvent, evtMsgs));
|
||||
@@ -2190,7 +2226,10 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
|
||||
if (raiseEvents)
|
||||
uow.Events.Dispatch(Saved, this, new SaveEventArgs<IContent>(content, false, evtMsgs));
|
||||
{
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Saved, this, saveEventArgs);
|
||||
}
|
||||
|
||||
//Save xml to db and call following method to fire event through PublishingStrategy to update cache
|
||||
if (published)
|
||||
@@ -2229,7 +2268,8 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (raiseEvents && uow.Events.DispatchCancelable(Saving, this, new SaveEventArgs<IContent>(content, evtMsgs)))
|
||||
var saveEventArgs = new SaveEventArgs<IContent>(content, evtMsgs);
|
||||
if (raiseEvents && uow.Events.DispatchCancelable(Saving, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return OperationStatus.Cancelled(evtMsgs);
|
||||
@@ -2258,7 +2298,10 @@ namespace Umbraco.Core.Services
|
||||
repository.AddOrUpdatePreviewXml(content, c => _entitySerializer.Serialize(this, _dataTypeService, _userService, c));
|
||||
|
||||
if (raiseEvents)
|
||||
uow.Events.Dispatch(Saved, this, new SaveEventArgs<IContent>(content, false, evtMsgs));
|
||||
{
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Saved, this, saveEventArgs);
|
||||
}
|
||||
|
||||
Audit(uow, AuditType.Save, "Save Content performed by user", userId, content.Id);
|
||||
uow.Commit();
|
||||
|
||||
@@ -54,7 +54,8 @@ namespace Umbraco.Core.Services
|
||||
CreatorId = userId
|
||||
};
|
||||
|
||||
if (uow.Events.DispatchCancelable(SavingContentTypeContainer, this, new SaveEventArgs<EntityContainer>(container, evtMsgs)))
|
||||
var saveEventArgs = new SaveEventArgs<EntityContainer>(container, evtMsgs);
|
||||
if (uow.Events.DispatchCancelable(SavingContentTypeContainer, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return Attempt.Fail(new OperationStatus<EntityContainer, OperationStatusType>(container, OperationStatusType.FailedCancelledByEvent, evtMsgs));
|
||||
@@ -62,8 +63,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
repo.AddOrUpdate(container);
|
||||
uow.Commit();
|
||||
|
||||
uow.Events.Dispatch(SavedContentTypeContainer, this, new SaveEventArgs<EntityContainer>(container, evtMsgs), "SavedContentTypeContainer");
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(SavedContentTypeContainer, this, saveEventArgs, "SavedContentTypeContainer");
|
||||
//TODO: Audit trail ?
|
||||
|
||||
return Attempt.Succeed(new OperationStatus<EntityContainer, OperationStatusType>(container, OperationStatusType.Success, evtMsgs));
|
||||
@@ -92,7 +93,8 @@ namespace Umbraco.Core.Services
|
||||
CreatorId = userId
|
||||
};
|
||||
|
||||
if (uow.Events.DispatchCancelable(SavingMediaTypeContainer, this, new SaveEventArgs<EntityContainer>(container, evtMsgs)))
|
||||
var saveEventArgs = new SaveEventArgs<EntityContainer>(container, evtMsgs);
|
||||
if (uow.Events.DispatchCancelable(SavingMediaTypeContainer, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return Attempt.Fail(new OperationStatus<EntityContainer, OperationStatusType>(container, OperationStatusType.FailedCancelledByEvent, evtMsgs));
|
||||
@@ -100,8 +102,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
repo.AddOrUpdate(container);
|
||||
uow.Commit();
|
||||
|
||||
uow.Events.Dispatch(SavedMediaTypeContainer, this, new SaveEventArgs<EntityContainer>(container, evtMsgs), "SavedMediaTypeContainer");
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(SavedMediaTypeContainer, this, saveEventArgs, "SavedMediaTypeContainer");
|
||||
//TODO: Audit trail ?
|
||||
|
||||
return Attempt.Succeed(new OperationStatus<EntityContainer, OperationStatusType>(container, OperationStatusType.Success, evtMsgs));
|
||||
@@ -289,7 +291,8 @@ namespace Umbraco.Core.Services
|
||||
return OperationStatus.NoOperation(evtMsgs);
|
||||
}
|
||||
|
||||
if (uow.Events.DispatchCancelable(DeletingContentTypeContainer, this, new DeleteEventArgs<EntityContainer>(container, evtMsgs)))
|
||||
var deleteEventArgs = new DeleteEventArgs<EntityContainer>(container, evtMsgs);
|
||||
if (uow.Events.DispatchCancelable(DeletingContentTypeContainer, this, deleteEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return Attempt.Fail(new OperationStatus(OperationStatusType.FailedCancelledByEvent, evtMsgs));
|
||||
@@ -297,8 +300,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
repo.Delete(container);
|
||||
uow.Commit();
|
||||
|
||||
uow.Events.Dispatch(DeletedContentTypeContainer, this, new DeleteEventArgs<EntityContainer>(container, evtMsgs), "DeletedContentTypeContainer");
|
||||
deleteEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(DeletedContentTypeContainer, this, deleteEventArgs, "DeletedContentTypeContainer");
|
||||
|
||||
return OperationStatus.Success(evtMsgs);
|
||||
//TODO: Audit trail ?
|
||||
@@ -319,7 +322,8 @@ namespace Umbraco.Core.Services
|
||||
return OperationStatus.NoOperation(evtMsgs);
|
||||
}
|
||||
|
||||
if (uow.Events.DispatchCancelable(DeletingMediaTypeContainer, this, new DeleteEventArgs<EntityContainer>(container, evtMsgs)))
|
||||
var deleteEventArgs = new DeleteEventArgs<EntityContainer>(container, evtMsgs);
|
||||
if (uow.Events.DispatchCancelable(DeletingMediaTypeContainer, this, deleteEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return Attempt.Fail(new OperationStatus(OperationStatusType.FailedCancelledByEvent, evtMsgs));
|
||||
@@ -327,8 +331,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
repo.Delete(container);
|
||||
uow.Commit();
|
||||
|
||||
uow.Events.Dispatch(DeletedMediaTypeContainer, this, new DeleteEventArgs<EntityContainer>(container, evtMsgs));
|
||||
deleteEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(DeletedMediaTypeContainer, this, deleteEventArgs);
|
||||
|
||||
return OperationStatus.Success(evtMsgs);
|
||||
//TODO: Audit trail ?
|
||||
@@ -756,7 +760,8 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(SavingContentType, this, new SaveEventArgs<IContentType>(contentType)))
|
||||
var saveEventArgs = new SaveEventArgs<IContentType>(contentType);
|
||||
if (uow.Events.DispatchCancelable(SavingContentType, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
@@ -779,7 +784,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
UpdateContentXmlStructure(contentType);
|
||||
|
||||
uow.Events.Dispatch(SavedContentType, this, new SaveEventArgs<IContentType>(contentType, false));
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(SavedContentType, this, saveEventArgs);
|
||||
|
||||
Audit(uow, AuditType.Save, "Save ContentType performed by user", userId, contentType.Id);
|
||||
uow.Commit();
|
||||
@@ -800,7 +806,8 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(SavingContentType, this, new SaveEventArgs<IContentType>(asArray)))
|
||||
var saveEventArgs = new SaveEventArgs<IContentType>(asArray);
|
||||
if (uow.Events.DispatchCancelable(SavingContentType, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
@@ -825,7 +832,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
UpdateContentXmlStructure(asArray.Cast<IContentTypeBase>().ToArray());
|
||||
|
||||
uow.Events.Dispatch(SavedContentType, this, new SaveEventArgs<IContentType>(asArray, false));
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(SavedContentType, this, saveEventArgs);
|
||||
|
||||
Audit(uow, AuditType.Save, "Save ContentTypes performed by user", userId, -1);
|
||||
uow.Commit();
|
||||
@@ -845,7 +853,8 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(DeletingContentType, this, new DeleteEventArgs<IContentType>(contentType)))
|
||||
var deleteEventArgs = new DeleteEventArgs<IContentType>(contentType);
|
||||
if (uow.Events.DispatchCancelable(DeletingContentType, this, deleteEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
@@ -860,8 +869,9 @@ namespace Umbraco.Core.Services
|
||||
_contentService.DeleteContentOfTypes(deletedContentTypes.Select(x => x.Id), userId);
|
||||
|
||||
repository.Delete(contentType);
|
||||
|
||||
uow.Events.Dispatch(DeletedContentType, this, new DeleteEventArgs<IContentType>(deletedContentTypes.DistinctBy(x => x.Id), false));
|
||||
deleteEventArgs.DeletedEntities = deletedContentTypes.DistinctBy(x => x.Id);
|
||||
deleteEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(DeletedContentType, this, deleteEventArgs);
|
||||
|
||||
Audit(uow, AuditType.Delete, string.Format("Delete ContentType performed by user"), userId, contentType.Id);
|
||||
uow.Commit();
|
||||
@@ -885,7 +895,8 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(DeletingContentType, this, new DeleteEventArgs<IContentType>(asArray)))
|
||||
var deleteEventArgs = new DeleteEventArgs<IContentType>(asArray);
|
||||
if (uow.Events.DispatchCancelable(DeletingContentType, this, deleteEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
@@ -906,8 +917,9 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
repository.Delete(contentType);
|
||||
}
|
||||
|
||||
uow.Events.Dispatch(DeletedContentType, this, new DeleteEventArgs<IContentType>(deletedContentTypes.DistinctBy(x => x.Id), false));
|
||||
deleteEventArgs.DeletedEntities = deletedContentTypes.DistinctBy(x => x.Id);
|
||||
deleteEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(DeletedContentType, this, deleteEventArgs);
|
||||
|
||||
Audit(uow, AuditType.Delete, string.Format("Delete ContentTypes performed by user"), userId, -1);
|
||||
uow.Commit();
|
||||
@@ -1056,7 +1068,9 @@ namespace Umbraco.Core.Services
|
||||
var moveInfo = new List<MoveEventInfo<IMediaType>>();
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(MovingMediaType, this, new MoveEventArgs<IMediaType>(evtMsgs, new MoveEventInfo<IMediaType>(toMove, toMove.Path, containerId))))
|
||||
var moveEventInfo = new MoveEventInfo<IMediaType>(toMove, toMove.Path, containerId);
|
||||
var moveEventArgs = new MoveEventArgs<IMediaType>(evtMsgs, moveEventInfo);
|
||||
if (uow.Events.DispatchCancelable(MovingMediaType, this, moveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return Attempt.Fail(new OperationStatus<MoveOperationStatusType>(MoveOperationStatusType.FailedCancelledByEvent, evtMsgs));
|
||||
@@ -1081,7 +1095,9 @@ namespace Umbraco.Core.Services
|
||||
return Attempt.Fail(new OperationStatus<MoveOperationStatusType>(ex.Operation, evtMsgs));
|
||||
}
|
||||
uow.Commit();
|
||||
uow.Events.Dispatch(MovedMediaType, this, new MoveEventArgs<IMediaType>(false, evtMsgs, moveInfo.ToArray()));
|
||||
moveEventArgs.MoveInfoCollection = moveInfo;
|
||||
moveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(MovedMediaType, this, moveEventArgs);
|
||||
}
|
||||
|
||||
return Attempt.Succeed(
|
||||
@@ -1095,7 +1111,9 @@ namespace Umbraco.Core.Services
|
||||
var moveInfo = new List<MoveEventInfo<IContentType>>();
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(MovingContentType, this, new MoveEventArgs<IContentType>(evtMsgs, new MoveEventInfo<IContentType>(toMove, toMove.Path, containerId))))
|
||||
var moveEventInfo = new MoveEventInfo<IContentType>(toMove, toMove.Path, containerId);
|
||||
var moveEventArgs = new MoveEventArgs<IContentType>(evtMsgs, moveEventInfo);
|
||||
if (uow.Events.DispatchCancelable(MovingContentType, this, moveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return Attempt.Fail(new OperationStatus<MoveOperationStatusType>(MoveOperationStatusType.FailedCancelledByEvent, evtMsgs));
|
||||
@@ -1119,8 +1137,10 @@ namespace Umbraco.Core.Services
|
||||
uow.Commit();
|
||||
return Attempt.Fail(new OperationStatus<MoveOperationStatusType>(ex.Operation, evtMsgs));
|
||||
}
|
||||
moveEventArgs.MoveInfoCollection = moveInfo;
|
||||
moveEventArgs.CanCancel = false;
|
||||
uow.Commit();
|
||||
uow.Events.Dispatch(MovedContentType, this, new MoveEventArgs<IContentType>(false, evtMsgs, moveInfo.ToArray()));
|
||||
uow.Events.Dispatch(MovedContentType, this, moveEventArgs);
|
||||
}
|
||||
|
||||
return Attempt.Succeed(
|
||||
@@ -1228,7 +1248,8 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(SavingMediaType, this, new SaveEventArgs<IMediaType>(mediaType)))
|
||||
var saveEventArgs = new SaveEventArgs<IMediaType>(mediaType);
|
||||
if (uow.Events.DispatchCancelable(SavingMediaType, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
@@ -1244,8 +1265,8 @@ namespace Umbraco.Core.Services
|
||||
uow.Commit();
|
||||
|
||||
UpdateContentXmlStructure(mediaType);
|
||||
|
||||
uow.Events.Dispatch(SavedMediaType, this, new SaveEventArgs<IMediaType>(mediaType, false));
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(SavedMediaType, this, saveEventArgs);
|
||||
|
||||
Audit(uow, AuditType.Save, "Save MediaType performed by user", userId, mediaType.Id);
|
||||
uow.Commit();
|
||||
@@ -1266,7 +1287,8 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(SavingMediaType, this, new SaveEventArgs<IMediaType>(asArray)))
|
||||
var saveEventArgs = new SaveEventArgs<IMediaType>(asArray);
|
||||
if (uow.Events.DispatchCancelable(SavingMediaType, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
@@ -1290,8 +1312,8 @@ namespace Umbraco.Core.Services
|
||||
uow.Commit();
|
||||
|
||||
UpdateContentXmlStructure(asArray.Cast<IContentTypeBase>().ToArray());
|
||||
|
||||
uow.Events.Dispatch(SavedMediaType, this, new SaveEventArgs<IMediaType>(asArray, false));
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(SavedMediaType, this, saveEventArgs);
|
||||
|
||||
Audit(uow, AuditType.Save, "Save MediaTypes performed by user", userId, -1);
|
||||
uow.Commit();
|
||||
@@ -1313,7 +1335,8 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(DeletingMediaType, this, new DeleteEventArgs<IMediaType>(mediaType)))
|
||||
var deleteEventArgs = new DeleteEventArgs<IMediaType>(mediaType);
|
||||
if (uow.Events.DispatchCancelable(DeletingMediaType, this, deleteEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
@@ -1329,7 +1352,9 @@ namespace Umbraco.Core.Services
|
||||
|
||||
repository.Delete(mediaType);
|
||||
|
||||
uow.Events.Dispatch(DeletedMediaType, this, new DeleteEventArgs<IMediaType>(deletedMediaTypes.DistinctBy(x => x.Id), false));
|
||||
deleteEventArgs.CanCancel = false;
|
||||
deleteEventArgs.DeletedEntities = deletedMediaTypes.DistinctBy(x => x.Id);
|
||||
uow.Events.Dispatch(DeletedMediaType, this, deleteEventArgs);
|
||||
|
||||
Audit(uow, AuditType.Delete, "Delete MediaType performed by user", userId, mediaType.Id);
|
||||
uow.Commit();
|
||||
@@ -1353,7 +1378,8 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(DeletingMediaType, this, new DeleteEventArgs<IMediaType>(asArray)))
|
||||
var deleteEventArgs = new DeleteEventArgs<IMediaType>(asArray);
|
||||
if (uow.Events.DispatchCancelable(DeletingMediaType, this, deleteEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
@@ -1375,7 +1401,9 @@ namespace Umbraco.Core.Services
|
||||
repository.Delete(mediaType);
|
||||
}
|
||||
|
||||
uow.Events.Dispatch(DeletedMediaType, this, new DeleteEventArgs<IMediaType>(deletedMediaTypes.DistinctBy(x => x.Id), false));
|
||||
deleteEventArgs.DeletedEntities = deletedMediaTypes.DistinctBy(x => x.Id);
|
||||
deleteEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(DeletedMediaType, this, deleteEventArgs);
|
||||
|
||||
Audit(uow, AuditType.Delete, "Delete MediaTypes performed by user", userId, -1);
|
||||
uow.Commit();
|
||||
|
||||
@@ -312,7 +312,9 @@ namespace Umbraco.Core.Services
|
||||
var moveInfo = new List<MoveEventInfo<IDataTypeDefinition>>();
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(Moving, this, new MoveEventArgs<IDataTypeDefinition>(evtMsgs, new MoveEventInfo<IDataTypeDefinition>(toMove, toMove.Path, parentId))))
|
||||
var moveEventInfo = new MoveEventInfo<IDataTypeDefinition>(toMove, toMove.Path, parentId);
|
||||
var moveEventArgs = new MoveEventArgs<IDataTypeDefinition>(evtMsgs, moveEventInfo);
|
||||
if (uow.Events.DispatchCancelable(Moving, this, moveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return Attempt.Fail(new OperationStatus<MoveOperationStatusType>(MoveOperationStatusType.FailedCancelledByEvent, evtMsgs));
|
||||
@@ -338,7 +340,9 @@ namespace Umbraco.Core.Services
|
||||
new OperationStatus<MoveOperationStatusType>(ex.Operation, evtMsgs));
|
||||
}
|
||||
uow.Commit();
|
||||
uow.Events.Dispatch(Moved, this, new MoveEventArgs<IDataTypeDefinition>(false, evtMsgs, moveInfo.ToArray()));
|
||||
moveEventArgs.MoveInfoCollection = moveInfo;
|
||||
moveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Moved, this, moveEventArgs);
|
||||
}
|
||||
|
||||
return Attempt.Succeed(
|
||||
@@ -354,7 +358,8 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(Saving, this, new SaveEventArgs<IDataTypeDefinition>(dataTypeDefinition)))
|
||||
var saveEventArgs = new SaveEventArgs<IDataTypeDefinition>(dataTypeDefinition);
|
||||
if (uow.Events.DispatchCancelable(Saving, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
@@ -369,8 +374,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
dataTypeDefinition.CreatorId = userId;
|
||||
repository.AddOrUpdate(dataTypeDefinition);
|
||||
|
||||
uow.Events.Dispatch(Saved, this, new SaveEventArgs<IDataTypeDefinition>(dataTypeDefinition, false));
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Saved, this, saveEventArgs);
|
||||
|
||||
Audit(uow, AuditType.Save, "Save DataTypeDefinition performed by user", userId, dataTypeDefinition.Id);
|
||||
uow.Commit();
|
||||
@@ -397,9 +402,10 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
var saveEventArgs = new SaveEventArgs<IDataTypeDefinition>(dataTypeDefinitions);
|
||||
if (raiseEvents)
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(Saving, this, new SaveEventArgs<IDataTypeDefinition>(dataTypeDefinitions)))
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(Saving, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
@@ -415,7 +421,10 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
|
||||
if (raiseEvents)
|
||||
uow.Events.Dispatch(Saved, this, new SaveEventArgs<IDataTypeDefinition>(dataTypeDefinitions, false));
|
||||
{
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Saved, this, saveEventArgs);
|
||||
}
|
||||
|
||||
Audit(uow, AuditType.Save, string.Format("Save DataTypeDefinition performed by user"), userId, -1);
|
||||
uow.Commit();
|
||||
@@ -504,7 +513,8 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(Saving, this, new SaveEventArgs<IDataTypeDefinition>(dataTypeDefinition)))
|
||||
var saveEventArgs = new SaveEventArgs<IDataTypeDefinition>(dataTypeDefinition);
|
||||
if (uow.Events.DispatchCancelable(Saving, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
@@ -526,8 +536,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
Audit(uow, AuditType.Save, string.Format("Save DataTypeDefinition performed by user"), userId, dataTypeDefinition.Id);
|
||||
uow.Commit();
|
||||
|
||||
uow.Events.Dispatch(Saved, this, new SaveEventArgs<IDataTypeDefinition>(dataTypeDefinition, false));
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Saved, this, saveEventArgs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -544,7 +554,8 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(Deleting, this, new DeleteEventArgs<IDataTypeDefinition>(dataTypeDefinition)))
|
||||
var deleteEventArgs = new DeleteEventArgs<IDataTypeDefinition>(dataTypeDefinition);
|
||||
if (uow.Events.DispatchCancelable(Deleting, this, deleteEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
@@ -556,8 +567,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
Audit(uow, AuditType.Delete, "Delete DataTypeDefinition performed by user", userId, dataTypeDefinition.Id);
|
||||
uow.Commit();
|
||||
|
||||
uow.Events.Dispatch(Deleted, this, new DeleteEventArgs<IDataTypeDefinition>(dataTypeDefinition, false));
|
||||
deleteEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Deleted, this, deleteEventArgs);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(Deleting, this, new DeleteEventArgs<IDomain>(domain, evtMsgs)))
|
||||
var deleteEventArgs = new DeleteEventArgs<IDomain>(domain, evtMsgs);
|
||||
if (uow.Events.DispatchCancelable(Deleting, this, deleteEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return OperationStatus.Cancelled(evtMsgs);
|
||||
@@ -42,8 +43,8 @@ namespace Umbraco.Core.Services
|
||||
repository.Delete(domain);
|
||||
uow.Commit();
|
||||
|
||||
var args = new DeleteEventArgs<IDomain>(domain, false, evtMsgs);
|
||||
uow.Events.Dispatch(Deleted, this, args);
|
||||
deleteEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Deleted, this, deleteEventArgs);
|
||||
return OperationStatus.Success(evtMsgs);
|
||||
}
|
||||
|
||||
@@ -92,7 +93,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(Saving, this, new SaveEventArgs<IDomain>(domainEntity, evtMsgs)))
|
||||
var saveEventArgs = new SaveEventArgs<IDomain>(domainEntity, evtMsgs);
|
||||
if (uow.Events.DispatchCancelable(Saving, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return OperationStatus.Cancelled(evtMsgs);
|
||||
@@ -101,7 +103,8 @@ namespace Umbraco.Core.Services
|
||||
var repository = RepositoryFactory.CreateDomainRepository(uow);
|
||||
repository.AddOrUpdate(domainEntity);
|
||||
uow.Commit();
|
||||
uow.Events.Dispatch(Saved, this, new SaveEventArgs<IDomain>(domainEntity, false, evtMsgs));
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Saved, this, saveEventArgs);
|
||||
return OperationStatus.Success(evtMsgs);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,50 +16,26 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
public class EntityService : ScopeRepositoryService, IEntityService
|
||||
{
|
||||
private readonly IRuntimeCacheProvider _runtimeCache;
|
||||
private readonly Dictionary<string, Tuple<UmbracoObjectTypes, Func<int, IUmbracoEntity>>> _supportedObjectTypes;
|
||||
|
||||
private readonly IdkMap _idkMap;
|
||||
|
||||
public EntityService(IDatabaseUnitOfWorkProvider provider, RepositoryFactory repositoryFactory, ILogger logger, IEventMessagesFactory eventMessagesFactory,
|
||||
IContentService contentService, IContentTypeService contentTypeService, IMediaService mediaService, IDataTypeService dataTypeService,
|
||||
IMemberService memberService, IMemberTypeService memberTypeService, IRuntimeCacheProvider runtimeCache)
|
||||
IMemberService memberService, IMemberTypeService memberTypeService, IdkMap idkMap)
|
||||
: base(provider, repositoryFactory, logger, eventMessagesFactory)
|
||||
{
|
||||
_runtimeCache = runtimeCache;
|
||||
IContentTypeService contentTypeService1 = contentTypeService;
|
||||
_idkMap = idkMap;
|
||||
|
||||
_supportedObjectTypes = new Dictionary<string, Tuple<UmbracoObjectTypes, Func<int, IUmbracoEntity>>>
|
||||
{
|
||||
{typeof (IDataTypeDefinition).FullName, new Tuple<UmbracoObjectTypes, Func<int, IUmbracoEntity>>(UmbracoObjectTypes.DataType, dataTypeService.GetDataTypeDefinitionById)},
|
||||
{typeof (IContent).FullName, new Tuple<UmbracoObjectTypes, Func<int, IUmbracoEntity>>(UmbracoObjectTypes.Document, contentService.GetById)},
|
||||
{typeof (IContentType).FullName, new Tuple<UmbracoObjectTypes, Func<int, IUmbracoEntity>>(UmbracoObjectTypes.DocumentType, contentTypeService1.GetContentType)},
|
||||
{typeof (IContentType).FullName, new Tuple<UmbracoObjectTypes, Func<int, IUmbracoEntity>>(UmbracoObjectTypes.DocumentType, contentTypeService.GetContentType)},
|
||||
{typeof (IMedia).FullName, new Tuple<UmbracoObjectTypes, Func<int, IUmbracoEntity>>(UmbracoObjectTypes.Media, mediaService.GetById)},
|
||||
{typeof (IMediaType).FullName, new Tuple<UmbracoObjectTypes, Func<int, IUmbracoEntity>>(UmbracoObjectTypes.MediaType, contentTypeService1.GetMediaType)},
|
||||
{typeof (IMediaType).FullName, new Tuple<UmbracoObjectTypes, Func<int, IUmbracoEntity>>(UmbracoObjectTypes.MediaType, contentTypeService.GetMediaType)},
|
||||
{typeof (IMember).FullName, new Tuple<UmbracoObjectTypes, Func<int, IUmbracoEntity>>(UmbracoObjectTypes.Member, memberService.GetById)},
|
||||
{typeof (IMemberType).FullName, new Tuple<UmbracoObjectTypes, Func<int, IUmbracoEntity>>(UmbracoObjectTypes.MemberType, memberTypeService.Get)},
|
||||
//{typeof (IUmbracoEntity).FullName, new Tuple<UmbracoObjectTypes, Func<int, IUmbracoEntity>>(UmbracoObjectTypes.EntityContainer, id =>
|
||||
//{
|
||||
// using (var uow = UowProvider.GetUnitOfWork())
|
||||
// {
|
||||
// var found = uow.Database.FirstOrDefault<NodeDto>("SELECT * FROM umbracoNode WHERE id=@id", new { id = id });
|
||||
// return found == null ? null : new UmbracoEntity(found.Trashed)
|
||||
// {
|
||||
// Id = found.NodeId,
|
||||
// Name = found.Text,
|
||||
// Key = found.UniqueId,
|
||||
// SortOrder = found.SortOrder,
|
||||
// Path = found.Path,
|
||||
// NodeObjectTypeId = found.NodeObjectType.Value,
|
||||
// CreateDate = found.CreateDate,
|
||||
// CreatorId = found.UserId.Value,
|
||||
// Level = found.Level,
|
||||
// ParentId = found.ParentId
|
||||
// };
|
||||
// }
|
||||
|
||||
//})}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#region Static Queries
|
||||
@@ -68,6 +44,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
#endregion
|
||||
|
||||
internal IdkMap IdkMap { get { return _idkMap; } }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the integer id for a given GUID
|
||||
/// </summary>
|
||||
@@ -76,33 +54,12 @@ namespace Umbraco.Core.Services
|
||||
/// <returns></returns>
|
||||
public Attempt<int> GetIdForKey(Guid key, UmbracoObjectTypes umbracoObjectType)
|
||||
{
|
||||
var result = _runtimeCache.GetCacheItem<int?>(CacheKeys.IdToKeyCacheKey + key, () =>
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork(readOnly:true))
|
||||
{
|
||||
var nodeObjectType = GetNodeObjectTypeGuid(umbracoObjectType);
|
||||
|
||||
var sql = new Sql()
|
||||
.Select("id")
|
||||
.From<NodeDto>()
|
||||
.Where<NodeDto>(
|
||||
dto =>
|
||||
dto.UniqueId == key &&
|
||||
dto.NodeObjectType == nodeObjectType);
|
||||
return uow.Database.ExecuteScalar<int?>(sql);
|
||||
}
|
||||
});
|
||||
return result.HasValue ? Attempt.Succeed(result.Value) : Attempt<int>.Fail();
|
||||
return _idkMap.GetIdForKey(key, umbracoObjectType);
|
||||
}
|
||||
|
||||
public Attempt<int> GetIdForUdi(Udi udi)
|
||||
{
|
||||
var guidUdi = udi as GuidUdi;
|
||||
if (guidUdi == null)
|
||||
return Attempt<int>.Fail();
|
||||
|
||||
var umbracoType = Constants.UdiEntityType.ToUmbracoObjectType(guidUdi.EntityType);
|
||||
return GetIdForKey(guidUdi.Guid, umbracoType);
|
||||
return _idkMap.GetIdForUdi(udi);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -113,32 +70,7 @@ namespace Umbraco.Core.Services
|
||||
/// <returns></returns>
|
||||
public Attempt<Guid> GetKeyForId(int id, UmbracoObjectTypes umbracoObjectType)
|
||||
{
|
||||
var result = _runtimeCache.GetCacheItem<Guid?>(CacheKeys.KeyToIdCacheKey + id, () =>
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork(readOnly:true))
|
||||
{
|
||||
var nodeObjectType = GetNodeObjectTypeGuid(umbracoObjectType);
|
||||
|
||||
var sql = new Sql()
|
||||
.Select("uniqueID")
|
||||
.From<NodeDto>()
|
||||
.Where<NodeDto>(
|
||||
dto =>
|
||||
dto.NodeId == id &&
|
||||
dto.NodeObjectType == nodeObjectType);
|
||||
return uow.Database.ExecuteScalar<Guid?>(sql);
|
||||
}
|
||||
});
|
||||
return result.HasValue ? Attempt.Succeed(result.Value) : Attempt<Guid>.Fail();
|
||||
}
|
||||
|
||||
private static Guid GetNodeObjectTypeGuid(UmbracoObjectTypes umbracoObjectType)
|
||||
{
|
||||
var guid = umbracoObjectType.GetGuid();
|
||||
if (guid == Guid.Empty)
|
||||
throw new NotSupportedException("Unsupported object type (" + umbracoObjectType + ").");
|
||||
|
||||
return guid;
|
||||
return _idkMap.GetKeyForId(id, umbracoObjectType);
|
||||
}
|
||||
|
||||
public IUmbracoEntity GetByKey(Guid key, bool loadBaseType = true)
|
||||
@@ -404,7 +336,7 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="totalRecords"></param>
|
||||
/// <param name="orderBy"></param>
|
||||
/// <param name="orderDirection"></param>
|
||||
/// <param name="filter"></param>
|
||||
/// <param name="filter"></param>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<IUmbracoEntity> GetPagedDescendants(int id, UmbracoObjectTypes umbracoObjectType, long pageIndex, int pageSize, out long totalRecords,
|
||||
string orderBy = "path", Direction orderDirection = Direction.Ascending, string filter = "")
|
||||
@@ -417,7 +349,7 @@ namespace Umbraco.Core.Services
|
||||
var query = Query<IUmbracoEntity>.Builder;
|
||||
//if the id is System Root, then just get all
|
||||
if (id != Constants.System.Root)
|
||||
query.Where(x => x.Path.SqlContains(string.Format(",{0},", id), TextColumnType.NVarchar));
|
||||
query.Where(x => x.Path.SqlContains(string.Format(",{0},", id), TextColumnType.NVarchar));
|
||||
|
||||
IQuery<IUmbracoEntity> filterQuery = null;
|
||||
if (filter.IsNullOrWhiteSpace() == false)
|
||||
|
||||
@@ -70,7 +70,8 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(SavingStylesheet, this, new SaveEventArgs<Stylesheet>(stylesheet)))
|
||||
var saveEventArgs = new SaveEventArgs<Stylesheet>(stylesheet);
|
||||
if (uow.Events.DispatchCancelable(SavingStylesheet, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
@@ -78,8 +79,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
var repository = RepositoryFactory.CreateStylesheetRepository(uow);
|
||||
repository.AddOrUpdate(stylesheet);
|
||||
|
||||
uow.Events.Dispatch(SavedStylesheet, this, new SaveEventArgs<Stylesheet>(stylesheet, false));
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(SavedStylesheet, this, saveEventArgs);
|
||||
|
||||
Audit(uow, AuditType.Save, "Save Stylesheet performed by user", userId, -1);
|
||||
uow.Commit();
|
||||
@@ -103,15 +104,16 @@ namespace Umbraco.Core.Services
|
||||
return;
|
||||
}
|
||||
|
||||
if (uow.Events.DispatchCancelable(DeletingStylesheet, this, new DeleteEventArgs<Stylesheet>(stylesheet)))
|
||||
var deleteEventArgs = new DeleteEventArgs<Stylesheet>(stylesheet);
|
||||
if (uow.Events.DispatchCancelable(DeletingStylesheet, this, deleteEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
}
|
||||
|
||||
repository.Delete(stylesheet);
|
||||
|
||||
uow.Events.Dispatch(DeletedStylesheet, this, new DeleteEventArgs<Stylesheet>(stylesheet, false));
|
||||
deleteEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(DeletedStylesheet, this, deleteEventArgs);
|
||||
|
||||
Audit(uow, AuditType.Delete, string.Format("Delete Stylesheet performed by user"), userId, -1);
|
||||
uow.Commit();
|
||||
@@ -171,7 +173,8 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(SavingScript, this, new SaveEventArgs<Script>(script)))
|
||||
var saveEventArgs = new SaveEventArgs<Script>(script);
|
||||
if (uow.Events.DispatchCancelable(SavingScript, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
@@ -179,8 +182,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
var repository = RepositoryFactory.CreateScriptRepository(uow);
|
||||
repository.AddOrUpdate(script);
|
||||
|
||||
uow.Events.Dispatch(SavedScript, this, new SaveEventArgs<Script>(script, false));
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(SavedScript, this, saveEventArgs);
|
||||
|
||||
Audit(uow, AuditType.Save, "Save Script performed by user", userId, -1);
|
||||
uow.Commit();
|
||||
@@ -204,15 +207,16 @@ namespace Umbraco.Core.Services
|
||||
return;
|
||||
}
|
||||
|
||||
if (uow.Events.DispatchCancelable(DeletingScript, this, new DeleteEventArgs<Script>(script)))
|
||||
var deleteEventArgs = new DeleteEventArgs<Script>(script);
|
||||
if (uow.Events.DispatchCancelable(DeletingScript, this, deleteEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
}
|
||||
|
||||
repository.Delete(script);
|
||||
|
||||
uow.Events.Dispatch(DeletedScript, this, new DeleteEventArgs<Script>(script, false));
|
||||
deleteEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(DeletedScript, this, deleteEventArgs);
|
||||
|
||||
Audit(uow, AuditType.Delete, string.Format("Delete Script performed by user"), userId, -1);
|
||||
uow.Commit();
|
||||
@@ -289,7 +293,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(SavingTemplate, this, new SaveEventArgs<ITemplate>(template, true, evtMsgs, additionalData)))
|
||||
var saveEventArgs = new SaveEventArgs<ITemplate>(template, true, evtMsgs, additionalData);
|
||||
if (uow.Events.DispatchCancelable(SavingTemplate, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return Attempt.Fail(new OperationStatus<ITemplate, OperationStatusType>(template, OperationStatusType.FailedCancelledByEvent, evtMsgs));
|
||||
@@ -297,8 +302,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
var repository = RepositoryFactory.CreateTemplateRepository(uow);
|
||||
repository.AddOrUpdate(template);
|
||||
|
||||
uow.Events.Dispatch(SavedTemplate, this, new SaveEventArgs<ITemplate>(template, false, evtMsgs));
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(SavedTemplate, this, saveEventArgs);
|
||||
|
||||
Audit(uow, AuditType.Save, "Save Template performed by user", userId, template.Id);
|
||||
uow.Commit();
|
||||
@@ -562,18 +567,21 @@ namespace Umbraco.Core.Services
|
||||
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
var repository = RepositoryFactory.CreateTemplateRepository(uow);
|
||||
|
||||
if (uow.Events.DispatchCancelable(DeletingTemplate, this, new DeleteEventArgs<ITemplate>(template)))
|
||||
var repository = RepositoryFactory.CreateTemplateRepository(uow);
|
||||
|
||||
var args = new DeleteEventArgs<ITemplate>(template);
|
||||
|
||||
if (uow.Events.DispatchCancelable(DeletingTemplate, this, args))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
repository.Delete(template);
|
||||
|
||||
uow.Events.Dispatch(DeletedTemplate, this, new DeleteEventArgs<ITemplate>(template, false));
|
||||
|
||||
args.CanCancel = false;
|
||||
uow.Events.Dispatch(DeletedTemplate, this, args);
|
||||
|
||||
Audit(uow, AuditType.Delete, "Delete Template performed by user", userId, template.Id);
|
||||
uow.Commit();
|
||||
}
|
||||
@@ -621,6 +629,34 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
public Stream GetMacroScriptFileContentStream(string filepath)
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
|
||||
{
|
||||
var repository = RepositoryFactory.CreateMacroScriptRepository(uow);
|
||||
return repository.GetFileContentStream(filepath);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetMacroScriptFileContent(string filepath, Stream content)
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
var repository = RepositoryFactory.CreateMacroScriptRepository(uow);
|
||||
repository.SetFileContent(filepath, content);
|
||||
uow.Commit();
|
||||
}
|
||||
}
|
||||
|
||||
public long GetMacroScriptFileSize(string filepath)
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
|
||||
{
|
||||
var repository = RepositoryFactory.CreateMacroScriptRepository(uow);
|
||||
return repository.GetFileSize(filepath);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public Stream GetStylesheetFileContentStream(string filepath)
|
||||
@@ -679,6 +715,34 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
public Stream GetUserControlFileContentStream(string filepath)
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
|
||||
{
|
||||
var repository = RepositoryFactory.CreateUserControlRepository(uow);
|
||||
return repository.GetFileContentStream(filepath);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetUserControlFileContent(string filepath, Stream content)
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
var repository = RepositoryFactory.CreateUserControlRepository(uow);
|
||||
repository.SetFileContent(filepath, content);
|
||||
uow.Commit();
|
||||
}
|
||||
}
|
||||
|
||||
public long GetUserControlFileSize(string filepath)
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
|
||||
{
|
||||
var repository = RepositoryFactory.CreateUserControlRepository(uow);
|
||||
return repository.GetFileSize(filepath);
|
||||
}
|
||||
}
|
||||
|
||||
public Stream GetXsltFileContentStream(string filepath)
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
|
||||
@@ -783,6 +847,26 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete("MacroScripts are obsolete - this is for backwards compatibility with upgraded sites.")]
|
||||
public IPartialView GetMacroScript(string path)
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
|
||||
{
|
||||
var repository = RepositoryFactory.CreateMacroScriptRepository(uow);
|
||||
return repository.Get(path);
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete("UserControls are obsolete - this is for backwards compatibility with upgraded sites.")]
|
||||
public IUserControl GetUserControl(string path)
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
|
||||
{
|
||||
var repository = RepositoryFactory.CreateUserControlRepository(uow);
|
||||
return repository.Get(path);
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<IPartialView> GetPartialViewMacros(params string[] names)
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
|
||||
@@ -822,10 +906,11 @@ namespace Umbraco.Core.Services
|
||||
|
||||
private Attempt<IPartialView> CreatePartialViewMacro(IPartialView partialView, PartialViewType partialViewType, string snippetName = null, int userId = 0)
|
||||
{
|
||||
var newEventArgs = new NewEventArgs<IPartialView>(partialView, true, partialView.Alias, -1);
|
||||
using (var scope = UowProvider.ScopeProvider.CreateScope())
|
||||
{
|
||||
scope.Complete(); // always
|
||||
if (scope.Events.DispatchCancelable(CreatingPartialView, this, new NewEventArgs<IPartialView>(partialView, true, partialView.Alias, -1)))
|
||||
scope.Complete(); // always
|
||||
if (scope.Events.DispatchCancelable(CreatingPartialView, this, newEventArgs))
|
||||
return Attempt<IPartialView>.Fail();
|
||||
}
|
||||
|
||||
@@ -839,8 +924,8 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
var repository = GetPartialViewRepository(partialViewType, uow);
|
||||
repository.AddOrUpdate(partialView);
|
||||
|
||||
uow.Events.Dispatch(CreatedPartialView, this, new NewEventArgs<IPartialView>(partialView, false, partialView.Alias, -1));
|
||||
newEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(CreatedPartialView, this, newEventArgs);
|
||||
|
||||
Audit(uow, AuditType.Save, string.Format("Save {0} performed by user", partialViewType), userId, -1);
|
||||
uow.Commit();
|
||||
@@ -871,15 +956,16 @@ namespace Umbraco.Core.Services
|
||||
return false;
|
||||
}
|
||||
|
||||
if (uow.Events.DispatchCancelable(DeletingPartialView, this, new DeleteEventArgs<IPartialView>(partialView)))
|
||||
var deleteEventArgs = new DeleteEventArgs<IPartialView>(partialView);
|
||||
if (uow.Events.DispatchCancelable(DeletingPartialView, this, deleteEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return false;
|
||||
}
|
||||
|
||||
repository.Delete(partialView);
|
||||
|
||||
uow.Events.Dispatch(DeletedPartialView, this, new DeleteEventArgs<IPartialView>(partialView, false));
|
||||
deleteEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(DeletedPartialView, this, deleteEventArgs);
|
||||
|
||||
Audit(uow, AuditType.Delete, string.Format("Delete {0} performed by user", partialViewType), userId, -1);
|
||||
uow.Commit();
|
||||
@@ -903,7 +989,8 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(SavingPartialView, this, new SaveEventArgs<IPartialView>(partialView)))
|
||||
var saveEventArgs = new SaveEventArgs<IPartialView>(partialView);
|
||||
if (uow.Events.DispatchCancelable(SavingPartialView, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return Attempt<IPartialView>.Fail();
|
||||
@@ -911,8 +998,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
var repository = GetPartialViewRepository(partialViewType, uow);
|
||||
repository.AddOrUpdate(partialView);
|
||||
|
||||
uow.Events.Dispatch(SavedPartialView, this, new SaveEventArgs<IPartialView>(partialView, false));
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(SavedPartialView, this, saveEventArgs);
|
||||
|
||||
Audit(uow, AuditType.Save, string.Format("Save {0} performed by user", partialViewType), userId, -1);
|
||||
uow.Commit();
|
||||
|
||||
@@ -17,6 +17,10 @@ namespace Umbraco.Core.Services
|
||||
void DeletePartialViewMacroFolder(string folderPath);
|
||||
IPartialView GetPartialView(string path);
|
||||
IPartialView GetPartialViewMacro(string path);
|
||||
[Obsolete("MacroScripts are obsolete - this is for backwards compatibility with upgraded sites.")]
|
||||
IPartialView GetMacroScript(string path);
|
||||
[Obsolete("UserControls are obsolete - this is for backwards compatibility with upgraded sites.")]
|
||||
IUserControl GetUserControl(string path);
|
||||
IEnumerable<IPartialView> GetPartialViewMacros(params string[] names);
|
||||
IXsltFile GetXsltFile(string path);
|
||||
IEnumerable<IXsltFile> GetXsltFiles(params string[] names);
|
||||
@@ -263,6 +267,27 @@ namespace Umbraco.Core.Services
|
||||
/// <returns>The size of the template.</returns>
|
||||
long GetTemplateFileSize(string filepath);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the content of a macroscript as a stream.
|
||||
/// </summary>
|
||||
/// <param name="filepath">The filesystem path to the macroscript.</param>
|
||||
/// <returns>The content of the macroscript.</returns>
|
||||
Stream GetMacroScriptFileContentStream(string filepath);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the content of a macroscript.
|
||||
/// </summary>
|
||||
/// <param name="filepath">The filesystem path to the macroscript.</param>
|
||||
/// <param name="content">The content of the macroscript.</param>
|
||||
void SetMacroScriptFileContent(string filepath, Stream content);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the size of a macroscript.
|
||||
/// </summary>
|
||||
/// <param name="filepath">The filesystem path to the macroscript.</param>
|
||||
/// <returns>The size of the macroscript.</returns>
|
||||
long GetMacroScriptFileSize(string filepath);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the content of a stylesheet as a stream.
|
||||
/// </summary>
|
||||
@@ -305,6 +330,27 @@ namespace Umbraco.Core.Services
|
||||
/// <returns>The size of the script file.</returns>
|
||||
long GetScriptFileSize(string filepath);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the content of a usercontrol as a stream.
|
||||
/// </summary>
|
||||
/// <param name="filepath">The filesystem path to the usercontrol.</param>
|
||||
/// <returns>The content of the usercontrol.</returns>
|
||||
Stream GetUserControlFileContentStream(string filepath);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the content of a usercontrol.
|
||||
/// </summary>
|
||||
/// <param name="filepath">The filesystem path to the usercontrol.</param>
|
||||
/// <param name="content">The content of the usercontrol.</param>
|
||||
void SetUserControlFileContent(string filepath, Stream content);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the size of a usercontrol.
|
||||
/// </summary>
|
||||
/// <param name="filepath">The filesystem path to the usercontrol.</param>
|
||||
/// <returns>The size of the usercontrol.</returns>
|
||||
long GetUserControlFileSize(string filepath);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the content of a XSLT file as a stream.
|
||||
/// </summary>
|
||||
|
||||
@@ -136,5 +136,11 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="language"><see cref="ILanguage"/> to delete</param>
|
||||
/// <param name="userId">Optional id of the user deleting the language</param>
|
||||
void Delete(ILanguage language, int userId = 0);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the full dictionary key map.
|
||||
/// </summary>
|
||||
/// <returns>The full dictionary key map.</returns>
|
||||
Dictionary<string, Guid> GetDictionaryItemKeyMap();
|
||||
}
|
||||
}
|
||||
@@ -119,10 +119,16 @@ namespace Umbraco.Core.Services
|
||||
IMember CreateMemberWithIdentity(string username, string email, string name, IMemberType memberType);
|
||||
|
||||
/// <summary>
|
||||
/// This is simply a helper method which essentially just wraps the MembershipProvider's ChangePassword method
|
||||
/// This is simply a helper method which essentially just wraps the MembershipProvider's ChangePassword method which can be
|
||||
/// used during Member creation.
|
||||
/// </summary>
|
||||
/// <remarks>This method exists so that Umbraco developers can use one entry point to create/update
|
||||
/// Members if they choose to. </remarks>
|
||||
/// <remarks>
|
||||
/// This method exists so that Umbraco developers can use this entry point to set a password when Creating members ...
|
||||
/// this will not work for updating members in most cases (depends on your membership provider settings)
|
||||
///
|
||||
/// It is preferred to use the membership APIs for working with passwords, in the near future this method will be obsoleted
|
||||
/// and the ASP.NET Identity APIs should be used instead.
|
||||
/// </remarks>
|
||||
/// <param name="member">The Member to save the password for</param>
|
||||
/// <param name="password">The password to encrypt and save</param>
|
||||
void SavePassword(IMember member, string password);
|
||||
|
||||
@@ -72,6 +72,18 @@ namespace Umbraco.Core.Services
|
||||
/// <returns><see cref="IMembershipUser"/></returns>
|
||||
T CreateWithIdentity(string username, string email, string passwordValue, string memberTypeAlias);
|
||||
|
||||
/// <summary>
|
||||
/// Creates and persists a new <see cref="IMembershipUser"/>
|
||||
/// </summary>
|
||||
/// <remarks>An <see cref="IMembershipUser"/> can be of type <see cref="IMember"/> or <see cref="IUser"/></remarks>
|
||||
/// <param name="username">Username of the <see cref="IMembershipUser"/> to create</param>
|
||||
/// <param name="email">Email of the <see cref="IMembershipUser"/> to create</param>
|
||||
/// <param name="passwordValue">This value should be the encoded/encrypted/hashed value for the password that will be stored in the database</param>
|
||||
/// <param name="memberTypeAlias">Alias of the Type</param>
|
||||
/// <param name="isApproved">IsApproved of the <see cref="IMembershipUser"/> to create</param>
|
||||
/// <returns><see cref="IMembershipUser"/></returns>
|
||||
T CreateWithIdentity(string username, string email, string passwordValue, string memberTypeAlias, bool isApproved);
|
||||
|
||||
/// <summary>
|
||||
/// Gets an <see cref="IMembershipUser"/> by its provider key
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,192 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
|
||||
namespace Umbraco.Core.Services
|
||||
{
|
||||
public class IdkMap
|
||||
{
|
||||
private readonly IDatabaseUnitOfWorkProvider _uowProvider;
|
||||
private readonly ReaderWriterLockSlim _locker = new ReaderWriterLockSlim();
|
||||
|
||||
private readonly Dictionary<int, TypedId<Guid>> _id2Key = new Dictionary<int, TypedId<Guid>>();
|
||||
private readonly Dictionary<Guid, TypedId<int>> _key2Id = new Dictionary<Guid, TypedId<int>>();
|
||||
|
||||
public IdkMap(IDatabaseUnitOfWorkProvider uowProvider)
|
||||
{
|
||||
_uowProvider = uowProvider;
|
||||
}
|
||||
|
||||
// note - no need for uow, scope would be enough, but a pain to wire
|
||||
// note - for pure read-only we might want to *not* enforce a transaction?
|
||||
|
||||
public Attempt<int> GetIdForKey(Guid key, UmbracoObjectTypes umbracoObjectType)
|
||||
{
|
||||
TypedId<int> id;
|
||||
try
|
||||
{
|
||||
_locker.EnterReadLock();
|
||||
if (_key2Id.TryGetValue(key, out id) && id.UmbracoObjectType == umbracoObjectType) return Attempt.Succeed(id.Id);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (_locker.IsReadLockHeld)
|
||||
_locker.ExitReadLock();
|
||||
}
|
||||
|
||||
int? val;
|
||||
using (var uow = _uowProvider.GetUnitOfWork())
|
||||
{
|
||||
val = uow.Database.ExecuteScalar<int?>("SELECT id FROM umbracoNode WHERE uniqueId=@id AND nodeObjectType=@nodeObjectType",
|
||||
new { id = key, nodeObjectType = GetNodeObjectTypeGuid(umbracoObjectType) });
|
||||
uow.Commit();
|
||||
}
|
||||
|
||||
if (val == null) return Attempt<int>.Fail();
|
||||
|
||||
try
|
||||
{
|
||||
_locker.EnterWriteLock();
|
||||
_id2Key[val.Value] = new TypedId<Guid>(key, umbracoObjectType);
|
||||
_key2Id[key] = new TypedId<int>(val.Value, umbracoObjectType);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (_locker.IsWriteLockHeld)
|
||||
_locker.ExitWriteLock();
|
||||
}
|
||||
|
||||
return Attempt.Succeed(val.Value);
|
||||
}
|
||||
|
||||
public Attempt<int> GetIdForUdi(Udi udi)
|
||||
{
|
||||
var guidUdi = udi as GuidUdi;
|
||||
if (guidUdi == null)
|
||||
return Attempt<int>.Fail();
|
||||
|
||||
var umbracoType = Constants.UdiEntityType.ToUmbracoObjectType(guidUdi.EntityType);
|
||||
return GetIdForKey(guidUdi.Guid, umbracoType);
|
||||
}
|
||||
|
||||
public Attempt<Guid> GetKeyForId(int id, UmbracoObjectTypes umbracoObjectType)
|
||||
{
|
||||
TypedId<Guid> key;
|
||||
try
|
||||
{
|
||||
_locker.EnterReadLock();
|
||||
if (_id2Key.TryGetValue(id, out key) && key.UmbracoObjectType == umbracoObjectType) return Attempt.Succeed(key.Id);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (_locker.IsReadLockHeld)
|
||||
_locker.ExitReadLock();
|
||||
}
|
||||
|
||||
Guid? val;
|
||||
using (var uow = _uowProvider.GetUnitOfWork())
|
||||
{
|
||||
val = uow.Database.ExecuteScalar<Guid?>("SELECT uniqueId FROM umbracoNode WHERE id=@id AND nodeObjectType=@nodeObjectType",
|
||||
new { id, nodeObjectType = GetNodeObjectTypeGuid(umbracoObjectType) });
|
||||
uow.Commit();
|
||||
}
|
||||
|
||||
if (val == null) return Attempt<Guid>.Fail();
|
||||
|
||||
try
|
||||
{
|
||||
_locker.EnterWriteLock();
|
||||
_id2Key[id] = new TypedId<Guid>(val.Value, umbracoObjectType); ;
|
||||
_key2Id[val.Value] = new TypedId<int>();
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (_locker.IsWriteLockHeld)
|
||||
_locker.ExitWriteLock();
|
||||
}
|
||||
|
||||
return Attempt.Succeed(val.Value);
|
||||
}
|
||||
|
||||
private static Guid GetNodeObjectTypeGuid(UmbracoObjectTypes umbracoObjectType)
|
||||
{
|
||||
var guid = umbracoObjectType.GetGuid();
|
||||
if (guid == Guid.Empty)
|
||||
throw new NotSupportedException("Unsupported object type (" + umbracoObjectType + ").");
|
||||
return guid;
|
||||
}
|
||||
|
||||
public void ClearCache()
|
||||
{
|
||||
try
|
||||
{
|
||||
_locker.EnterWriteLock();
|
||||
_id2Key.Clear();
|
||||
_key2Id.Clear();
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (_locker.IsWriteLockHeld)
|
||||
_locker.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearCache(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
_locker.EnterWriteLock();
|
||||
TypedId<Guid> key;
|
||||
if (_id2Key.TryGetValue(id, out key) == false) return;
|
||||
_id2Key.Remove(id);
|
||||
_key2Id.Remove(key.Id);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (_locker.IsWriteLockHeld)
|
||||
_locker.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearCache(Guid key)
|
||||
{
|
||||
try
|
||||
{
|
||||
_locker.EnterWriteLock();
|
||||
TypedId<int> id;
|
||||
if (_key2Id.TryGetValue(key, out id) == false) return;
|
||||
_id2Key.Remove(id.Id);
|
||||
_key2Id.Remove(key);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (_locker.IsWriteLockHeld)
|
||||
_locker.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
|
||||
private struct TypedId<T>
|
||||
{
|
||||
private readonly T _id;
|
||||
private readonly UmbracoObjectTypes _umbracoObjectType;
|
||||
|
||||
public T Id
|
||||
{
|
||||
get { return _id; }
|
||||
}
|
||||
|
||||
public UmbracoObjectTypes UmbracoObjectType
|
||||
{
|
||||
get { return _umbracoObjectType; }
|
||||
}
|
||||
|
||||
public TypedId(T id, UmbracoObjectTypes umbracoObjectType)
|
||||
{
|
||||
_umbracoObjectType = umbracoObjectType;
|
||||
_id = id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -79,7 +79,8 @@ namespace Umbraco.Core.Services
|
||||
item.Translations = translations;
|
||||
}
|
||||
|
||||
if (uow.Events.DispatchCancelable(SavingDictionaryItem, this, new SaveEventArgs<IDictionaryItem>(item)))
|
||||
var saveEventArgs = new SaveEventArgs<IDictionaryItem>(item);
|
||||
if (uow.Events.DispatchCancelable(SavingDictionaryItem, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return item;
|
||||
@@ -90,8 +91,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
//ensure the lazy Language callback is assigned
|
||||
EnsureDictionaryItemLanguageCallback(item);
|
||||
|
||||
uow.Events.Dispatch(SavedDictionaryItem, this, new SaveEventArgs<IDictionaryItem>(item));
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(SavedDictionaryItem, this, saveEventArgs);
|
||||
|
||||
return item;
|
||||
}
|
||||
@@ -256,7 +257,8 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(DeletingDictionaryItem, this, new DeleteEventArgs<IDictionaryItem>(dictionaryItem)))
|
||||
var deleteEventArgs = new DeleteEventArgs<IDictionaryItem>(dictionaryItem);
|
||||
if (uow.Events.DispatchCancelable(DeletingDictionaryItem, this, deleteEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
@@ -264,8 +266,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
var repository = RepositoryFactory.CreateDictionaryRepository(uow);
|
||||
repository.Delete(dictionaryItem);
|
||||
|
||||
uow.Events.Dispatch(DeletedDictionaryItem, this, new DeleteEventArgs<IDictionaryItem>(dictionaryItem, false));
|
||||
deleteEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(DeletedDictionaryItem, this, deleteEventArgs);
|
||||
|
||||
Audit(uow, AuditType.Delete, "Delete DictionaryItem performed by user", userId, dictionaryItem.Id);
|
||||
uow.Commit();
|
||||
@@ -336,15 +338,16 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(SavingLanguage, this, new SaveEventArgs<ILanguage>(language)))
|
||||
var saveEventArgs = new SaveEventArgs<ILanguage>(language);
|
||||
if (uow.Events.DispatchCancelable(SavingLanguage, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
}
|
||||
var repository = RepositoryFactory.CreateLanguageRepository(uow);
|
||||
repository.AddOrUpdate(language);
|
||||
|
||||
uow.Events.Dispatch(SavedLanguage, this, new SaveEventArgs<ILanguage>(language, false));
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(SavedLanguage, this, saveEventArgs);
|
||||
|
||||
Audit(uow, AuditType.Save, "Save Language performed by user", userId, language.Id);
|
||||
uow.Commit();
|
||||
@@ -360,7 +363,8 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(DeletingLanguage, this, new DeleteEventArgs<ILanguage>(language)))
|
||||
var deleteEventArgs = new DeleteEventArgs<ILanguage>(language);
|
||||
if (uow.Events.DispatchCancelable(DeletingLanguage, this, deleteEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
@@ -369,7 +373,8 @@ namespace Umbraco.Core.Services
|
||||
var repository = RepositoryFactory.CreateLanguageRepository(uow);
|
||||
repository.Delete(language);
|
||||
|
||||
uow.Events.Dispatch(DeletedLanguage, this, new DeleteEventArgs<ILanguage>(language, false));
|
||||
deleteEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(DeletedLanguage, this, deleteEventArgs);
|
||||
|
||||
Audit(uow, AuditType.Delete, "Delete Language performed by user", userId, language.Id);
|
||||
uow.Commit();
|
||||
@@ -400,6 +405,15 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
public Dictionary<string, Guid> GetDictionaryItemKeyMap()
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
|
||||
{
|
||||
var repository = RepositoryFactory.CreateDictionaryRepository(uow);
|
||||
return repository.GetDictionaryItemKeyMap();
|
||||
}
|
||||
}
|
||||
|
||||
#region Event Handlers
|
||||
/// <summary>
|
||||
/// Occurs before Delete
|
||||
|
||||
@@ -144,15 +144,16 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(Deleting, this, new DeleteEventArgs<IMacro>(macro)))
|
||||
var deleteEventArgs = new DeleteEventArgs<IMacro>(macro);
|
||||
if (uow.Events.DispatchCancelable(Deleting, this, deleteEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
}
|
||||
var repository = RepositoryFactory.CreateMacroRepository(uow);
|
||||
repository.Delete(macro);
|
||||
|
||||
uow.Events.Dispatch(Deleted, this, new DeleteEventArgs<IMacro>(macro, false));
|
||||
deleteEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Deleted, this, deleteEventArgs);
|
||||
|
||||
Audit(uow, AuditType.Delete, "Delete Macro performed by user", userId, -1);
|
||||
uow.Commit();
|
||||
@@ -168,7 +169,8 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(Saving, this, new SaveEventArgs<IMacro>(macro)))
|
||||
var saveEventArgs = new SaveEventArgs<IMacro>(macro);
|
||||
if (uow.Events.DispatchCancelable(Saving, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
@@ -181,8 +183,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
var repository = RepositoryFactory.CreateMacroRepository(uow);
|
||||
repository.AddOrUpdate(macro);
|
||||
|
||||
uow.Events.Dispatch(Saved, this, new SaveEventArgs<IMacro>(macro, false));
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Saved, this, saveEventArgs);
|
||||
|
||||
Audit(uow, AuditType.Save, "Save Macro performed by user", userId, -1);
|
||||
uow.Commit();
|
||||
|
||||
@@ -35,14 +35,16 @@ namespace Umbraco.Core.Services
|
||||
private readonly IDataTypeService _dataTypeService;
|
||||
private readonly IUserService _userService;
|
||||
private readonly MediaFileSystem _mediaFileSystem = FileSystemProviderManager.Current.MediaFileSystem;
|
||||
private readonly IdkMap _idkMap;
|
||||
|
||||
public MediaService(IDatabaseUnitOfWorkProvider provider, RepositoryFactory repositoryFactory, ILogger logger, IEventMessagesFactory eventMessagesFactory, IDataTypeService dataTypeService, IUserService userService)
|
||||
public MediaService(IDatabaseUnitOfWorkProvider provider, RepositoryFactory repositoryFactory, ILogger logger, IEventMessagesFactory eventMessagesFactory, IDataTypeService dataTypeService, IUserService userService, IdkMap idkMap)
|
||||
: base(provider, repositoryFactory, logger, eventMessagesFactory)
|
||||
{
|
||||
if (dataTypeService == null) throw new ArgumentNullException("dataTypeService");
|
||||
if (userService == null) throw new ArgumentNullException("userService");
|
||||
_dataTypeService = dataTypeService;
|
||||
_userService = userService;
|
||||
_idkMap = idkMap;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -68,7 +70,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(Creating, this, new NewEventArgs<IMedia>(media, mediaTypeAlias, parentId)))
|
||||
var newEventArgs = new NewEventArgs<IMedia>(media, mediaTypeAlias, parentId);
|
||||
if (uow.Events.DispatchCancelable(Creating, this, newEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
media.WasCancelled = true;
|
||||
@@ -76,7 +79,8 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
|
||||
media.CreatorId = userId;
|
||||
uow.Events.Dispatch(Created, this, new NewEventArgs<IMedia>(media, false, mediaTypeAlias, parentId));
|
||||
newEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Created, this, newEventArgs);
|
||||
Audit(uow, AuditType.New, string.Format("Media '{0}' was created", name), media.CreatorId, media.Id);
|
||||
uow.Commit();
|
||||
|
||||
@@ -108,7 +112,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(Creating, this, new NewEventArgs<IMedia>(media, mediaTypeAlias, parent)))
|
||||
var newEventArgs = new NewEventArgs<IMedia>(media, mediaTypeAlias, parent);
|
||||
if (uow.Events.DispatchCancelable(Creating, this, newEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
media.WasCancelled = true;
|
||||
@@ -116,8 +121,8 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
|
||||
media.CreatorId = userId;
|
||||
|
||||
uow.Events.Dispatch(Created, this, new NewEventArgs<IMedia>(media, false, mediaTypeAlias, parent));
|
||||
newEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Created, this, newEventArgs);
|
||||
|
||||
Audit(uow, AuditType.New, string.Format("Media '{0}' was created", name), media.CreatorId, media.Id);
|
||||
uow.Commit();
|
||||
@@ -148,14 +153,16 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
//NOTE: I really hate the notion of these Creating/Created events - they are so inconsistent, I've only just found
|
||||
// out that in these 'WithIdentity' methods, the Saving/Saved events were not fired, wtf. Anyways, they're added now.
|
||||
if (uow.Events.DispatchCancelable(Creating, this, new NewEventArgs<IMedia>(media, mediaTypeAlias, parentId)))
|
||||
var newEventArgs = new NewEventArgs<IMedia>(media, mediaTypeAlias, parentId);
|
||||
if (uow.Events.DispatchCancelable(Creating, this, newEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
media.WasCancelled = true;
|
||||
return media;
|
||||
}
|
||||
|
||||
if (uow.Events.DispatchCancelable(Saving, this, new SaveEventArgs<IMedia>(media)))
|
||||
var saveEventArgs = new SaveEventArgs<IMedia>(media);
|
||||
if (uow.Events.DispatchCancelable(Saving, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
media.WasCancelled = true;
|
||||
@@ -172,8 +179,10 @@ namespace Umbraco.Core.Services
|
||||
repository.AddOrUpdatePreviewXml(media, m => _entitySerializer.Serialize(this, _dataTypeService, _userService, m));
|
||||
}
|
||||
|
||||
uow.Events.Dispatch(Saved, this, new SaveEventArgs<IMedia>(media, false));
|
||||
uow.Events.Dispatch(Created, this, new NewEventArgs<IMedia>(media, false, mediaTypeAlias, parentId));
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Saved, this, saveEventArgs);
|
||||
newEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Created, this, newEventArgs);
|
||||
|
||||
Audit(uow, AuditType.New, string.Format("Media '{0}' was created with Id {1}", name, media.Id), media.CreatorId, media.Id);
|
||||
uow.Commit();
|
||||
@@ -206,14 +215,16 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
//NOTE: I really hate the notion of these Creating/Created events - they are so inconsistent, I've only just found
|
||||
// out that in these 'WithIdentity' methods, the Saving/Saved events were not fired, wtf. Anyways, they're added now.
|
||||
if (uow.Events.DispatchCancelable(Creating, this, new NewEventArgs<IMedia>(media, mediaTypeAlias, parent)))
|
||||
var newEventArgs = new NewEventArgs<IMedia>(media, mediaTypeAlias, parent);
|
||||
if (uow.Events.DispatchCancelable(Creating, this, newEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
media.WasCancelled = true;
|
||||
return media;
|
||||
}
|
||||
|
||||
if (uow.Events.DispatchCancelable(Saving, this, new SaveEventArgs<IMedia>(media)))
|
||||
var saveEventArgs = new SaveEventArgs<IMedia>(media);
|
||||
if (uow.Events.DispatchCancelable(Saving, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
media.WasCancelled = true;
|
||||
@@ -230,8 +241,10 @@ namespace Umbraco.Core.Services
|
||||
repository.AddOrUpdatePreviewXml(media, m => _entitySerializer.Serialize(this, _dataTypeService, _userService, m));
|
||||
}
|
||||
|
||||
uow.Events.Dispatch(Saved, this, new SaveEventArgs<IMedia>(media, false));
|
||||
uow.Events.Dispatch(Created, this, new NewEventArgs<IMedia>(media, false, mediaTypeAlias, parent));
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Saved, this, saveEventArgs);
|
||||
newEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Created, this, newEventArgs);
|
||||
|
||||
Audit(uow, AuditType.New, string.Format("Media '{0}' was created with Id {1}", name, media.Id), media.CreatorId, media.Id);
|
||||
uow.Commit();
|
||||
@@ -327,12 +340,15 @@ namespace Umbraco.Core.Services
|
||||
/// <returns><see cref="IMedia"/></returns>
|
||||
public IMedia GetById(Guid key)
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
|
||||
{
|
||||
var repository = RepositoryFactory.CreateMediaRepository(uow);
|
||||
var query = Query<IMedia>.Builder.Where(x => x.Key == key);
|
||||
return repository.GetByQuery(query).SingleOrDefault();
|
||||
}
|
||||
// the repository implements a cache policy on int identifiers, not guids,
|
||||
// and we are not changing it now, but we still would like to rely on caching
|
||||
// instead of running a full query against the database, so relying on the
|
||||
// id-key map, which is fast.
|
||||
//
|
||||
// we should inject the id-key map but ... breaking changes ... yada
|
||||
|
||||
var a = _idkMap.GetIdForKey(key, UmbracoObjectTypes.Media);
|
||||
return a.Success ? GetById(a.Result) : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -781,7 +797,9 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
var originalPath = media.Path;
|
||||
|
||||
if (uow.Events.DispatchCancelable(Moving, this, new MoveEventArgs<IMedia>(new MoveEventInfo<IMedia>(media, originalPath, parentId)), "Moving"))
|
||||
var moveEventInfo = new MoveEventInfo<IMedia>(media, originalPath, parentId);
|
||||
var moveEventArgs = new MoveEventArgs<IMedia>(moveEventInfo);
|
||||
if (uow.Events.DispatchCancelable(Moving, this, moveEventArgs, "Moving"))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
@@ -797,7 +815,7 @@ namespace Umbraco.Core.Services
|
||||
//used to track all the moved entities to be given to the event
|
||||
var moveInfo = new List<MoveEventInfo<IMedia>>
|
||||
{
|
||||
new MoveEventInfo<IMedia>(media, originalPath, parentId)
|
||||
moveEventInfo
|
||||
};
|
||||
|
||||
//Ensure that relevant properties are updated on children
|
||||
@@ -811,7 +829,9 @@ namespace Umbraco.Core.Services
|
||||
Save(updatedDescendants, userId, false); //no events!
|
||||
}
|
||||
|
||||
uow.Events.Dispatch(Moved, this, new MoveEventArgs<IMedia>(false, moveInfo.ToArray()), "Moved");
|
||||
moveEventArgs.MoveInfoCollection = moveInfo;
|
||||
moveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Moved, this, moveEventArgs, "Moved");
|
||||
|
||||
Audit(uow, AuditType.Move, "Move Media performed by user", userId, media.Id);
|
||||
uow.Commit();
|
||||
@@ -853,7 +873,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
private Attempt<OperationStatus> DeleteUow(IScopeUnitOfWork uow, IMedia media, int userId, EventMessages evtMsgs)
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(Deleting, this, new DeleteEventArgs<IMedia>(media, evtMsgs)))
|
||||
var deleteEventArgs = new DeleteEventArgs<IMedia>(media, evtMsgs);
|
||||
if (uow.Events.DispatchCancelable(Deleting, this, deleteEventArgs))
|
||||
{
|
||||
return OperationStatus.Cancelled(evtMsgs);
|
||||
}
|
||||
@@ -867,9 +888,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
var repository = RepositoryFactory.CreateMediaRepository(uow);
|
||||
repository.Delete(media);
|
||||
|
||||
var args = new DeleteEventArgs<IMedia>(media, false, evtMsgs);
|
||||
uow.Events.Dispatch(Deleted, this, args);
|
||||
deleteEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Deleted, this, deleteEventArgs);
|
||||
|
||||
Audit(uow, AuditType.Delete, "Delete Media performed by user", userId, media.Id);
|
||||
|
||||
@@ -888,7 +908,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (raiseEvents && uow.Events.DispatchCancelable(Saving, this, new SaveEventArgs<IMedia>(media, evtMsgs)))
|
||||
var saveEventArgs = new SaveEventArgs<IMedia>(media, evtMsgs);
|
||||
if (raiseEvents && uow.Events.DispatchCancelable(Saving, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return OperationStatus.Cancelled(evtMsgs);
|
||||
@@ -899,13 +920,13 @@ namespace Umbraco.Core.Services
|
||||
throw new ArgumentException("Cannot save media with empty name.");
|
||||
}
|
||||
|
||||
var repository = RepositoryFactory.CreateMediaRepository(uow);
|
||||
|
||||
var repository = RepositoryFactory.CreateMediaRepository(uow);
|
||||
|
||||
//set the creator id if it's new
|
||||
if (media.HasIdentity == false)
|
||||
{
|
||||
media.CreatorId = userId;
|
||||
}
|
||||
}
|
||||
|
||||
repository.AddOrUpdate(media);
|
||||
repository.AddOrUpdateContentXml(media, m => _entitySerializer.Serialize(this, _dataTypeService, _userService, m));
|
||||
@@ -916,7 +937,10 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
|
||||
if (raiseEvents)
|
||||
uow.Events.Dispatch(Saved, this, new SaveEventArgs<IMedia>(media, false, evtMsgs));
|
||||
{
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Saved, this, saveEventArgs);
|
||||
}
|
||||
|
||||
Audit(uow, AuditType.Save, "Save Media performed by user", userId, media.Id);
|
||||
uow.Commit();
|
||||
@@ -938,7 +962,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (raiseEvents && uow.Events.DispatchCancelable(Saving, this, new SaveEventArgs<IMedia>(asArray, evtMsgs)))
|
||||
var saveEventArgs = new SaveEventArgs<IMedia>(asArray, evtMsgs);
|
||||
if (raiseEvents && uow.Events.DispatchCancelable(Saving, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return OperationStatus.Cancelled(evtMsgs);
|
||||
@@ -958,7 +983,10 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
|
||||
if (raiseEvents)
|
||||
uow.Events.Dispatch(Saved, this, new SaveEventArgs<IMedia>(asArray, false, evtMsgs));
|
||||
{
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Saved, this, saveEventArgs);
|
||||
}
|
||||
|
||||
Audit(uow, AuditType.Save, "Save Media items performed by user", userId, -1);
|
||||
uow.Commit();
|
||||
@@ -983,15 +1011,17 @@ namespace Umbraco.Core.Services
|
||||
|
||||
var files = ((MediaRepository)repository).GetFilesInRecycleBinForUploadField();
|
||||
|
||||
if (uow.Events.DispatchCancelable(EmptyingRecycleBin, this, new RecycleBinEventArgs(nodeObjectType, entities, files)))
|
||||
var recycleBinEventArgs = new RecycleBinEventArgs(nodeObjectType, entities, files);
|
||||
if (uow.Events.DispatchCancelable(EmptyingRecycleBin, this, recycleBinEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
}
|
||||
|
||||
var success = repository.EmptyRecycleBin();
|
||||
|
||||
uow.Events.Dispatch(EmptiedRecycleBin, this, new RecycleBinEventArgs(nodeObjectType, entities, files, success));
|
||||
recycleBinEventArgs.CanCancel = false;
|
||||
recycleBinEventArgs.RecycleBinEmptiedSuccessfully = success;
|
||||
uow.Events.Dispatch(EmptiedRecycleBin, this, recycleBinEventArgs);
|
||||
|
||||
Audit(uow, AuditType.Delete, "Empty Media Recycle Bin performed by user", 0, -21);
|
||||
uow.Commit();
|
||||
@@ -1017,7 +1047,8 @@ namespace Umbraco.Core.Services
|
||||
IDictionary<string, IMedia> rootItems;
|
||||
var mediaToDelete = this.TrackDeletionsForDeleteContentOfTypes(mediaTypeIds, repository, out rootItems).ToArray();
|
||||
|
||||
if (uow.Events.DispatchCancelable(Deleting, this, new DeleteEventArgs<IMedia>(mediaToDelete), "Deleting"))
|
||||
var deleteEventArgs = new DeleteEventArgs<IMedia>(mediaToDelete);
|
||||
if (uow.Events.DispatchCancelable(Deleting, this, deleteEventArgs, "Deleting"))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
@@ -1089,14 +1120,16 @@ namespace Umbraco.Core.Services
|
||||
//see: http://issues.umbraco.org/issue/U4-9336
|
||||
media.EnsureValidPath(Logger, entity => GetById(entity.ParentId), QuickUpdate);
|
||||
var originalPath = media.Path;
|
||||
if (uow.Events.DispatchCancelable(Trashing, this, new MoveEventArgs<IMedia>(new MoveEventInfo<IMedia>(media, originalPath, Constants.System.RecycleBinMedia)), "Trashing"))
|
||||
var moveEventInfo = new MoveEventInfo<IMedia>(media, originalPath, Constants.System.RecycleBinMedia);
|
||||
var moveEventArgs = new MoveEventArgs<IMedia>(moveEventInfo);
|
||||
if (uow.Events.DispatchCancelable(Trashing, this, moveEventArgs, "Trashing"))
|
||||
{
|
||||
uow.Commit();
|
||||
return OperationStatus.Cancelled(evtMsgs);
|
||||
}
|
||||
var moveInfo = new List<MoveEventInfo<IMedia>>
|
||||
{
|
||||
new MoveEventInfo<IMedia>(media, originalPath, Constants.System.RecycleBinMedia)
|
||||
moveEventInfo
|
||||
};
|
||||
|
||||
//get descendents to process of the content item that is being moved to trash - must be done before changing the state below,
|
||||
@@ -1119,7 +1152,9 @@ namespace Umbraco.Core.Services
|
||||
moveInfo.Add(new MoveEventInfo<IMedia>(descendant, descendant.Path, descendant.ParentId));
|
||||
}
|
||||
|
||||
uow.Events.Dispatch(Trashed, this, new MoveEventArgs<IMedia>(false, evtMsgs, moveInfo.ToArray()), "Trashed");
|
||||
moveEventArgs.MoveInfoCollection = moveInfo;
|
||||
moveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Trashed, this, moveEventArgs, "Trashed");
|
||||
|
||||
Audit(uow, AuditType.Move, "Move Media to Recycle Bin performed by user", userId, media.Id);
|
||||
uow.Commit();
|
||||
@@ -1162,12 +1197,14 @@ namespace Umbraco.Core.Services
|
||||
|
||||
private void DeleteVersions(IScopeUnitOfWork uow, int id, DateTime versionDate, int userId = 0)
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(DeletingVersions, this, new DeleteRevisionsEventArgs(id, dateToRetain: versionDate)))
|
||||
var deleteRevisionsEventArgs = new DeleteRevisionsEventArgs(id, dateToRetain: versionDate);
|
||||
if (uow.Events.DispatchCancelable(DeletingVersions, this, deleteRevisionsEventArgs))
|
||||
return;
|
||||
|
||||
var repository = RepositoryFactory.CreateMediaRepository(uow);
|
||||
repository.DeleteVersions(id, versionDate);
|
||||
uow.Events.Dispatch(DeletedVersions, this, new DeleteRevisionsEventArgs(id, false, dateToRetain: versionDate));
|
||||
deleteRevisionsEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(DeletedVersions, this, deleteRevisionsEventArgs);
|
||||
Audit(uow, AuditType.Delete, "Delete Media by version date performed by user", userId, -1);
|
||||
}
|
||||
|
||||
@@ -1183,7 +1220,8 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(DeletingVersions, this, new DeleteRevisionsEventArgs(id, specificVersion: versionId)))
|
||||
var deleteRevisionsEventArgs = new DeleteRevisionsEventArgs(id, specificVersion: versionId);
|
||||
if (uow.Events.DispatchCancelable(DeletingVersions, this, deleteRevisionsEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
@@ -1197,8 +1235,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
var repository = RepositoryFactory.CreateMediaRepository(uow);
|
||||
repository.DeleteVersion(versionId);
|
||||
|
||||
uow.Events.Dispatch(DeletedVersions, this, new DeleteRevisionsEventArgs(id, false, specificVersion: versionId));
|
||||
deleteRevisionsEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(DeletedVersions, this, deleteRevisionsEventArgs);
|
||||
|
||||
Audit(uow, AuditType.Delete, "Delete Media by version performed by user", userId, -1);
|
||||
uow.Commit();
|
||||
@@ -1241,7 +1279,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (raiseEvents && uow.Events.DispatchCancelable(Saving, this, new SaveEventArgs<IMedia>(asArray)))
|
||||
var saveEventArgs = new SaveEventArgs<IMedia>(asArray);
|
||||
if (raiseEvents && uow.Events.DispatchCancelable(Saving, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return false;
|
||||
@@ -1273,7 +1312,10 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
|
||||
if (raiseEvents)
|
||||
uow.Events.Dispatch(Saved, this, new SaveEventArgs<IMedia>(asArray, false));
|
||||
{
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Saved, this, saveEventArgs);
|
||||
}
|
||||
|
||||
Audit(uow, AuditType.Sort, "Sorting Media performed by user", userId, 0);
|
||||
uow.Commit();
|
||||
|
||||
@@ -71,7 +71,8 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (raiseEvents && uow.Events.DispatchCancelable(Saving, this, new SaveEventArgs<IMemberGroup>(memberGroup)))
|
||||
var saveEventArgs = new SaveEventArgs<IMemberGroup>(memberGroup);
|
||||
if (raiseEvents && uow.Events.DispatchCancelable(Saving, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
@@ -81,17 +82,19 @@ namespace Umbraco.Core.Services
|
||||
repository.AddOrUpdate(memberGroup);
|
||||
uow.Commit();
|
||||
if (raiseEvents)
|
||||
uow.Events.Dispatch(Saved, this, new SaveEventArgs<IMemberGroup>(memberGroup, false));
|
||||
{
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Saved, this, saveEventArgs);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void Delete(IMemberGroup memberGroup)
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(Deleting, this, new DeleteEventArgs<IMemberGroup>(memberGroup)))
|
||||
var deleteEventArgs = new DeleteEventArgs<IMemberGroup>(memberGroup);
|
||||
if (uow.Events.DispatchCancelable(Deleting, this, deleteEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
@@ -99,7 +102,8 @@ namespace Umbraco.Core.Services
|
||||
var repository = RepositoryFactory.CreateMemberGroupRepository(uow);
|
||||
repository.Delete(memberGroup);
|
||||
uow.Commit();
|
||||
uow.Events.Dispatch(Deleted, this, new DeleteEventArgs<IMemberGroup>(memberGroup, false));
|
||||
deleteEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Deleted, this, deleteEventArgs);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,8 +25,11 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
private readonly IMemberGroupService _memberGroupService;
|
||||
private readonly EntityXmlSerializer _entitySerializer = new EntityXmlSerializer();
|
||||
private readonly IDataTypeService _dataTypeService;
|
||||
private static readonly ReaderWriterLockSlim Locker = new ReaderWriterLockSlim();
|
||||
private readonly IDataTypeService _dataTypeService;
|
||||
private static readonly ReaderWriterLockSlim Locker = new ReaderWriterLockSlim();
|
||||
|
||||
//only for unit tests!
|
||||
internal MembershipProviderBase MembershipProvider { get; set; }
|
||||
|
||||
public MemberService(IDatabaseUnitOfWorkProvider provider, RepositoryFactory repositoryFactory, ILogger logger, IEventMessagesFactory eventMessagesFactory, IMemberGroupService memberGroupService, IDataTypeService dataTypeService)
|
||||
: base(provider, repositoryFactory, logger, eventMessagesFactory)
|
||||
@@ -35,7 +38,7 @@ namespace Umbraco.Core.Services
|
||||
if (dataTypeService == null) throw new ArgumentNullException("dataTypeService");
|
||||
_memberGroupService = memberGroupService;
|
||||
_dataTypeService = dataTypeService;
|
||||
}
|
||||
}
|
||||
|
||||
#region IMemberService Implementation
|
||||
|
||||
@@ -91,7 +94,7 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
if (member == null) throw new ArgumentNullException("member");
|
||||
|
||||
var provider = MembershipProviderExtensions.GetMembersMembershipProvider();
|
||||
var provider = MembershipProvider ?? MembershipProviderExtensions.GetMembersMembershipProvider();
|
||||
if (provider.IsUmbracoMembershipProvider())
|
||||
{
|
||||
provider.ChangePassword(member.Username, "", password);
|
||||
@@ -234,7 +237,8 @@ namespace Umbraco.Core.Services
|
||||
var query = Query<IMember>.Builder.Where(x => x.ContentTypeId == memberTypeId);
|
||||
var members = repository.GetByQuery(query).ToArray();
|
||||
|
||||
if (uow.Events.DispatchCancelable(Deleting, this, new DeleteEventArgs<IMember>(members)))
|
||||
var deleteEventArgs = new DeleteEventArgs<IMember>(members);
|
||||
if (uow.Events.DispatchCancelable(Deleting, this, deleteEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
@@ -826,6 +830,22 @@ namespace Umbraco.Core.Services
|
||||
return CreateMemberWithIdentity(username, email, username, passwordValue, memberType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and persists a new <see cref="IMember"/>
|
||||
/// </summary>
|
||||
/// <remarks>An <see cref="IMembershipUser"/> can be of type <see cref="IMember"/> or <see cref="IUser"/></remarks>
|
||||
/// <param name="username">Username of the <see cref="IMembershipUser"/> to create</param>
|
||||
/// <param name="email">Email of the <see cref="IMembershipUser"/> to create</param>
|
||||
/// <param name="passwordValue">This value should be the encoded/encrypted/hashed value for the password that will be stored in the database</param>
|
||||
/// <param name="memberTypeAlias">Alias of the Type</param>
|
||||
/// <param name="isApproved">Is the member approved</param>
|
||||
/// <returns><see cref="IMember"/></returns>
|
||||
IMember IMembershipMemberService<IMember>.CreateWithIdentity(string username, string email, string passwordValue, string memberTypeAlias, bool isApproved)
|
||||
{
|
||||
var memberType = FindMemberTypeByAlias(memberTypeAlias);
|
||||
return CreateMemberWithIdentity(username, email, username, passwordValue, memberType, isApproved);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and persists a Member
|
||||
/// </summary>
|
||||
@@ -836,16 +856,18 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="name">Name of the Member to create</param>
|
||||
/// <param name="passwordValue">This value should be the encoded/encrypted/hashed value for the password that will be stored in the database</param>
|
||||
/// <param name="memberType">MemberType the Member should be based on</param>
|
||||
/// <param name="isApproved">Optional IsApproved of the Member to create</param>
|
||||
/// <returns><see cref="IMember"/></returns>
|
||||
private IMember CreateMemberWithIdentity(string username, string email, string name, string passwordValue, IMemberType memberType)
|
||||
private IMember CreateMemberWithIdentity(string username, string email, string name, string passwordValue, IMemberType memberType, bool isApproved = true)
|
||||
{
|
||||
if (memberType == null) throw new ArgumentNullException("memberType");
|
||||
|
||||
var member = new Member(name, email.ToLower().Trim(), username, passwordValue, memberType);
|
||||
var member = new Member(name, email.ToLower().Trim(), username, passwordValue, memberType, isApproved);
|
||||
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(Saving, this, new SaveEventArgs<IMember>(member)))
|
||||
var saveEventArgs = new SaveEventArgs<IMember>(member);
|
||||
if (uow.Events.DispatchCancelable(Saving, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
member.WasCancelled = true;
|
||||
@@ -864,7 +886,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
uow.Commit();
|
||||
|
||||
uow.Events.Dispatch(Saved, this, new SaveEventArgs<IMember>(member, false));
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Saved, this, saveEventArgs);
|
||||
uow.Events.Dispatch(Created, this, new NewEventArgs<IMember>(member, false, memberType.Alias, -1));
|
||||
}
|
||||
|
||||
@@ -941,7 +964,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
private void Delete(IScopeUnitOfWork uow, IMember member)
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(Deleting, this, new DeleteEventArgs<IMember>(member)))
|
||||
var deleteEventArgs = new DeleteEventArgs<IMember>(member);
|
||||
if (uow.Events.DispatchCancelable(Deleting, this, deleteEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
@@ -951,8 +975,8 @@ namespace Umbraco.Core.Services
|
||||
repository.Delete(member);
|
||||
uow.Commit();
|
||||
|
||||
var args = new DeleteEventArgs<IMember>(member, false);
|
||||
uow.Events.Dispatch(Deleted, this, args);
|
||||
deleteEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Deleted, this, deleteEventArgs);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -965,9 +989,10 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
var saveEventArgs = new SaveEventArgs<IMember>(entity);
|
||||
if (raiseEvents)
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(Saving, this, new SaveEventArgs<IMember>(entity)))
|
||||
if (uow.Events.DispatchCancelable(Saving, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
@@ -991,7 +1016,10 @@ namespace Umbraco.Core.Services
|
||||
uow.Commit();
|
||||
|
||||
if (raiseEvents)
|
||||
uow.Events.Dispatch(Saved, this, new SaveEventArgs<IMember>(entity, false));
|
||||
{
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Saved, this, saveEventArgs);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1010,7 +1038,8 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (raiseEvents && uow.Events.DispatchCancelable(Saving, this, new SaveEventArgs<IMember>(asArray)))
|
||||
var saveEventArgs = new SaveEventArgs<IMember>(asArray);
|
||||
if (raiseEvents && uow.Events.DispatchCancelable(Saving, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
@@ -1032,7 +1061,10 @@ namespace Umbraco.Core.Services
|
||||
uow.Commit();
|
||||
|
||||
if (raiseEvents)
|
||||
uow.Events.Dispatch(Saved, this, new SaveEventArgs<IMember>(asArray, false));
|
||||
{
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Saved, this, saveEventArgs);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -80,7 +80,8 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(Saving, this, new SaveEventArgs<IMemberType>(memberType)))
|
||||
var saveEventArgs = new SaveEventArgs<IMemberType>(memberType);
|
||||
if (uow.Events.DispatchCancelable(Saving, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
@@ -101,7 +102,8 @@ namespace Umbraco.Core.Services
|
||||
UpdateContentXmlStructure(memberType);
|
||||
uow.Commit(); // actually commit uow
|
||||
|
||||
uow.Events.Dispatch(Saved, this, new SaveEventArgs<IMemberType>(memberType, false));
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Saved, this, saveEventArgs);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -114,7 +116,8 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(Saving, this, new SaveEventArgs<IMemberType>(asArray)))
|
||||
var saveEventArgs = new SaveEventArgs<IMemberType>(asArray);
|
||||
if (uow.Events.DispatchCancelable(Saving, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
@@ -131,8 +134,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
UpdateContentXmlStructure(asArray.Cast<IContentTypeBase>().ToArray());
|
||||
uow.Commit(); // actually commit uow
|
||||
|
||||
uow.Events.Dispatch(Saved, this, new SaveEventArgs<IMemberType>(asArray, false));
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Saved, this, saveEventArgs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,10 +145,11 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
var deleteEventArgs = new DeleteEventArgs<IMemberType>(memberType);
|
||||
using (var scope = UowProvider.ScopeProvider.CreateScope())
|
||||
{
|
||||
scope.Complete(); // always
|
||||
if (scope.Events.DispatchCancelable(Deleting, this, new DeleteEventArgs<IMemberType>(memberType)))
|
||||
scope.Complete(); // always
|
||||
if (scope.Events.DispatchCancelable(Deleting, this, deleteEventArgs))
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -157,7 +161,8 @@ namespace Umbraco.Core.Services
|
||||
repository.Delete(memberType);
|
||||
uow.Commit();
|
||||
|
||||
uow.Events.Dispatch(Deleted, this, new DeleteEventArgs<IMemberType>(memberType, false));
|
||||
deleteEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Deleted, this, deleteEventArgs);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -168,10 +173,11 @@ namespace Umbraco.Core.Services
|
||||
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
var deleteEventArgs = new DeleteEventArgs<IMemberType>(asArray);
|
||||
using (var scope = UowProvider.ScopeProvider.CreateScope())
|
||||
{
|
||||
scope.Complete(); // always
|
||||
if (scope.Events.DispatchCancelable(Deleting, this, new DeleteEventArgs<IMemberType>(asArray)))
|
||||
scope.Complete(); // always
|
||||
if (scope.Events.DispatchCancelable(Deleting, this, deleteEventArgs))
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -189,8 +195,8 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
|
||||
uow.Commit();
|
||||
|
||||
uow.Events.Dispatch(Deleted, this, new DeleteEventArgs<IMemberType>(asArray, false));
|
||||
deleteEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Deleted, this, deleteEventArgs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,18 +89,18 @@ namespace Umbraco.Core.Services
|
||||
/// <returns></returns>
|
||||
public string FetchPackageFile(Guid packageId, Version umbracoVersion, int userId)
|
||||
{
|
||||
var packageRepo = UmbracoConfig.For.UmbracoSettings().PackageRepositories.GetDefault();
|
||||
var packageRepo = UmbracoConfig.For.UmbracoSettings().PackageRepositories.GetDefault();
|
||||
|
||||
using (var httpClient = new HttpClient())
|
||||
using (var uow = _uowProvider.GetUnitOfWork())
|
||||
{
|
||||
{
|
||||
//includeHidden = true because we don't care if it's hidden we want to get the file regardless
|
||||
var url = string.Format("{0}/{1}?version={2}&includeHidden=true&asFile=true", packageRepo.RestApiUrl, packageId, umbracoVersion.ToString(3));
|
||||
byte[] bytes;
|
||||
try
|
||||
{
|
||||
bytes = httpClient.GetByteArrayAsync(url).GetAwaiter().GetResult();
|
||||
}
|
||||
try
|
||||
{
|
||||
bytes = httpClient.GetByteArrayAsync(url).GetAwaiter().GetResult();
|
||||
}
|
||||
catch (HttpRequestException ex)
|
||||
{
|
||||
throw new ConnectionException("An error occuring downloading the package from " + url, ex);
|
||||
@@ -109,20 +109,20 @@ namespace Umbraco.Core.Services
|
||||
//successfull
|
||||
if (bytes.Length > 0)
|
||||
{
|
||||
var packagePath = IOHelper.MapPath(SystemDirectories.Packages);
|
||||
var packagePath = IOHelper.MapPath(SystemDirectories.Packages);
|
||||
|
||||
// Check for package directory
|
||||
if (Directory.Exists(packagePath) == false)
|
||||
Directory.CreateDirectory(packagePath);
|
||||
|
||||
var packageFilePath = Path.Combine(packagePath, packageId + ".umb");
|
||||
var packageFilePath = Path.Combine(packagePath, packageId + ".umb");
|
||||
|
||||
using (var fs1 = new FileStream(packageFilePath, FileMode.Create))
|
||||
{
|
||||
fs1.Write(bytes, 0, bytes.Length);
|
||||
return "packages\\" + packageId + ".umb";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Audit(uow, AuditType.PackagerInstall, string.Format("Package {0} fetched from {1}", packageId, packageRepo.Id), userId, -1);
|
||||
return null;
|
||||
@@ -133,7 +133,7 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
var auditRepo = _repositoryFactory.CreateAuditRepository(uow);
|
||||
auditRepo.AddOrUpdate(new AuditItem(objectId, message, type, userId));
|
||||
}
|
||||
}
|
||||
|
||||
#region Content
|
||||
|
||||
@@ -285,6 +285,7 @@ namespace Umbraco.Core.Services
|
||||
var nodeName = element.Attribute("nodeName").Value;
|
||||
var path = element.Attribute("path").Value;
|
||||
var template = element.Attribute("template").Value;
|
||||
var key = Guid.Empty;
|
||||
|
||||
var properties = from property in element.Elements()
|
||||
where property.Attribute("isDoc") == null
|
||||
@@ -302,6 +303,12 @@ namespace Umbraco.Core.Services
|
||||
SortOrder = int.Parse(sortOrder)
|
||||
};
|
||||
|
||||
if (element.Attribute("key") != null && Guid.TryParse(element.Attribute("key").Value, out key))
|
||||
{
|
||||
// update the Guid (for UDI support)
|
||||
content.Key = key;
|
||||
}
|
||||
|
||||
foreach (var property in properties)
|
||||
{
|
||||
string propertyTypeAlias = isLegacySchema ? property.Attribute("alias").Value : property.Name.LocalName;
|
||||
@@ -520,7 +527,7 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
var foldersAttribute = documentType.Attribute("Folders");
|
||||
var infoElement = documentType.Element("Info");
|
||||
if (foldersAttribute != null && infoElement != null
|
||||
if (foldersAttribute != null && infoElement != null
|
||||
//don't import any folder if this is a child doc type - the parent doc type will need to
|
||||
//exist which contains it's folders
|
||||
&& ((string)infoElement.Element("Master")).IsNullOrWhiteSpace())
|
||||
@@ -1041,7 +1048,7 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
_logger.Error<PackagingService>("Could not create folder: " + rootFolder, tryCreateFolder.Exception);
|
||||
throw tryCreateFolder.Exception;
|
||||
}
|
||||
}
|
||||
current = _dataTypeService.GetContainer(tryCreateFolder.Result.Entity.Id);
|
||||
}
|
||||
|
||||
@@ -1091,14 +1098,14 @@ namespace Umbraco.Core.Services
|
||||
if (dataTypeDefinition != null)
|
||||
{
|
||||
var valuesWithoutKeys = prevaluesElement.Elements("PreValue")
|
||||
.Where(x => ((string) x.Attribute("Alias")).IsNullOrWhiteSpace())
|
||||
.Where(x => ((string)x.Attribute("Alias")).IsNullOrWhiteSpace())
|
||||
.Select(x => x.Attribute("Value").Value);
|
||||
|
||||
var valuesWithKeys = prevaluesElement.Elements("PreValue")
|
||||
.Where(x => ((string) x.Attribute("Alias")).IsNullOrWhiteSpace() == false)
|
||||
.Where(x => ((string)x.Attribute("Alias")).IsNullOrWhiteSpace() == false)
|
||||
.ToDictionary(
|
||||
key => (string) key.Attribute("Alias"),
|
||||
val => new PreValue((string) val.Attribute("Value")));
|
||||
key => (string)key.Attribute("Alias"),
|
||||
val => new PreValue((string)val.Attribute("Value")));
|
||||
|
||||
//save the values with keys
|
||||
_dataTypeService.SavePreValues(dataTypeDefinition, valuesWithKeys);
|
||||
@@ -1956,12 +1963,12 @@ namespace Umbraco.Core.Services
|
||||
/// <summary>
|
||||
/// Occurs after a package is imported
|
||||
/// </summary>
|
||||
internal static event TypedEventHandler<IPackagingService, ImportPackageEventArgs<InstallationSummary>> ImportedPackage;
|
||||
public static event TypedEventHandler<IPackagingService, ImportPackageEventArgs<InstallationSummary>> ImportedPackage;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs after a package is uninstalled
|
||||
/// </summary>
|
||||
internal static event TypedEventHandler<IPackagingService, UninstallPackageEventArgs<UninstallationSummary>> UninstalledPackage;
|
||||
public static event TypedEventHandler<IPackagingService, UninstallPackageEventArgs<UninstallationSummary>> UninstalledPackage;
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -148,7 +148,8 @@ namespace Umbraco.Core.Services
|
||||
return Attempt<OperationStatus<PublicAccessEntry, OperationStatusType>>.Succeed(new OperationStatus<PublicAccessEntry, OperationStatusType>(entry, OperationStatusType.Success, evtMsgs));
|
||||
}
|
||||
|
||||
if (uow.Events.DispatchCancelable(Saving, this, new SaveEventArgs<PublicAccessEntry>(entry, evtMsgs)))
|
||||
var saveEventArgs = new SaveEventArgs<PublicAccessEntry>(entry, evtMsgs);
|
||||
if (uow.Events.DispatchCancelable(Saving, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return Attempt<OperationStatus<PublicAccessEntry, OperationStatusType>>.Fail(
|
||||
@@ -158,8 +159,8 @@ namespace Umbraco.Core.Services
|
||||
repo.AddOrUpdate(entry);
|
||||
|
||||
uow.Commit();
|
||||
|
||||
uow.Events.Dispatch(Saved, this, new SaveEventArgs<PublicAccessEntry>(entry, false, evtMsgs));
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Saved, this, saveEventArgs);
|
||||
return Attempt<OperationStatus<PublicAccessEntry, OperationStatusType>>.Succeed(
|
||||
new OperationStatus<PublicAccessEntry, OperationStatusType>(entry, OperationStatusType.Success, evtMsgs));
|
||||
}
|
||||
@@ -193,7 +194,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
entry.RemoveRule(existingRule);
|
||||
|
||||
if (uow.Events.DispatchCancelable(Saving, this, new SaveEventArgs<PublicAccessEntry>(entry, evtMsgs)))
|
||||
var saveEventArgs = new SaveEventArgs<PublicAccessEntry>(entry, evtMsgs);
|
||||
if (uow.Events.DispatchCancelable(Saving, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return OperationStatus.Cancelled(evtMsgs);
|
||||
@@ -202,8 +204,8 @@ namespace Umbraco.Core.Services
|
||||
repo.AddOrUpdate(entry);
|
||||
|
||||
uow.Commit();
|
||||
|
||||
uow.Events.Dispatch(Saved, this, new SaveEventArgs<PublicAccessEntry>(entry, false, evtMsgs));
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Saved, this, saveEventArgs);
|
||||
return OperationStatus.Success(evtMsgs);
|
||||
}
|
||||
|
||||
@@ -219,7 +221,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(Saving, this, new SaveEventArgs<PublicAccessEntry>(entry, evtMsgs)))
|
||||
var saveEventArgs = new SaveEventArgs<PublicAccessEntry>(entry, evtMsgs);
|
||||
if (uow.Events.DispatchCancelable(Saving, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return OperationStatus.Cancelled(evtMsgs);
|
||||
@@ -228,7 +231,8 @@ namespace Umbraco.Core.Services
|
||||
var repo = RepositoryFactory.CreatePublicAccessRepository(uow);
|
||||
repo.AddOrUpdate(entry);
|
||||
uow.Commit();
|
||||
uow.Events.Dispatch(Saved, this, new SaveEventArgs<PublicAccessEntry>(entry, false, evtMsgs));
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Saved, this, saveEventArgs);
|
||||
return OperationStatus.Success(evtMsgs);
|
||||
}
|
||||
|
||||
@@ -245,7 +249,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(Deleting, this, new DeleteEventArgs<PublicAccessEntry>(entry, evtMsgs)))
|
||||
var deleteEventArgs = new DeleteEventArgs<PublicAccessEntry>(entry, evtMsgs);
|
||||
if (uow.Events.DispatchCancelable(Deleting, this, deleteEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return OperationStatus.Cancelled(evtMsgs);
|
||||
@@ -254,7 +259,8 @@ namespace Umbraco.Core.Services
|
||||
var repo = RepositoryFactory.CreatePublicAccessRepository(uow);
|
||||
repo.Delete(entry);
|
||||
uow.Commit();
|
||||
uow.Events.Dispatch(Deleted, this, new DeleteEventArgs<PublicAccessEntry>(entry, false, evtMsgs));
|
||||
deleteEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(Deleted, this, deleteEventArgs);
|
||||
return OperationStatus.Success(evtMsgs);
|
||||
}
|
||||
|
||||
|
||||
@@ -72,10 +72,28 @@ namespace Umbraco.Core.Services
|
||||
|
||||
public static bool HasAccess(this IPublicAccessService publicAccessService, string path, MembershipUser member, RoleProvider roleProvider)
|
||||
{
|
||||
return publicAccessService.HasAccess(path, member.UserName, roleProvider.GetRolesForUser);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the member with the specified username has access to the path which is also based on the passed in roles for the member
|
||||
/// </summary>
|
||||
/// <param name="publicAccessService"></param>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="username"></param>
|
||||
/// <param name="rolesCallback">A callback to retrieve the roles for this member</param>
|
||||
/// <returns></returns>
|
||||
public static bool HasAccess(this IPublicAccessService publicAccessService, string path, string username, Func<string, IEnumerable<string>> rolesCallback)
|
||||
{
|
||||
if (rolesCallback == null) throw new ArgumentNullException("roles");
|
||||
if (string.IsNullOrWhiteSpace(username)) throw new ArgumentException("Value cannot be null or whitespace.", "username");
|
||||
if (string.IsNullOrWhiteSpace(path)) throw new ArgumentException("Value cannot be null or whitespace.", "path");
|
||||
|
||||
var entry = publicAccessService.GetEntryForContent(path.EnsureEndsWith(path));
|
||||
if (entry == null) return true;
|
||||
|
||||
var roles = roleProvider.GetRolesForUser(member.UserName);
|
||||
var roles = rolesCallback(username);
|
||||
|
||||
return entry.Rules.Any(x => x.RuleType == Constants.Conventions.PublicAccess.MemberRoleRuleType
|
||||
&& roles.Contains(x.RuleValue));
|
||||
}
|
||||
|
||||
@@ -412,7 +412,8 @@ namespace Umbraco.Core.Services
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
var repository = RepositoryFactory.CreateRelationRepository(uow);
|
||||
if (uow.Events.DispatchCancelable(SavingRelation, this, new SaveEventArgs<IRelation>(relation)))
|
||||
var saveEventArgs = new SaveEventArgs<IRelation>(relation);
|
||||
if (uow.Events.DispatchCancelable(SavingRelation, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return relation;
|
||||
@@ -420,7 +421,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
repository.AddOrUpdate(relation);
|
||||
uow.Commit();
|
||||
uow.Events.Dispatch(SavedRelation, this, new SaveEventArgs<IRelation>(relation, false));
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(SavedRelation, this, saveEventArgs);
|
||||
return relation;
|
||||
}
|
||||
}
|
||||
@@ -442,7 +444,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(SavingRelation, this, new SaveEventArgs<IRelation>(relation)))
|
||||
var saveEventArgs = new SaveEventArgs<IRelation>(relation);
|
||||
if (uow.Events.DispatchCancelable(SavingRelation, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return relation;
|
||||
@@ -450,8 +453,8 @@ namespace Umbraco.Core.Services
|
||||
var repository = RepositoryFactory.CreateRelationRepository(uow);
|
||||
repository.AddOrUpdate(relation);
|
||||
uow.Commit();
|
||||
|
||||
uow.Events.Dispatch(SavedRelation, this, new SaveEventArgs<IRelation>(relation, false));
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(SavedRelation, this, saveEventArgs);
|
||||
return relation;
|
||||
}
|
||||
}
|
||||
@@ -568,7 +571,8 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(SavingRelation, this, new SaveEventArgs<IRelation>(relation)))
|
||||
var saveEventArgs = new SaveEventArgs<IRelation>(relation);
|
||||
if (uow.Events.DispatchCancelable(SavingRelation, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
@@ -576,7 +580,8 @@ namespace Umbraco.Core.Services
|
||||
var repository = RepositoryFactory.CreateRelationRepository(uow);
|
||||
repository.AddOrUpdate(relation);
|
||||
uow.Commit();
|
||||
uow.Events.Dispatch(SavedRelation, this, new SaveEventArgs<IRelation>(relation, false));
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(SavedRelation, this, saveEventArgs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -588,7 +593,8 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(SavingRelationType, this, new SaveEventArgs<IRelationType>(relationType)))
|
||||
var saveEventArgs = new SaveEventArgs<IRelationType>(relationType);
|
||||
if (uow.Events.DispatchCancelable(SavingRelationType, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
@@ -596,7 +602,8 @@ namespace Umbraco.Core.Services
|
||||
var repository = RepositoryFactory.CreateRelationTypeRepository(uow);
|
||||
repository.AddOrUpdate(relationType);
|
||||
uow.Commit();
|
||||
uow.Events.Dispatch(SavedRelationType, this, new SaveEventArgs<IRelationType>(relationType, false));
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(SavedRelationType, this, saveEventArgs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -608,7 +615,8 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(DeletingRelation, this, new DeleteEventArgs<IRelation>(relation)))
|
||||
var deleteEventArgs = new DeleteEventArgs<IRelation>(relation);
|
||||
if (uow.Events.DispatchCancelable(DeletingRelation, this, deleteEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
@@ -616,7 +624,8 @@ namespace Umbraco.Core.Services
|
||||
var repository = RepositoryFactory.CreateRelationRepository(uow);
|
||||
repository.Delete(relation);
|
||||
uow.Commit();
|
||||
uow.Events.Dispatch(DeletedRelation, this, new DeleteEventArgs<IRelation>(relation, false));
|
||||
deleteEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(DeletedRelation, this, deleteEventArgs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -628,7 +637,8 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(DeletingRelationType, this, new DeleteEventArgs<IRelationType>(relationType)))
|
||||
var deleteEventArgs = new DeleteEventArgs<IRelationType>(relationType);
|
||||
if (uow.Events.DispatchCancelable(DeletingRelationType, this, deleteEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
@@ -636,7 +646,8 @@ namespace Umbraco.Core.Services
|
||||
var repository = RepositoryFactory.CreateRelationTypeRepository(uow);
|
||||
repository.Delete(relationType);
|
||||
uow.Commit();
|
||||
uow.Events.Dispatch(DeletedRelationType, this, new DeleteEventArgs<IRelationType>(relationType, false));
|
||||
deleteEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(DeletedRelationType, this, deleteEventArgs);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -63,6 +63,8 @@ namespace Umbraco.Core.Services
|
||||
private Lazy<IExternalLoginService> _externalLoginService;
|
||||
private Lazy<IRedirectUrlService> _redirectUrlService;
|
||||
|
||||
internal IdkMap IdkMap { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// public ctor - will generally just be used for unit testing all items are optional and if not specified, the defaults will be used
|
||||
/// </summary>
|
||||
@@ -171,9 +173,11 @@ namespace Umbraco.Core.Services
|
||||
|
||||
EventMessagesFactory = eventMessagesFactory;
|
||||
|
||||
IdkMap = new IdkMap(provider);
|
||||
|
||||
BuildServiceCache(provider, cache,
|
||||
repositoryFactory,
|
||||
logger, eventMessagesFactory);
|
||||
logger, eventMessagesFactory, IdkMap);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -184,7 +188,8 @@ namespace Umbraco.Core.Services
|
||||
CacheHelper cache,
|
||||
RepositoryFactory repositoryFactory,
|
||||
ILogger logger,
|
||||
IEventMessagesFactory eventMessagesFactory)
|
||||
IEventMessagesFactory eventMessagesFactory,
|
||||
IdkMap idkMap)
|
||||
{
|
||||
EventMessagesFactory = eventMessagesFactory;
|
||||
|
||||
@@ -256,10 +261,10 @@ namespace Umbraco.Core.Services
|
||||
_memberService = new Lazy<IMemberService>(() => new MemberService(provider, repositoryFactory, logger, eventMessagesFactory, _memberGroupService.Value, _dataTypeService.Value));
|
||||
|
||||
if (_contentService == null)
|
||||
_contentService = new Lazy<IContentService>(() => new ContentService(provider, repositoryFactory, logger, eventMessagesFactory, _dataTypeService.Value, _userService.Value));
|
||||
_contentService = new Lazy<IContentService>(() => new ContentService(provider, repositoryFactory, logger, eventMessagesFactory, _dataTypeService.Value, _userService.Value, idkMap));
|
||||
|
||||
if (_mediaService == null)
|
||||
_mediaService = new Lazy<IMediaService>(() => new MediaService(provider, repositoryFactory, logger, eventMessagesFactory, _dataTypeService.Value, _userService.Value));
|
||||
_mediaService = new Lazy<IMediaService>(() => new MediaService(provider, repositoryFactory, logger, eventMessagesFactory, _dataTypeService.Value, _userService.Value, idkMap));
|
||||
|
||||
if (_contentTypeService == null)
|
||||
_contentTypeService = new Lazy<IContentTypeService>(() => new ContentTypeService(provider, repositoryFactory, logger, eventMessagesFactory, _contentService.Value, _mediaService.Value));
|
||||
@@ -277,8 +282,7 @@ namespace Umbraco.Core.Services
|
||||
_entityService = new Lazy<IEntityService>(() => new EntityService(
|
||||
provider, repositoryFactory, logger, eventMessagesFactory,
|
||||
_contentService.Value, _contentTypeService.Value, _mediaService.Value, _dataTypeService.Value, _memberService.Value, _memberTypeService.Value,
|
||||
//TODO: Consider making this an isolated cache instead of using the global one
|
||||
cache.RuntimeCache));
|
||||
idkMap));
|
||||
|
||||
if (_packagingService == null)
|
||||
_packagingService = new Lazy<IPackagingService>(() => new PackagingService(logger, _contentService.Value, _contentTypeService.Value, _mediaService.Value, _macroService.Value, _dataTypeService.Value, _fileService.Value, _localizationService.Value, _entityService.Value, _userService.Value, repositoryFactory, provider));
|
||||
|
||||
@@ -19,7 +19,6 @@ namespace Umbraco.Core.Services
|
||||
/// </summary>
|
||||
public class UserService : ScopeRepositoryService, IUserService
|
||||
{
|
||||
|
||||
//TODO: We need to change the isUpgrading flag to use an app state enum as described here: http://issues.umbraco.org/issue/U4-6816
|
||||
// in the meantime, we will use a boolean which we are currently using during upgrades to ensure that a user object is not persisted during this phase, otherwise
|
||||
// exceptions can occur if the db is not in it's correct state.
|
||||
@@ -113,6 +112,26 @@ namespace Umbraco.Core.Services
|
||||
return CreateUserWithIdentity(username, email, passwordValue, userType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and persists a new <see cref="IUser"/>
|
||||
/// </summary>
|
||||
/// <param name="username">Username of the <see cref="IUser"/> to create</param>
|
||||
/// <param name="email">Email of the <see cref="IUser"/> to create</param>
|
||||
/// <param name="passwordValue">This value should be the encoded/encrypted/hashed value for the password that will be stored in the database</param>
|
||||
/// <param name="memberTypeAlias">Alias of the Type</param>
|
||||
/// <param name="isApproved">Is the member approved</param>
|
||||
/// <returns><see cref="IUser"/></returns>
|
||||
IUser IMembershipMemberService<IUser>.CreateWithIdentity(string username, string email, string passwordValue, string memberTypeAlias, bool isApproved)
|
||||
{
|
||||
var userType = GetUserTypeByAlias(memberTypeAlias);
|
||||
if (userType == null)
|
||||
{
|
||||
throw new EntityNotFoundException("The user type " + memberTypeAlias + " could not be resolved");
|
||||
}
|
||||
|
||||
return CreateUserWithIdentity(username, email, passwordValue, userType, isApproved);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and persists a Member
|
||||
/// </summary>
|
||||
@@ -122,8 +141,9 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="email">Email of the Member to create</param>
|
||||
/// <param name="passwordValue">This value should be the encoded/encrypted/hashed value for the password that will be stored in the database</param>
|
||||
/// <param name="userType">MemberType the Member should be based on</param>
|
||||
/// <param name="isApproved">Is the user approved</param>
|
||||
/// <returns><see cref="IUser"/></returns>
|
||||
private IUser CreateUserWithIdentity(string username, string email, string passwordValue, IUserType userType)
|
||||
private IUser CreateUserWithIdentity(string username, string email, string passwordValue, IUserType userType, bool isApproved = true)
|
||||
{
|
||||
if (userType == null) throw new ArgumentNullException("userType");
|
||||
|
||||
@@ -152,13 +172,14 @@ namespace Umbraco.Core.Services
|
||||
StartContentId = -1,
|
||||
StartMediaId = -1,
|
||||
IsLockedOut = false,
|
||||
IsApproved = true
|
||||
IsApproved = isApproved
|
||||
};
|
||||
//adding default sections content and media
|
||||
user.AddAllowedSection("content");
|
||||
user.AddAllowedSection("media");
|
||||
|
||||
if (uow.Events.DispatchCancelable(SavingUser, this, new SaveEventArgs<IUser>(user)))
|
||||
var saveEventArgs = new SaveEventArgs<IUser>(user);
|
||||
if (uow.Events.DispatchCancelable(SavingUser, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return user;
|
||||
@@ -166,8 +187,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
repository.AddOrUpdate(user);
|
||||
uow.Commit();
|
||||
|
||||
uow.Events.Dispatch(SavedUser, this, new SaveEventArgs<IUser>(user, false));
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(SavedUser, this, saveEventArgs);
|
||||
|
||||
return user;
|
||||
}
|
||||
@@ -294,7 +315,8 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(DeletingUser, this, new DeleteEventArgs<IUser>(user)))
|
||||
var deleteEventArgs = new DeleteEventArgs<IUser>(user);
|
||||
if (uow.Events.DispatchCancelable(DeletingUser, this, deleteEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
@@ -302,7 +324,8 @@ namespace Umbraco.Core.Services
|
||||
var repository = RepositoryFactory.CreateUserRepository(uow);
|
||||
repository.Delete(user);
|
||||
uow.Commit();
|
||||
uow.Events.Dispatch(DeletedUser, this, new DeleteEventArgs<IUser>(user, false));
|
||||
deleteEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(DeletedUser, this, deleteEventArgs);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -317,7 +340,8 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (raiseEvents && uow.Events.DispatchCancelable(SavingUser, this, new SaveEventArgs<IUser>(entity)))
|
||||
var saveEventArgs = new SaveEventArgs<IUser>(entity);
|
||||
if (raiseEvents && uow.Events.DispatchCancelable(SavingUser, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
@@ -343,7 +367,10 @@ namespace Umbraco.Core.Services
|
||||
uow.Commit();
|
||||
|
||||
if (raiseEvents)
|
||||
uow.Events.Dispatch(SavedUser, this, new SaveEventArgs<IUser>(entity, false));
|
||||
{
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(SavedUser, this, saveEventArgs);
|
||||
}
|
||||
}
|
||||
catch (DbException ex)
|
||||
{
|
||||
@@ -371,9 +398,10 @@ namespace Umbraco.Core.Services
|
||||
var asArray = entities.ToArray();
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
var saveEventArgs = new SaveEventArgs<IUser>(asArray);
|
||||
if (raiseEvents)
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(SavingUser, this, new SaveEventArgs<IUser>(asArray)))
|
||||
if (uow.Events.DispatchCancelable(SavingUser, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
@@ -396,7 +424,10 @@ namespace Umbraco.Core.Services
|
||||
uow.Commit();
|
||||
|
||||
if (raiseEvents)
|
||||
uow.Events.Dispatch(SavedUser, this, new SaveEventArgs<IUser>(asArray, false));
|
||||
{
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(SavedUser, this, saveEventArgs);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -699,7 +730,8 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (raiseEvents && uow.Events.DispatchCancelable(SavingUserType, this, new SaveEventArgs<IUserType>(userType)))
|
||||
var saveEventArgs = new SaveEventArgs<IUserType>(userType);
|
||||
if (raiseEvents && uow.Events.DispatchCancelable(SavingUserType, this, saveEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
@@ -709,7 +741,10 @@ namespace Umbraco.Core.Services
|
||||
repository.AddOrUpdate(userType);
|
||||
uow.Commit();
|
||||
if (raiseEvents)
|
||||
uow.Events.Dispatch(SavedUserType, this, new SaveEventArgs<IUserType>(userType, false));
|
||||
{
|
||||
saveEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(SavedUserType, this, saveEventArgs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -721,7 +756,8 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
if (uow.Events.DispatchCancelable(DeletingUserType, this, new DeleteEventArgs<IUserType>(userType)))
|
||||
var deleteEventArgs = new DeleteEventArgs<IUserType>(userType);
|
||||
if (uow.Events.DispatchCancelable(DeletingUserType, this, deleteEventArgs))
|
||||
{
|
||||
uow.Commit();
|
||||
return;
|
||||
@@ -729,7 +765,8 @@ namespace Umbraco.Core.Services
|
||||
var repository = RepositoryFactory.CreateUserTypeRepository(uow);
|
||||
repository.Delete(userType);
|
||||
uow.Commit();
|
||||
uow.Events.Dispatch(DeletedUserType, this, new DeleteEventArgs<IUserType>(userType, false));
|
||||
deleteEventArgs.CanCancel = false;
|
||||
uow.Events.Dispatch(DeletedUserType, this, deleteEventArgs);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -701,67 +701,72 @@ namespace Umbraco.Core
|
||||
return val;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a hash of a string based on the FIPS compliance setting.
|
||||
/// </summary>
|
||||
/// <param name="str">Referrs to itself</param>
|
||||
/// <returns>The hashed string</returns>
|
||||
public static string GenerateHash(this string str)
|
||||
{
|
||||
return CryptoConfig.AllowOnlyFipsAlgorithms
|
||||
? str.ToSHA1()
|
||||
: str.ToMd5();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the string to MD5
|
||||
/// </summary>
|
||||
/// <param name="stringToConvert">referrs to itself</param>
|
||||
/// <returns>the md5 hashed string</returns>
|
||||
/// <param name="stringToConvert">Referrs to itself</param>
|
||||
/// <returns>The MD5 hashed string</returns>
|
||||
public static string ToMd5(this string stringToConvert)
|
||||
{
|
||||
//create an instance of the MD5CryptoServiceProvider
|
||||
var md5Provider = new MD5CryptoServiceProvider();
|
||||
|
||||
//convert our string into byte array
|
||||
var byteArray = Encoding.UTF8.GetBytes(stringToConvert);
|
||||
|
||||
//get the hashed values created by our MD5CryptoServiceProvider
|
||||
var hashedByteArray = md5Provider.ComputeHash(byteArray);
|
||||
|
||||
//create a StringBuilder object
|
||||
var stringBuilder = new StringBuilder();
|
||||
|
||||
//loop to each each byte
|
||||
foreach (var b in hashedByteArray)
|
||||
{
|
||||
//append it to our StringBuilder
|
||||
stringBuilder.Append(b.ToString("x2").ToLower());
|
||||
}
|
||||
|
||||
//return the hashed value
|
||||
return stringBuilder.ToString();
|
||||
return stringToConvert.GenerateHash("MD5");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the string to SHA1
|
||||
/// </summary>
|
||||
/// <param name="stringToConvert">referrs to itself</param>
|
||||
/// <returns>the md5 hashed string</returns>
|
||||
/// <returns>The SHA1 hashed string</returns>
|
||||
public static string ToSHA1(this string stringToConvert)
|
||||
{
|
||||
//create an instance of the SHA1CryptoServiceProvider
|
||||
var md5Provider = new SHA1CryptoServiceProvider();
|
||||
|
||||
//convert our string into byte array
|
||||
var byteArray = Encoding.UTF8.GetBytes(stringToConvert);
|
||||
|
||||
//get the hashed values created by our SHA1CryptoServiceProvider
|
||||
var hashedByteArray = md5Provider.ComputeHash(byteArray);
|
||||
|
||||
//create a StringBuilder object
|
||||
var stringBuilder = new StringBuilder();
|
||||
|
||||
//loop to each each byte
|
||||
foreach (var b in hashedByteArray)
|
||||
{
|
||||
//append it to our StringBuilder
|
||||
stringBuilder.Append(b.ToString("x2").ToLower());
|
||||
}
|
||||
|
||||
//return the hashed value
|
||||
return stringBuilder.ToString();
|
||||
return stringToConvert.GenerateHash("SHA1");
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Generate a hash of a string based on the hashType passed in
|
||||
/// </summary>
|
||||
/// <param name="str">Referrs to itself</param>
|
||||
/// <param name="hashType">String with the hash type. See remarks section of the CryptoConfig Class in MSDN docs for a list of possible values.</param>
|
||||
/// <returns>The hashed string</returns>
|
||||
private static string GenerateHash(this string str, string hashType)
|
||||
{
|
||||
//create an instance of the correct hashing provider based on the type passed in
|
||||
var hasher = HashAlgorithm.Create(hashType);
|
||||
if (hasher == null) throw new InvalidOperationException("No hashing type found by name " + hashType);
|
||||
using (hasher)
|
||||
{
|
||||
//convert our string into byte array
|
||||
var byteArray = Encoding.UTF8.GetBytes(str);
|
||||
|
||||
//get the hashed values created by our selected provider
|
||||
var hashedByteArray = hasher.ComputeHash(byteArray);
|
||||
|
||||
//create a StringBuilder object
|
||||
var stringBuilder = new StringBuilder();
|
||||
|
||||
//loop to each each byte
|
||||
foreach (var b in hashedByteArray)
|
||||
{
|
||||
//append it to our StringBuilder
|
||||
stringBuilder.Append(b.ToString("x2"));
|
||||
}
|
||||
|
||||
//return the hashed value
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decodes a string that was encoded with UrlTokenEncode
|
||||
/// </summary>
|
||||
@@ -869,7 +874,7 @@ namespace Umbraco.Core
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures that the folder path endds with a DirectorySeperatorChar
|
||||
/// Ensures that the folder path ends with a DirectorySeperatorChar
|
||||
/// </summary>
|
||||
/// <param name="currentFolder"></param>
|
||||
/// <returns></returns>
|
||||
@@ -1465,10 +1470,84 @@ namespace Umbraco.Core
|
||||
/// <returns></returns>
|
||||
internal static Guid ToGuid(this string text)
|
||||
{
|
||||
var md5 = MD5.Create();
|
||||
byte[] myStringBytes = Encoding.ASCII.GetBytes(text);
|
||||
byte[] hash = md5.ComputeHash(myStringBytes);
|
||||
return new Guid(hash);
|
||||
return CreateGuidFromHash(UrlNamespace,
|
||||
text,
|
||||
CryptoConfig.AllowOnlyFipsAlgorithms
|
||||
? 5 // SHA1
|
||||
: 3); // MD5
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The namespace for URLs (from RFC 4122, Appendix C).
|
||||
///
|
||||
/// See <a href="http://www.ietf.org/rfc/rfc4122.txt">RFC 4122</a>
|
||||
/// </summary>
|
||||
internal static readonly Guid UrlNamespace = new Guid("6ba7b811-9dad-11d1-80b4-00c04fd430c8");
|
||||
|
||||
/// <summary>
|
||||
/// Creates a name-based UUID using the algorithm from RFC 4122 §4.3.
|
||||
///
|
||||
/// See <a href="https://github.com/LogosBible/Logos.Utility/blob/master/src/Logos.Utility/GuidUtility.cs#L34">GuidUtility.cs</a> for original implementation.
|
||||
/// </summary>
|
||||
/// <param name="namespaceId">The ID of the namespace.</param>
|
||||
/// <param name="name">The name (within that namespace).</param>
|
||||
/// <param name="version">The version number of the UUID to create; this value must be either
|
||||
/// 3 (for MD5 hashing) or 5 (for SHA-1 hashing).</param>
|
||||
/// <returns>A UUID derived from the namespace and name.</returns>
|
||||
/// <remarks>See <a href="http://code.logos.com/blog/2011/04/generating_a_deterministic_guid.html">Generating a deterministic GUID</a>.</remarks>
|
||||
internal static Guid CreateGuidFromHash(Guid namespaceId, string name, int version)
|
||||
{
|
||||
if (name == null)
|
||||
throw new ArgumentNullException("name");
|
||||
if (version != 3 && version != 5)
|
||||
throw new ArgumentOutOfRangeException("version", "version must be either 3 or 5.");
|
||||
|
||||
// convert the name to a sequence of octets (as defined by the standard or conventions of its namespace) (step 3)
|
||||
// ASSUME: UTF-8 encoding is always appropriate
|
||||
byte[] nameBytes = Encoding.UTF8.GetBytes(name);
|
||||
|
||||
// convert the namespace UUID to network order (step 3)
|
||||
byte[] namespaceBytes = namespaceId.ToByteArray();
|
||||
SwapByteOrder(namespaceBytes);
|
||||
|
||||
// comput the hash of the name space ID concatenated with the name (step 4)
|
||||
byte[] hash;
|
||||
using (HashAlgorithm algorithm = version == 3 ? (HashAlgorithm)MD5.Create() : SHA1.Create())
|
||||
{
|
||||
algorithm.TransformBlock(namespaceBytes, 0, namespaceBytes.Length, null, 0);
|
||||
algorithm.TransformFinalBlock(nameBytes, 0, nameBytes.Length);
|
||||
hash = algorithm.Hash;
|
||||
}
|
||||
|
||||
// most bytes from the hash are copied straight to the bytes of the new GUID (steps 5-7, 9, 11-12)
|
||||
byte[] newGuid = new byte[16];
|
||||
Array.Copy(hash, 0, newGuid, 0, 16);
|
||||
|
||||
// set the four most significant bits (bits 12 through 15) of the time_hi_and_version field to the appropriate 4-bit version number from Section 4.1.3 (step 8)
|
||||
newGuid[6] = (byte)((newGuid[6] & 0x0F) | (version << 4));
|
||||
|
||||
// set the two most significant bits (bits 6 and 7) of the clock_seq_hi_and_reserved to zero and one, respectively (step 10)
|
||||
newGuid[8] = (byte)((newGuid[8] & 0x3F) | 0x80);
|
||||
|
||||
// convert the resulting UUID to local byte order (step 13)
|
||||
SwapByteOrder(newGuid);
|
||||
return new Guid(newGuid);
|
||||
}
|
||||
|
||||
// Converts a GUID (expressed as a byte array) to/from network order (MSB-first).
|
||||
internal static void SwapByteOrder(byte[] guid)
|
||||
{
|
||||
SwapBytes(guid, 0, 3);
|
||||
SwapBytes(guid, 1, 2);
|
||||
SwapBytes(guid, 4, 5);
|
||||
SwapBytes(guid, 6, 7);
|
||||
}
|
||||
|
||||
private static void SwapBytes(byte[] guid, int left, int right)
|
||||
{
|
||||
byte temp = guid[left];
|
||||
guid[left] = guid[right];
|
||||
guid[right] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ namespace Umbraco.Core.Strings
|
||||
/// <summary>
|
||||
/// Flag mask for encoding.
|
||||
/// </summary>
|
||||
CodeMask = Unicode | Utf8 | Ascii,
|
||||
CodeMask = Unicode | Utf8 | Ascii | TryAscii,
|
||||
|
||||
/// <summary>
|
||||
/// Unicode encoding.
|
||||
@@ -86,6 +86,10 @@ namespace Umbraco.Core.Strings
|
||||
/// </summary>
|
||||
Ascii = 0x0400,
|
||||
|
||||
/// <summary>
|
||||
/// Ascii encoding, if possible.
|
||||
/// </summary>
|
||||
TryAscii = 0x0800,
|
||||
|
||||
// role values
|
||||
|
||||
|
||||
@@ -152,12 +152,18 @@ namespace Umbraco.Core.Strings
|
||||
/// <returns>The short string helper.</returns>
|
||||
public DefaultShortStringHelper WithDefaultConfig()
|
||||
{
|
||||
var urlSegmentConvertTo = CleanStringType.Utf8;
|
||||
if (_umbracoSettings.RequestHandler.ConvertUrlsToAscii)
|
||||
urlSegmentConvertTo = CleanStringType.Ascii;
|
||||
if (_umbracoSettings.RequestHandler.TryConvertUrlsToAscii)
|
||||
urlSegmentConvertTo = CleanStringType.TryAscii;
|
||||
|
||||
return WithConfig(CleanStringType.UrlSegment, new Config
|
||||
{
|
||||
PreFilter = ApplyUrlReplaceCharacters,
|
||||
PostFilter = x => CutMaxLength(x, 240),
|
||||
IsTerm = (c, leading) => char.IsLetterOrDigit(c) || c == '_', // letter, digit or underscore
|
||||
StringType = (_umbracoSettings.RequestHandler.ConvertUrlsToAscii ? CleanStringType.Ascii : CleanStringType.Utf8) | CleanStringType.LowerCase,
|
||||
StringType = urlSegmentConvertTo | CleanStringType.LowerCase,
|
||||
BreakTermsOnUpper = false,
|
||||
Separator = '-'
|
||||
}).WithConfig(CleanStringType.FileName, new Config
|
||||
@@ -542,9 +548,20 @@ function validateSafeAlias(input, value, immediate, callback) {{
|
||||
|
||||
// recode
|
||||
var codeType = stringType & CleanStringType.CodeMask;
|
||||
text = codeType == CleanStringType.Ascii
|
||||
? Utf8ToAsciiConverter.ToAsciiString(text)
|
||||
: RemoveSurrogatePairs(text);
|
||||
switch (codeType)
|
||||
{
|
||||
case CleanStringType.Ascii:
|
||||
text = Utf8ToAsciiConverter.ToAsciiString(text);
|
||||
break;
|
||||
case CleanStringType.TryAscii:
|
||||
const char ESC = (char) 27;
|
||||
var ctext = Utf8ToAsciiConverter.ToAsciiString(text, ESC);
|
||||
if (ctext.Contains(ESC) == false) text = ctext;
|
||||
break;
|
||||
default:
|
||||
text = RemoveSurrogatePairs(text);
|
||||
break;
|
||||
}
|
||||
|
||||
// clean
|
||||
text = CleanCodeString(text, stringType, separator.Value, culture, config);
|
||||
|
||||
@@ -17,8 +17,9 @@ namespace Umbraco.Core.Strings
|
||||
/// Converts an Utf8 string into an Ascii string.
|
||||
/// </summary>
|
||||
/// <param name="text">The text to convert.</param>
|
||||
/// <param name="fail">The character to used to replace characters that cannot properly be converted.</param>
|
||||
/// <returns>The converted text.</returns>
|
||||
public static string ToAsciiString(string text)
|
||||
public static string ToAsciiString(string text, char fail = '?')
|
||||
{
|
||||
var input = text.ToCharArray();
|
||||
|
||||
@@ -26,7 +27,7 @@ namespace Umbraco.Core.Strings
|
||||
// but... we should be filtering short strings only...
|
||||
|
||||
var output = new char[input.Length * 3]; // *3 because of things such as OE
|
||||
var len = ToAscii(input, output);
|
||||
var len = ToAscii(input, output, fail);
|
||||
return new string(output, 0, len);
|
||||
|
||||
//var output = new StringBuilder(input.Length + 16); // default is 16, start with at least input length + little extra
|
||||
@@ -38,8 +39,9 @@ namespace Umbraco.Core.Strings
|
||||
/// Converts an Utf8 string into an array of Ascii characters.
|
||||
/// </summary>
|
||||
/// <param name="text">The text to convert.</param>
|
||||
/// <param name="fail">The character to used to replace characters that cannot properly be converted.</param>
|
||||
/// <returns>The converted text.</returns>
|
||||
public static char[] ToAsciiCharArray(string text)
|
||||
public static char[] ToAsciiCharArray(string text, char fail = '?')
|
||||
{
|
||||
var input = text.ToCharArray();
|
||||
|
||||
@@ -47,7 +49,7 @@ namespace Umbraco.Core.Strings
|
||||
// but... we should be filtering short strings only...
|
||||
|
||||
var output = new char[input.Length * 3]; // *3 because of things such as OE
|
||||
var len = ToAscii(input, output);
|
||||
var len = ToAscii(input, output, fail);
|
||||
var array = new char[len];
|
||||
Array.Copy(output, array, len);
|
||||
return array;
|
||||
@@ -64,10 +66,11 @@ namespace Umbraco.Core.Strings
|
||||
/// </summary>
|
||||
/// <param name="input">The input array.</param>
|
||||
/// <param name="output">The output array.</param>
|
||||
/// <param name="fail">The character to used to replace characters that cannot properly be converted.</param>
|
||||
/// <returns>The number of characters in the output array.</returns>
|
||||
/// <remarks>The caller must ensure that the output array is big enough.</remarks>
|
||||
/// <exception cref="OverflowException">The output array is not big enough.</exception>
|
||||
private static int ToAscii(char[] input, char[] output)
|
||||
private static int ToAscii(char[] input, char[] output, char fail = '?')
|
||||
{
|
||||
var opos = 0;
|
||||
|
||||
@@ -75,10 +78,10 @@ namespace Umbraco.Core.Strings
|
||||
if (char.IsSurrogate(input[ipos])) // ignore high surrogate
|
||||
{
|
||||
ipos++; // and skip low surrogate
|
||||
output[opos++] = '?';
|
||||
output[opos++] = fail;
|
||||
}
|
||||
else
|
||||
ToAscii(input, ipos, output, ref opos);
|
||||
ToAscii(input, ipos, output, ref opos, fail);
|
||||
|
||||
return opos;
|
||||
}
|
||||
@@ -109,12 +112,13 @@ namespace Umbraco.Core.Strings
|
||||
/// <param name="ipos">The input position.</param>
|
||||
/// <param name="output">The output array.</param>
|
||||
/// <param name="opos">The output position.</param>
|
||||
/// <param name="fail">The character to used to replace characters that cannot properly be converted.</param>
|
||||
/// <remarks>
|
||||
/// <para>Adapted from various sources on the 'net including <c>Lucene.Net.Analysis.ASCIIFoldingFilter</c>.</para>
|
||||
/// <para>Input should contain Utf8 characters exclusively and NOT Unicode.</para>
|
||||
/// <para>Removes controls, normalizes whitespaces, replaces symbols by '?'.</para>
|
||||
/// </remarks>
|
||||
private static void ToAscii(char[] input, int ipos, char[] output, ref int opos)
|
||||
private static void ToAscii(char[] input, int ipos, char[] output, ref int opos, char fail = '?')
|
||||
{
|
||||
var c = input[ipos];
|
||||
|
||||
@@ -3583,7 +3587,7 @@ namespace Umbraco.Core.Strings
|
||||
// output[opos++] = c;
|
||||
|
||||
// strict ASCII
|
||||
output[opos++] = '?';
|
||||
output[opos++] = fail;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -126,10 +126,12 @@ namespace Umbraco.Core.Sync
|
||||
|
||||
public static string GetServerHash(string machineName, string appDomainAppId)
|
||||
{
|
||||
var hasher = new HashCodeCombiner();
|
||||
hasher.AddCaseInsensitiveString(appDomainAppId);
|
||||
hasher.AddCaseInsensitiveString(machineName);
|
||||
return hasher.GetCombinedHashCode();
|
||||
using (var generator = new HashGenerator())
|
||||
{
|
||||
generator.AddString(machineName);
|
||||
generator.AddString(appDomainAppId);
|
||||
return generator.GenerateHash();
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool RequiresDistributed(IEnumerable<IServerAddress> servers, ICacheRefresher refresher, MessageType messageType)
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core
|
||||
@@ -70,6 +69,10 @@ namespace Umbraco.Core
|
||||
[UdiType(UdiType.StringUdi)]
|
||||
public const string AnyString = "any-string"; // that one is for tests
|
||||
|
||||
[UdiType(UdiType.StringUdi)]
|
||||
public const string Language = "language";
|
||||
[UdiType(UdiType.StringUdi)]
|
||||
public const string MacroScript = "macroscript";
|
||||
[UdiType(UdiType.StringUdi)]
|
||||
public const string MediaFile = "media-file";
|
||||
[UdiType(UdiType.StringUdi)]
|
||||
@@ -83,6 +86,8 @@ namespace Umbraco.Core
|
||||
[UdiType(UdiType.StringUdi)]
|
||||
public const string PartialViewMacro = "partial-view-macro";
|
||||
[UdiType(UdiType.StringUdi)]
|
||||
public const string UserControl = "usercontrol";
|
||||
[UdiType(UdiType.StringUdi)]
|
||||
public const string Xslt = "xslt";
|
||||
|
||||
public static string FromUmbracoObjectType(UmbracoObjectTypes umbracoObjectType)
|
||||
@@ -123,6 +128,8 @@ namespace Umbraco.Core
|
||||
return FormsPreValue;
|
||||
case UmbracoObjectTypes.FormsDataSource:
|
||||
return FormsDataSource;
|
||||
case UmbracoObjectTypes.Language:
|
||||
return Language;
|
||||
}
|
||||
throw new NotSupportedException(string.Format("UmbracoObjectType \"{0}\" does not have a matching EntityType.", umbracoObjectType));
|
||||
}
|
||||
@@ -165,6 +172,8 @@ namespace Umbraco.Core
|
||||
return UmbracoObjectTypes.FormsPreValue;
|
||||
case FormsDataSource:
|
||||
return UmbracoObjectTypes.FormsDataSource;
|
||||
case Language:
|
||||
return UmbracoObjectTypes.Language;
|
||||
}
|
||||
throw new NotSupportedException(
|
||||
string.Format("EntityType \"{0}\" does not have a matching UmbracoObjectType.", entityType));
|
||||
|
||||
@@ -97,7 +97,7 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity.</param>
|
||||
/// <returns>The entity identifier of the entity.</returns>
|
||||
public static GuidUdi GetUdi(this Umbraco.Core.Models.EntityContainer entity)
|
||||
public static GuidUdi GetUdi(this EntityContainer entity)
|
||||
{
|
||||
if (entity == null) throw new ArgumentNullException("entity");
|
||||
|
||||
@@ -190,6 +190,17 @@ namespace Umbraco.Core
|
||||
return new GuidUdi(Constants.UdiEntityType.Macro, entity.Key).EnsureClosed();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the entity identifier of the entity.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity.</param>
|
||||
/// <returns>The entity identifier of the entity.</returns>
|
||||
public static StringUdi GetUdi(this IUserControl entity)
|
||||
{
|
||||
if (entity == null) throw new ArgumentNullException("entity");
|
||||
return new StringUdi(Constants.UdiEntityType.UserControl, entity.Path.TrimStart('/')).EnsureClosed();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the entity identifier of the entity.
|
||||
/// </summary>
|
||||
@@ -246,6 +257,17 @@ namespace Umbraco.Core
|
||||
return new GuidUdi(Constants.UdiEntityType.RelationType, entity.Key).EnsureClosed();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the entity identifier of the entity.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity.</param>
|
||||
/// <returns>The entity identifier of the entity.</returns>
|
||||
public static StringUdi GetUdi(this ILanguage entity)
|
||||
{
|
||||
if (entity == null) throw new ArgumentNullException("entity");
|
||||
return new StringUdi(Constants.UdiEntityType.Language, entity.IsoCode).EnsureClosed();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the entity identifier of the entity.
|
||||
/// </summary>
|
||||
@@ -279,7 +301,7 @@ namespace Umbraco.Core
|
||||
var dataTypeComposition = entity as IDataTypeDefinition;
|
||||
if (dataTypeComposition != null) return dataTypeComposition.GetUdi();
|
||||
|
||||
var container = entity as Umbraco.Core.Models.EntityContainer;
|
||||
var container = entity as EntityContainer;
|
||||
if (container != null) return container.GetUdi();
|
||||
|
||||
var media = entity as IMedia;
|
||||
@@ -315,6 +337,9 @@ namespace Umbraco.Core
|
||||
var relationType = entity as IRelationType;
|
||||
if (relationType != null) return relationType.GetUdi();
|
||||
|
||||
var language = entity as ILanguage;
|
||||
if (language != null) return language.GetUdi();
|
||||
|
||||
throw new NotSupportedException(string.Format("Entity type {0} is not supported.", entity.GetType().FullName));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -342,9 +342,12 @@
|
||||
<Compile Include="Events\SupersedeEventAttribute.cs" />
|
||||
<Compile Include="Exceptions\ConnectionException.cs" />
|
||||
<Compile Include="HashCodeHelper.cs" />
|
||||
<Compile Include="HashGenerator.cs" />
|
||||
<Compile Include="IHttpContextAccessor.cs" />
|
||||
<Compile Include="Models\EntityBase\IDeletableEntity.cs" />
|
||||
<Compile Include="Models\IUserControl.cs" />
|
||||
<Compile Include="Models\PublishedContent\PublishedContentTypeConverter.cs" />
|
||||
<Compile Include="Models\UserControl.cs" />
|
||||
<Compile Include="OrderedHashSet.cs" />
|
||||
<Compile Include="Events\UninstallPackageEventArgs.cs" />
|
||||
<Compile Include="Models\GridValue.cs" />
|
||||
@@ -576,12 +579,16 @@
|
||||
<Compile Include="Persistence\Repositories\Interfaces\IRedirectUrlRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\Interfaces\IServerRegistrationRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\Interfaces\IDeleteMediaFilesRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\Interfaces\IUserControlRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\Interfaces\IXsltFileRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\Interfaces\ITaskRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\Interfaces\ITaskTypeRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\MacroScriptRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\MigrationEntryRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\PublicAccessRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\RedirectUrlRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\SimilarNodeName.cs" />
|
||||
<Compile Include="Persistence\Repositories\UserControlRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\XsltFileRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\TaskRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\TaskTypeRepository.cs" />
|
||||
@@ -650,6 +657,7 @@
|
||||
<Compile Include="Services\ContentTypeServiceExtensions.cs" />
|
||||
<Compile Include="Models\RedirectUrl.cs" />
|
||||
<Compile Include="Services\IContentServiceBase.cs" />
|
||||
<Compile Include="Services\IdkMap.cs" />
|
||||
<Compile Include="Services\RedirectUrlService.cs" />
|
||||
<Compile Include="Services\DomainService.cs" />
|
||||
<Compile Include="Services\ExternalLoginService.cs" />
|
||||
@@ -758,7 +766,6 @@
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenTwoZero\AddMissingForeignKeyForContentType.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenTwoZero\AlterDataTypePreValueTable.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenOneZero\AssignMissingPrimaryForMySqlKeys.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenTwoZero\AddIndexToUmbracoNodeTable.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenTwoZero\RemoveCmsDocumentAliasColumn.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSeven\AssignMissingKeysAndIndexes.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSixTwoZero\AssignMissingPrimaryForMySqlKeys.cs" />
|
||||
@@ -1182,7 +1189,6 @@
|
||||
<Compile Include="Persistence\Repositories\RepositoryBase.cs" />
|
||||
<Compile Include="Persistence\Repositories\ScriptRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\ServerRegistrationRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\SimilarNodeNameComparer.cs" />
|
||||
<Compile Include="Persistence\Repositories\StylesheetRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\TemplateRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\UserRepository.cs" />
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
<configuration>
|
||||
<configSections>
|
||||
|
||||
<sectionGroup name="umbracoConfiguration">
|
||||
<sectionGroup name="umbracoConfiguration">
|
||||
<section name="FileSystemProviders" type="Umbraco.Core.Configuration.FileSystemProvidersSection, Umbraco.Core" requirePermission="false" />
|
||||
</sectionGroup>
|
||||
|
||||
|
||||
</configSections>
|
||||
|
||||
|
||||
<umbracoConfiguration>
|
||||
<FileSystemProviders>
|
||||
<Provider alias="media" type="Umbraco.Core.IO.PhysicalFileSystem, Umbraco.Core">
|
||||
@@ -52,7 +52,7 @@
|
||||
</Provider>
|
||||
</FileSystemProviders>
|
||||
</umbracoConfiguration>
|
||||
|
||||
|
||||
<appSettings>
|
||||
<add key="umbracoConfigurationStatus" value="6.0.0" />
|
||||
<add key="umbracoReservedUrls" value="~/config/splashes/booting.aspx,~/install/default.aspx,~/config/splashes/noNodes.aspx,~/VSEnterpriseHelper.axd" />
|
||||
@@ -64,7 +64,7 @@
|
||||
<add key="umbracoDefaultUILanguage" value="en" />
|
||||
<add key="umbracoUseSSL" value="false" />
|
||||
</appSettings>
|
||||
|
||||
|
||||
<connectionStrings>
|
||||
<add name="umbracoDbDSN" connectionString="Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf;Flush Interval=1;" providerName="System.Data.SqlServerCe.4.0" />
|
||||
</connectionStrings>
|
||||
@@ -83,133 +83,77 @@
|
||||
<compilation defaultLanguage="c#" debug="true" batch="false" targetFramework="4.0"></compilation>
|
||||
<machineKey validationKey="5E7B955FCE36F5F2A867C2A0D85DC61E7FEA9E15F1561E8386F78BFE9EE23FF18B21E6A44AA17300B3B9D5DBEB37AA61A2C73884A5BBEDA6D3B14BA408A7A8CD" decryptionKey="116B853D031219E404E088FCA0986D6CF2DFA77E1957B59FCC9404B8CA3909A1" validation="SHA1" decryption="AES" />
|
||||
<!--<trust level="Medium" originUrl=".*"/>-->
|
||||
|
||||
<!-- Sitemap provider-->
|
||||
<siteMap defaultProvider="UmbracoSiteMapProvider" enabled="true">
|
||||
<providers>
|
||||
<clear />
|
||||
<add name="UmbracoSiteMapProvider" type="umbraco.presentation.nodeFactory.UmbracoSiteMapProvider" defaultDescriptionAlias="description" securityTrimmingEnabled="true" />
|
||||
<add name="UmbracoSiteMapProvider" type="umbraco.presentation.nodeFactory.UmbracoSiteMapProvider, umbraco" defaultDescriptionAlias="description" securityTrimmingEnabled="true" />
|
||||
</providers>
|
||||
</siteMap>
|
||||
</system.web>
|
||||
|
||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /></startup>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
|
||||
</startup>
|
||||
<runtime>
|
||||
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
|
||||
<dependentAssembly>
|
||||
|
||||
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
|
||||
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
|
||||
|
||||
</dependentAssembly>
|
||||
|
||||
<dependentAssembly>
|
||||
|
||||
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
|
||||
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
|
||||
|
||||
</dependentAssembly>
|
||||
|
||||
<dependentAssembly>
|
||||
|
||||
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
|
||||
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
|
||||
|
||||
</dependentAssembly>
|
||||
|
||||
<dependentAssembly>
|
||||
|
||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
||||
|
||||
<bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0" />
|
||||
|
||||
</dependentAssembly>
|
||||
|
||||
<dependentAssembly>
|
||||
|
||||
<assemblyIdentity name="MiniProfiler" publicKeyToken="b44f9351044011a3" culture="neutral" />
|
||||
|
||||
<bindingRedirect oldVersion="0.0.0.0-2.1.0.0" newVersion="2.1.0.0" />
|
||||
|
||||
</dependentAssembly>
|
||||
|
||||
<dependentAssembly>
|
||||
|
||||
<assemblyIdentity name="NuGet.Core" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
|
||||
<bindingRedirect oldVersion="0.0.0.0-1.0.11220.104" newVersion="1.0.11220.104" />
|
||||
|
||||
</dependentAssembly>
|
||||
|
||||
<dependentAssembly>
|
||||
|
||||
<assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
|
||||
|
||||
</dependentAssembly>
|
||||
|
||||
<dependentAssembly>
|
||||
|
||||
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
|
||||
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
|
||||
|
||||
</dependentAssembly>
|
||||
|
||||
<dependentAssembly>
|
||||
|
||||
<assemblyIdentity name="Microsoft.Owin.Security.OAuth" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
|
||||
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
|
||||
|
||||
</dependentAssembly>
|
||||
|
||||
<dependentAssembly>
|
||||
|
||||
<assemblyIdentity name="Microsoft.Owin.Security" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
|
||||
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
|
||||
|
||||
</dependentAssembly>
|
||||
|
||||
<dependentAssembly>
|
||||
|
||||
<assemblyIdentity name="Microsoft.Owin.Security.Cookies" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
|
||||
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
|
||||
|
||||
</dependentAssembly>
|
||||
|
||||
<dependentAssembly>
|
||||
|
||||
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
|
||||
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
|
||||
|
||||
</dependentAssembly>
|
||||
|
||||
<dependentAssembly>
|
||||
|
||||
<assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
|
||||
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
|
||||
|
||||
</dependentAssembly>
|
||||
|
||||
<dependentAssembly>
|
||||
|
||||
<assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" culture="neutral" />
|
||||
|
||||
<bindingRedirect oldVersion="0.0.0.0-2.0.8.0" newVersion="2.0.8.0" />
|
||||
|
||||
</dependentAssembly>
|
||||
|
||||
</assemblyBinding>
|
||||
|
||||
</runtime>
|
||||
</configuration>
|
||||
|
||||
@@ -9,10 +9,10 @@ namespace Umbraco.Tests.Cache
|
||||
public class CacheRefresherTests
|
||||
{
|
||||
[TestCase("", "123456", "testmachine", true)] //empty hash will continue
|
||||
[TestCase("fffffff28449cf33", "123456", "testmachine", false)] //match, don't continue
|
||||
[TestCase("fffffff28449cf33", "12345", "testmachine", true)] // no match, continue
|
||||
[TestCase("fffffff28449cf33", "123456", "testmachin", true)] // same
|
||||
[TestCase("fffffff28449cf3", "123456", "testmachine", true)] // same
|
||||
[TestCase("2e6deefea4444a69dbd15a01b4c2749d", "123456", "testmachine", false)] //match, don't continue
|
||||
[TestCase("2e6deefea4444a69dbd15a01b4c2749d", "12345", "testmachine", true)] // no match, continue
|
||||
[TestCase("2e6deefea4444a69dbd15a01b4c2749d", "123456", "testmachin", true)] // same
|
||||
[TestCase("2e6deefea4444a69dbd15a01b4c2749", "123456", "testmachine", true)] // same
|
||||
public void Continue_Refreshing_For_Request(string hash, string appDomainAppId, string machineName, bool expected)
|
||||
{
|
||||
if (expected)
|
||||
|
||||
@@ -6,7 +6,7 @@ using Umbraco.Core;
|
||||
|
||||
namespace Umbraco.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
[TestFixture]
|
||||
public class HashCodeCombinerTests
|
||||
{
|
||||
|
||||
|
||||
@@ -0,0 +1,184 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
|
||||
namespace Umbraco.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class HashGeneratorTests
|
||||
{
|
||||
private string Generate(bool isCaseSensitive, params string[] strs)
|
||||
{
|
||||
using (var generator = new HashGenerator())
|
||||
{
|
||||
foreach (var str in strs)
|
||||
{
|
||||
if (isCaseSensitive)
|
||||
generator.AddString(str);
|
||||
else
|
||||
generator.AddCaseInsensitiveString(str);
|
||||
}
|
||||
return generator.GenerateHash();
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Generate_Hash_Multiple_Strings_Case_Sensitive()
|
||||
{
|
||||
|
||||
var hash1 = Generate(true, "hello", "world");
|
||||
var hash2 = Generate(true, "hello", "world");
|
||||
var hashFalse1 = Generate(true, "hello", "worlD");
|
||||
var hashFalse2 = Generate(true, "hEllo", "world");
|
||||
|
||||
Assert.AreEqual(hash1, hash2);
|
||||
Assert.AreNotEqual(hash1, hashFalse1);
|
||||
Assert.AreNotEqual(hash1, hashFalse2);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Generate_Hash_Multiple_Strings_Case_Insensitive()
|
||||
{
|
||||
var hash1 = Generate(false, "hello", "world");
|
||||
var hash2 = Generate(false, "hello", "world");
|
||||
var hashFalse1 = Generate(false, "hello", "worlD");
|
||||
var hashFalse2 = Generate(false, "hEllo", "world");
|
||||
|
||||
Assert.AreEqual(hash1, hash2);
|
||||
Assert.AreEqual(hash1, hashFalse1);
|
||||
Assert.AreEqual(hash1, hashFalse2);
|
||||
}
|
||||
|
||||
private DirectoryInfo PrepareFolder()
|
||||
{
|
||||
var assDir = new FileInfo(Assembly.GetExecutingAssembly().Location).Directory;
|
||||
var dir = Directory.CreateDirectory(Path.Combine(assDir.FullName, "HashCombiner", Guid.NewGuid().ToString("N")));
|
||||
foreach (var f in dir.GetFiles())
|
||||
{
|
||||
f.Delete();
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void HashCombiner_Test_String()
|
||||
{
|
||||
using (var combiner1 = new HashGenerator())
|
||||
using (var combiner2 = new HashGenerator())
|
||||
{
|
||||
combiner1.AddCaseInsensitiveString("Hello");
|
||||
combiner2.AddCaseInsensitiveString("hello");
|
||||
Assert.AreEqual(combiner1.GenerateHash(), combiner2.GenerateHash());
|
||||
combiner2.AddCaseInsensitiveString("world");
|
||||
Assert.AreNotEqual(combiner1.GenerateHash(), combiner2.GenerateHash());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void HashCombiner_Test_Int()
|
||||
{
|
||||
using (var combiner1 = new HashGenerator())
|
||||
using (var combiner2 = new HashGenerator())
|
||||
{
|
||||
combiner1.AddInt(1234);
|
||||
combiner2.AddInt(1234);
|
||||
Assert.AreEqual(combiner1.GenerateHash(), combiner2.GenerateHash());
|
||||
combiner2.AddInt(1);
|
||||
Assert.AreNotEqual(combiner1.GenerateHash(), combiner2.GenerateHash());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void HashCombiner_Test_DateTime()
|
||||
{
|
||||
using (var combiner1 = new HashGenerator())
|
||||
using (var combiner2 = new HashGenerator())
|
||||
{
|
||||
var dt = DateTime.Now;
|
||||
combiner1.AddDateTime(dt);
|
||||
combiner2.AddDateTime(dt);
|
||||
Assert.AreEqual(combiner1.GenerateHash(), combiner2.GenerateHash());
|
||||
combiner2.AddDateTime(DateTime.Now);
|
||||
Assert.AreNotEqual(combiner1.GenerateHash(), combiner2.GenerateHash());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void HashCombiner_Test_File()
|
||||
{
|
||||
using (var combiner1 = new HashGenerator())
|
||||
using (var combiner2 = new HashGenerator())
|
||||
using (var combiner3 = new HashGenerator())
|
||||
{
|
||||
var dir = PrepareFolder();
|
||||
var file1Path = Path.Combine(dir.FullName, "hastest1.txt");
|
||||
File.Delete(file1Path);
|
||||
using (var file1 = File.CreateText(Path.Combine(dir.FullName, "hastest1.txt")))
|
||||
{
|
||||
file1.WriteLine("hello");
|
||||
}
|
||||
var file2Path = Path.Combine(dir.FullName, "hastest2.txt");
|
||||
File.Delete(file2Path);
|
||||
using (var file2 = File.CreateText(Path.Combine(dir.FullName, "hastest2.txt")))
|
||||
{
|
||||
//even though files are the same, the dates are different
|
||||
file2.WriteLine("hello");
|
||||
}
|
||||
|
||||
combiner1.AddFile(new FileInfo(file1Path));
|
||||
|
||||
combiner2.AddFile(new FileInfo(file1Path));
|
||||
|
||||
combiner3.AddFile(new FileInfo(file2Path));
|
||||
|
||||
Assert.AreEqual(combiner1.GenerateHash(), combiner2.GenerateHash());
|
||||
Assert.AreNotEqual(combiner1.GenerateHash(), combiner3.GenerateHash());
|
||||
|
||||
combiner2.AddFile(new FileInfo(file2Path));
|
||||
|
||||
Assert.AreNotEqual(combiner1.GenerateHash(), combiner2.GenerateHash());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void HashCombiner_Test_Folder()
|
||||
{
|
||||
using (var combiner1 = new HashGenerator())
|
||||
using (var combiner2 = new HashGenerator())
|
||||
using (var combiner3 = new HashGenerator())
|
||||
{
|
||||
var dir = PrepareFolder();
|
||||
var file1Path = Path.Combine(dir.FullName, "hastest1.txt");
|
||||
File.Delete(file1Path);
|
||||
using (var file1 = File.CreateText(Path.Combine(dir.FullName, "hastest1.txt")))
|
||||
{
|
||||
file1.WriteLine("hello");
|
||||
}
|
||||
|
||||
//first test the whole folder
|
||||
combiner1.AddFolder(dir);
|
||||
|
||||
combiner2.AddFolder(dir);
|
||||
|
||||
Assert.AreEqual(combiner1.GenerateHash(), combiner2.GenerateHash());
|
||||
|
||||
//now add a file to the folder
|
||||
|
||||
var file2Path = Path.Combine(dir.FullName, "hastest2.txt");
|
||||
File.Delete(file2Path);
|
||||
using (var file2 = File.CreateText(Path.Combine(dir.FullName, "hastest2.txt")))
|
||||
{
|
||||
//even though files are the same, the dates are different
|
||||
file2.WriteLine("hello");
|
||||
}
|
||||
|
||||
combiner3.AddFolder(dir);
|
||||
|
||||
Assert.AreNotEqual(combiner1.GenerateHash(), combiner3.GenerateHash());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Specialized;
|
||||
using System.Configuration.Provider;
|
||||
using System.Collections.Specialized;
|
||||
using System.Web.Security;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
@@ -83,10 +81,10 @@ namespace Umbraco.Tests.Membership
|
||||
mServiceMock.Setup(service => service.GetByEmail("test@test.com")).Returns(() => null);
|
||||
mServiceMock.Setup(service => service.GetDefaultMemberType()).Returns("Member");
|
||||
mServiceMock.Setup(
|
||||
service => service.CreateWithIdentity(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
|
||||
.Callback((string u, string e, string p, string m) =>
|
||||
service => service.CreateWithIdentity(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<bool>()))
|
||||
.Callback((string u, string e, string p, string m, bool isApproved) =>
|
||||
{
|
||||
createdMember = new Member("test", e, u, p, memberType);
|
||||
createdMember = new Member("test", e, u, p, memberType, isApproved);
|
||||
})
|
||||
.Returns(() => createdMember);
|
||||
var provider = new MembersMembershipProvider(mServiceMock.Object);
|
||||
@@ -114,10 +112,10 @@ namespace Umbraco.Tests.Membership
|
||||
mServiceMock.Setup(service => service.GetByEmail("test@test.com")).Returns(() => null);
|
||||
mServiceMock.Setup(service => service.GetDefaultMemberType()).Returns("Member");
|
||||
mServiceMock.Setup(
|
||||
service => service.CreateWithIdentity(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
|
||||
.Callback((string u, string e, string p, string m) =>
|
||||
service => service.CreateWithIdentity(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<bool>()))
|
||||
.Callback((string u, string e, string p, string m, bool isApproved) =>
|
||||
{
|
||||
createdMember = new Member("test", e, u, p, memberType);
|
||||
createdMember = new Member("test", e, u, p, memberType, isApproved);
|
||||
})
|
||||
.Returns(() => createdMember);
|
||||
|
||||
@@ -147,10 +145,10 @@ namespace Umbraco.Tests.Membership
|
||||
mServiceMock.Setup(service => service.GetByEmail("test@test.com")).Returns(() => null);
|
||||
mServiceMock.Setup(service => service.GetDefaultMemberType()).Returns("Member");
|
||||
mServiceMock.Setup(
|
||||
service => service.CreateWithIdentity(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
|
||||
.Callback((string u, string e, string p, string m) =>
|
||||
service => service.CreateWithIdentity(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<bool>()))
|
||||
.Callback((string u, string e, string p, string m, bool isApproved) =>
|
||||
{
|
||||
createdMember = new Member("test", e, u, p, memberType);
|
||||
createdMember = new Member("test", e, u, p, memberType, isApproved);
|
||||
})
|
||||
.Returns(() => createdMember);
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
@@ -122,7 +123,7 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
|
||||
//re-get
|
||||
dictionaryItem = repository.Get(dictionaryItem.Id);
|
||||
|
||||
|
||||
|
||||
// Assert
|
||||
Assert.That(dictionaryItem, Is.Not.Null);
|
||||
@@ -140,10 +141,10 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
// Arrange
|
||||
var provider = new PetaPocoUnitOfWorkProvider(Logger);
|
||||
var unitOfWork = provider.GetUnitOfWork();
|
||||
|
||||
|
||||
using (var repository = CreateRepository(unitOfWork))
|
||||
{
|
||||
var dictionaryItem = (IDictionaryItem) new DictionaryItem("Testing1235");
|
||||
var dictionaryItem = (IDictionaryItem) new DictionaryItem("Testing1235");
|
||||
|
||||
repository.AddOrUpdate(dictionaryItem);
|
||||
unitOfWork.Commit();
|
||||
@@ -160,7 +161,6 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void Can_Perform_GetAll_On_DictionaryRepository()
|
||||
{
|
||||
@@ -319,7 +319,7 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
unitOfWork.Commit();
|
||||
|
||||
var dictionaryItem = (DictionaryItem)repository.Get(1);
|
||||
|
||||
|
||||
// Assert
|
||||
Assert.That(dictionaryItem, Is.Not.Null);
|
||||
Assert.That(dictionaryItem.Translations.Count(), Is.EqualTo(3));
|
||||
@@ -364,6 +364,24 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Perform_GetDictionaryItemKeyMap_On_DictionaryRepository()
|
||||
{
|
||||
Dictionary<string, Guid> keyMap;
|
||||
|
||||
var provider = new PetaPocoUnitOfWorkProvider(Logger);
|
||||
using (var unitOfWork = provider.GetUnitOfWork(readOnly: true))
|
||||
{
|
||||
var repository = CreateRepository(unitOfWork);
|
||||
keyMap = repository.GetDictionaryItemKeyMap();
|
||||
}
|
||||
|
||||
Assert.IsNotNull(keyMap);
|
||||
Assert.IsNotEmpty(keyMap);
|
||||
foreach (var kvp in keyMap)
|
||||
Console.WriteLine("{0}: {1}", kvp.Key, kvp.Value);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public override void TearDown()
|
||||
{
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core.Persistence.Repositories;
|
||||
|
||||
namespace Umbraco.Tests.Persistence.Repositories
|
||||
{
|
||||
[TestFixture]
|
||||
public class SimilarNodeNameTests
|
||||
{
|
||||
[TestCase("Alpha", "Alpha", 0)]
|
||||
[TestCase("Alpha", "ALPHA", +1)] // case is important
|
||||
[TestCase("Alpha", "Bravo", -1)]
|
||||
[TestCase("Bravo", "Alpha", +1)]
|
||||
[TestCase("Alpha (1)", "Alpha (1)", 0)]
|
||||
[TestCase("Alpha", "Alpha (1)", -1)]
|
||||
[TestCase("Alpha (1)", "Alpha", +1)]
|
||||
[TestCase("Alpha (1)", "Alpha (2)", -1)]
|
||||
[TestCase("Alpha (2)", "Alpha (1)", +1)]
|
||||
[TestCase("Alpha (2)", "Alpha (10)", -1)] // this is the real stuff
|
||||
[TestCase("Alpha (10)", "Alpha (2)", +1)] // this is the real stuff
|
||||
[TestCase("Kilo", "Golf (2)", +1)]
|
||||
[TestCase("Kilo (1)", "Golf (2)", +1)]
|
||||
public void ComparerTest(string name1, string name2, int expected)
|
||||
{
|
||||
var comparer = new SimilarNodeName.Comparer();
|
||||
|
||||
var result = comparer.Compare(new SimilarNodeName { Name = name1 }, new SimilarNodeName { Name = name2 });
|
||||
if (expected == 0)
|
||||
Assert.AreEqual(0, result);
|
||||
else if (expected < 0)
|
||||
Assert.IsTrue(result < 0, "Expected <0 but was " + result);
|
||||
else if (expected > 0)
|
||||
Assert.IsTrue(result > 0, "Expected >0 but was " + result);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void OrderByTest()
|
||||
{
|
||||
var names = new[]
|
||||
{
|
||||
new SimilarNodeName { Id = 1, Name = "Alpha (2)" },
|
||||
new SimilarNodeName { Id = 2, Name = "Alpha" },
|
||||
new SimilarNodeName { Id = 3, Name = "Golf" },
|
||||
new SimilarNodeName { Id = 4, Name = "Zulu" },
|
||||
new SimilarNodeName { Id = 5, Name = "Mike" },
|
||||
new SimilarNodeName { Id = 6, Name = "Kilo (1)" },
|
||||
new SimilarNodeName { Id = 7, Name = "Yankee" },
|
||||
new SimilarNodeName { Id = 8, Name = "Kilo" },
|
||||
new SimilarNodeName { Id = 9, Name = "Golf (2)" },
|
||||
new SimilarNodeName { Id = 10, Name = "Alpha (1)" },
|
||||
};
|
||||
|
||||
var ordered = names.OrderBy(x => x, new SimilarNodeName.Comparer()).ToArray();
|
||||
|
||||
var i = 0;
|
||||
Assert.AreEqual(2, ordered[i++].Id);
|
||||
Assert.AreEqual(10, ordered[i++].Id);
|
||||
Assert.AreEqual(1, ordered[i++].Id);
|
||||
Assert.AreEqual(3, ordered[i++].Id);
|
||||
Assert.AreEqual(9, ordered[i++].Id);
|
||||
Assert.AreEqual(8, ordered[i++].Id);
|
||||
Assert.AreEqual(6, ordered[i++].Id);
|
||||
Assert.AreEqual(5, ordered[i++].Id);
|
||||
Assert.AreEqual(7, ordered[i++].Id);
|
||||
Assert.AreEqual(4, ordered[i++].Id);
|
||||
}
|
||||
|
||||
[TestCase(0, "Charlie", "Charlie")]
|
||||
[TestCase(0, "Zulu", "Zulu (1)")]
|
||||
[TestCase(0, "Golf", "Golf (1)")]
|
||||
[TestCase(0, "Kilo", "Kilo (2)")]
|
||||
[TestCase(0, "Alpha", "Alpha (3)")]
|
||||
[TestCase(0, "Kilo (1)", "Kilo (1) (1)")] // though... we might consider "Kilo (2)"
|
||||
[TestCase(6, "Kilo (1)", "Kilo (1)")] // because of the id
|
||||
public void Test(int nodeId, string nodeName, string expected)
|
||||
{
|
||||
var names = new[]
|
||||
{
|
||||
new SimilarNodeName { Id = 1, Name = "Alpha (2)" },
|
||||
new SimilarNodeName { Id = 2, Name = "Alpha" },
|
||||
new SimilarNodeName { Id = 3, Name = "Golf" },
|
||||
new SimilarNodeName { Id = 4, Name = "Zulu" },
|
||||
new SimilarNodeName { Id = 5, Name = "Mike" },
|
||||
new SimilarNodeName { Id = 6, Name = "Kilo (1)" },
|
||||
new SimilarNodeName { Id = 7, Name = "Yankee" },
|
||||
new SimilarNodeName { Id = 8, Name = "Kilo" },
|
||||
new SimilarNodeName { Id = 9, Name = "Golf (2)" },
|
||||
new SimilarNodeName { Id = 10, Name = "Alpha (1)" },
|
||||
};
|
||||
|
||||
Assert.AreEqual(expected, SimilarNodeName.GetUniqueName(names, nodeId, nodeName));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -218,15 +218,7 @@ AnotherContentFinder
|
||||
//ensure they are all found
|
||||
Assert.IsTrue(plugins.Result.ContainsAll(shouldContain));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PluginHash_From_String()
|
||||
{
|
||||
var s = "hello my name is someone".GetHashCode().ToString("x", CultureInfo.InvariantCulture);
|
||||
var output = PluginManager.ConvertHashToInt64(s);
|
||||
Assert.AreNotEqual(0, output);
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void Get_Plugins_Hash()
|
||||
{
|
||||
|
||||
@@ -96,5 +96,25 @@ namespace Umbraco.Tests.PropertyEditors
|
||||
|
||||
Assert.AreEqual(expected, result);
|
||||
}
|
||||
|
||||
[TestCase(null, "1", false, 1)]
|
||||
[TestCase(null, "1", true, 1)]
|
||||
[TestCase(null, "0", false, 0)]
|
||||
[TestCase(null, "0", true, 0)]
|
||||
[TestCase(null, null, false, 0)]
|
||||
[TestCase(null, null, true, 0)]
|
||||
[TestCase(null, "-1", false, -1)]
|
||||
[TestCase(null, "-1", true, -1)]
|
||||
[TestCase(null, "1.65", false, 1.65)]
|
||||
[TestCase(null, "1.65", true, 1.65)]
|
||||
[TestCase(null, "-1.65", false, -1.65)]
|
||||
[TestCase(null, "-1.65", true, -1.65)]
|
||||
public void CanConvertDecimalAliasPropertyEditor(Core.Models.PublishedContent.PublishedPropertyType propertyType, object value, bool preview, double expected)
|
||||
{
|
||||
var converter = new DecimalValueConverter();
|
||||
var result = converter.ConvertDataToSource(propertyType, value, preview);
|
||||
|
||||
Assert.AreEqual(expected, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user