Modifying a row configuration name will result in loss of
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/multiurlpicker/multiurlpicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/multiurlpicker/multiurlpicker.controller.js
index cfad66456d..1b8d60601f 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/multiurlpicker/multiurlpicker.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/multiurlpicker/multiurlpicker.controller.js
@@ -58,6 +58,8 @@ function multiUrlPickerController($scope, localizationService, entityResource, i
$scope.multiUrlPickerForm.maxCount.$setValidity("maxCount", true);
}
$scope.sortableOptions.disabled = $scope.renderModel.length === 1;
+ //Update value
+ $scope.model.value = $scope.renderModel;
}
);
diff --git a/src/Umbraco.Web/Compose/BlockEditorComponent.cs b/src/Umbraco.Web/Compose/BlockEditorComponent.cs
index a8b4cfb8ca..ac92aa6918 100644
--- a/src/Umbraco.Web/Compose/BlockEditorComponent.cs
+++ b/src/Umbraco.Web/Compose/BlockEditorComponent.cs
@@ -5,6 +5,7 @@ using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Umbraco.Core;
using Umbraco.Core.Composing;
+using Umbraco.Core.Logging;
using Umbraco.Core.Models.Blocks;
using Umbraco.Core.PropertyEditors;
@@ -17,6 +18,17 @@ namespace Umbraco.Web.Compose
{
private ComplexPropertyEditorContentEventHandler _handler;
private readonly BlockListEditorDataConverter _converter = new BlockListEditorDataConverter();
+ private readonly ILogger _logger;
+
+ [Obsolete("Use the ctor injecting dependencies.")]
+ public BlockEditorComponent() : this(Current.Logger)
+ {
+ }
+
+ public BlockEditorComponent(ILogger logger)
+ {
+ _logger = logger;
+ }
public void Initialize()
{
@@ -116,8 +128,23 @@ namespace Umbraco.Web.Compose
// this gets a little ugly because there could be some other complex editor that contains another block editor
// and since we would have no idea how to parse that, all we can do is try JSON Path to find another block editor
// of our type
- var json = JToken.Parse(asString);
- if (ProcessJToken(json, createGuid, out var result))
+ JToken json = null;
+ try
+ {
+ json = JToken.Parse(asString);
+ }
+ catch (Exception e)
+ {
+ // See issue https://github.com/umbraco/Umbraco-CMS/issues/10879
+ // We are detecting JSON data by seeing if a string is surrounded by [] or {}
+ // If people enter text like [PLACEHOLDER] JToken parsing fails, it's safe to ignore though
+ // Logging this just in case in the future we find values that are not safe to ignore
+ _logger.Warn(
+ "The property {PropertyAlias} on content type {ContentTypeKey} has a value of: {BlockItemValue} - this was recognized as JSON but could not be parsed",
+ data.Key, propertyAliasToBlockItemData.Key, asString);
+ }
+
+ if (json != null && ProcessJToken(json, createGuid, out var result))
{
// need to re-save this back to the RawPropertyValues
data.RawPropertyValues[propertyAliasToBlockItemData.Key] = result;
diff --git a/src/Umbraco.Web/HealthCheck/Checks/Security/HttpsCheck.cs b/src/Umbraco.Web/HealthCheck/Checks/Security/HttpsCheck.cs
index 18d27ba028..15906af96a 100644
--- a/src/Umbraco.Web/HealthCheck/Checks/Security/HttpsCheck.cs
+++ b/src/Umbraco.Web/HealthCheck/Checks/Security/HttpsCheck.cs
@@ -92,24 +92,26 @@ namespace Umbraco.Web.HealthCheck.Checks.Security
// Hat-tip: https://stackoverflow.com/a/15343898/489433
const int NumberOfDaysForExpiryWarning = 14;
var cert = request.ServicePoint.Certificate;
- var cert2 = new X509Certificate2(cert);
- var expirationDate = cert2.NotAfter;
+ using (var cert2 = new X509Certificate2(cert))
+ {
+ var expirationDate = cert2.NotAfter;
- var daysToExpiry = (int)Math.Floor((cert2.NotAfter - DateTime.Now).TotalDays);
- if (daysToExpiry <= 0)
- {
- result = StatusResultType.Error;
- message = _textService.Localize("healthcheck", "httpsCheckExpiredCertificate");
- }
- else if (daysToExpiry < NumberOfDaysForExpiryWarning)
- {
- result = StatusResultType.Warning;
- message = _textService.Localize("healthcheck", "httpsCheckExpiringCertificate", new[] { daysToExpiry.ToString() });
- }
- else
- {
- result = StatusResultType.Success;
- message = _textService.Localize("healthcheck", "httpsCheckValidCertificate");
+ var daysToExpiry = (int)Math.Floor((cert2.NotAfter - DateTime.Now).TotalDays);
+ if (daysToExpiry <= 0)
+ {
+ result = StatusResultType.Error;
+ message = _textService.Localize("healthcheck", "httpsCheckExpiredCertificate");
+ }
+ else if (daysToExpiry < NumberOfDaysForExpiryWarning)
+ {
+ result = StatusResultType.Warning;
+ message = _textService.Localize("healthcheck", "httpsCheckExpiringCertificate", new[] { daysToExpiry.ToString() });
+ }
+ else
+ {
+ result = StatusResultType.Success;
+ message = _textService.Localize("healthcheck", "httpsCheckValidCertificate");
+ }
}
}
else
diff --git a/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs b/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs
index 73d06db12b..7a07dcf051 100644
--- a/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs
+++ b/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs
@@ -347,28 +347,6 @@ namespace Umbraco.Web.PublishedCache.NuCache
return path;
}
- private void DeleteLocalFilesForContent()
- {
- if (_isReady && _localContentDb != null)
- throw new InvalidOperationException("Cannot delete local files while the cache uses them.");
-
- var path = GetLocalFilesPath();
- var localContentDbPath = Path.Combine(path, "NuCache.Content.db");
- if (File.Exists(localContentDbPath))
- File.Delete(localContentDbPath);
- }
-
- private void DeleteLocalFilesForMedia()
- {
- if (_isReady && _localMediaDb != null)
- throw new InvalidOperationException("Cannot delete local files while the cache uses them.");
-
- var path = GetLocalFilesPath();
- var localMediaDbPath = Path.Combine(path, "NuCache.Media.db");
- if (File.Exists(localMediaDbPath))
- File.Delete(localMediaDbPath);
- }
-
#endregion
#region Environment
@@ -660,38 +638,13 @@ namespace Umbraco.Web.PublishedCache.NuCache
#region Handle Notifications
- // note: if the service is not ready, ie _isReady is false, then notifications are ignored
-
- // SetUmbracoVersionStep issues a DistributedCache.Instance.RefreshAll...() call which should cause
- // the entire content, media etc caches to reload from database -- and then the app restarts -- however,
- // at the time SetUmbracoVersionStep runs, Umbraco is not fully initialized and therefore some property
- // value converters, etc are not registered, and rebuilding the NuCache may not work properly.
- //
- // More details: ApplicationContext.IsConfigured being false, ApplicationEventHandler.ExecuteWhen... is
- // called and in most cases events are skipped, so property value converters are not registered or
- // removed, so PublishedPropertyType either initializes with the wrong converter, or throws because it
- // detects more than one converter for a property type.
- //
- // It's not an issue for XmlStore - the app restart takes place *after* the install has refreshed the
- // cache, and XmlStore just writes a new umbraco.config file upon RefreshAll, so that's OK.
- //
- // But for NuCache... we cannot rebuild the cache now. So it will NOT work and we are not fixing it,
- // because now we should ALWAYS run with the database server messenger, and then the RefreshAll will
- // be processed as soon as we are configured and the messenger processes instructions.
-
// note: notifications for content type and data type changes should be invoked with the
// pure live model factory, if any, locked and refreshed - see ContentTypeCacheRefresher and
// DataTypeCacheRefresher
public override void Notify(ContentCacheRefresher.JsonPayload[] payloads, out bool draftChanged, out bool publishedChanged)
{
- // no cache, trash everything
- if (_isReady == false)
- {
- DeleteLocalFilesForContent();
- draftChanged = publishedChanged = true;
- return;
- }
+ EnsureCaches();
using (_contentStore.GetScopedWriteLock(_scopeProvider))
{
@@ -785,13 +738,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
///
public override void Notify(MediaCacheRefresher.JsonPayload[] payloads, out bool anythingChanged)
{
- // no cache, trash everything
- if (_isReady == false)
- {
- DeleteLocalFilesForMedia();
- anythingChanged = true;
- return;
- }
+ EnsureCaches();
using (_mediaStore.GetScopedWriteLock(_scopeProvider))
{
@@ -878,9 +825,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
///
public override void Notify(ContentTypeCacheRefresher.JsonPayload[] payloads)
{
- // no cache, nothing we can do
- if (_isReady == false)
- return;
+ EnsureCaches();
foreach (var payload in payloads)
_logger.Debug("Notified {ChangeTypes} for {ItemType} {ItemId}", payload.ChangeTypes, payload.ItemType, payload.Id);
@@ -960,9 +905,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
public override void Notify(DataTypeCacheRefresher.JsonPayload[] payloads)
{
- // no cache, nothing we can do
- if (_isReady == false)
- return;
+ EnsureCaches();
var idsA = payloads.Select(x => x.Id).ToArray();
@@ -1000,9 +943,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
public override void Notify(DomainCacheRefresher.JsonPayload[] payloads)
{
- // no cache, nothing we can do
- if (_isReady == false)
- return;
+ EnsureCaches();
// see note in LockAndLoadContent
using (_domainStore.GetScopedWriteLock(_scopeProvider))