Merge remote-tracking branch 'origin/temp8' into temp8-U4-11282

This commit is contained in:
Shannon
2018-05-08 00:39:12 +10:00
65 changed files with 820 additions and 699 deletions

View File

@@ -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<object> 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<object>)x.Value, true);
var value = GetSafeLazyValue((Lazy<object>) 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<T>()
{
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<object>)x.Value, true);
var value = GetSafeLazyValue((Lazy<object>) 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<T>(Func<string, T, bool> 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<object>)x.Value, true);
var value = GetSafeLazyValue((Lazy<object>) 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<DictionaryEntry> 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<object>)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<DictionaryEntry> 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<object>)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<object> result;
using (ReadLock)
try
{
EnterReadLock();
result = GetEntry(cacheKey) as Lazy<object>; // null if key not found
}
finally
{
ExitReadLock();
}
return result == null ? null : GetSafeLazyValue(result); // return exceptions as null
}

View File

@@ -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<object> result;
using (WriteLock)
try
{
EnterWriteLock();
result = ContextItems[cacheKey] as Lazy<object>; // 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

View File

@@ -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<object>; // 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<object> getCacheItem, TimeSpan? timeout = null, bool isSliding = false, CacheItemPriority priority = CacheItemPriority.Normal, CacheItemRemovedCallback removedCallback = null, string[] dependentFiles = null)

View File

@@ -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<T>()
{
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<T>(Func<string, T, bool> 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<object> GetCacheItemsByKeySearch(string keyStartsWith)
{
KeyValuePair<string, object>[] 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<object>)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<object> GetCacheItemsByKeyExpression(string regexString)
{
KeyValuePair<string, object>[] 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<object>)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<object> result;
using (new ReadLock(_locker))
try
{
_locker.EnterReadLock();
result = MemoryCache.Get(cacheKey) as Lazy<object>; // null if key not found
}
finally
{
if (_locker.IsReadLockHeld)
_locker.ExitReadLock();
}
return result == null ? null : DictionaryCacheProviderBase.GetSafeLazyValue(result); // return exceptions as null
}

View File

@@ -50,10 +50,16 @@ namespace Umbraco.Core.Collections
/// <param name="item">The object to remove from the <see cref="T:System.Collections.Generic.ICollection`1"/>.</param><exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only.</exception>
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
/// <param name="item">The object to add to the <see cref="T:System.Collections.Generic.ICollection`1"/>.</param><exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only.</exception>
public void Add(T item)
{
using (new WriteLock(_instanceLocker))
try
{
_instanceLocker.EnterWriteLock();
_innerSet.Add(item);
}
finally
{
if (_instanceLocker.IsWriteLockHeld)
_instanceLocker.ExitWriteLock();
}
}
/// <summary>
@@ -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();
}
}
/// <summary>
@@ -116,10 +135,16 @@ namespace Umbraco.Core.Collections
/// <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only. </exception>
public void Clear()
{
using (new WriteLock(_instanceLocker))
try
{
_instanceLocker.EnterWriteLock();
_innerSet.Clear();
}
finally
{
if (_instanceLocker.IsWriteLockHeld)
_instanceLocker.ExitWriteLock();
}
}
/// <summary>
@@ -147,10 +172,16 @@ namespace Umbraco.Core.Collections
private HashSet<T> GetThreadSafeClone()
{
HashSet<T> clone = null;
using (new WriteLock(_instanceLocker))
try
{
_instanceLocker.EnterWriteLock();
clone = new HashSet<T>(_innerSet, _innerSet.Comparer);
}
finally
{
if (_instanceLocker.IsWriteLockHeld)
_instanceLocker.ExitWriteLock();
}
return clone;
}

View File

@@ -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;
//}
}
/// <summary>

View File

@@ -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<TItem> ForEach<TItem>(this IEnumerable<TItem> items, Action<TItem> action)
{
if (items != null)
{
foreach (TItem item in items)
{
action(item);
}
}
return items;
}
/// <summary>The flatten list.</summary>
/// <param name="e">The items.</param>
/// <param name="f">The select child.</param>

View File

@@ -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();

View File

@@ -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 (

View File

@@ -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
/// </summary>
/// <returns></returns>
public IMediaType DeepCloneWithResetIdentities(string alias)
public new IMediaType DeepCloneWithResetIdentities(string alias)
{
var clone = (MediaType)DeepClone();
clone.Alias = alias;

View File

@@ -271,6 +271,10 @@ namespace Umbraco.Core.Models
/// </summary>
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);

View File

@@ -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();
}
}
/// <summary>

View File

@@ -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();
}
}
/// <summary>

View File

@@ -1,45 +0,0 @@
using System;
using NuGet;
using Umbraco.Core.Configuration;
namespace Umbraco.Core.Packaging
{
internal class DefaultPackageContext : IPackageContext
{
public DefaultPackageContext(Func<string, string> mapPath)
{}
private readonly string _localPackageRepoFolderPath;
private readonly string _pluginInstallFolderPath;
private readonly Lazy<IPackageManager> _localPackageManager;
private readonly Lazy<IPackageRepository> _localPackageRepository;
private readonly Lazy<IPackageManager> _publicPackageManager;
private readonly Lazy<IPackageManager> _privatePackageManager;
private readonly Lazy<IPackageRepository> _publicPackageRepository;
private readonly Lazy<IPackageRepository> _sprivatePackageRepository;
/// <summary>
/// Gets the local path resolver.
/// </summary>
public IPackagePathResolver LocalPathResolver
{
get { return ((PackageManager)LocalPackageManager).PathResolver; }
}
/// <summary>
/// Gets the local package manager.
/// </summary>
public IPackageManager LocalPackageManager
{
get { return _localPackageManager.Value; }
}
/// <summary>
/// Gets the public package manager.
/// </summary>
public IPackageManager PublicPackageManager
{
get { return _publicPackageManager.Value; }
}
}
}

View File

@@ -1,11 +0,0 @@
using NuGet;
namespace Umbraco.Core.Packaging
{
internal interface IPackageContext
{
IPackageManager LocalPackageManager { get; }
IPackageManager PublicPackageManager { get; }
IPackagePathResolver LocalPathResolver { get; }
}
}

View File

@@ -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;

View File

@@ -126,8 +126,10 @@ namespace Umbraco.Core.Persistence
/// <inheritdoc />
public void Configure(string connectionString, string providerName)
{
using (new WriteLock(_lock))
try
{
_lock.EnterWriteLock();
_logger.Debug<UmbracoDatabaseFactory>("Configuring.");
if (Configured) throw new InvalidOperationException("Already configured.");
@@ -173,6 +175,11 @@ namespace Umbraco.Core.Persistence
_logger.Debug<UmbracoDatabaseFactory>("Configured.");
Configured = true;
}
finally
{
if (_lock.IsWriteLockHeld)
_lock.ExitWriteLock();
}
}
/// <inheritdoc />

View File

@@ -10,9 +10,11 @@ namespace Umbraco.Core
/// Provides a convenience methodology for implementing locked access to resources.
/// </summary>
/// <remarks>
/// Intended as an infrastructure class.
/// <para>Intended as an infrastructure class.</para>
/// <para>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!</para>
/// </remarks>
[Obsolete("stop using, allocates")]
public class ReadLock : IDisposable
{
private readonly ReaderWriterLockSlim _rwLock;

View File

@@ -26,8 +26,6 @@ namespace Umbraco.Core.Security
validation=""HMACSHA256"" decryption=""AES""
/>";
var Xxx = 3;
return string.Format(c, GenerateAESDecryptionKey(), GenerateHMACSHA256ValidationKey());
}

View File

@@ -186,8 +186,9 @@ namespace Umbraco.Core.Services.Implement
/// <param name="email">Email of the <see cref="IMembershipUser"/> to create</param>
/// <param name="passwordValue">This value should be the encoded/encrypted/hashed value for the password that will be stored in the database</param>
/// <param name="memberTypeAlias">Alias of the Type</param>
/// <param name="isApproved"></param>
/// <returns><see cref="IMember"/></returns>
IMember IMembershipMemberService<IMember>.CreateWithIdentity(string username, string email, string passwordValue, string memberTypeAlias, bool isApproved = true)
IMember IMembershipMemberService<IMember>.CreateWithIdentity(string username, string email, string passwordValue, string memberTypeAlias, bool isApproved)
{
return CreateMemberWithIdentity(username, email, username, passwordValue, memberTypeAlias, isApproved);
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -47,7 +47,6 @@
<Reference Include="System.Runtime.Caching" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Transactions" />
<Reference Include="System.ValueTuple" />
<Reference Include="System.Web" />
<Reference Include="System.Web.ApplicationServices" />
<Reference Include="System.Web.Extensions" />
@@ -74,7 +73,7 @@
<PackageReference Include="Microsoft.Owin.Security.OAuth" Version="4.0.0" />
<PackageReference Include="Microsoft.Web.Xdt" Version="2.1.2" />
<PackageReference Include="MiniProfiler" Version="3.2.0.157" />
<PackageReference Include="MySql.Data" Version="6.10.6" />
<PackageReference Include="MySql.Data" Version="6.10.7" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<PackageReference Include="NPoco" Version="3.9.3" />
<PackageReference Include="NuGet.Core" Version="2.14.0" />
@@ -395,6 +394,7 @@
<Compile Include="PropertyEditors\ValueConverters\ImageCropperValueTypeConverter.cs" />
<Compile Include="PropertyEditors\ValueListConfiguration.cs" />
<Compile Include="PropertyEditors\VoidEditor.cs" />
<Compile Include="ReadLock.cs" />
<Compile Include="ReflectionUtilities-Unused.cs" />
<Compile Include="Runtime\CoreRuntime.cs" />
<Compile Include="Runtime\CoreRuntimeComponent.cs" />
@@ -836,9 +836,7 @@
<Compile Include="ObjectExtensions.cs" />
<Compile Include="Collections\OrderedHashSet.cs" />
<Compile Include="Packaging\ConflictingPackageData.cs" />
<Compile Include="Packaging\DefaultPackageContext.cs" />
<Compile Include="Packaging\IConflictingPackageData.cs" />
<Compile Include="Packaging\IPackageContext.cs" />
<Compile Include="Packaging\IPackageExtraction.cs" />
<Compile Include="Packaging\IPackageInstallation.cs" />
<Compile Include="Packaging\Models\UninstallationSummary.cs" />
@@ -1265,7 +1263,6 @@
<Compile Include="PropertyEditors\ValueConverters\UploadPropertyConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\YesNoValueConverter.cs" />
<Compile Include="Publishing\ScheduledPublisher.cs" />
<Compile Include="ReadLock.cs" />
<Compile Include="ReflectionUtilities.cs" />
<Compile Include="RenderingEngine.cs" />
<Compile Include="RuntimeLevel.cs" />

View File

@@ -10,9 +10,11 @@ namespace Umbraco.Core
/// Provides a convenience methodology for implementing locked access to resources.
/// </summary>
/// <remarks>
/// Intended as an infrastructure class.
/// <para>Intended as an infrastructure class.</para>
/// <para>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!</para>
/// </remarks>
[Obsolete("stop using, allocates")]
public class WriteLock : IDisposable
{
private readonly ReaderWriterLockSlim _rwLock;

View File

@@ -69,7 +69,6 @@
<PackageReference Include="Microsoft.Diagnostics.Tracing.TraceEvent" Version="2.0.11" />
<PackageReference Include="Microsoft.DotNet.InternalAbstractions" Version="1.0.0" />
<PackageReference Include="Microsoft.DotNet.PlatformAbstractions" Version="2.0.4" />
<PackageReference Include="Microsoft.SqlServer.Compact" Version="4.0.8876.1" />
<PackageReference Include="Microsoft.Win32.Registry" Version="4.4.0" />
<PackageReference Include="Moq" Version="4.8.2" />
<PackageReference Include="NPoco" Version="3.9.3" />
@@ -157,24 +156,11 @@
<Name>Umbraco.Web</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- get NuGet packages directory -->
<PropertyGroup>
<PostBuildEvent>
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"</PostBuildEvent>
</PropertyGroup>
<PropertyGroup>
<PreBuildEvent>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</PreBuildEvent>
<PostBuildEvent>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"</PostBuildEvent>
<NuGetPackages>$(NuGetPackageFolders.Split(';')[0])</NuGetPackages>
</PropertyGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="BeforeBuild">
<ItemGroup>
<SqlCE64 Include="$(NuGetPackages)SqlServerCE\4.0.0.1\amd64\*.*" />

View File

@@ -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;
}

View File

@@ -35,7 +35,7 @@ namespace Umbraco.Tests.Models.Collections
internal void Reset(IEnumerable<OrderItem> properties)
{
Clear();
properties.ForEach(Add);
foreach (var property in properties) Add(property);
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}

View File

@@ -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());

View File

@@ -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 + ">";

View File

@@ -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();
}
}

View File

@@ -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 = [];
@@ -320,7 +320,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: "Ready to Publish?", //TODO: localize
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
@@ -416,7 +416,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;
@@ -424,7 +424,7 @@
relation = data[0];
if (relation.parentId == -1) {
if (relation.parentId === -1) {
target = { id: -1, name: "Root" };
moveNode(content, target);
} else {
@@ -481,7 +481,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;

View File

@@ -1,19 +1,18 @@
<div class="sub-view-columns">
<div class="sub-view-column-left">
<h5><localize key="contentTypeEditor_enableListViewHeading" /></h5>
<small><localize key="contentTypeEditor_enableListViewDescription" /></small>
</div>
<div class="sub-view-column-right">
<umb-list-view-settings
enable-list-view="model.isContainer"
model-alias="model.alias"
list-view-name="model.listViewEditorName"
content-type="documentType">
</umb-list-view-settings>
</div>
</div>
<umb-box>
<umb-box-content>
<div class="sub-view-columns">
<div class="sub-view-column-left">
<h5><localize key="contentTypeEditor_enableListViewHeading" /></h5>
<small><localize key="contentTypeEditor_enableListViewDescription" /></small>
</div>
<div class="sub-view-column-right">
<umb-list-view-settings
enable-list-view="model.isContainer"
model-alias="model.alias"
list-view-name="model.listViewEditorName"
content-type="documentType">
</umb-list-view-settings>
</div>
</div>
</umb-box-content>
</umb-box>

View File

@@ -1,60 +1,65 @@
<div ng-controller="Umbraco.Editors.DocumentType.PermissionsController as vm">
<div class="sub-view-columns">
<umb-box>
<umb-box-content>
<div class="sub-view-column-left">
<h5><localize key="contentTypeEditor_allowAsRootHeading" /></h5>
<small><localize key="contentTypeEditor_allowAsRootDescription" /></small>
</div>
<div class="sub-view-column-right">
<label class="checkbox no-indent">
<input type="checkbox" ng-model="model.allowAsRoot" hotkey="alt+shift+r" />
<localize key="contentTypeEditor_allowAsRootCheckbox" />
</label>
</div>
<div class="sub-view-columns">
</div>
<div class="sub-view-column-left">
<h5><localize key="contentTypeEditor_allowAsRootHeading" /></h5>
<small><localize key="contentTypeEditor_allowAsRootDescription" /></small>
</div>
<div class="sub-view-column-right">
<label class="checkbox no-indent">
<input type="checkbox" ng-model="model.allowAsRoot" hotkey="alt+shift+r" />
<localize key="contentTypeEditor_allowAsRootCheckbox" />
</label>
</div>
<div class="sub-view-columns">
</div>
<div class="sub-view-column-left">
<h5><localize key="contentTypeEditor_childNodesHeading" /></h5>
<small><localize key="contentTypeEditor_childNodesDescription" /></small>
</div>
<div class="sub-view-columns">
<div class="sub-view-column-right">
<umb-child-selector selected-children="vm.selectedChildren"
available-children="vm.contentTypes"
parent-name="model.name"
parent-icon="model.icon"
parent-id="model.id"
on-add="vm.addChild"
on-remove="vm.removeChild">
</umb-child-selector>
<div class="sub-view-column-left">
<h5><localize key="contentTypeEditor_childNodesHeading" /></h5>
<small><localize key="contentTypeEditor_childNodesDescription" /></small>
</div>
<umb-overlay ng-if="vm.childNodeSelectorOverlay.show"
model="vm.childNodeSelectorOverlay"
position="target"
view="vm.childNodeSelectorOverlay.view">
</umb-overlay>
<div class="sub-view-column-right">
<umb-child-selector selected-children="vm.selectedChildren"
available-children="vm.contentTypes"
parent-name="model.name"
parent-icon="model.icon"
parent-id="model.id"
on-add="vm.addChild"
on-remove="vm.removeChild">
</umb-child-selector>
</div>
<umb-overlay ng-if="vm.childNodeSelectorOverlay.show"
model="vm.childNodeSelectorOverlay"
position="target"
view="vm.childNodeSelectorOverlay.view">
</umb-overlay>
</div>
</div>
<div class="sub-view-columns">
</div>
<div class="sub-view-column-left">
<h5>Content Type Variation</h5>
<small>Define the rules for how this content type's properties can be varied</small>
</div>
<div class="sub-view-column-right">
<label class="checkbox no-indent">
<input type="checkbox" ng-model="model.allowCultureVariant" />
Allow varying by Culture
</label>
</div>
<div class="sub-view-columns">
</div>
<div class="sub-view-column-left">
<h5>Content Type Variation</h5>
<small>Define the rules for how this content type's properties can be varied</small>
</div>
<div class="sub-view-column-right">
<label class="checkbox no-indent">
<input type="checkbox" ng-model="model.allowCultureVariant" />
Allow varying by Culture
</label>
</div>
</div>
</umb-box-content>
</umb-box>
</div>

View File

@@ -1,23 +1,27 @@
<div class="sub-view-columns" ng-controller="Umbraco.Editors.DocumentType.TemplatesController as vm">
<div ng-controller="Umbraco.Editors.DocumentType.TemplatesController as vm">
<umb-box>
<umb-box-content>
<div class="sub-view-columns">
<div class="sub-view-column-left">
<h5><localize key="contentTypeEditor_allowedTemplatesHeading" /></h5>
<small><localize key="contentTypeEditor_allowedTemplatesDescription" /></small>
</div>
<div class="sub-view-column-right">
<umb-grid-selector
ng-if="vm.availableTemplates"
selected-items="model.allowedTemplates"
available-items="vm.availableTemplates"
default-item="model.defaultTemplate"
item-name="template"
name="model.name"
alias="model.alias"
update-placeholder="vm.updateTemplatePlaceholder">
</umb-grid-selector>
</div>
<div class="sub-view-column-left">
<h5><localize key="contentTypeEditor_allowedTemplatesHeading" /></h5>
<small><localize key="contentTypeEditor_allowedTemplatesDescription" /></small>
</div>
<div class="sub-view-column-right">
<umb-grid-selector
ng-if="vm.availableTemplates"
selected-items="model.allowedTemplates"
available-items="vm.availableTemplates"
default-item="model.defaultTemplate"
item-name="template"
name="model.name"
alias="model.alias"
update-placeholder="vm.updateTemplatePlaceholder">
</umb-grid-selector>
</div>
</div>
</umb-box-content>
</umb-box>
</div>

View File

@@ -1,19 +1,18 @@
<div class="sub-view-columns">
<div class="sub-view-column-left">
<h5><localize key="contentTypeEditor_enableListViewHeading" /></h5>
<small><localize key="contentTypeEditor_enableListViewDescription" /></small>
</div>
<div class="sub-view-column-right">
<umb-list-view-settings
enable-list-view="model.isContainer"
model-alias="model.alias"
list-view-name="model.listViewEditorName"
content-type="mediaType">
</umb-list-view-settings>
</div>
</div>
<umb-box>
<umb-box-content>
<div class="sub-view-columns">
<div class="sub-view-column-left">
<h5><localize key="contentTypeEditor_enableListViewHeading" /></h5>
<small><localize key="contentTypeEditor_enableListViewDescription" /></small>
</div>
<div class="sub-view-column-right">
<umb-list-view-settings
enable-list-view="model.isContainer"
model-alias="model.alias"
list-view-name="model.listViewEditorName"
content-type="mediaType">
</umb-list-view-settings>
</div>
</div>
</umb-box-content>
</umb-box>

View File

@@ -1,49 +1,51 @@
<div ng-controller="Umbraco.Editors.MediaType.PermissionsController as vm">
<umb-box>
<umb-box-content>
<div class="sub-view-columns">
<div class="sub-view-columns">
<div class="sub-view-column-left">
<h5><localize key="contentTypeEditor_allowAsRootHeading" /></h5>
<small><localize key="contentTypeEditor_allowAsRootDescription" /></small>
</div>
<div class="sub-view-column-right">
<label class="checkbox no-indent" >
<input type="checkbox" ng-model="model.allowAsRoot" hotkey="alt+shift+r" />
<localize key="contentTypeEditor_allowAsRootCheckbox" />
</label>
</div>
</div>
<div class="sub-view-columns">
<div class="sub-view-column-left">
<h5><localize key="contentTypeEditor_childNodesHeading" /></h5>
<small><localize key="contentTypeEditor_childNodesDescription" /></small>
</div>
<div class="sub-view-column-right">
<umb-child-selector
selected-children="vm.selectedChildren"
available-children="vm.mediaTypes"
parent-name="model.name"
parent-icon="model.icon"
parent-id="model.id"
on-add="vm.addChild"
on-remove="vm.removeChild">
</umb-child-selector>
<umb-overlay
ng-if="vm.childNodeSelectorOverlay.show"
model="vm.childNodeSelectorOverlay"
position="target"
view="vm.childNodeSelectorOverlay.view">
</umb-overlay>
</div>
</div>
<div class="sub-view-column-left">
<h5><localize key="contentTypeEditor_allowAsRootHeading" /></h5>
<small><localize key="contentTypeEditor_allowAsRootDescription" /></small>
</div>
<div class="sub-view-column-right">
<label class="checkbox no-indent" >
<input type="checkbox" ng-model="model.allowAsRoot" hotkey="alt+shift+r" />
<localize key="contentTypeEditor_allowAsRootCheckbox" />
</label>
</div>
</div>
<div class="sub-view-columns">
<div class="sub-view-column-left">
<h5><localize key="contentTypeEditor_childNodesHeading" /></h5>
<small><localize key="contentTypeEditor_childNodesDescription" /></small>
</div>
<div class="sub-view-column-right">
<umb-child-selector
selected-children="vm.selectedChildren"
available-children="vm.mediaTypes"
parent-name="model.name"
parent-icon="model.icon"
parent-id="model.id"
on-add="vm.addChild"
on-remove="vm.removeChild">
</umb-child-selector>
<umb-overlay
ng-if="vm.childNodeSelectorOverlay.show"
model="vm.childNodeSelectorOverlay"
position="target"
view="vm.childNodeSelectorOverlay.view">
</umb-overlay>
</div>
</div>
</umb-box-content>
</umb-box>
</div>

View File

@@ -19,50 +19,53 @@
</umb-editor-header>
<umb-editor-container>
<umb-box>
<umb-box-content>
<div class="flex" style="margin-bottom: 30px;">
<div class="flex" style="margin-bottom: 30px;">
<div class="flex" style="margin-left: auto;">
<div class="btn-group umb-era-button-group dropdown" style="margin-right: 10px;">
<button
type="button"
class="umb-era-button umb-button--s"
ng-click="vm.openInsertOverlay()">
<i class="icon icon-add"></i> <localize key="template_insert">Insert</localize>
</button>
<div class="flex" style="margin-left: auto;">
<div class="btn-group umb-era-button-group dropdown" style="margin-right: 10px;">
<button
type="button"
class="umb-era-button umb-button--s"
ng-click="vm.openInsertOverlay()">
<i class="icon icon-add"></i> <localize key="template_insert">Insert</localize>
</button>
<a class="umb-era-button umb-button--s dropdown-toggle umb-button-group__toggle" data-toggle="dropdown">
<span class="caret"></span>
</a>
<a class="umb-era-button umb-button--s dropdown-toggle umb-button-group__toggle" data-toggle="dropdown">
<span class="caret"></span>
</a>
<ul aria-labelledby="dLabel" class="dropdown-menu bottom-up umb-button-group__sub-buttons" role="menu">
<li><a href="" ng-click="vm.openPageFieldOverlay()"><localize key="template_insertPageField">Value</localize></a></li>
<li><a href="" ng-click="vm.openMacroOverlay()"><localize key="template_insertMacro">Macro</localize></a></li>
<li><a href="" ng-click="vm.openDictionaryItemOverlay()"><localize key="template_insertDictionaryItem">Dictionary item</localize></a></li>
</ul>
<ul aria-labelledby="dLabel" class="dropdown-menu bottom-up umb-button-group__sub-buttons" role="menu">
<li><a href="" ng-click="vm.openPageFieldOverlay()"><localize key="template_insertPageField">Value</localize></a></li>
<li><a href="" ng-click="vm.openMacroOverlay()"><localize key="template_insertMacro">Macro</localize></a></li>
<li><a href="" ng-click="vm.openDictionaryItemOverlay()"><localize key="template_insertDictionaryItem">Dictionary item</localize></a></li>
</ul>
</div>
<button
type="button"
style="margin-right: 10px;"
class="umb-era-button umb-button--s"
ng-click="vm.openQueryBuilderOverlay()">
<i class="icon icon-wand"></i> <localize key="template_queryBuilder">Query builder</localize>
</button>
</div>
</div>
<button
type="button"
style="margin-right: 10px;"
class="umb-era-button umb-button--s"
ng-click="vm.openQueryBuilderOverlay()">
<i class="icon icon-wand"></i> <localize key="template_queryBuilder">Query builder</localize>
</button>
</div>
</div>
<div
auto-scale="85"
umb-ace-editor="vm.aceOption"
model="vm.partialViewMacro.content">
</div>
<div
auto-scale="85"
umb-ace-editor="vm.aceOption"
model="vm.partialViewMacro.content">
</div>
</umb-box-content>
</umb-box>
</umb-editor-container>
<umb-editor-footer>

View File

@@ -20,49 +20,54 @@
<umb-editor-container>
<div class="flex" style="margin-bottom: 30px;">
<umb-box>
<umb-box-content>
<div class="flex" style="margin-bottom: 30px;">
<div class="flex" style="margin-left: auto;">
<div class="btn-group umb-era-button-group dropdown" style="margin-right: 10px;">
<button
type="button"
class="umb-era-button umb-button--s"
ng-click="vm.openInsertOverlay()">
<i class="icon icon-add"></i> <localize key="template_insert">Insert</localize>
</button>
<a class="umb-era-button umb-button--s dropdown-toggle umb-button-group__toggle" data-toggle="dropdown">
<span class="caret"></span>
</a>
<ul aria-labelledby="dLabel" class="dropdown-menu bottom-up umb-button-group__sub-buttons" role="menu">
<li><a href="" ng-click="vm.openPageFieldOverlay()"><localize key="template_insertPageField">Value</localize></a></li>
<li><a href="" ng-click="vm.openMacroOverlay()"><localize key="template_insertMacro">Macro</localize></a></li>
<li><a href="" ng-click="vm.openDictionaryItemOverlay()"><localize key="template_insertDictionaryItem">Dictionary item</localize></a></li>
</ul>
</div>
<div class="flex" style="margin-left: auto;">
<div class="btn-group umb-era-button-group dropdown" style="margin-right: 10px;">
<button
type="button"
style="margin-right: 10px;"
class="umb-era-button umb-button--s"
ng-click="vm.openInsertOverlay()">
<i class="icon icon-add"></i> <localize key="template_insert">Insert</localize>
ng-click="vm.openQueryBuilderOverlay()">
<i class="icon icon-wand"></i> <localize key="template_queryBuilder">Query builder</localize>
</button>
<a class="umb-era-button umb-button--s dropdown-toggle umb-button-group__toggle" data-toggle="dropdown">
<span class="caret"></span>
</a>
<ul aria-labelledby="dLabel" class="dropdown-menu bottom-up umb-button-group__sub-buttons" role="menu">
<li><a href="" ng-click="vm.openPageFieldOverlay()"><localize key="template_insertPageField">Value</localize></a></li>
<li><a href="" ng-click="vm.openMacroOverlay()"><localize key="template_insertMacro">Macro</localize></a></li>
<li><a href="" ng-click="vm.openDictionaryItemOverlay()"><localize key="template_insertDictionaryItem">Dictionary item</localize></a></li>
</ul>
</div>
<button
type="button"
style="margin-right: 10px;"
class="umb-era-button umb-button--s"
ng-click="vm.openQueryBuilderOverlay()">
<i class="icon icon-wand"></i> <localize key="template_queryBuilder">Query builder</localize>
</button>
</div>
</div>
<div
auto-scale="85"
umb-ace-editor="vm.aceOption"
model="vm.partialView.content">
</div>
<div
auto-scale="85"
umb-ace-editor="vm.aceOption"
model="vm.partialView.content">
</div>
</umb-box-content>
</umb-box>
</umb-editor-container>
<umb-editor-footer>

View File

@@ -19,14 +19,16 @@
</umb-editor-header>
<umb-editor-container>
<div
data-element="code-editor"
auto-scale="85"
umb-ace-editor="vm.aceOption"
model="vm.script.content">
</div>
<umb-box>
<umb-box-content>
<div
data-element="code-editor"
auto-scale="85"
umb-ace-editor="vm.aceOption"
model="vm.script.content">
</div>
</umb-box-content>
</umb-box>
</umb-editor-container>
<umb-editor-footer>

View File

@@ -7,14 +7,12 @@
novalidate
val-form-manager>
<umb-editor-view ng-if="!vm.page.loading">
<umb-editor-header
name="vm.template.name"
alias="vm.template.alias"
key="vm.template.key"
hideDescription="true"
description="vm.template.virtualPath"
description-locked="true"
menu="vm.page.menu"
@@ -23,84 +21,90 @@
<umb-editor-container>
<div class="flex" style="margin-bottom: 30px;">
<umb-box>
<umb-box-content>
<div class="flex">
<div class="flex" style="margin-bottom: 30px;">
<div ng-class="{'btn-group umb-era-button-group': vm.template.masterTemplateAlias}" style="margin-right: 10px;">
<button
data-element="button-masterTemplate"
type="button"
class="umb-era-button umb-button--s"
ng-click="vm.openMasterTemplateOverlay()">
<i class="icon icon-layout"></i>
<span class="bold"><localize key="template_mastertemplate">Master template</localize>:</span>
<span style="margin-left: 5px;">
<span ng-if="vm.template.masterTemplateAlias">{{ vm.getMasterTemplateName(vm.template.masterTemplateAlias, vm.templates) }}</span>
<span ng-if="!vm.template.masterTemplateAlias"><localize key="template_noMaster">No master</localize></span>
</span>
</button>
<div class="flex">
<a ng-if="vm.template.masterTemplateAlias" ng-click="vm.removeMasterTemplate()" class="umb-era-button umb-button--s dropdown-toggle umb-button-group__toggle">
<span class="icon icon-wrong"></span>
</a>
<div ng-class="{'btn-group umb-era-button-group': vm.template.masterTemplateAlias}" style="margin-right: 10px;">
<button
data-element="button-masterTemplate"
type="button"
class="umb-era-button umb-button--s"
ng-click="vm.openMasterTemplateOverlay()">
<i class="icon icon-layout"></i>
<span class="bold"><localize key="template_mastertemplate">Master template</localize>:</span>
<span style="margin-left: 5px;">
<span ng-if="vm.template.masterTemplateAlias">{{ vm.getMasterTemplateName(vm.template.masterTemplateAlias, vm.templates) }}</span>
<span ng-if="!vm.template.masterTemplateAlias"><localize key="template_noMaster">No master</localize></span>
</span>
</button>
<a ng-if="vm.template.masterTemplateAlias" ng-click="vm.removeMasterTemplate()" class="umb-era-button umb-button--s dropdown-toggle umb-button-group__toggle">
<span class="icon icon-wrong"></span>
</a>
</div>
</div>
<div class="flex" style="margin-left: auto;">
<div class="btn-group umb-era-button-group dropdown" style="margin-right: 10px;">
<button
data-element="button-insert"
type="button"
class="umb-era-button umb-button--s"
ng-click="vm.openInsertOverlay()">
<i class="icon icon-add"></i> <localize key="general_insert">Insert</localize>
</button>
<a class="umb-era-button umb-button--s dropdown-toggle umb-button-group__toggle" data-toggle="dropdown">
<span class="caret"></span>
</a>
<ul aria-labelledby="dLabel" class="dropdown-menu bottom-up umb-button-group__sub-buttons" role="menu">
<li><a href="" ng-click="vm.openPageFieldOverlay()"><localize key="template_insertPageField">Value</localize></a></li>
<li><a href="" ng-click="vm.openPartialOverlay()"><localize key="template_insertPartialView">Partial view</localize></a></li>
<li><a href="" ng-click="vm.openDictionaryItemOverlay()"><localize key="template_insertDictionaryItem">Dictionary</localize></a></li>
<li><a href="" ng-click="vm.openMacroOverlay()"><localize key="template_insertMacro">Macro</localize></a></li>
</ul>
</div>
<button
data-element="button-queryBuilder"
type="button"
style="margin-right: 10px;"
class="umb-era-button umb-button--s"
ng-click="vm.openQueryBuilderOverlay()">
<i class="icon icon-wand"></i> <localize key="template_queryBuilder">Query builder</localize>
</button>
<button
data-element="button-sections"
type="button"
class="umb-era-button umb-button--s"
ng-click="vm.openSectionsOverlay()">
<i class="icon icon-indent"></i> <localize key="template_insertSections">Sections</localize>
</button>
</div>
</div>
</div>
<div class="flex" style="margin-left: auto;">
<div class="btn-group umb-era-button-group dropdown" style="margin-right: 10px;">
<button
data-element="button-insert"
type="button"
class="umb-era-button umb-button--s"
ng-click="vm.openInsertOverlay()">
<i class="icon icon-add"></i> <localize key="general_insert">Insert</localize>
</button>
<a class="umb-era-button umb-button--s dropdown-toggle umb-button-group__toggle" data-toggle="dropdown">
<span class="caret"></span>
</a>
<ul aria-labelledby="dLabel" class="dropdown-menu bottom-up umb-button-group__sub-buttons" role="menu">
<li><a href="" ng-click="vm.openPageFieldOverlay()"><localize key="template_insertPageField">Value</localize></a></li>
<li><a href="" ng-click="vm.openPartialOverlay()"><localize key="template_insertPartialView">Partial view</localize></a></li>
<li><a href="" ng-click="vm.openDictionaryItemOverlay()"><localize key="template_insertDictionaryItem">Dictionary</localize></a></li>
<li><a href="" ng-click="vm.openMacroOverlay()"><localize key="template_insertMacro">Macro</localize></a></li>
</ul>
<div
data-element="code-editor"
auto-scale="85"
umb-ace-editor="vm.aceOption"
model="vm.template.content">
</div>
<button
data-element="button-queryBuilder"
type="button"
style="margin-right: 10px;"
class="umb-era-button umb-button--s"
ng-click="vm.openQueryBuilderOverlay()">
<i class="icon icon-wand"></i> <localize key="template_queryBuilder">Query builder</localize>
</button>
<button
data-element="button-sections"
type="button"
class="umb-era-button umb-button--s"
ng-click="vm.openSectionsOverlay()">
<i class="icon icon-indent"></i> <localize key="template_insertSections">Sections</localize>
</button>
</div>
</div>
<div
data-element="code-editor"
auto-scale="85"
umb-ace-editor="vm.aceOption"
model="vm.template.content">
</div>
</umb-box-content>
</umb-box>
</umb-editor-container>

View File

@@ -165,196 +165,200 @@
<div class="umb-package-details__sidebar">
<div class="umb-package-details__section">
<umb-box>
<!-- Avatar -->
<div style="margin-bottom: 20px; padding-bottom: 20px; border-bottom: 1px solid #d8d7d9;">
<ng-form name="avatarForm" class="flex flex-column justify-center items-center">
<umb-box-content>
<umb-avatar style="margin-bottom: 15px;"
color="secondary"
size="xxl"
name="{{model.user.name}}"
img-src="{{model.user.avatars[3]}}"
img-srcset="{{model.user.avatars[4]}} 2x, {{model.user.avatars[4]}} 3x">
</umb-avatar>
<!-- Avatar -->
<div style="margin-bottom: 20px; padding-bottom: 20px; border-bottom: 1px solid #d8d7d9;">
<ng-form name="avatarForm" class="flex flex-column justify-center items-center">
<umb-progress-bar style="max-width: 120px;"
ng-if="model.avatarFile.uploadStatus === 'uploading'"
progress="{{ model.avatarFile.uploadProgress }}"
size="s">
</umb-progress-bar>
<umb-avatar style="margin-bottom: 15px;"
color="secondary"
size="xxl"
name="{{model.user.name}}"
img-src="{{model.user.avatars[3]}}"
img-srcset="{{model.user.avatars[4]}} 2x, {{model.user.avatars[4]}} 3x">
</umb-avatar>
<div class="flex items-center" ng-if="model.avatarFile.uploadStatus !== 'uploading'">
<umb-progress-bar style="max-width: 120px;"
ng-if="model.avatarFile.uploadStatus === 'uploading'"
progress="{{ model.avatarFile.uploadProgress }}"
size="s">
</umb-progress-bar>
<a href=""
class="umb-user-group-preview__action"
ngf-select ng-model="filesHolder"
ngf-change="model.changeAvatar($files, $event)"
ngf-multiple="false"
ngf-pattern="{{model.acceptedFileTypes}}"
ngf-max-size="{{ model.maxFileSize }}">
<localize key="user_changePhoto">Change photo</localize>
</a>
<div class="flex items-center" ng-if="model.avatarFile.uploadStatus !== 'uploading'">
<a href=""
ng-if="model.user.avatars"
class="umb-user-group-preview__action umb-user-group-preview__action--red"
ng-click="model.clearAvatar()"
prevent-default>
<localize key="user_removePhoto">Remove photo</localize>
</a>
<a href=""
class="umb-user-group-preview__action"
ngf-select ng-model="filesHolder"
ngf-change="model.changeAvatar($files, $event)"
ngf-multiple="false"
ngf-pattern="{{model.acceptedFileTypes}}"
ngf-max-size="{{ model.maxFileSize }}">
<localize key="user_changePhoto">Change photo</localize>
</a>
<a href=""
ng-if="model.user.avatars"
class="umb-user-group-preview__action umb-user-group-preview__action--red"
ng-click="model.clearAvatar()"
prevent-default>
<localize key="user_removePhoto">Remove photo</localize>
</a>
</div>
</ng-form>
</div>
<!-- Actions -->
<div style="margin-bottom: 20px;">
<div style="margin-bottom: 10px;">
<umb-button ng-if="model.user.userDisplayState.key === 'Disabled' && !model.user.isCurrentUser"
type="button"
button-style="[success,block]"
state="model.enableUserButtonState"
action="model.enableUser()"
label="Enable"
label-key="actions_enable"
size="s">
</umb-button>
</div>
</ng-form>
<div style="margin-bottom: 10px;">
<umb-button ng-if="model.user.userDisplayState.key === 'LockedOut' && !model.user.isCurrentUser"
type="button"
button-style="[success,block]"
state="model.unlockUserButtonState"
action="model.unlockUser()"
label="Unlock"
label-key="actions_unlock"
size="s">
</umb-button>
</div>
</div>
<!-- Actions -->
<div style="margin-bottom: 20px;">
<div style="margin-bottom: 10px;">
<umb-button ng-if="model.user.userDisplayState.key === 'Disabled' && !model.user.isCurrentUser"
type="button"
button-style="[success,block]"
state="model.enableUserButtonState"
action="model.enableUser()"
label="Enable"
label-key="actions_enable"
size="s">
</umb-button>
</div>
<div style="margin-bottom: 10px;">
<umb-button ng-if="model.user.userDisplayState.key === 'LockedOut' && !model.user.isCurrentUser"
type="button"
button-style="[success,block]"
state="model.unlockUserButtonState"
action="model.unlockUser()"
label="Unlock"
label-key="actions_unlock"
size="s">
</umb-button>
</div>
<div style="margin-bottom: 10px;">
<umb-button ng-if="model.user.userDisplayState.key !== 'Disabled' && !model.user.isCurrentUser"
type="button"
button-style="[info,block]"
action="model.disableUser()"
state="model.disableUserButtonState"
label="Disable"
label-key="actions_disable"
size="s">
</umb-button>
</div>
<umb-button type="button"
button-style="[info,block]"
action="model.toggleChangePassword()"
label="Change password"
label-key="general_changePassword"
state="changePasswordButtonState"
ng-if="model.changePasswordModel.isChanging === false"
size="s">
</umb-button>
<ng-form ng-if="model.changePasswordModel.isChanging" name="passwordForm" class="block-form" val-form-manager>
<change-password password-values="model.user.changePassword"
config="model.changePasswordModel.config">
</change-password>
<div style="margin-bottom: 10px;">
<umb-button ng-if="model.user.userDisplayState.key !== 'Disabled' && !model.user.isCurrentUser"
type="button"
button-style="[info,block]"
action="model.disableUser()"
state="model.disableUserButtonState"
label="Disable"
label-key="actions_disable"
size="s">
</umb-button>
</div>
<umb-button type="button"
button-style="[info,block]"
action="model.toggleChangePassword()"
label="Cancel"
label-key="general_cancel"
button-style="cancel">
label="Change password"
label-key="general_changePassword"
state="changePasswordButtonState"
ng-if="model.changePasswordModel.isChanging === false"
size="s">
</umb-button>
</ng-form>
<ng-form ng-if="model.changePasswordModel.isChanging" name="passwordForm" class="block-form" val-form-manager>
<change-password password-values="model.user.changePassword"
config="model.changePasswordModel.config">
</change-password>
<umb-button type="button"
action="model.toggleChangePassword()"
label="Cancel"
label-key="general_cancel"
button-style="cancel">
</umb-button>
</ng-form>
<div ng-if="model.user.resetPasswordValue">
<p><br />Password reset to value: <strong>{{model.user.resetPasswordValue}}</strong></p>
</div>
<div ng-if="model.user.resetPasswordValue">
<p><br />Password reset to value: <strong>{{model.user.resetPasswordValue}}</strong></p>
</div>
</div>
<!-- User stats -->
<div class="umb-package-details__information-item">
<div class="umb-package-details__information-item-label">
<localize key="general_status">Status</localize>:
</div>
<div class="umb-package-details__information-item-content">
<umb-badge style="margin-top: 4px;" size="s" color="{{model.user.userDisplayState.color}}">
{{model.user.userDisplayState.name}}
</umb-badge>
</div>
</div>
<!-- User stats -->
<div class="umb-package-details__information-item">
<div class="umb-package-details__information-item-label">
<localize key="general_status">Status</localize>:
<div class="umb-package-details__information-item">
<div class="umb-package-details__information-item-label">
<localize key="user_lastLogin">Last login</localize>:
</div>
<div class="umb-package-details__information-item-content">
<span ng-if="model.user.lastLoginDate">{{ model.user.formattedLastLogin }}</span>
<span ng-if="!model.user.lastLoginDate">{{ model.user.name | umbWordLimit:1 }} <localize key="user_noLogin">has not logged in yet</localize></span>
</div>
</div>
<div class="umb-package-details__information-item-content">
<umb-badge style="margin-top: 4px;" size="s" color="{{model.user.userDisplayState.color}}">
{{model.user.userDisplayState.name}}
</umb-badge>
</div>
</div>
<div class="umb-package-details__information-item">
<div class="umb-package-details__information-item-label">
<localize key="user_lastLogin">Last login</localize>:
<div class="umb-package-details__information-item">
<div class="umb-package-details__information-item-label">
<localize key="user_failedPasswordAttempts">Failed login attempts</localize>:
</div>
<div class="umb-package-details__information-item-content">
{{ model.user.failedPasswordAttempts }}
</div>
</div>
<div class="umb-package-details__information-item-content">
<span ng-if="model.user.lastLoginDate">{{ model.user.formattedLastLogin }}</span>
<span ng-if="!model.user.lastLoginDate">{{ model.user.name | umbWordLimit:1 }} <localize key="user_noLogin">has not logged in yet</localize></span>
</div>
</div>
<div class="umb-package-details__information-item">
<div class="umb-package-details__information-item-label">
<localize key="user_failedPasswordAttempts">Failed login attempts</localize>:
<div class="umb-package-details__information-item">
<div class="umb-package-details__information-item-label">
<localize key="user_lastLockoutDate">Last lockout date</localize>:
</div>
<div class="umb-package-details__information-item-content">
<span ng-if="model.user.lastLockoutDate === '0001-01-01T00:00:00'">
{{ model.user.name | umbWordLimit:1 }} <localize key="user_noLockouts">hasn't been locked out</localize>
</span>
<span ng-if="model.user.lastLockoutDate !== '0001-01-01T00:00:00'">{{ model.user.formattedLastLockoutDate }}</span>
</div>
</div>
<div class="umb-package-details__information-item-content">
{{ model.user.failedPasswordAttempts }}
</div>
</div>
<div class="umb-package-details__information-item">
<div class="umb-package-details__information-item-label">
<localize key="user_lastLockoutDate">Last lockout date</localize>:
<div class="umb-package-details__information-item">
<div class="umb-package-details__information-item-label">
<localize key="user_lastPasswordChangeDate">Password is last changed</localize>:
</div>
<div class="umb-package-details__information-item-content">
<span ng-if="model.user.lastPasswordChangeDate === '0001-01-01T00:00:00'">
<localize key="user_noPasswordChange">The password hasn't been changed</localize>
</span>
<span ng-if="model.user.lastPasswordChangeDate !== '0001-01-01T00:00:00'">{{ model.user.formattedLastPasswordChangeDate }}</span>
</div>
</div>
<div class="umb-package-details__information-item-content">
<span ng-if="model.user.lastLockoutDate === '0001-01-01T00:00:00'">
{{ model.user.name | umbWordLimit:1 }} <localize key="user_noLockouts">hasn't been locked out</localize>
</span>
<span ng-if="model.user.lastLockoutDate !== '0001-01-01T00:00:00'">{{ model.user.formattedLastLockoutDate }}</span>
</div>
</div>
<div class="umb-package-details__information-item">
<div class="umb-package-details__information-item-label">
<localize key="user_lastPasswordChangeDate">Password is last changed</localize>:
<div class="umb-package-details__information-item">
<div class="umb-package-details__information-item-label">
<localize key="user_createDate">User is created</localize>:
</div>
<div class="umb-package-details__information-item-content">
{{ model.user.formattedCreateDate }}
</div>
</div>
<div class="umb-package-details__information-item-content">
<span ng-if="model.user.lastPasswordChangeDate === '0001-01-01T00:00:00'">
<localize key="user_noPasswordChange">The password hasn't been changed</localize>
</span>
<span ng-if="model.user.lastPasswordChangeDate !== '0001-01-01T00:00:00'">{{ model.user.formattedLastPasswordChangeDate }}</span>
</div>
</div>
<div class="umb-package-details__information-item">
<div class="umb-package-details__information-item-label">
<localize key="user_createDate">User is created</localize>:
<div class="umb-package-details__information-item">
<div class="umb-package-details__information-item-label">
<localize key="user_updateDate">User is last updated</localize>:
</div>
<div class="umb-package-details__information-item-content">
{{ model.user.formattedUpdateDate }}
</div>
</div>
<div class="umb-package-details__information-item-content">
{{ model.user.formattedCreateDate }}
</div>
</div>
<div class="umb-package-details__information-item">
<div class="umb-package-details__information-item-label">
<localize key="user_updateDate">User is last updated</localize>:
</div>
<div class="umb-package-details__information-item-content">
{{ model.user.formattedUpdateDate }}
</div>
</div>
</umb-box-content>
</div>
</umb-box>
</div>

View File

@@ -121,7 +121,7 @@
<PackageReference Include="Microsoft.Owin.Security.Cookies" Version="4.0.0" />
<PackageReference Include="Microsoft.Owin.Security.OAuth" Version="4.0.0" />
<PackageReference Include="MiniProfiler" Version="3.2.0.157" />
<PackageReference Include="MySql.Data" Version="6.10.6" />
<PackageReference Include="MySql.Data" Version="6.10.7" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<PackageReference Include="SqlServerCE" Version="4.0.0.1" />
<PackageReference Include="System.Reflection.Metadata" Version="1.5.0" />
@@ -656,11 +656,12 @@
<Target Name="CleanBelle" AfterTargets="Clean" Condition="'$(UmbracoBuild)' == ''">
<Message Text="-CleanBelle-" Importance="high" />
<Message Text="Nothing to clean, as $(ProjectDir)Umbraco\lib does not exist." Importance="High" Condition="!Exists('$(ProjectDir)Umbraco\lib')" />
<Message Text="Remove $(ProjectDir)Umbraco\lib." Importance="High" Condition="Exists('$(ProjectDir)Umbraco\lib')" />
<Message Text="Not cleaning (found src/preserve.belle)." Importance="High" Condition="Exists('$(ProjectDir)Umbraco\lib') and Exists('$(SolutionDir)preserve.belle')" />
<Message Text="Remove $(ProjectDir)Umbraco\lib." Importance="High" Condition="Exists('$(ProjectDir)Umbraco\lib') and !Exists('$(SolutionDir)preserve.belle')" />
<ItemGroup>
<BelleLib Include="$(ProjectDir)Umbraco\lib" />
</ItemGroup>
<RemoveDir Directories="@(BelleLib)" />
<RemoveDir Directories="@(BelleLib)" Condition="Exists('$(ProjectDir)Umbraco\lib') and !Exists('$(SolutionDir)preserve.belle')"/>
</Target>
<Target Name="AfterBuild">
<Message Text="-AfterBuild-" Importance="high" />

View File

@@ -235,7 +235,7 @@
<key alias="languagesToPublish">What languages would you like to publish?</key>
<key alias="noLanguagesToPublish">No languages available to be published.</key>
<key alias="publishedLanguages">Published Languages.</key>
<key alias="readyToPublish">Ready to Publish?</key>
</area>
<area alias="blueprints">
<key alias="createBlueprintFrom">Create a new Content Template from '%0%'</key>

View File

@@ -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.
-->
<system.web>
<compilation debug="true" xdt:Transform="SetAttributes(debug)" />
</system.web>
<compilation debug="true" xdt:Transform="SetAttributes(debug)">
</compilation>
<!--
<!--
FIXME
for historical reasons, this file tries to cleanup everything as much as it can
BUT it means that it needs to be kept in sync with web.Template.config very closely

View File

@@ -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<IMacro>();
@@ -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<IMacro>();
if (macroRepoCache)
{
macroRepoCache.Result.ClearCacheItem(RepositoryCacheKeys.GetKey<IMacro>(payload.Id));
}
});
};
base.Refresh(json);
}

View File

@@ -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);
};
}
}
}

View File

@@ -373,7 +373,6 @@ namespace Umbraco.Web.Editors
// Services.TextService.Localize("speechBubbles/partialViewErrorHeader"),
// Services.TextService.Localize("speechBubbles/partialViewErrorText"));
break;

View File

@@ -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

View File

@@ -89,8 +89,6 @@ namespace Umbraco.Web.Editors
{
if (pack == null) throw new ArgumentNullException("pack");
var refreshCache = false;
var removedTemplates = new List<ITemplate>();
var removedMacros = new List<IMacro>();
var removedContentTypes = new List<IContentType>();
@@ -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

View File

@@ -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)

View File

@@ -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.

View File

@@ -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");
}

View File

@@ -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

View File

@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Globalization;
using Umbraco.Web.Mvc;
using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Web.Routing
{

View File

@@ -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;

View File

@@ -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
{

View File

@@ -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();

View File

@@ -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;
}

View File

@@ -51,8 +51,6 @@
<Reference Include="System.Runtime.Caching" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.ServiceModel" />
<Reference Include="System.Threading.Tasks.Dataflow" />
<Reference Include="System.ValueTuple" />
<Reference Include="System.Web" />
<Reference Include="System.Web.Abstractions" />
<Reference Include="System.Web.ApplicationServices" />

View File

@@ -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();

View File

@@ -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;

View File

@@ -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;

View File

@@ -21,8 +21,6 @@ namespace umbraco.presentation.webservices
[ScriptService]
public class legacyAjaxCalls : UmbracoAuthorizedWebService
{
private IUser _currentUser;
/// <summary>
/// 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