Compare commits

...

64 Commits

Author SHA1 Message Date
Sebastiaan Janssen 5a07e34fb4 Bump version to 8.0.2 2019-04-26 15:15:17 +02:00
Stephan 1b5d614f5a Fix recycle bin moves
(cherry picked from commit 173df80e3d)

# Conflicts:
#	src/Umbraco.Core/Services/Implement/MediaService.cs
2019-04-26 15:03:09 +02:00
Sebastiaan Janssen abb08260eb v8: Imagepicker prevalue and grid setting/styles as infinite editor (#4971)
(cherry picked from commit f82dff597b)

# Conflicts:
#	src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js
2019-04-25 13:43:03 +02:00
Stephan 57c567c570 Fix paging error in NuCache
(cherry picked from commit 5d0010a993)
2019-04-23 14:08:19 +02:00
Stephan 424f4601ae Merge commit 'a2a247b413' into v8/8.0 2019-04-23 13:51:29 +02:00
Shannon a2a247b413 removes the enforcement of non duplicate property type aliases for now 2019-04-17 21:00:15 +10:00
Shannon 0b6a369047 When removing a property group, we need to first remove the group and then re-assign the property types so that duplicates are not added 2019-04-17 17:12:34 +10:00
Shannon 522fdefb8c Ensures that ALL membership properties are created by the installer, removes the logic that updates a membertype while fetching it, fixes the logic of mapping membership properties when fetching and they don't exist. 2019-04-17 16:42:17 +10:00
Shannon 4d8d10f07a adds comments, ignores test for now 2019-04-17 16:03:36 +10:00
Shannon 6f17129364 Make DropDownFlexibleConfiguration class public to allow configuration to be set when creating a new data type 2019-04-17 15:23:35 +10:00
Shannon 6f44e4fd09 Fixes INotifyCollectionChanged collections to raise the correct events, ensures that no duplicate property type aliases can be added/updated to 2019-04-16 17:37:42 +10:00
Shannon 02ddf80014 Adds a unit test 2019-04-16 15:39:28 +10:00
Shannon 723d9eddd1 unbreaks a ctor change preventing 8.0.2 from being dropped into the bin 2019-04-15 18:15:52 +10:00
Shannon fa655b812c Fix composers ordering 2019-04-15 17:55:22 +10:00
Shannon 576c10cd50 NuCache: fix vanishing content when refreshing content types 2019-04-15 12:56:45 +10:00
Kenn Jacobsen 179afe7e0d Add IsVisible extension on IPublishedElement 2019-04-11 17:44:16 +02:00
Shannon be7f42c454 Don't show the recycle bin in tree pickers/dialogs 2019-04-10 09:52:06 +10:00
Shannon 7e1ee26dee Fix spelling mistake 2019-04-09 10:34:59 +10:00
Stephan 1c9b449c46 Log more details about boot environment 2019-04-07 16:25:06 +02:00
Shannon e38095b727 NuCache: fix loading the media cache from local files, was missing media 2019-04-05 10:49:19 +11:00
Shannon b5796ad237 Enable configuration of NuCache BTree block size #5114 2019-04-05 10:44:36 +11:00
Stephan f985c437b5 Add content.SetValue overload for posted files 2019-04-04 09:28:34 +02:00
Andrew Deans 63fb8f5933 Fix case of query parameter 2019-04-04 09:12:40 +02:00
Shannon eb529783c4 Don't allow move in members listview 2019-04-03 16:22:13 +11:00
Shannon a8265db5f0 Reload listview after moving items 2019-04-03 10:45:04 +11:00
Shannon 7dcf2b1abb infinity editing dim-layer for umb-modelcolumn 2019-04-01 17:05:13 +11:00
Stephan 514452ddb9 Better ServerMessenger configuration 2019-04-01 16:30:37 +11:00
Stephan 1eb55a83c0 Merge branch 'patch-8.0.1' into v8/8.0 2019-03-30 12:13:12 +01:00
Stephan dfe6f2029a NuCache: better fixing, cleanup 2019-03-26 10:25:05 +01:00
Stephan 851c844c8b NuCache: fix panic exception 2019-03-26 10:25:05 +01:00
Stephan 7e413ed406 NuCache: troubleshooting 2019-03-26 10:25:05 +01:00
Stephan c56b8863ee NuCache: reorg some classes 2019-03-26 10:25:05 +01:00
Stephan 13a8548d3a NuCache: rename things 2019-03-26 10:25:05 +01:00
Stephan a70cb51559 NuCache: cleanup scoped objects 2019-03-26 10:25:05 +01:00
Kenn Jacobsen 8a56b3db16 Fix the "Language" dropdown in the "Culture and Hostnames" dialog 2019-03-26 20:10:50 +11:00
Bjarke Berg 4fcf2ce7bd Fixed issue when creating variant content templates, but the properties is invariant. Before this change an exception was thrown 2019-03-26 20:10:03 +11:00
Shannon 080ace90b2 Bugfix: https://github.com/umbraco/Umbraco-CMS/issues/4827 - Fixed MediaPickerValueConverter when config is Only Images 2019-03-26 20:09:12 +11:00
Shannon 2bfa81c707 fixes 4627 + makes front-end validations appear as soon as they are invalid again. 2019-03-26 20:07:42 +11:00
Sebastiaan Janssen 44cb5fd96b Apparently the highest minClientVersion allowed is 4.1.0 for now - see https://github.com/NuGet/NuGetGallery/blob/master/src/NuGetGallery/GalleryConstants.cs#L36 2019-03-19 09:24:41 +01:00
Robert b0b987f9cd Merge pull request #4710 from umbraco/temp8-4708-fix-for-exit-preview-with-null-culture
Fix for exit preview with null culture

(cherry picked from commit 9b25cdaa14)
2019-03-14 13:21:28 +01:00
Sebastiaan Janssen 3961e2533d Fix JS unit tests 2019-03-11 15:50:16 +01:00
Stephan b46f842400 Do not inject IEnumerable but Collection in UmbracoContextFactory
(cherry picked from commit 7e67bbea13)
2019-03-11 15:41:40 +01:00
Kenn Jacobsen 930acfeb68 Show the content app for media folders with content properties
(cherry picked from commit 9062b400d4)
2019-03-11 14:58:13 +01:00
Shannon b004c616ad Removes faulty CustomRouteUrlProvider
(cherry picked from commit 52beb01110)
2019-03-11 14:54:43 +01:00
Sebastiaan Janssen 9d64c4e551 Bugfix CoreRuntime
(cherry picked from commit 2209b37a4a and 7f31ddc250)
2019-03-11 14:45:48 +01:00
Sebastiaan Janssen 9a0aacd45a Upgrade to ModelsBuilder 8.0.2, support Custom Tool (#4881)
* Upgrade to ModelsBuilder 8.0.2, support Custom Tool

* Upgrade to ModelsBuilder 8.0.3

* Fix controllers

* Upgrade MB

* Fix previous commit

(cherry picked from commit c85c055424)
2019-03-11 14:37:59 +01:00
Kenn Jacobsen 29ff7bc340 Handle checkbox value conversion from Nested Content
(cherry picked from commit 2352b50d97)
2019-03-08 15:09:54 +01:00
Shannon 39a97fb768 Enable adding api controllers 2019-03-07 19:09:13 +11:00
Kenn Jacobsen 0852bd90d0 Always update URLs on save no matter which app is active
(cherry picked from commit 869d088e4b)
2019-03-06 17:26:36 +01:00
Niels Lyngsø e28365a0e5 hack for not using scope() in grid redordering
(cherry picked from commit a67163fd03)
2019-03-06 16:58:57 +01:00
Sebastiaan Janssen 0d16c79d0c Require higher NuGet version so we don't target VS15 any more (unsupported)
Making backups before we upgrade is no longer needed, removed from install.ps1
If people include the bin folder in their solution they will get errors upgrading now, we shouldn't need to try and fix this, there's no reason to include the bin folder in the solution - therefore install.core.ps1 is removed

(cherry picked from commit 82b78c7530)
2019-03-06 14:57:53 +01:00
Sebastiaan Janssen 7cc8983a25 Fix NuCache url segments
(cherry picked from commits 7a0f11bc6f and cfa94b1bb8)
2019-03-06 10:25:21 +01:00
Shannon e7f8baeca4 fixed correct destination url instead of #. 2019-03-05 16:14:06 +11:00
Stephan e716d14a0a Fix distributed cache handler for medias (#4751)
(cherry picked from commit 31b293aa4d)
2019-03-04 16:51:15 +01:00
Robert Foster 4c6a742007 Changed all references of umbracoUseSSL to Umbraco.Core.UseHttps to fix issue #4749
(cherry picked from commit 5aa38c1f43)
2019-03-04 15:33:08 +01:00
Sebastiaan Janssen 410241b61d 4766 fixed up other instances where nodeSelectHandler was being passed incorrect number of arguments
(cherry picked from commit 553bf6d304 and 4503967778)
2019-03-04 15:13:30 +01:00
Kenn Jacobsen 4e47fa9a70 Fix the "selected" checkmark in tree picker search results
(cherry picked from commit 09dc908332)
2019-03-04 15:10:55 +01:00
Robert Foster 9c5fb1fead Fix for Content App badges not being displayed (#4787)
(cherry picked from commit 055f983cbf)
2019-03-04 15:10:09 +01:00
Sebastiaan Janssen dc41db5fc1 Bumps version to 8.0.1 2019-03-04 15:08:23 +01:00
Sebastiaan Janssen 11b6a98df8 Bugfix exception during install, live models collision
(cherry picked from commit aa86dfa956)
2019-03-04 15:05:17 +01:00
Sebastiaan Janssen da9fc1e147 Make it possible to upload the same file twice or more (#4755)
(cherry picked from commit b5bda772af)
2019-03-04 15:04:27 +01:00
Sebastiaan Janssen 319c75757a Bugfix: Don't use ToString :'(
(cherry picked from commit ed6d54e64a)
2019-03-04 15:01:54 +01:00
Pete Duncanson 6e81e57c8e Removed System.Web.WebPages reference in nonodes.aspx as was failing a clean build
(cherry picked from commit f1d1c95709)
2019-03-04 14:58:05 +01:00
Sebastiaan Janssen 9ebe282ba6 Ensure we dont double insert
(cherry picked from commit 578eb8b32c and b86e7dc0e8)
2019-03-04 14:57:13 +01:00
133 changed files with 1868 additions and 1271 deletions
+1 -1
View File
@@ -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 -1
View File
@@ -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>
+2 -2
View File
@@ -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)" />
+46 -36
View File
@@ -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" />
-93
View File
@@ -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 }
}
}
-27
View File
@@ -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
View File
@@ -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);
}
+95 -38
View File
@@ -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>();
+1 -2
View File
@@ -8,7 +8,6 @@
/// <summary>
/// Compose.
/// </summary>
/// <param name="composition"></param>
void Compose(Composition composition);
}
}
}
+2 -4
View File
@@ -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
{ }
}
+2 -2
View File
@@ -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);
}
}
}
+22
View File
@@ -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>
+11 -5
View File
@@ -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;
+17
View File
@@ -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>();
}
}
}
+19 -3
View File
@@ -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();
}
}
}
}
@@ -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;
}
@@ -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)
{
+9 -3
View File
@@ -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;
+5 -3
View File
@@ -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
+214 -28
View File
@@ -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
+43 -9
View File
@@ -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>()))
@@ -344,8 +344,8 @@
loadAuditTrail(true);
loadRedirectUrls();
setNodePublishStatus();
updateCurrentUrls();
}
updateCurrentUrls();
});
//ensure to unregister from all events!
@@ -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);
@@ -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 () {
@@ -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>
@@ -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;
};
@@ -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
+3 -3
View File
@@ -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