Merge remote-tracking branch 'origin/temp8' into temp8-U4-11282
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 (
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
using NuGet;
|
||||
|
||||
namespace Umbraco.Core.Packaging
|
||||
{
|
||||
internal interface IPackageContext
|
||||
{
|
||||
IPackageManager LocalPackageManager { get; }
|
||||
IPackageManager PublicPackageManager { get; }
|
||||
IPackagePathResolver LocalPathResolver { get; }
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 />
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -26,8 +26,6 @@ namespace Umbraco.Core.Security
|
||||
validation=""HMACSHA256"" decryption=""AES""
|
||||
/>";
|
||||
|
||||
var Xxx = 3;
|
||||
|
||||
return string.Format(c, GenerateAESDecryptionKey(), GenerateHMACSHA256ValidationKey());
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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\*.*" />
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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 + ">";
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -373,7 +373,6 @@ namespace Umbraco.Web.Editors
|
||||
// Services.TextService.Localize("speechBubbles/partialViewErrorHeader"),
|
||||
// Services.TextService.Localize("speechBubbles/partialViewErrorText"));
|
||||
|
||||
break;
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using Umbraco.Web.Mvc;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Web.Routing
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user