Compare commits
64 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5a07e34fb4 | |||
| 1b5d614f5a | |||
| abb08260eb | |||
| 57c567c570 | |||
| 424f4601ae | |||
| a2a247b413 | |||
| 0b6a369047 | |||
| 522fdefb8c | |||
| 4d8d10f07a | |||
| 6f17129364 | |||
| 6f44e4fd09 | |||
| 02ddf80014 | |||
| 723d9eddd1 | |||
| fa655b812c | |||
| 576c10cd50 | |||
| 179afe7e0d | |||
| be7f42c454 | |||
| 7e1ee26dee | |||
| 1c9b449c46 | |||
| e38095b727 | |||
| b5796ad237 | |||
| f985c437b5 | |||
| 63fb8f5933 | |||
| eb529783c4 | |||
| a8265db5f0 | |||
| 7dcf2b1abb | |||
| 514452ddb9 | |||
| 1eb55a83c0 | |||
| dfe6f2029a | |||
| 851c844c8b | |||
| 7e413ed406 | |||
| c56b8863ee | |||
| 13a8548d3a | |||
| a70cb51559 | |||
| 8a56b3db16 | |||
| 4fcf2ce7bd | |||
| 080ace90b2 | |||
| 2bfa81c707 | |||
| 44cb5fd96b | |||
| b0b987f9cd | |||
| 3961e2533d | |||
| b46f842400 | |||
| 930acfeb68 | |||
| b004c616ad | |||
| 9d64c4e551 | |||
| 9a0aacd45a | |||
| 29ff7bc340 | |||
| 39a97fb768 | |||
| 0852bd90d0 | |||
| e28365a0e5 | |||
| 0d16c79d0c | |||
| 7cc8983a25 | |||
| e7f8baeca4 | |||
| e716d14a0a | |||
| 4c6a742007 | |||
| 410241b61d | |||
| 4e47fa9a70 | |||
| 9c5fb1fead | |||
| dc41db5fc1 | |||
| 11b6a98df8 | |||
| da9fc1e147 | |||
| 319c75757a | |||
| 6e81e57c8e | |||
| 9ebe282ba6 |
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata minClientVersion="3.4.4">
|
||||
<metadata minClientVersion="4.1.0">
|
||||
<id>UmbracoCms.Core</id>
|
||||
<version>8.0.0</version>
|
||||
<title>Umbraco Cms Core Binaries</title>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata minClientVersion="3.4.4">
|
||||
<metadata minClientVersion="4.1.0">
|
||||
<id>UmbracoCms.Web</id>
|
||||
<version>8.0.0</version>
|
||||
<title>Umbraco Cms Core Binaries</title>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata minClientVersion="3.4.4">
|
||||
<metadata minClientVersion="4.1.0">
|
||||
<id>UmbracoCms</id>
|
||||
<version>8.0.0</version>
|
||||
<title>Umbraco Cms</title>
|
||||
@@ -25,7 +25,7 @@
|
||||
not want this to happen as the alpha of the next major is, really, the next major already.
|
||||
-->
|
||||
<dependency id="Microsoft.AspNet.SignalR.Core" version="[2.4.0, 2.999999)" />
|
||||
<dependency id="Umbraco.ModelsBuilder.Ui" version="[8.0.1]" />
|
||||
<dependency id="Umbraco.ModelsBuilder.Ui" version="[8.0.4]" />
|
||||
<dependency id="ImageProcessor.Web" version="[4.10.0.100,4.999999)" />
|
||||
<dependency id="ImageProcessor.Web.Config" version="[2.5.0.100,2.999999)" />
|
||||
<dependency id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="[2.0.1,2.999999)" />
|
||||
|
||||
@@ -126,45 +126,55 @@
|
||||
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='Microsoft.CodeAnalysis.CSharp')" xdt:Transform="Remove" />
|
||||
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='log4net')" xdt:Transform="Remove" />
|
||||
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='System.Data.SqlServerCe')" xdt:Transform="Remove" />
|
||||
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='System.ValueTuple')" xdt:Transform="Remove" />
|
||||
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='System.Net.Http.Formatting')" xdt:Transform="Remove" />
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="Microsoft.Owin.Security" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="Microsoft.Owin.Security.Cookies" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="Microsoft.Owin.Security.OAuth" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-11.0.0.0" newVersion="11.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-1.2.1.0" newVersion="1.2.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-5.2.6.0" newVersion="5.2.6.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-5.2.6.0" newVersion="5.2.6.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="Microsoft.Owin.Security" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="Microsoft.Owin.Security.Cookies" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="Microsoft.Owin.Security.OAuth" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-1.2.3.0" newVersion="1.2.3.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-5.2.7.0" newVersion="5.2.7.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-5.2.7.0" newVersion="5.2.7.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="System.ValueTuple" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-5.2.7.0" newVersion="5.2.7.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
|
||||
<system.web.webPages.razor xdt:Transform="Remove" />
|
||||
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
param($installPath, $toolsPath, $package, $project)
|
||||
|
||||
Write-Host "installPath:" "${installPath}"
|
||||
Write-Host "toolsPath:" "${toolsPath}"
|
||||
|
||||
Write-Host " "
|
||||
|
||||
if ($project) {
|
||||
$dateTime = Get-Date -Format yyyyMMdd-HHmmss
|
||||
|
||||
# Create paths and list them
|
||||
$projectPath = (Get-Item $project.Properties.Item("FullPath").Value).FullName
|
||||
Write-Host "projectPath:" "${projectPath}"
|
||||
$backupPath = Join-Path $projectPath "App_Data\NuGetBackup\$dateTime"
|
||||
Write-Host "backupPath:" "${backupPath}"
|
||||
$copyLogsPath = Join-Path $backupPath "CopyLogs"
|
||||
Write-Host "copyLogsPath:" "${copyLogsPath}"
|
||||
$umbracoBinFolder = Join-Path $projectPath "bin"
|
||||
Write-Host "umbracoBinFolder:" "${umbracoBinFolder}"
|
||||
|
||||
# Create backup folder and logs folder if it doesn't exist yet
|
||||
New-Item -ItemType Directory -Force -Path $backupPath
|
||||
New-Item -ItemType Directory -Force -Path $copyLogsPath
|
||||
|
||||
# After backing up, remove all umbraco dlls from bin folder in case dll files are included in the VS project
|
||||
# See: http://issues.umbraco.org/issue/U4-4930
|
||||
|
||||
if(Test-Path $umbracoBinFolder) {
|
||||
$umbracoBinBackupPath = Join-Path $backupPath "bin"
|
||||
|
||||
New-Item -ItemType Directory -Force -Path $umbracoBinBackupPath
|
||||
|
||||
robocopy $umbracoBinFolder $umbracoBinBackupPath /e /LOG:$copyLogsPath\UmbracoBinBackup.log
|
||||
|
||||
# Delete files Umbraco ships with
|
||||
if(Test-Path $umbracoBinFolder\Microsoft.ApplicationBlocks.Data.dll) { Remove-Item $umbracoBinFolder\Microsoft.ApplicationBlocks.Data.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Data.SqlServerCe.dll) { Remove-Item $umbracoBinFolder\System.Data.SqlServerCe.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Data.SqlServerCe.Entity.dll) { Remove-Item $umbracoBinFolder\System.Data.SqlServerCe.Entity.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Umbraco.Web.dll) { Remove-Item $umbracoBinFolder\Umbraco.Web.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Umbraco.Core.dll) { Remove-Item $umbracoBinFolder\Umbraco.Core.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Umbraco.ModelsBuilder.dll) { Remove-Item $umbracoBinFolder\Umbraco.ModelsBuilder.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Umbraco.ModelsBuilder.AspNet.dll) { Remove-Item $umbracoBinFolder\Umbraco.ModelsBuilder.AspNet.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Umbraco.Web.UI.dll) { Remove-Item $umbracoBinFolder\Umbraco.Web.UI.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Umbraco.Examine.dll) { Remove-Item $umbracoBinFolder\Umbraco.Examine.dll -Force -Confirm:$false }
|
||||
|
||||
# Delete files Umbraco depends upon
|
||||
$amd64Folder = Join-Path $umbracoBinFolder "amd64"
|
||||
if(Test-Path $amd64Folder) { Remove-Item $amd64Folder -Force -Recurse -Confirm:$false }
|
||||
$x86Folder = Join-Path $umbracoBinFolder "x86"
|
||||
if(Test-Path $x86Folder) { Remove-Item $x86Folder -Force -Recurse -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\AutoMapper.dll) { Remove-Item $umbracoBinFolder\AutoMapper.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\AutoMapper.Net4.dll) { Remove-Item $umbracoBinFolder\AutoMapper.Net4.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\ClientDependency.Core.dll) { Remove-Item $umbracoBinFolder\ClientDependency.Core.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\ClientDependency.Core.Mvc.dll) { Remove-Item $umbracoBinFolder\ClientDependency.Core.Mvc.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\CookComputing.XmlRpcV2.dll) { Remove-Item $umbracoBinFolder\CookComputing.XmlRpcV2.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Examine.dll) { Remove-Item $umbracoBinFolder\Examine.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\HtmlAgilityPack.dll) { Remove-Item $umbracoBinFolder\HtmlAgilityPack.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\ICSharpCode.SharpZipLib.dll) { Remove-Item $umbracoBinFolder\ICSharpCode.SharpZipLib.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\ImageProcessor.dll) { Remove-Item $umbracoBinFolder\ImageProcessor.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\ImageProcessor.Web.dll) { Remove-Item $umbracoBinFolder\ImageProcessor.Web.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Lucene.Net.dll) { Remove-Item $umbracoBinFolder\Lucene.Net.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Microsoft.IO.RecyclableMemoryStream.dll) { Remove-Item $umbracoBinFolder\Microsoft.IO.RecyclableMemoryStream.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Microsoft.AspNet.Identity.Core.dll) { Remove-Item $umbracoBinFolder\Microsoft.AspNet.Identity.Core.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Microsoft.AspNet.Identity.Owin.dll) { Remove-Item $umbracoBinFolder\Microsoft.AspNet.Identity.Owin.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Microsoft.CodeAnalysis.CSharp.dll) { Remove-Item $umbracoBinFolder\Microsoft.CodeAnalysis.CSharp.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Microsoft.CodeAnalysis.dll) { Remove-Item $umbracoBinFolder\Microsoft.CodeAnalysis.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Microsoft.Owin.dll) { Remove-Item $umbracoBinFolder\Microsoft.Owin.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Microsoft.Owin.Host.SystemWeb.dll) { Remove-Item $umbracoBinFolder\Microsoft.Owin.Host.SystemWeb.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Microsoft.Owin.Security.dll) { Remove-Item $umbracoBinFolder\Microsoft.Owin.Security.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Microsoft.Owin.Security.Cookies.dll) { Remove-Item $umbracoBinFolder\Microsoft.Owin.Security.Cookies.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Microsoft.Owin.Security.OAuth.dll) { Remove-Item $umbracoBinFolder\Microsoft.Owin.Security.OAuth.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Microsoft.Web.Infrastructure.dll) { Remove-Item $umbracoBinFolder\Microsoft.Web.Infrastructure.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Microsoft.Web.Helpers.dll) { Remove-Item $umbracoBinFolder\Microsoft.Web.Helpers.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Microsoft.Web.Mvc.FixedDisplayModes.dll) { Remove-Item $umbracoBinFolder\Microsoft.Web.Mvc.FixedDisplayModes.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\MiniProfiler.dll) { Remove-Item $umbracoBinFolder\MiniProfiler.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Newtonsoft.Json.dll) { Remove-Item $umbracoBinFolder\Newtonsoft.Json.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Owin.dll) { Remove-Item $umbracoBinFolder\Owin.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Semver.dll) { Remove-Item $umbracoBinFolder\Semver.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Collections.Immutable.dll) { Remove-Item $umbracoBinFolder\System.Collections.Immutable.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Reflection.Metadata.dll) { Remove-Item $umbracoBinFolder\System.Reflection.Metadata.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Net.Http.Extensions.dll) { Remove-Item $umbracoBinFolder\System.Net.Http.Extensions.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Net.Http.Formatting.dll) { Remove-Item $umbracoBinFolder\System.Net.Http.Formatting.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Net.Http.Primitives.dll) { Remove-Item $umbracoBinFolder\System.Net.Http.Primitives.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Web.Helpers.dll) { Remove-Item $umbracoBinFolder\System.Web.Helpers.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Web.Http.dll) { Remove-Item $umbracoBinFolder\System.Web.Http.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Web.Http.WebHost.dll) { Remove-Item $umbracoBinFolder\System.Web.Http.WebHost.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Web.Mvc.dll) { Remove-Item $umbracoBinFolder\System.Web.Mvc.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Web.Razor.dll) { Remove-Item $umbracoBinFolder\System.Web.Razor.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Web.WebPages.dll) { Remove-Item $umbracoBinFolder\System.Web.WebPages.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Web.WebPages.Deployment.dll) { Remove-Item $umbracoBinFolder\System.Web.WebPages.Deployment.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Web.WebPages.Razor.dll) { Remove-Item $umbracoBinFolder\System.Web.WebPages.Razor.dll -Force -Confirm:$false }
|
||||
}
|
||||
}
|
||||
@@ -11,37 +11,15 @@ if ($project) {
|
||||
# Create paths and list them
|
||||
$projectPath = (Get-Item $project.Properties.Item("FullPath").Value).FullName
|
||||
Write-Host "projectPath:" "${projectPath}"
|
||||
$backupPath = Join-Path $projectPath "App_Data\NuGetBackup\$dateTime"
|
||||
Write-Host "backupPath:" "${backupPath}"
|
||||
$copyLogsPath = Join-Path $backupPath "CopyLogs"
|
||||
Write-Host "copyLogsPath:" "${copyLogsPath}"
|
||||
$webConfigSource = Join-Path $projectPath "Web.config"
|
||||
Write-Host "webConfigSource:" "${webConfigSource}"
|
||||
$configFolder = Join-Path $projectPath "Config"
|
||||
Write-Host "configFolder:" "${configFolder}"
|
||||
|
||||
# Create backup folder and logs folder if it doesn't exist yet
|
||||
New-Item -ItemType Directory -Force -Path $backupPath
|
||||
New-Item -ItemType Directory -Force -Path $copyLogsPath
|
||||
|
||||
# Create a backup of original web.config
|
||||
Copy-Item $webConfigSource $backupPath -Force
|
||||
|
||||
# Backup config files folder
|
||||
if(Test-Path $configFolder) {
|
||||
$umbracoBackupPath = Join-Path $backupPath "Config"
|
||||
New-Item -ItemType Directory -Force -Path $umbracoBackupPath
|
||||
|
||||
robocopy $configFolder $umbracoBackupPath /e /LOG:$copyLogsPath\ConfigBackup.log
|
||||
}
|
||||
|
||||
# Copy umbraco and umbraco_files from package to project folder
|
||||
$umbracoFolder = Join-Path $projectPath "Umbraco"
|
||||
New-Item -ItemType Directory -Force -Path $umbracoFolder
|
||||
$umbracoFolderSource = Join-Path $installPath "UmbracoFiles\Umbraco"
|
||||
$umbracoBackupPath = Join-Path $backupPath "Umbraco"
|
||||
New-Item -ItemType Directory -Force -Path $umbracoBackupPath
|
||||
robocopy $umbracoFolder $umbracoBackupPath /e /LOG:$copyLogsPath\UmbracoBackup.log
|
||||
robocopy $umbracoFolderSource $umbracoFolder /is /it /e /xf UI.xml /LOG:$copyLogsPath\UmbracoCopy.log
|
||||
|
||||
$copyWebconfig = $true
|
||||
@@ -100,11 +78,6 @@ if ($project) {
|
||||
}
|
||||
}
|
||||
|
||||
$installFolder = Join-Path $projectPath "Install"
|
||||
if(Test-Path $installFolder) {
|
||||
Remove-Item $installFolder -Force -Recurse -Confirm:$false
|
||||
}
|
||||
|
||||
# Open appropriate readme
|
||||
if($copyWebconfig -eq $true)
|
||||
{
|
||||
|
||||
+2
-2
@@ -18,5 +18,5 @@ using System.Resources;
|
||||
[assembly: AssemblyVersion("8.0.0")]
|
||||
|
||||
// these are FYI and changed automatically
|
||||
[assembly: AssemblyFileVersion("8.0.0")]
|
||||
[assembly: AssemblyInformationalVersion("8.0.0")]
|
||||
[assembly: AssemblyFileVersion("8.0.2")]
|
||||
[assembly: AssemblyInformationalVersion("8.0.2")]
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace Umbraco.Core.Composing
|
||||
|
||||
protected override IComponent CreateItem(IFactory factory, Type itemType)
|
||||
{
|
||||
using (_logger.DebugDuration<Composers>($"Creating {itemType.FullName}.", $"Created {itemType.FullName}.", thresholdMilliseconds: LogThresholdMilliseconds))
|
||||
using (_logger.DebugDuration<ComponentCollectionBuilder>($"Creating {itemType.FullName}.", $"Created {itemType.FullName}.", thresholdMilliseconds: LogThresholdMilliseconds))
|
||||
{
|
||||
return base.CreateItem(factory, itemType);
|
||||
}
|
||||
|
||||
@@ -70,7 +70,23 @@ namespace Umbraco.Core.Composing
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<Type> PrepareComposerTypes()
|
||||
internal IEnumerable<Type> PrepareComposerTypes()
|
||||
{
|
||||
var requirements = GetRequirements();
|
||||
|
||||
// only for debugging, this is verbose
|
||||
//_logger.Debug<Composers>(GetComposersReport(requirements));
|
||||
|
||||
var sortedComposerTypes = SortComposers(requirements);
|
||||
|
||||
// bit verbose but should help for troubleshooting
|
||||
//var text = "Ordered Composers: " + Environment.NewLine + string.Join(Environment.NewLine, sortedComposerTypes) + Environment.NewLine;
|
||||
_logger.Debug<Composers>("Ordered Composers: {SortedComposerTypes}", sortedComposerTypes);
|
||||
|
||||
return sortedComposerTypes;
|
||||
}
|
||||
|
||||
internal Dictionary<Type, List<Type>> GetRequirements(bool throwOnMissing = true)
|
||||
{
|
||||
// create a list, remove those that cannot be enabled due to runtime level
|
||||
var composerTypeList = _composerTypes
|
||||
@@ -89,25 +105,69 @@ namespace Umbraco.Core.Composing
|
||||
// enable or disable composers
|
||||
EnableDisableComposers(composerTypeList);
|
||||
|
||||
// sort the composers according to their dependencies
|
||||
var requirements = new Dictionary<Type, List<Type>>();
|
||||
foreach (var type in composerTypeList) requirements[type] = null;
|
||||
foreach (var type in composerTypeList)
|
||||
void GatherInterfaces<TAttribute>(Type type, Func<TAttribute, Type> getTypeInAttribute, HashSet<Type> iset, List<Type> set2)
|
||||
where TAttribute : Attribute
|
||||
{
|
||||
GatherRequirementsFromRequireAttribute(type, composerTypeList, requirements);
|
||||
GatherRequirementsFromRequiredByAttribute(type, composerTypeList, requirements);
|
||||
foreach (var attribute in type.GetCustomAttributes<TAttribute>())
|
||||
{
|
||||
var typeInAttribute = getTypeInAttribute(attribute);
|
||||
if (typeInAttribute != null && // if the attribute references a type ...
|
||||
typeInAttribute.IsInterface && // ... which is an interface ...
|
||||
typeof(IComposer).IsAssignableFrom(typeInAttribute) && // ... which implements IComposer ...
|
||||
!iset.Contains(typeInAttribute)) // ... which is not already in the list
|
||||
{
|
||||
// add it to the new list
|
||||
iset.Add(typeInAttribute);
|
||||
set2.Add(typeInAttribute);
|
||||
|
||||
// add all its interfaces implementing IComposer
|
||||
foreach (var i in typeInAttribute.GetInterfaces().Where(x => typeof(IComposer).IsAssignableFrom(x)))
|
||||
{
|
||||
iset.Add(i);
|
||||
set2.Add(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// only for debugging, this is verbose
|
||||
//_logger.Debug<Composers>(GetComposersReport(requirements));
|
||||
// gather interfaces too
|
||||
var interfaces = new HashSet<Type>(composerTypeList.SelectMany(x => x.GetInterfaces().Where(y => typeof(IComposer).IsAssignableFrom(y))));
|
||||
composerTypeList.AddRange(interfaces);
|
||||
var list1 = composerTypeList;
|
||||
while (list1.Count > 0)
|
||||
{
|
||||
var list2 = new List<Type>();
|
||||
foreach (var t in list1)
|
||||
{
|
||||
GatherInterfaces<ComposeAfterAttribute>(t, a => a.RequiredType, interfaces, list2);
|
||||
GatherInterfaces<ComposeBeforeAttribute>(t, a => a.RequiringType, interfaces, list2);
|
||||
}
|
||||
composerTypeList.AddRange(list2);
|
||||
list1 = list2;
|
||||
}
|
||||
|
||||
// sort the composers according to their dependencies
|
||||
var requirements = new Dictionary<Type, List<Type>>();
|
||||
foreach (var type in composerTypeList)
|
||||
requirements[type] = null;
|
||||
foreach (var type in composerTypeList)
|
||||
{
|
||||
GatherRequirementsFromAfterAttribute(type, composerTypeList, requirements, throwOnMissing);
|
||||
GatherRequirementsFromBeforeAttribute(type, composerTypeList, requirements);
|
||||
}
|
||||
|
||||
return requirements;
|
||||
}
|
||||
|
||||
internal IEnumerable<Type> SortComposers(Dictionary<Type, List<Type>> requirements)
|
||||
{
|
||||
// sort composers
|
||||
var graph = new TopoGraph<Type, KeyValuePair<Type, List<Type>>>(kvp => kvp.Key, kvp => kvp.Value);
|
||||
graph.AddItems(requirements);
|
||||
List<Type> sortedComposerTypes;
|
||||
try
|
||||
{
|
||||
sortedComposerTypes = graph.GetSortedItems().Select(x => x.Key).ToList();
|
||||
sortedComposerTypes = graph.GetSortedItems().Select(x => x.Key).Where(x => !x.IsInterface).ToList();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -117,40 +177,37 @@ namespace Umbraco.Core.Composing
|
||||
throw;
|
||||
}
|
||||
|
||||
// bit verbose but should help for troubleshooting
|
||||
//var text = "Ordered Composers: " + Environment.NewLine + string.Join(Environment.NewLine, sortedComposerTypes) + Environment.NewLine;
|
||||
_logger.Debug<Composers>("Ordered Composers: {SortedComposerTypes}", sortedComposerTypes);
|
||||
|
||||
return sortedComposerTypes;
|
||||
}
|
||||
|
||||
private static string GetComposersReport(Dictionary<Type, List<Type>> requirements)
|
||||
internal static string GetComposersReport(Dictionary<Type, List<Type>> requirements)
|
||||
{
|
||||
var text = new StringBuilder();
|
||||
text.AppendLine("Composers & Dependencies:");
|
||||
text.AppendLine(" < compose before");
|
||||
text.AppendLine(" > compose after");
|
||||
text.AppendLine(" : implements");
|
||||
text.AppendLine(" = depends");
|
||||
text.AppendLine();
|
||||
|
||||
bool HasReq(IEnumerable<Type> types, Type type)
|
||||
=> types.Any(x => type.IsAssignableFrom(x) && !x.IsInterface);
|
||||
|
||||
foreach (var kvp in requirements)
|
||||
{
|
||||
var type = kvp.Key;
|
||||
|
||||
text.AppendLine(type.FullName);
|
||||
foreach (var attribute in type.GetCustomAttributes<ComposeAfterAttribute>())
|
||||
text.AppendLine(" -> " + attribute.RequiredType + (attribute.Weak.HasValue
|
||||
? (attribute.Weak.Value ? " (weak)" : (" (strong" + (requirements.ContainsKey(attribute.RequiredType) ? ", missing" : "") + ")"))
|
||||
: ""));
|
||||
foreach (var attribute in type.GetCustomAttributes<ComposeBeforeAttribute>())
|
||||
text.AppendLine(" -< " + attribute.RequiringType);
|
||||
foreach (var i in type.GetInterfaces())
|
||||
{
|
||||
text.AppendLine(" : " + i.FullName);
|
||||
foreach (var attribute in i.GetCustomAttributes<ComposeAfterAttribute>())
|
||||
text.AppendLine(" -> " + attribute.RequiredType + (attribute.Weak.HasValue
|
||||
? (attribute.Weak.Value ? " (weak)" : (" (strong" + (requirements.ContainsKey(attribute.RequiredType) ? ", missing" : "") + ")"))
|
||||
: ""));
|
||||
foreach (var attribute in i.GetCustomAttributes<ComposeBeforeAttribute>())
|
||||
text.AppendLine(" -< " + attribute.RequiringType);
|
||||
var weak = !(attribute.RequiredType.IsInterface ? attribute.Weak == false : attribute.Weak != true);
|
||||
text.AppendLine(" > " + attribute.RequiredType +
|
||||
(weak ? " (weak" : " (strong") + (HasReq(requirements.Keys, attribute.RequiredType) ? ", found" : ", missing") + ")");
|
||||
}
|
||||
foreach (var attribute in type.GetCustomAttributes<ComposeBeforeAttribute>())
|
||||
text.AppendLine(" < " + attribute.RequiringType);
|
||||
foreach (var i in type.GetInterfaces())
|
||||
text.AppendLine(" : " + i.FullName);
|
||||
if (kvp.Value != null)
|
||||
foreach (var t in kvp.Value)
|
||||
text.AppendLine(" = " + t);
|
||||
@@ -221,16 +278,16 @@ namespace Umbraco.Core.Composing
|
||||
types.Remove(kvp.Key);
|
||||
}
|
||||
|
||||
private static void GatherRequirementsFromRequireAttribute(Type type, ICollection<Type> types, IDictionary<Type, List<Type>> requirements)
|
||||
private static void GatherRequirementsFromAfterAttribute(Type type, ICollection<Type> types, IDictionary<Type, List<Type>> requirements, bool throwOnMissing = true)
|
||||
{
|
||||
// get 'require' attributes
|
||||
// these attributes are *not* inherited because we want to "custom-inherit" for interfaces only
|
||||
var requireAttributes = type
|
||||
var afterAttributes = type
|
||||
.GetInterfaces().SelectMany(x => x.GetCustomAttributes<ComposeAfterAttribute>()) // those marking interfaces
|
||||
.Concat(type.GetCustomAttributes<ComposeAfterAttribute>()); // those marking the composer
|
||||
|
||||
// what happens in case of conflicting attributes (different strong/weak for same type) is not specified.
|
||||
foreach (var attr in requireAttributes)
|
||||
foreach (var attr in afterAttributes)
|
||||
{
|
||||
if (attr.RequiredType == type) continue; // ignore self-requirements (+ exclude in implems, below)
|
||||
|
||||
@@ -238,13 +295,13 @@ namespace Umbraco.Core.Composing
|
||||
// unless strong, and then require at least one enabled composer implementing that interface
|
||||
if (attr.RequiredType.IsInterface)
|
||||
{
|
||||
var implems = types.Where(x => x != type && attr.RequiredType.IsAssignableFrom(x)).ToList();
|
||||
var implems = types.Where(x => x != type && attr.RequiredType.IsAssignableFrom(x) && !x.IsInterface).ToList();
|
||||
if (implems.Count > 0)
|
||||
{
|
||||
if (requirements[type] == null) requirements[type] = new List<Type>();
|
||||
requirements[type].AddRange(implems);
|
||||
}
|
||||
else if (attr.Weak == false) // if explicitly set to !weak, is strong, else is weak
|
||||
else if (attr.Weak == false && throwOnMissing) // if explicitly set to !weak, is strong, else is weak
|
||||
throw new Exception($"Broken composer dependency: {type.FullName} -> {attr.RequiredType.FullName}.");
|
||||
}
|
||||
// requiring a class = require that the composer is enabled
|
||||
@@ -256,28 +313,28 @@ namespace Umbraco.Core.Composing
|
||||
if (requirements[type] == null) requirements[type] = new List<Type>();
|
||||
requirements[type].Add(attr.RequiredType);
|
||||
}
|
||||
else if (attr.Weak != true) // if not explicitly set to weak, is strong
|
||||
else if (attr.Weak != true && throwOnMissing) // if not explicitly set to weak, is strong
|
||||
throw new Exception($"Broken composer dependency: {type.FullName} -> {attr.RequiredType.FullName}.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void GatherRequirementsFromRequiredByAttribute(Type type, ICollection<Type> types, IDictionary<Type, List<Type>> requirements)
|
||||
private static void GatherRequirementsFromBeforeAttribute(Type type, ICollection<Type> types, IDictionary<Type, List<Type>> requirements)
|
||||
{
|
||||
// get 'required' attributes
|
||||
// these attributes are *not* inherited because we want to "custom-inherit" for interfaces only
|
||||
var requiredAttributes = type
|
||||
var beforeAttributes = type
|
||||
.GetInterfaces().SelectMany(x => x.GetCustomAttributes<ComposeBeforeAttribute>()) // those marking interfaces
|
||||
.Concat(type.GetCustomAttributes<ComposeBeforeAttribute>()); // those marking the composer
|
||||
|
||||
foreach (var attr in requiredAttributes)
|
||||
foreach (var attr in beforeAttributes)
|
||||
{
|
||||
if (attr.RequiringType == type) continue; // ignore self-requirements (+ exclude in implems, below)
|
||||
|
||||
// required by an interface = by any enabled composer implementing this that interface
|
||||
if (attr.RequiringType.IsInterface)
|
||||
{
|
||||
var implems = types.Where(x => x != type && attr.RequiringType.IsAssignableFrom(x)).ToList();
|
||||
var implems = types.Where(x => x != type && attr.RequiringType.IsAssignableFrom(x) && !x.IsInterface).ToList();
|
||||
foreach (var implem in implems)
|
||||
{
|
||||
if (requirements[implem] == null) requirements[implem] = new List<Type>();
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
/// <summary>
|
||||
/// Compose.
|
||||
/// </summary>
|
||||
/// <param name="composition"></param>
|
||||
void Compose(Composition composition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,10 +4,8 @@
|
||||
/// Represents a core <see cref="IComposer"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>All core composers are required by (compose before) all user composers,
|
||||
/// and require (compose after) all runtime composers.</para>
|
||||
/// <para>Core composers compose after the initial composer, and before user composers.</para>
|
||||
/// </remarks>
|
||||
[ComposeAfter(typeof(IRuntimeComposer))]
|
||||
public interface ICoreComposer : IComposer
|
||||
{ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
namespace Umbraco.Core.Composing
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a runtime <see cref="IComposer"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>All runtime composers are required by (compose before) all core composers</para>
|
||||
/// </remarks>
|
||||
public interface IRuntimeComposer : IComposer
|
||||
{ }
|
||||
}
|
||||
@@ -4,9 +4,9 @@
|
||||
/// Represents a user <see cref="IComposer"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>All user composers require (compose after) all core composers.</para>
|
||||
/// <para>User composers compose after core composers, and before the final composer.</para>
|
||||
/// </remarks>
|
||||
[ComposeAfter(typeof(ICoreComposer))]
|
||||
public interface IUserComposer : IComposer
|
||||
{ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Umbraco.Core.Composing
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides a base class for collections of types.
|
||||
/// </summary>
|
||||
public abstract class TypeCollectionBuilderBase<TCollection, TConstraint> : ICollectionBuilder<TCollection, Type>
|
||||
where TCollection : class, IBuilderCollection<Type>
|
||||
{
|
||||
private readonly HashSet<Type> _types = new HashSet<Type>();
|
||||
|
||||
private Type Validate(Type type, string action)
|
||||
{
|
||||
if (!typeof(TConstraint).IsAssignableFrom(type))
|
||||
throw new InvalidOperationException($"Cannot {action} type {type.FullName} as it does not inherit from/implement {typeof(TConstraint).FullName}.");
|
||||
return type;
|
||||
}
|
||||
|
||||
public void Add(Type type) => _types.Add(Validate(type, "add"));
|
||||
|
||||
public void Add<T>() => Add(typeof(T));
|
||||
|
||||
public void Add(IEnumerable<Type> types)
|
||||
{
|
||||
foreach (var type in types) Add(type);
|
||||
}
|
||||
|
||||
public void Remove(Type type) => _types.Remove(Validate(type, "remove"));
|
||||
|
||||
public void Remove<T>() => Remove(typeof(T));
|
||||
|
||||
public TCollection CreateCollection(IFactory factory)
|
||||
{
|
||||
return factory.CreateInstance<TCollection>(_types);
|
||||
}
|
||||
|
||||
public void RegisterWith(IRegister register)
|
||||
{
|
||||
register.Register(CreateCollection, Lifetime.Singleton);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -203,6 +203,28 @@ namespace Umbraco.Core
|
||||
composition.RegisterUnique(_ => registrar);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the database server messenger options.
|
||||
/// </summary>
|
||||
/// <param name="composition">The composition.</param>
|
||||
/// <param name="factory">A function creating the options.</param>
|
||||
/// <remarks>Use DatabaseServerRegistrarAndMessengerComposer.GetDefaultOptions to get the options that Umbraco would use by default.</remarks>
|
||||
public static void SetDatabaseServerMessengerOptions(this Composition composition, Func<IFactory, DatabaseServerMessengerOptions> factory)
|
||||
{
|
||||
composition.RegisterUnique(factory);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the database server messenger options.
|
||||
/// </summary>
|
||||
/// <param name="composition">The composition.</param>
|
||||
/// <param name="options">Options.</param>
|
||||
/// <remarks>Use DatabaseServerRegistrarAndMessengerComposer.GetDefaultOptions to get the options that Umbraco would use by default.</remarks>
|
||||
public static void SetDatabaseServerMessengerOptions(this Composition composition, DatabaseServerMessengerOptions options)
|
||||
{
|
||||
composition.RegisterUnique(_ => options);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the short string helper.
|
||||
/// </summary>
|
||||
|
||||
@@ -7,6 +7,7 @@ using System.Web;
|
||||
using System.Xml.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NPoco.Expressions;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Models;
|
||||
@@ -52,8 +53,8 @@ namespace Umbraco.Core
|
||||
return ContentStatus.Unpublished;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
@@ -134,9 +135,14 @@ namespace Umbraco.Core
|
||||
/// <summary>
|
||||
/// Sets the posted file value of a property.
|
||||
/// </summary>
|
||||
/// <remarks>This really is for FileUpload fields only, and should be obsoleted. For anything else,
|
||||
/// you need to store the file by yourself using Store and then figure out
|
||||
/// how to deal with auto-fill properties (if any) and thumbnails (if any) by yourself.</remarks>
|
||||
public static void SetValue(this IContentBase content, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, string propertyTypeAlias, string filename, HttpPostedFileBase postedFile, string culture = null, string segment = null)
|
||||
{
|
||||
content.SetValue(contentTypeBaseServiceProvider, propertyTypeAlias, postedFile.FileName, postedFile.InputStream, culture, segment);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the posted file value of a property.
|
||||
/// </summary>
|
||||
public static void SetValue(this IContentBase content, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, string propertyTypeAlias, string filename, Stream filestream, string culture = null, string segment = null)
|
||||
{
|
||||
if (filename == null || filestream == null) return;
|
||||
|
||||
@@ -10,6 +10,23 @@ namespace Umbraco.Core
|
||||
///</summary>
|
||||
public static class EnumerableExtensions
|
||||
{
|
||||
internal static bool HasDuplicates<T>(this IEnumerable<T> items, bool includeNull)
|
||||
{
|
||||
var hs = new HashSet<T>();
|
||||
foreach (var item in items)
|
||||
{
|
||||
if (item != null || includeNull)
|
||||
{
|
||||
if (!hs.Add(item))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Wraps this object instance into an IEnumerable{T} consisting of a single item.
|
||||
/// </summary>
|
||||
|
||||
@@ -226,6 +226,8 @@ namespace Umbraco.Core.Migrations.Install
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 32, UniqueId = 32.ToGuid(), DataTypeId = Constants.DataTypes.LabelDateTime, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.LastLockoutDate, Name = Constants.Conventions.Member.LastLockoutDateLabel, SortOrder = 4, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 33, UniqueId = 33.ToGuid(), DataTypeId = Constants.DataTypes.LabelDateTime, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.LastLoginDate, Name = Constants.Conventions.Member.LastLoginDateLabel, SortOrder = 5, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 34, UniqueId = 34.ToGuid(), DataTypeId = Constants.DataTypes.LabelDateTime, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.LastPasswordChangeDate, Name = Constants.Conventions.Member.LastPasswordChangeDateLabel, SortOrder = 6, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 35, UniqueId = 35.ToGuid(), DataTypeId = Constants.DataTypes.LabelDateTime, ContentTypeId = 1044, PropertyTypeGroupId = null, Alias = Constants.Conventions.Member.PasswordQuestion, Name = Constants.Conventions.Member.PasswordQuestionLabel, SortOrder = 7, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte)ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 36, UniqueId = 36.ToGuid(), DataTypeId = Constants.DataTypes.LabelDateTime, ContentTypeId = 1044, PropertyTypeGroupId = null, Alias = Constants.Conventions.Member.PasswordAnswer, Name = Constants.Conventions.Member.PasswordAnswerLabel, SortOrder = 8, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte)ContentVariation.Nothing });
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Migrations.Upgrade.V_7_12_0;
|
||||
using Umbraco.Core.Migrations.Upgrade.V_7_14_0;
|
||||
using Umbraco.Core.Migrations.Upgrade.V_8_0_0;
|
||||
using Umbraco.Core.Migrations.Upgrade.V_8_0_1;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade
|
||||
{
|
||||
@@ -137,6 +138,8 @@ namespace Umbraco.Core.Migrations.Upgrade
|
||||
|
||||
To<RenameLabelAndRichTextPropertyEditorAliases>("{E0CBE54D-A84F-4A8F-9B13-900945FD7ED9}");
|
||||
To<MergeDateAndDateTimePropertyEditor>("{78BAF571-90D0-4D28-8175-EF96316DA789}");
|
||||
To<ChangeNuCacheJsonFormat>("{80C0A0CB-0DD5-4573-B000-C4B7C313C70D}");
|
||||
|
||||
//FINAL
|
||||
|
||||
|
||||
@@ -167,7 +170,7 @@ namespace Umbraco.Core.Migrations.Upgrade
|
||||
From("{init-7.12.4}").To("{init-7.10.0}"); // same as 7.12.0
|
||||
From("{init-7.13.0}").To("{init-7.10.0}"); // same as 7.12.0
|
||||
From("{init-7.13.1}").To("{init-7.10.0}"); // same as 7.12.0
|
||||
|
||||
|
||||
// 7.14.0 has migrations, handle it...
|
||||
// clone going from 7.10 to 1350617A (the last one before we started to merge 7.12 migrations), then
|
||||
// clone going from CF51B39B (after 7.12 migrations) to 0009109C (the last one before we started to merge 7.12 migrations),
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
using Umbraco.Core.Migrations.PostMigrations;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_8_0_1
|
||||
{
|
||||
public class ChangeNuCacheJsonFormat : MigrationBase
|
||||
{
|
||||
public ChangeNuCacheJsonFormat(IMigrationContext context) : base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
// nothing - just adding the post-migration
|
||||
Context.AddPostMigration<RebuildPublishedSnapshot>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -95,6 +95,21 @@ namespace Umbraco.Core.Models
|
||||
|
||||
protected void PropertyTypesChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
//enable this to detect duplicate property aliases. We do want this, however making this change in a
|
||||
//patch release might be a little dangerous
|
||||
|
||||
////detect if there are any duplicate aliases - this cannot be allowed
|
||||
//if (e.Action == NotifyCollectionChangedAction.Add
|
||||
// || e.Action == NotifyCollectionChangedAction.Replace)
|
||||
//{
|
||||
// var allAliases = _noGroupPropertyTypes.Concat(PropertyGroups.SelectMany(x => x.PropertyTypes)).Select(x => x.Alias);
|
||||
// if (allAliases.HasDuplicates(false))
|
||||
// {
|
||||
// var newAliases = string.Join(", ", e.NewItems.Cast<PropertyType>().Select(x => x.Alias));
|
||||
// throw new InvalidOperationException($"Other property types already exist with the aliases: {newAliases}");
|
||||
// }
|
||||
//}
|
||||
|
||||
OnPropertyChanged(nameof(PropertyTypes));
|
||||
}
|
||||
|
||||
@@ -397,15 +412,16 @@ namespace Umbraco.Core.Models
|
||||
var group = PropertyGroups[propertyGroupName];
|
||||
if (group == null) return;
|
||||
|
||||
// re-assign the group's properties to no group
|
||||
// first remove the group
|
||||
PropertyGroups.RemoveItem(propertyGroupName);
|
||||
|
||||
// Then re-assign the group's properties to no group
|
||||
foreach (var property in group.PropertyTypes)
|
||||
{
|
||||
property.PropertyGroupId = null;
|
||||
_noGroupPropertyTypes.Add(property);
|
||||
}
|
||||
|
||||
// actually remove the group
|
||||
PropertyGroups.RemoveItem(propertyGroupName);
|
||||
OnPropertyChanged(nameof(PropertyGroups));
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Umbraco.Core.Models
|
||||
public class PropertyCollection : KeyedCollection<string, Property>, INotifyCollectionChanged, IDeepCloneable
|
||||
{
|
||||
private readonly object _addLocker = new object();
|
||||
internal Action OnAdd;
|
||||
|
||||
internal Func<Property, bool> AdditionValidator { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -49,10 +49,12 @@ namespace Umbraco.Core.Models
|
||||
/// </summary>
|
||||
internal void Reset(IEnumerable<Property> properties)
|
||||
{
|
||||
//collection events will be raised in each of these calls
|
||||
Clear();
|
||||
|
||||
//collection events will be raised in each of these calls
|
||||
foreach (var property in properties)
|
||||
Add(property);
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -60,8 +62,9 @@ namespace Umbraco.Core.Models
|
||||
/// </summary>
|
||||
protected override void SetItem(int index, Property property)
|
||||
{
|
||||
var oldItem = index >= 0 ? this[index] : property;
|
||||
base.SetItem(index, property);
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, property, index));
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, property, oldItem));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -120,10 +123,8 @@ namespace Umbraco.Core.Models
|
||||
}
|
||||
}
|
||||
|
||||
//collection events will be raised in InsertItem with Add
|
||||
base.Add(property);
|
||||
|
||||
OnAdd?.Invoke();
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, property));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,9 +19,6 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
private readonly ReaderWriterLockSlim _addLocker = new ReaderWriterLockSlim();
|
||||
|
||||
// TODO: this doesn't seem to be used anywhere
|
||||
internal Action OnAdd;
|
||||
|
||||
internal PropertyGroupCollection()
|
||||
{ }
|
||||
|
||||
@@ -37,16 +34,19 @@ namespace Umbraco.Core.Models
|
||||
/// <remarks></remarks>
|
||||
internal void Reset(IEnumerable<PropertyGroup> groups)
|
||||
{
|
||||
//collection events will be raised in each of these calls
|
||||
Clear();
|
||||
|
||||
//collection events will be raised in each of these calls
|
||||
foreach (var group in groups)
|
||||
Add(group);
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
|
||||
}
|
||||
|
||||
protected override void SetItem(int index, PropertyGroup item)
|
||||
{
|
||||
var oldItem = index >= 0 ? this[index] : item;
|
||||
base.SetItem(index, item);
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, index));
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, item, oldItem));
|
||||
}
|
||||
|
||||
protected override void RemoveItem(int index)
|
||||
@@ -84,6 +84,7 @@ namespace Umbraco.Core.Models
|
||||
if (keyExists)
|
||||
throw new Exception($"Naming conflict: Changing the name of PropertyGroup '{item.Name}' would result in duplicates");
|
||||
|
||||
//collection events will be raised in SetItem
|
||||
SetItem(IndexOfKey(item.Id), item);
|
||||
return;
|
||||
}
|
||||
@@ -96,16 +97,14 @@ namespace Umbraco.Core.Models
|
||||
var exists = Contains(key);
|
||||
if (exists)
|
||||
{
|
||||
//collection events will be raised in SetItem
|
||||
SetItem(IndexOfKey(key), item);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//collection events will be raised in InsertItem
|
||||
base.Add(item);
|
||||
OnAdd?.Invoke();
|
||||
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item));
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
@@ -19,9 +19,6 @@ namespace Umbraco.Core.Models
|
||||
[IgnoreDataMember]
|
||||
private readonly ReaderWriterLockSlim _addLocker = new ReaderWriterLockSlim();
|
||||
|
||||
// TODO: This doesn't seem to be used
|
||||
[IgnoreDataMember]
|
||||
internal Action OnAdd;
|
||||
|
||||
internal PropertyTypeCollection(bool supportsPublishing)
|
||||
{
|
||||
@@ -43,36 +40,44 @@ namespace Umbraco.Core.Models
|
||||
/// <remarks></remarks>
|
||||
internal void Reset(IEnumerable<PropertyType> properties)
|
||||
{
|
||||
//collection events will be raised in each of these calls
|
||||
Clear();
|
||||
|
||||
//collection events will be raised in each of these calls
|
||||
foreach (var property in properties)
|
||||
Add(property);
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
|
||||
Add(property);
|
||||
}
|
||||
|
||||
protected override void SetItem(int index, PropertyType item)
|
||||
{
|
||||
item.SupportsPublishing = SupportsPublishing;
|
||||
base.SetItem(index, item);
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, index));
|
||||
var oldItem = index >= 0 ? this[index] : item;
|
||||
base.SetItem(index, item);
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, item, oldItem));
|
||||
item.PropertyChanged += Item_PropertyChanged;
|
||||
}
|
||||
|
||||
protected override void RemoveItem(int index)
|
||||
{
|
||||
var removed = this[index];
|
||||
base.RemoveItem(index);
|
||||
removed.PropertyChanged -= Item_PropertyChanged;
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, removed));
|
||||
}
|
||||
|
||||
protected override void InsertItem(int index, PropertyType item)
|
||||
{
|
||||
item.SupportsPublishing = SupportsPublishing;
|
||||
base.InsertItem(index, item);
|
||||
base.InsertItem(index, item);
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item));
|
||||
item.PropertyChanged += Item_PropertyChanged;
|
||||
}
|
||||
|
||||
protected override void ClearItems()
|
||||
{
|
||||
base.ClearItems();
|
||||
foreach (var item in this)
|
||||
item.PropertyChanged -= Item_PropertyChanged;
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
|
||||
}
|
||||
|
||||
@@ -91,6 +96,7 @@ namespace Umbraco.Core.Models
|
||||
var exists = Contains(key);
|
||||
if (exists)
|
||||
{
|
||||
//collection events will be raised in SetItem
|
||||
SetItem(IndexOfKey(key), item);
|
||||
return;
|
||||
}
|
||||
@@ -103,10 +109,8 @@ namespace Umbraco.Core.Models
|
||||
item.SortOrder = this.Max(x => x.SortOrder) + 1;
|
||||
}
|
||||
|
||||
//collection events will be raised in InsertItem
|
||||
base.Add(item);
|
||||
OnAdd?.Invoke();
|
||||
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item));
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -115,6 +119,17 @@ namespace Umbraco.Core.Models
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when a property changes on a PropertyType that exists in this collection
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void Item_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||||
{
|
||||
var propType = (PropertyType)sender;
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, propType, propType));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether this collection contains a <see cref="Property"/> whose alias matches the specified PropertyType.
|
||||
/// </summary>
|
||||
|
||||
@@ -11,14 +11,14 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PublishedCultureInfo"/> class.
|
||||
/// </summary>
|
||||
public PublishedCultureInfo(string culture, string name, DateTime date)
|
||||
public PublishedCultureInfo(string culture, string name, string urlSegment, DateTime date)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(culture)) throw new ArgumentNullOrEmptyException(nameof(culture));
|
||||
if (string.IsNullOrWhiteSpace(name)) throw new ArgumentNullOrEmptyException(nameof(name));
|
||||
|
||||
Culture = culture;
|
||||
Name = name;
|
||||
UrlSegment = name.ToUrlSegment(culture);
|
||||
UrlSegment = urlSegment;
|
||||
Date = date;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,11 +9,10 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
{
|
||||
internal static class MemberTypeReadOnlyFactory
|
||||
{
|
||||
public static IMemberType BuildEntity(MemberTypeReadOnlyDto dto, out bool needsSaving)
|
||||
public static IMemberType BuildEntity(MemberTypeReadOnlyDto dto)
|
||||
{
|
||||
var standardPropertyTypes = Constants.Conventions.Member.GetStandardPropertyTypeStubs();
|
||||
needsSaving = false;
|
||||
|
||||
|
||||
var memberType = new MemberType(dto.ParentId);
|
||||
|
||||
try
|
||||
@@ -41,27 +40,29 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
var propertyTypeGroupCollection = GetPropertyTypeGroupCollection(dto, memberType, standardPropertyTypes);
|
||||
memberType.PropertyGroups = propertyTypeGroupCollection;
|
||||
|
||||
var propertyTypes = GetPropertyTypes(dto, memberType, standardPropertyTypes);
|
||||
memberType.NoGroupPropertyTypes = GetNoGroupPropertyTypes(dto, memberType, standardPropertyTypes);
|
||||
|
||||
//By Convention we add 9 standard PropertyTypes - This is only here to support loading of types that didn't have these conventions before.
|
||||
// By Convention we add 9 standard PropertyTypes - This is only here to support loading of types that didn't have these conventions before.
|
||||
// In theory this should not happen! The only reason this did happen was because:
|
||||
// A) we didn't install all of the default membership properties by default
|
||||
// B) the existing data is super old when we didn't store membership properties at all (very very old)
|
||||
// So what to do? We absolutely do not want to update the database when only a read was requested, this will cause problems
|
||||
// so we should just add these virtual properties, they will have no ids but they will have aliases and this should be perfectly
|
||||
// fine for any membership provider logic to work since neither membership providers or asp.net identity care about whether a property
|
||||
// has an ID or not.
|
||||
// When the member type is saved, all the properties will correctly be added.
|
||||
|
||||
//This will add this group if it doesn't exist, no need to error check here
|
||||
memberType.AddPropertyGroup(Constants.Conventions.Member.StandardPropertiesGroupName);
|
||||
foreach (var standardPropertyType in standardPropertyTypes)
|
||||
{
|
||||
if (dto.PropertyTypes.Any(x => x.Alias.Equals(standardPropertyType.Key))) continue;
|
||||
//This will add the property if it doesn't exist, no need to error check here
|
||||
memberType.AddPropertyType(standardPropertyType.Value, Constants.Conventions.Member.StandardPropertiesGroupName);
|
||||
|
||||
// beware!
|
||||
// means that we can return a memberType "from database" that has some property types
|
||||
// that do *not* come from the database and therefore are incomplete eg have no key,
|
||||
// no id, no dataTypeDefinitionId - ouch! - better notify caller of the situation
|
||||
needsSaving = true;
|
||||
|
||||
//Add the standard PropertyType to the current list
|
||||
propertyTypes.Add(standardPropertyType.Value);
|
||||
|
||||
//Internal dictionary for adding "MemberCanEdit", "VisibleOnProfile", "IsSensitive" properties to each PropertyType
|
||||
memberType.MemberTypePropertyTypes.Add(standardPropertyType.Key,
|
||||
new MemberTypePropertyProfileAccess(false, false, false));
|
||||
if (!memberType.MemberTypePropertyTypes.TryGetValue(standardPropertyType.Key, out var memberTypePropertyProfile))
|
||||
memberType.MemberTypePropertyTypes[standardPropertyType.Key] = new MemberTypePropertyProfileAccess(false, false, false);
|
||||
}
|
||||
memberType.NoGroupPropertyTypes = propertyTypes;
|
||||
|
||||
return memberType;
|
||||
}
|
||||
@@ -147,13 +148,14 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
return propertyGroups;
|
||||
}
|
||||
|
||||
private static List<PropertyType> GetPropertyTypes(MemberTypeReadOnlyDto dto, MemberType memberType, Dictionary<string, PropertyType> standardProps)
|
||||
private static List<PropertyType> GetNoGroupPropertyTypes(MemberTypeReadOnlyDto dto, MemberType memberType, Dictionary<string, PropertyType> standardProps)
|
||||
{
|
||||
//Find PropertyTypes that does not belong to a PropertyTypeGroup
|
||||
var propertyTypes = new List<PropertyType>();
|
||||
foreach (var typeDto in dto.PropertyTypes.Where(x => (x.PropertyTypeGroupId.HasValue == false || x.PropertyTypeGroupId.Value == 0) && x.Id.HasValue))
|
||||
{
|
||||
//Internal dictionary for adding "MemberCanEdit" and "VisibleOnProfile" properties to each PropertyType
|
||||
|
||||
memberType.MemberTypePropertyTypes.Add(typeDto.Alias,
|
||||
new MemberTypePropertyProfileAccess(typeDto.ViewOnProfile, typeDto.CanEdit, typeDto.IsSensitive));
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
protected override IIdentityUserLogin PerformGet(int id)
|
||||
{
|
||||
var sql = GetBaseQuery(false);
|
||||
sql.Where(GetBaseWhereClause(), new { Id = id });
|
||||
sql.Where(GetBaseWhereClause(), new { id = id });
|
||||
|
||||
var dto = Database.Fetch<ExternalLoginDto>(SqlSyntax.SelectTop(sql, 1)).FirstOrDefault();
|
||||
if (dto == null)
|
||||
|
||||
@@ -308,13 +308,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
if (dtos == null || dtos.Any() == false)
|
||||
return Enumerable.Empty<IMemberType>();
|
||||
|
||||
return dtos.Select(x =>
|
||||
{
|
||||
bool needsSaving;
|
||||
var memberType = MemberTypeReadOnlyFactory.BuildEntity(x, out needsSaving);
|
||||
if (needsSaving) PersistUpdatedItem(memberType);
|
||||
return memberType;
|
||||
}).ToList();
|
||||
return dtos.Select(MemberTypeReadOnlyFactory.BuildEntity).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
namespace Umbraco.Core.PropertyEditors
|
||||
{
|
||||
internal class DropDownFlexibleConfiguration : ValueListConfiguration
|
||||
public class DropDownFlexibleConfiguration : ValueListConfiguration
|
||||
{
|
||||
[ConfigurationField("multiple", "Enable multiple choice", "boolean", Description = "When checked, the dropdown will be a select multiple / combo box style dropdown.")]
|
||||
public bool Multiple { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,10 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
if (source is int)
|
||||
return (int)source == 1;
|
||||
|
||||
// this is required for correct true/false handling in nested content elements
|
||||
if (source is long)
|
||||
return (long)source == 1;
|
||||
|
||||
if (source is bool)
|
||||
return (bool)source;
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides extension methods for <see cref="IPublishedModelFactory"/>.
|
||||
/// </summary>
|
||||
public static class PublishedModelFactoryExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Executes an action with a safe live factory/
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>If the factory is a live factory, ensures it is refreshed and locked while executing the action.</para>
|
||||
/// </remarks>
|
||||
public static void WithSafeLiveFactory(this IPublishedModelFactory factory, Action action)
|
||||
{
|
||||
if (factory is ILivePublishedModelFactory liveFactory)
|
||||
{
|
||||
lock (liveFactory.SyncRoot)
|
||||
{
|
||||
liveFactory.Refresh();
|
||||
action();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
action();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -5,11 +5,11 @@ using Umbraco.Core.IO;
|
||||
|
||||
namespace Umbraco.Core.Runtime
|
||||
{
|
||||
public class CoreRuntimeComponent : IComponent
|
||||
public class CoreInitialComponent : IComponent
|
||||
{
|
||||
private readonly IEnumerable<Profile> _mapperProfiles;
|
||||
|
||||
public CoreRuntimeComponent(IEnumerable<Profile> mapperProfiles)
|
||||
public CoreInitialComponent(IEnumerable<Profile> mapperProfiles)
|
||||
{
|
||||
_mapperProfiles = mapperProfiles;
|
||||
}
|
||||
+3
-1
@@ -24,7 +24,9 @@ using IntegerValidator = Umbraco.Core.PropertyEditors.Validators.IntegerValidato
|
||||
|
||||
namespace Umbraco.Core.Runtime
|
||||
{
|
||||
public class CoreRuntimeComposer : ComponentComposer<CoreRuntimeComponent>, IRuntimeComposer
|
||||
// core's initial composer composes before all core composers
|
||||
[ComposeBefore(typeof(ICoreComposer))]
|
||||
public class CoreInitialComposer : ComponentComposer<CoreInitialComponent>
|
||||
{
|
||||
public override void Compose(Composition composition)
|
||||
{
|
||||
@@ -5,6 +5,7 @@ using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Web;
|
||||
using System.Web.Hosting;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Configuration;
|
||||
@@ -70,10 +71,15 @@ namespace Umbraco.Core.Runtime
|
||||
// objects.
|
||||
|
||||
using (var timer = profilingLogger.TraceDuration<CoreRuntime>(
|
||||
$"Booting Umbraco {UmbracoVersion.SemanticVersion.ToSemanticString()} on {NetworkHelper.MachineName}.",
|
||||
$"Booting Umbraco {UmbracoVersion.SemanticVersion.ToSemanticString()}.",
|
||||
"Booted.",
|
||||
"Boot failed."))
|
||||
{
|
||||
logger.Info<CoreRuntime>("Booting site '{HostingSiteName}', app '{HostingApplicationID}', path '{HostingPhysicalPath}', server '{MachineName}'.",
|
||||
HostingEnvironment.SiteName,
|
||||
HostingEnvironment.ApplicationID,
|
||||
HostingEnvironment.ApplicationPhysicalPath,
|
||||
NetworkHelper.MachineName);
|
||||
logger.Debug<CoreRuntime>("Runtime: {Runtime}", GetType().FullName);
|
||||
|
||||
// application environment
|
||||
@@ -168,7 +174,7 @@ namespace Umbraco.Core.Runtime
|
||||
_state.BootFailedException = bfe;
|
||||
}
|
||||
|
||||
timer.Fail(exception: bfe); // be sure to log the exception - even if we repeat ourselves
|
||||
timer?.Fail(exception: bfe); // be sure to log the exception - even if we repeat ourselves
|
||||
|
||||
// if something goes wrong above, we may end up with no factory
|
||||
// meaning nothing can get the runtime state, etc - so let's try
|
||||
@@ -242,7 +248,7 @@ namespace Umbraco.Core.Runtime
|
||||
}
|
||||
catch
|
||||
{
|
||||
timer.Fail();
|
||||
timer?.Fail();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,39 +2,61 @@
|
||||
|
||||
namespace Umbraco.Core.Scoping
|
||||
{
|
||||
// base class for an object that will be enlisted in scope context, if any. it
|
||||
// must be used in a 'using' block, and if not scoped, released when disposed,
|
||||
// else when scope context runs enlisted actions
|
||||
/// <summary>
|
||||
/// Provides a base class for scope contextual objects.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>A scope contextual object is enlisted in the current scope context,
|
||||
/// if any, and released when the context exists. It must be used in a 'using'
|
||||
/// block, and will be released when disposed, if not part of a scope.</para>
|
||||
/// </remarks>
|
||||
public abstract class ScopeContextualBase : IDisposable
|
||||
{
|
||||
private bool _using, _scoped;
|
||||
private bool _scoped;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a contextual object.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the object.</typeparam>
|
||||
/// <param name="scopeProvider">A scope provider.</param>
|
||||
/// <param name="key">A context key for the object.</param>
|
||||
/// <param name="ctor">A function producing the contextual object.</param>
|
||||
/// <returns>The contextual object.</returns>
|
||||
/// <remarks>
|
||||
/// <para></para>
|
||||
/// </remarks>
|
||||
public static T Get<T>(IScopeProvider scopeProvider, string key, Func<bool, T> ctor)
|
||||
where T : ScopeContextualBase
|
||||
{
|
||||
// no scope context = create a non-scoped object
|
||||
var scopeContext = scopeProvider.Context;
|
||||
if (scopeContext == null)
|
||||
return ctor(false);
|
||||
|
||||
// create & enlist the scoped object
|
||||
var w = scopeContext.Enlist("ScopeContextualBase_" + key,
|
||||
() => ctor(true),
|
||||
(completed, item) => { item.Release(completed); });
|
||||
|
||||
if (w._using) throw new InvalidOperationException("panic: used.");
|
||||
w._using = true;
|
||||
w._scoped = true;
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <remarks>
|
||||
/// <para>If not scoped, then this releases the contextual object.</para>
|
||||
/// </remarks>
|
||||
public void Dispose()
|
||||
{
|
||||
_using = false;
|
||||
|
||||
if (_scoped == false)
|
||||
Release(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Releases the contextual object.
|
||||
/// </summary>
|
||||
/// <param name="completed">A value indicating whether the scoped operation completed.</param>
|
||||
public abstract void Release(bool completed);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1902,9 +1902,8 @@ namespace Umbraco.Core.Services.Implement
|
||||
content.ParentId = parentId;
|
||||
|
||||
// get the level delta (old pos to new pos)
|
||||
var levelDelta = parent == null
|
||||
? 1 - content.Level + (parentId == Constants.System.RecycleBinContent ? 1 : 0)
|
||||
: parent.Level + 1 - content.Level;
|
||||
// note that recycle bin (id:-20) level is 0!
|
||||
var levelDelta = 1 - content.Level + (parent?.Level ?? 0);
|
||||
|
||||
var paths = new Dictionary<int, string>();
|
||||
|
||||
@@ -2875,7 +2874,14 @@ namespace Umbraco.Core.Services.Implement
|
||||
{
|
||||
foreach (var property in blueprint.Properties)
|
||||
{
|
||||
content.SetValue(property.Alias, property.GetValue(culture), culture);
|
||||
if (property.PropertyType.VariesByCulture())
|
||||
{
|
||||
content.SetValue(property.Alias, property.GetValue(culture), culture);
|
||||
}
|
||||
else
|
||||
{
|
||||
content.SetValue(property.Alias, property.GetValue());
|
||||
}
|
||||
}
|
||||
|
||||
content.Name = blueprint.Name;
|
||||
|
||||
@@ -289,7 +289,7 @@ namespace Umbraco.Core.Services.Implement
|
||||
scope.Events.Dispatch(Saved, this, saveEventArgs);
|
||||
scope.Events.Dispatch(TreeChanged, this, new TreeChange<IMedia>(media, TreeChangeTypes.RefreshNode).ToEventArgs());
|
||||
}
|
||||
|
||||
|
||||
if (withIdentity == false)
|
||||
return;
|
||||
|
||||
@@ -716,7 +716,7 @@ namespace Umbraco.Core.Services.Implement
|
||||
#endregion
|
||||
|
||||
#region Delete
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Permanently deletes an <see cref="IMedia"/> object
|
||||
/// </summary>
|
||||
@@ -975,9 +975,8 @@ namespace Umbraco.Core.Services.Implement
|
||||
media.ParentId = parentId;
|
||||
|
||||
// get the level delta (old pos to new pos)
|
||||
var levelDelta = parent == null
|
||||
? 1 - media.Level + (parentId == Constants.System.RecycleBinMedia ? 1 : 0)
|
||||
: parent.Level + 1 - media.Level;
|
||||
// note that recycle bin (id:-20) level is 0!
|
||||
var levelDelta = 1 - media.Level + (parent?.Level ?? 0);
|
||||
|
||||
var paths = new Dictionary<int, string>();
|
||||
|
||||
@@ -1024,6 +1023,7 @@ namespace Umbraco.Core.Services.Implement
|
||||
/// <summary>
|
||||
/// Empties the Recycle Bin by deleting all <see cref="IMedia"/> that resides in the bin
|
||||
/// </summary>
|
||||
/// <param name="userId">Optional Id of the User emptying the Recycle Bin</param>
|
||||
public OperationResult EmptyRecycleBin()
|
||||
{
|
||||
var nodeObjectType = Constants.ObjectTypes.Media;
|
||||
|
||||
@@ -168,7 +168,6 @@
|
||||
<Compile Include="Composing\EnableComposerAttribute.cs" />
|
||||
<Compile Include="Composing\IComposer.cs" />
|
||||
<Compile Include="Composing\ICoreComposer.cs" />
|
||||
<Compile Include="Composing\IRuntimeComposer.cs" />
|
||||
<Compile Include="Composing\IComponent.cs" />
|
||||
<Compile Include="Composing\IUserComposer.cs" />
|
||||
<Compile Include="Compose\ManifestWatcherComposer.cs" />
|
||||
@@ -209,10 +208,13 @@
|
||||
<Compile Include="Composing\TypeLoader.cs" />
|
||||
<Compile Include="IO\MediaPathSchemes\UniqueMediaPathScheme.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\MergeDateAndDateTimePropertyEditor.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_1\ChangeNuCacheJsonFormat.cs" />
|
||||
<Compile Include="Models\PublishedContent\ILivePublishedModelFactory.cs" />
|
||||
<Compile Include="PropertyEditors\DateTimeConfiguration.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\RenameLabelAndRichTextPropertyEditorAliases.cs" />
|
||||
<Compile Include="PublishedModelFactoryExtensions.cs" />
|
||||
<Compile Include="Services\PropertyValidationService.cs" />
|
||||
<Compile Include="Composing\TypeCollectionBuilderBase.cs" />
|
||||
<Compile Include="TypeLoaderExtensions.cs" />
|
||||
<Compile Include="Composing\WeightAttribute.cs" />
|
||||
<Compile Include="Composing\WeightedCollectionBuilderBase.cs" />
|
||||
@@ -529,7 +531,7 @@
|
||||
<Compile Include="RuntimeLevelReason.cs" />
|
||||
<Compile Include="RuntimeOptions.cs" />
|
||||
<Compile Include="Runtime\CoreRuntime.cs" />
|
||||
<Compile Include="Runtime\CoreRuntimeComponent.cs" />
|
||||
<Compile Include="Runtime\CoreInitialComponent.cs" />
|
||||
<Compile Include="CustomBooleanTypeConverter.cs" />
|
||||
<Compile Include="Migrations\Expressions\Common\ExecutableBuilder.cs" />
|
||||
<Compile Include="Migrations\Expressions\Common\IExecutableBuilder.cs" />
|
||||
@@ -1310,7 +1312,7 @@
|
||||
<Compile Include="ReflectionUtilities.cs" />
|
||||
<Compile Include="RuntimeLevel.cs" />
|
||||
<Compile Include="RuntimeState.cs" />
|
||||
<Compile Include="Runtime\CoreRuntimeComposer.cs" />
|
||||
<Compile Include="Runtime\CoreInitialComposer.cs" />
|
||||
<Compile Include="SafeCallContext.cs" />
|
||||
<Compile Include="Scoping\IInstanceIdentifiable.cs" />
|
||||
<Compile Include="Scoping\IScope.cs" />
|
||||
|
||||
@@ -158,7 +158,7 @@ namespace Umbraco.Tests.Cache
|
||||
new TestDefaultCultureAccessor(),
|
||||
TestObjects.GetUmbracoSettings(),
|
||||
TestObjects.GetGlobalSettings(),
|
||||
Enumerable.Empty<IUrlProvider>(),
|
||||
new UrlProviderCollection(Enumerable.Empty<IUrlProvider>()),
|
||||
Mock.Of<IUserService>());
|
||||
|
||||
// just assert it does not throw
|
||||
|
||||
@@ -5,6 +5,7 @@ using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core.Scoping;
|
||||
using Umbraco.Web.PublishedCache.NuCache;
|
||||
using Umbraco.Web.PublishedCache.NuCache.Snap;
|
||||
|
||||
namespace Umbraco.Tests.Cache
|
||||
{
|
||||
@@ -388,8 +389,7 @@ namespace Umbraco.Tests.Cache
|
||||
// collect liveGen
|
||||
GC.Collect();
|
||||
|
||||
SnapDictionary<int, string>.GenerationObject genObj;
|
||||
Assert.IsTrue(d.Test.GenerationObjects.TryPeek(out genObj));
|
||||
Assert.IsTrue(d.Test.GenObjs.TryPeek(out var genObj));
|
||||
genObj = null;
|
||||
|
||||
// in Release mode, it works, but in Debug mode, the weak reference is still alive
|
||||
@@ -399,14 +399,14 @@ namespace Umbraco.Tests.Cache
|
||||
GC.Collect();
|
||||
#endif
|
||||
|
||||
Assert.IsTrue(d.Test.GenerationObjects.TryPeek(out genObj));
|
||||
Assert.IsFalse(genObj.WeakReference.IsAlive); // snapshot is gone, along with its reference
|
||||
Assert.IsTrue(d.Test.GenObjs.TryPeek(out genObj));
|
||||
Assert.IsFalse(genObj.WeakGenRef.IsAlive); // snapshot is gone, along with its reference
|
||||
|
||||
await d.CollectAsync();
|
||||
|
||||
Assert.AreEqual(0, d.Test.GetValues(1).Length); // null value is gone
|
||||
Assert.AreEqual(0, d.Count); // item is gone
|
||||
Assert.AreEqual(0, d.Test.GenerationObjects.Count);
|
||||
Assert.AreEqual(0, d.Test.GenObjs.Count);
|
||||
Assert.AreEqual(0, d.SnapCount); // snapshot is gone
|
||||
Assert.AreEqual(0, d.GenCount); // and generation has been dequeued
|
||||
}
|
||||
@@ -632,7 +632,7 @@ namespace Umbraco.Tests.Cache
|
||||
Assert.AreEqual(1, d.Test.LiveGen);
|
||||
Assert.IsTrue(d.Test.NextGen);
|
||||
|
||||
using (d.GetWriter(GetScopeProvider()))
|
||||
using (d.GetScopedWriteLock(GetScopeProvider()))
|
||||
{
|
||||
var s1 = d.CreateSnapshot();
|
||||
|
||||
@@ -685,7 +685,7 @@ namespace Umbraco.Tests.Cache
|
||||
Assert.IsFalse(d.Test.NextGen);
|
||||
Assert.AreEqual("uno", s2.Get(1));
|
||||
|
||||
using (d.GetWriter(GetScopeProvider()))
|
||||
using (d.GetScopedWriteLock(GetScopeProvider()))
|
||||
{
|
||||
// gen 3
|
||||
Assert.AreEqual(2, d.Test.GetValues(1).Length);
|
||||
@@ -712,16 +712,102 @@ namespace Umbraco.Tests.Cache
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NestedWriteLocking()
|
||||
public void NestedWriteLocking1()
|
||||
{
|
||||
var d = new SnapDictionary<int, string>();
|
||||
var t = d.Test;
|
||||
t.CollectAuto = false;
|
||||
|
||||
Assert.AreEqual(0, d.CreateSnapshot().Gen);
|
||||
|
||||
// no scope context: writers nest, last one to be disposed commits
|
||||
|
||||
var scopeProvider = GetScopeProvider();
|
||||
|
||||
using (var w1 = d.GetScopedWriteLock(scopeProvider))
|
||||
{
|
||||
Assert.AreEqual(1, t.LiveGen);
|
||||
Assert.AreEqual(1, t.WLocked);
|
||||
Assert.IsTrue(t.NextGen);
|
||||
|
||||
using (var w2 = d.GetScopedWriteLock(scopeProvider))
|
||||
{
|
||||
Assert.AreEqual(1, t.LiveGen);
|
||||
Assert.AreEqual(2, t.WLocked);
|
||||
Assert.IsTrue(t.NextGen);
|
||||
|
||||
Assert.AreNotSame(w1, w2); // get a new writer each time
|
||||
|
||||
d.Set(1, "one");
|
||||
|
||||
Assert.AreEqual(0, d.CreateSnapshot().Gen);
|
||||
}
|
||||
|
||||
Assert.AreEqual(1, t.LiveGen);
|
||||
Assert.AreEqual(1, t.WLocked);
|
||||
Assert.IsTrue(t.NextGen);
|
||||
|
||||
Assert.AreEqual(0, d.CreateSnapshot().Gen);
|
||||
}
|
||||
|
||||
Assert.AreEqual(1, t.LiveGen);
|
||||
Assert.AreEqual(0, t.WLocked);
|
||||
Assert.IsTrue(t.NextGen);
|
||||
|
||||
Assert.AreEqual(1, d.CreateSnapshot().Gen);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NestedWriteLocking2()
|
||||
{
|
||||
var d = new SnapDictionary<int, string>();
|
||||
d.Test.CollectAuto = false;
|
||||
|
||||
var scopeProvider = GetScopeProvider();
|
||||
using (d.GetWriter(scopeProvider))
|
||||
Assert.AreEqual(0, d.CreateSnapshot().Gen);
|
||||
|
||||
// scope context: writers enlist
|
||||
|
||||
var scopeContext = new ScopeContext();
|
||||
var scopeProvider = GetScopeProvider(scopeContext);
|
||||
|
||||
using (var w1 = d.GetScopedWriteLock(scopeProvider))
|
||||
{
|
||||
using (d.GetWriter(scopeProvider))
|
||||
using (var w2 = d.GetScopedWriteLock(scopeProvider))
|
||||
{
|
||||
Assert.AreSame(w1, w2);
|
||||
|
||||
d.Set(1, "one");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NestedWriteLocking3()
|
||||
{
|
||||
var d = new SnapDictionary<int, string>();
|
||||
var t = d.Test;
|
||||
t.CollectAuto = false;
|
||||
|
||||
Assert.AreEqual(0, d.CreateSnapshot().Gen);
|
||||
|
||||
var scopeContext = new ScopeContext();
|
||||
var scopeProvider1 = GetScopeProvider();
|
||||
var scopeProvider2 = GetScopeProvider(scopeContext);
|
||||
|
||||
using (var w1 = d.GetScopedWriteLock(scopeProvider1))
|
||||
{
|
||||
Assert.AreEqual(1, t.LiveGen);
|
||||
Assert.AreEqual(1, t.WLocked);
|
||||
Assert.IsTrue(t.NextGen);
|
||||
|
||||
using (var w2 = d.GetScopedWriteLock(scopeProvider2))
|
||||
{
|
||||
Assert.AreEqual(1, t.LiveGen);
|
||||
Assert.AreEqual(2, t.WLocked);
|
||||
Assert.IsTrue(t.NextGen);
|
||||
|
||||
Assert.AreNotSame(w1, w2);
|
||||
|
||||
d.Set(1, "one");
|
||||
}
|
||||
}
|
||||
@@ -764,7 +850,7 @@ namespace Umbraco.Tests.Cache
|
||||
|
||||
var scopeProvider = GetScopeProvider();
|
||||
|
||||
using (d.GetWriter(scopeProvider))
|
||||
using (d.GetScopedWriteLock(scopeProvider))
|
||||
{
|
||||
// gen 3
|
||||
Assert.AreEqual(2, d.Test.GetValues(1).Length);
|
||||
@@ -809,7 +895,7 @@ namespace Umbraco.Tests.Cache
|
||||
|
||||
var scopeProvider = GetScopeProvider();
|
||||
|
||||
using (d.GetWriter(scopeProvider))
|
||||
using (d.GetScopedWriteLock(scopeProvider))
|
||||
{
|
||||
// creating a snapshot in a write-lock does NOT return the "current" content
|
||||
// it uses the previous snapshot, so new snapshot created only on release
|
||||
@@ -846,9 +932,10 @@ namespace Umbraco.Tests.Cache
|
||||
Assert.AreEqual(2, s2.Gen);
|
||||
Assert.AreEqual("uno", s2.Get(1));
|
||||
|
||||
var scopeProvider = GetScopeProvider(true);
|
||||
var scopeContext = new ScopeContext();
|
||||
var scopeProvider = GetScopeProvider(scopeContext);
|
||||
|
||||
using (d.GetWriter(scopeProvider))
|
||||
using (d.GetScopedWriteLock(scopeProvider))
|
||||
{
|
||||
// creating a snapshot in a write-lock does NOT return the "current" content
|
||||
// it uses the previous snapshot, so new snapshot created only on release
|
||||
@@ -867,7 +954,7 @@ namespace Umbraco.Tests.Cache
|
||||
Assert.AreEqual(2, s4.Gen);
|
||||
Assert.AreEqual("uno", s4.Get(1));
|
||||
|
||||
((ScopeContext) scopeProvider.Context).ScopeExit(true);
|
||||
scopeContext.ScopeExit(true);
|
||||
|
||||
var s5 = d.CreateSnapshot();
|
||||
Assert.AreEqual(3, s5.Gen);
|
||||
@@ -878,7 +965,8 @@ namespace Umbraco.Tests.Cache
|
||||
public void ScopeLocking2()
|
||||
{
|
||||
var d = new SnapDictionary<int, string>();
|
||||
d.Test.CollectAuto = false;
|
||||
var t = d.Test;
|
||||
t.CollectAuto = false;
|
||||
|
||||
// gen 1
|
||||
d.Set(1, "one");
|
||||
@@ -891,12 +979,13 @@ namespace Umbraco.Tests.Cache
|
||||
Assert.AreEqual(2, s2.Gen);
|
||||
Assert.AreEqual("uno", s2.Get(1));
|
||||
|
||||
var scopeProviderMock = new Mock<IScopeProvider>();
|
||||
var scopeContext = new ScopeContext();
|
||||
scopeProviderMock.Setup(x => x.Context).Returns(scopeContext);
|
||||
var scopeProvider = scopeProviderMock.Object;
|
||||
Assert.AreEqual(2, t.LiveGen);
|
||||
Assert.IsFalse(t.NextGen);
|
||||
|
||||
using (d.GetWriter(scopeProvider))
|
||||
var scopeContext = new ScopeContext();
|
||||
var scopeProvider = GetScopeProvider(scopeContext);
|
||||
|
||||
using (d.GetScopedWriteLock(scopeProvider))
|
||||
{
|
||||
// creating a snapshot in a write-lock does NOT return the "current" content
|
||||
// it uses the previous snapshot, so new snapshot created only on release
|
||||
@@ -905,18 +994,35 @@ namespace Umbraco.Tests.Cache
|
||||
Assert.AreEqual(2, s3.Gen);
|
||||
Assert.AreEqual("uno", s3.Get(1));
|
||||
|
||||
// we made some changes, so a next gen is required
|
||||
Assert.AreEqual(3, t.LiveGen);
|
||||
Assert.IsTrue(t.NextGen);
|
||||
Assert.AreEqual(1, t.WLocked);
|
||||
|
||||
// but live snapshot contains changes
|
||||
var ls = d.Test.LiveSnapshot;
|
||||
var ls = t.LiveSnapshot;
|
||||
Assert.AreEqual("ein", ls.Get(1));
|
||||
Assert.AreEqual(3, ls.Gen);
|
||||
}
|
||||
|
||||
// nothing is committed until scope exits
|
||||
Assert.AreEqual(3, t.LiveGen);
|
||||
Assert.IsTrue(t.NextGen);
|
||||
Assert.AreEqual(1, t.WLocked);
|
||||
|
||||
// no changes until exit
|
||||
var s4 = d.CreateSnapshot();
|
||||
Assert.AreEqual(2, s4.Gen);
|
||||
Assert.AreEqual("uno", s4.Get(1));
|
||||
|
||||
scopeContext.ScopeExit(false);
|
||||
|
||||
// now things have changed
|
||||
Assert.AreEqual(2, t.LiveGen);
|
||||
Assert.IsFalse(t.NextGen);
|
||||
Assert.AreEqual(0, t.WLocked);
|
||||
|
||||
// no changes since not completed
|
||||
var s5 = d.CreateSnapshot();
|
||||
Assert.AreEqual(2, s5.Gen);
|
||||
Assert.AreEqual("uno", s5.Get(1));
|
||||
@@ -955,12 +1061,92 @@ namespace Umbraco.Tests.Cache
|
||||
Assert.AreEqual("four", all[3]);
|
||||
}
|
||||
|
||||
private IScopeProvider GetScopeProvider(bool withContext = false)
|
||||
[Test]
|
||||
public void DontPanic()
|
||||
{
|
||||
var scopeProviderMock = new Mock<IScopeProvider>();
|
||||
var scopeContext = withContext ? new ScopeContext() : null;
|
||||
scopeProviderMock.Setup(x => x.Context).Returns(scopeContext);
|
||||
var scopeProvider = scopeProviderMock.Object;
|
||||
var d = new SnapDictionary<int, string>();
|
||||
d.Test.CollectAuto = false;
|
||||
|
||||
Assert.IsNull(d.Test.GenObj);
|
||||
|
||||
// gen 1
|
||||
d.Set(1, "one");
|
||||
Assert.IsTrue(d.Test.NextGen);
|
||||
Assert.AreEqual(1, d.Test.LiveGen);
|
||||
Assert.IsNull(d.Test.GenObj);
|
||||
|
||||
var s1 = d.CreateSnapshot();
|
||||
Assert.IsFalse(d.Test.NextGen);
|
||||
Assert.AreEqual(1, d.Test.LiveGen);
|
||||
Assert.IsNotNull(d.Test.GenObj);
|
||||
Assert.AreEqual(1, d.Test.GenObj.Gen);
|
||||
|
||||
Assert.AreEqual(1, s1.Gen);
|
||||
Assert.AreEqual("one", s1.Get(1));
|
||||
|
||||
d.Set(1, "uno");
|
||||
Assert.IsTrue(d.Test.NextGen);
|
||||
Assert.AreEqual(2, d.Test.LiveGen);
|
||||
Assert.IsNotNull(d.Test.GenObj);
|
||||
Assert.AreEqual(1, d.Test.GenObj.Gen);
|
||||
|
||||
var scopeContext = new ScopeContext();
|
||||
var scopeProvider = GetScopeProvider(scopeContext);
|
||||
|
||||
// scopeProvider.Context == scopeContext -> writer is scoped
|
||||
// writer is scope contextual and scoped
|
||||
// when disposed, nothing happens
|
||||
// when the context exists, the writer is released
|
||||
using (d.GetScopedWriteLock(scopeProvider))
|
||||
{
|
||||
d.Set(1, "ein");
|
||||
Assert.IsTrue(d.Test.NextGen);
|
||||
Assert.AreEqual(3, d.Test.LiveGen);
|
||||
Assert.IsNotNull(d.Test.GenObj);
|
||||
Assert.AreEqual(2, d.Test.GenObj.Gen);
|
||||
}
|
||||
|
||||
// writer has not released
|
||||
Assert.AreEqual(1, d.Test.WLocked);
|
||||
Assert.IsNotNull(d.Test.GenObj);
|
||||
Assert.AreEqual(2, d.Test.GenObj.Gen);
|
||||
|
||||
// nothing changed
|
||||
Assert.IsTrue(d.Test.NextGen);
|
||||
Assert.AreEqual(3, d.Test.LiveGen);
|
||||
|
||||
// panic!
|
||||
var s2 = d.CreateSnapshot();
|
||||
|
||||
Assert.AreEqual(1, d.Test.WLocked);
|
||||
Assert.IsNotNull(d.Test.GenObj);
|
||||
Assert.AreEqual(2, d.Test.GenObj.Gen);
|
||||
Assert.AreEqual(3, d.Test.LiveGen);
|
||||
Assert.IsTrue(d.Test.NextGen);
|
||||
|
||||
// release writer
|
||||
scopeContext.ScopeExit(true);
|
||||
|
||||
Assert.AreEqual(0, d.Test.WLocked);
|
||||
Assert.IsNotNull(d.Test.GenObj);
|
||||
Assert.AreEqual(2, d.Test.GenObj.Gen);
|
||||
Assert.AreEqual(3, d.Test.LiveGen);
|
||||
Assert.IsTrue(d.Test.NextGen);
|
||||
|
||||
var s3 = d.CreateSnapshot();
|
||||
|
||||
Assert.AreEqual(0, d.Test.WLocked);
|
||||
Assert.IsNotNull(d.Test.GenObj);
|
||||
Assert.AreEqual(3, d.Test.GenObj.Gen);
|
||||
Assert.AreEqual(3, d.Test.LiveGen);
|
||||
Assert.IsFalse(d.Test.NextGen);
|
||||
}
|
||||
|
||||
private IScopeProvider GetScopeProvider(ScopeContext scopeContext = null)
|
||||
{
|
||||
var scopeProvider = Mock.Of<IScopeProvider>();
|
||||
Mock.Get(scopeProvider)
|
||||
.Setup(x => x.Context).Returns(scopeContext);
|
||||
return scopeProvider;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Linq;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Compose;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.IO;
|
||||
@@ -299,11 +300,19 @@ namespace Umbraco.Tests.Components
|
||||
composers = new Composers(composition, types, Mock.Of<IProfilingLogger>());
|
||||
Composed.Clear();
|
||||
Assert.Throws<Exception>(() => composers.Compose());
|
||||
Console.WriteLine("throws:");
|
||||
composers = new Composers(composition, types, Mock.Of<IProfilingLogger>());
|
||||
var requirements = composers.GetRequirements(false);
|
||||
Console.WriteLine(Composers.GetComposersReport(requirements));
|
||||
|
||||
types = new[] { typeof(Composer2) };
|
||||
composers = new Composers(composition, types, Mock.Of<IProfilingLogger>());
|
||||
Composed.Clear();
|
||||
Assert.Throws<Exception>(() => composers.Compose());
|
||||
Console.WriteLine("throws:");
|
||||
composers = new Composers(composition, types, Mock.Of<IProfilingLogger>());
|
||||
requirements = composers.GetRequirements(false);
|
||||
Console.WriteLine(Composers.GetComposersReport(requirements));
|
||||
|
||||
types = new[] { typeof(Composer12) };
|
||||
composers = new Composers(composition, types, Mock.Of<IProfilingLogger>());
|
||||
@@ -349,6 +358,25 @@ namespace Umbraco.Tests.Components
|
||||
Assert.AreEqual(typeof(Composer27), Composed[1]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AllComposers()
|
||||
{
|
||||
var typeLoader = new TypeLoader(AppCaches.Disabled.RuntimeCache, IOHelper.MapPath("~/App_Data/TEMP"), Mock.Of<IProfilingLogger>());
|
||||
|
||||
var register = MockRegister();
|
||||
var composition = new Composition(register, typeLoader, Mock.Of<IProfilingLogger>(), MockRuntimeState(RuntimeLevel.Run));
|
||||
|
||||
var types = typeLoader.GetTypes<IComposer>().Where(x => x.FullName.StartsWith("Umbraco.Core.") || x.FullName.StartsWith("Umbraco.Web"));
|
||||
var composers = new Composers(composition, types, Mock.Of<IProfilingLogger>());
|
||||
var requirements = composers.GetRequirements();
|
||||
var report = Composers.GetComposersReport(requirements);
|
||||
Console.WriteLine(report);
|
||||
var composerTypes = composers.SortComposers(requirements);
|
||||
|
||||
foreach (var type in composerTypes)
|
||||
Console.WriteLine(type);
|
||||
}
|
||||
|
||||
#region Compothings
|
||||
|
||||
public class TestComposerBase : IComposer
|
||||
|
||||
@@ -15,13 +15,47 @@ namespace Umbraco.Tests.Models
|
||||
[TestFixture]
|
||||
public class ContentTypeTests : UmbracoTestBase
|
||||
{
|
||||
[Test]
|
||||
[Ignore("Ignoring this test until we actually enforce this, see comments in ContentTypeBase.PropertyTypesChanged")]
|
||||
public void Cannot_Add_Duplicate_Property_Aliases()
|
||||
{
|
||||
var contentType = MockedContentTypes.CreateBasicContentType();
|
||||
|
||||
contentType.PropertyGroups.Add(new PropertyGroup(new PropertyTypeCollection(false, new[]
|
||||
{
|
||||
new PropertyType("testPropertyEditor", ValueStorageType.Nvarchar){ Alias = "myPropertyType" }
|
||||
})));
|
||||
|
||||
Assert.Throws<InvalidOperationException>(() =>
|
||||
contentType.PropertyTypeCollection.Add(
|
||||
new PropertyType("testPropertyEditor", ValueStorageType.Nvarchar) { Alias = "myPropertyType" }));
|
||||
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Ignore("Ignoring this test until we actually enforce this, see comments in ContentTypeBase.PropertyTypesChanged")]
|
||||
public void Cannot_Update_Duplicate_Property_Aliases()
|
||||
{
|
||||
var contentType = MockedContentTypes.CreateBasicContentType();
|
||||
|
||||
contentType.PropertyGroups.Add(new PropertyGroup(new PropertyTypeCollection(false, new[]
|
||||
{
|
||||
new PropertyType("testPropertyEditor", ValueStorageType.Nvarchar){ Alias = "myPropertyType" }
|
||||
})));
|
||||
|
||||
contentType.PropertyTypeCollection.Add(new PropertyType("testPropertyEditor", ValueStorageType.Nvarchar) { Alias = "myPropertyType2" });
|
||||
|
||||
var toUpdate = contentType.PropertyTypeCollection["myPropertyType2"];
|
||||
|
||||
Assert.Throws<InvalidOperationException>(() => toUpdate.Alias = "myPropertyType");
|
||||
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Deep_Clone_Content_Type_Sort()
|
||||
{
|
||||
var contentType = new ContentTypeSort(new Lazy<int>(() => 3), 4, "test");
|
||||
var clone = (ContentTypeSort) contentType.DeepClone();
|
||||
var clone = (ContentTypeSort)contentType.DeepClone();
|
||||
Assert.AreNotSame(clone, contentType);
|
||||
Assert.AreEqual(clone, contentType);
|
||||
Assert.AreEqual(clone.Id.Value, contentType.Id.Value);
|
||||
@@ -54,7 +88,7 @@ namespace Umbraco.Tests.Models
|
||||
contentType.Id = 10;
|
||||
contentType.CreateDate = DateTime.Now;
|
||||
contentType.CreatorId = 22;
|
||||
contentType.SetDefaultTemplate(new Template((string) "Test Template", (string) "testTemplate")
|
||||
contentType.SetDefaultTemplate(new Template((string)"Test Template", (string)"testTemplate")
|
||||
{
|
||||
Id = 88
|
||||
});
|
||||
@@ -117,12 +151,12 @@ namespace Umbraco.Tests.Models
|
||||
{
|
||||
group.Id = ++i;
|
||||
}
|
||||
contentType.AllowedTemplates = new[] { new Template((string) "Name", (string) "name") { Id = 200 }, new Template((string) "Name2", (string) "name2") { Id = 201 } };
|
||||
contentType.AllowedTemplates = new[] { new Template((string)"Name", (string)"name") { Id = 200 }, new Template((string)"Name2", (string)"name2") { Id = 201 } };
|
||||
contentType.AllowedContentTypes = new[] { new ContentTypeSort(new Lazy<int>(() => 888), 8, "sub"), new ContentTypeSort(new Lazy<int>(() => 889), 9, "sub2") };
|
||||
contentType.Id = 10;
|
||||
contentType.CreateDate = DateTime.Now;
|
||||
contentType.CreatorId = 22;
|
||||
contentType.SetDefaultTemplate(new Template((string) "Test Template", (string) "testTemplate")
|
||||
contentType.SetDefaultTemplate(new Template((string)"Test Template", (string)"testTemplate")
|
||||
{
|
||||
Id = 88
|
||||
});
|
||||
@@ -167,12 +201,12 @@ namespace Umbraco.Tests.Models
|
||||
{
|
||||
group.Id = ++i;
|
||||
}
|
||||
contentType.AllowedTemplates = new[] { new Template((string) "Name", (string) "name") { Id = 200 }, new Template((string) "Name2", (string) "name2") { Id = 201 } };
|
||||
contentType.AllowedContentTypes = new[] {new ContentTypeSort(new Lazy<int>(() => 888), 8, "sub"), new ContentTypeSort(new Lazy<int>(() => 889), 9, "sub2")};
|
||||
contentType.AllowedTemplates = new[] { new Template((string)"Name", (string)"name") { Id = 200 }, new Template((string)"Name2", (string)"name2") { Id = 201 } };
|
||||
contentType.AllowedContentTypes = new[] { new ContentTypeSort(new Lazy<int>(() => 888), 8, "sub"), new ContentTypeSort(new Lazy<int>(() => 889), 9, "sub2") };
|
||||
contentType.Id = 10;
|
||||
contentType.CreateDate = DateTime.Now;
|
||||
contentType.CreatorId = 22;
|
||||
contentType.SetDefaultTemplate(new Template((string) "Test Template", (string) "testTemplate")
|
||||
contentType.SetDefaultTemplate(new Template((string)"Test Template", (string)"testTemplate")
|
||||
{
|
||||
Id = 88
|
||||
});
|
||||
@@ -264,12 +298,12 @@ namespace Umbraco.Tests.Models
|
||||
{
|
||||
propertyType.Id = ++i;
|
||||
}
|
||||
contentType.AllowedTemplates = new[] { new Template((string) "Name", (string) "name") { Id = 200 }, new Template((string) "Name2", (string) "name2") { Id = 201 } };
|
||||
contentType.AllowedTemplates = new[] { new Template((string)"Name", (string)"name") { Id = 200 }, new Template((string)"Name2", (string)"name2") { Id = 201 } };
|
||||
contentType.AllowedContentTypes = new[] { new ContentTypeSort(new Lazy<int>(() => 888), 8, "sub"), new ContentTypeSort(new Lazy<int>(() => 889), 9, "sub2") };
|
||||
contentType.Id = 10;
|
||||
contentType.CreateDate = DateTime.Now;
|
||||
contentType.CreatorId = 22;
|
||||
contentType.SetDefaultTemplate(new Template((string) "Test Template", (string) "testTemplate")
|
||||
contentType.SetDefaultTemplate(new Template((string)"Test Template", (string)"testTemplate")
|
||||
{
|
||||
Id = 88
|
||||
});
|
||||
|
||||
@@ -232,6 +232,35 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This demonstates an issue found: https://github.com/umbraco/Umbraco-CMS/issues/4963#issuecomment-483516698
|
||||
/// </summary>
|
||||
[Test]
|
||||
[Ignore("Still testing")]
|
||||
public void Bug_Changing_Built_In_Member_Type_Property_Type_Aliases_Results_In_Exception()
|
||||
{
|
||||
//TODO: Fix this bug and then change this test
|
||||
|
||||
var provider = TestObjects.GetScopeProvider(Logger);
|
||||
using (var scope = provider.CreateScope())
|
||||
{
|
||||
var repository = CreateRepository(provider);
|
||||
|
||||
IMemberType memberType = MockedContentTypes.CreateSimpleMemberType();
|
||||
repository.Save(memberType);
|
||||
|
||||
foreach (var stub in Constants.Conventions.Member.GetStandardPropertyTypeStubs())
|
||||
{
|
||||
var prop = memberType.PropertyTypes.First(x => x.Alias == stub.Key);
|
||||
prop.Alias = prop.Alias + "__0000";
|
||||
}
|
||||
|
||||
repository.Save(memberType);
|
||||
|
||||
//Assert.Throws<ArgumentException>(() => );
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Built_In_Member_Type_Properties_Are_Automatically_Added_When_Creating()
|
||||
{
|
||||
|
||||
@@ -15,6 +15,7 @@ using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.Scoping;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Services.Changes;
|
||||
using Umbraco.Core.Strings;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
using Umbraco.Tests.Testing.Objects;
|
||||
using Umbraco.Tests.Testing.Objects.Accessors;
|
||||
@@ -180,8 +181,9 @@ namespace Umbraco.Tests.PublishedContent
|
||||
dataSource,
|
||||
globalSettings,
|
||||
new SiteDomainHelper(),
|
||||
contentTypeServiceBaseFactory,
|
||||
Mock.Of<IEntityXmlSerializer>());
|
||||
Mock.Of<IEntityXmlSerializer>(),
|
||||
Mock.Of<IPublishedModelFactory>(),
|
||||
new UrlSegmentProviderCollection(new[] { new DefaultUrlSegmentProvider() }));
|
||||
|
||||
// invariant is the current default
|
||||
_variationAccesor.VariationContext = new VariationContext();
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace Umbraco.Tests.Routing
|
||||
{
|
||||
base.SetUp();
|
||||
|
||||
WebRuntimeComponent.CreateRoutes(
|
||||
WebFinalComponent.CreateRoutes(
|
||||
new TestUmbracoContextAccessor(),
|
||||
TestObjects.GetGlobalSettings(),
|
||||
new SurfaceControllerTypeCollection(Enumerable.Empty<Type>()),
|
||||
|
||||
@@ -81,7 +81,7 @@ namespace Umbraco.Tests.Runtimes
|
||||
|
||||
var composerTypes = typeLoader.GetTypes<IComposer>() // all of them
|
||||
.Where(x => !x.FullName.StartsWith("Umbraco.Tests.")) // exclude test components
|
||||
.Where(x => x != typeof(WebRuntimeComposer)); // exclude web runtime
|
||||
.Where(x => x != typeof(WebInitialComposer)); // exclude web runtime
|
||||
var composers = new Composers(composition, composerTypes, profilingLogger);
|
||||
composers.Compose();
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace Umbraco.Tests.Runtimes
|
||||
new PluginViewEngine()
|
||||
};
|
||||
|
||||
WebRuntimeComponent.WrapViewEngines(engines);
|
||||
WebInitialComponent.WrapViewEngines(engines);
|
||||
|
||||
Assert.That(engines.Count, Is.EqualTo(2));
|
||||
Assert.That(engines[0], Is.InstanceOf<ProfilingViewEngine>());
|
||||
@@ -34,7 +34,7 @@ namespace Umbraco.Tests.Runtimes
|
||||
new PluginViewEngine()
|
||||
};
|
||||
|
||||
WebRuntimeComponent.WrapViewEngines(engines);
|
||||
WebInitialComponent.WrapViewEngines(engines);
|
||||
|
||||
Assert.That(engines.Count, Is.EqualTo(2));
|
||||
Assert.That(((ProfilingViewEngine)engines[0]).Inner, Is.InstanceOf<RenderViewEngine>());
|
||||
@@ -50,7 +50,7 @@ namespace Umbraco.Tests.Runtimes
|
||||
profiledEngine
|
||||
};
|
||||
|
||||
WebRuntimeComponent.WrapViewEngines(engines);
|
||||
WebInitialComponent.WrapViewEngines(engines);
|
||||
|
||||
Assert.That(engines[0], Is.SameAs(profiledEngine));
|
||||
}
|
||||
@@ -58,7 +58,7 @@ namespace Umbraco.Tests.Runtimes
|
||||
[Test]
|
||||
public void WrapViewEngines_CollectionIsNull_DoesNotThrow()
|
||||
{
|
||||
Assert.DoesNotThrow(() => WebRuntimeComponent.WrapViewEngines(null));
|
||||
Assert.DoesNotThrow(() => WebInitialComponent.WrapViewEngines(null));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ using Umbraco.Core.Persistence.Repositories;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Services.Implement;
|
||||
using Umbraco.Core.Strings;
|
||||
using Umbraco.Core.Sync;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
using Umbraco.Tests.Testing;
|
||||
@@ -97,8 +98,10 @@ namespace Umbraco.Tests.Scoping
|
||||
documentRepository, mediaRepository, memberRepository,
|
||||
DefaultCultureAccessor,
|
||||
new DatabaseDataSource(),
|
||||
Factory.GetInstance<IGlobalSettings>(), new SiteDomainHelper(), contentTypeServiceBaseFactory,
|
||||
Factory.GetInstance<IEntityXmlSerializer>());
|
||||
Factory.GetInstance<IGlobalSettings>(), new SiteDomainHelper(),
|
||||
Factory.GetInstance<IEntityXmlSerializer>(),
|
||||
Mock.Of<IPublishedModelFactory>(),
|
||||
new UrlSegmentProviderCollection(new[] { new DefaultUrlSegmentProvider() }));
|
||||
}
|
||||
|
||||
protected UmbracoContext GetUmbracoContextNu(string url, int templateId = 1234, RouteData routeData = null, bool setSingleton = false, IUmbracoSettingsSection umbracoSettings = null, IEnumerable<IUrlProvider> urlProviders = null)
|
||||
|
||||
@@ -15,6 +15,7 @@ using Umbraco.Core.Persistence.Dtos;
|
||||
using Umbraco.Core.Persistence.Repositories;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Strings;
|
||||
using Umbraco.Core.Sync;
|
||||
using Umbraco.Tests.Testing;
|
||||
using Umbraco.Web;
|
||||
@@ -70,8 +71,10 @@ namespace Umbraco.Tests.Services
|
||||
documentRepository, mediaRepository, memberRepository,
|
||||
DefaultCultureAccessor,
|
||||
new DatabaseDataSource(),
|
||||
Factory.GetInstance<IGlobalSettings>(), new SiteDomainHelper(), contentTypeServiceBaseFactory,
|
||||
Factory.GetInstance<IEntityXmlSerializer>());
|
||||
Factory.GetInstance<IGlobalSettings>(), new SiteDomainHelper(),
|
||||
Factory.GetInstance<IEntityXmlSerializer>(),
|
||||
Mock.Of<IPublishedModelFactory>(),
|
||||
new UrlSegmentProviderCollection(new[] { new DefaultUrlSegmentProvider() }));
|
||||
}
|
||||
|
||||
public class LocalServerMessenger : ServerMessengerBase
|
||||
|
||||
@@ -116,7 +116,7 @@ namespace Umbraco.Tests.TestHelpers
|
||||
|
||||
var umbracoSettings = GetUmbracoSettings();
|
||||
var globalSettings = GetGlobalSettings();
|
||||
var urlProviders = Enumerable.Empty<IUrlProvider>();
|
||||
var urlProviders = new UrlProviderCollection(Enumerable.Empty<IUrlProvider>());
|
||||
|
||||
if (accessor == null) accessor = new TestUmbracoContextAccessor();
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ namespace Umbraco.Tests.Web.Mvc
|
||||
new TestDefaultCultureAccessor(),
|
||||
TestObjects.GetUmbracoSettings(),
|
||||
globalSettings,
|
||||
Enumerable.Empty<IUrlProvider>(),
|
||||
new UrlProviderCollection(Enumerable.Empty<IUrlProvider>()),
|
||||
Mock.Of<IUserService>());
|
||||
|
||||
var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(Mock.Of<HttpContextBase>());
|
||||
@@ -100,7 +100,7 @@ namespace Umbraco.Tests.Web.Mvc
|
||||
new TestDefaultCultureAccessor(),
|
||||
TestObjects.GetUmbracoSettings(),
|
||||
globalSettings,
|
||||
Enumerable.Empty<IUrlProvider>(),
|
||||
new UrlProviderCollection(Enumerable.Empty<IUrlProvider>()),
|
||||
Mock.Of<IUserService>());
|
||||
|
||||
var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(Mock.Of<HttpContextBase>());
|
||||
@@ -129,7 +129,7 @@ namespace Umbraco.Tests.Web.Mvc
|
||||
new TestDefaultCultureAccessor(),
|
||||
TestObjects.GetUmbracoSettings(),
|
||||
globalSettings,
|
||||
Enumerable.Empty<IUrlProvider>(),
|
||||
new UrlProviderCollection(Enumerable.Empty<IUrlProvider>()),
|
||||
Mock.Of<IUserService>());
|
||||
|
||||
var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(Mock.Of<HttpContextBase>());
|
||||
@@ -158,7 +158,7 @@ namespace Umbraco.Tests.Web.Mvc
|
||||
new TestDefaultCultureAccessor(),
|
||||
TestObjects.GetUmbracoSettings(),
|
||||
globalSettings,
|
||||
Enumerable.Empty<IUrlProvider>(),
|
||||
new UrlProviderCollection(Enumerable.Empty<IUrlProvider>()),
|
||||
Mock.Of<IUserService>());
|
||||
|
||||
var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(Mock.Of<HttpContextBase>());
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace Umbraco.Tests.Web.Mvc
|
||||
new TestDefaultCultureAccessor(),
|
||||
TestObjects.GetUmbracoSettings(),
|
||||
globalSettings,
|
||||
Enumerable.Empty<IUrlProvider>(),
|
||||
new UrlProviderCollection(Enumerable.Empty<IUrlProvider>()),
|
||||
Mock.Of<IUserService>());
|
||||
|
||||
var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(Mock.Of<HttpContextBase>());
|
||||
@@ -73,7 +73,7 @@ namespace Umbraco.Tests.Web.Mvc
|
||||
new TestDefaultCultureAccessor(),
|
||||
TestObjects.GetUmbracoSettings(),
|
||||
globalSettings,
|
||||
Enumerable.Empty<IUrlProvider>(),
|
||||
new UrlProviderCollection(Enumerable.Empty<IUrlProvider>()),
|
||||
Mock.Of<IUserService>());
|
||||
|
||||
var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(Mock.Of<HttpContextBase>());
|
||||
@@ -103,7 +103,7 @@ namespace Umbraco.Tests.Web.Mvc
|
||||
new TestDefaultCultureAccessor(),
|
||||
Mock.Of<IUmbracoSettingsSection>(section => section.WebRouting == Mock.Of<IWebRoutingSection>(routingSection => routingSection.UrlProviderMode == "Auto")),
|
||||
globalSettings,
|
||||
Enumerable.Empty<IUrlProvider>(),
|
||||
new UrlProviderCollection(Enumerable.Empty<IUrlProvider>()),
|
||||
Mock.Of<IUserService>());
|
||||
|
||||
var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(Mock.Of<HttpContextBase>());
|
||||
@@ -140,7 +140,7 @@ namespace Umbraco.Tests.Web.Mvc
|
||||
new TestDefaultCultureAccessor(),
|
||||
Mock.Of<IUmbracoSettingsSection>(section => section.WebRouting == webRoutingSettings),
|
||||
globalSettings,
|
||||
Enumerable.Empty<IUrlProvider>(),
|
||||
new UrlProviderCollection(Enumerable.Empty<IUrlProvider>()),
|
||||
Mock.Of<IUserService>());
|
||||
|
||||
var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(Mock.Of<HttpContextBase>());
|
||||
|
||||
@@ -104,7 +104,7 @@ namespace Umbraco.Tests.Web
|
||||
new TestDefaultCultureAccessor(),
|
||||
Mock.Of<IUmbracoSettingsSection>(section => section.WebRouting == Mock.Of<IWebRoutingSection>(routingSection => routingSection.UrlProviderMode == "Auto")),
|
||||
globalSettings,
|
||||
new[] { testUrlProvider.Object },
|
||||
new UrlProviderCollection(new[] { testUrlProvider.Object }),
|
||||
Mock.Of<IUserService>());
|
||||
|
||||
using (var reference = umbracoContextFactory.EnsureUmbracoContext(Mock.Of<HttpContextBase>()))
|
||||
|
||||
+1
-1
@@ -344,8 +344,8 @@
|
||||
loadAuditTrail(true);
|
||||
loadRedirectUrls();
|
||||
setNodePublishStatus();
|
||||
updateCurrentUrls();
|
||||
}
|
||||
updateCurrentUrls();
|
||||
});
|
||||
|
||||
//ensure to unregister from all events!
|
||||
|
||||
+4
-2
@@ -15,10 +15,12 @@ function umbFileUpload() {
|
||||
el.on('change', function (event) {
|
||||
var files = event.target.files;
|
||||
//emit event upward
|
||||
scope.$emit("filesSelected", { files: files });
|
||||
scope.$emit("filesSelected", { files: files });
|
||||
//clear the element value - this allows us to pick the same file again and again
|
||||
el.val('');
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
angular.module('umbraco.directives').directive("umbFileUpload", umbFileUpload);
|
||||
angular.module('umbraco.directives').directive("umbFileUpload", umbFileUpload);
|
||||
|
||||
+7
-4
@@ -62,8 +62,8 @@ function valPropertyMsg(serverValidationManager) {
|
||||
if (!watcher) {
|
||||
watcher = scope.$watch("currentProperty.value",
|
||||
function (newValue, oldValue) {
|
||||
|
||||
if (!newValue || angular.equals(newValue, oldValue)) {
|
||||
|
||||
if (angular.equals(newValue, oldValue)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -78,10 +78,12 @@ function valPropertyMsg(serverValidationManager) {
|
||||
// based on other errors. We'll also check if there's no other validation errors apart from valPropertyMsg, if valPropertyMsg
|
||||
// is the only one, then we'll clear.
|
||||
|
||||
if ((errCount === 1 && angular.isArray(formCtrl.$error.valPropertyMsg)) || (formCtrl.$invalid && angular.isArray(formCtrl.$error.valServer))) {
|
||||
if (errCount === 0 || (errCount === 1 && angular.isArray(formCtrl.$error.valPropertyMsg)) || (formCtrl.$invalid && angular.isArray(formCtrl.$error.valServer))) {
|
||||
scope.errorMsg = "";
|
||||
formCtrl.$setValidity('valPropertyMsg', true);
|
||||
stopWatch();
|
||||
} else if (showValidation && scope.errorMsg === "") {
|
||||
formCtrl.$setValidity('valPropertyMsg', false);
|
||||
scope.errorMsg = getErrorMsg();
|
||||
}
|
||||
}, true);
|
||||
}
|
||||
@@ -152,6 +154,7 @@ function valPropertyMsg(serverValidationManager) {
|
||||
showValidation = true;
|
||||
if (hasError && scope.errorMsg === "") {
|
||||
scope.errorMsg = getErrorMsg();
|
||||
startWatch();
|
||||
}
|
||||
else if (!hasError) {
|
||||
scope.errorMsg = "";
|
||||
|
||||
@@ -112,6 +112,7 @@ When building a custom infinite editor view you can use the same components as a
|
||||
type="button"
|
||||
button-style="link"
|
||||
label-key="general_close"
|
||||
shortcut="esc"
|
||||
action="vm.close()">
|
||||
</umb-button>
|
||||
<umb-button
|
||||
|
||||
@@ -166,7 +166,9 @@ body.touch .umb-tree {
|
||||
}
|
||||
|
||||
.umb-tree .umb-tree-node-checked > .umb-tree-item__inner > i[class^="icon-"],
|
||||
.umb-tree .umb-tree-node-checked > .umb-tree-item__inner > i[class*=" icon-"] {
|
||||
.umb-tree .umb-tree-node-checked > .umb-tree-item__inner > i[class*=" icon-"],
|
||||
.umb-tree .umb-tree-node-checked .umb-search-group-item-name > i[class^="icon-"],
|
||||
.umb-tree .umb-tree-node-checked .umb-search-group-item-name > i[class*=" icon-"] {
|
||||
font-family: 'icomoon' !important;
|
||||
color: @green !important;
|
||||
|
||||
|
||||
@@ -151,14 +151,14 @@ input.umb-table__input {
|
||||
|
||||
// Show checkmark when checked, hide file icon
|
||||
.umb-table-row--selected {
|
||||
/*
|
||||
|
||||
.umb-table-body__fileicon {
|
||||
display: none;
|
||||
}
|
||||
.umb-table-body__checkicon {
|
||||
display: inline-block;
|
||||
}
|
||||
*/
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
|
||||
@@ -55,6 +55,16 @@
|
||||
position: absolute;;
|
||||
}
|
||||
|
||||
.--notInFront .umb-modalcolumn::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
background: rgba(0,0,0,.4);
|
||||
}
|
||||
|
||||
/* re-align loader */
|
||||
.umb-modal .umb-loader-wrapper, .umb-modalcolumn .umb-loader-wrapper, .umb-dialog .umb-loader-wrapper{
|
||||
position:relative;
|
||||
|
||||
@@ -113,7 +113,12 @@ var app = angular.module("umbraco.preview", ['umbraco.resources', 'umbraco.servi
|
||||
$scope.exitPreview = function () {
|
||||
|
||||
var culture = $location.search().culture || getParameterByName("culture");
|
||||
var relativeUrl = "/" + $scope.pageId +'?culture='+ culture;
|
||||
var relativeUrl = "/" + $scope.pageId;
|
||||
|
||||
if(culture){
|
||||
relativeUrl +='?culture='+ culture;
|
||||
}
|
||||
|
||||
window.top.location.href = "../preview/end?redir=" + encodeURIComponent(relativeUrl);
|
||||
};
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
// method to select a search result
|
||||
function selectResult(evt, result) {
|
||||
result.selected = result.selected === true ? false : true;
|
||||
nodeSelectHandler(evt, { event: evt, node: result });
|
||||
nodeSelectHandler({ event: evt, node: result });
|
||||
}
|
||||
|
||||
//callback when there are search results
|
||||
@@ -96,7 +96,7 @@
|
||||
// Mini list view
|
||||
$scope.selectListViewNode = function (node) {
|
||||
node.selected = node.selected === true ? false : true;
|
||||
nodeSelectHandler({}, { node: node });
|
||||
nodeSelectHandler({ node: node });
|
||||
};
|
||||
|
||||
$scope.closeMiniListView = function () {
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
// method to select a search result
|
||||
function selectResult(evt, result) {
|
||||
result.selected = result.selected === true ? false : true;
|
||||
nodeSelectHandler(evt, { event: evt, node: result });
|
||||
nodeSelectHandler({ event: evt, node: result });
|
||||
}
|
||||
|
||||
//callback when there are search results
|
||||
@@ -96,7 +96,7 @@
|
||||
// Mini list view
|
||||
$scope.selectListViewNode = function (node) {
|
||||
node.selected = node.selected === true ? false : true;
|
||||
nodeSelectHandler({}, { node: node });
|
||||
nodeSelectHandler({ node: node });
|
||||
};
|
||||
|
||||
$scope.closeMiniListView = function () {
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@
|
||||
ng-class="{'is-active': vm.item.active, '-has-error': vm.item.hasError}">
|
||||
<i class="icon {{ vm.item.icon }}"></i>
|
||||
<span class="umb-sub-views-nav-item-text">{{ vm.item.name }}</span>
|
||||
<div ng-show="item.badge" class="badge -type-{{vm.item.badge.type}}">{{vm.item.badge.count}}</div>
|
||||
<div ng-show="vm.item.badge" class="badge -type-{{vm.item.badge.type}}">{{vm.item.badge.count}}</div>
|
||||
</a>
|
||||
|
||||
<ul class="dropdown-menu umb-sub-views-nav-item__anchor_dropdown" ng-if="vm.item.anchors && vm.item.anchors.length > 1">
|
||||
|
||||
@@ -46,8 +46,7 @@
|
||||
|
||||
if (data.language !== "undefined") {
|
||||
var lang = vm.languages.filter(function (l) {
|
||||
return matchLanguageById(l, data.language.Id);
|
||||
|
||||
return matchLanguageById(l, data.language);
|
||||
});
|
||||
if (lang.length > 0) {
|
||||
vm.language = lang[0];
|
||||
|
||||
@@ -93,7 +93,7 @@ angular.module("umbraco").controller("Umbraco.Editors.Content.CopyController",
|
||||
// method to select a search result
|
||||
$scope.selectResult = function (evt, result) {
|
||||
result.selected = result.selected === true ? false : true;
|
||||
nodeSelectHandler(evt, { event: evt, node: result });
|
||||
nodeSelectHandler({ event: evt, node: result });
|
||||
};
|
||||
|
||||
//callback when there are search results
|
||||
|
||||
@@ -66,7 +66,7 @@ angular.module("umbraco").controller("Umbraco.Editors.Content.MoveController",
|
||||
// method to select a search result
|
||||
$scope.selectResult = function (evt, result) {
|
||||
result.selected = result.selected === true ? false : true;
|
||||
nodeSelectHandler(evt, { event: evt, node: result });
|
||||
nodeSelectHandler({ event: evt, node: result });
|
||||
};
|
||||
|
||||
//callback when there are search results
|
||||
@@ -124,7 +124,7 @@ angular.module("umbraco").controller("Umbraco.Editors.Content.MoveController",
|
||||
// Mini list view
|
||||
$scope.selectListViewNode = function (node) {
|
||||
node.selected = node.selected === true ? false : true;
|
||||
nodeSelectHandler({}, { node: node });
|
||||
nodeSelectHandler({ node: node });
|
||||
};
|
||||
|
||||
$scope.closeMiniListView = function () {
|
||||
|
||||
@@ -57,7 +57,7 @@ angular.module("umbraco").controller("Umbraco.Editors.Content.RestoreController"
|
||||
// method to select a search result
|
||||
$scope.selectResult = function (evt, result) {
|
||||
result.selected = result.selected === true ? false : true;
|
||||
nodeSelectHandler(evt, { event: evt, node: result });
|
||||
nodeSelectHandler({ event: evt, node: result });
|
||||
};
|
||||
|
||||
//callback when there are search results
|
||||
@@ -74,7 +74,7 @@ angular.module("umbraco").controller("Umbraco.Editors.Content.RestoreController"
|
||||
// Mini list view
|
||||
$scope.selectListViewNode = function (node) {
|
||||
node.selected = node.selected === true ? false : true;
|
||||
nodeSelectHandler({}, { node: node });
|
||||
nodeSelectHandler({ node: node });
|
||||
};
|
||||
|
||||
$scope.closeMiniListView = function () {
|
||||
|
||||
@@ -57,7 +57,7 @@ angular.module("umbraco").controller("Umbraco.Editors.Media.RestoreController",
|
||||
// method to select a search result
|
||||
$scope.selectResult = function (evt, result) {
|
||||
result.selected = result.selected === true ? false : true;
|
||||
nodeSelectHandler(evt, { event: evt, node: result });
|
||||
nodeSelectHandler({ event: evt, node: result });
|
||||
};
|
||||
|
||||
//callback when there are search results
|
||||
@@ -74,7 +74,7 @@ angular.module("umbraco").controller("Umbraco.Editors.Media.RestoreController",
|
||||
// Mini list view
|
||||
$scope.selectListViewNode = function (node) {
|
||||
node.selected = node.selected === true ? false : true;
|
||||
nodeSelectHandler({}, { node: node });
|
||||
nodeSelectHandler({ node: node });
|
||||
};
|
||||
|
||||
$scope.closeMiniListView = function () {
|
||||
|
||||
@@ -250,7 +250,7 @@
|
||||
<umb-box>
|
||||
<umb-box-content>
|
||||
<div class="umb-package-details__section-title"><localize key="packager_packageCompatibility">Compatibility</localize></div>
|
||||
<div class="umb-package-details__section-description"><localize key="packager_packageCompatibilityDescription">This package is compatible with the following versions of Umbraco, as reported by community members. Full compatability cannot be gauranteed for versions reported below 100%</localize></div>
|
||||
<div class="umb-package-details__section-description"><localize key="packager_packageCompatibilityDescription">This package is compatible with the following versions of Umbraco, as reported by community members. Full compatability cannot be guaranteed for versions reported below 100%</localize></div>
|
||||
<div class="umb-package-details__compatability" ng-repeat="compatibility in vm.package.compatibility | filter:percentage > 0">
|
||||
<div class="umb-package-details__compatability-label">
|
||||
<span class="umb-package-details__information-item-label">{{compatibility.version}}</span>
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
function imageFilePickerController($scope) {
|
||||
function imageFilePickerController($scope, editorService) {
|
||||
|
||||
$scope.add = function() {
|
||||
$scope.mediaPickerOverlay = {
|
||||
var mediaPickerOptions = {
|
||||
view: "mediapicker",
|
||||
multiPicker: false,
|
||||
disableFolderSelect: true,
|
||||
onlyImages: true,
|
||||
show: true,
|
||||
submit: function (model) {
|
||||
$scope.model.value = model.selection[0].image;
|
||||
$scope.mediaPickerOverlay.show = false;
|
||||
$scope.mediaPickerOverlay = null;
|
||||
|
||||
editorService.close();
|
||||
},
|
||||
close: function () {
|
||||
$scope.mediaPickerOverlay.show = false;
|
||||
$scope.mediaPickerOverlay = null;
|
||||
}
|
||||
editorService.close();
|
||||
}
|
||||
};
|
||||
editorService.mediaPicker(mediaPickerOptions);
|
||||
};
|
||||
|
||||
$scope.remove = function () {
|
||||
|
||||
@@ -19,11 +19,4 @@
|
||||
<i class="icon icon-add large"></i>
|
||||
</a>
|
||||
|
||||
<umb-overlay
|
||||
ng-if="mediaPickerOverlay.show"
|
||||
model="mediaPickerOverlay"
|
||||
view="mediaPickerOverlay.view"
|
||||
position="right">
|
||||
</umb-overlay>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
function ConfigController($scope) {
|
||||
|
||||
var vm = this;
|
||||
|
||||
vm.submit = submit;
|
||||
vm.close = close;
|
||||
|
||||
function submit() {
|
||||
if ($scope.model && $scope.model.submit) {
|
||||
$scope.model.submit($scope.model);
|
||||
}
|
||||
}
|
||||
|
||||
function close() {
|
||||
if ($scope.model.close) {
|
||||
$scope.model.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
angular.module("umbraco").controller("Umbraco.PropertyEditors.GridPrevalueEditor.ConfigController", ConfigController);
|
||||
@@ -1,16 +1,61 @@
|
||||
<div ng-if="model.config">
|
||||
<umb-property
|
||||
property="configValue"
|
||||
ng-repeat="configValue in model.config">
|
||||
<umb-property-editor model="configValue" is-pre-value="true"></umb-property-editor>
|
||||
</umb-property>
|
||||
</div>
|
||||
<div ng-controller="Umbraco.PropertyEditors.GridPrevalueEditor.ConfigController as vm">
|
||||
|
||||
<umb-editor-view>
|
||||
|
||||
<umb-editor-header
|
||||
name="model.title"
|
||||
name-locked="true"
|
||||
hide-alias="true"
|
||||
hide-icon="true"
|
||||
hide-description="true">
|
||||
</umb-editor-header>
|
||||
|
||||
<umb-editor-container>
|
||||
<ng-form name="gridItemConfigEditor" val-form-manager>
|
||||
|
||||
<umb-box ng-if="model.config">
|
||||
<umb-box-header title-key="grid_settings" />
|
||||
<umb-box-content>
|
||||
<div>
|
||||
<umb-property property="configValue"
|
||||
ng-repeat="configValue in model.config">
|
||||
<umb-property-editor model="configValue" is-pre-value="true"></umb-property-editor>
|
||||
</umb-property>
|
||||
</div>
|
||||
</umb-box-content>
|
||||
</umb-box>
|
||||
|
||||
<umb-box ng-if="model.styles">
|
||||
<umb-box-header title-key="grid_styles" />
|
||||
<umb-box-content>
|
||||
<div>
|
||||
<umb-property property="styleValue"
|
||||
ng-repeat="styleValue in model.styles">
|
||||
<umb-property-editor model="styleValue" is-pre-value="true"></umb-property-editor>
|
||||
</umb-property>
|
||||
</div>
|
||||
</umb-box-content>
|
||||
</umb-box>
|
||||
|
||||
</ng-form>
|
||||
</umb-editor-container>
|
||||
|
||||
<umb-editor-footer>
|
||||
<umb-editor-footer-content-right>
|
||||
<umb-button type="button"
|
||||
button-style="link"
|
||||
label-key="general_close"
|
||||
shortcut="esc"
|
||||
action="vm.close()">
|
||||
</umb-button>
|
||||
<umb-button type="button"
|
||||
button-style="success"
|
||||
label-key="general_submit"
|
||||
action="vm.submit()">
|
||||
</umb-button>
|
||||
</umb-editor-footer-content-right>
|
||||
</umb-editor-footer>
|
||||
|
||||
</umb-editor-view>
|
||||
|
||||
<div ng-if="model.styles">
|
||||
<h4>Style</h4>
|
||||
<umb-property
|
||||
property="styleValue"
|
||||
ng-repeat="styleValue in model.styles">
|
||||
<umb-property-editor model="styleValue" is-pre-value="true"></umb-property-editor>
|
||||
</umb-property>
|
||||
</div>
|
||||
|
||||
+14
-8
@@ -1,16 +1,22 @@
|
||||
function EditConfigController($scope) {
|
||||
|
||||
$scope.close = function() {
|
||||
if($scope.model.close) {
|
||||
$scope.model.close();
|
||||
}
|
||||
}
|
||||
|
||||
$scope.submit = function() {
|
||||
if($scope.model && $scope.model.submit) {
|
||||
var vm = this;
|
||||
|
||||
vm.submit = submit;
|
||||
vm.close = close;
|
||||
|
||||
function submit() {
|
||||
if ($scope.model && $scope.model.submit) {
|
||||
$scope.model.submit($scope.model);
|
||||
}
|
||||
}
|
||||
|
||||
function close() {
|
||||
if ($scope.model.close) {
|
||||
$scope.model.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
angular.module("umbraco").controller("Umbraco.PropertyEditors.GridPrevalueEditor.EditConfigController", EditConfigController);
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
<div class="usky-grid usky-grid-configuration" ng-controller="Umbraco.PropertyEditors.GridPrevalueEditor.EditConfigController">
|
||||
<div class="usky-grid usky-grid-configuration" ng-controller="Umbraco.PropertyEditors.GridPrevalueEditor.EditConfigController as vm">
|
||||
|
||||
<umb-editor-view>
|
||||
|
||||
|
||||
<umb-editor-view>
|
||||
|
||||
<form novalidate name="EditConfigForm" val-form-manager>
|
||||
<form novalidate name="EditConfigForm" val-form-manager>
|
||||
|
||||
<umb-editor-header
|
||||
name="model.title"
|
||||
@@ -18,44 +16,39 @@
|
||||
<umb-box>
|
||||
<umb-box-content>
|
||||
|
||||
<ng-form name="gridConfigEditor">
|
||||
|
||||
<h4>{{model.name}}</h4>
|
||||
<p>Settings will only save if the entered json configuration is valid</p>
|
||||
<textarea name="configSource"
|
||||
validate-on="'blur'"
|
||||
rows="20" class="umb-property-editor umb-textarea"
|
||||
umb-raw-model="model.config"></textarea>
|
||||
|
||||
<form name="gridConfigEditor">
|
||||
<div class="alert alert-error" ng-show="gridConfigEditor.$invalid === true">
|
||||
This configuration is not valid json, and will not be saved.
|
||||
</div>
|
||||
|
||||
<h4>{{model.name}}</h4>
|
||||
<p>Settings will only save if the entered json configuration is valid</p>
|
||||
<textarea name="configSource"
|
||||
validate-on="'blur'"
|
||||
rows="20" class="umb-property-editor umb-textarea"
|
||||
umb-raw-model="model.config"></textarea>
|
||||
</ng-form>
|
||||
|
||||
<div class="alert alert-error" ng-show="gridConfigEditor.$invalid === true">
|
||||
This configuration is not valid json, and will not be saved.
|
||||
</div>
|
||||
</umb-box-content>
|
||||
</umb-box>
|
||||
</umb-editor-container>
|
||||
|
||||
</form>
|
||||
|
||||
|
||||
|
||||
|
||||
</umb-box-content>
|
||||
</umb-box>
|
||||
</umb-editor-container>
|
||||
|
||||
<umb-editor-footer>
|
||||
<umb-editor-footer-content-right>
|
||||
<umb-editor-footer>
|
||||
<umb-editor-footer-content-right>
|
||||
<umb-button
|
||||
type="button"
|
||||
button-style="link"
|
||||
label-key="general_close"
|
||||
shortcut="esc"
|
||||
action="close()">
|
||||
action="vm.close()">
|
||||
</umb-button>
|
||||
<umb-button
|
||||
type="button"
|
||||
button-style="success"
|
||||
label-key="general_submit"
|
||||
action="submit()">
|
||||
action="vm.submit()">
|
||||
</umb-button>
|
||||
</umb-editor-footer-content-right>
|
||||
</umb-editor-footer>
|
||||
|
||||
@@ -8,17 +8,20 @@ angular.module("umbraco")
|
||||
umbRequestHelper,
|
||||
angularHelper,
|
||||
$element,
|
||||
eventsService
|
||||
eventsService,
|
||||
editorService
|
||||
) {
|
||||
|
||||
// Grid status variables
|
||||
var placeHolder = "";
|
||||
var currentForm = angularHelper.getCurrentForm($scope);
|
||||
|
||||
|
||||
$scope.currentRow = null;
|
||||
$scope.currentCell = null;
|
||||
$scope.currentToolsControl = null;
|
||||
$scope.currentControl = null;
|
||||
|
||||
$scope.openRTEToolbarId = null;
|
||||
$scope.hasSettings = false;
|
||||
$scope.showRowConfigurations = true;
|
||||
@@ -122,24 +125,25 @@ angular.module("umbraco")
|
||||
},
|
||||
|
||||
over: function (event, ui) {
|
||||
var area = $(event.target).scope().area;
|
||||
|
||||
var area = event.target.getScope_HackForSortable().area;
|
||||
var allowedEditors = area.allowed;
|
||||
|
||||
if (($.inArray(ui.item.scope().control.editor.alias, allowedEditors) < 0 && allowedEditors) ||
|
||||
|
||||
if (($.inArray(ui.item[0].getScope_HackForSortable().control.editor.alias, allowedEditors) < 0 && allowedEditors) ||
|
||||
(startingArea != area && area.maxItems != '' && area.maxItems > 0 && area.maxItems < area.controls.length + 1)) {
|
||||
|
||||
$scope.$apply(function () {
|
||||
$(event.target).scope().area.dropNotAllowed = true;
|
||||
event.target.getScope_HackForSortable().area.dropNotAllowed = true;
|
||||
});
|
||||
|
||||
ui.placeholder.hide();
|
||||
cancelMove = true;
|
||||
}
|
||||
else {
|
||||
if ($(event.target).scope().area.controls.length == 0){
|
||||
if (event.target.getScope_HackForSortable().area.controls.length == 0){
|
||||
|
||||
$scope.$apply(function () {
|
||||
$(event.target).scope().area.dropOnEmpty = true;
|
||||
event.target.getScope_HackForSortable().area.dropOnEmpty = true;
|
||||
});
|
||||
ui.placeholder.hide();
|
||||
} else {
|
||||
@@ -151,8 +155,9 @@ angular.module("umbraco")
|
||||
|
||||
out: function(event, ui) {
|
||||
$scope.$apply(function () {
|
||||
$(event.target).scope().area.dropNotAllowed = false;
|
||||
$(event.target).scope().area.dropOnEmpty = false;
|
||||
var dropArea = event.target.getScope_HackForSortable().area;
|
||||
dropArea.dropNotAllowed = false;
|
||||
dropArea.dropOnEmpty = false;
|
||||
});
|
||||
},
|
||||
|
||||
@@ -178,10 +183,9 @@ angular.module("umbraco")
|
||||
currentForm.$setDirty();
|
||||
},
|
||||
|
||||
start: function (e, ui) {
|
||||
|
||||
start: function (event, ui) {
|
||||
//Get the starting area for reference
|
||||
var area = $(e.target).scope().area;
|
||||
var area = event.target.getScope_HackForSortable().area;
|
||||
startingArea = area;
|
||||
|
||||
// fade out control when sorting
|
||||
@@ -207,7 +211,7 @@ angular.module("umbraco")
|
||||
});
|
||||
},
|
||||
|
||||
stop: function (e, ui) {
|
||||
stop: function (event, ui) {
|
||||
|
||||
// Fade in control when sorting stops
|
||||
ui.item[0].style.opacity = "1";
|
||||
@@ -236,9 +240,11 @@ angular.module("umbraco")
|
||||
|
||||
$scope.$apply(function () {
|
||||
|
||||
var cell = $(e.target).scope().area;
|
||||
var cell = event.target.getScope_HackForSortable().area;
|
||||
|
||||
cell.hasActiveChild = hasActiveChild(cell, cell.controls);
|
||||
cell.active = false;
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@@ -272,7 +278,7 @@ angular.module("umbraco")
|
||||
localizationService.localize("grid_insertControl").then(function(value){
|
||||
title = value;
|
||||
$scope.editorOverlay = {
|
||||
view: "itempicker",
|
||||
view: "itempicker",
|
||||
filter: area.$allowedEditors.length > 15,
|
||||
title: title,
|
||||
availableItems: area.$allowedEditors,
|
||||
@@ -313,6 +319,7 @@ angular.module("umbraco")
|
||||
|
||||
$scope.clickOutsideRow = function(index, rows) {
|
||||
rows[index].active = false;
|
||||
|
||||
};
|
||||
|
||||
function getAllowedLayouts(section) {
|
||||
@@ -430,44 +437,46 @@ angular.module("umbraco")
|
||||
});
|
||||
}
|
||||
|
||||
$scope.gridItemSettingsDialog = {};
|
||||
$scope.gridItemSettingsDialog.view = "views/propertyeditors/grid/dialogs/config.html";
|
||||
$scope.gridItemSettingsDialog.title = "Settings";
|
||||
$scope.gridItemSettingsDialog.styles = styles;
|
||||
$scope.gridItemSettingsDialog.config = config;
|
||||
var dialogOptions = {
|
||||
view: "views/propertyeditors/grid/dialogs/config.html",
|
||||
size: "small",
|
||||
styles: styles,
|
||||
config: config,
|
||||
submit: function (model) {
|
||||
var styleObject = {};
|
||||
var configObject = {};
|
||||
|
||||
$scope.gridItemSettingsDialog.show = true;
|
||||
_.each(model.styles, function (style) {
|
||||
if (style.value) {
|
||||
styleObject[style.key] = addModifier(style.value, style.modifier);
|
||||
}
|
||||
});
|
||||
_.each(model.config, function (cfg) {
|
||||
cfg.alias = cfg.key;
|
||||
cfg.label = cfg.value;
|
||||
|
||||
$scope.gridItemSettingsDialog.submit = function(model) {
|
||||
if (cfg.value) {
|
||||
configObject[cfg.key] = addModifier(cfg.value, cfg.modifier);
|
||||
}
|
||||
});
|
||||
|
||||
var styleObject = {};
|
||||
var configObject = {};
|
||||
gridItem.styles = styleObject;
|
||||
gridItem.config = configObject;
|
||||
gridItem.hasConfig = gridItemHasConfig(styleObject, configObject);
|
||||
|
||||
_.each(model.styles, function(style){
|
||||
if(style.value){
|
||||
styleObject[style.key] = addModifier(style.value, style.modifier);
|
||||
currentForm.$setDirty();
|
||||
|
||||
editorService.close();
|
||||
},
|
||||
close: function () {
|
||||
editorService.close();
|
||||
}
|
||||
});
|
||||
_.each(model.config, function (cfg) {
|
||||
if (cfg.value) {
|
||||
configObject[cfg.key] = addModifier(cfg.value, cfg.modifier);
|
||||
}
|
||||
});
|
||||
|
||||
gridItem.styles = styleObject;
|
||||
gridItem.config = configObject;
|
||||
gridItem.hasConfig = gridItemHasConfig(styleObject, configObject);
|
||||
|
||||
currentForm.$setDirty();
|
||||
|
||||
$scope.gridItemSettingsDialog.show = false;
|
||||
$scope.gridItemSettingsDialog = null;
|
||||
};
|
||||
|
||||
$scope.gridItemSettingsDialog.close = function(oldModel) {
|
||||
$scope.gridItemSettingsDialog.show = false;
|
||||
$scope.gridItemSettingsDialog = null;
|
||||
};
|
||||
localizationService.localize("general_settings").then(value => {
|
||||
dialogOptions.title = value;
|
||||
editorService.open(dialogOptions);
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
@@ -537,6 +546,7 @@ angular.module("umbraco")
|
||||
// Control management functions
|
||||
// *********************************************
|
||||
$scope.clickControl = function (index, controls, cell) {
|
||||
|
||||
controls[index].active = true;
|
||||
cell.hasActiveChild = true;
|
||||
};
|
||||
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
function umbGridHackScope() {
|
||||
|
||||
function link($scope, $element) {
|
||||
|
||||
// Since the grid used the el.scope() method, which should only be used by debugging, and only are avilable in debug-mode. I had to make a replica method doig the same:
|
||||
$element[0].getScope_HackForSortable = function() {
|
||||
return $scope;
|
||||
}
|
||||
}
|
||||
|
||||
var directive = {
|
||||
restrict: "A",
|
||||
link: link
|
||||
};
|
||||
|
||||
return directive;
|
||||
|
||||
}
|
||||
|
||||
angular.module("umbraco").directive("umbGridHackScope", umbGridHackScope);
|
||||
|
||||
})();
|
||||
@@ -159,7 +159,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="umb-cell-inner" ui-sortable="sortableOptionsCell" ng-model="area.controls">
|
||||
<div class="umb-cell-inner" ui-sortable="sortableOptionsCell" umb-grid-hack-scope ng-model="area.controls">
|
||||
|
||||
<!-- Control placeholder -->
|
||||
<div class="umb-cell-placeholder" ng-if="area.controls.length === 0" ng-click="openEditorOverlay($event, area, 0, area.$uniqueId);">
|
||||
@@ -171,6 +171,7 @@
|
||||
|
||||
<!-- for each control in areas -->
|
||||
<div class="umb-control"
|
||||
umb-grid-hack-scope
|
||||
ng-repeat="control in area.controls"
|
||||
ng-click="clickControl($index, area.controls, area)"
|
||||
ng-class="{'-active': control.active}"
|
||||
@@ -304,11 +305,4 @@
|
||||
position="target">
|
||||
</umb-overlay>
|
||||
|
||||
<umb-overlay
|
||||
ng-if="gridItemSettingsDialog.show"
|
||||
model="gridItemSettingsDialog"
|
||||
view="gridItemSettingsDialog.view"
|
||||
position="right">
|
||||
</umb-overlay>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -159,7 +159,7 @@ function listViewController($scope, $routeParams, $injector, $timeout, currentUs
|
||||
allowBulkPublish: $scope.entityType === 'content' && $scope.model.config.bulkActionPermissions.allowBulkPublish,
|
||||
allowBulkUnpublish: $scope.entityType === 'content' && $scope.model.config.bulkActionPermissions.allowBulkUnpublish,
|
||||
allowBulkCopy: $scope.entityType === 'content' && $scope.model.config.bulkActionPermissions.allowBulkCopy,
|
||||
allowBulkMove: $scope.model.config.bulkActionPermissions.allowBulkMove,
|
||||
allowBulkMove: $scope.entityType !== 'member' && $scope.model.config.bulkActionPermissions.allowBulkMove,
|
||||
allowBulkDelete: $scope.model.config.bulkActionPermissions.allowBulkDelete,
|
||||
cultureName: $routeParams.cculture ? $routeParams.cculture : $routeParams.mculture
|
||||
};
|
||||
@@ -583,6 +583,8 @@ function listViewController($scope, $routeParams, $injector, $timeout, currentUs
|
||||
.then(function () {
|
||||
//executes if all is successful, let's sync the tree
|
||||
if (newPath) {
|
||||
// reload the current view so the moved items are no longer shown
|
||||
$scope.reloadView($scope.contentId);
|
||||
|
||||
//we need to do a double sync here: first refresh the node where the content was moved,
|
||||
// then refresh the node where the content was moved from
|
||||
|
||||
@@ -105,7 +105,7 @@
|
||||
<PackageReference Include="MiniProfiler" Version="4.0.138" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
|
||||
<PackageReference Include="Umbraco.ModelsBuilder.Ui">
|
||||
<Version>8.0.1</Version>
|
||||
<Version>8.0.4</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Umbraco.SqlServerCE" Version="4.0.0.1" />
|
||||
</ItemGroup>
|
||||
@@ -340,9 +340,9 @@
|
||||
<WebProjectProperties>
|
||||
<UseIIS>False</UseIIS>
|
||||
<AutoAssignPort>True</AutoAssignPort>
|
||||
<DevelopmentServerPort>8000</DevelopmentServerPort>
|
||||
<DevelopmentServerPort>8020</DevelopmentServerPort>
|
||||
<DevelopmentServerVPath>/</DevelopmentServerVPath>
|
||||
<IISUrl>http://localhost:8000</IISUrl>
|
||||
<IISUrl>http://localhost:8020</IISUrl>
|
||||
<NTLMAuthentication>False</NTLMAuthentication>
|
||||
<UseCustomServer>False</UseCustomServer>
|
||||
<CustomServerUrl>
|
||||
|
||||
@@ -1127,7 +1127,7 @@ To manage your website, simply open the Umbraco back office and start adding con
|
||||
<key alias="cancelAndUploadAnother">Cancel and upload another package</key>
|
||||
<key alias="accept">I accept</key>
|
||||
<key alias="termsOfUse">terms of use</key>
|
||||
|
||||
|
||||
<key alias="pathToFile">Path to file</key>
|
||||
<key alias="pathToFileDescription">Absolute path to file (ie: /bin/umbraco.bin)</key>
|
||||
<key alias="installed">Installed</key>
|
||||
@@ -1164,7 +1164,7 @@ To manage your website, simply open the Umbraco back office and start adding con
|
||||
<key alias="packageDownloads">Downloads</key>
|
||||
<key alias="packageLikes">Likes</key>
|
||||
<key alias="packageCompatibility">Compatibility</key>
|
||||
<key alias="packageCompatibilityDescription">This package is compatible with the following versions of Umbraco, as reported by community members. Full compatability cannot be gauranteed for versions reported below 100%</key>
|
||||
<key alias="packageCompatibilityDescription">This package is compatible with the following versions of Umbraco, as reported by community members. Full compatability cannot be guaranteed for versions reported below 100%</key>
|
||||
<key alias="packageExternalSources">External sources</key>
|
||||
<key alias="packageAuthor">Author</key>
|
||||
<key alias="packageDocumentation">Documentation</key>
|
||||
@@ -1994,13 +1994,13 @@ To manage your website, simply open the Umbraco back office and start adding con
|
||||
<key alias="httpsCheckExpiringCertificate">Your website's SSL certificate is expiring in %0% days.</key>
|
||||
<key alias="healthCheckInvalidUrl">Error pinging the URL %0% - '%1%'</key>
|
||||
<key alias="httpsCheckIsCurrentSchemeHttps">You are currently %0% viewing the site using the HTTPS scheme.</key>
|
||||
<key alias="httpsCheckConfigurationRectifyNotPossible">The appSetting 'umbracoUseSSL' is set to 'false' in your web.config file. Once you access this site using the HTTPS scheme, that should be set to 'true'.</key>
|
||||
<key alias="httpsCheckConfigurationCheckResult">The appSetting 'umbracoUseSSL' is set to '%0%' in your web.config file, your cookies are %1% marked as secure.</key>
|
||||
<key alias="httpsCheckEnableHttpsError">Could not update the 'umbracoUseSSL' setting in your web.config file. Error: %0%</key>
|
||||
<key alias="httpsCheckConfigurationRectifyNotPossible">The appSetting 'Umbraco.Core.UseHttps' is set to 'false' in your web.config file. Once you access this site using the HTTPS scheme, that should be set to 'true'.</key>
|
||||
<key alias="httpsCheckConfigurationCheckResult">The appSetting 'Umbraco.Core.UseHttps' is set to '%0%' in your web.config file, your cookies are %1% marked as secure.</key>
|
||||
<key alias="httpsCheckEnableHttpsError">Could not update the 'Umbraco.Core.UseHttps' setting in your web.config file. Error: %0%</key>
|
||||
<!-- The following keys don't get tokens passed in -->
|
||||
<key alias="httpsCheckEnableHttpsButton">Enable HTTPS</key>
|
||||
<key alias="httpsCheckEnableHttpsDescription">Sets umbracoSSL setting to true in the appSettings of the web.config file.</key>
|
||||
<key alias="httpsCheckEnableHttpsSuccess">The appSetting 'umbracoUseSSL' is now set to 'true' in your web.config file, your cookies will be marked as secure.</key>
|
||||
<key alias="httpsCheckEnableHttpsSuccess">The appSetting 'Umbraco.Core.UseHttps' is now set to 'true' in your web.config file, your cookies will be marked as secure.</key>
|
||||
<key alias="rectifyButton">Fix</key>
|
||||
<key alias="cannotRectifyShouldNotEqual">Cannot fix a check with a value comparison type of 'ShouldNotEqual'.</key>
|
||||
<key alias="cannotRectifyShouldEqualWithValue">Cannot fix a check with a value comparison type of 'ShouldEqual' with a provided value.</key>
|
||||
|
||||
@@ -1163,7 +1163,7 @@ To manage your website, simply open the Umbraco back office and start adding con
|
||||
<key alias="packageDownloads">Downloads</key>
|
||||
<key alias="packageLikes">Likes</key>
|
||||
<key alias="packageCompatibility">Compatibility</key>
|
||||
<key alias="packageCompatibilityDescription">This package is compatible with the following versions of Umbraco, as reported by community members. Full compatability cannot be gauranteed for versions reported below 100%</key>
|
||||
<key alias="packageCompatibilityDescription">This package is compatible with the following versions of Umbraco, as reported by community members. Full compatability cannot be guaranteed for versions reported below 100%</key>
|
||||
<key alias="packageExternalSources">External sources</key>
|
||||
<key alias="packageAuthor">Author</key>
|
||||
<key alias="packageDocumentation">Documentation</key>
|
||||
@@ -2005,13 +2005,13 @@ To manage your website, simply open the Umbraco back office and start adding con
|
||||
<key alias="httpsCheckExpiringCertificate">Your website's SSL certificate is expiring in %0% days.</key>
|
||||
<key alias="healthCheckInvalidUrl">Error pinging the URL %0% - '%1%'</key>
|
||||
<key alias="httpsCheckIsCurrentSchemeHttps">You are currently %0% viewing the site using the HTTPS scheme.</key>
|
||||
<key alias="httpsCheckConfigurationRectifyNotPossible">The appSetting 'umbracoUseSSL' is set to 'false' in your web.config file. Once you access this site using the HTTPS scheme, that should be set to 'true'.</key>
|
||||
<key alias="httpsCheckConfigurationCheckResult">The appSetting 'umbracoUseSSL' is set to '%0%' in your web.config file, your cookies are %1% marked as secure.</key>
|
||||
<key alias="httpsCheckEnableHttpsError">Could not update the 'umbracoUseSSL' setting in your web.config file. Error: %0%</key>
|
||||
<key alias="httpsCheckConfigurationRectifyNotPossible">The appSetting 'Umbraco.Core.UseHttps' is set to 'false' in your web.config file. Once you access this site using the HTTPS scheme, that should be set to 'true'.</key>
|
||||
<key alias="httpsCheckConfigurationCheckResult">The appSetting 'Umbraco.Core.UseHttps' is set to '%0%' in your web.config file, your cookies are %1% marked as secure.</key>
|
||||
<key alias="httpsCheckEnableHttpsError">Could not update the 'Umbraco.Core.UseHttps' setting in your web.config file. Error: %0%</key>
|
||||
<!-- The following keys don't get tokens passed in -->
|
||||
<key alias="httpsCheckEnableHttpsButton">Enable HTTPS</key>
|
||||
<key alias="httpsCheckEnableHttpsDescription">Sets umbracoSSL setting to true in the appSettings of the web.config file.</key>
|
||||
<key alias="httpsCheckEnableHttpsSuccess">The appSetting 'umbracoUseSSL' is now set to 'true' in your web.config file, your cookies will be marked as secure.</key>
|
||||
<key alias="httpsCheckEnableHttpsSuccess">The appSetting 'Umbraco.Core.UseHttps' is now set to 'true' in your web.config file, your cookies will be marked as secure.</key>
|
||||
<key alias="rectifyButton">Fix</key>
|
||||
<key alias="cannotRectifyShouldNotEqual">Cannot fix a check with a value comparison type of 'ShouldNotEqual'.</key>
|
||||
<key alias="cannotRectifyShouldEqualWithValue">Cannot fix a check with a value comparison type of 'ShouldEqual' with a provided value.</key>
|
||||
|
||||
@@ -1292,9 +1292,9 @@
|
||||
<key alias="mailBody"><![CDATA[
|
||||
Hola %0%.
|
||||
|
||||
Este mail se ha generado automáticamente para informale que %2% has solicitado que el documento '%1%' sea traducido en '%5%'.
|
||||
Este mail se ha generado automáticamente para informale que %2% has solicitado que el documento '%1%' sea traducido en '%5%'.
|
||||
|
||||
Para editarlo, vaya a la dirección http://%3%/translation/details.aspx?id=%4% o inicia sesión en umbraco y ve a http://%3% para ver las tareas pendientes de traducir.
|
||||
Para editarlo, vaya a la dirección http://%3%/translation/details.aspx?id=%4% o inicia sesión en umbraco y ve a http://%3% para ver las tareas pendientes de traducir.
|
||||
|
||||
Espero que tenga un buen dia.
|
||||
|
||||
@@ -1587,13 +1587,13 @@
|
||||
<key alias="httpsCheckExpiringCertificate">El certificado SSL de tu sitio caducará en %0% días.</key>
|
||||
<key alias="healthCheckInvalidUrl">Error haciendo ping a la URL %0% - '%1%'</key>
|
||||
<key alias="httpsCheckIsCurrentSchemeHttps">Actualmente estás %0% viendo el sitio usando el esquema HTTPS.</key>
|
||||
<key alias="httpsCheckConfigurationRectifyNotPossible">El appSetting 'umbracoUseSSL' está configurado como 'false' en tu archivo web.config. Una vez que accedes al sitio usando HTTPS, debería ser configurado como 'true'.</key>
|
||||
<key alias="httpsCheckConfigurationCheckResult">Ele appSetting 'umbracoUseSSL' está configurado como '%0%' en tu archivo web.config, tus cookies son %1% marcadas como seguras.</key>
|
||||
<key alias="httpsCheckEnableHttpsError">No se pudo actualizar 'umbracoUseSSL' en tu archivo web.config. Error: %0%</key>
|
||||
<key alias="httpsCheckConfigurationRectifyNotPossible">El appSetting 'Umbraco.Core.UseHttps' está configurado como 'false' en tu archivo web.config. Una vez que accedes al sitio usando HTTPS, debería ser configurado como 'true'.</key>
|
||||
<key alias="httpsCheckConfigurationCheckResult">Ele appSetting 'Umbraco.Core.UseHttps' está configurado como '%0%' en tu archivo web.config, tus cookies son %1% marcadas como seguras.</key>
|
||||
<key alias="httpsCheckEnableHttpsError">No se pudo actualizar 'Umbraco.Core.UseHttps' en tu archivo web.config. Error: %0%</key>
|
||||
<!-- The following keys don't get tokens passed in -->
|
||||
<key alias="httpsCheckEnableHttpsButton">Activar HTTPS</key>
|
||||
<key alias="httpsCheckEnableHttpsDescription">Configura umbracoSSL como true en los appSettings del archivo web.config.</key>
|
||||
<key alias="httpsCheckEnableHttpsSuccess">El appSetting 'umbracoUseSSL' está ahora configurado como 'true' en tu archivo web.config, tus cookies se marcarán como seguras.</key>
|
||||
<key alias="httpsCheckEnableHttpsSuccess">El appSetting 'Umbraco.Core.UseHttps' está ahora configurado como 'true' en tu archivo web.config, tus cookies se marcarán como seguras.</key>
|
||||
<key alias="rectifyButton">Arreglar</key>
|
||||
<key alias="cannotRectifyShouldNotEqual">No se pudo arreglar chequeo con un valor de comparación 'ShouldNotEqual'.</key>
|
||||
<key alias="cannotRectifyShouldEqualWithValue">No se pudo arreglar chequeo con un valor de comparación 'ShouldEqual' con el valor introducido.</key>
|
||||
|
||||
@@ -1782,13 +1782,13 @@ Pour gérer votre site, ouvrez simplement le backoffice Umbraco et commencez à
|
||||
<key alias="httpsCheckExpiringCertificate">Le certificat SSL de votre site web va expirer dans %0% jours.</key>
|
||||
<key alias="healthCheckInvalidUrl">Erreur en essayant de contacter l'URL %0% - '%1%'</key>
|
||||
<key alias="httpsCheckIsCurrentSchemeHttps">Vous êtes actuellement %0% à voir le site via le schéma HTTPS.</key>
|
||||
<key alias="httpsCheckConfigurationRectifyNotPossible">La valeur appSetting 'umbracoUseSSL' est fixée à 'false' dans votre fichier web.config. Une fois que vous donnerez accès à ce site en utilisant le schéma HTTPS, cette valeur devra être mise à 'true'.</key>
|
||||
<key alias="httpsCheckConfigurationCheckResult">La valeur appSetting 'umbracoUseSSL' est fixée à '%0%' dans votre fichier web.config, vos cookies sont %1% marqués comme étant sécurisés.</key>
|
||||
<key alias="httpsCheckEnableHttpsError">Impossible de mettre à jour la configuration 'umbracoUseSSL' dans votre fichier web.config. Erreur : %0%</key>
|
||||
<key alias="httpsCheckConfigurationRectifyNotPossible">La valeur appSetting 'Umbraco.Core.UseHttps' est fixée à 'false' dans votre fichier web.config. Une fois que vous donnerez accès à ce site en utilisant le schéma HTTPS, cette valeur devra être mise à 'true'.</key>
|
||||
<key alias="httpsCheckConfigurationCheckResult">La valeur appSetting 'Umbraco.Core.UseHttps' est fixée à '%0%' dans votre fichier web.config, vos cookies sont %1% marqués comme étant sécurisés.</key>
|
||||
<key alias="httpsCheckEnableHttpsError">Impossible de mettre à jour la configuration 'Umbraco.Core.UseHttps' dans votre fichier web.config. Erreur : %0%</key>
|
||||
<!-- The following keys don't get tokens passed in -->
|
||||
<key alias="httpsCheckEnableHttpsButton">Activer HTTPS</key>
|
||||
<key alias="httpsCheckEnableHttpsDescription">Fixe la configuration 'umbracoSSL' à 'true' dans la section appSettings du fichier web.config.</key>
|
||||
<key alias="httpsCheckEnableHttpsSuccess">La configuration appSetting 'umbracoUseSSL' est maintenant fixée à 'true' dans votre fichier web.config, vos cookies seront marqués comme étant sécurisés.</key>
|
||||
<key alias="httpsCheckEnableHttpsSuccess">La configuration appSetting 'Umbraco.Core.UseHttps' est maintenant fixée à 'true' dans votre fichier web.config, vos cookies seront marqués comme étant sécurisés.</key>
|
||||
<key alias="rectifyButton">Corriger</key>
|
||||
<key alias="cannotRectifyShouldNotEqual">Impossible de corriger une vérification avec un type de comparaison 'ShouldNotEqual'.</key>
|
||||
<key alias="cannotRectifyShouldEqualWithValue">Impossible de corriger une vérification avec un type de comparaison 'ShouldEqual' avec une valeur spécifiée.</key>
|
||||
|
||||
@@ -1344,13 +1344,13 @@ Echter, Runway biedt een gemakkelijke basis om je snel op weg te helpen. Als je
|
||||
<key alias="httpsCheckInvalidCertificate">Cerficaat validatie foutmelding: '%0%'</key>
|
||||
<key alias="healthCheckInvalidUrl">Fout bij pingen van URL %0% - '%1%'</key>
|
||||
<key alias="httpsCheckIsCurrentSchemeHttps">De site wordt momenteel %0% bekeken via HTTPS.</key>
|
||||
<key alias="httpsCheckConfigurationRectifyNotPossible">De appSetting 'umbracoUseSSL' in web.config staat op 'false'. Indien HTTPS gebruikt wordt moet deze op 'true' staan.</key>
|
||||
<key alias="httpsCheckConfigurationCheckResult">De appSetting 'umbracoUseSSL' in web.config is ingesteld op '%0%'. Cookies zijn %1% ingesteld als secure.</key>
|
||||
<key alias="httpsCheckEnableHttpsError">De 'umbracoUseSSL' waarde in web.config kon niet aangepast worden. Foutmelding: %0%</key>
|
||||
<key alias="httpsCheckConfigurationRectifyNotPossible">De appSetting 'Umbraco.Core.UseHttps' in web.config staat op 'false'. Indien HTTPS gebruikt wordt moet deze op 'true' staan.</key>
|
||||
<key alias="httpsCheckConfigurationCheckResult">De appSetting 'Umbraco.Core.UseHttps' in web.config is ingesteld op '%0%'. Cookies zijn %1% ingesteld als secure.</key>
|
||||
<key alias="httpsCheckEnableHttpsError">De 'Umbraco.Core.UseHttps' waarde in web.config kon niet aangepast worden. Foutmelding: %0%</key>
|
||||
<!-- The following keys don't get tokens passed in -->
|
||||
<key alias="httpsCheckEnableHttpsButton">HTTPS inschakelen</key>
|
||||
<key alias="httpsCheckEnableHttpsDescription">Zet in de appSettings van de web.config de umbracoSSL instelling op 'true'.</key>
|
||||
<key alias="httpsCheckEnableHttpsSuccess">De appSetting 'umbracoUseSSL' is nu ingesteld op 'true', cookies zullen als 'secure' worden aangemerkt.</key>
|
||||
<key alias="httpsCheckEnableHttpsSuccess">De appSetting 'Umbraco.Core.UseHttps' is nu ingesteld op 'true', cookies zullen als 'secure' worden aangemerkt.</key>
|
||||
<key alias="rectifyButton">Herstellen</key>
|
||||
<key alias="cannotRectifyShouldNotEqual">Kan een controle met vergelijkingstype 'ShouldNotEqual' niet herstellen.</key>
|
||||
<key alias="cannotRectifyShouldEqualWithValue">Kan een controle met vergelijkingstype 'ShouldNotEqual' en gedefinieerde waarde niet herstellen.</key>
|
||||
|
||||
@@ -1423,13 +1423,13 @@ Naciśnij przycisk <strong>instaluj</strong>, aby zainstalować bazę danych Umb
|
||||
<key alias="httpsCheckExpiringCertificate">Certyfikat SSL Twojej strony wygaśnie za %0% dni.</key>
|
||||
<key alias="healthCheckInvalidUrl">Błąd pingowania adresu URL %0% - '%1%'</key>
|
||||
<key alias="httpsCheckIsCurrentSchemeHttps">Oglądasz %0% stronę używając HTTPS.</key>
|
||||
<key alias="httpsCheckConfigurationRectifyNotPossible">appSetting 'umbracoUseSSL' został ustawiony na 'false' w Twoim pliku web.config. Po uzyskaniu dostępu do strony, używając HTTPS, powinieneś go ustawić na 'true'.</key>
|
||||
<key alias="httpsCheckConfigurationCheckResult">appSetting 'umbracoUseSSL' został ustawiony na '%0%' w Twoim pliku web.config, Twoje ciasteczka są %1% ustawione jako bezpieczne.</key>
|
||||
<key alias="httpsCheckEnableHttpsError">Nie można zaktualizaować ustawień 'umbracoUseSSL' w Twoim pliku web.config file. Błąd: %0%</key>
|
||||
<key alias="httpsCheckConfigurationRectifyNotPossible">appSetting 'Umbraco.Core.UseHttps' został ustawiony na 'false' w Twoim pliku web.config. Po uzyskaniu dostępu do strony, używając HTTPS, powinieneś go ustawić na 'true'.</key>
|
||||
<key alias="httpsCheckConfigurationCheckResult">appSetting 'Umbraco.Core.UseHttps' został ustawiony na '%0%' w Twoim pliku web.config, Twoje ciasteczka są %1% ustawione jako bezpieczne.</key>
|
||||
<key alias="httpsCheckEnableHttpsError">Nie można zaktualizaować ustawień 'Umbraco.Core.UseHttps' w Twoim pliku web.config file. Błąd: %0%</key>
|
||||
<!-- Następujące klucze nie mają przekazanych tokenów -->
|
||||
<key alias="httpsCheckEnableHttpsButton">Włącz HTTPS</key>
|
||||
<key alias="httpsCheckEnableHttpsDescription">Ustawia umbracoSSL na 'true' w appSettings pliku web.config.</key>
|
||||
<key alias="httpsCheckEnableHttpsSuccess">appSetting 'umbracoUseSSL' jest teraz ustawione na 'true' w Twoim pliku web.config, Twoje ciasteczka będą oznaczone jako bezpieczne.</key>
|
||||
<key alias="httpsCheckEnableHttpsSuccess">appSetting 'Umbraco.Core.UseHttps' jest teraz ustawione na 'true' w Twoim pliku web.config, Twoje ciasteczka będą oznaczone jako bezpieczne.</key>
|
||||
<key alias="rectifyButton">Napraw</key>
|
||||
<key alias="cannotRectifyShouldNotEqual">Nie można naprawić sprawdzenia z wartością typu porównania 'ShouldNotEqual'.</key>
|
||||
<key alias="cannotRectifyShouldEqualWithValue">Nie można naprawić sprawdzenia z wartością typu porównania 'ShouldEqual' z wprowadzoną wartością.</key>
|
||||
|
||||
@@ -712,13 +712,13 @@
|
||||
<key alias="httpsCheckValidCertificate">Сертификат Вашего веб-сайта отмечен как проверенный.</key>
|
||||
<key alias="httpsCheckInvalidCertificate">Ошибка проверки сертификата: '%0%'</key>
|
||||
<key alias="httpsCheckIsCurrentSchemeHttps">Сейчас Вы %0% просматриваете сайт, используя протокол HTTPS.</key>
|
||||
<key alias="httpsCheckConfigurationRectifyNotPossible">Параметр 'umbracoUseSSL' в секции 'appSetting' установлен в 'false' в файле web.config. Если Вам необходим доступ к сайту по протоколу HTTPS, нужно установить данный параметр в 'true'.</key>
|
||||
<key alias="httpsCheckConfigurationCheckResult">Параметр 'umbracoUseSSL' в секции 'appSetting' в файле установлен в '%0%', значения cookies %1% маркированы как безопасные.</key>
|
||||
<key alias="httpsCheckEnableHttpsError">Невозможно обновить значение параметра 'umbracoUseSSL' в файле web.config. Ошибка: %0%</key>
|
||||
<key alias="httpsCheckConfigurationRectifyNotPossible">Параметр 'Umbraco.Core.UseHttps' в секции 'appSetting' установлен в 'false' в файле web.config. Если Вам необходим доступ к сайту по протоколу HTTPS, нужно установить данный параметр в 'true'.</key>
|
||||
<key alias="httpsCheckConfigurationCheckResult">Параметр 'Umbraco.Core.UseHttps' в секции 'appSetting' в файле установлен в '%0%', значения cookies %1% маркированы как безопасные.</key>
|
||||
<key alias="httpsCheckEnableHttpsError">Невозможно обновить значение параметра 'Umbraco.Core.UseHttps' в файле web.config. Ошибка: %0%</key>
|
||||
<!-- The following keys don't get tokens passed in -->
|
||||
<key alias="httpsCheckEnableHttpsButton">Разрешить HTTPS</key>
|
||||
<key alias="httpsCheckEnableHttpsDescription">Устанавливает значение параметра 'umbracoSSL' в 'true' в секции 'appSettings' файла web.config.</key>
|
||||
<key alias="httpsCheckEnableHttpsSuccess">Параметр 'umbracoUseSSL' в секции 'appSetting' файла web.config теперь установлен в 'true', значения cookies будут промаркированы как безопасные.</key>
|
||||
<key alias="httpsCheckEnableHttpsSuccess">Параметр 'Umbraco.Core.UseHttps' в секции 'appSetting' файла web.config теперь установлен в 'true', значения cookies будут промаркированы как безопасные.</key>
|
||||
<key alias="rectifyButton">Исправить</key>
|
||||
<key alias="cannotRectifyShouldNotEqual">Невозможно исправление по результату проверки значения на 'ShouldNotEqual'.</key>
|
||||
<key alias="cannotRectifyShouldEqualWithValue">Невозможно исправление по результату проверки значения на 'ShouldEqual' с предоставленным значением.</key>
|
||||
|
||||
@@ -1208,13 +1208,13 @@
|
||||
<key alias="httpsCheckInvalidCertificate">Certificate validation error: '%0%'</key>
|
||||
<key alias="httpsCheckInvalidUrl">Error pinging the URL %0% - '%1%'</key>
|
||||
<key alias="httpsCheckIsCurrentSchemeHttps">You are currently %0% viewing the site using the HTTPS scheme.</key>
|
||||
<key alias="httpsCheckConfigurationRectifyNotPossible">The appSetting 'umbracoUseSSL' is set to 'false' in your web.config file. Once you access this site using the HTTPS scheme, that should be set to 'true'.</key>
|
||||
<key alias="httpsCheckConfigurationCheckResult">The appSetting 'umbracoUseSSL' is set to '%0%' in your web.config file, your cookies are %1% marked as secure.</key>
|
||||
<key alias="httpsCheckEnableHttpsError">Could not update the 'umbracoUseSSL' setting in your web.config file. Error: %0%</key>
|
||||
<key alias="httpsCheckConfigurationRectifyNotPossible">The appSetting 'Umbraco.Core.UseHttps' is set to 'false' in your web.config file. Once you access this site using the HTTPS scheme, that should be set to 'true'.</key>
|
||||
<key alias="httpsCheckConfigurationCheckResult">The appSetting 'Umbraco.Core.UseHttps' is set to '%0%' in your web.config file, your cookies are %1% marked as secure.</key>
|
||||
<key alias="httpsCheckEnableHttpsError">Could not update the 'Umbraco.Core.UseHttps' setting in your web.config file. Error: %0%</key>
|
||||
<!-- The following keys don't get tokens passed in -->
|
||||
<key alias="httpsCheckEnableHttpsButton">Enable HTTPS</key>
|
||||
<key alias="httpsCheckEnableHttpsDescription">Sets umbracoSSL setting to true in the appSettings of the web.config file.</key>
|
||||
<key alias="httpsCheckEnableHttpsSuccess">The appSetting 'umbracoUseSSL' is now set to 'true' in your web.config file, your cookies will be marked as secure.</key>
|
||||
<key alias="httpsCheckEnableHttpsSuccess">The appSetting 'Umbraco.Core.UseHttps' is now set to 'true' in your web.config file, your cookies will be marked as secure.</key>
|
||||
<key alias="rectifyButton">Fix</key>
|
||||
<key alias="cannotRectifyShouldNotEqual">Cannot fix a check with a value comparison type of 'ShouldNotEqual'.</key>
|
||||
<key alias="cannotRectifyShouldEqualWithValue">Cannot fix a check with a value comparison type of 'ShouldEqual' with a provided value.</key>
|
||||
|
||||
@@ -1187,13 +1187,13 @@
|
||||
<key alias="httpsCheckInvalidCertificate">憑證驗證錯誤:%0%</key>
|
||||
<key alias="healthCheckInvalidUrl">網址探查錯誤:%0% - '%1%'</key>
|
||||
<key alias="httpsCheckIsCurrentSchemeHttps">您目前使用HTTPS瀏覽本站:%0%</key>
|
||||
<key alias="httpsCheckConfigurationRectifyNotPossible">在您的web.config檔案中,appSetting的umbracoUseSSL是設為false。當您開始使用HTTPS時,應將其改為 true。</key>
|
||||
<key alias="httpsCheckConfigurationCheckResult">在您的web.config檔案中,appSetting的umbracoUseSSL是設為 %0%,您的cookies %0% 標成安全。</key>
|
||||
<key alias="httpsCheckEnableHttpsError">無法在您的web.config檔案中,更新appSetting的umbracoUseSSL設定,錯誤訊息:%0%</key>
|
||||
<key alias="httpsCheckConfigurationRectifyNotPossible">在您的web.config檔案中,appSetting的Umbraco.Core.UseHttps是設為false。當您開始使用HTTPS時,應將其改為 true。</key>
|
||||
<key alias="httpsCheckConfigurationCheckResult">在您的web.config檔案中,appSetting的Umbraco.Core.UseHttps是設為 %0%,您的cookies %0% 標成安全。</key>
|
||||
<key alias="httpsCheckEnableHttpsError">無法在您的web.config檔案中,更新appSetting的Umbraco.Core.UseHttps設定,錯誤訊息:%0%</key>
|
||||
<!-- The following keys don't get tokens passed in -->
|
||||
<key alias="httpsCheckEnableHttpsButton">開啟HTTPS</key>
|
||||
<key alias="httpsCheckEnableHttpsDescription">在web.config檔案中,將appSetting的umbracoUseSSL設true。</key>
|
||||
<key alias="httpsCheckEnableHttpsSuccess">在您的web.config檔案中,appSetting的umbracoUseSSL已設為 true,您的cookies 將被標成安全。</key>
|
||||
<key alias="httpsCheckEnableHttpsDescription">在web.config檔案中,將appSetting的Umbraco.Core.UseHttps設true。</key>
|
||||
<key alias="httpsCheckEnableHttpsSuccess">在您的web.config檔案中,appSetting的Umbraco.Core.UseHttps已設為 true,您的cookies 將被標成安全。</key>
|
||||
<key alias="rectifyButton">修正</key>
|
||||
<key alias="cannotRectifyShouldNotEqual">無法修正比較種類檢查為'ShouldNotEqual'。</key>
|
||||
<key alias="cannotRectifyShouldEqualWithValue">用提供的數值無法修正比較種類檢查為'ShouldEqual'。</key>
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.WebPages;
|
||||
using Umbraco.Web.Composing;
|
||||
|
||||
namespace Umbraco.Web.UI.Config.Splashes
|
||||
|
||||
@@ -13,6 +13,7 @@ using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
using Umbraco.Core.Scoping;
|
||||
using Umbraco.Web.Composing;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace Umbraco.Web
|
||||
{
|
||||
@@ -26,10 +27,17 @@ namespace Umbraco.Web
|
||||
{
|
||||
private readonly IUmbracoDatabaseFactory _databaseFactory;
|
||||
|
||||
[Obsolete("This overload should not be used, enableDistCalls has no effect")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public BatchedDatabaseServerMessenger(
|
||||
IRuntimeState runtime, IUmbracoDatabaseFactory databaseFactory, IScopeProvider scopeProvider, ISqlContext sqlContext, IProfilingLogger proflog, IGlobalSettings globalSettings,
|
||||
bool enableDistCalls, DatabaseServerMessengerOptions options)
|
||||
: base(runtime, scopeProvider, sqlContext, proflog, globalSettings, enableDistCalls, options)
|
||||
IRuntimeState runtime, IUmbracoDatabaseFactory databaseFactory, IScopeProvider scopeProvider, ISqlContext sqlContext, IProfilingLogger proflog, IGlobalSettings globalSettings, bool enableDistCalls, DatabaseServerMessengerOptions options)
|
||||
: this(runtime, databaseFactory, scopeProvider, sqlContext, proflog, globalSettings, options)
|
||||
{
|
||||
}
|
||||
|
||||
public BatchedDatabaseServerMessenger(
|
||||
IRuntimeState runtime, IUmbracoDatabaseFactory databaseFactory, IScopeProvider scopeProvider, ISqlContext sqlContext, IProfilingLogger proflog, IGlobalSettings globalSettings, DatabaseServerMessengerOptions options)
|
||||
: base(runtime, scopeProvider, sqlContext, proflog, globalSettings, true, options)
|
||||
{
|
||||
_databaseFactory = databaseFactory;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
@@ -82,20 +83,8 @@ namespace Umbraco.Web.Cache
|
||||
// service of changes, else factories may try to rebuild models while
|
||||
// we are using the database to load content into caches
|
||||
|
||||
// ReSharper disable once SuspiciousTypeConversion.Global
|
||||
if (_publishedModelFactory is ILivePublishedModelFactory live)
|
||||
{
|
||||
lock (live.SyncRoot)
|
||||
{
|
||||
live.Refresh();
|
||||
_publishedSnapshotService.Notify(payloads);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// ReSharper disable once InconsistentlySynchronizedField
|
||||
_publishedSnapshotService.Notify(payloads);
|
||||
}
|
||||
_publishedModelFactory.WithSafeLiveFactory(() =>
|
||||
_publishedSnapshotService.Notify(payloads));
|
||||
|
||||
// now we can trigger the event
|
||||
base.Refresh(payloads);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
@@ -65,20 +66,8 @@ namespace Umbraco.Web.Cache
|
||||
// service of changes, else factories may try to rebuild models while
|
||||
// we are using the database to load content into caches
|
||||
|
||||
// ReSharper disable once SuspiciousTypeConversion.Global
|
||||
if (_publishedModelFactory is ILivePublishedModelFactory live)
|
||||
{
|
||||
lock (live.SyncRoot)
|
||||
{
|
||||
live.Refresh();
|
||||
_publishedSnapshotService.Notify(payloads);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// ReSharper disable once InconsistentlySynchronizedField
|
||||
_publishedSnapshotService.Notify(payloads);
|
||||
}
|
||||
_publishedModelFactory.WithSafeLiveFactory(() =>
|
||||
_publishedSnapshotService.Notify(payloads));
|
||||
|
||||
base.Refresh(payloads);
|
||||
}
|
||||
|
||||
@@ -119,8 +119,8 @@ namespace Umbraco.Web.Cache
|
||||
() => MemberGroupService.Deleted -= MemberGroupService_Deleted);
|
||||
|
||||
// bind to media events - handles all media changes
|
||||
Bind(() => MediaService.TreeChanged += MediaService_Changed,
|
||||
() => MediaService.TreeChanged -= MediaService_Changed);
|
||||
Bind(() => MediaService.TreeChanged += MediaService_TreeChanged,
|
||||
() => MediaService.TreeChanged -= MediaService_TreeChanged);
|
||||
|
||||
// bind to content events
|
||||
Bind(() => ContentService.Saved += ContentService_Saved, // needed for permissions
|
||||
@@ -403,7 +403,7 @@ namespace Umbraco.Web.Cache
|
||||
|
||||
#region MediaService
|
||||
|
||||
private void MediaService_Changed(IMediaService sender, TreeChange<IMedia>.EventArgs args)
|
||||
private void MediaService_TreeChanged(IMediaService sender, TreeChange<IMedia>.EventArgs args)
|
||||
{
|
||||
_distributedCache.RefreshMediaCache(args.Changes.ToArray());
|
||||
}
|
||||
|
||||
@@ -38,54 +38,44 @@ namespace Umbraco.Web.Compose
|
||||
|
||||
public sealed class DatabaseServerRegistrarAndMessengerComposer : ComponentComposer<DatabaseServerRegistrarAndMessengerComponent>, ICoreComposer
|
||||
{
|
||||
public static DatabaseServerMessengerOptions GetDefaultOptions(IFactory factory)
|
||||
{
|
||||
var logger = factory.GetInstance<ILogger>();
|
||||
var indexRebuilder = factory.GetInstance<IndexRebuilder>();
|
||||
|
||||
return new DatabaseServerMessengerOptions
|
||||
{
|
||||
//These callbacks will be executed if the server has not been synced
|
||||
// (i.e. it is a new server or the lastsynced.txt file has been removed)
|
||||
InitializingCallbacks = new Action[]
|
||||
{
|
||||
//rebuild the xml cache file if the server is not synced
|
||||
() =>
|
||||
{
|
||||
// rebuild the published snapshot caches entirely, if the server is not synced
|
||||
// this is equivalent to DistributedCache RefreshAll... but local only
|
||||
// (we really should have a way to reuse RefreshAll... locally)
|
||||
// note: refresh all content & media caches does refresh content types too
|
||||
var svc = Current.PublishedSnapshotService;
|
||||
svc.Notify(new[] { new DomainCacheRefresher.JsonPayload(0, DomainChangeTypes.RefreshAll) });
|
||||
svc.Notify(new[] { new ContentCacheRefresher.JsonPayload(0, TreeChangeTypes.RefreshAll) }, out _, out _);
|
||||
svc.Notify(new[] { new MediaCacheRefresher.JsonPayload(0, TreeChangeTypes.RefreshAll) }, out _);
|
||||
},
|
||||
|
||||
//rebuild indexes if the server is not synced
|
||||
// NOTE: This will rebuild ALL indexes including the members, if developers want to target specific
|
||||
// indexes then they can adjust this logic themselves.
|
||||
() => { ExamineComponent.RebuildIndexes(indexRebuilder, logger, false, 5000); }
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public override void Compose(Composition composition)
|
||||
{
|
||||
base.Compose(composition);
|
||||
|
||||
composition.SetServerMessenger(factory =>
|
||||
{
|
||||
var runtime = factory.GetInstance<IRuntimeState>();
|
||||
var databaseFactory = factory.GetInstance<IUmbracoDatabaseFactory>();
|
||||
var globalSettings = factory.GetInstance<IGlobalSettings>();
|
||||
var proflog = factory.GetInstance<IProfilingLogger>();
|
||||
var scopeProvider = factory.GetInstance<IScopeProvider>();
|
||||
var sqlContext = factory.GetInstance<ISqlContext>();
|
||||
var logger = factory.GetInstance<ILogger>();
|
||||
var indexRebuilder = factory.GetInstance<IndexRebuilder>();
|
||||
|
||||
return new BatchedDatabaseServerMessenger(
|
||||
runtime, databaseFactory, scopeProvider, sqlContext, proflog, globalSettings,
|
||||
true,
|
||||
//Default options for web including the required callbacks to build caches
|
||||
new DatabaseServerMessengerOptions
|
||||
{
|
||||
//These callbacks will be executed if the server has not been synced
|
||||
// (i.e. it is a new server or the lastsynced.txt file has been removed)
|
||||
InitializingCallbacks = new Action[]
|
||||
{
|
||||
//rebuild the xml cache file if the server is not synced
|
||||
() =>
|
||||
{
|
||||
// rebuild the published snapshot caches entirely, if the server is not synced
|
||||
// this is equivalent to DistributedCache RefreshAll... but local only
|
||||
// (we really should have a way to reuse RefreshAll... locally)
|
||||
// note: refresh all content & media caches does refresh content types too
|
||||
var svc = Current.PublishedSnapshotService;
|
||||
svc.Notify(new[] { new DomainCacheRefresher.JsonPayload(0, DomainChangeTypes.RefreshAll) });
|
||||
svc.Notify(new[] { new ContentCacheRefresher.JsonPayload(0, TreeChangeTypes.RefreshAll) }, out _, out _);
|
||||
svc.Notify(new[] { new MediaCacheRefresher.JsonPayload(0, TreeChangeTypes.RefreshAll) }, out _);
|
||||
},
|
||||
|
||||
//rebuild indexes if the server is not synced
|
||||
// NOTE: This will rebuild ALL indexes including the members, if developers want to target specific
|
||||
// indexes then they can adjust this logic themselves.
|
||||
() =>
|
||||
{
|
||||
ExamineComponent.RebuildIndexes(indexRebuilder, logger, false, 5000);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
composition.SetDatabaseServerMessengerOptions(GetDefaultOptions);
|
||||
composition.SetServerMessenger<BatchedDatabaseServerMessenger>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,7 +118,7 @@ namespace Umbraco.Web.Compose
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
{
|
||||
//We will start the whole process when a successful request is made
|
||||
if (_registrar != null || _messenger != null)
|
||||
UmbracoModule.RouteAttempt += RegisterBackgroundTasksOnce;
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace Umbraco.Web.ContentApps
|
||||
Weight = Weight
|
||||
});
|
||||
|
||||
case IMedia media when !media.ContentType.IsContainer && media.ContentType.Alias != Core.Constants.Conventions.MediaTypes.Folder:
|
||||
case IMedia media when !media.ContentType.IsContainer || media.Properties.Count > 0:
|
||||
return _mediaApp ?? (_mediaApp = new ContentApp
|
||||
{
|
||||
Alias = "umbContent",
|
||||
|
||||
@@ -183,7 +183,7 @@ namespace Umbraco.Web.HealthCheck.Checks.Security
|
||||
private HealthCheckStatus FixHttpsSetting()
|
||||
{
|
||||
var configFile = IOHelper.MapPath("~/Web.config");
|
||||
const string xPath = "/configuration/appSettings/add[@key='umbracoUseSSL']/@value";
|
||||
const string xPath = "/configuration/appSettings/add[@key='Umbraco.Core.UseHttps']/@value";
|
||||
var configurationService = new ConfigurationService(configFile, xPath, _textService);
|
||||
var updateConfigFile = configurationService.UpdateConfigFile("true");
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.Strings;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Web.Editors;
|
||||
using Umbraco.Web.Routing;
|
||||
@@ -198,10 +199,10 @@ namespace Umbraco.Web.Macros
|
||||
Id = _inner.Id;
|
||||
Key = _inner.Key;
|
||||
|
||||
// TODO: ARGH! need to fix this - this is not good because it uses ApplicationContext.Current
|
||||
CreatorName = _inner.GetCreatorProfile()?.Name;
|
||||
WriterName = _inner.GetWriterProfile()?.Name;
|
||||
|
||||
// TODO: inject
|
||||
var contentType = Current.Services.ContentTypeBaseServices.GetContentTypeOf(_inner);
|
||||
ContentType = Current.PublishedContentTypeFactory.CreateContentType(contentType);
|
||||
|
||||
@@ -252,8 +253,9 @@ namespace Umbraco.Web.Macros
|
||||
if (_cultureInfos != null)
|
||||
return _cultureInfos;
|
||||
|
||||
var urlSegmentProviders = Current.UrlSegmentProviders; // TODO inject
|
||||
return _cultureInfos = _inner.PublishCultureInfos.Values
|
||||
.ToDictionary(x => x.Culture, x => new PublishedCultureInfo(x.Culture, x.Name, x.Date));
|
||||
.ToDictionary(x => x.Culture, x => new PublishedCultureInfo(x.Culture, x.Name, _inner.GetUrlSegment(urlSegmentProviders, x.Culture), x.Date));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,6 @@ namespace Umbraco.Web.Models.Mapping
|
||||
.ForMember(x => x.RedirectId, expression => expression.MapFrom(item => item.Key));
|
||||
}
|
||||
|
||||
private static string GetUrl(IUmbracoContextAccessor umbracoContextAccessor, IRedirectUrl item) => umbracoContextAccessor?.UmbracoContext?.UrlProvider?.GetUrl(item.Id, item.Culture);
|
||||
private static string GetUrl(IUmbracoContextAccessor umbracoContextAccessor, IRedirectUrl item) => umbracoContextAccessor?.UmbracoContext?.UrlProvider?.GetUrl(item.ContentId, item.Culture);
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user