From 5798d8e57b223e9dfb7128a4d8cff64bea8a669c Mon Sep 17 00:00:00 2001 From: Stephan Date: Thu, 3 May 2018 11:27:08 +0200 Subject: [PATCH 01/15] Enable src/preserve.belle to stop rebuilding Belle all the time --- .gitignore | 3 +++ src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 5 +++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 9f22544f35..6c180fa693 100644 --- a/.gitignore +++ b/.gitignore @@ -121,6 +121,9 @@ src/Umbraco.Web.UI.Client/bower_components/* /src/Umbraco.Web.UI/Umbraco/preview /src/Umbraco.Web.UI/Umbraco/preview.old +# ignore rule for clearing out Belle (avoid rebuilding all the time) +preserve.belle + #Ignore Rule for output of generated documentation files from Grunt docserve src/Umbraco.Web.UI.Client/docs/api src/*.boltdata/ diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index e03c3b4b41..a27f65620d 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -656,11 +656,12 @@ - + + - + From 41144bb7f7a30308f53968b80e540a9d38dd5ce7 Mon Sep 17 00:00:00 2001 From: Stephan Date: Thu, 3 May 2018 14:13:53 +0200 Subject: [PATCH 02/15] Fix references and build --- build/NuSpecs/UmbracoCms.Core.nuspec | 2 +- src/Umbraco.Core/Umbraco.Core.csproj | 3 +-- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 2 +- src/Umbraco.Web/Umbraco.Web.csproj | 2 -- 4 files changed, 3 insertions(+), 6 deletions(-) diff --git a/build/NuSpecs/UmbracoCms.Core.nuspec b/build/NuSpecs/UmbracoCms.Core.nuspec index d06b5e7136..5e836f602b 100644 --- a/build/NuSpecs/UmbracoCms.Core.nuspec +++ b/build/NuSpecs/UmbracoCms.Core.nuspec @@ -43,7 +43,7 @@ - + diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 456d7d667a..260f185607 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -47,7 +47,6 @@ - @@ -74,7 +73,7 @@ - + diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index a27f65620d..63348ecb9a 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -121,7 +121,7 @@ - + diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index d589c06bdd..86d20ca440 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -51,8 +51,6 @@ - - From d04a5738881bd09e16b2e864061ff0db1d323fc3 Mon Sep 17 00:00:00 2001 From: Stephan Date: Thu, 3 May 2018 14:50:21 +0200 Subject: [PATCH 03/15] Refactor some locks, get rid of warnings --- .../Cache/DictionaryCacheProviderBase.cs | 86 +++++++++++++++---- .../Cache/HttpRequestCacheProvider.cs | 35 +++++--- .../Cache/HttpRuntimeCacheProvider.cs | 36 ++++++-- .../Cache/ObjectCacheRuntimeCacheProvider.cs | 80 ++++++++++++++--- .../Collections/ConcurrentHashSet.cs | 41 +++++++-- .../Models/PropertyGroupCollection.cs | 9 +- .../Models/PropertyTypeCollection.cs | 8 +- .../Persistence/UmbracoDatabaseFactory.cs | 9 +- src/Umbraco.Core/ReadLock.cs | 6 +- src/Umbraco.Core/Umbraco.Core.csproj | 2 +- src/Umbraco.Core/WriteLock.cs | 6 +- 11 files changed, 260 insertions(+), 58 deletions(-) diff --git a/src/Umbraco.Core/Cache/DictionaryCacheProviderBase.cs b/src/Umbraco.Core/Cache/DictionaryCacheProviderBase.cs index 6baa2cf0ed..9da202b5aa 100644 --- a/src/Umbraco.Core/Cache/DictionaryCacheProviderBase.cs +++ b/src/Umbraco.Core/Cache/DictionaryCacheProviderBase.cs @@ -24,8 +24,13 @@ namespace Umbraco.Core.Cache protected abstract object GetEntry(string key); // read-write lock the underlying cache - protected abstract IDisposable ReadLock { get; } - protected abstract IDisposable WriteLock { get; } + //protected abstract IDisposable ReadLock { get; } + //protected abstract IDisposable WriteLock { get; } + + protected abstract void EnterReadLock(); + protected abstract void ExitReadLock(); + protected abstract void EnterWriteLock(); + protected abstract void ExitWriteLock(); protected string GetCacheKey(string key) { @@ -88,21 +93,31 @@ namespace Umbraco.Core.Cache public virtual void ClearAllCache() { - using (WriteLock) + try { + EnterWriteLock(); foreach (var entry in GetDictionaryEntries() .ToArray()) RemoveEntry((string) entry.Key); } + finally + { + ExitWriteLock(); + } } public virtual void ClearCacheItem(string key) { var cacheKey = GetCacheKey(key); - using (WriteLock) + try { + EnterWriteLock(); RemoveEntry(cacheKey); } + finally + { + ExitWriteLock(); + } } public virtual void ClearCacheObjectTypes(string typeName) @@ -110,15 +125,16 @@ namespace Umbraco.Core.Cache var type = TypeFinder.GetTypeByName(typeName); if (type == null) return; var isInterface = type.IsInterface; - using (WriteLock) + try { + EnterWriteLock(); foreach (var entry in GetDictionaryEntries() .Where(x => { // entry.Value is Lazy and not null, its value may be null // remove null values as well, does not hurt // get non-created as NonCreatedValue & exceptions as null - var value = GetSafeLazyValue((Lazy)x.Value, true); + var value = GetSafeLazyValue((Lazy) x.Value, true); // if T is an interface remove anything that implements that interface // otherwise remove exact types (not inherited types) @@ -127,14 +143,19 @@ namespace Umbraco.Core.Cache .ToArray()) RemoveEntry((string) entry.Key); } + finally + { + ExitWriteLock(); + } } public virtual void ClearCacheObjectTypes() { var typeOfT = typeof(T); var isInterface = typeOfT.IsInterface; - using (WriteLock) + try { + EnterWriteLock(); foreach (var entry in GetDictionaryEntries() .Where(x => { @@ -142,7 +163,7 @@ namespace Umbraco.Core.Cache // remove null values as well, does not hurt // compare on exact type, don't use "is" // get non-created as NonCreatedValue & exceptions as null - var value = GetSafeLazyValue((Lazy)x.Value, true); + var value = GetSafeLazyValue((Lazy) x.Value, true); // if T is an interface remove anything that implements that interface // otherwise remove exact types (not inherited types) @@ -151,6 +172,10 @@ namespace Umbraco.Core.Cache .ToArray()) RemoveEntry((string) entry.Key); } + finally + { + ExitWriteLock(); + } } public virtual void ClearCacheObjectTypes(Func predicate) @@ -158,8 +183,9 @@ namespace Umbraco.Core.Cache var typeOfT = typeof(T); var isInterface = typeOfT.IsInterface; var plen = CacheItemPrefix.Length + 1; - using (WriteLock) + try { + EnterWriteLock(); foreach (var entry in GetDictionaryEntries() .Where(x => { @@ -167,7 +193,7 @@ namespace Umbraco.Core.Cache // remove null values as well, does not hurt // compare on exact type, don't use "is" // get non-created as NonCreatedValue & exceptions as null - var value = GetSafeLazyValue((Lazy)x.Value, true); + var value = GetSafeLazyValue((Lazy) x.Value, true); if (value == null) return true; // if T is an interface remove anything that implements that interface @@ -178,30 +204,44 @@ namespace Umbraco.Core.Cache })) RemoveEntry((string) entry.Key); } + finally + { + ExitWriteLock(); + } } public virtual void ClearCacheByKeySearch(string keyStartsWith) { var plen = CacheItemPrefix.Length + 1; - using (WriteLock) + try { + EnterWriteLock(); foreach (var entry in GetDictionaryEntries() .Where(x => ((string)x.Key).Substring(plen).InvariantStartsWith(keyStartsWith)) .ToArray()) RemoveEntry((string) entry.Key); } + finally + { + ExitWriteLock(); + } } public virtual void ClearCacheByKeyExpression(string regexString) { var plen = CacheItemPrefix.Length + 1; - using (WriteLock) + try { + EnterWriteLock(); foreach (var entry in GetDictionaryEntries() .Where(x => Regex.IsMatch(((string)x.Key).Substring(plen), regexString)) .ToArray()) RemoveEntry((string) entry.Key); } + finally + { + ExitWriteLock(); + } } #endregion @@ -212,12 +252,18 @@ namespace Umbraco.Core.Cache { var plen = CacheItemPrefix.Length + 1; IEnumerable entries; - using (ReadLock) + try { + EnterReadLock(); entries = GetDictionaryEntries() .Where(x => ((string)x.Key).Substring(plen).InvariantStartsWith(keyStartsWith)) .ToArray(); // evaluate while locked } + finally + { + ExitReadLock(); + } + return entries .Select(x => GetSafeLazyValue((Lazy)x.Value)) // return exceptions as null .Where(x => x != null); // backward compat, don't store null values in the cache @@ -228,12 +274,17 @@ namespace Umbraco.Core.Cache const string prefix = CacheItemPrefix + "-"; var plen = prefix.Length; IEnumerable entries; - using (ReadLock) + try { + EnterReadLock(); entries = GetDictionaryEntries() .Where(x => Regex.IsMatch(((string)x.Key).Substring(plen), regexString)) .ToArray(); // evaluate while locked } + finally + { + ExitReadLock(); + } return entries .Select(x => GetSafeLazyValue((Lazy)x.Value)) // return exceptions as null .Where(x => x != null); // backward compat, don't store null values in the cache @@ -243,10 +294,15 @@ namespace Umbraco.Core.Cache { cacheKey = GetCacheKey(cacheKey); Lazy result; - using (ReadLock) + try { + EnterReadLock(); result = GetEntry(cacheKey) as Lazy; // null if key not found } + finally + { + ExitReadLock(); + } return result == null ? null : GetSafeLazyValue(result); // return exceptions as null } diff --git a/src/Umbraco.Core/Cache/HttpRequestCacheProvider.cs b/src/Umbraco.Core/Cache/HttpRequestCacheProvider.cs index 6f97651042..5554655d83 100644 --- a/src/Umbraco.Core/Cache/HttpRequestCacheProvider.cs +++ b/src/Umbraco.Core/Cache/HttpRequestCacheProvider.cs @@ -79,24 +79,26 @@ namespace Umbraco.Core.Cache #region Lock - protected override IDisposable ReadLock + private bool _entered; + + protected override void EnterReadLock() => EnterWriteLock(); + + protected override void EnterWriteLock() { - // there's no difference between ReadLock and WriteLock here - get { return WriteLock; } + if (HasContextItems) + { + System.Threading.Monitor.Enter(ContextItems.SyncRoot, ref _entered); + } } - protected override IDisposable WriteLock - { - // NOTE - // could think about just overriding base.Locker to return a different - // object but then we'd create a ReaderWriterLockSlim per request, - // which is less efficient than just using a basic monitor lock. + protected override void ExitReadLock() => ExitWriteLock(); - get + protected override void ExitWriteLock() + { + if (_entered) { - return HasContextItems - ? (IDisposable) new MonitorLock(ContextItems.SyncRoot) - : new NoopLocker(); + _entered = false; + System.Threading.Monitor.Exit(ContextItems.SyncRoot); } } @@ -113,8 +115,9 @@ namespace Umbraco.Core.Cache Lazy result; - using (WriteLock) + try { + EnterWriteLock(); result = ContextItems[cacheKey] as Lazy; // null if key not found // cannot create value within the lock, so if result.IsValueCreated is false, just @@ -127,6 +130,10 @@ namespace Umbraco.Core.Cache ContextItems[cacheKey] = result; } } + finally + { + ExitWriteLock(); + } // using GetSafeLazy and GetSafeLazyValue ensures that we don't cache // exceptions (but try again and again) and silently eat them - however at diff --git a/src/Umbraco.Core/Cache/HttpRuntimeCacheProvider.cs b/src/Umbraco.Core/Cache/HttpRuntimeCacheProvider.cs index ad46201c0c..068bf3605e 100644 --- a/src/Umbraco.Core/Cache/HttpRuntimeCacheProvider.cs +++ b/src/Umbraco.Core/Cache/HttpRuntimeCacheProvider.cs @@ -50,14 +50,26 @@ namespace Umbraco.Core.Cache #region Lock - protected override IDisposable ReadLock + protected override void EnterReadLock() { - get { return new ReadLock(_locker); } + _locker.EnterReadLock(); } - protected override IDisposable WriteLock + protected override void EnterWriteLock() { - get { return new WriteLock(_locker); } + _locker.EnterWriteLock();; + } + + protected override void ExitReadLock() + { + if (_locker.IsReadLockHeld) + _locker.ExitReadLock(); + } + + protected override void ExitWriteLock() + { + if (_locker.IsWriteLockHeld) + _locker.ExitWriteLock(); } #endregion @@ -118,10 +130,16 @@ namespace Umbraco.Core.Cache // reads. We first try with a normal ReadLock for maximum concurrency and take the penalty of // having to re-lock in case there's no value. Would need to benchmark to figure out whether // it's worth it, though... - using (new ReadLock(_locker)) + try { + _locker.EnterReadLock(); result = _cache.Get(cacheKey) as Lazy; // null if key not found } + finally + { + if (_locker.IsReadLockHeld) + _locker.ExitReadLock(); + } var value = result == null ? null : GetSafeLazyValue(result); if (value != null) return value; @@ -195,11 +213,17 @@ namespace Umbraco.Core.Cache var absolute = isSliding ? System.Web.Caching.Cache.NoAbsoluteExpiration : (timeout == null ? System.Web.Caching.Cache.NoAbsoluteExpiration : DateTime.Now.Add(timeout.Value)); var sliding = isSliding == false ? System.Web.Caching.Cache.NoSlidingExpiration : (timeout ?? System.Web.Caching.Cache.NoSlidingExpiration); - using (new WriteLock(_locker)) + try { + _locker.EnterWriteLock(); //NOTE: 'Insert' on System.Web.Caching.Cache actually does an add or update! _cache.Insert(cacheKey, result, dependency, absolute, sliding, priority, removedCallback); } + finally + { + if (_locker.IsWriteLockHeld) + _locker.ExitWriteLock(); + } } public void InsertCacheItem(string cacheKey, Func getCacheItem, TimeSpan? timeout = null, bool isSliding = false, CacheItemPriority priority = CacheItemPriority.Normal, CacheItemRemovedCallback removedCallback = null, string[] dependentFiles = null) diff --git a/src/Umbraco.Core/Cache/ObjectCacheRuntimeCacheProvider.cs b/src/Umbraco.Core/Cache/ObjectCacheRuntimeCacheProvider.cs index 70e37addb8..b3a643dbfb 100644 --- a/src/Umbraco.Core/Cache/ObjectCacheRuntimeCacheProvider.cs +++ b/src/Umbraco.Core/Cache/ObjectCacheRuntimeCacheProvider.cs @@ -37,20 +37,32 @@ namespace Umbraco.Core.Cache public virtual void ClearAllCache() { - using (new WriteLock(_locker)) + try { + _locker.EnterWriteLock(); MemoryCache.DisposeIfDisposable(); MemoryCache = new MemoryCache("in-memory"); } + finally + { + if (_locker.IsWriteLockHeld) + _locker.ExitWriteLock(); + } } public virtual void ClearCacheItem(string key) { - using (new WriteLock(_locker)) + try { + _locker.EnterWriteLock(); if (MemoryCache[key] == null) return; MemoryCache.Remove(key); } + finally + { + if (_locker.IsWriteLockHeld) + _locker.ExitWriteLock(); + } } public virtual void ClearCacheObjectTypes(string typeName) @@ -58,8 +70,9 @@ namespace Umbraco.Core.Cache var type = TypeFinder.GetTypeByName(typeName); if (type == null) return; var isInterface = type.IsInterface; - using (new WriteLock(_locker)) + try { + _locker.EnterWriteLock(); foreach (var key in MemoryCache .Where(x => { @@ -76,12 +89,18 @@ namespace Umbraco.Core.Cache .ToArray()) // ToArray required to remove MemoryCache.Remove(key); } + finally + { + if (_locker.IsWriteLockHeld) + _locker.ExitWriteLock(); + } } public virtual void ClearCacheObjectTypes() { - using (new WriteLock(_locker)) + try { + _locker.EnterWriteLock(); var typeOfT = typeof (T); var isInterface = typeOfT.IsInterface; foreach (var key in MemoryCache @@ -101,12 +120,18 @@ namespace Umbraco.Core.Cache .ToArray()) // ToArray required to remove MemoryCache.Remove(key); } + finally + { + if (_locker.IsWriteLockHeld) + _locker.ExitWriteLock(); + } } public virtual void ClearCacheObjectTypes(Func predicate) { - using (new WriteLock(_locker)) + try { + _locker.EnterWriteLock(); var typeOfT = typeof(T); var isInterface = typeOfT.IsInterface; foreach (var key in MemoryCache @@ -127,30 +152,47 @@ namespace Umbraco.Core.Cache .ToArray()) // ToArray required to remove MemoryCache.Remove(key); } + finally + { + if (_locker.IsWriteLockHeld) + _locker.ExitWriteLock(); + } } public virtual void ClearCacheByKeySearch(string keyStartsWith) { - using (new WriteLock(_locker)) + try { + _locker.EnterWriteLock(); foreach (var key in MemoryCache .Where(x => x.Key.InvariantStartsWith(keyStartsWith)) .Select(x => x.Key) .ToArray()) // ToArray required to remove MemoryCache.Remove(key); } + finally + { + if (_locker.IsWriteLockHeld) + _locker.ExitWriteLock(); + } } public virtual void ClearCacheByKeyExpression(string regexString) { - using (new WriteLock(_locker)) + try { + _locker.EnterWriteLock(); foreach (var key in MemoryCache .Where(x => Regex.IsMatch(x.Key, regexString)) .Select(x => x.Key) .ToArray()) // ToArray required to remove MemoryCache.Remove(key); } + finally + { + if (_locker.IsWriteLockHeld) + _locker.ExitWriteLock(); + } } #endregion @@ -160,12 +202,18 @@ namespace Umbraco.Core.Cache public IEnumerable GetCacheItemsByKeySearch(string keyStartsWith) { KeyValuePair[] entries; - using (new ReadLock(_locker)) + try { + _locker.EnterReadLock(); entries = MemoryCache .Where(x => x.Key.InvariantStartsWith(keyStartsWith)) .ToArray(); // evaluate while locked } + finally + { + if (_locker.IsReadLockHeld) + _locker.ExitReadLock(); + } return entries .Select(x => DictionaryCacheProviderBase.GetSafeLazyValue((Lazy)x.Value)) // return exceptions as null .Where(x => x != null) // backward compat, don't store null values in the cache @@ -175,12 +223,18 @@ namespace Umbraco.Core.Cache public IEnumerable GetCacheItemsByKeyExpression(string regexString) { KeyValuePair[] entries; - using (new ReadLock(_locker)) + try { + _locker.EnterReadLock(); entries = MemoryCache .Where(x => Regex.IsMatch(x.Key, regexString)) .ToArray(); // evaluate while locked } + finally + { + if (_locker.IsReadLockHeld) + _locker.ExitReadLock(); + } return entries .Select(x => DictionaryCacheProviderBase.GetSafeLazyValue((Lazy)x.Value)) // return exceptions as null .Where(x => x != null) // backward compat, don't store null values in the cache @@ -190,10 +244,16 @@ namespace Umbraco.Core.Cache public object GetCacheItem(string cacheKey) { Lazy result; - using (new ReadLock(_locker)) + try { + _locker.EnterReadLock(); result = MemoryCache.Get(cacheKey) as Lazy; // null if key not found } + finally + { + if (_locker.IsReadLockHeld) + _locker.ExitReadLock(); + } return result == null ? null : DictionaryCacheProviderBase.GetSafeLazyValue(result); // return exceptions as null } diff --git a/src/Umbraco.Core/Collections/ConcurrentHashSet.cs b/src/Umbraco.Core/Collections/ConcurrentHashSet.cs index 39cb701e69..4cad6e9f15 100644 --- a/src/Umbraco.Core/Collections/ConcurrentHashSet.cs +++ b/src/Umbraco.Core/Collections/ConcurrentHashSet.cs @@ -50,10 +50,16 @@ namespace Umbraco.Core.Collections /// The object to remove from the .The is read-only. public bool Remove(T item) { - using (new WriteLock(_instanceLocker)) + try { + _instanceLocker.EnterWriteLock(); return _innerSet.Remove(item); } + finally + { + if (_instanceLocker.IsWriteLockHeld) + _instanceLocker.ExitWriteLock(); + } } @@ -86,10 +92,16 @@ namespace Umbraco.Core.Collections /// The object to add to the .The is read-only. public void Add(T item) { - using (new WriteLock(_instanceLocker)) + try { + _instanceLocker.EnterWriteLock(); _innerSet.Add(item); } + finally + { + if (_instanceLocker.IsWriteLockHeld) + _instanceLocker.ExitWriteLock(); + } } /// @@ -101,13 +113,20 @@ namespace Umbraco.Core.Collections { var clone = GetThreadSafeClone(); if (clone.Contains(item)) return false; - using (new WriteLock(_instanceLocker)) + try { + _instanceLocker.EnterWriteLock(); + //double check if (_innerSet.Contains(item)) return false; _innerSet.Add(item); return true; } + finally + { + if (_instanceLocker.IsWriteLockHeld) + _instanceLocker.ExitWriteLock(); + } } /// @@ -116,10 +135,16 @@ namespace Umbraco.Core.Collections /// The is read-only. public void Clear() { - using (new WriteLock(_instanceLocker)) + try { + _instanceLocker.EnterWriteLock(); _innerSet.Clear(); } + finally + { + if (_instanceLocker.IsWriteLockHeld) + _instanceLocker.ExitWriteLock(); + } } /// @@ -147,10 +172,16 @@ namespace Umbraco.Core.Collections private HashSet GetThreadSafeClone() { HashSet clone = null; - using (new WriteLock(_instanceLocker)) + try { + _instanceLocker.EnterWriteLock(); clone = new HashSet(_innerSet, _innerSet.Comparer); } + finally + { + if (_instanceLocker.IsWriteLockHeld) + _instanceLocker.ExitWriteLock(); + } return clone; } diff --git a/src/Umbraco.Core/Models/PropertyGroupCollection.cs b/src/Umbraco.Core/Models/PropertyGroupCollection.cs index abec6febcb..0083bdb502 100644 --- a/src/Umbraco.Core/Models/PropertyGroupCollection.cs +++ b/src/Umbraco.Core/Models/PropertyGroupCollection.cs @@ -67,8 +67,10 @@ namespace Umbraco.Core.Models internal new void Add(PropertyGroup item) { - using (new WriteLock(_addLocker)) + try { + _addLocker.EnterWriteLock(); + //Note this is done to ensure existig groups can be renamed if (item.HasIdentity && item.Id > 0) { @@ -102,6 +104,11 @@ namespace Umbraco.Core.Models OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item)); } + finally + { + if (_addLocker.IsWriteLockHeld) + _addLocker.ExitWriteLock(); + } } /// diff --git a/src/Umbraco.Core/Models/PropertyTypeCollection.cs b/src/Umbraco.Core/Models/PropertyTypeCollection.cs index 4788221854..dbe97248f9 100644 --- a/src/Umbraco.Core/Models/PropertyTypeCollection.cs +++ b/src/Umbraco.Core/Models/PropertyTypeCollection.cs @@ -80,8 +80,9 @@ namespace Umbraco.Core.Models item.IsPublishing = IsPublishing; // fixme redo this entirely!!! - using (new WriteLock(_addLocker)) + try { + _addLocker.EnterWriteLock(); var key = GetKeyForItem(item); if (key != null) { @@ -105,6 +106,11 @@ namespace Umbraco.Core.Models OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item)); } + finally + { + if (_addLocker.IsWriteLockHeld) + _addLocker.ExitWriteLock(); + } } /// diff --git a/src/Umbraco.Core/Persistence/UmbracoDatabaseFactory.cs b/src/Umbraco.Core/Persistence/UmbracoDatabaseFactory.cs index efe05e951d..2b82ec7fac 100644 --- a/src/Umbraco.Core/Persistence/UmbracoDatabaseFactory.cs +++ b/src/Umbraco.Core/Persistence/UmbracoDatabaseFactory.cs @@ -126,8 +126,10 @@ namespace Umbraco.Core.Persistence /// public void Configure(string connectionString, string providerName) { - using (new WriteLock(_lock)) + try { + _lock.EnterWriteLock(); + _logger.Debug("Configuring."); if (Configured) throw new InvalidOperationException("Already configured."); @@ -173,6 +175,11 @@ namespace Umbraco.Core.Persistence _logger.Debug("Configured."); Configured = true; } + finally + { + if (_lock.IsWriteLockHeld) + _lock.ExitWriteLock(); + } } /// diff --git a/src/Umbraco.Core/ReadLock.cs b/src/Umbraco.Core/ReadLock.cs index 61025721fc..6e6ecf14b8 100644 --- a/src/Umbraco.Core/ReadLock.cs +++ b/src/Umbraco.Core/ReadLock.cs @@ -10,9 +10,11 @@ namespace Umbraco.Core /// Provides a convenience methodology for implementing locked access to resources. /// /// - /// Intended as an infrastructure class. + /// Intended as an infrastructure class. + /// This is a very unefficient way to lock as it allocates one object each time we lock, + /// so it's OK to use this class for things that happen once, where it is convenient, but not + /// for performance-critical code! /// - [Obsolete("stop using, allocates")] public class ReadLock : IDisposable { private readonly ReaderWriterLockSlim _rwLock; diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 260f185607..e8a5a3654b 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -394,6 +394,7 @@ + @@ -1264,7 +1265,6 @@ - diff --git a/src/Umbraco.Core/WriteLock.cs b/src/Umbraco.Core/WriteLock.cs index b6a957234b..6ddc7e0bb3 100644 --- a/src/Umbraco.Core/WriteLock.cs +++ b/src/Umbraco.Core/WriteLock.cs @@ -10,9 +10,11 @@ namespace Umbraco.Core /// Provides a convenience methodology for implementing locked access to resources. /// /// - /// Intended as an infrastructure class. + /// Intended as an infrastructure class. + /// This is a very unefficient way to lock as it allocates one object each time we lock, + /// so it's OK to use this class for things that happen once, where it is convenient, but not + /// for performance-critical code! /// - [Obsolete("stop using, allocates")] public class WriteLock : IDisposable { private readonly ReaderWriterLockSlim _rwLock; From bcf46eceb6a9cd22c10a0c58613b365f79377674 Mon Sep 17 00:00:00 2001 From: Stephan Date: Thu, 3 May 2018 14:58:34 +0200 Subject: [PATCH 04/15] Cleanup, get rid of warnings --- .../Composing/LightInjectExtensions.cs | 18 ++++---- src/Umbraco.Core/IO/FileSystems.cs | 1 - .../Upgrade/V_8_0_0/RefactorXmlColumns.cs | 7 --- src/Umbraco.Core/Models/MediaType.cs | 2 +- .../Packaging/DefaultPackageContext.cs | 45 ------------------- src/Umbraco.Core/Packaging/IPackageContext.cs | 11 ----- .../Implement/StylesheetRepository.cs | 2 +- .../Security/MachineKeyGenerator.cs | 2 - .../Services/Implement/MemberService.cs | 3 +- .../Services/Implement/UserService.cs | 4 +- src/Umbraco.Core/StringExtensions.cs | 4 +- src/Umbraco.Core/Umbraco.Core.csproj | 2 - 12 files changed, 17 insertions(+), 84 deletions(-) delete mode 100644 src/Umbraco.Core/Packaging/DefaultPackageContext.cs delete mode 100644 src/Umbraco.Core/Packaging/IPackageContext.cs diff --git a/src/Umbraco.Core/Composing/LightInjectExtensions.cs b/src/Umbraco.Core/Composing/LightInjectExtensions.cs index c7b51404fe..68ba48c803 100644 --- a/src/Umbraco.Core/Composing/LightInjectExtensions.cs +++ b/src/Umbraco.Core/Composing/LightInjectExtensions.cs @@ -311,15 +311,15 @@ namespace Umbraco.Core.Composing // we HAVE to let LightInject throw - and catch at THE OUTERMOST if InvalidOperationException in LightInject.Anything! return factory.GetInstance(tService, serviceName, args); - try - { - return factory.GetInstance(tService, serviceName, args); - } - catch (Exception e) - { - LightInjectException.TryThrow(e, implementingType); - throw; - } + //try + //{ + // return factory.GetInstance(tService, serviceName, args); + //} + //catch (Exception e) + //{ + // LightInjectException.TryThrow(e, implementingType); + // throw; + //} } /// diff --git a/src/Umbraco.Core/IO/FileSystems.cs b/src/Umbraco.Core/IO/FileSystems.cs index 33989122b8..5d7088b0e1 100644 --- a/src/Umbraco.Core/IO/FileSystems.cs +++ b/src/Umbraco.Core/IO/FileSystems.cs @@ -28,7 +28,6 @@ namespace Umbraco.Core.IO private ShadowWrapper _scriptsFileSystem; private ShadowWrapper _masterPagesFileSystem; private ShadowWrapper _mvcViewsFileSystem; - private ShadowWrapper _javaScriptLibraryFileSystem; // well-known file systems lazy initialization private object _wkfsLock = new object(); diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/RefactorXmlColumns.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/RefactorXmlColumns.cs index 8b85d6992e..b7d869ee62 100644 --- a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/RefactorXmlColumns.cs +++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/RefactorXmlColumns.cs @@ -67,13 +67,6 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0 .Do(); } - private bool ColumnExists(string tableName, string columnName) - { - // that's ok even on MySql - var columns = SqlSyntax.GetColumnsInSchema(Context.Database).Distinct().ToArray(); - return columns.Any(x => x.TableName.InvariantEquals(tableName) && x.ColumnName.InvariantEquals(columnName)); - } - private void RemoveDuplicates() { const string sql = @"delete from cmsPreviewXml where versionId in ( diff --git a/src/Umbraco.Core/Models/MediaType.cs b/src/Umbraco.Core/Models/MediaType.cs index bc8b7c4c89..9612fce728 100644 --- a/src/Umbraco.Core/Models/MediaType.cs +++ b/src/Umbraco.Core/Models/MediaType.cs @@ -48,7 +48,7 @@ namespace Umbraco.Core.Models /// Creates a deep clone of the current entity with its identity/alias and it's property identities reset /// /// - public IMediaType DeepCloneWithResetIdentities(string alias) + public new IMediaType DeepCloneWithResetIdentities(string alias) { var clone = (MediaType)DeepClone(); clone.Alias = alias; diff --git a/src/Umbraco.Core/Packaging/DefaultPackageContext.cs b/src/Umbraco.Core/Packaging/DefaultPackageContext.cs deleted file mode 100644 index c08418ec86..0000000000 --- a/src/Umbraco.Core/Packaging/DefaultPackageContext.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; -using NuGet; -using Umbraco.Core.Configuration; - -namespace Umbraco.Core.Packaging -{ - internal class DefaultPackageContext : IPackageContext - { - public DefaultPackageContext(Func mapPath) - {} - - private readonly string _localPackageRepoFolderPath; - private readonly string _pluginInstallFolderPath; - private readonly Lazy _localPackageManager; - private readonly Lazy _localPackageRepository; - private readonly Lazy _publicPackageManager; - private readonly Lazy _privatePackageManager; - private readonly Lazy _publicPackageRepository; - private readonly Lazy _sprivatePackageRepository; - - /// - /// Gets the local path resolver. - /// - public IPackagePathResolver LocalPathResolver - { - get { return ((PackageManager)LocalPackageManager).PathResolver; } - } - - /// - /// Gets the local package manager. - /// - public IPackageManager LocalPackageManager - { - get { return _localPackageManager.Value; } - } - - /// - /// Gets the public package manager. - /// - public IPackageManager PublicPackageManager - { - get { return _publicPackageManager.Value; } - } - } -} diff --git a/src/Umbraco.Core/Packaging/IPackageContext.cs b/src/Umbraco.Core/Packaging/IPackageContext.cs deleted file mode 100644 index 41cf372ce6..0000000000 --- a/src/Umbraco.Core/Packaging/IPackageContext.cs +++ /dev/null @@ -1,11 +0,0 @@ -using NuGet; - -namespace Umbraco.Core.Packaging -{ - internal interface IPackageContext - { - IPackageManager LocalPackageManager { get; } - IPackageManager PublicPackageManager { get; } - IPackagePathResolver LocalPathResolver { get; } - } -} diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/StylesheetRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/StylesheetRepository.cs index 8a0333a965..73dcb44fef 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/StylesheetRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/StylesheetRepository.cs @@ -139,7 +139,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement FileSystem.AddFile(filepath, content, true); } - public long GetFileSize(string filepath) + public new long GetFileSize(string filepath) { if (FileSystem.FileExists(filepath) == false) return -1; diff --git a/src/Umbraco.Core/Security/MachineKeyGenerator.cs b/src/Umbraco.Core/Security/MachineKeyGenerator.cs index 283ca1ac3a..a20f04c919 100644 --- a/src/Umbraco.Core/Security/MachineKeyGenerator.cs +++ b/src/Umbraco.Core/Security/MachineKeyGenerator.cs @@ -26,8 +26,6 @@ namespace Umbraco.Core.Security validation=""HMACSHA256"" decryption=""AES"" />"; - var Xxx = 3; - return string.Format(c, GenerateAESDecryptionKey(), GenerateHMACSHA256ValidationKey()); } diff --git a/src/Umbraco.Core/Services/Implement/MemberService.cs b/src/Umbraco.Core/Services/Implement/MemberService.cs index f8245f18c2..ca2b39dee2 100644 --- a/src/Umbraco.Core/Services/Implement/MemberService.cs +++ b/src/Umbraco.Core/Services/Implement/MemberService.cs @@ -186,8 +186,9 @@ namespace Umbraco.Core.Services.Implement /// Email of the to create /// This value should be the encoded/encrypted/hashed value for the password that will be stored in the database /// Alias of the Type + /// /// - IMember IMembershipMemberService.CreateWithIdentity(string username, string email, string passwordValue, string memberTypeAlias, bool isApproved = true) + IMember IMembershipMemberService.CreateWithIdentity(string username, string email, string passwordValue, string memberTypeAlias, bool isApproved) { return CreateMemberWithIdentity(username, email, username, passwordValue, memberTypeAlias, isApproved); } diff --git a/src/Umbraco.Core/Services/Implement/UserService.cs b/src/Umbraco.Core/Services/Implement/UserService.cs index 4b27fb5c51..96cac1d814 100644 --- a/src/Umbraco.Core/Services/Implement/UserService.cs +++ b/src/Umbraco.Core/Services/Implement/UserService.cs @@ -198,7 +198,7 @@ namespace Umbraco.Core.Services.Implement { return _userRepository.GetByUsername(username, includeSecurityData: true); } - catch (DbException ex) + catch (DbException) { // fixme - refactor users/upgrade // currently kinda accepting anything on upgrade, but that won't deal with all cases @@ -727,7 +727,7 @@ namespace Umbraco.Core.Services.Implement { return _userRepository.Get(id); } - catch (DbException ex) + catch (DbException) { // fixme - refactor users/upgrade // currently kinda accepting anything on upgrade, but that won't deal with all cases diff --git a/src/Umbraco.Core/StringExtensions.cs b/src/Umbraco.Core/StringExtensions.cs index a399c82f0c..4369e8faac 100644 --- a/src/Umbraco.Core/StringExtensions.cs +++ b/src/Umbraco.Core/StringExtensions.cs @@ -164,7 +164,7 @@ namespace Umbraco.Core var obj = JsonConvert.DeserializeObject(input); return obj; } - catch (Exception ex) + catch (Exception) { return input; } @@ -622,7 +622,7 @@ namespace Umbraco.Core byte[] decodedBytes = UrlTokenDecode(input); return decodedBytes != null ? Encoding.UTF8.GetString(decodedBytes) : null; } - catch (FormatException ex) + catch (FormatException) { return null; } diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index e8a5a3654b..42e532869b 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -836,9 +836,7 @@ - - From 34953310058fc3a82f56bc6121f747d3b8ae8062 Mon Sep 17 00:00:00 2001 From: Stephan Date: Thu, 3 May 2018 15:09:56 +0200 Subject: [PATCH 05/15] Cleanup, get rid of warnings --- src/Umbraco.Core/EnumerableExtensions.cs | 15 --------------- src/Umbraco.Tests/Composing/TypeFinderTests.cs | 2 +- .../Models/Collections/SimpleOrder.cs | 2 +- .../Scheduling/BackgroundTaskRunnerTests.cs | 4 ++-- .../Services/MemberTypeServiceTests.cs | 6 +++--- src/Umbraco.Tests/TestHelpers/TestHelper.cs | 5 +++-- src/Umbraco.Web/Cache/MacroCacheRefresher.cs | 16 +++++++--------- .../Components/NotificationsComponent.cs | 15 ++++++++++++--- src/Umbraco.Web/Editors/CodeFileController.cs | 1 - src/Umbraco.Web/Editors/LogController.cs | 5 ----- .../Editors/PackageInstallController.cs | 4 ---- .../HealthCheck/Checks/Services/SmtpCheck.cs | 1 - src/Umbraco.Web/Install/FilePermissionHelper.cs | 2 +- .../Install/InstallSteps/NewInstallStep.cs | 2 +- .../PublishedCache/NuCache/Property.cs | 1 - .../Routing/CustomRouteUrlProvider.cs | 1 - src/Umbraco.Web/Security/MembershipHelper.cs | 2 -- src/Umbraco.Web/Trees/MemberTreeController.cs | 1 - src/Umbraco.Web/Trees/PackagesTreeController.cs | 2 -- src/Umbraco.Web/Trees/UserTreeController.cs | 2 -- .../PackageActions/publishRootDocument.cs | 2 -- .../umbraco/dialogs/create.aspx.cs | 4 ---- .../umbraco/dialogs/sendToTranslation.aspx.cs | 2 -- .../umbraco/webservices/legacyAjaxCalls.asmx.cs | 2 -- 24 files changed, 31 insertions(+), 68 deletions(-) diff --git a/src/Umbraco.Core/EnumerableExtensions.cs b/src/Umbraco.Core/EnumerableExtensions.cs index d5d4a66122..6ae96c9d53 100644 --- a/src/Umbraco.Core/EnumerableExtensions.cs +++ b/src/Umbraco.Core/EnumerableExtensions.cs @@ -92,21 +92,6 @@ namespace Umbraco.Core } } - [EditorBrowsable(EditorBrowsableState.Never)] - [Obsolete("Use a normal foreach loop instead, this adds more allocations than necessary")] - public static IEnumerable ForEach(this IEnumerable items, Action action) - { - if (items != null) - { - foreach (TItem item in items) - { - action(item); - } - } - - return items; - } - /// The flatten list. /// The items. /// The select child. diff --git a/src/Umbraco.Tests/Composing/TypeFinderTests.cs b/src/Umbraco.Tests/Composing/TypeFinderTests.cs index 9a0d473db0..b30312647e 100644 --- a/src/Umbraco.Tests/Composing/TypeFinderTests.cs +++ b/src/Umbraco.Tests/Composing/TypeFinderTests.cs @@ -310,7 +310,7 @@ namespace Umbraco.Tests.Composing using (new WriteLock(LocalFilteredAssemblyCacheLocker)) { var assemblies = GetFilteredAssemblies(excludeFromResults, KnownAssemblyExclusionFilter); - assemblies.ForEach(LocalFilteredAssemblyCache.Add); + foreach (var assembly in assemblies) LocalFilteredAssemblyCache.Add(assembly); } return LocalFilteredAssemblyCache; } diff --git a/src/Umbraco.Tests/Models/Collections/SimpleOrder.cs b/src/Umbraco.Tests/Models/Collections/SimpleOrder.cs index e7b7d4a9bc..4b52289e2a 100644 --- a/src/Umbraco.Tests/Models/Collections/SimpleOrder.cs +++ b/src/Umbraco.Tests/Models/Collections/SimpleOrder.cs @@ -35,7 +35,7 @@ namespace Umbraco.Tests.Models.Collections internal void Reset(IEnumerable properties) { Clear(); - properties.ForEach(Add); + foreach (var property in properties) Add(property); OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); } diff --git a/src/Umbraco.Tests/Scheduling/BackgroundTaskRunnerTests.cs b/src/Umbraco.Tests/Scheduling/BackgroundTaskRunnerTests.cs index e1c856297d..38990405c4 100644 --- a/src/Umbraco.Tests/Scheduling/BackgroundTaskRunnerTests.cs +++ b/src/Umbraco.Tests/Scheduling/BackgroundTaskRunnerTests.cs @@ -441,7 +441,7 @@ namespace Umbraco.Tests.Scheduling tManager.TaskCompleted += (sender, task) => tasks[task.Task].Set(); //execute first batch - tasks.ForEach(t => tManager.Add(t.Key)); + foreach (var t in tasks) tManager.Add(t.Key); //wait for all ITasks to complete WaitHandle.WaitAll(tasks.Values.Select(x => (WaitHandle)x).ToArray()); @@ -455,7 +455,7 @@ namespace Umbraco.Tests.Scheduling Thread.Sleep(2000); tasks = getTasks(); - tasks.ForEach(t => tManager.Add(t.Key)); + foreach (var t in tasks) tManager.Add(t.Key); //wait for all ITasks to complete WaitHandle.WaitAll(tasks.Values.Select(x => (WaitHandle)x).ToArray()); diff --git a/src/Umbraco.Tests/Services/MemberTypeServiceTests.cs b/src/Umbraco.Tests/Services/MemberTypeServiceTests.cs index d5c0eac8c9..b607290c5e 100644 --- a/src/Umbraco.Tests/Services/MemberTypeServiceTests.cs +++ b/src/Umbraco.Tests/Services/MemberTypeServiceTests.cs @@ -108,9 +108,9 @@ namespace Umbraco.Tests.Services ServiceContext.MemberTypeService.Save(contentType1); ServiceContext.MemberTypeService.Save(contentType2); var contentItems1 = MockedMember.CreateSimpleMember(contentType1, 10).ToArray(); - contentItems1.ForEach(x => ServiceContext.MemberService.Save(x)); + foreach (var x in contentItems1) ServiceContext.MemberService.Save(x); var contentItems2 = MockedMember.CreateSimpleMember(contentType2, 5).ToArray(); - contentItems2.ForEach(x => ServiceContext.MemberService.Save(x)); + foreach (var x in contentItems2) ServiceContext.MemberService.Save(x); //only update the contentType1 alias which will force an xml rebuild for all content of that type contentType1.Alias = "newAlias"; ServiceContext.MemberTypeService.Save(contentType1); @@ -141,7 +141,7 @@ namespace Umbraco.Tests.Services var contentType1 = MockedContentTypes.CreateSimpleMemberType("test1", "Test1"); ServiceContext.MemberTypeService.Save(contentType1); var contentItems1 = MockedMember.CreateSimpleMember(contentType1, 10).ToArray(); - contentItems1.ForEach(x => ServiceContext.MemberService.Save(x)); + foreach (var x in contentItems1) ServiceContext.MemberService.Save(x); var alias = contentType1.PropertyTypes.First(x => standardProps.ContainsKey(x.Alias) == false).Alias; var elementToMatch = "<" + alias + ">"; diff --git a/src/Umbraco.Tests/TestHelpers/TestHelper.cs b/src/Umbraco.Tests/TestHelpers/TestHelper.cs index 25ac6314e2..5380a747f5 100644 --- a/src/Umbraco.Tests/TestHelpers/TestHelper.cs +++ b/src/Umbraco.Tests/TestHelpers/TestHelper.cs @@ -84,8 +84,9 @@ namespace Umbraco.Tests.TestHelpers { var directoryInfo = new DirectoryInfo(IOHelper.MapPath(directory)); var preserve = preserves.ContainsKey(directory) ? preserves[directory] : null; - if (directoryInfo.Exists) - directoryInfo.GetFiles().Where(x => preserve == null || preserve.Contains(x.Name) == false).ForEach(x => x.Delete()); + if (directoryInfo.Exists) + foreach (var x in directoryInfo.GetFiles().Where(x => preserve == null || preserve.Contains(x.Name) == false)) + x.Delete(); } } diff --git a/src/Umbraco.Web/Cache/MacroCacheRefresher.cs b/src/Umbraco.Web/Cache/MacroCacheRefresher.cs index c7157bf9dc..03b95d06cb 100644 --- a/src/Umbraco.Web/Cache/MacroCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/MacroCacheRefresher.cs @@ -32,9 +32,8 @@ namespace Umbraco.Web.Cache public override void RefreshAll() { - GetAllMacroCacheKeys().ForEach( - prefix => - CacheHelper.RuntimeCache.ClearCacheByKeySearch(prefix)); + foreach (var prefix in GetAllMacroCacheKeys()) + CacheHelper.RuntimeCache.ClearCacheByKeySearch(prefix); ClearAllIsolatedCacheByEntityType(); @@ -46,19 +45,18 @@ namespace Umbraco.Web.Cache public override void Refresh(string json) { var payloads = Deserialize(json); - - payloads.ForEach(payload => + + foreach (var payload in payloads) { - GetCacheKeysForAlias(payload.Alias).ForEach( - alias => - CacheHelper.RuntimeCache.ClearCacheByKeySearch(alias)); + foreach (var alias in GetCacheKeysForAlias(payload.Alias)) + CacheHelper.RuntimeCache.ClearCacheByKeySearch(alias); var macroRepoCache = CacheHelper.IsolatedRuntimeCache.GetCache(); if (macroRepoCache) { macroRepoCache.Result.ClearCacheItem(RepositoryCacheKeys.GetKey(payload.Id)); } - }); + }; base.Refresh(json); } diff --git a/src/Umbraco.Web/Components/NotificationsComponent.cs b/src/Umbraco.Web/Components/NotificationsComponent.cs index 292bb4bf58..8bf03055e3 100644 --- a/src/Umbraco.Web/Components/NotificationsComponent.cs +++ b/src/Umbraco.Web/Components/NotificationsComponent.cs @@ -19,7 +19,10 @@ namespace Umbraco.Web.Components //Send notifications for the published action ContentService.Published += (sender, args) => - args.PublishedEntities.ForEach(content => notificationService.SendNotification(content, ActionPublish.Instance)); + { + foreach (var content in args.PublishedEntities) + notificationService.SendNotification(content, ActionPublish.Instance); + }; //Send notifications for the update and created actions ContentService.Saved += (sender, args) => @@ -48,11 +51,17 @@ namespace Umbraco.Web.Components //Send notifications for the delete action ContentService.Deleted += (sender, args) => - args.DeletedEntities.ForEach(content => notificationService.SendNotification(content, ActionDelete.Instance)); + { + foreach (var content in args.DeletedEntities) + notificationService.SendNotification(content, ActionDelete.Instance); + }; //Send notifications for the unpublish action ContentService.UnPublished += (sender, args) => - args.PublishedEntities.ForEach(content => notificationService.SendNotification(content, ActionUnPublish.Instance)); + { + foreach (var content in args.PublishedEntities) + notificationService.SendNotification(content, ActionUnPublish.Instance); + }; } } } diff --git a/src/Umbraco.Web/Editors/CodeFileController.cs b/src/Umbraco.Web/Editors/CodeFileController.cs index 6cf6d61c44..edcd71b2e8 100644 --- a/src/Umbraco.Web/Editors/CodeFileController.cs +++ b/src/Umbraco.Web/Editors/CodeFileController.cs @@ -373,7 +373,6 @@ namespace Umbraco.Web.Editors // Services.TextService.Localize("speechBubbles/partialViewErrorHeader"), // Services.TextService.Localize("speechBubbles/partialViewErrorText")); - break; diff --git a/src/Umbraco.Web/Editors/LogController.cs b/src/Umbraco.Web/Editors/LogController.cs index d8b0fe48ca..30c2a33ff1 100644 --- a/src/Umbraco.Web/Editors/LogController.cs +++ b/src/Umbraco.Web/Editors/LogController.cs @@ -1,15 +1,10 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Net; -using System.Net.Http; -using System.Windows.Forms; using AutoMapper; using Umbraco.Web.Models.ContentEditing; using Umbraco.Core.Models; -using Umbraco.Core.Models; using Umbraco.Core.Persistence.DatabaseModelDefinitions; -using Umbraco.Core.Persistence.Querying; using Umbraco.Web.Mvc; namespace Umbraco.Web.Editors diff --git a/src/Umbraco.Web/Editors/PackageInstallController.cs b/src/Umbraco.Web/Editors/PackageInstallController.cs index 5a1318acb5..fec358f113 100644 --- a/src/Umbraco.Web/Editors/PackageInstallController.cs +++ b/src/Umbraco.Web/Editors/PackageInstallController.cs @@ -89,8 +89,6 @@ namespace Umbraco.Web.Editors { if (pack == null) throw new ArgumentNullException("pack"); - var refreshCache = false; - var removedTemplates = new List(); var removedMacros = new List(); var removedContentTypes = new List(); @@ -137,8 +135,6 @@ namespace Umbraco.Web.Editors if (contentType == null) continue; contentTypes.Add(contentType); pack.Data.Documenttypes.Remove(nId.ToString(CultureInfo.InvariantCulture)); - // refresh content cache when document types are removed - refreshCache = true; } //Order the DocumentTypes before removing them diff --git a/src/Umbraco.Web/HealthCheck/Checks/Services/SmtpCheck.cs b/src/Umbraco.Web/HealthCheck/Checks/Services/SmtpCheck.cs index 8e3447c79f..d6f7cef497 100644 --- a/src/Umbraco.Web/HealthCheck/Checks/Services/SmtpCheck.cs +++ b/src/Umbraco.Web/HealthCheck/Checks/Services/SmtpCheck.cs @@ -52,7 +52,6 @@ namespace Umbraco.Web.HealthCheck.Checks.Services var success = false; // appPath is the virtual application root path on the server - var appPath = ""; var config = WebConfigurationManager.OpenWebConfiguration(_runtime.ApplicationVirtualPath); var settings = (MailSettingsSectionGroup)config.GetSectionGroup("system.net/mailSettings"); if (settings == null) diff --git a/src/Umbraco.Web/Install/FilePermissionHelper.cs b/src/Umbraco.Web/Install/FilePermissionHelper.cs index c58c2fd4fd..367f09bb1d 100644 --- a/src/Umbraco.Web/Install/FilePermissionHelper.cs +++ b/src/Umbraco.Web/Install/FilePermissionHelper.cs @@ -210,7 +210,7 @@ namespace Umbraco.Web.Install if (accessRules == null) return false; } - catch (Exception e) + catch (Exception) { //This is not 100% accurate btw because it could turn out that the current user doesn't //have access to read the current permissions but does have write access. diff --git a/src/Umbraco.Web/Install/InstallSteps/NewInstallStep.cs b/src/Umbraco.Web/Install/InstallSteps/NewInstallStep.cs index e55203ec9f..ab3bd0aac5 100644 --- a/src/Umbraco.Web/Install/InstallSteps/NewInstallStep.cs +++ b/src/Umbraco.Web/Install/InstallSteps/NewInstallStep.cs @@ -69,7 +69,7 @@ namespace Umbraco.Web.Install.InstallSteps throw new FormatException("Password must be at least " + CurrentProvider.MinRequiredPasswordLength + " characters long and contain at least " + CurrentProvider.MinRequiredNonAlphanumericCharacters + " symbols"); } } - catch (Exception ex) + catch (Exception) { throw new FormatException("Password must be at least " + CurrentProvider.MinRequiredPasswordLength + " characters long and contain at least " + CurrentProvider.MinRequiredNonAlphanumericCharacters + " symbols"); } diff --git a/src/Umbraco.Web/PublishedCache/NuCache/Property.cs b/src/Umbraco.Web/PublishedCache/NuCache/Property.cs index f2e3355750..82dabeaba3 100644 --- a/src/Umbraco.Web/PublishedCache/NuCache/Property.cs +++ b/src/Umbraco.Web/PublishedCache/NuCache/Property.cs @@ -34,7 +34,6 @@ namespace Umbraco.Web.PublishedCache.NuCache private CacheValues _cacheValues; private string _valuesCacheKey; - private string _recurseCacheKey; // initializes a published content property with no value public Property(PublishedPropertyType propertyType, PublishedContent content, IPublishedSnapshotAccessor publishedSnapshotAccessor, PropertyCacheLevel referenceCacheLevel = PropertyCacheLevel.Element) diff --git a/src/Umbraco.Web/Routing/CustomRouteUrlProvider.cs b/src/Umbraco.Web/Routing/CustomRouteUrlProvider.cs index 138155c8f6..e75c733290 100644 --- a/src/Umbraco.Web/Routing/CustomRouteUrlProvider.cs +++ b/src/Umbraco.Web/Routing/CustomRouteUrlProvider.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Globalization; using Umbraco.Web.Mvc; -using Umbraco.Core.Models.PublishedContent; namespace Umbraco.Web.Routing { diff --git a/src/Umbraco.Web/Security/MembershipHelper.cs b/src/Umbraco.Web/Security/MembershipHelper.cs index 9b7ce72817..6d28680877 100644 --- a/src/Umbraco.Web/Security/MembershipHelper.cs +++ b/src/Umbraco.Web/Security/MembershipHelper.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.ComponentModel; -using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using System.Web; @@ -19,7 +18,6 @@ using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.Services; using Umbraco.Web.Editors; using Umbraco.Web.Security.Providers; -using Umbraco.Core.Services; using Umbraco.Web.Routing; using MPE = global::Umbraco.Core.Security.MembershipProviderExtensions; diff --git a/src/Umbraco.Web/Trees/MemberTreeController.cs b/src/Umbraco.Web/Trees/MemberTreeController.cs index a0dbcee233..8dd889c052 100644 --- a/src/Umbraco.Web/Trees/MemberTreeController.cs +++ b/src/Umbraco.Web/Trees/MemberTreeController.cs @@ -17,7 +17,6 @@ using Umbraco.Web._Legacy.Actions; using Umbraco.Web.Models.ContentEditing; using Umbraco.Web.Search; using Constants = Umbraco.Core.Constants; -using Umbraco.Core.Services; namespace Umbraco.Web.Trees { diff --git a/src/Umbraco.Web/Trees/PackagesTreeController.cs b/src/Umbraco.Web/Trees/PackagesTreeController.cs index ff23738e92..ce95cf4ee0 100644 --- a/src/Umbraco.Web/Trees/PackagesTreeController.cs +++ b/src/Umbraco.Web/Trees/PackagesTreeController.cs @@ -35,8 +35,6 @@ namespace Umbraco.Web.Trees protected override TreeNodeCollection GetTreeNodes(string id, FormDataCollection queryStrings) { - var baseUrl = Constants.Applications.Developer + "/packages/"; - var nodes = new TreeNodeCollection(); var createdPackages = CreatedPackage.GetAllCreatedPackages(); diff --git a/src/Umbraco.Web/Trees/UserTreeController.cs b/src/Umbraco.Web/Trees/UserTreeController.cs index 2c0a4c6cae..db1bca0234 100644 --- a/src/Umbraco.Web/Trees/UserTreeController.cs +++ b/src/Umbraco.Web/Trees/UserTreeController.cs @@ -33,8 +33,6 @@ namespace Umbraco.Web.Trees protected override TreeNodeCollection GetTreeNodes(string id, FormDataCollection queryStrings) { - var baseUrl = Constants.Applications.Users + "/users/"; - var nodes = new TreeNodeCollection(); return nodes; } diff --git a/src/Umbraco.Web/_Legacy/PackageActions/publishRootDocument.cs b/src/Umbraco.Web/_Legacy/PackageActions/publishRootDocument.cs index 61c334f184..32147342f6 100644 --- a/src/Umbraco.Web/_Legacy/PackageActions/publishRootDocument.cs +++ b/src/Umbraco.Web/_Legacy/PackageActions/publishRootDocument.cs @@ -28,8 +28,6 @@ namespace Umbraco.Web._Legacy.PackageActions string documentName = xmlData.Attributes["documentName"].Value; - int parentDocid = 0; - //global::umbraco.cms.businesslogic.web.Document[] rootDocs = global::umbraco.cms.businesslogic.web.Document.GetRootDocuments(); var rootDocs = Current.Services.ContentService.GetRootContent(); diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/create.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/create.aspx.cs index f1df183074..d5dd83f278 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/create.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/create.aspx.cs @@ -1,16 +1,12 @@ using System; using System.Linq; using System.Globalization; -using System.Linq; using System.Web.UI; using System.Xml; using Umbraco.Core.IO; using Umbraco.Web; -using umbraco.cms.businesslogic; using Umbraco.Core; -using Umbraco.Core.Models; using Umbraco.Core.Services; -using Umbraco.Web.Composing; using Umbraco.Web.UI.Pages; using Umbraco.Web._Legacy.Actions; using Button = System.Web.UI.WebControls.Button; diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/sendToTranslation.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/sendToTranslation.aspx.cs index 2d8b100e93..b28b037ddd 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/sendToTranslation.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/sendToTranslation.aspx.cs @@ -2,7 +2,6 @@ using System; using System.Linq; using System.Net.Mail; using System.Web; -using System.Linq; using System.Web.UI.WebControls; using Umbraco.Core; using Umbraco.Core.Services; @@ -13,7 +12,6 @@ using Umbraco.Core.Models.Membership; using Umbraco.Web; using Umbraco.Web.Composing; using Umbraco.Web.UI.Pages; -using Umbraco.Core; using Umbraco.Core.Configuration; using Umbraco.Core.Models.Entities; diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/legacyAjaxCalls.asmx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/legacyAjaxCalls.asmx.cs index ea22777168..13b37b21e8 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/legacyAjaxCalls.asmx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/legacyAjaxCalls.asmx.cs @@ -21,8 +21,6 @@ namespace umbraco.presentation.webservices [ScriptService] public class legacyAjaxCalls : UmbracoAuthorizedWebService { - private IUser _currentUser; - /// /// method to accept a string value for the node id. Used for tree's such as python /// and xslt since the file names are the node IDs From 48c70604a9584259fc5189637ce5a902346104a8 Mon Sep 17 00:00:00 2001 From: Robert Date: Fri, 4 May 2018 13:42:33 +0200 Subject: [PATCH 06/15] Added localization for "Ready to publish?" publish overlay, added previously removed property which was still in use. --- .../common/directives/components/content/edit.controller.js | 6 ++---- .../src/views/components/overlays/umb-overlay.html | 2 +- src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml | 2 +- src/Umbraco.Web/PublishedCache/NuCache/Property.cs | 1 + 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js index 63bdb9c92e..da5ac5034f 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js @@ -304,7 +304,6 @@ //before we launch the dialog we want to execute all client side validations first if (formHelper.submitForm({ scope: $scope, action: "publish" })) { var dialog = { - title: "Ready to Publish?", //TODO: localize view: "publish", variants: $scope.content.variants, //set a model property for the dialog skipFormValidation: true, //when submitting the overlay form, skip any client side validation @@ -400,7 +399,7 @@ var target = null; var error = { headline: "Cannot automatically restore this item", content: "Use the Move menu item to move it manually" }; - if (data.length == 0) { + if (data.length === 0) { notificationsService.error(error.headline, "There is no 'restore' relation found for this node. Use the Move menu item to move it manually."); $scope.page.buttonRestore = "error"; return; @@ -408,7 +407,7 @@ relation = data[0]; - if (relation.parentId == -1) { + if (relation.parentId === -1) { target = { id: -1, name: "Root" }; moveNode(content, target); } else { @@ -465,7 +464,6 @@ $scope.editors[editorIndex].content = angular.copy($scope.content); $scope.editors[editorIndex].content.name = "What a variant"; // set selected variant on split view content - console.log($scope.editors[editorIndex].content.variants); angular.forEach($scope.editors[editorIndex].content.variants, function (variant) { if (variant.culture === selectedVariant.culture) { variant.current = true; diff --git a/src/Umbraco.Web.UI.Client/src/views/components/overlays/umb-overlay.html b/src/Umbraco.Web.UI.Client/src/views/components/overlays/umb-overlay.html index 14a7ebf006..4180219ded 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/overlays/umb-overlay.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/overlays/umb-overlay.html @@ -2,7 +2,7 @@
-

{{model.title}}

+

{{model.subtitle}}

diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml index b8df84ad25..f5b890bd8c 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml @@ -235,7 +235,7 @@ What languages would you like to publish? No languages available to be published. Published Languages. - + Ready to Publish? Create a new Content Template from '%0%' diff --git a/src/Umbraco.Web/PublishedCache/NuCache/Property.cs b/src/Umbraco.Web/PublishedCache/NuCache/Property.cs index 82dabeaba3..f2e3355750 100644 --- a/src/Umbraco.Web/PublishedCache/NuCache/Property.cs +++ b/src/Umbraco.Web/PublishedCache/NuCache/Property.cs @@ -34,6 +34,7 @@ namespace Umbraco.Web.PublishedCache.NuCache private CacheValues _cacheValues; private string _valuesCacheKey; + private string _recurseCacheKey; // initializes a published content property with no value public Property(PublishedPropertyType propertyType, PublishedContent content, IPublishedSnapshotAccessor publishedSnapshotAccessor, PropertyCacheLevel referenceCacheLevel = PropertyCacheLevel.Element) From c5de31cce3e5ba9895663386506c49fa816f2db0 Mon Sep 17 00:00:00 2001 From: Robert Date: Fri, 4 May 2018 13:44:04 +0200 Subject: [PATCH 07/15] Invariant property value should persist trough all variants of a content item --- .../Models/Mapping/ContentPropertyBasicConverter.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web/Models/Mapping/ContentPropertyBasicConverter.cs b/src/Umbraco.Web/Models/Mapping/ContentPropertyBasicConverter.cs index 10fec19b38..aec5c375d9 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentPropertyBasicConverter.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentPropertyBasicConverter.cs @@ -46,12 +46,17 @@ namespace Umbraco.Web.Models.Mapping editor = _propertyEditors[Constants.PropertyEditors.Aliases.NoEdit]; } - var culture = context.GetCulture(); + var culture = context.GetCulture(); if (culture == null && property.PropertyType.Variations == ContentVariation.CultureNeutral) { //a language Id needs to be set for a property type that can be varried by language throw new InvalidOperationException($"No languageId found in mapping operation when one is required for the culture neutral property type {property.PropertyType.Alias}"); + } + if (property.PropertyType.Variations == ContentVariation.InvariantNeutral) + { + culture = null; + } var result = new TDestination From cc7febcc6d25e8de81f39bc09539fa48af75cbf6 Mon Sep 17 00:00:00 2001 From: Robert Date: Fri, 4 May 2018 13:51:35 +0200 Subject: [PATCH 08/15] Allows variant content item to save while having a invariant property, also fixes not being able to save invariant content item with invariant property --- src/Umbraco.Core/Models/Property.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Umbraco.Core/Models/Property.cs b/src/Umbraco.Core/Models/Property.cs index 709c37daaa..7e53eb764a 100644 --- a/src/Umbraco.Core/Models/Property.cs +++ b/src/Umbraco.Core/Models/Property.cs @@ -271,6 +271,10 @@ namespace Umbraco.Core.Models ///
public void SetValue(object value, string culture = null, string segment = null) { + if (PropertyType.Variations == ContentVariation.InvariantNeutral) + { + culture = null; + } PropertyType.ValidateVariation(culture, segment, true); (var pvalue, var change) = GetPValue(culture, segment, true); From 8388eca5033c45d8e55048a2e05d5f98c2f2babd Mon Sep 17 00:00:00 2001 From: Stephan Date: Fri, 4 May 2018 15:00:10 +0200 Subject: [PATCH 09/15] Fix agressive cleanup --- src/Umbraco.Web/PublishedCache/NuCache/Property.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Umbraco.Web/PublishedCache/NuCache/Property.cs b/src/Umbraco.Web/PublishedCache/NuCache/Property.cs index 82dabeaba3..f2e3355750 100644 --- a/src/Umbraco.Web/PublishedCache/NuCache/Property.cs +++ b/src/Umbraco.Web/PublishedCache/NuCache/Property.cs @@ -34,6 +34,7 @@ namespace Umbraco.Web.PublishedCache.NuCache private CacheValues _cacheValues; private string _valuesCacheKey; + private string _recurseCacheKey; // initializes a published content property with no value public Property(PublishedPropertyType propertyType, PublishedContent content, IPublishedSnapshotAccessor publishedSnapshotAccessor, PropertyCacheLevel referenceCacheLevel = PropertyCacheLevel.Element) From 9474c78de87ec1b48a610e97b7f48a46079b9254 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 4 May 2018 18:21:04 +0200 Subject: [PATCH 10/15] add bg boxes to content type editors --- .../views/listview/listview.html | 37 ++++---- .../views/permissions/permissions.html | 95 ++++++++++--------- .../views/templates/templates.html | 44 +++++---- .../mediatypes/views/listview/listview.html | 37 ++++---- .../views/permissions/permissions.html | 94 +++++++++--------- 5 files changed, 158 insertions(+), 149 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/listview/listview.html b/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/listview/listview.html index c27d885483..7d435adc6d 100644 --- a/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/listview/listview.html +++ b/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/listview/listview.html @@ -1,19 +1,18 @@ -
- -
-
- -
- -
- - - - -
- -
+ + +
+
+
+ +
+
+ + +
+
+
+
\ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/permissions/permissions.html b/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/permissions/permissions.html index 7df2577871..606ae1d9b1 100644 --- a/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/permissions/permissions.html +++ b/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/permissions/permissions.html @@ -1,60 +1,65 @@
-
+ + -
-
- -
-
- -
+
-
+
+
+ +
+
+ +
-
+
-
-
- -
+
-
- - +
+
+ +
- - +
+ + -
+ + -
+
-
+
-
-
Content Type Variation
- Define the rules for how this content type's properties can be varied -
-
- -
+
-
+
+
Content Type Variation
+ Define the rules for how this content type's properties can be varied +
+
+ +
+
+ + +
diff --git a/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/templates/templates.html b/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/templates/templates.html index 0cfe76cd7a..c3bc28a145 100644 --- a/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/templates/templates.html +++ b/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/templates/templates.html @@ -1,23 +1,27 @@ -
+
+ + +
-
-
- -
- -
- - - - -
+
+
+ +
+ +
+ + +
+
+
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/mediatypes/views/listview/listview.html b/src/Umbraco.Web.UI.Client/src/views/mediatypes/views/listview/listview.html index 1461341d6d..21d29b2161 100644 --- a/src/Umbraco.Web.UI.Client/src/views/mediatypes/views/listview/listview.html +++ b/src/Umbraco.Web.UI.Client/src/views/mediatypes/views/listview/listview.html @@ -1,19 +1,18 @@ -
- -
-
- -
- -
- - - - -
- -
+ + +
+
+
+ +
+
+ + +
+
+
+
\ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/mediatypes/views/permissions/permissions.html b/src/Umbraco.Web.UI.Client/src/views/mediatypes/views/permissions/permissions.html index 7c9811e37a..d34b31c8ea 100644 --- a/src/Umbraco.Web.UI.Client/src/views/mediatypes/views/permissions/permissions.html +++ b/src/Umbraco.Web.UI.Client/src/views/mediatypes/views/permissions/permissions.html @@ -1,49 +1,51 @@
+ + +
-
- -
-
- -
-
- -
- -
- -
- -
-
- -
- -
- - - - - - - - -
- -
- +
+
+ +
+
+ +
+ +
+ +
+ +
+
+ +
+ +
+ + + + + + + + +
+ +
+
+
From ed0886b040e5cb704788ec82cfd4c66512400a3c Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 4 May 2018 18:21:58 +0200 Subject: [PATCH 11/15] add bg box to user details sidebar --- .../src/views/users/views/user/details.html | 320 +++++++++--------- 1 file changed, 162 insertions(+), 158 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/users/views/user/details.html b/src/Umbraco.Web.UI.Client/src/views/users/views/user/details.html index 67f204aa2f..5aded20cfa 100644 --- a/src/Umbraco.Web.UI.Client/src/views/users/views/user/details.html +++ b/src/Umbraco.Web.UI.Client/src/views/users/views/user/details.html @@ -165,196 +165,200 @@
-
+ - -
- + - - + +
+ - - + + - + + +
+ +
+ +
- +
+ + +
-
- - -
- -
- - -
- -
- - -
- -
- - -
- - - - - - - - +
+ + +
+ label="Change password" + label-key="general_changePassword" + state="changePasswordButtonState" + ng-if="model.changePasswordModel.isChanging === false" + size="s"> -
+ + + + + + + + + + +
+


Password reset to value: {{model.user.resetPasswordValue}}

+
-
-


Password reset to value: {{model.user.resetPasswordValue}}

-
+ +
+
+ Status: +
+
+ + {{model.user.userDisplayState.name}} + +
+
- -
-
- Status: +
+
+ Last login: +
+
+ {{ model.user.formattedLastLogin }} + {{ model.user.name | umbWordLimit:1 }} has not logged in yet +
-
- - {{model.user.userDisplayState.name}} - -
-
-
-
- Last login: +
+
+ Failed login attempts: +
+
+ {{ model.user.failedPasswordAttempts }} +
-
- {{ model.user.formattedLastLogin }} - {{ model.user.name | umbWordLimit:1 }} has not logged in yet -
-
-
-
- Failed login attempts: +
+
+ Last lockout date: +
+
+ + {{ model.user.name | umbWordLimit:1 }} hasn't been locked out + + {{ model.user.formattedLastLockoutDate }} +
-
- {{ model.user.failedPasswordAttempts }} -
-
-
-
- Last lockout date: +
+
+ Password is last changed: +
+
+ + The password hasn't been changed + + {{ model.user.formattedLastPasswordChangeDate }} +
-
- - {{ model.user.name | umbWordLimit:1 }} hasn't been locked out - - {{ model.user.formattedLastLockoutDate }} -
-
-
-
- Password is last changed: +
+
+ User is created: +
+
+ {{ model.user.formattedCreateDate }} +
-
- - The password hasn't been changed - - {{ model.user.formattedLastPasswordChangeDate }} -
-
-
-
- User is created: +
+
+ User is last updated: +
+
+ {{ model.user.formattedUpdateDate }} +
-
- {{ model.user.formattedCreateDate }} -
-
-
-
- User is last updated: -
-
- {{ model.user.formattedUpdateDate }} -
-
+ -
+
From 63d77686533bf73c966c29db297549a8033ec0df Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 4 May 2018 18:32:35 +0200 Subject: [PATCH 12/15] add bg box to code editors --- .../src/views/partialviewmacros/edit.html | 75 ++++----- .../src/views/partialviews/edit.html | 69 ++++---- .../src/views/scripts/edit.html | 18 ++- .../src/views/templates/edit.html | 150 +++++++++--------- 4 files changed, 163 insertions(+), 149 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/partialviewmacros/edit.html b/src/Umbraco.Web.UI.Client/src/views/partialviewmacros/edit.html index 8f093a5924..d692c6fd9e 100644 --- a/src/Umbraco.Web.UI.Client/src/views/partialviewmacros/edit.html +++ b/src/Umbraco.Web.UI.Client/src/views/partialviewmacros/edit.html @@ -19,50 +19,53 @@ + + -
+
-
- - - -
- -
- -
-
- +
+
+ + diff --git a/src/Umbraco.Web.UI.Client/src/views/partialviews/edit.html b/src/Umbraco.Web.UI.Client/src/views/partialviews/edit.html index 6ecc2b2d89..3bbf735199 100644 --- a/src/Umbraco.Web.UI.Client/src/views/partialviews/edit.html +++ b/src/Umbraco.Web.UI.Client/src/views/partialviews/edit.html @@ -20,49 +20,54 @@ -
+ + + +
+ +
+ -
- - -
-
- -
-
- +
+
+ + + diff --git a/src/Umbraco.Web.UI.Client/src/views/scripts/edit.html b/src/Umbraco.Web.UI.Client/src/views/scripts/edit.html index 9b03935efc..2e747fd5a5 100644 --- a/src/Umbraco.Web.UI.Client/src/views/scripts/edit.html +++ b/src/Umbraco.Web.UI.Client/src/views/scripts/edit.html @@ -19,14 +19,16 @@ - -
-
- + + +
+
+
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/templates/edit.html b/src/Umbraco.Web.UI.Client/src/views/templates/edit.html index 279cdc538d..25cfb7ea61 100644 --- a/src/Umbraco.Web.UI.Client/src/views/templates/edit.html +++ b/src/Umbraco.Web.UI.Client/src/views/templates/edit.html @@ -7,14 +7,12 @@ novalidate val-form-manager> - -
+ + -
+
-
- - +
- - - +
+ + + + + + + +
+ +
+ +
+ + + + + + +
- -
- -
- - -
- -
-
+ + From 73b5694aad27d109c870cf1d373cc7c228050d84 Mon Sep 17 00:00:00 2001 From: Stephan Date: Fri, 4 May 2018 18:33:40 +0200 Subject: [PATCH 13/15] Fix web.config transform --- src/Umbraco.Web.UI/web.Template.Debug.config | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web.UI/web.Template.Debug.config b/src/Umbraco.Web.UI/web.Template.Debug.config index f9c62eeb0e..510b4f17db 100644 --- a/src/Umbraco.Web.UI/web.Template.Debug.config +++ b/src/Umbraco.Web.UI/web.Template.Debug.config @@ -11,11 +11,11 @@ One can edit web.config, it will not be overritten, but it WILL be altered by this transform file everytime Umbraco builds. --> + + + - - - - - -REM if not exist "$(TargetDir)x86" md "$(TargetDir)x86" -REM xcopy /s /y "$(SolutionDir)packages\Microsoft.SqlServer.Compact.4.0.8876.1\NativeBinaries\x86\*.*" "$(TargetDir)x86" -REM if not exist "$(TargetDir)amd64" md "$(TargetDir)amd64" -REM xcopy /s /y "$(SolutionDir)packages\Microsoft.SqlServer.Compact.4.0.8876.1\NativeBinaries\amd64\*.*" "$(TargetDir)amd64" - - - REM xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.1\amd64\*.* "$(TargetDir)amd64\" /Y /F /E /I /C /D -REM xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.1\x86\*.* "$(TargetDir)x86\" /Y /F /E /I /C /D - REM if not exist "$(TargetDir)x86" md "$(TargetDir)x86" -REM xcopy /s /y "$(NugetPackages)\Microsoft.SqlServer.Compact.4.0.8876.1\NativeBinaries\x86\*.*" "$(TargetDir)x86" -REM if not exist "$(TargetDir)amd64" md "$(TargetDir)amd64" -REM xcopy /s /y "$(NugetPackages)\Microsoft.SqlServer.Compact.4.0.8876.1\NativeBinaries\amd64\*.*" "$(TargetDir)amd64" $(NuGetPackageFolders.Split(';')[0]) + From 1b2a964001a6cd61920d39f573819c62eb1a4930 Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 7 May 2018 12:08:59 +0200 Subject: [PATCH 15/15] Fixed localization --- .../common/directives/components/content/edit.controller.js | 3 ++- .../src/views/components/overlays/umb-overlay.html | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js index da5ac5034f..080e224b9d 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js @@ -4,7 +4,7 @@ function ContentEditController($rootScope, $scope, $routeParams, $q, $timeout, $window, $location, appState, contentResource, entityResource, navigationService, notificationsService, angularHelper, serverValidationManager, contentEditingHelper, treeService, fileManager, formHelper, umbRequestHelper, - keyboardService, umbModelMapper, editorState, $http, eventsService, relationResource, overlayService) { + keyboardService, umbModelMapper, editorState, $http, eventsService, relationResource, overlayService, localizationService) { var evts = []; @@ -304,6 +304,7 @@ //before we launch the dialog we want to execute all client side validations first if (formHelper.submitForm({ scope: $scope, action: "publish" })) { var dialog = { + title: localizationService.localize("content_readyToPublish"), view: "publish", variants: $scope.content.variants, //set a model property for the dialog skipFormValidation: true, //when submitting the overlay form, skip any client side validation diff --git a/src/Umbraco.Web.UI.Client/src/views/components/overlays/umb-overlay.html b/src/Umbraco.Web.UI.Client/src/views/components/overlays/umb-overlay.html index 4180219ded..14a7ebf006 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/overlays/umb-overlay.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/overlays/umb-overlay.html @@ -2,7 +2,7 @@
-

+

{{model.title}}

{{model.subtitle}}