Compare commits
96 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ddbe15de08 | |||
| 5c5d63ce9a | |||
| d3916a1d85 | |||
| db7cb2dcb4 | |||
| 6281268954 | |||
| cd606a7e9e | |||
| ae9d77a765 | |||
| f6e44b4e7c | |||
| 8e1c45e981 | |||
| 955282f260 | |||
| 4a7ee52d63 | |||
| b4d88b0361 | |||
| b41cf37dd5 | |||
| e6fcdc8dc6 | |||
| 547a137b9a | |||
| 5041e6fcc4 | |||
| db0d139a39 | |||
| fc32100142 | |||
| 7ecbc3b391 | |||
| c3c44df52e | |||
| 13a86624ff | |||
| 2f61bc27c8 | |||
| f484dbf0fc | |||
| 6d0ededd9f | |||
| e7d157a209 | |||
| d3ed90c23e | |||
| f6155d8e49 | |||
| c1cd609325 | |||
| b916360771 | |||
| db4b93dbc3 | |||
| fa8934f89a | |||
| c6940096d3 | |||
| 40868ac361 | |||
| f399a9f52b | |||
| 562851b93e | |||
| 634e4a6949 | |||
| e61b567ee1 | |||
| 7ccae64dd1 | |||
| aef44065c5 | |||
| 4ce22b836e | |||
| 2b8544b4c7 | |||
| 6afa6a277f | |||
| f5bf05a6f5 | |||
| 469db82f1d | |||
| e50569597b | |||
| 071f3dcc01 | |||
| e0bc99af9c | |||
| 232581664b | |||
| b15e147d6b | |||
| c7a4c782e3 | |||
| 780908e24f | |||
| 3ac7e237c4 | |||
| 6943a454f3 | |||
| e870db3c29 | |||
| 41b17160f7 | |||
| b19621c07b | |||
| 0ff979e814 | |||
| f26e39f5ce | |||
| 9a6030a3eb | |||
| 84ef216d57 | |||
| ecfe51134d | |||
| c8414116ad | |||
| 532f407260 | |||
| 834d04f8ed | |||
| 2aa902beaf | |||
| 2f16e6662d | |||
| 0c4897d7c1 | |||
| 43dc14fa93 | |||
| e209aa3c2a | |||
| 5890fe1849 | |||
| b6f52bf782 | |||
| 922ebe5411 | |||
| f36ab37f6a | |||
| aeff33d0a6 | |||
| 645637d550 | |||
| 5cfe9e57ce | |||
| 4863e657df | |||
| 2486e75210 | |||
| c0e1be4df9 | |||
| a93e562f14 | |||
| 2201c644f7 | |||
| 822cac5d87 | |||
| d58487fafc | |||
| ea9653fa83 | |||
| b38397868e | |||
| 7d1a18638b | |||
| 748e88c3e8 | |||
| cb8d080f1d | |||
| 3fd3bf0fda | |||
| 09a6cdc8b6 | |||
| b2fe35695f | |||
| 67b57dea50 | |||
| 3d6172738f | |||
| d94772892d | |||
| 50c12a5c35 | |||
| b42fb1c5c1 |
@@ -32,3 +32,4 @@ b247b35d821144849f551e02da8ba719f91d5fb0 Release-6.0.2
|
||||
aed55cba29009ad3db48880a7cfb66407ce9805f release-6.0.3
|
||||
87cf618a39e38ec58df916d10e6a924de62ae37d release-6.1.0-beta
|
||||
0dee9964687ea51ea797984cf7cce3655d6a6558 release-6.0.4
|
||||
7670bb47a671a9ecc15118589d8048907ea76241 release-6.1.0-beta2
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
@ECHO OFF
|
||||
SET release=6.1.0
|
||||
SET comment=beta-2
|
||||
SET comment=
|
||||
SET version=%release%
|
||||
|
||||
IF [%comment%] EQU [] (SET version=%release%) ELSE (SET version=%release%-%comment%)
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Web.Caching;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// An abstract class for implementing a cache helper
|
||||
/// An abstract class for implementing a basic cache provider
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// THIS MUST REMAIN INTERNAL UNTIL WE STREAMLINE HOW ALL CACHE IS HANDLED, WE NEED TO SUPPORT HTTP RUNTIME CACHE, IN MEMORY CACHE, ETC...
|
||||
@@ -22,13 +20,5 @@ namespace Umbraco.Core.Cache
|
||||
public abstract IEnumerable<T> GetCacheItemsByKeySearch<T>(string keyStartsWith);
|
||||
public abstract T GetCacheItem<T>(string cacheKey);
|
||||
public abstract T GetCacheItem<T>(string cacheKey, Func<T> getCacheItem);
|
||||
public abstract T GetCacheItem<T>(string cacheKey, TimeSpan? timeout, Func<T> getCacheItem);
|
||||
public abstract T GetCacheItem<T>(string cacheKey, CacheItemRemovedCallback refreshAction, TimeSpan? timeout, Func<T> getCacheItem);
|
||||
public abstract T GetCacheItem<T>(string cacheKey, CacheItemPriority priority, CacheItemRemovedCallback refreshAction, TimeSpan? timeout, Func<T> getCacheItem);
|
||||
public abstract T GetCacheItem<T>(string cacheKey, CacheItemPriority priority, CacheItemRemovedCallback refreshAction, CacheDependency cacheDependency, TimeSpan? timeout, Func<T> getCacheItem);
|
||||
public abstract void InsertCacheItem<T>(string cacheKey, CacheItemPriority priority, Func<T> getCacheItem);
|
||||
public abstract void InsertCacheItem<T>(string cacheKey, CacheItemPriority priority, TimeSpan? timeout, Func<T> getCacheItem);
|
||||
public abstract void InsertCacheItem<T>(string cacheKey, CacheItemPriority priority, CacheDependency cacheDependency, TimeSpan? timeout, Func<T> getCacheItem);
|
||||
public abstract void InsertCacheItem<T>(string cacheKey, CacheItemPriority priority, CacheItemRemovedCallback refreshAction, CacheDependency cacheDependency, TimeSpan? timeout, Func<T> getCacheItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ namespace Umbraco.Core.Cache
|
||||
/// <summary>
|
||||
/// A CacheProvider that wraps the logic of the HttpRuntime.Cache
|
||||
/// </summary>
|
||||
internal class HttpRuntimeCacheProvider : CacheProviderBase
|
||||
internal class HttpRuntimeCacheProvider : RuntimeCacheProviderBase
|
||||
{
|
||||
private readonly System.Web.Caching.Cache _cache;
|
||||
private static readonly object Locker = new object();
|
||||
|
||||
@@ -5,7 +5,7 @@ using System.Web.Caching;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
internal class NullCacheProvider : CacheProviderBase
|
||||
internal class NullCacheProvider : RuntimeCacheProviderBase
|
||||
{
|
||||
public override void ClearAllCache()
|
||||
{
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Web.Caching;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// An abstract class for implementing a runtime cache provider
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// THIS MUST REMAIN INTERNAL UNTIL WE STREAMLINE HOW ALL CACHE IS HANDLED, WE NEED TO SUPPORT HTTP RUNTIME CACHE, IN MEMORY CACHE, ETC...
|
||||
/// </remarks>
|
||||
internal abstract class RuntimeCacheProviderBase : CacheProviderBase
|
||||
{
|
||||
public abstract T GetCacheItem<T>(string cacheKey, TimeSpan? timeout, Func<T> getCacheItem);
|
||||
public abstract T GetCacheItem<T>(string cacheKey, CacheItemRemovedCallback refreshAction, TimeSpan? timeout, Func<T> getCacheItem);
|
||||
public abstract T GetCacheItem<T>(string cacheKey, CacheItemPriority priority, CacheItemRemovedCallback refreshAction, TimeSpan? timeout, Func<T> getCacheItem);
|
||||
public abstract T GetCacheItem<T>(string cacheKey, CacheItemPriority priority, CacheItemRemovedCallback refreshAction, CacheDependency cacheDependency, TimeSpan? timeout, Func<T> getCacheItem);
|
||||
public abstract void InsertCacheItem<T>(string cacheKey, CacheItemPriority priority, Func<T> getCacheItem);
|
||||
public abstract void InsertCacheItem<T>(string cacheKey, CacheItemPriority priority, TimeSpan? timeout, Func<T> getCacheItem);
|
||||
public abstract void InsertCacheItem<T>(string cacheKey, CacheItemPriority priority, CacheDependency cacheDependency, TimeSpan? timeout, Func<T> getCacheItem);
|
||||
public abstract void InsertCacheItem<T>(string cacheKey, CacheItemPriority priority, CacheItemRemovedCallback refreshAction, CacheDependency cacheDependency, TimeSpan? timeout, Func<T> getCacheItem);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Web.Caching;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// A cache provider that statically caches everything in an in memory dictionary
|
||||
/// </summary>
|
||||
internal class StaticCacheProvider : CacheProviderBase
|
||||
{
|
||||
private readonly ConcurrentDictionary<string, object> _staticCache = new ConcurrentDictionary<string, object>();
|
||||
|
||||
public override void ClearAllCache()
|
||||
{
|
||||
_staticCache.Clear();
|
||||
}
|
||||
|
||||
public override void ClearCacheItem(string key)
|
||||
{
|
||||
object val;
|
||||
_staticCache.TryRemove(key, out val);
|
||||
}
|
||||
|
||||
public override void ClearCacheObjectTypes(string typeName)
|
||||
{
|
||||
foreach (var key in _staticCache.Keys)
|
||||
{
|
||||
if (_staticCache[key] != null
|
||||
&& _staticCache[key].GetType().ToString().InvariantEquals(typeName))
|
||||
{
|
||||
object val;
|
||||
_staticCache.TryRemove(key, out val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void ClearCacheObjectTypes<T>()
|
||||
{
|
||||
foreach (var key in _staticCache.Keys)
|
||||
{
|
||||
if (_staticCache[key] != null
|
||||
&& _staticCache[key].GetType() == typeof(T))
|
||||
{
|
||||
object val;
|
||||
_staticCache.TryRemove(key, out val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void ClearCacheByKeySearch(string keyStartsWith)
|
||||
{
|
||||
foreach (var key in _staticCache.Keys)
|
||||
{
|
||||
if (key.InvariantStartsWith(keyStartsWith))
|
||||
{
|
||||
ClearCacheItem(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void ClearCacheByKeyExpression(string regexString)
|
||||
{
|
||||
foreach (var key in _staticCache.Keys)
|
||||
{
|
||||
if (Regex.IsMatch(key, regexString))
|
||||
{
|
||||
ClearCacheItem(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override IEnumerable<T> GetCacheItemsByKeySearch<T>(string keyStartsWith)
|
||||
{
|
||||
return (from KeyValuePair<string, object> c in _staticCache
|
||||
where c.Key.InvariantStartsWith(keyStartsWith)
|
||||
select c.Value.TryConvertTo<T>()
|
||||
into attempt
|
||||
where attempt.Success
|
||||
select attempt.Result).ToList();
|
||||
}
|
||||
|
||||
public override T GetCacheItem<T>(string cacheKey)
|
||||
{
|
||||
var result = _staticCache[cacheKey];
|
||||
if (result == null)
|
||||
{
|
||||
return default(T);
|
||||
}
|
||||
return result.TryConvertTo<T>().Result;
|
||||
}
|
||||
|
||||
public override T GetCacheItem<T>(string cacheKey, Func<T> getCacheItem)
|
||||
{
|
||||
return (T)_staticCache.GetOrAdd(cacheKey, getCacheItem);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+240
-76
@@ -15,14 +15,13 @@ namespace Umbraco.Core
|
||||
/// <summary>
|
||||
/// Class that is exposed by the ApplicationContext for application wide caching purposes
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This class may be opened publicly at some point but needs a review of what is absoletely necessary.
|
||||
/// </remarks>
|
||||
public class CacheHelper //: CacheProviderBase
|
||||
public class CacheHelper
|
||||
{
|
||||
private readonly bool _enableCache;
|
||||
private readonly HttpRuntimeCacheProvider _httpCache;
|
||||
private readonly NullCacheProvider _nullCache = new NullCacheProvider();
|
||||
private readonly CacheProviderBase _staticCache;
|
||||
private readonly CacheProviderBase _nullStaticCache = new NullCacheProvider();
|
||||
private readonly RuntimeCacheProviderBase _httpCache;
|
||||
private readonly RuntimeCacheProviderBase _nullHttpCache = new NullCacheProvider();
|
||||
|
||||
public CacheHelper(System.Web.Caching.Cache cache)
|
||||
: this(cache, true)
|
||||
@@ -30,21 +29,185 @@ namespace Umbraco.Core
|
||||
}
|
||||
|
||||
internal CacheHelper(System.Web.Caching.Cache cache, bool enableCache)
|
||||
{
|
||||
_httpCache = new HttpRuntimeCacheProvider(cache);
|
||||
_enableCache = enableCache;
|
||||
: this(new HttpRuntimeCacheProvider(cache), enableCache)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
internal CacheHelper(RuntimeCacheProviderBase httpCacheProvider, bool enableCache)
|
||||
: this(httpCacheProvider, new StaticCacheProvider(), enableCache)
|
||||
{
|
||||
}
|
||||
|
||||
internal CacheHelper(RuntimeCacheProviderBase httpCacheProvider, CacheProviderBase staticCacheProvider, bool enableCache)
|
||||
{
|
||||
_httpCache = httpCacheProvider;
|
||||
_staticCache = staticCacheProvider;
|
||||
_enableCache = enableCache;
|
||||
}
|
||||
|
||||
#region Static cache
|
||||
|
||||
/// <summary>
|
||||
/// Clears the item in umbraco's static cache
|
||||
/// </summary>
|
||||
internal void ClearAllStaticCache()
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
_nullStaticCache.ClearAllCache();
|
||||
}
|
||||
else
|
||||
{
|
||||
_staticCache.ClearAllCache();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the item in umbraco's static cache with the given key
|
||||
/// </summary>
|
||||
/// <param name="key">Key</param>
|
||||
internal void ClearStaticCacheItem(string key)
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
_nullStaticCache.ClearCacheItem(key);
|
||||
}
|
||||
else
|
||||
{
|
||||
_staticCache.ClearCacheItem(key);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears all objects in the static cache with the System.Type name as the
|
||||
/// input parameter. (using [object].GetType())
|
||||
/// </summary>
|
||||
/// <param name="typeName">The name of the System.Type which should be cleared from cache ex "System.Xml.XmlDocument"</param>
|
||||
internal void ClearStaticCacheObjectTypes(string typeName)
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
_nullStaticCache.ClearCacheObjectTypes(typeName);
|
||||
}
|
||||
else
|
||||
{
|
||||
_staticCache.ClearCacheObjectTypes(typeName);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears all objects in the static cache with the System.Type specified
|
||||
/// </summary>
|
||||
internal void ClearStaticCacheObjectTypes<T>()
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
_nullStaticCache.ClearCacheObjectTypes<T>();
|
||||
}
|
||||
else
|
||||
{
|
||||
_staticCache.ClearCacheObjectTypes<T>();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears all static cache items that starts with the key passed.
|
||||
/// </summary>
|
||||
/// <param name="keyStartsWith">The start of the key</param>
|
||||
internal void ClearStaticCacheByKeySearch(string keyStartsWith)
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
_nullStaticCache.ClearCacheByKeySearch(keyStartsWith);
|
||||
}
|
||||
else
|
||||
{
|
||||
_staticCache.ClearCacheByKeySearch(keyStartsWith);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears all cache items that have a key that matches the regular expression
|
||||
/// </summary>
|
||||
/// <param name="regexString"></param>
|
||||
internal void ClearStaticCacheByKeyExpression(string regexString)
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
_nullStaticCache.ClearCacheByKeyExpression(regexString);
|
||||
}
|
||||
else
|
||||
{
|
||||
_staticCache.ClearCacheByKeyExpression(regexString);
|
||||
}
|
||||
}
|
||||
|
||||
internal IEnumerable<T> GetStaticCacheItemsByKeySearch<T>(string keyStartsWith)
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
return _nullStaticCache.GetCacheItemsByKeySearch<T>(keyStartsWith);
|
||||
}
|
||||
else
|
||||
{
|
||||
return _staticCache.GetCacheItemsByKeySearch<T>(keyStartsWith);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a static cache item by key, does not update the cache if it isn't there.
|
||||
/// </summary>
|
||||
/// <typeparam name="TT"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <returns></returns>
|
||||
internal TT GetStaticCacheItem<TT>(string cacheKey)
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
return _nullStaticCache.GetCacheItem<TT>(cacheKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
return _staticCache.GetCacheItem<TT>(cacheKey);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets (and adds if necessary) an item from the static cache with all of the default parameters
|
||||
/// </summary>
|
||||
/// <typeparam name="TT"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
/// <returns></returns>
|
||||
internal TT GetStaticCacheItem<TT>(string cacheKey, Func<TT> getCacheItem)
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
return _nullStaticCache.GetCacheItem<TT>(cacheKey, getCacheItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
return _staticCache.GetCacheItem<TT>(cacheKey, getCacheItem);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Runtime/Http Cache
|
||||
/// <summary>
|
||||
/// Clears the item in umbraco's runtime cache
|
||||
/// </summary>
|
||||
public void ClearAllCache()
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
_nullCache.ClearAllCache();
|
||||
}
|
||||
else
|
||||
{
|
||||
_httpCache.ClearAllCache();
|
||||
}
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
_nullHttpCache.ClearAllCache();
|
||||
}
|
||||
else
|
||||
{
|
||||
_httpCache.ClearAllCache();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -55,7 +218,7 @@ namespace Umbraco.Core
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
_nullCache.ClearCacheItem(key);
|
||||
_nullHttpCache.ClearCacheItem(key);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -73,7 +236,7 @@ namespace Umbraco.Core
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
_nullCache.ClearCacheObjectTypes(typeName);
|
||||
_nullHttpCache.ClearCacheObjectTypes(typeName);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -84,55 +247,55 @@ namespace Umbraco.Core
|
||||
/// <summary>
|
||||
/// Clears all objects in the System.Web.Cache with the System.Type specified
|
||||
/// </summary>
|
||||
public void ClearCacheObjectTypes<T>()
|
||||
{
|
||||
public void ClearCacheObjectTypes<T>()
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
_nullCache.ClearCacheObjectTypes<T>();
|
||||
_nullHttpCache.ClearCacheObjectTypes<T>();
|
||||
}
|
||||
else
|
||||
{
|
||||
_httpCache.ClearCacheObjectTypes<T>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// Clears all cache items that starts with the key passed.
|
||||
/// </summary>
|
||||
/// <param name="keyStartsWith">The start of the key</param>
|
||||
public void ClearCacheByKeySearch(string keyStartsWith)
|
||||
{
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
_nullCache.ClearCacheByKeySearch(keyStartsWith);
|
||||
_nullHttpCache.ClearCacheByKeySearch(keyStartsWith);
|
||||
}
|
||||
else
|
||||
{
|
||||
_httpCache.ClearCacheByKeySearch(keyStartsWith);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears all cache items that have a key that matches the regular expression
|
||||
/// </summary>
|
||||
/// <param name="regexString"></param>
|
||||
public void ClearCacheByKeyExpression(string regexString)
|
||||
{
|
||||
public void ClearCacheByKeyExpression(string regexString)
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
_nullCache.ClearCacheByKeyExpression(regexString);
|
||||
_nullHttpCache.ClearCacheByKeyExpression(regexString);
|
||||
}
|
||||
else
|
||||
{
|
||||
_httpCache.ClearCacheByKeyExpression(regexString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<T> GetCacheItemsByKeySearch<T>(string keyStartsWith)
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
return _nullCache.GetCacheItemsByKeySearch<T>(keyStartsWith);
|
||||
return _nullHttpCache.GetCacheItemsByKeySearch<T>(keyStartsWith);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -140,7 +303,7 @@ namespace Umbraco.Core
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// Returns a cache item by key, does not update the cache if it isn't there.
|
||||
/// </summary>
|
||||
/// <typeparam name="TT"></typeparam>
|
||||
@@ -150,7 +313,7 @@ namespace Umbraco.Core
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
return _nullCache.GetCacheItem<TT>(cacheKey);
|
||||
return _nullHttpCache.GetCacheItem<TT>(cacheKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -169,7 +332,7 @@ namespace Umbraco.Core
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
return _nullCache.GetCacheItem<TT>(cacheKey, getCacheItem);
|
||||
return _nullHttpCache.GetCacheItem<TT>(cacheKey, getCacheItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -190,7 +353,7 @@ namespace Umbraco.Core
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
return _nullCache.GetCacheItem<TT>(cacheKey, timeout, getCacheItem);
|
||||
return _nullHttpCache.GetCacheItem<TT>(cacheKey, timeout, getCacheItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -213,7 +376,7 @@ namespace Umbraco.Core
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
return _nullCache.GetCacheItem<TT>(cacheKey, refreshAction, timeout, getCacheItem);
|
||||
return _nullHttpCache.GetCacheItem<TT>(cacheKey, refreshAction, timeout, getCacheItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -237,7 +400,7 @@ namespace Umbraco.Core
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
return _nullCache.GetCacheItem<TT>(cacheKey, priority, refreshAction, timeout, getCacheItem);
|
||||
return _nullHttpCache.GetCacheItem<TT>(cacheKey, priority, refreshAction, timeout, getCacheItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -257,15 +420,15 @@ namespace Umbraco.Core
|
||||
/// <param name="getCacheItem"></param>
|
||||
/// <returns></returns>
|
||||
public TT GetCacheItem<TT>(string cacheKey,
|
||||
CacheItemPriority priority,
|
||||
CacheItemRemovedCallback refreshAction,
|
||||
CacheDependency cacheDependency,
|
||||
TimeSpan timeout,
|
||||
Func<TT> getCacheItem)
|
||||
CacheItemPriority priority,
|
||||
CacheItemRemovedCallback refreshAction,
|
||||
CacheDependency cacheDependency,
|
||||
TimeSpan timeout,
|
||||
Func<TT> getCacheItem)
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
return _nullCache.GetCacheItem<TT>(cacheKey, priority, refreshAction, cacheDependency, timeout, getCacheItem);
|
||||
return _nullHttpCache.GetCacheItem<TT>(cacheKey, priority, refreshAction, cacheDependency, timeout, getCacheItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -289,7 +452,7 @@ namespace Umbraco.Core
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
return _nullCache.GetCacheItem<TT>(cacheKey, priority, null, cacheDependency, null, getCacheItem);
|
||||
return _nullHttpCache.GetCacheItem<TT>(cacheKey, priority, null, cacheDependency, null, getCacheItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -310,14 +473,14 @@ namespace Umbraco.Core
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
_nullCache.InsertCacheItem<T>(cacheKey, priority, getCacheItem);
|
||||
_nullHttpCache.InsertCacheItem<T>(cacheKey, priority, getCacheItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
_httpCache.InsertCacheItem<T>(cacheKey, priority, getCacheItem);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Inserts an item into the cache, if it already exists in the cache it will be replaced
|
||||
/// </summary>
|
||||
@@ -333,7 +496,7 @@ namespace Umbraco.Core
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
_nullCache.InsertCacheItem<T>(cacheKey, priority, timeout, getCacheItem);
|
||||
_nullHttpCache.InsertCacheItem<T>(cacheKey, priority, timeout, getCacheItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -341,30 +504,30 @@ namespace Umbraco.Core
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts an item into the cache, if it already exists in the cache it will be replaced
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="priority"></param>
|
||||
/// <param name="cacheDependency"></param>
|
||||
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
public void InsertCacheItem<T>(string cacheKey,
|
||||
CacheItemPriority priority,
|
||||
CacheDependency cacheDependency,
|
||||
TimeSpan timeout,
|
||||
Func<T> getCacheItem)
|
||||
{
|
||||
/// <summary>
|
||||
/// Inserts an item into the cache, if it already exists in the cache it will be replaced
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="priority"></param>
|
||||
/// <param name="cacheDependency"></param>
|
||||
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
public void InsertCacheItem<T>(string cacheKey,
|
||||
CacheItemPriority priority,
|
||||
CacheDependency cacheDependency,
|
||||
TimeSpan timeout,
|
||||
Func<T> getCacheItem)
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
_nullCache.InsertCacheItem<T>(cacheKey, priority, cacheDependency, timeout, getCacheItem);
|
||||
_nullHttpCache.InsertCacheItem<T>(cacheKey, priority, cacheDependency, timeout, getCacheItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
_httpCache.InsertCacheItem<T>(cacheKey, priority, cacheDependency, timeout, getCacheItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts an item into the cache, if it already exists in the cache it will be replaced
|
||||
@@ -376,22 +539,23 @@ namespace Umbraco.Core
|
||||
/// <param name="cacheDependency"></param>
|
||||
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
public void InsertCacheItem<T>(string cacheKey,
|
||||
CacheItemPriority priority,
|
||||
CacheItemRemovedCallback refreshAction,
|
||||
CacheDependency cacheDependency,
|
||||
TimeSpan? timeout,
|
||||
Func<T> getCacheItem)
|
||||
{
|
||||
public void InsertCacheItem<T>(string cacheKey,
|
||||
CacheItemPriority priority,
|
||||
CacheItemRemovedCallback refreshAction,
|
||||
CacheDependency cacheDependency,
|
||||
TimeSpan? timeout,
|
||||
Func<T> getCacheItem)
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
_nullCache.InsertCacheItem<T>(cacheKey, priority, refreshAction, cacheDependency, timeout, getCacheItem);
|
||||
_nullHttpCache.InsertCacheItem<T>(cacheKey, priority, refreshAction, cacheDependency, timeout, getCacheItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
_httpCache.InsertCacheItem<T>(cacheKey, priority, refreshAction, cacheDependency, timeout, getCacheItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets the version comment (like beta or RC).
|
||||
/// </summary>
|
||||
/// <value>The version comment.</value>
|
||||
public static string CurrentComment { get { return "beta-2"; } }
|
||||
public static string CurrentComment { get { return ""; } }
|
||||
|
||||
// Get the version of the umbraco.dll by looking at a class in that dll
|
||||
// Had to do it like this due to medium trust issues, see: http://haacked.com/archive/2010/11/04/assembly-location-and-medium-trust.aspx
|
||||
|
||||
@@ -10,6 +10,7 @@ using Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix;
|
||||
using Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixZeroOne;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
using Umbraco.Core.Profiling;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.Publishing;
|
||||
using Umbraco.Core.Macros;
|
||||
@@ -52,8 +53,9 @@ namespace Umbraco.Core
|
||||
if (_isInitialized)
|
||||
throw new InvalidOperationException("The boot manager has already been initialized");
|
||||
|
||||
LogHelper.Info<CoreBootManager>("Umbraco application starting");
|
||||
_timer = DisposableTimer.Start(x => LogHelper.Info<CoreBootManager>("Umbraco application startup complete" + " (took " + x + "ms)"));
|
||||
InitializeProfilerResolver();
|
||||
|
||||
_timer = DisposableTimer.DebugDuration<CoreBootManager>("Umbraco application starting", "Umbraco application startup complete");
|
||||
|
||||
//create database and service contexts for the app context
|
||||
var dbFactory = new DefaultDatabaseFactory(GlobalSettings.UmbracoConnectionName);
|
||||
@@ -93,6 +95,20 @@ namespace Umbraco.Core
|
||||
ApplicationContext = ApplicationContext.Current = new ApplicationContext(dbContext, serviceContext);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Special method to initialize the ProfilerResolver
|
||||
/// </summary>
|
||||
protected virtual void InitializeProfilerResolver()
|
||||
{
|
||||
//By default we'll initialize the Log profiler (in the web project, we'll override with the web profiler)
|
||||
ProfilerResolver.Current = new ProfilerResolver(new LogProfiler())
|
||||
{
|
||||
//This is another special resolver that needs to be resolvable before resolution is frozen
|
||||
//since it is used for profiling the application startup
|
||||
CanResolveBeforeFrozen = true
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Special method to initialize the ApplicationEventsResolver and any modifications required for it such
|
||||
/// as adding custom types to the resolver.
|
||||
@@ -113,6 +129,17 @@ namespace Umbraco.Core
|
||||
ApplicationEventsResolver.Current.AddType<PublishedContentHelper>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Special method to extend the use of Umbraco by enabling the consumer to overwrite
|
||||
/// the absolute path to the root of an Umbraco site/solution, which is used for stuff
|
||||
/// like Umbraco.Core.IO.IOHelper.MapPath etc.
|
||||
/// </summary>
|
||||
/// <param name="rootPath">Absolute</param>
|
||||
protected virtual void InitializeApplicationRootPath(string rootPath)
|
||||
{
|
||||
Umbraco.Core.IO.IOHelper.SetRootDirectory(rootPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fires after initialization and calls the callback to allow for customizations to occur &
|
||||
/// Ensure that the OnApplicationStarting methods of the IApplicationEvents are called
|
||||
@@ -185,7 +212,8 @@ namespace Umbraco.Core
|
||||
/// Create the resolvers
|
||||
/// </summary>
|
||||
protected virtual void InitializeResolvers()
|
||||
{
|
||||
{
|
||||
|
||||
//by default we'll use the standard configuration based sync
|
||||
ServerRegistrarResolver.Current = new ServerRegistrarResolver(
|
||||
new ConfigServerRegistrar());
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
@@ -10,10 +11,60 @@ using System.Web;
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
///<summary>
|
||||
/// Extension methods for dictionary
|
||||
/// Extension methods for dictionary & concurrentdictionary
|
||||
///</summary>
|
||||
internal static class DictionaryExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Updates an item with the specified key with the specified value
|
||||
/// </summary>
|
||||
/// <typeparam name="TKey"></typeparam>
|
||||
/// <typeparam name="TValue"></typeparam>
|
||||
/// <param name="dict"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="updateFactory"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// Taken from: http://stackoverflow.com/questions/12240219/is-there-a-way-to-use-concurrentdictionary-tryupdate-with-a-lambda-expression
|
||||
///
|
||||
/// If there is an item in the dictionary with the key, it will keep trying to update it until it can
|
||||
/// </remarks>
|
||||
public static bool TryUpdate<TKey, TValue>(this ConcurrentDictionary<TKey, TValue> dict, TKey key, Func<TValue, TValue> updateFactory)
|
||||
{
|
||||
TValue curValue;
|
||||
while (dict.TryGetValue(key, out curValue))
|
||||
{
|
||||
if (dict.TryUpdate(key, updateFactory(curValue), curValue))
|
||||
return true;
|
||||
//if we're looping either the key was removed by another thread, or another thread
|
||||
//changed the value, so we start again.
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates an item with the specified key with the specified value
|
||||
/// </summary>
|
||||
/// <typeparam name="TKey"></typeparam>
|
||||
/// <typeparam name="TValue"></typeparam>
|
||||
/// <param name="dict"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="updateFactory"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// Taken from: http://stackoverflow.com/questions/12240219/is-there-a-way-to-use-concurrentdictionary-tryupdate-with-a-lambda-expression
|
||||
///
|
||||
/// WARNING: If the value changes after we've retreived it, then the item will not be updated
|
||||
/// </remarks>
|
||||
public static bool TryUpdateOptimisitic<TKey, TValue>(this ConcurrentDictionary<TKey, TValue> dict, TKey key, Func<TValue, TValue> updateFactory)
|
||||
{
|
||||
TValue curValue;
|
||||
if (!dict.TryGetValue(key, out curValue))
|
||||
return false;
|
||||
dict.TryUpdate(key, updateFactory(curValue), curValue);
|
||||
return true;//note we return true whether we succeed or not, see explanation below.
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a dictionary to another type by only using direct casting
|
||||
/// </summary>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Web;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Profiling;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
@@ -9,11 +11,17 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <code>
|
||||
///
|
||||
/// using (DisposableTimer.TraceDuration{MyType}("starting", "finished"))
|
||||
/// {
|
||||
/// Thread.Sleep(567);
|
||||
/// }
|
||||
///
|
||||
/// Console.WriteLine("Testing Stopwatchdisposable, should be 567:");
|
||||
// using (var timer = new DisposableTimer(result => Console.WriteLine("Took {0}ms", result)))
|
||||
// {
|
||||
// Thread.Sleep(567);
|
||||
// }
|
||||
/// using (var timer = new DisposableTimer(result => Console.WriteLine("Took {0}ms", result)))
|
||||
/// {
|
||||
/// Thread.Sleep(567);
|
||||
/// }
|
||||
/// </code>
|
||||
/// </example>
|
||||
public class DisposableTimer : DisposableObject
|
||||
@@ -24,7 +32,7 @@ namespace Umbraco.Core
|
||||
protected DisposableTimer(Action<long> callback)
|
||||
{
|
||||
_callback = callback;
|
||||
}
|
||||
}
|
||||
|
||||
public Stopwatch Stopwatch
|
||||
{
|
||||
@@ -36,96 +44,149 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
/// <param name="callback">The callback.</param>
|
||||
/// <returns></returns>
|
||||
[Obsolete("Use either TraceDuration or DebugDuration instead of using Start")]
|
||||
public static DisposableTimer Start(Action<long> callback)
|
||||
{
|
||||
return new DisposableTimer(callback);
|
||||
}
|
||||
|
||||
public static DisposableTimer TraceDuration<T>(Func<string> startMessage, Func<string> completeMessage)
|
||||
{
|
||||
return TraceDuration(typeof(T), startMessage, completeMessage);
|
||||
}
|
||||
#region TraceDuration
|
||||
public static DisposableTimer TraceDuration<T>(Func<string> startMessage, Func<string> completeMessage)
|
||||
{
|
||||
return TraceDuration(typeof(T), startMessage, completeMessage);
|
||||
}
|
||||
|
||||
public static DisposableTimer TraceDuration(Type loggerType, Func<string> startMessage, Func<string> completeMessage)
|
||||
{
|
||||
LogHelper.Debug(loggerType, startMessage);
|
||||
return new DisposableTimer(x => LogHelper.Info(loggerType, () => completeMessage() + " (took " + x + "ms)"));
|
||||
}
|
||||
public static DisposableTimer TraceDuration(Type loggerType, Func<string> startMessage, Func<string> completeMessage)
|
||||
{
|
||||
var startMsg = startMessage();
|
||||
LogHelper.Info(loggerType, startMsg);
|
||||
if (HttpContext.Current != null)
|
||||
HttpContext.Current.Trace.Write("Start: " + startMsg);
|
||||
var profiler = ActivateProfiler(loggerType, startMsg);
|
||||
return new DisposableTimer(x =>
|
||||
{
|
||||
profiler.DisposeIfDisposable();
|
||||
LogHelper.Info(loggerType, () => completeMessage() + " (took " + x + "ms)");
|
||||
if (HttpContext.Current != null)
|
||||
HttpContext.Current.Trace.Write("End: " + startMsg);
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a start and end log entry as Info and tracks how long it takes until disposed.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="startMessage"></param>
|
||||
/// <param name="completeMessage"></param>
|
||||
/// <returns></returns>
|
||||
public static DisposableTimer TraceDuration<T>(string startMessage, string completeMessage)
|
||||
{
|
||||
return TraceDuration(typeof(T), startMessage, completeMessage);
|
||||
}
|
||||
/// <summary>
|
||||
/// Adds a start and end log entry as Info and tracks how long it takes until disposed.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="startMessage"></param>
|
||||
/// <param name="completeMessage"></param>
|
||||
/// <returns></returns>
|
||||
public static DisposableTimer TraceDuration<T>(string startMessage, string completeMessage)
|
||||
{
|
||||
return TraceDuration(typeof(T), startMessage, completeMessage);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a start and end log entry as Info and tracks how long it takes until disposed.
|
||||
/// </summary>
|
||||
/// <param name="loggerType"></param>
|
||||
/// <param name="startMessage"></param>
|
||||
/// <param name="completeMessage"></param>
|
||||
/// <returns></returns>
|
||||
public static DisposableTimer TraceDuration(Type loggerType, string startMessage, string completeMessage)
|
||||
{
|
||||
LogHelper.Info(loggerType, () => startMessage);
|
||||
return new DisposableTimer(x => LogHelper.Info(loggerType, () => completeMessage + " (took " + x + "ms)"));
|
||||
}
|
||||
public static DisposableTimer TraceDuration<T>(string startMessage)
|
||||
{
|
||||
return TraceDuration(typeof(T), startMessage, "Complete");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a start and end log entry as Debug and tracks how long it takes until disposed.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="startMessage"></param>
|
||||
/// <param name="completeMessage"></param>
|
||||
/// <returns></returns>
|
||||
public static DisposableTimer DebugDuration<T>(string startMessage, string completeMessage)
|
||||
{
|
||||
return DebugDuration(typeof(T), startMessage, completeMessage);
|
||||
}
|
||||
/// <summary>
|
||||
/// Adds a start and end log entry as Info and tracks how long it takes until disposed.
|
||||
/// </summary>
|
||||
/// <param name="loggerType"></param>
|
||||
/// <param name="startMessage"></param>
|
||||
/// <param name="completeMessage"></param>
|
||||
/// <returns></returns>
|
||||
public static DisposableTimer TraceDuration(Type loggerType, string startMessage, string completeMessage)
|
||||
{
|
||||
LogHelper.Info(loggerType, startMessage);
|
||||
if (HttpContext.Current != null)
|
||||
HttpContext.Current.Trace.Write("Start: " + startMessage);
|
||||
var profiler = ActivateProfiler(loggerType, startMessage);
|
||||
return new DisposableTimer(x =>
|
||||
{
|
||||
profiler.DisposeIfDisposable();
|
||||
LogHelper.Info(loggerType, () => completeMessage + " (took " + x + "ms)");
|
||||
if (HttpContext.Current != null)
|
||||
HttpContext.Current.Trace.Write("End: " + startMessage);
|
||||
});
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Adds a start and end log entry as Debug and tracks how long it takes until disposed.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="startMessage"></param>
|
||||
/// <param name="completeMessage"></param>
|
||||
/// <returns></returns>
|
||||
public static DisposableTimer DebugDuration<T>(Func<string> startMessage, Func<string> completeMessage)
|
||||
{
|
||||
return DebugDuration(typeof(T), startMessage, completeMessage);
|
||||
}
|
||||
#region DebugDuration
|
||||
/// <summary>
|
||||
/// Adds a start and end log entry as Debug and tracks how long it takes until disposed.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="startMessage"></param>
|
||||
/// <param name="completeMessage"></param>
|
||||
/// <returns></returns>
|
||||
public static DisposableTimer DebugDuration<T>(string startMessage, string completeMessage)
|
||||
{
|
||||
return DebugDuration(typeof(T), startMessage, completeMessage);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a start and end log entry as Debug and tracks how long it takes until disposed.
|
||||
/// </summary>
|
||||
/// <param name="loggerType"></param>
|
||||
/// <param name="startMessage"></param>
|
||||
/// <param name="completeMessage"></param>
|
||||
/// <returns></returns>
|
||||
public static DisposableTimer DebugDuration(Type loggerType, string startMessage, string completeMessage)
|
||||
{
|
||||
LogHelper.Debug(loggerType, () => startMessage);
|
||||
return new DisposableTimer(x => LogHelper.Debug(loggerType, () => completeMessage + " (took " + x + "ms)"));
|
||||
}
|
||||
public static DisposableTimer DebugDuration<T>(string startMessage)
|
||||
{
|
||||
return DebugDuration(typeof(T), startMessage, "Complete");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a start and end log entry as Debug and tracks how long it takes until disposed.
|
||||
/// </summary>
|
||||
/// <param name="loggerType"></param>
|
||||
/// <param name="startMessage"></param>
|
||||
/// <param name="completeMessage"></param>
|
||||
/// <returns></returns>
|
||||
public static DisposableTimer DebugDuration(Type loggerType, Func<string> startMessage, Func<string> completeMessage)
|
||||
{
|
||||
LogHelper.Debug(loggerType, startMessage);
|
||||
return new DisposableTimer(x => LogHelper.Debug(loggerType, () => completeMessage() + " (took " + x + "ms)"));
|
||||
}
|
||||
/// <summary>
|
||||
/// Adds a start and end log entry as Debug and tracks how long it takes until disposed.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="startMessage"></param>
|
||||
/// <param name="completeMessage"></param>
|
||||
/// <returns></returns>
|
||||
public static DisposableTimer DebugDuration<T>(Func<string> startMessage, Func<string> completeMessage)
|
||||
{
|
||||
return DebugDuration(typeof(T), startMessage, completeMessage);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a start and end log entry as Debug and tracks how long it takes until disposed.
|
||||
/// </summary>
|
||||
/// <param name="loggerType"></param>
|
||||
/// <param name="startMessage"></param>
|
||||
/// <param name="completeMessage"></param>
|
||||
/// <returns></returns>
|
||||
public static DisposableTimer DebugDuration(Type loggerType, string startMessage, string completeMessage)
|
||||
{
|
||||
LogHelper.Debug(loggerType, startMessage);
|
||||
if (HttpContext.Current != null)
|
||||
HttpContext.Current.Trace.Write("Start: " + startMessage);
|
||||
var profiler = ActivateProfiler(loggerType, startMessage);
|
||||
return new DisposableTimer(x =>
|
||||
{
|
||||
profiler.DisposeIfDisposable();
|
||||
LogHelper.Debug(loggerType, () => completeMessage + " (took " + x + "ms)");
|
||||
if (HttpContext.Current != null)
|
||||
HttpContext.Current.Trace.Write("End: " + startMessage);
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a start and end log entry as Debug and tracks how long it takes until disposed.
|
||||
/// </summary>
|
||||
/// <param name="loggerType"></param>
|
||||
/// <param name="startMessage"></param>
|
||||
/// <param name="completeMessage"></param>
|
||||
/// <returns></returns>
|
||||
public static DisposableTimer DebugDuration(Type loggerType, Func<string> startMessage, Func<string> completeMessage)
|
||||
{
|
||||
var msg = startMessage();
|
||||
LogHelper.Debug(loggerType, msg);
|
||||
if (HttpContext.Current != null)
|
||||
HttpContext.Current.Trace.Write("Start: " + startMessage);
|
||||
var profiler = ActivateProfiler(loggerType, msg);
|
||||
return new DisposableTimer(x =>
|
||||
{
|
||||
profiler.DisposeIfDisposable();
|
||||
LogHelper.Debug(loggerType, () => completeMessage() + " (took " + x + "ms)");
|
||||
if (HttpContext.Current != null)
|
||||
HttpContext.Current.Trace.Write("End: " + startMessage);
|
||||
});
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Handles the disposal of resources. Derived from abstract class <see cref="DisposableObject"/> which handles common required locking logic.
|
||||
@@ -134,5 +195,19 @@ namespace Umbraco.Core
|
||||
{
|
||||
_callback.Invoke(Stopwatch.ElapsedMilliseconds);
|
||||
}
|
||||
|
||||
private static IDisposable ActivateProfiler(Type loggerType, string profileName)
|
||||
{
|
||||
try
|
||||
{
|
||||
return ProfilerResolver.Current.Profiler.Step(loggerType, profileName);
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
{
|
||||
//swallow this exception, it will occur if the ProfilerResolver is not initialized... generally only in
|
||||
// unit tests.
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,12 +5,11 @@ using System.Text;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
|
||||
namespace Umbraco.Core.IO
|
||||
{
|
||||
[UmbracoExperimentalFeature("http://issues.umbraco.org/issue/U4-1156", "Will be declared public after 4.10")]
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
|
||||
internal class FileSystemProviderAttribute : Attribute
|
||||
public class FileSystemProviderAttribute : Attribute
|
||||
{
|
||||
public string Alias { get; set; }
|
||||
public string Alias { get; private set; }
|
||||
|
||||
public FileSystemProviderAttribute(string alias)
|
||||
{
|
||||
|
||||
+1
-2
@@ -6,8 +6,7 @@ using Umbraco.Core.CodeAnnotations;
|
||||
|
||||
namespace Umbraco.Core.IO
|
||||
{
|
||||
[UmbracoExperimentalFeature("http://issues.umbraco.org/issue/U4-1156", "Will be declared public after 4.10")]
|
||||
internal class FileSystemProvider
|
||||
internal class FileSystemProviderConstants
|
||||
{
|
||||
public const string Media = "media";
|
||||
}
|
||||
@@ -9,9 +9,8 @@ using Umbraco.Core.CodeAnnotations;
|
||||
using Umbraco.Core.Configuration;
|
||||
|
||||
namespace Umbraco.Core.IO
|
||||
{
|
||||
[UmbracoExperimentalFeature("http://issues.umbraco.org/issue/U4-1156", "Will be declared public after 4.10")]
|
||||
internal class FileSystemProviderManager
|
||||
{
|
||||
public class FileSystemProviderManager
|
||||
{
|
||||
private readonly FileSystemProvidersSection _config;
|
||||
|
||||
@@ -28,7 +27,7 @@ namespace Umbraco.Core.IO
|
||||
|
||||
#region Constructors
|
||||
|
||||
public FileSystemProviderManager()
|
||||
internal FileSystemProviderManager()
|
||||
{
|
||||
_config = (FileSystemProvidersSection)ConfigurationManager.GetSection("FileSystemProviders");
|
||||
}
|
||||
@@ -48,7 +47,15 @@ namespace Umbraco.Core.IO
|
||||
private readonly ConcurrentDictionary<string, ProviderConstructionInfo> _providerLookup = new ConcurrentDictionary<string, ProviderConstructionInfo>();
|
||||
private readonly ConcurrentDictionary<Type, string> _wrappedProviderLookup = new ConcurrentDictionary<Type, string>();
|
||||
|
||||
public IFileSystem GetFileSystemProvider(string alias)
|
||||
/// <summary>
|
||||
/// Returns the underlying (non-typed) file system provider for the alias specified
|
||||
/// </summary>
|
||||
/// <param name="alias"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// It is recommended to use the typed GetFileSystemProvider method instead to get a strongly typed provider instance.
|
||||
/// </remarks>
|
||||
public IFileSystem GetUnderlyingFileSystemProvider(string alias)
|
||||
{
|
||||
//either get the constructor info from cache or create it and add to cache
|
||||
var ctorInfo = _providerLookup.GetOrAdd(alias, s =>
|
||||
@@ -88,6 +95,11 @@ namespace Umbraco.Core.IO
|
||||
return fs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the strongly typed file system provider
|
||||
/// </summary>
|
||||
/// <typeparam name="TProviderTypeFilter"></typeparam>
|
||||
/// <returns></returns>
|
||||
public TProviderTypeFilter GetFileSystemProvider<TProviderTypeFilter>()
|
||||
where TProviderTypeFilter : FileSystemWrapper
|
||||
{
|
||||
@@ -111,7 +123,7 @@ namespace Umbraco.Core.IO
|
||||
return attr.Alias;
|
||||
});
|
||||
|
||||
var innerFs = GetFileSystemProvider(alias);
|
||||
var innerFs = GetUnderlyingFileSystemProvider(alias);
|
||||
var outputFs = Activator.CreateInstance(typeof (TProviderTypeFilter), innerFs);
|
||||
return (TProviderTypeFilter)outputFs;
|
||||
}
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using System.Configuration;
|
||||
using System.Web;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Xml;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
|
||||
@@ -37,7 +34,7 @@ namespace Umbraco.Core.IO
|
||||
if (virtualPath.StartsWith("~"))
|
||||
retval = virtualPath.Replace("~", SystemDirectories.Root);
|
||||
|
||||
if (virtualPath.StartsWith("/") && !virtualPath.StartsWith(SystemDirectories.Root))
|
||||
if (virtualPath.StartsWith("/") && virtualPath.StartsWith(SystemDirectories.Root) == false)
|
||||
retval = SystemDirectories.Root + "/" + virtualPath.TrimStart('/');
|
||||
|
||||
return retval;
|
||||
@@ -68,11 +65,7 @@ namespace Umbraco.Core.IO
|
||||
if (tag.Groups[1].Success)
|
||||
url = tag.Groups[1].Value;
|
||||
|
||||
// The richtext editor inserts a slash in front of the url. That's why we need this little fix
|
||||
// if (url.StartsWith("/"))
|
||||
// text = text.Replace(url, ResolveUrl(url.Substring(1)));
|
||||
// else
|
||||
if (!String.IsNullOrEmpty(url))
|
||||
if (string.IsNullOrEmpty(url) == false)
|
||||
{
|
||||
string resolvedUrl = (url.Substring(0, 1) == "/") ? ResolveUrl(url.Substring(1)) : ResolveUrl(url);
|
||||
text = text.Replace(url, resolvedUrl);
|
||||
@@ -97,19 +90,15 @@ namespace Umbraco.Core.IO
|
||||
if (useHttpContext && HttpContext.Current != null)
|
||||
{
|
||||
//string retval;
|
||||
if (!string.IsNullOrEmpty(path) && (path.StartsWith("~") || path.StartsWith(SystemDirectories.Root)))
|
||||
if (string.IsNullOrEmpty(path) == false && (path.StartsWith("~") || path.StartsWith(SystemDirectories.Root)))
|
||||
return System.Web.Hosting.HostingEnvironment.MapPath(path);
|
||||
else
|
||||
return System.Web.Hosting.HostingEnvironment.MapPath("~/" + path.TrimStart('/'));
|
||||
}
|
||||
|
||||
//var root = (!string.IsNullOrEmpty(System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath))
|
||||
// ? System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath.TrimEnd(IOHelper.DirSepChar)
|
||||
// : getRootDirectorySafe();
|
||||
|
||||
var root = GetRootDirectorySafe();
|
||||
var newPath = path.TrimStart('~', '/').Replace('/', IOHelper.DirSepChar);
|
||||
var retval = root + IOHelper.DirSepChar.ToString() + newPath;
|
||||
var retval = root + IOHelper.DirSepChar.ToString(CultureInfo.InvariantCulture) + newPath;
|
||||
|
||||
return retval;
|
||||
}
|
||||
@@ -144,9 +133,9 @@ namespace Umbraco.Core.IO
|
||||
/// <returns>A value indicating whether the filepath is valid.</returns>
|
||||
internal static bool VerifyEditPath(string filePath, string validDir)
|
||||
{
|
||||
if (!filePath.StartsWith(MapPath(SystemDirectories.Root)))
|
||||
if (filePath.StartsWith(MapPath(SystemDirectories.Root)) == false)
|
||||
filePath = MapPath(filePath);
|
||||
if (!validDir.StartsWith(MapPath(SystemDirectories.Root)))
|
||||
if (validDir.StartsWith(MapPath(SystemDirectories.Root)) == false)
|
||||
validDir = MapPath(validDir);
|
||||
|
||||
return filePath.StartsWith(validDir);
|
||||
@@ -161,7 +150,7 @@ namespace Umbraco.Core.IO
|
||||
/// <exception cref="FileSecurityException">The filepath is invalid.</exception>
|
||||
internal static bool ValidateEditPath(string filePath, string validDir)
|
||||
{
|
||||
if (!VerifyEditPath(filePath, validDir))
|
||||
if (VerifyEditPath(filePath, validDir) == false)
|
||||
throw new FileSecurityException(String.Format("The filepath '{0}' is not within an allowed directory for this type of files", filePath.Replace(MapPath(SystemDirectories.Root), "")));
|
||||
return true;
|
||||
}
|
||||
@@ -177,9 +166,9 @@ namespace Umbraco.Core.IO
|
||||
foreach (var dir in validDirs)
|
||||
{
|
||||
var validDir = dir;
|
||||
if (!filePath.StartsWith(MapPath(SystemDirectories.Root)))
|
||||
if (filePath.StartsWith(MapPath(SystemDirectories.Root)) == false)
|
||||
filePath = MapPath(filePath);
|
||||
if (!validDir.StartsWith(MapPath(SystemDirectories.Root)))
|
||||
if (validDir.StartsWith(MapPath(SystemDirectories.Root)) == false)
|
||||
validDir = MapPath(validDir);
|
||||
|
||||
if (filePath.StartsWith(validDir))
|
||||
@@ -198,7 +187,7 @@ namespace Umbraco.Core.IO
|
||||
/// <exception cref="FileSecurityException">The filepath is invalid.</exception>
|
||||
internal static bool ValidateEditPath(string filePath, IEnumerable<string> validDirs)
|
||||
{
|
||||
if (!VerifyEditPath(filePath, validDirs))
|
||||
if (VerifyEditPath(filePath, validDirs) == false)
|
||||
throw new FileSecurityException(String.Format("The filepath '{0}' is not within an allowed directory for this type of files", filePath.Replace(MapPath(SystemDirectories.Root), "")));
|
||||
return true;
|
||||
}
|
||||
@@ -211,7 +200,7 @@ namespace Umbraco.Core.IO
|
||||
/// <returns>A value indicating whether the filepath is valid.</returns>
|
||||
internal static bool VerifyFileExtension(string filePath, List<string> validFileExtensions)
|
||||
{
|
||||
if (!filePath.StartsWith(MapPath(SystemDirectories.Root)))
|
||||
if (filePath.StartsWith(MapPath(SystemDirectories.Root)) == false)
|
||||
filePath = MapPath(filePath);
|
||||
var f = new FileInfo(filePath);
|
||||
|
||||
@@ -227,7 +216,7 @@ namespace Umbraco.Core.IO
|
||||
/// <exception cref="FileSecurityException">The filepath is invalid.</exception>
|
||||
internal static bool ValidateFileExtension(string filePath, List<string> validFileExtensions)
|
||||
{
|
||||
if (!VerifyFileExtension(filePath, validFileExtensions))
|
||||
if (VerifyFileExtension(filePath, validFileExtensions) == false)
|
||||
throw new FileSecurityException(String.Format("The extension for the current file '{0}' is not of an allowed type for this editor. This is typically controlled from either the installed MacroEngines or based on configuration in /config/umbracoSettings.config", filePath.Replace(MapPath(SystemDirectories.Root), "")));
|
||||
return true;
|
||||
}
|
||||
@@ -241,7 +230,7 @@ namespace Umbraco.Core.IO
|
||||
/// <returns></returns>
|
||||
internal static string GetRootDirectorySafe()
|
||||
{
|
||||
if (!String.IsNullOrEmpty(_rootDir))
|
||||
if (string.IsNullOrEmpty(_rootDir) == false)
|
||||
{
|
||||
return _rootDir;
|
||||
}
|
||||
@@ -250,12 +239,27 @@ namespace Umbraco.Core.IO
|
||||
var uri = new Uri(codeBase);
|
||||
var path = uri.LocalPath;
|
||||
var baseDirectory = Path.GetDirectoryName(path);
|
||||
_rootDir = baseDirectory.Substring(0, baseDirectory.LastIndexOf("bin") - 1);
|
||||
if (string.IsNullOrEmpty(baseDirectory))
|
||||
throw new Exception("No root directory could be resolved. Please ensure that your Umbraco solution is correctly configured.");
|
||||
|
||||
_rootDir = baseDirectory.Contains("bin")
|
||||
? baseDirectory.Substring(0, baseDirectory.LastIndexOf("bin", StringComparison.OrdinalIgnoreCase) - 1)
|
||||
: baseDirectory;
|
||||
|
||||
return _rootDir;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allows you to overwrite RootDirectory, which would otherwise be resolved
|
||||
/// automatically upon application start.
|
||||
/// </summary>
|
||||
/// <remarks>The supplied path should be the absolute path to the root of the umbraco site.</remarks>
|
||||
/// <param name="rootPath"></param>
|
||||
internal static void SetRootDirectory(string rootPath)
|
||||
{
|
||||
_rootDir = rootPath;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check to see if filename passed has any special chars in it and strips them to create a safe filename. Used to overcome an issue when Umbraco is used in IE in an intranet environment.
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.Web.Security;
|
||||
|
||||
namespace Umbraco.Core.Models.Membership
|
||||
{
|
||||
internal class UmbracoMembershipUser<T> : MembershipUser where T : IMembershipUser
|
||||
{
|
||||
private T _user;
|
||||
|
||||
#region Constructors
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UmbracoMembershipUser{T}"/> class.
|
||||
/// </summary>
|
||||
public UmbracoMembershipUser(T user)
|
||||
{
|
||||
_user = user;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UmbracoMembershipUser{T}"/> class.
|
||||
/// </summary>
|
||||
/// <param name="providerName">Name of the provider.</param>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="providerUserKey">The provider user key.</param>
|
||||
/// <param name="email">The email.</param>
|
||||
/// <param name="passwordQuestion">The password question.</param>
|
||||
/// <param name="comment">The comment.</param>
|
||||
/// <param name="isApproved">if set to <c>true</c> [is approved].</param>
|
||||
/// <param name="isLockedOut">if set to <c>true</c> [is locked out].</param>
|
||||
/// <param name="creationDate">The creation date.</param>
|
||||
/// <param name="lastLoginDate">The last login date.</param>
|
||||
/// <param name="lastActivityDate">The last activity date.</param>
|
||||
/// <param name="lastPasswordChangedDate">The last password changed date.</param>
|
||||
/// <param name="lastLockoutDate">The last lockout date.</param>
|
||||
/// <param name="fullName">The full name.</param>
|
||||
/// <param name="language">The language.</param>
|
||||
/// <param name="userType">Type of the user.</param>
|
||||
/// <param name="user"></param>
|
||||
public UmbracoMembershipUser(string providerName, string name, object providerUserKey, string email,
|
||||
string passwordQuestion, string comment, bool isApproved, bool isLockedOut,
|
||||
DateTime creationDate, DateTime lastLoginDate, DateTime lastActivityDate, DateTime lastPasswordChangedDate,
|
||||
DateTime lastLockoutDate, string fullName, string language, IUserType userType, T user)
|
||||
: base( providerName, name, providerUserKey, email, passwordQuestion, comment, isApproved, isLockedOut,
|
||||
creationDate, lastLoginDate, lastActivityDate, lastPasswordChangedDate, lastLockoutDate)
|
||||
{
|
||||
_user = user;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -20,5 +20,8 @@ namespace Umbraco.Core.Models.Rdbms
|
||||
[Column("SortOrder")]
|
||||
[Constraint(Name = "df_cmsContentTypeAllowedContentType_sortOrder", Default = "0")]
|
||||
public int SortOrder { get; set; }
|
||||
|
||||
[ResultColumn]
|
||||
public ContentTypeDto ContentTypeDto { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -171,7 +171,7 @@ namespace Umbraco.Core.Models
|
||||
|
||||
public bool IsDraft
|
||||
{
|
||||
get { return _isPublished; }
|
||||
get { return _isDraft; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
|
||||
@@ -170,7 +170,7 @@ namespace Umbraco.Core.ObjectResolution
|
||||
get
|
||||
{
|
||||
// ensure we can
|
||||
if (!CanResolveBeforeFrozen)
|
||||
if (CanResolveBeforeFrozen == false)
|
||||
Resolution.EnsureIsFrozen();
|
||||
|
||||
// note: we apply .ToArray() to the output of CreateInstance() because that is an IEnumerable that
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Umbraco.Core.ObjectResolution
|
||||
//add itself to the internal collection
|
||||
ResolverCollection.Add(this, resetAction);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -69,6 +69,12 @@ namespace Umbraco.Core.ObjectResolution
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the resolver can resolve objects before resolution is frozen.
|
||||
/// </summary>
|
||||
/// <remarks>This is false by default and is used for some special internal resolvers.</remarks>
|
||||
internal bool CanResolveBeforeFrozen { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the resolved object instance can be null.
|
||||
/// </summary>
|
||||
@@ -96,7 +102,10 @@ namespace Umbraco.Core.ObjectResolution
|
||||
{
|
||||
get
|
||||
{
|
||||
Resolution.EnsureIsFrozen();
|
||||
// ensure we can
|
||||
if (CanResolveBeforeFrozen == false)
|
||||
Resolution.EnsureIsFrozen();
|
||||
|
||||
using (new ReadLock(_lock))
|
||||
{
|
||||
if (!_canBeNull && _value == null)
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
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; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
using NuGet;
|
||||
|
||||
namespace Umbraco.Core.Packaging
|
||||
{
|
||||
internal interface IPackageContext
|
||||
{
|
||||
IPackageManager LocalPackageManager { get; }
|
||||
IPackageManager PublicPackageManager { get; }
|
||||
IPackagePathResolver LocalPathResolver { get; }
|
||||
}
|
||||
}
|
||||
@@ -28,12 +28,9 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
UmbracoFile = dto.UmbracoFile ?? string.Empty
|
||||
};
|
||||
|
||||
entity.IsPublished = dto.PublishedVersion != default(Guid) ||
|
||||
(dto.NewestVersion != default(Guid) && dto.PublishedVersion == dto.NewestVersion);
|
||||
entity.IsDraft = dto.NewestVersion != default(Guid) &&
|
||||
(dto.PublishedVersion == default(Guid) || dto.PublishedVersion != dto.NewestVersion);
|
||||
entity.HasPendingChanges = dto.PublishedVersion != default(Guid) && dto.NewestVersion != default(Guid) &&
|
||||
dto.PublishedVersion != dto.NewestVersion;
|
||||
entity.IsPublished = dto.PublishedVersion != default(Guid) || (dto.NewestVersion != default(Guid) && dto.PublishedVersion == dto.NewestVersion);
|
||||
entity.IsDraft = dto.NewestVersion != default(Guid) && (dto.PublishedVersion == default(Guid) || dto.PublishedVersion != dto.NewestVersion);
|
||||
entity.HasPendingChanges = (dto.PublishedVersion != default(Guid) && dto.NewestVersion != default(Guid)) && dto.PublishedVersion != dto.NewestVersion;
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
@@ -455,9 +455,12 @@ namespace Umbraco.Core.Persistence.Querying
|
||||
if (fieldType == typeof(decimal))
|
||||
return ((decimal)value).ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
if(fieldType == typeof(DateTime))
|
||||
if (fieldType == typeof(DateTime))
|
||||
return "'" + EscapeParam(((DateTime)value).ToString(CultureInfo.InvariantCulture)) + "'";
|
||||
|
||||
|
||||
if (fieldType == typeof(bool))
|
||||
return ((bool)value) ? Convert.ToString(1, CultureInfo.InvariantCulture) : Convert.ToString(0, CultureInfo.InvariantCulture);
|
||||
|
||||
return ShouldQuoteValue(fieldType)
|
||||
? "'" + EscapeParam(value) + "'"
|
||||
: value.ToString();
|
||||
|
||||
@@ -320,10 +320,12 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
var sql = new Sql();
|
||||
sql.Select("*")
|
||||
.From<ContentTypeAllowedContentTypeDto>()
|
||||
.LeftJoin<ContentTypeDto>()
|
||||
.On<ContentTypeAllowedContentTypeDto, ContentTypeDto>(left => left.Id, right => right.NodeId)
|
||||
.Where<ContentTypeAllowedContentTypeDto>(x => x.Id == id);
|
||||
|
||||
var allowedContentTypeDtos = Database.Fetch<ContentTypeAllowedContentTypeDto>(sql);
|
||||
return allowedContentTypeDtos.Select(x => new ContentTypeSort { Id = new Lazy<int>(() => x.AllowedId), SortOrder = x.SortOrder }).ToList();
|
||||
var allowedContentTypeDtos = Database.Fetch<ContentTypeAllowedContentTypeDto, ContentTypeDto>(sql);
|
||||
return allowedContentTypeDtos.Select(x => new ContentTypeSort { Id = new Lazy<int>(() => x.AllowedId), Alias = x.ContentTypeDto.Alias, SortOrder = x.SortOrder }).ToList();
|
||||
}
|
||||
|
||||
protected PropertyGroupCollection GetPropertyGroupCollection(int id, DateTime createDate, DateTime updateDate)
|
||||
|
||||
@@ -262,7 +262,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
[Column("publishedVerison")]
|
||||
public Guid PublishedVersion { get; set; }
|
||||
|
||||
[Column("newestVerison")]
|
||||
[Column("newestVersion")]
|
||||
public Guid NewestVersion { get; set; }
|
||||
|
||||
[Column("alias")]
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.Profiling
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines an object for use in the application to profile operations
|
||||
/// </summary>
|
||||
internal interface IProfiler
|
||||
{
|
||||
/// <summary>
|
||||
/// Render the UI to display the profiler
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// Generally used for HTML displays
|
||||
/// </remarks>
|
||||
string Render();
|
||||
|
||||
/// <summary>
|
||||
/// Profile an operation
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// Use the 'using(' syntax
|
||||
/// </remarks>
|
||||
IDisposable Step(string name);
|
||||
|
||||
/// <summary>
|
||||
/// Start the profiler
|
||||
/// </summary>
|
||||
void Start();
|
||||
|
||||
/// <summary>
|
||||
/// Start the profiler
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// set discardResults to false when you want to abandon all profiling, this is useful for
|
||||
/// when someone is not authenticated or you want to clear the results based on some other mechanism.
|
||||
/// </remarks>
|
||||
void Stop(bool discardResults = false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Umbraco.Core.Logging;
|
||||
|
||||
namespace Umbraco.Core.Profiling
|
||||
{
|
||||
/// <summary>
|
||||
/// A profiler that outputs its results to the LogHelper
|
||||
/// </summary>
|
||||
internal class LogProfiler : IProfiler
|
||||
{
|
||||
public string Render()
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
public IDisposable Step(string name)
|
||||
{
|
||||
LogHelper.Debug(typeof(LogProfiler), "Starting - " + name);
|
||||
return DisposableTimer.Start(l => LogHelper.Info(typeof(LogProfiler), () => name + " (took " + l + "ms)"));
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
//the log will alwasy be started
|
||||
}
|
||||
|
||||
public void Stop(bool discardResults = false)
|
||||
{
|
||||
//we don't need to do anything here
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using StackExchange.Profiling;
|
||||
|
||||
namespace Umbraco.Core.Profiling
|
||||
{
|
||||
public class Profiler
|
||||
{
|
||||
private static Profiler _instance;
|
||||
|
||||
private Profiler()
|
||||
{
|
||||
}
|
||||
|
||||
public string Render()
|
||||
{
|
||||
return MiniProfiler.RenderIncludes().ToString();
|
||||
}
|
||||
|
||||
public IDisposable Step(string name)
|
||||
{
|
||||
return MiniProfiler.Current.Step(name);
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
MiniProfiler.Start();
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
MiniProfiler.Stop();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static Profiler Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_instance == null)
|
||||
{
|
||||
_instance = new Profiler();
|
||||
}
|
||||
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.Profiling
|
||||
{
|
||||
internal static class ProfilerExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Writes out a step prefixed with the type
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="profiler"></param>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
internal static IDisposable Step<T>(this IProfiler profiler, string name)
|
||||
{
|
||||
if (profiler == null) throw new ArgumentNullException("profiler");
|
||||
return profiler.Step(typeof (T), name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes out a step prefixed with the type
|
||||
/// </summary>
|
||||
/// <param name="profiler"></param>
|
||||
/// <param name="objectType"></param>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
internal static IDisposable Step(this IProfiler profiler, Type objectType, string name)
|
||||
{
|
||||
if (profiler == null) throw new ArgumentNullException("profiler");
|
||||
if (objectType == null) throw new ArgumentNullException("objectType");
|
||||
if (name == null) throw new ArgumentNullException("name");
|
||||
return profiler.Step(string.Format("[{0}] {1}", objectType.Name, name));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using Umbraco.Core.ObjectResolution;
|
||||
|
||||
namespace Umbraco.Core.Profiling
|
||||
{
|
||||
/// <summary>
|
||||
/// A resolver exposing the current profiler
|
||||
/// </summary>
|
||||
internal class ProfilerResolver : SingleObjectResolverBase<ProfilerResolver, IProfiler>
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="profiler"></param>
|
||||
public ProfilerResolver(IProfiler profiler)
|
||||
: base(profiler)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method allowing to change the profiler during startup
|
||||
/// </summary>
|
||||
/// <param name="profiler"></param>
|
||||
internal void SetProfiler(IProfiler profiler)
|
||||
{
|
||||
Value = profiler;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current profiler
|
||||
/// </summary>
|
||||
public IProfiler Profiler
|
||||
{
|
||||
get { return Value; }
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
using System;
|
||||
using System.Web;
|
||||
using StackExchange.Profiling;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
|
||||
namespace Umbraco.Core.Profiling
|
||||
{
|
||||
/// <summary>
|
||||
/// A profiler used for web based activity based on the MiniProfiler framework
|
||||
/// </summary>
|
||||
internal class WebProfiler : IProfiler
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Binds to application events to enable the MiniProfiler
|
||||
/// </remarks>
|
||||
internal WebProfiler()
|
||||
{
|
||||
UmbracoApplicationBase.ApplicationInit += UmbracoApplicationApplicationInit;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle the Init event o fthe UmbracoApplication which allows us to subscribe to the HttpApplication events
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
void UmbracoApplicationApplicationInit(object sender, EventArgs e)
|
||||
{
|
||||
var app = sender as HttpApplication;
|
||||
if (app == null) return;
|
||||
|
||||
if (SystemUtilities.GetCurrentTrustLevel() < AspNetHostingPermissionLevel.High)
|
||||
{
|
||||
//If we don't have a high enough trust level we cannot bind to the events
|
||||
LogHelper.Info<WebProfiler>("Cannot start the WebProfiler since the application is running in Medium trust");
|
||||
}
|
||||
else
|
||||
{
|
||||
app.BeginRequest += UmbracoApplicationBeginRequest;
|
||||
app.EndRequest += UmbracoApplicationEndRequest;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle the begin request event
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
void UmbracoApplicationEndRequest(object sender, EventArgs e)
|
||||
{
|
||||
if (GlobalSettings.DebugMode == false) return;
|
||||
var request = TryGetRequest(sender);
|
||||
if (request.Success == false) return;
|
||||
if (request.Result.Url.IsClientSideRequest()) return;
|
||||
if (string.IsNullOrEmpty(request.Result["umbDebug"]) == false)
|
||||
{
|
||||
//stop the profiler
|
||||
Stop();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle the end request event
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
void UmbracoApplicationBeginRequest(object sender, EventArgs e)
|
||||
{
|
||||
if (GlobalSettings.DebugMode == false) return;
|
||||
var request = TryGetRequest(sender);
|
||||
if (request.Success == false) return;
|
||||
if (request.Result.Url.IsClientSideRequest()) return;
|
||||
if (string.IsNullOrEmpty(request.Result["umbDebug"]) == false)
|
||||
{
|
||||
//start the profiler
|
||||
Start();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Render the UI to display the profiler
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// Generally used for HTML displays
|
||||
/// </remarks>
|
||||
public string Render()
|
||||
{
|
||||
return MiniProfiler.RenderIncludes().ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Profile a step
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// Use the 'using(' syntax
|
||||
/// </remarks>
|
||||
public IDisposable Step(string name)
|
||||
{
|
||||
if (GlobalSettings.DebugMode == false) return null;
|
||||
|
||||
return MiniProfiler.Current.Step(name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start the profiler
|
||||
/// </summary>
|
||||
public void Start()
|
||||
{
|
||||
if (GlobalSettings.DebugMode == false) return;
|
||||
//will not run in medium trust
|
||||
if (SystemUtilities.GetCurrentTrustLevel() < AspNetHostingPermissionLevel.High) return;
|
||||
|
||||
MiniProfiler.Start();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start the profiler
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// set discardResults to false when you want to abandon all profiling, this is useful for
|
||||
/// when someone is not authenticated or you want to clear the results based on some other mechanism.
|
||||
/// </remarks>
|
||||
public void Stop(bool discardResults = false)
|
||||
{
|
||||
if (GlobalSettings.DebugMode == false) return;
|
||||
//will not run in medium trust
|
||||
if (SystemUtilities.GetCurrentTrustLevel() < AspNetHostingPermissionLevel.High) return;
|
||||
|
||||
MiniProfiler.Stop(discardResults);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the request object from the app instance if it is available
|
||||
/// </summary>
|
||||
/// <param name="sender">The application object</param>
|
||||
/// <returns></returns>
|
||||
private Attempt<HttpRequestBase> TryGetRequest(object sender)
|
||||
{
|
||||
var app = sender as HttpApplication;
|
||||
if (app == null) return Attempt<HttpRequestBase>.False;
|
||||
|
||||
try
|
||||
{
|
||||
var req = app.Request;
|
||||
return new Attempt<HttpRequestBase>(true, new HttpRequestWrapper(req));
|
||||
}
|
||||
catch (HttpException ex)
|
||||
{
|
||||
return new Attempt<HttpRequestBase>(ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -42,4 +42,5 @@ using System.Security.Permissions;
|
||||
[assembly: InternalsVisibleTo("Umbraco.Courier.Persistence")]
|
||||
|
||||
[assembly: InternalsVisibleTo("Concorde.Sync")]
|
||||
[assembly: InternalsVisibleTo("Umbraco.Belle")]
|
||||
[assembly: InternalsVisibleTo("Umbraco.Belle")]
|
||||
[assembly: InternalsVisibleTo("Umbraco.VisualStudio")]
|
||||
@@ -1,48 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.PropertyEditors.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a PropertyEditor
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
|
||||
internal sealed class PropertyEditorAttribute : Attribute
|
||||
{
|
||||
public PropertyEditorAttribute(string id, string alias, string name)
|
||||
{
|
||||
Mandate.ParameterNotNullOrEmpty(id, "id");
|
||||
Mandate.ParameterNotNullOrEmpty(alias, "alias");
|
||||
Mandate.ParameterNotNullOrEmpty(name, "name");
|
||||
|
||||
Id = Guid.Parse(id);
|
||||
Alias = alias;
|
||||
Name = name;
|
||||
|
||||
IsContentPropertyEditor = true;
|
||||
}
|
||||
|
||||
public Guid Id { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name.
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the alias.
|
||||
/// </summary>
|
||||
/// <value>The alias.</value>
|
||||
public string Alias { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Flag determining if this property editor is used to edit content
|
||||
/// </summary>
|
||||
public bool IsContentPropertyEditor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Flag determining if this property editor is used to edit parameters
|
||||
/// </summary>
|
||||
public bool IsParameterEditor { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.PropertyEditors.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// Attribute determining whether or not to hide/show the label of a property
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This directly affects the meta data property: HideSurroundingHtml
|
||||
/// </remarks>
|
||||
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
|
||||
internal class ShowLabelAttribute : Attribute
|
||||
{
|
||||
public ShowLabelAttribute(bool show)
|
||||
{
|
||||
ShowLabel = show;
|
||||
}
|
||||
|
||||
public bool ShowLabel { get; private set; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
namespace Umbraco.Core.PropertyEditors
|
||||
{
|
||||
/// <summary>
|
||||
/// A class representing a blank, null or empty pre-value editor.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This class can be used for Property Editors who do not define a Pre value editor
|
||||
/// </remarks>
|
||||
internal class BlankPreValueModel : PreValueModel
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,147 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Web.Mvc;
|
||||
|
||||
namespace Umbraco.Core.PropertyEditors
|
||||
{
|
||||
internal abstract class EditorModel<TValueModel> where TValueModel : IValueModel, new()
|
||||
{
|
||||
protected EditorModel()
|
||||
{
|
||||
// Set the UI Elements collection to an empty list
|
||||
//UIElements = new List<UIElement>();
|
||||
}
|
||||
|
||||
[ReadOnly(true)]
|
||||
public virtual bool ShowUmbracoLabel
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of UI Elements for the property editor.
|
||||
/// </summary>
|
||||
//[ScaffoldColumn(false)]
|
||||
//public virtual IList<UIElement> UIElements { get; protected internal set; }
|
||||
|
||||
private ModelMetadata _modelMetadata;
|
||||
|
||||
/// <summary>
|
||||
/// Returns the meta data for the current editor model
|
||||
/// </summary>
|
||||
protected internal ModelMetadata MetaData
|
||||
{
|
||||
get
|
||||
{
|
||||
return _modelMetadata ?? (_modelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => this, GetType()));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the serialized value for the PropertyEditor
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public virtual IDictionary<string, object> GetSerializedValue()
|
||||
{
|
||||
var editableProps = MetaData.Properties.Where(x => x.ShowForEdit && !x.IsReadOnly);
|
||||
var d = new Dictionary<string, object>();
|
||||
foreach (var p in editableProps)
|
||||
{
|
||||
//by default, we will not support complex modelled properties, developers will need to override
|
||||
//the GetSerializedValue method if they need support for this.
|
||||
if (p.IsComplexType)
|
||||
{
|
||||
//TODO: We should magically support this
|
||||
throw new NotSupportedException("The default serialization implementation of EditorModel does not support properties that are complex models");
|
||||
}
|
||||
|
||||
d.Add(p.PropertyName, p.Model);
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
public virtual void SetModelValues(IDictionary<string, object> serializedVal)
|
||||
{
|
||||
if (serializedVal == null || serializedVal.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var modelProperties = GetType().GetProperties();
|
||||
|
||||
var editableProps = MetaData.Properties.Where(x => x.ShowForEdit && !x.IsReadOnly);
|
||||
|
||||
foreach (var i in serializedVal)
|
||||
{
|
||||
if (i.Value == null)
|
||||
continue;
|
||||
|
||||
//get the property with the name
|
||||
var prop = editableProps.Where(x => x.PropertyName == i.Key).SingleOrDefault();
|
||||
if (prop != null)
|
||||
{
|
||||
//set the property value
|
||||
var toConverter = TypeDescriptor.GetConverter(prop.ModelType);
|
||||
if (toConverter != null)
|
||||
{
|
||||
//get the model property for this property meta data to set its value
|
||||
var propInfo = modelProperties.Where(x => x.Name == prop.PropertyName).Single();
|
||||
object convertedVal;
|
||||
|
||||
//if value is already of the same type, just use the current value, otherwise try and convert it
|
||||
if (i.Value.GetType() == propInfo.PropertyType)
|
||||
{
|
||||
convertedVal = i.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
convertedVal = toConverter.ConvertFrom(i.Value);
|
||||
}
|
||||
catch (NotSupportedException)
|
||||
{
|
||||
//this occurs when the converter doesn't know how, so we can try the opposite way as a last ditch effort
|
||||
var fromConverter = TypeDescriptor.GetConverter(i.Value.GetType());
|
||||
if (fromConverter == null)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
convertedVal = fromConverter.ConvertTo(i.Value, prop.ModelType);
|
||||
|
||||
}
|
||||
}
|
||||
propInfo.SetValue(this, convertedVal, null);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public virtual TValueModel GetValueModel()
|
||||
{
|
||||
var editableProps = MetaData.Properties.Where(x => x.ShowForEdit && !x.IsReadOnly);
|
||||
var d = new TValueModel();
|
||||
foreach (var p in editableProps)
|
||||
{
|
||||
//by default, we will not support complex modelled properties, developers will need to override
|
||||
//the GetSerializedValue method if they need support for this.
|
||||
//TODO Test if this exception is still valid
|
||||
if (p.IsComplexType)
|
||||
{
|
||||
throw new NotSupportedException("The default serialization implementation of EditorModel does not support properties that are complex models");
|
||||
}
|
||||
|
||||
var property = d.GetType().GetProperty(p.PropertyName);
|
||||
if(property != null)
|
||||
{
|
||||
property.SetValue(d, p.Model, null);
|
||||
}
|
||||
}
|
||||
return d;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
namespace Umbraco.Core.PropertyEditors
|
||||
{
|
||||
/// <summary>
|
||||
/// An abstract class representing the model to render a Property Editor's content editor with PreValues
|
||||
/// </summary>
|
||||
/// <typeparam name="TPreValueModel">The type of the PreValue model.</typeparam>
|
||||
/// <typeparam name="TValueModel"> </typeparam>
|
||||
internal abstract class EditorModel<TValueModel, TPreValueModel> : EditorModel<TValueModel>
|
||||
where TValueModel : IValueModel, new()
|
||||
where TPreValueModel : PreValueModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="preValues">The pre value options used to construct the editor</param>
|
||||
protected EditorModel(TPreValueModel preValues)
|
||||
{
|
||||
PreValueModel = preValues;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The pre value options used to configure the editor
|
||||
/// </summary>
|
||||
/// <value>The pre value model.</value>
|
||||
public TPreValueModel PreValueModel { get; protected internal set; }
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
namespace Umbraco.Core.PropertyEditors
|
||||
{
|
||||
internal interface IValueModel
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.PropertyEditors
|
||||
{
|
||||
/// <summary>
|
||||
/// A class representing a single value of a Pre-Value editor to be saved
|
||||
/// </summary>
|
||||
internal class PreValueDefinition
|
||||
{
|
||||
public PreValueDefinition(string propertyName, Type modeType, object modelValue)
|
||||
{
|
||||
ModelType = modeType;
|
||||
PropertyName = propertyName;
|
||||
ModelValue = modelValue;
|
||||
}
|
||||
|
||||
public Type ModelType { get; private set; }
|
||||
public string PropertyName { get; private set; }
|
||||
public object ModelValue { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Umbraco.Core.PropertyEditors
|
||||
{
|
||||
/// <summary>
|
||||
/// Abstract class representing a Property Editor's model to render it's Pre value editor
|
||||
/// </summary>
|
||||
internal abstract class PreValueModel
|
||||
{
|
||||
protected virtual IEnumerable<PreValueDefinition> GetValueDefinitions()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public virtual string GetSerializedValue()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected virtual void SetModelPropertyValue(PreValueDefinition def, Action<object> setProperty)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public virtual void SetModelValues(string serializedVal)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.PropertyEditors.Attributes;
|
||||
|
||||
namespace Umbraco.Core.PropertyEditors
|
||||
{
|
||||
internal abstract class PropertyEditor
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor for a PropertyEditor
|
||||
/// </summary>
|
||||
protected PropertyEditor()
|
||||
{
|
||||
//Locate the metadata attribute
|
||||
var docTypeAttributes = GetType()
|
||||
.GetCustomAttributes(typeof(PropertyEditorAttribute), true)
|
||||
.OfType<PropertyEditorAttribute>();
|
||||
|
||||
if (!docTypeAttributes.Any())
|
||||
throw new InvalidOperationException(
|
||||
string.Format("The PropertyEditor of type {0} is missing the {1} attribute", GetType().FullName,
|
||||
typeof(PropertyEditorAttribute).FullName));
|
||||
|
||||
//assign the properties of this object to those of the metadata attribute
|
||||
var attr = docTypeAttributes.First();
|
||||
Id = attr.Id;
|
||||
Name = attr.Name;
|
||||
Alias = attr.Alias;
|
||||
}
|
||||
|
||||
public virtual Guid Id { get; protected set; }
|
||||
|
||||
public virtual string Name { get; protected set; }
|
||||
|
||||
public virtual string Alias { get; protected set; }
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
namespace Umbraco.Core.PropertyEditors
|
||||
{
|
||||
/// <summary>
|
||||
/// Abstract class that all Property editors should inherit from
|
||||
/// </summary>
|
||||
/// <typeparam name="TEditorModel"></typeparam>
|
||||
/// <typeparam name="TPreValueModel"></typeparam>
|
||||
/// <typeparam name="TValueModel"> </typeparam>
|
||||
internal abstract class PropertyEditor<TValueModel, TEditorModel, TPreValueModel> : PropertyEditor
|
||||
where TValueModel : IValueModel, new()
|
||||
where TEditorModel : EditorModel<TValueModel>
|
||||
where TPreValueModel : PreValueModel
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Returns the editor model to be used for the property editor
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public abstract TEditorModel CreateEditorModel(TPreValueModel preValues);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the editor model to be used for the prevalue editor
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public abstract TPreValueModel CreatePreValueEditorModel();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Abstract class that Property editors should inherit from that don't require a pre-value editor
|
||||
/// </summary>
|
||||
/// <typeparam name="TEditorModel"></typeparam>
|
||||
/// <typeparam name="TValueModel"> </typeparam>
|
||||
internal abstract class PropertyEditor<TValueModel, TEditorModel> : PropertyEditor<TValueModel, TEditorModel, BlankPreValueModel>
|
||||
where TValueModel : IValueModel, new()
|
||||
where TEditorModel : EditorModel<TValueModel>
|
||||
{
|
||||
public override BlankPreValueModel CreatePreValueEditorModel()
|
||||
{
|
||||
return new BlankPreValueModel();
|
||||
}
|
||||
|
||||
public sealed override TEditorModel CreateEditorModel(BlankPreValueModel preValues)
|
||||
{
|
||||
return CreateEditorModel();
|
||||
}
|
||||
|
||||
public abstract TEditorModel CreateEditorModel();
|
||||
}
|
||||
}
|
||||
@@ -60,8 +60,13 @@ namespace Umbraco.Core.Services
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="IContent"/> object using the alias of the <see cref="IContentType"/>
|
||||
/// that this Content is based on.
|
||||
/// that this Content should based on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Note that using this method will simply return a new IContent without any identity
|
||||
/// as it has not yet been persisted. It is intended as a shortcut to creating new content objects
|
||||
/// that does not invoke a save operation against the database.
|
||||
/// </remarks>
|
||||
/// <param name="name">Name of the Content object</param>
|
||||
/// <param name="parentId">Id of Parent for the new Content</param>
|
||||
/// <param name="contentTypeAlias">Alias of the <see cref="IContentType"/></param>
|
||||
@@ -70,7 +75,7 @@ namespace Umbraco.Core.Services
|
||||
public IContent CreateContent(string name, int parentId, string contentTypeAlias, int userId = 0)
|
||||
{
|
||||
var contentType = FindContentTypeByAlias(contentTypeAlias);
|
||||
var content = new Content(name, parentId, contentType); ;
|
||||
var content = new Content(name, parentId, contentType);
|
||||
|
||||
if (Creating.IsRaisedEventCancelled(new NewEventArgs<IContent>(content, contentTypeAlias, parentId), this))
|
||||
{
|
||||
@@ -90,8 +95,13 @@ namespace Umbraco.Core.Services
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="IContent"/> object using the alias of the <see cref="IContentType"/>
|
||||
/// that this Content is based on.
|
||||
/// that this Content should based on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Note that using this method will simply return a new IContent without any identity
|
||||
/// as it has not yet been persisted. It is intended as a shortcut to creating new content objects
|
||||
/// that does not invoke a save operation against the database.
|
||||
/// </remarks>
|
||||
/// <param name="name">Name of the Content object</param>
|
||||
/// <param name="parent">Parent <see cref="IContent"/> object for the new Content</param>
|
||||
/// <param name="contentTypeAlias">Alias of the <see cref="IContentType"/></param>
|
||||
@@ -118,6 +128,86 @@ namespace Umbraco.Core.Services
|
||||
return content;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and saves an <see cref="IContent"/> object using the alias of the <see cref="IContentType"/>
|
||||
/// that this Content should based on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method returns an <see cref="IContent"/> object that has been persisted to the database
|
||||
/// and therefor has an identity.
|
||||
/// </remarks>
|
||||
/// <param name="name">Name of the Content object</param>
|
||||
/// <param name="parentId">Id of Parent for the new Content</param>
|
||||
/// <param name="contentTypeAlias">Alias of the <see cref="IContentType"/></param>
|
||||
/// <param name="userId">Optional id of the user creating the content</param>
|
||||
/// <returns><see cref="IContent"/></returns>
|
||||
public IContent CreateContentWithIdentity(string name, int parentId, string contentTypeAlias, int userId = 0)
|
||||
{
|
||||
var contentType = FindContentTypeByAlias(contentTypeAlias);
|
||||
var content = new Content(name, parentId, contentType);
|
||||
|
||||
if (Creating.IsRaisedEventCancelled(new NewEventArgs<IContent>(content, contentTypeAlias, parentId), this))
|
||||
{
|
||||
content.WasCancelled = true;
|
||||
return content;
|
||||
}
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateContentRepository(uow))
|
||||
{
|
||||
content.CreatorId = userId;
|
||||
content.WriterId = userId;
|
||||
repository.AddOrUpdate(content);
|
||||
uow.Commit();
|
||||
}
|
||||
|
||||
Created.RaiseEvent(new NewEventArgs<IContent>(content, false, contentTypeAlias, parentId), this);
|
||||
|
||||
Audit.Add(AuditTypes.New, "", content.CreatorId, content.Id);
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and saves an <see cref="IContent"/> object using the alias of the <see cref="IContentType"/>
|
||||
/// that this Content should based on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method returns an <see cref="IContent"/> object that has been persisted to the database
|
||||
/// and therefor has an identity.
|
||||
/// </remarks>
|
||||
/// <param name="name">Name of the Content object</param>
|
||||
/// <param name="parent">Parent <see cref="IContent"/> object for the new Content</param>
|
||||
/// <param name="contentTypeAlias">Alias of the <see cref="IContentType"/></param>
|
||||
/// <param name="userId">Optional id of the user creating the content</param>
|
||||
/// <returns><see cref="IContent"/></returns>
|
||||
public IContent CreateContentWithIdentity(string name, IContent parent, string contentTypeAlias, int userId = 0)
|
||||
{
|
||||
var contentType = FindContentTypeByAlias(contentTypeAlias);
|
||||
var content = new Content(name, parent, contentType);
|
||||
|
||||
if (Creating.IsRaisedEventCancelled(new NewEventArgs<IContent>(content, contentTypeAlias, parent), this))
|
||||
{
|
||||
content.WasCancelled = true;
|
||||
return content;
|
||||
}
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateContentRepository(uow))
|
||||
{
|
||||
content.CreatorId = userId;
|
||||
content.WriterId = userId;
|
||||
repository.AddOrUpdate(content);
|
||||
uow.Commit();
|
||||
}
|
||||
|
||||
Created.RaiseEvent(new NewEventArgs<IContent>(content, false, contentTypeAlias, parent), this);
|
||||
|
||||
Audit.Add(AuditTypes.New, "", content.CreatorId, content.Id);
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an <see cref="IContent"/> object by Id
|
||||
/// </summary>
|
||||
@@ -1094,6 +1184,92 @@ namespace Umbraco.Core.Services
|
||||
return content;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sorts a collection of <see cref="IContent"/> objects by updating the SortOrder according
|
||||
/// to the ordering of items in the passed in <see cref="IEnumerable{T}"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Using this method will ensure that the Published-state is maintained upon sorting
|
||||
/// so the cache is updated accordingly - as needed.
|
||||
/// </remarks>
|
||||
/// <param name="items"></param>
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="raiseEvents"></param>
|
||||
/// <returns>True if sorting succeeded, otherwise False</returns>
|
||||
public bool Sort(IEnumerable<IContent> items, int userId = 0, bool raiseEvents = true)
|
||||
{
|
||||
if (raiseEvents)
|
||||
{
|
||||
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IContent>(items), this))
|
||||
return false;
|
||||
}
|
||||
|
||||
var shouldBePublished = new List<IContent>();
|
||||
var shouldBeSaved = new List<IContent>();
|
||||
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateContentRepository(uow))
|
||||
{
|
||||
int i = 0;
|
||||
foreach (var content in items)
|
||||
{
|
||||
//If the current sort order equals that of the content
|
||||
//we don't need to update it, so just increment the sort order
|
||||
//and continue.
|
||||
if (content.SortOrder == i)
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
content.SortOrder = i;
|
||||
content.WriterId = userId;
|
||||
i++;
|
||||
|
||||
if (content.Published)
|
||||
{
|
||||
var published = _publishingStrategy.Publish(content, userId);
|
||||
shouldBePublished.Add(content);
|
||||
}
|
||||
else
|
||||
shouldBeSaved.Add(content);
|
||||
|
||||
repository.AddOrUpdate(content);
|
||||
}
|
||||
|
||||
uow.Commit();
|
||||
|
||||
foreach (var content in shouldBeSaved)
|
||||
{
|
||||
//Create and Save PreviewXml DTO
|
||||
var xml = content.ToXml();
|
||||
CreateAndSavePreviewXml(xml, content.Id, content.Version, uow.Database);
|
||||
}
|
||||
|
||||
foreach (var content in shouldBePublished)
|
||||
{
|
||||
//Create and Save PreviewXml DTO
|
||||
var xml = content.ToXml();
|
||||
CreateAndSavePreviewXml(xml, content.Id, content.Version, uow.Database);
|
||||
//Create and Save ContentXml DTO
|
||||
CreateAndSaveContentXml(xml, content.Id, uow.Database);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (raiseEvents)
|
||||
Saved.RaiseEvent(new SaveEventArgs<IContent>(items, false), this);
|
||||
|
||||
if(shouldBePublished.Any())
|
||||
_publishingStrategy.PublishingFinalized(shouldBePublished, false);
|
||||
|
||||
Audit.Add(AuditTypes.Sort, "Sorting content performed by user", userId, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#region Internal Methods
|
||||
|
||||
/// <summary>
|
||||
@@ -1369,24 +1545,9 @@ namespace Umbraco.Core.Services
|
||||
var publishStatus = new PublishStatus(content, PublishStatusType.Success); //initially set to success
|
||||
|
||||
//Check if parent is published (although not if its a root node) - if parent isn't published this Content cannot be published
|
||||
if (content.ParentId != -1 && content.ParentId != -20 && IsPublishable(content) == false)
|
||||
{
|
||||
LogHelper.Info<ContentService>(
|
||||
string.Format(
|
||||
"Content '{0}' with Id '{1}' could not be published because its parent is not published.",
|
||||
content.Name, content.Id));
|
||||
publishStatus.StatusType = PublishStatusType.FailedPathNotPublished;
|
||||
}
|
||||
|
||||
publishStatus.StatusType = CheckAndLogIsPublishable(content);
|
||||
//Content contains invalid property values and can therefore not be published - fire event?
|
||||
if (content.IsValid() == false)
|
||||
{
|
||||
LogHelper.Info<ContentService>(
|
||||
string.Format(
|
||||
"Content '{0}' with Id '{1}' could not be published because of invalid properties.",
|
||||
content.Name, content.Id));
|
||||
publishStatus.StatusType = PublishStatusType.FailedContentInvalid;
|
||||
}
|
||||
publishStatus.StatusType = CheckAndLogIsValid(content);
|
||||
|
||||
//if we're still successful, then publish using the strategy
|
||||
if (publishStatus.StatusType == PublishStatusType.Success)
|
||||
@@ -1413,37 +1574,12 @@ namespace Umbraco.Core.Services
|
||||
|
||||
var xml = content.ToXml();
|
||||
//Preview Xml
|
||||
var previewPoco = new PreviewXmlDto
|
||||
{
|
||||
NodeId = content.Id,
|
||||
Timestamp = DateTime.Now,
|
||||
VersionId = content.Version,
|
||||
Xml = xml.ToString(SaveOptions.None)
|
||||
};
|
||||
var previewExists =
|
||||
uow.Database.ExecuteScalar<int>("SELECT COUNT(nodeId) FROM cmsPreviewXml WHERE nodeId = @Id AND versionId = @Version",
|
||||
new { Id = content.Id, Version = content.Version }) != 0;
|
||||
int previewResult = previewExists
|
||||
? uow.Database.Update<PreviewXmlDto>(
|
||||
"SET xml = @Xml, timestamp = @Timestamp WHERE nodeId = @Id AND versionId = @Version",
|
||||
new
|
||||
{
|
||||
Xml = previewPoco.Xml,
|
||||
Timestamp = previewPoco.Timestamp,
|
||||
Id = previewPoco.NodeId,
|
||||
Version = previewPoco.VersionId
|
||||
})
|
||||
: Convert.ToInt32(uow.Database.Insert(previewPoco));
|
||||
CreateAndSavePreviewXml(xml, content.Id, content.Version, uow.Database);
|
||||
|
||||
if (published)
|
||||
{
|
||||
//Content Xml
|
||||
var contentPoco = new ContentXmlDto { NodeId = content.Id, Xml = xml.ToString(SaveOptions.None) };
|
||||
var contentExists = uow.Database.ExecuteScalar<int>("SELECT COUNT(nodeId) FROM cmsContentXml WHERE nodeId = @Id", new { Id = content.Id }) != 0;
|
||||
int contentResult = contentExists
|
||||
? uow.Database.Update(contentPoco)
|
||||
: Convert.ToInt32(uow.Database.Insert(contentPoco));
|
||||
|
||||
CreateAndSaveContentXml(xml, content.Id, uow.Database);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1501,27 +1637,7 @@ namespace Umbraco.Core.Services
|
||||
|
||||
//Preview Xml
|
||||
var xml = content.ToXml();
|
||||
var previewPoco = new PreviewXmlDto
|
||||
{
|
||||
NodeId = content.Id,
|
||||
Timestamp = DateTime.Now,
|
||||
VersionId = content.Version,
|
||||
Xml = xml.ToString(SaveOptions.None)
|
||||
};
|
||||
var previewExists =
|
||||
uow.Database.ExecuteScalar<int>("SELECT COUNT(nodeId) FROM cmsPreviewXml WHERE nodeId = @Id AND versionId = @Version",
|
||||
new { Id = content.Id, Version = content.Version }) != 0;
|
||||
int previewResult = previewExists
|
||||
? uow.Database.Update<PreviewXmlDto>(
|
||||
"SET xml = @Xml, timestamp = @Timestamp WHERE nodeId = @Id AND versionId = @Version",
|
||||
new
|
||||
{
|
||||
Xml = previewPoco.Xml,
|
||||
Timestamp = previewPoco.Timestamp,
|
||||
Id = previewPoco.NodeId,
|
||||
Version = previewPoco.VersionId
|
||||
})
|
||||
: Convert.ToInt32(uow.Database.Insert(previewPoco));
|
||||
CreateAndSavePreviewXml(xml, content.Id, content.Version, uow.Database);
|
||||
}
|
||||
|
||||
if (raiseEvents)
|
||||
@@ -1565,6 +1681,68 @@ namespace Umbraco.Core.Services
|
||||
return true;
|
||||
}
|
||||
|
||||
private PublishStatusType CheckAndLogIsPublishable(IContent content)
|
||||
{
|
||||
//Check if parent is published (although not if its a root node) - if parent isn't published this Content cannot be published
|
||||
if (content.ParentId != -1 && content.ParentId != -20 && IsPublishable(content) == false)
|
||||
{
|
||||
LogHelper.Info<ContentService>(
|
||||
string.Format(
|
||||
"Content '{0}' with Id '{1}' could not be published because its parent is not published.",
|
||||
content.Name, content.Id));
|
||||
return PublishStatusType.FailedPathNotPublished;
|
||||
}
|
||||
|
||||
return PublishStatusType.Success;
|
||||
}
|
||||
|
||||
private PublishStatusType CheckAndLogIsValid(IContent content)
|
||||
{
|
||||
//Content contains invalid property values and can therefore not be published - fire event?
|
||||
if (content.IsValid() == false)
|
||||
{
|
||||
LogHelper.Info<ContentService>(
|
||||
string.Format(
|
||||
"Content '{0}' with Id '{1}' could not be published because of invalid properties.",
|
||||
content.Name, content.Id));
|
||||
return PublishStatusType.FailedContentInvalid;
|
||||
}
|
||||
|
||||
return PublishStatusType.Success;
|
||||
}
|
||||
|
||||
private void CreateAndSavePreviewXml(XElement xml, int id, Guid version, UmbracoDatabase db)
|
||||
{
|
||||
var previewPoco = new PreviewXmlDto
|
||||
{
|
||||
NodeId = id,
|
||||
Timestamp = DateTime.Now,
|
||||
VersionId = version,
|
||||
Xml = xml.ToString(SaveOptions.None)
|
||||
};
|
||||
var previewExists =
|
||||
db.ExecuteScalar<int>("SELECT COUNT(nodeId) FROM cmsPreviewXml WHERE nodeId = @Id AND versionId = @Version",
|
||||
new { Id = id, Version = version }) != 0;
|
||||
int previewResult = previewExists
|
||||
? db.Update<PreviewXmlDto>(
|
||||
"SET xml = @Xml, timestamp = @Timestamp WHERE nodeId = @Id AND versionId = @Version",
|
||||
new
|
||||
{
|
||||
Xml = previewPoco.Xml,
|
||||
Timestamp = previewPoco.Timestamp,
|
||||
Id = previewPoco.NodeId,
|
||||
Version = previewPoco.VersionId
|
||||
})
|
||||
: Convert.ToInt32(db.Insert(previewPoco));
|
||||
}
|
||||
|
||||
private void CreateAndSaveContentXml(XElement xml, int id, UmbracoDatabase db)
|
||||
{
|
||||
var contentPoco = new ContentXmlDto { NodeId = id, Xml = xml.ToString(SaveOptions.None) };
|
||||
var contentExists = db.ExecuteScalar<int>("SELECT COUNT(nodeId) FROM cmsContentXml WHERE nodeId = @Id", new { Id = id }) != 0;
|
||||
int contentResult = contentExists ? db.Update(contentPoco) : Convert.ToInt32(db.Insert(contentPoco));
|
||||
}
|
||||
|
||||
private IContentType FindContentTypeByAlias(string contentTypeAlias)
|
||||
{
|
||||
using (var repository = _repositoryFactory.CreateContentTypeRepository(_uowProvider.GetUnitOfWork()))
|
||||
@@ -1572,7 +1750,7 @@ namespace Umbraco.Core.Services
|
||||
var query = Query<IContentType>.Builder.Where(x => x.Alias == contentTypeAlias);
|
||||
var types = repository.GetByQuery(query);
|
||||
|
||||
if (!types.Any())
|
||||
if (types.Any() == false)
|
||||
throw new Exception(
|
||||
string.Format("No ContentType matching the passed in Alias: '{0}' was found",
|
||||
contentTypeAlias));
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Linq;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Services
|
||||
@@ -12,8 +11,13 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates an <see cref="IContent"/> object using the alias of the <see cref="IContentType"/>
|
||||
/// that this Content is based on.
|
||||
/// that this Content should based on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Note that using this method will simply return a new IContent without any identity
|
||||
/// as it has not yet been persisted. It is intended as a shortcut to creating new content objects
|
||||
/// that does not invoke a save operation against the database.
|
||||
/// </remarks>
|
||||
/// <param name="name">Name of the Content object</param>
|
||||
/// <param name="parentId">Id of Parent for the new Content</param>
|
||||
/// <param name="contentTypeAlias">Alias of the <see cref="IContentType"/></param>
|
||||
@@ -23,8 +27,13 @@ namespace Umbraco.Core.Services
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="IContent"/> object using the alias of the <see cref="IContentType"/>
|
||||
/// that this Content is based on.
|
||||
/// that this Content should based on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Note that using this method will simply return a new IContent without any identity
|
||||
/// as it has not yet been persisted. It is intended as a shortcut to creating new content objects
|
||||
/// that does not invoke a save operation against the database.
|
||||
/// </remarks>
|
||||
/// <param name="name">Name of the Content object</param>
|
||||
/// <param name="parent">Parent <see cref="IContent"/> object for the new Content</param>
|
||||
/// <param name="contentTypeAlias">Alias of the <see cref="IContentType"/></param>
|
||||
@@ -302,6 +311,18 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="content"><see cref="IContent"/> to retrieve ancestors for</param>
|
||||
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
|
||||
IEnumerable<IContent> GetAncestors(IContent content);
|
||||
/// Sorts a collection of <see cref="IContent"/> objects by updating the SortOrder according
|
||||
/// to the ordering of items in the passed in <see cref="IEnumerable{T}"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Using this method will ensure that the Published-state is maintained upon sorting
|
||||
/// so the cache is updated accordingly - as needed.
|
||||
/// </remarks>
|
||||
/// <param name="items"></param>
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="raiseEvents"></param>
|
||||
/// <returns>True if sorting succeeded, otherwise False</returns>
|
||||
bool Sort(IEnumerable<IContent> items, int userId = 0, bool raiseEvents = true);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the parent of the current content as an <see cref="IContent"/> item.
|
||||
@@ -316,5 +337,33 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="content"><see cref="IContent"/> to retrieve the parent from</param>
|
||||
/// <returns>Parent <see cref="IContent"/> object</returns>
|
||||
IContent GetParent(IContent content);
|
||||
/// Creates and saves an <see cref="IContent"/> object using the alias of the <see cref="IContentType"/>
|
||||
/// that this Content should based on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method returns an <see cref="IContent"/> object that has been persisted to the database
|
||||
/// and therefor has an identity.
|
||||
/// </remarks>
|
||||
/// <param name="name">Name of the Content object</param>
|
||||
/// <param name="parent">Parent <see cref="IContent"/> object for the new Content</param>
|
||||
/// <param name="contentTypeAlias">Alias of the <see cref="IContentType"/></param>
|
||||
/// <param name="userId">Optional id of the user creating the content</param>
|
||||
/// <returns><see cref="IContent"/></returns>
|
||||
IContent CreateContentWithIdentity(string name, IContent parent, string contentTypeAlias, int userId = 0);
|
||||
|
||||
/// <summary>
|
||||
/// Creates and saves an <see cref="IContent"/> object using the alias of the <see cref="IContentType"/>
|
||||
/// that this Content should based on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method returns an <see cref="IContent"/> object that has been persisted to the database
|
||||
/// and therefor has an identity.
|
||||
/// </remarks>
|
||||
/// <param name="name">Name of the Content object</param>
|
||||
/// <param name="parentId">Id of Parent for the new Content</param>
|
||||
/// <param name="contentTypeAlias">Alias of the <see cref="IContentType"/></param>
|
||||
/// <param name="userId">Optional id of the user creating the content</param>
|
||||
/// <returns><see cref="IContent"/></returns>
|
||||
IContent CreateContentWithIdentity(string name, int parentId, string contentTypeAlias, int userId = 0);
|
||||
}
|
||||
}
|
||||
@@ -11,8 +11,13 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates an <see cref="IMedia"/> object using the alias of the <see cref="IMediaType"/>
|
||||
/// that this Media is based on.
|
||||
/// that this Media should based on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Note that using this method will simply return a new IMedia without any identity
|
||||
/// as it has not yet been persisted. It is intended as a shortcut to creating new media objects
|
||||
/// that does not invoke a save operation against the database.
|
||||
/// </remarks>
|
||||
/// <param name="name">Name of the Media object</param>
|
||||
/// <param name="parentId">Id of Parent for the new Media item</param>
|
||||
/// <param name="mediaTypeAlias">Alias of the <see cref="IMediaType"/></param>
|
||||
@@ -22,8 +27,13 @@ namespace Umbraco.Core.Services
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="IMedia"/> object using the alias of the <see cref="IMediaType"/>
|
||||
/// that this Media is based on.
|
||||
/// that this Media should based on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Note that using this method will simply return a new IMedia without any identity
|
||||
/// as it has not yet been persisted. It is intended as a shortcut to creating new media objects
|
||||
/// that does not invoke a save operation against the database.
|
||||
/// </remarks>
|
||||
/// <param name="name">Name of the Media object</param>
|
||||
/// <param name="parent">Parent <see cref="IMedia"/> for the new Media item</param>
|
||||
/// <param name="mediaTypeAlias">Alias of the <see cref="IMediaType"/></param>
|
||||
@@ -184,7 +194,7 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="mediaPath">Path of the media item to retreive (for example: /media/1024/koala_403x328.jpg)</param>
|
||||
/// <returns><see cref="IMedia"/></returns>
|
||||
IMedia GetMediaByPath(string mediaPath);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of <see cref="IMedia"/> objects, which are ancestors of the current media.
|
||||
/// </summary>
|
||||
@@ -219,5 +229,45 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="media"><see cref="IMedia"/> to retrieve the parent from</param>
|
||||
/// <returns>Parent <see cref="IMedia"/> object</returns>
|
||||
IMedia GetParent(IMedia media);
|
||||
|
||||
/// <summary>
|
||||
/// Sorts a collection of <see cref="IMedia"/> objects by updating the SortOrder according
|
||||
/// to the ordering of items in the passed in <see cref="IEnumerable{T}"/>.
|
||||
/// </summary>
|
||||
/// <param name="items"></param>
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="raiseEvents"></param>
|
||||
/// <returns>True if sorting succeeded, otherwise False</returns>
|
||||
bool Sort(IEnumerable<IMedia> items, int userId = 0, bool raiseEvents = true);
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="IMedia"/> object using the alias of the <see cref="IMediaType"/>
|
||||
/// that this Media should based on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method returns an <see cref="IMedia"/> object that has been persisted to the database
|
||||
/// and therefor has an identity.
|
||||
/// </remarks>
|
||||
/// <param name="name">Name of the Media object</param>
|
||||
/// <param name="parent">Parent <see cref="IMedia"/> for the new Media item</param>
|
||||
/// <param name="mediaTypeAlias">Alias of the <see cref="IMediaType"/></param>
|
||||
/// <param name="userId">Optional id of the user creating the media item</param>
|
||||
/// <returns><see cref="IMedia"/></returns>
|
||||
IMedia CreateMediaWithIdentity(string name, IMedia parent, string mediaTypeAlias, int userId = 0);
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="IMedia"/> object using the alias of the <see cref="IMediaType"/>
|
||||
/// that this Media should based on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method returns an <see cref="IMedia"/> object that has been persisted to the database
|
||||
/// and therefor has an identity.
|
||||
/// </remarks>
|
||||
/// <param name="name">Name of the Media object</param>
|
||||
/// <param name="parentId">Id of Parent for the new Media item</param>
|
||||
/// <param name="mediaTypeAlias">Alias of the <see cref="IMediaType"/></param>
|
||||
/// <param name="userId">Optional id of the user creating the media item</param>
|
||||
/// <returns><see cref="IMedia"/></returns>
|
||||
IMedia CreateMediaWithIdentity(string name, int parentId, string mediaTypeAlias, int userId = 0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
namespace Umbraco.Core.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the MemberService, which is an easy access to operations involving (umbraco) members.
|
||||
/// </summary>
|
||||
internal interface IMemberService : IMembershipMemberService
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines part of the MemberService, which is specific to methods used by the membership provider.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Idea is to have this is an isolated interface so that it can be easily 'replaced' in the membership provider impl.
|
||||
/// </remarks>
|
||||
internal interface IMembershipMemberService : IService
|
||||
{}
|
||||
}
|
||||
@@ -4,31 +4,40 @@ using Umbraco.Core.Models.Membership;
|
||||
namespace Umbraco.Core.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the UserService, which is an easy access to operations involving <see cref="IProfile"/> and eventually Users and Members.
|
||||
/// Defines the UserService, which is an easy access to operations involving <see cref="IProfile"/> and eventually Users.
|
||||
/// </summary>
|
||||
internal interface IUserService : IService
|
||||
internal interface IUserService : IMembershipUserService
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets an <see cref="IProfile"/> for the current BackOffice User
|
||||
/// </summary>
|
||||
/// <param name="httpContext">HttpContext to fetch the user through</param>
|
||||
/// <returns><see cref="IProfile"/> containing the Name and Id of the logged in BackOffice User</returns>
|
||||
IProfile GetCurrentBackOfficeUser(HttpContextBase httpContext);
|
||||
|
||||
/// <summary>
|
||||
/// Gets an <see cref="IProfile"/> for the current BackOffice User.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Requests the current HttpContext, so this method will only work in a web context.
|
||||
/// </remarks>
|
||||
/// <returns><see cref="IProfile"/> containing the Name and Id of the logged in BackOffice User</returns>
|
||||
IProfile GetCurrentBackOfficeUser();
|
||||
|
||||
/// <summary>
|
||||
/// Gets an IProfile by User Id.
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the User to retrieve</param>
|
||||
/// <returns><see cref="IProfile"/></returns>
|
||||
IProfile GetProfileById(int id);
|
||||
|
||||
/// <summary>
|
||||
/// Gets an IUserType by its Alias
|
||||
/// </summary>
|
||||
/// <param name="alias">Alias of the UserType to retrieve</param>
|
||||
/// <returns><see cref="IUserType"/></returns>
|
||||
IUserType GetUserTypeByAlias(string alias);
|
||||
|
||||
/// <summary>
|
||||
/// Gets an IUserType by its Name
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the UserType to retrieve</param>
|
||||
/// <returns><see cref="IUserType"/></returns>
|
||||
IUserType GetUserTypeByName(string name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines part of the UserService, which is specific to methods used by the membership provider.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Idea is to have this is an isolated interface so that it can be easily 'replaced' in the membership provider impl.
|
||||
/// </remarks>
|
||||
internal interface IMembershipUserService : IService
|
||||
{
|
||||
IMembershipUser CreateUser(string name, string login, string password, IUserType userType, string email = "");
|
||||
}
|
||||
}
|
||||
@@ -38,8 +38,13 @@ namespace Umbraco.Core.Services
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="IMedia"/> object using the alias of the <see cref="IMediaType"/>
|
||||
/// that this Media is based on.
|
||||
/// that this Media should based on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Note that using this method will simply return a new IMedia without any identity
|
||||
/// as it has not yet been persisted. It is intended as a shortcut to creating new media objects
|
||||
/// that does not invoke a save operation against the database.
|
||||
/// </remarks>
|
||||
/// <param name="name">Name of the Media object</param>
|
||||
/// <param name="parentId">Id of Parent for the new Media item</param>
|
||||
/// <param name="mediaTypeAlias">Alias of the <see cref="IMediaType"/></param>
|
||||
@@ -47,25 +52,7 @@ namespace Umbraco.Core.Services
|
||||
/// <returns><see cref="IMedia"/></returns>
|
||||
public IMedia CreateMedia(string name, int parentId, string mediaTypeAlias, int userId = 0)
|
||||
{
|
||||
IMediaType mediaType;
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMediaTypeRepository(uow))
|
||||
{
|
||||
var query = Query<IMediaType>.Builder.Where(x => x.Alias == mediaTypeAlias);
|
||||
var mediaTypes = repository.GetByQuery(query);
|
||||
|
||||
if (!mediaTypes.Any())
|
||||
throw new Exception(string.Format("No MediaType matching the passed in Alias: '{0}' was found",
|
||||
mediaTypeAlias));
|
||||
|
||||
mediaType = mediaTypes.First();
|
||||
|
||||
if (mediaType == null)
|
||||
throw new Exception(string.Format("MediaType matching the passed in Alias: '{0}' was null",
|
||||
mediaTypeAlias));
|
||||
}
|
||||
|
||||
var mediaType = FindMediaTypeByAlias(mediaTypeAlias);
|
||||
var media = new Models.Media(name, parentId, mediaType);
|
||||
|
||||
if (Creating.IsRaisedEventCancelled(new NewEventArgs<IMedia>(media, mediaTypeAlias, parentId), this))
|
||||
@@ -85,8 +72,13 @@ namespace Umbraco.Core.Services
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="IMedia"/> object using the alias of the <see cref="IMediaType"/>
|
||||
/// that this Media is based on.
|
||||
/// that this Media should based on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Note that using this method will simply return a new IMedia without any identity
|
||||
/// as it has not yet been persisted. It is intended as a shortcut to creating new media objects
|
||||
/// that does not invoke a save operation against the database.
|
||||
/// </remarks>
|
||||
/// <param name="name">Name of the Media object</param>
|
||||
/// <param name="parent">Parent <see cref="IMedia"/> for the new Media item</param>
|
||||
/// <param name="mediaTypeAlias">Alias of the <see cref="IMediaType"/></param>
|
||||
@@ -94,25 +86,7 @@ namespace Umbraco.Core.Services
|
||||
/// <returns><see cref="IMedia"/></returns>
|
||||
public IMedia CreateMedia(string name, IMedia parent, string mediaTypeAlias, int userId = 0)
|
||||
{
|
||||
IMediaType mediaType;
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMediaTypeRepository(uow))
|
||||
{
|
||||
var query = Query<IMediaType>.Builder.Where(x => x.Alias == mediaTypeAlias);
|
||||
var mediaTypes = repository.GetByQuery(query);
|
||||
|
||||
if (!mediaTypes.Any())
|
||||
throw new Exception(string.Format("No MediaType matching the passed in Alias: '{0}' was found",
|
||||
mediaTypeAlias));
|
||||
|
||||
mediaType = mediaTypes.First();
|
||||
|
||||
if (mediaType == null)
|
||||
throw new Exception(string.Format("MediaType matching the passed in Alias: '{0}' was null",
|
||||
mediaTypeAlias));
|
||||
}
|
||||
|
||||
var mediaType = FindMediaTypeByAlias(mediaTypeAlias);
|
||||
var media = new Models.Media(name, parent, mediaType);
|
||||
if (Creating.IsRaisedEventCancelled(new NewEventArgs<IMedia>(media, mediaTypeAlias, parent), this))
|
||||
{
|
||||
@@ -129,6 +103,94 @@ namespace Umbraco.Core.Services
|
||||
return media;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="IMedia"/> object using the alias of the <see cref="IMediaType"/>
|
||||
/// that this Media should based on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method returns an <see cref="IMedia"/> object that has been persisted to the database
|
||||
/// and therefor has an identity.
|
||||
/// </remarks>
|
||||
/// <param name="name">Name of the Media object</param>
|
||||
/// <param name="parentId">Id of Parent for the new Media item</param>
|
||||
/// <param name="mediaTypeAlias">Alias of the <see cref="IMediaType"/></param>
|
||||
/// <param name="userId">Optional id of the user creating the media item</param>
|
||||
/// <returns><see cref="IMedia"/></returns>
|
||||
public IMedia CreateMediaWithIdentity(string name, int parentId, string mediaTypeAlias, int userId = 0)
|
||||
{
|
||||
var mediaType = FindMediaTypeByAlias(mediaTypeAlias);
|
||||
var media = new Models.Media(name, parentId, mediaType);
|
||||
if (Creating.IsRaisedEventCancelled(new NewEventArgs<IMedia>(media, mediaTypeAlias, parentId), this))
|
||||
{
|
||||
media.WasCancelled = true;
|
||||
return media;
|
||||
}
|
||||
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMediaRepository(uow))
|
||||
{
|
||||
media.CreatorId = userId;
|
||||
repository.AddOrUpdate(media);
|
||||
uow.Commit();
|
||||
|
||||
var xml = media.ToXml();
|
||||
CreateAndSaveMediaXml(xml, media.Id, uow.Database);
|
||||
}
|
||||
}
|
||||
|
||||
Created.RaiseEvent(new NewEventArgs<IMedia>(media, false, mediaTypeAlias, parentId), this);
|
||||
|
||||
Audit.Add(AuditTypes.New, "", media.CreatorId, media.Id);
|
||||
|
||||
return media;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="IMedia"/> object using the alias of the <see cref="IMediaType"/>
|
||||
/// that this Media should based on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method returns an <see cref="IMedia"/> object that has been persisted to the database
|
||||
/// and therefor has an identity.
|
||||
/// </remarks>
|
||||
/// <param name="name">Name of the Media object</param>
|
||||
/// <param name="parent">Parent <see cref="IMedia"/> for the new Media item</param>
|
||||
/// <param name="mediaTypeAlias">Alias of the <see cref="IMediaType"/></param>
|
||||
/// <param name="userId">Optional id of the user creating the media item</param>
|
||||
/// <returns><see cref="IMedia"/></returns>
|
||||
public IMedia CreateMediaWithIdentity(string name, IMedia parent, string mediaTypeAlias, int userId = 0)
|
||||
{
|
||||
var mediaType = FindMediaTypeByAlias(mediaTypeAlias);
|
||||
var media = new Models.Media(name, parent, mediaType);
|
||||
if (Creating.IsRaisedEventCancelled(new NewEventArgs<IMedia>(media, mediaTypeAlias, parent), this))
|
||||
{
|
||||
media.WasCancelled = true;
|
||||
return media;
|
||||
}
|
||||
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMediaRepository(uow))
|
||||
{
|
||||
media.CreatorId = userId;
|
||||
repository.AddOrUpdate(media);
|
||||
uow.Commit();
|
||||
|
||||
var xml = media.ToXml();
|
||||
CreateAndSaveMediaXml(xml, media.Id, uow.Database);
|
||||
}
|
||||
}
|
||||
|
||||
Created.RaiseEvent(new NewEventArgs<IMedia>(media, false, mediaTypeAlias, parent), this);
|
||||
|
||||
Audit.Add(AuditTypes.New, "", media.CreatorId, media.Id);
|
||||
|
||||
return media;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an <see cref="IMedia"/> object by Id
|
||||
/// </summary>
|
||||
@@ -651,18 +713,14 @@ namespace Umbraco.Core.Services
|
||||
uow.Commit();
|
||||
|
||||
var xml = media.ToXml();
|
||||
var poco = new ContentXmlDto {NodeId = media.Id, Xml = xml.ToString(SaveOptions.None)};
|
||||
var exists = uow.Database.FirstOrDefault<ContentXmlDto>("WHERE nodeId = @Id", new {Id = media.Id}) != null;
|
||||
int result = exists
|
||||
? uow.Database.Update(poco)
|
||||
: Convert.ToInt32(uow.Database.Insert(poco));
|
||||
CreateAndSaveMediaXml(xml, media.Id, uow.Database);
|
||||
}
|
||||
|
||||
if (raiseEvents)
|
||||
Saved.RaiseEvent(new SaveEventArgs<IMedia>(media, false), this);
|
||||
|
||||
Audit.Add(AuditTypes.Save, "Save Media performed by user", media.CreatorId, media.Id);
|
||||
}
|
||||
|
||||
if (raiseEvents)
|
||||
Saved.RaiseEvent(new SaveEventArgs<IMedia>(media, false), this);
|
||||
|
||||
Audit.Add(AuditTypes.Save, "Save Media performed by user", userId, media.Id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -679,6 +737,7 @@ namespace Umbraco.Core.Services
|
||||
return;
|
||||
}
|
||||
|
||||
var mediaXml = new Dictionary<int, Lazy<XElement>>();
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMediaRepository(uow))
|
||||
{
|
||||
@@ -690,6 +749,11 @@ namespace Umbraco.Core.Services
|
||||
|
||||
//commit the whole lot in one go
|
||||
uow.Commit();
|
||||
|
||||
foreach (var media in medias)
|
||||
{
|
||||
CreateAndSaveMediaXml(media.ToXml(), media.Id, uow.Database);
|
||||
}
|
||||
}
|
||||
|
||||
if(raiseEvents)
|
||||
@@ -698,6 +762,67 @@ namespace Umbraco.Core.Services
|
||||
Audit.Add(AuditTypes.Save, "Save Media items performed by user", userId, -1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sorts a collection of <see cref="IMedia"/> objects by updating the SortOrder according
|
||||
/// to the ordering of items in the passed in <see cref="IEnumerable{T}"/>.
|
||||
/// </summary>
|
||||
/// <param name="items"></param>
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="raiseEvents"></param>
|
||||
/// <returns>True if sorting succeeded, otherwise False</returns>
|
||||
public bool Sort(IEnumerable<IMedia> items, int userId = 0, bool raiseEvents = true)
|
||||
{
|
||||
if (raiseEvents)
|
||||
{
|
||||
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IMedia>(items), this))
|
||||
return false;
|
||||
}
|
||||
|
||||
var shouldBeCached = new List<IMedia>();
|
||||
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMediaRepository(uow))
|
||||
{
|
||||
int i = 0;
|
||||
foreach (var media in items)
|
||||
{
|
||||
//If the current sort order equals that of the media
|
||||
//we don't need to update it, so just increment the sort order
|
||||
//and continue.
|
||||
if (media.SortOrder == i)
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
media.SortOrder = i;
|
||||
i++;
|
||||
|
||||
repository.AddOrUpdate(media);
|
||||
shouldBeCached.Add(media);
|
||||
}
|
||||
|
||||
uow.Commit();
|
||||
|
||||
foreach (var content in shouldBeCached)
|
||||
{
|
||||
//Create and Save ContentXml DTO
|
||||
var xml = content.ToXml();
|
||||
CreateAndSaveMediaXml(xml, content.Id, uow.Database);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (raiseEvents)
|
||||
Saved.RaiseEvent(new SaveEventArgs<IMedia>(items, false), this);
|
||||
|
||||
Audit.Add(AuditTypes.Sort, "Sorting Media performed by user", userId, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rebuilds all xml content in the cmsContentXml table for all media
|
||||
/// </summary>
|
||||
@@ -790,6 +915,35 @@ namespace Umbraco.Core.Services
|
||||
return list;
|
||||
}
|
||||
|
||||
private void CreateAndSaveMediaXml(XElement xml, int id, UmbracoDatabase db)
|
||||
{
|
||||
var poco = new ContentXmlDto { NodeId = id, Xml = xml.ToString(SaveOptions.None) };
|
||||
var exists = db.FirstOrDefault<ContentXmlDto>("WHERE nodeId = @Id", new { Id = id }) != null;
|
||||
int result = exists ? db.Update(poco) : Convert.ToInt32(db.Insert(poco));
|
||||
}
|
||||
|
||||
private IMediaType FindMediaTypeByAlias(string mediaTypeAlias)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMediaTypeRepository(uow))
|
||||
{
|
||||
var query = Query<IMediaType>.Builder.Where(x => x.Alias == mediaTypeAlias);
|
||||
var mediaTypes = repository.GetByQuery(query);
|
||||
|
||||
if (mediaTypes.Any() == false)
|
||||
throw new Exception(string.Format("No MediaType matching the passed in Alias: '{0}' was found",
|
||||
mediaTypeAlias));
|
||||
|
||||
var mediaType = mediaTypes.First();
|
||||
|
||||
if (mediaType == null)
|
||||
throw new Exception(string.Format("MediaType matching the passed in Alias: '{0}' was null",
|
||||
mediaTypeAlias));
|
||||
|
||||
return mediaType;
|
||||
}
|
||||
}
|
||||
|
||||
#region Event Handlers
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
|
||||
namespace Umbraco.Core.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the MemberService.
|
||||
/// </summary>
|
||||
internal class MemberService : IMemberService
|
||||
{
|
||||
private readonly RepositoryFactory _repositoryFactory;
|
||||
private readonly IDatabaseUnitOfWorkProvider _uowProvider;
|
||||
|
||||
public MemberService(RepositoryFactory repositoryFactory)
|
||||
: this(new PetaPocoUnitOfWorkProvider(), repositoryFactory)
|
||||
{
|
||||
}
|
||||
|
||||
public MemberService(IDatabaseUnitOfWorkProvider provider)
|
||||
: this(provider, new RepositoryFactory())
|
||||
{
|
||||
}
|
||||
|
||||
public MemberService(IDatabaseUnitOfWorkProvider provider, RepositoryFactory repositoryFactory)
|
||||
{
|
||||
_repositoryFactory = repositoryFactory;
|
||||
_uowProvider = provider;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -192,6 +192,71 @@ namespace Umbraco.Core.Services
|
||||
|
||||
#region ContentTypes
|
||||
|
||||
public XElement Export(IContentType contentType)
|
||||
{
|
||||
var info = new XElement("Info",
|
||||
new XElement("Name", contentType.Name),
|
||||
new XElement("Alias", contentType.Alias),
|
||||
new XElement("Icon", contentType.Icon),
|
||||
new XElement("Thumbnail", contentType.Thumbnail),
|
||||
new XElement("Description", contentType.Description),
|
||||
new XElement("AllowAtRoot", contentType.AllowedAsRoot.ToString()));
|
||||
|
||||
var masterContentType = contentType.CompositionAliases().FirstOrDefault();
|
||||
if(masterContentType != null)
|
||||
info.Add(new XElement("Master", masterContentType));
|
||||
|
||||
var allowedTemplates = new XElement("AllowedTemplates");
|
||||
foreach (var template in contentType.AllowedTemplates)
|
||||
{
|
||||
allowedTemplates.Add(new XElement("Template", template.Alias));
|
||||
}
|
||||
info.Add(allowedTemplates);
|
||||
if(contentType.DefaultTemplate != null && contentType.DefaultTemplate.Id != 0)
|
||||
info.Add(new XElement("DefaultTemplate", contentType.DefaultTemplate.Alias));
|
||||
else
|
||||
info.Add(new XElement("DefaultTemplate", ""));
|
||||
|
||||
var structure = new XElement("Structure");
|
||||
foreach (var allowedType in contentType.AllowedContentTypes)
|
||||
{
|
||||
structure.Add(new XElement("DocumentType", allowedType.Alias));
|
||||
}
|
||||
|
||||
var genericProperties = new XElement("GenericProperties");
|
||||
foreach (var propertyType in contentType.PropertyTypes)
|
||||
{
|
||||
var definition = _dataTypeService.GetDataTypeDefinitionById(propertyType.DataTypeDefinitionId);
|
||||
var propertyGroup = contentType.PropertyGroups.FirstOrDefault(x => x.Id == propertyType.PropertyGroupId.Value);
|
||||
var genericProperty = new XElement("GenericProperty",
|
||||
new XElement("Name", propertyType.Name),
|
||||
new XElement("Alias", propertyType.Alias),
|
||||
new XElement("Type", propertyType.DataTypeId.ToString()),
|
||||
new XElement("Definition", definition.Key),
|
||||
new XElement("Tab", propertyGroup == null ? "" : propertyGroup.Name),
|
||||
new XElement("Mandatory", propertyType.Mandatory.ToString()),
|
||||
new XElement("Validation", propertyType.ValidationRegExp),
|
||||
new XElement("Description", new XCData(propertyType.Description)));
|
||||
genericProperties.Add(genericProperty);
|
||||
}
|
||||
|
||||
var tabs = new XElement("Tabs");
|
||||
foreach (var propertyGroup in contentType.PropertyGroups)
|
||||
{
|
||||
var tab = new XElement("Tab",
|
||||
new XElement("Id", propertyGroup.Id.ToString()),
|
||||
new XElement("Caption", propertyGroup.Name));
|
||||
tabs.Add(tab);
|
||||
}
|
||||
|
||||
var xml = new XElement("DocumentType",
|
||||
info,
|
||||
structure,
|
||||
genericProperties,
|
||||
tabs);
|
||||
return xml;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Imports and saves package xml as <see cref="IContentType"/>
|
||||
/// </summary>
|
||||
@@ -324,6 +389,7 @@ namespace Umbraco.Core.Services
|
||||
var template = _fileService.GetTemplate(alias);
|
||||
if (template != null)
|
||||
{
|
||||
if(allowedTemplates.Any(x => x.Id == template.Id)) continue;
|
||||
allowedTemplates.Add(template);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -140,6 +140,21 @@ namespace Umbraco.Core.Services
|
||||
return repository.GetByQuery(query);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of <see cref="Relation"/> objects by their child or parent Id.
|
||||
/// Using this method will get you all relations regards of it being a child or parent relation.
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the child or parent to retrieve relations for</param>
|
||||
/// <returns>An enumerable list of <see cref="Relation"/> objects</returns>
|
||||
public IEnumerable<Relation> GetByParentOrChildId(int id)
|
||||
{
|
||||
using (var repository = _repositoryFactory.CreateRelationRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
var query = new Query<Relation>().Where(x => x.ChildId == id || x.ParentId == id);
|
||||
return repository.GetByQuery(query);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of <see cref="Relation"/> objects by the Name of the <see cref="RelationType"/>
|
||||
|
||||
@@ -14,6 +14,7 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
private Lazy<ContentService> _contentService;
|
||||
private Lazy<UserService> _userService;
|
||||
private Lazy<MemberService> _memberService;
|
||||
private Lazy<MediaService> _mediaService;
|
||||
private Lazy<ContentTypeService> _contentTypeService;
|
||||
private Lazy<DataTypeService> _dataTypeService;
|
||||
@@ -56,6 +57,9 @@ namespace Umbraco.Core.Services
|
||||
if (_userService == null)
|
||||
_userService = new Lazy<UserService>(() => new UserService(provider, repositoryFactory.Value));
|
||||
|
||||
if (_memberService == null)
|
||||
_memberService = new Lazy<MemberService>(() => new MemberService(provider, repositoryFactory.Value));
|
||||
|
||||
if (_contentService == null)
|
||||
_contentService = new Lazy<ContentService>(() => new ContentService(provider, repositoryFactory.Value, publishingStrategy));
|
||||
|
||||
@@ -165,11 +169,19 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="IMacroService"/>
|
||||
/// Gets the <see cref="UserService"/>
|
||||
/// </summary>
|
||||
internal IUserService UserService
|
||||
{
|
||||
get { return _userService.Value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="MemberService"/>
|
||||
/// </summary>
|
||||
internal IMemberService MemberService
|
||||
{
|
||||
get { return _memberService.Value; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,16 @@
|
||||
using System;
|
||||
using System.Web;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Querying;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
|
||||
namespace Umbraco.Core.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the UserService, which is an easy access to operations involving <see cref="IProfile"/> and eventually Users and Members.
|
||||
/// Represents the UserService, which is an easy access to operations involving <see cref="IProfile"/>, <see cref="IMembershipUser"/> and eventually Backoffice Users.
|
||||
/// </summary>
|
||||
internal class UserService : IUserService
|
||||
{
|
||||
@@ -28,69 +31,6 @@ namespace Umbraco.Core.Services
|
||||
|
||||
#region Implementation of IUserService
|
||||
|
||||
/// <summary>
|
||||
/// Gets an <see cref="IProfile"/> for the current BackOffice User.
|
||||
/// </summary>
|
||||
/// <param name="httpContext">HttpContext to fetch the user through</param>
|
||||
/// <returns><see cref="IProfile"/> containing the Name and Id of the logged in BackOffice User</returns>
|
||||
public IProfile GetCurrentBackOfficeUser(HttpContextBase httpContext)
|
||||
{
|
||||
Mandate.That(httpContext != null,
|
||||
() =>
|
||||
new ArgumentException(
|
||||
"The HttpContext which is used to retrieve information about the currently logged in backoffice user was null and can therefor not be used",
|
||||
"HttpContextBase"));
|
||||
if (httpContext == null) return null;
|
||||
|
||||
var cookie = httpContext.Request.Cookies["UMB_UCONTEXT"];
|
||||
Mandate.That(cookie != null, () => new ArgumentException("The Cookie containing the UserContext Guid Id was null", "Cookie"));
|
||||
if (cookie == null) return null;
|
||||
|
||||
string contextId = cookie.Value;
|
||||
string cacheKey = string.Concat("UmbracoUserContext", contextId);
|
||||
|
||||
int userId = 0;
|
||||
|
||||
if(HttpRuntime.Cache[cacheKey] == null)
|
||||
{
|
||||
using (var uow = _uowProvider.GetUnitOfWork())
|
||||
{
|
||||
userId =
|
||||
uow.Database.ExecuteScalar<int>(
|
||||
"select userID from umbracoUserLogins where contextID = @ContextId",
|
||||
new { ContextId = new Guid(contextId) });
|
||||
|
||||
HttpRuntime.Cache.Insert(cacheKey, userId,
|
||||
null,
|
||||
System.Web.Caching.Cache.NoAbsoluteExpiration,
|
||||
new TimeSpan(0, (int)(Umbraco.Core.Configuration.GlobalSettings.TimeOutInMinutes / 10), 0));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
userId = (int) HttpRuntime.Cache[cacheKey];
|
||||
}
|
||||
|
||||
var profile = GetProfileById(userId);
|
||||
return profile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an <see cref="IProfile"/> for the current BackOffice User.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Requests the current HttpContext, so this method will only work in a web context.
|
||||
/// </remarks>
|
||||
/// <returns><see cref="IProfile"/> containing the Name and Id of the logged in BackOffice User</returns>
|
||||
public IProfile GetCurrentBackOfficeUser()
|
||||
{
|
||||
var context = HttpContext.Current;
|
||||
Mandate.That<Exception>(context != null);
|
||||
|
||||
var wrapper = new HttpContextWrapper(context);
|
||||
return GetCurrentBackOfficeUser(wrapper);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an IProfile by User Id.
|
||||
/// </summary>
|
||||
@@ -104,6 +44,76 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an IUserType by its Alias
|
||||
/// </summary>
|
||||
/// <param name="alias">Alias of the UserType to retrieve</param>
|
||||
/// <returns><see cref="IUserType"/></returns>
|
||||
public IUserType GetUserTypeByAlias(string alias)
|
||||
{
|
||||
using (var repository = _repositoryFactory.CreateUserTypeRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
var query = Query<IUserType>.Builder.Where(x => x.Alias == alias);
|
||||
var contents = repository.GetByQuery(query);
|
||||
return contents.SingleOrDefault();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an IUserType by its Name
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the UserType to retrieve</param>
|
||||
/// <returns><see cref="IUserType"/></returns>
|
||||
public IUserType GetUserTypeByName(string name)
|
||||
{
|
||||
using (var repository = _repositoryFactory.CreateUserTypeRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
var query = Query<IUserType>.Builder.Where(x => x.Name == name);
|
||||
var contents = repository.GetByQuery(query);
|
||||
return contents.SingleOrDefault();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new user for logging into the umbraco backoffice
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="login"></param>
|
||||
/// <param name="password"></param>
|
||||
/// <param name="userType"></param>
|
||||
/// <param name="email"></param>
|
||||
/// <returns></returns>
|
||||
public IMembershipUser CreateUser(string name, string login, string password, IUserType userType, string email = "")
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateUserRepository(uow))
|
||||
{
|
||||
var loginExists = uow.Database.ExecuteScalar<int>("SELECT COUNT(id) FROM umbracoUser WHERE userLogin = @Login", new { Login = login }) != 0;
|
||||
if (loginExists)
|
||||
throw new ArgumentException("Login already exists");
|
||||
|
||||
var user = new User(userType)
|
||||
{
|
||||
DefaultToLiveEditing = false,
|
||||
Email = email,
|
||||
Language = Umbraco.Core.Configuration.GlobalSettings.DefaultUILanguage,
|
||||
Name = name,
|
||||
Password = password,
|
||||
Permissions = userType.Permissions,
|
||||
Username = login,
|
||||
StartContentId = -1,
|
||||
StartMediaId = -1,
|
||||
NoConsole = false,
|
||||
IsApproved = true
|
||||
};
|
||||
|
||||
repository.AddOrUpdate(user);
|
||||
uow.Commit();
|
||||
|
||||
return user;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
using System;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
using Umbraco.Core.Publishing;
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
namespace Umbraco.Core.Standalone
|
||||
{
|
||||
internal class ServiceContextManager : IDisposable
|
||||
{
|
||||
private readonly string _connectionString;
|
||||
private readonly string _providerName;
|
||||
private ServiceContext _serviceContext;
|
||||
private readonly StandaloneCoreApplication _application;
|
||||
|
||||
public ServiceContextManager(string connectionString, string providerName)
|
||||
{
|
||||
_connectionString = connectionString;
|
||||
_providerName = providerName;
|
||||
|
||||
_application = StandaloneCoreApplication.GetApplication();
|
||||
_application.Start();
|
||||
}
|
||||
|
||||
public ServiceContext Services
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_serviceContext == null)
|
||||
{
|
||||
var dbFactory = new DefaultDatabaseFactory(_connectionString, _providerName);
|
||||
var dbContext = new DatabaseContext(dbFactory);
|
||||
Database.Mapper = new PetaPocoMapper();
|
||||
_serviceContext = new ServiceContext(
|
||||
new PetaPocoUnitOfWorkProvider(dbFactory),
|
||||
new FileUnitOfWorkProvider(),
|
||||
new PublishingStrategy());
|
||||
|
||||
//initialize the DatabaseContext
|
||||
dbContext.Initialize(_providerName);
|
||||
}
|
||||
|
||||
return _serviceContext;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
((IDisposable)ApplicationContext.Current).Dispose();
|
||||
_application.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Umbraco.Core.Standalone
|
||||
{
|
||||
internal class StandaloneCoreApplication : UmbracoApplicationBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="StandaloneCoreApplication"/> class.
|
||||
/// </summary>
|
||||
protected StandaloneCoreApplication() { }
|
||||
|
||||
/// <summary>
|
||||
/// Provides the application boot manager.
|
||||
/// </summary>
|
||||
/// <returns>An application boot manager.</returns>
|
||||
protected override IBootManager GetBootManager()
|
||||
{
|
||||
return new StandaloneCoreBootManager(this, _handlersToAdd, _handlersToRemove);
|
||||
}
|
||||
|
||||
#region Application
|
||||
|
||||
private static StandaloneCoreApplication _application;
|
||||
private static bool _started;
|
||||
private static readonly object AppLock = new object();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instance of the standalone Umbraco application.
|
||||
/// </summary>
|
||||
public static StandaloneCoreApplication GetApplication()
|
||||
{
|
||||
lock (AppLock)
|
||||
{
|
||||
return _application ?? (_application = new StandaloneCoreApplication());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts the application.
|
||||
/// </summary>
|
||||
public void Start()
|
||||
{
|
||||
lock (AppLock)
|
||||
{
|
||||
if (_started)
|
||||
throw new InvalidOperationException("Application has already started.");
|
||||
Application_Start(this, EventArgs.Empty);
|
||||
_started = true;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IApplicationEventHandler management
|
||||
|
||||
private readonly List<Type> _handlersToAdd = new List<Type>();
|
||||
private readonly List<Type> _handlersToRemove = new List<Type>();
|
||||
|
||||
/// <summary>
|
||||
/// Associates an <see cref="IApplicationEventHandler"/> type with the application.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type to associate.</typeparam>
|
||||
/// <returns>The application.</returns>
|
||||
/// <remarks>Types implementing <see cref="IApplicationEventHandler"/> from within
|
||||
/// an executable are not automatically discovered by Umbraco and have to be
|
||||
/// explicitely associated with the application using this method.</remarks>
|
||||
public StandaloneCoreApplication WithApplicationEventHandler<T>()
|
||||
where T : IApplicationEventHandler
|
||||
{
|
||||
_handlersToAdd.Add(typeof(T));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dissociates an <see cref="IApplicationEventHandler"/> type from the application.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type to dissociate.</typeparam>
|
||||
/// <returns>The application.</returns>
|
||||
public StandaloneCoreApplication WithoutApplicationEventHandler<T>()
|
||||
where T : IApplicationEventHandler
|
||||
{
|
||||
_handlersToRemove.Add(typeof(T));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Associates an <see cref="IApplicationEventHandler"/> type with the application.
|
||||
/// </summary>
|
||||
/// <param name="type">The type to associate.</param>
|
||||
/// <returns>The application.</returns>
|
||||
/// <remarks>Types implementing <see cref="IApplicationEventHandler"/> from within
|
||||
/// an executable are not automatically discovered by Umbraco and have to be
|
||||
/// explicitely associated with the application using this method.</remarks>
|
||||
public StandaloneCoreApplication WithApplicationEventHandler(Type type)
|
||||
{
|
||||
if (type.Implements<IApplicationEventHandler>() == false)
|
||||
throw new ArgumentException("Type does not implement IApplicationEventHandler.", "type");
|
||||
_handlersToAdd.Add(type);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dissociates an <see cref="IApplicationEventHandler"/> type from the application.
|
||||
/// </summary>
|
||||
/// <param name="type">The type to dissociate.</param>
|
||||
/// <returns>The application.</returns>
|
||||
public StandaloneCoreApplication WithoutApplicationEventHandler(Type type)
|
||||
{
|
||||
if (type.Implements<IApplicationEventHandler>() == false)
|
||||
throw new ArgumentException("Type does not implement IApplicationEventHandler.", "type");
|
||||
_handlersToRemove.Add(type);
|
||||
return this;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.ObjectResolution;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
using umbraco.interfaces;
|
||||
|
||||
namespace Umbraco.Core.Standalone
|
||||
{
|
||||
internal class StandaloneCoreBootManager : CoreBootManager
|
||||
{
|
||||
private readonly IEnumerable<Type> _handlersToAdd;
|
||||
private readonly IEnumerable<Type> _handlersToRemove;
|
||||
|
||||
public StandaloneCoreBootManager(UmbracoApplicationBase umbracoApplication, IEnumerable<Type> handlersToAdd, IEnumerable<Type> handlersToRemove)
|
||||
: base(umbracoApplication)
|
||||
{
|
||||
_handlersToAdd = handlersToAdd;
|
||||
_handlersToRemove = handlersToRemove;
|
||||
|
||||
// this is only here to ensure references to the assemblies needed for
|
||||
// the DataTypesResolver otherwise they won't be loaded into the AppDomain.
|
||||
var interfacesAssemblyName = typeof(IDataType).Assembly.FullName;
|
||||
}
|
||||
|
||||
protected override void InitializeApplicationEventsResolver()
|
||||
{
|
||||
base.InitializeApplicationEventsResolver();
|
||||
foreach (var type in _handlersToAdd)
|
||||
ApplicationEventsResolver.Current.AddType(type);
|
||||
foreach (var type in _handlersToRemove)
|
||||
ApplicationEventsResolver.Current.RemoveType(type);
|
||||
}
|
||||
|
||||
protected override void InitializeResolvers()
|
||||
{
|
||||
base.InitializeResolvers();
|
||||
|
||||
//Mappers are not resolved, which could be because of a known TypeMapper issue
|
||||
MappingResolver.Reset();
|
||||
MappingResolver.Current = new MappingResolver(
|
||||
() =>
|
||||
new List<Type>
|
||||
{
|
||||
typeof (ContentMapper),
|
||||
typeof (ContentTypeMapper),
|
||||
typeof (MediaMapper),
|
||||
typeof (MediaTypeMapper),
|
||||
typeof (DataTypeDefinitionMapper),
|
||||
typeof (UmbracoEntityMapper)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -64,6 +64,7 @@
|
||||
<Reference Include="System.Runtime.Serialization" />
|
||||
<Reference Include="System.Transactions" />
|
||||
<Reference Include="System.Web" />
|
||||
<Reference Include="System.Web.ApplicationServices" />
|
||||
<Reference Include="System.Web.Extensions" />
|
||||
<Reference Include="System.Web.Helpers, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<Private>True</Private>
|
||||
@@ -112,13 +113,15 @@
|
||||
<Compile Include="Auditing\IAuditWriteProvider.cs" />
|
||||
<Compile Include="CacheHelper.cs" />
|
||||
<Compile Include="Cache\CacheKeys.cs" />
|
||||
<Compile Include="Cache\CacheProviderBase.cs" />
|
||||
<Compile Include="Cache\CacheRefresherBase.cs" />
|
||||
<Compile Include="Cache\CacheRefresherEventArgs.cs" />
|
||||
<Compile Include="Cache\CacheProviderBase.cs" />
|
||||
<Compile Include="Cache\RuntimeCacheProviderBase.cs" />
|
||||
<Compile Include="Cache\HttpRuntimeCacheProvider.cs" />
|
||||
<Compile Include="Cache\IJsonCacheRefresher.cs" />
|
||||
<Compile Include="Cache\JsonCacheRefresherBase.cs" />
|
||||
<Compile Include="Cache\NullCacheProvider.cs" />
|
||||
<Compile Include="Cache\StaticCacheProvider.cs" />
|
||||
<Compile Include="Cache\TypedCacheRefresherBase.cs" />
|
||||
<Compile Include="CodeAnnotations\FriendlyNameAttribute.cs" />
|
||||
<Compile Include="CodeAnnotations\UmbracoObjectTypeAttribute.cs" />
|
||||
@@ -193,6 +196,7 @@
|
||||
<Compile Include="Models\IDictionaryTranslation.cs" />
|
||||
<Compile Include="Models\IFile.cs" />
|
||||
<Compile Include="Models\ILanguage.cs" />
|
||||
<Compile Include="Models\Membership\UmbracoMembershipUser.cs" />
|
||||
<Compile Include="Models\ServerRegistration.cs" />
|
||||
<Compile Include="Models\ITemplate.cs" />
|
||||
<Compile Include="Models\Language.cs" />
|
||||
@@ -521,17 +525,11 @@
|
||||
<Compile Include="Persistence\UnitOfWork\IUnitOfWorkRepository.cs" />
|
||||
<Compile Include="Persistence\UnitOfWork\PetaPocoUnitOfWork.cs" />
|
||||
<Compile Include="Persistence\UnitOfWork\PetaPocoUnitOfWorkProvider.cs" />
|
||||
<Compile Include="Profiling\Profiler.cs" />
|
||||
<Compile Include="PropertyEditors\Attributes\PropertyEditorAttribute.cs" />
|
||||
<Compile Include="PropertyEditors\Attributes\ShowLabelAttribute.cs" />
|
||||
<Compile Include="PropertyEditors\BlankPreValueModel.cs" />
|
||||
<Compile Include="PropertyEditors\EditorModel.cs" />
|
||||
<Compile Include="PropertyEditors\EditorModel`T.cs" />
|
||||
<Compile Include="PropertyEditors\IValueModel.cs" />
|
||||
<Compile Include="PropertyEditors\PreValueDefinition.cs" />
|
||||
<Compile Include="PropertyEditors\PreValueModel.cs" />
|
||||
<Compile Include="PropertyEditors\PropertyEditor.cs" />
|
||||
<Compile Include="PropertyEditors\PropertyEditor`T.cs" />
|
||||
<Compile Include="Profiling\IProfiler.cs" />
|
||||
<Compile Include="Profiling\LogProfiler.cs" />
|
||||
<Compile Include="Profiling\ProfilerExtensions.cs" />
|
||||
<Compile Include="Profiling\ProfilerResolver.cs" />
|
||||
<Compile Include="Profiling\WebProfiler.cs" />
|
||||
<Compile Include="PublishedContentExtensions.cs" />
|
||||
<Compile Include="Dictionary\ICultureDictionary.cs" />
|
||||
<Compile Include="Dynamics\ClassFactory.cs" />
|
||||
@@ -681,15 +679,20 @@
|
||||
<Compile Include="Services\IFileService.cs" />
|
||||
<Compile Include="Services\ILocalizationService.cs" />
|
||||
<Compile Include="Services\IMediaService.cs" />
|
||||
<Compile Include="Services\IMemberService.cs" />
|
||||
<Compile Include="Services\IService.cs" />
|
||||
<Compile Include="Services\IUserService.cs" />
|
||||
<Compile Include="Services\LocalizationService.cs" />
|
||||
<Compile Include="Services\MediaService.cs" />
|
||||
<Compile Include="Services\MemberService.cs" />
|
||||
<Compile Include="Services\RelationService.cs" />
|
||||
<Compile Include="Services\ServerRegistrationService.cs" />
|
||||
<Compile Include="Services\PackagingService.cs" />
|
||||
<Compile Include="Services\ServiceContext.cs" />
|
||||
<Compile Include="Services\UserService.cs" />
|
||||
<Compile Include="Standalone\ServiceContextManager.cs" />
|
||||
<Compile Include="Standalone\StandaloneCoreApplication.cs" />
|
||||
<Compile Include="Standalone\StandaloneCoreBootManager.cs" />
|
||||
<Compile Include="Strings\ContentBaseExtensions.cs" />
|
||||
<Compile Include="TopologicalSorter.cs" />
|
||||
<Compile Include="Strings\DefaultUrlSegmentProvider.cs" />
|
||||
@@ -748,7 +751,7 @@
|
||||
<Compile Include="IfExtensions.cs" />
|
||||
<Compile Include="PluginManager.cs" />
|
||||
<Compile Include="IO\FileSecurityException.cs" />
|
||||
<Compile Include="IO\FileSystemProvider.cs" />
|
||||
<Compile Include="IO\FileSystemProviderConstants.cs" />
|
||||
<Compile Include="IO\FileSystemProviderManager.cs" />
|
||||
<Compile Include="IO\IFileSystem.cs" />
|
||||
<Compile Include="IO\IOHelper.cs" />
|
||||
@@ -785,6 +788,10 @@
|
||||
<ItemGroup>
|
||||
<Content Include="Strings\Notes.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Packaging\" />
|
||||
<Folder Include="PropertyEditors\Attributes\" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(SolutionDir)\.nuget\nuget.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
using System.Web.Hosting;
|
||||
using System.Web.Mvc;
|
||||
@@ -25,6 +22,11 @@ namespace Umbraco.Core
|
||||
public static event EventHandler ApplicationStarting;
|
||||
public static event EventHandler ApplicationStarted;
|
||||
|
||||
/// <summary>
|
||||
/// Called when the HttpApplication.Init() is fired, allows developers to subscribe to the HttpApplication events
|
||||
/// </summary>
|
||||
public static event EventHandler ApplicationInit;
|
||||
|
||||
/// <summary>
|
||||
/// Boots up the Umbraco application
|
||||
/// </summary>
|
||||
@@ -50,22 +52,13 @@ namespace Umbraco.Core
|
||||
StartApplication(sender, e);
|
||||
}
|
||||
|
||||
protected void Application_BeginRequest()
|
||||
/// <summary>
|
||||
/// Override init and raise the event
|
||||
/// </summary>
|
||||
public override void Init()
|
||||
{
|
||||
if (GlobalSettings.DebugMode)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(Request["umbDebug"]))
|
||||
Umbraco.Core.Profiling.Profiler.Instance.Start();
|
||||
}
|
||||
}
|
||||
|
||||
protected void Application_EndRequest()
|
||||
{
|
||||
if (GlobalSettings.DebugMode)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(Request["umbDebug"]))
|
||||
Umbraco.Core.Profiling.Profiler.Instance.Stop();
|
||||
}
|
||||
base.Init();
|
||||
OnApplicationInit(this, new EventArgs());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -90,6 +83,17 @@ namespace Umbraco.Core
|
||||
ApplicationStarted(sender, e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called to raise the ApplicationInit event
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void OnApplicationInit(object sender, EventArgs e)
|
||||
{
|
||||
if (ApplicationInit != null)
|
||||
ApplicationInit(sender, e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A method that can be overridden to invoke code when the application has an error.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Umbraco.Core
|
||||
@@ -8,6 +10,19 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
public static class UriExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// This is a performance tweak to check if this is a .css, .js or .ico, .jpg, .jpeg, .png, .gif file request since
|
||||
/// .Net will pass these requests through to the module when in integrated mode.
|
||||
/// We want to ignore all of these requests immediately.
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <returns></returns>
|
||||
internal static bool IsClientSideRequest(this Uri url)
|
||||
{
|
||||
var toIgnore = new[] { ".js", ".css", ".ico", ".png", ".jpg", ".jpeg", ".gif" };
|
||||
return toIgnore.Any(x => Path.GetExtension(url.LocalPath).InvariantEquals(x));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rewrites the path of uri.
|
||||
/// </summary>
|
||||
|
||||
@@ -7,29 +7,38 @@ using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.ObjectResolution;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
using umbraco.interfaces;
|
||||
|
||||
namespace Umbraco.Tests.BootManagers
|
||||
{
|
||||
[TestFixture]
|
||||
public class CoreBootManagerTests
|
||||
public class CoreBootManagerTests : BaseUmbracoApplicationTest
|
||||
{
|
||||
|
||||
private TestApp _testApp;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
_testApp = new TestApp();
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
public override void TearDown()
|
||||
{
|
||||
base.TearDown();
|
||||
|
||||
_testApp = null;
|
||||
|
||||
ApplicationEventsResolver.Reset();
|
||||
SqlSyntaxProvidersResolver.Reset();
|
||||
//ApplicationEventsResolver.Reset();
|
||||
//SqlSyntaxProvidersResolver.Reset();
|
||||
}
|
||||
|
||||
protected override void FreezeResolution()
|
||||
{
|
||||
//don't freeze resolution, we'll do that in the boot manager
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace Umbraco.Tests.IO
|
||||
[Test]
|
||||
public void Can_Get_Base_File_System()
|
||||
{
|
||||
var fs = FileSystemProviderManager.Current.GetFileSystemProvider(FileSystemProvider.Media);
|
||||
var fs = FileSystemProviderManager.Current.GetUnderlyingFileSystemProvider(FileSystemProviderConstants.Media);
|
||||
|
||||
Assert.NotNull(fs);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Web.Caching;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Profiling;
|
||||
using umbraco;
|
||||
using umbraco.cms.businesslogic.macro;
|
||||
|
||||
@@ -20,11 +18,17 @@ namespace Umbraco.Tests.Macros
|
||||
{
|
||||
//we DO want cache enabled for these tests
|
||||
ApplicationContext.Current = new ApplicationContext(true);
|
||||
ProfilerResolver.Current = new ProfilerResolver(new LogProfiler())
|
||||
{
|
||||
CanResolveBeforeFrozen = true
|
||||
};
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
ProfilerResolver.Current.DisposeIfDisposable();
|
||||
ProfilerResolver.Reset();
|
||||
ApplicationContext.Current.ApplicationCache.ClearAllCache();
|
||||
ApplicationContext.Current.DisposeIfDisposable();
|
||||
ApplicationContext.Current = null;
|
||||
|
||||
@@ -330,7 +330,7 @@ namespace Umbraco.Tests
|
||||
public void Resolves_RestExtensions()
|
||||
{
|
||||
var types = PluginManager.Current.ResolveRestExtensions();
|
||||
Assert.AreEqual(2, types.Count());
|
||||
Assert.AreEqual(3, types.Count());
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
//need to specify a custom callback for unit tests
|
||||
PublishedContentHelper.GetDataTypeCallback = (docTypeAlias, propertyAlias) =>
|
||||
{
|
||||
if (propertyAlias == "content")
|
||||
if (propertyAlias.InvariantEquals("content"))
|
||||
{
|
||||
//return the rte type id
|
||||
return Guid.Parse(Constants.PropertyEditors.TinyMCEv3);
|
||||
|
||||
@@ -240,6 +240,10 @@ namespace Umbraco.Tests.PublishedContent
|
||||
var propVal2 = doc.GetPropertyValue<IHtmlString>("content");
|
||||
Assert.IsTrue(TypeHelper.IsTypeAssignableFrom<IHtmlString>(propVal2.GetType()));
|
||||
Assert.AreEqual("<div>This is some content</div>", propVal2.ToString());
|
||||
|
||||
var propVal3 = doc.GetPropertyValue("Content");
|
||||
Assert.IsTrue(TypeHelper.IsTypeAssignableFrom<IHtmlString>(propVal3.GetType()));
|
||||
Assert.AreEqual("<div>This is some content</div>", propVal3.ToString());
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -88,7 +88,7 @@ namespace Umbraco.Tests.Routing
|
||||
public void Is_Client_Side_Request(string url, bool assert)
|
||||
{
|
||||
var uri = new Uri("http://test.com" + url);
|
||||
var result = _module.IsClientSideRequest(uri);
|
||||
var result = uri.IsClientSideRequest();
|
||||
Assert.AreEqual(assert, result);
|
||||
}
|
||||
|
||||
|
||||
@@ -184,6 +184,32 @@ namespace Umbraco.Tests.Services
|
||||
Assert.That(homeDoc.ContentTypeId, Is.EqualTo(ctHomePage.Id));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Create_And_Save_ContentType_Composition()
|
||||
{
|
||||
/*
|
||||
* Global
|
||||
* - Components
|
||||
* - Category
|
||||
*/
|
||||
var service = ServiceContext.ContentTypeService;
|
||||
var global = MockedContentTypes.CreateSimpleContentType("global", "Global");
|
||||
service.Save(global);
|
||||
|
||||
var components = MockedContentTypes.CreateSimpleContentType("components", "Components", global);
|
||||
service.Save(components);
|
||||
|
||||
var component = MockedContentTypes.CreateSimpleContentType("component", "Component", components);
|
||||
service.Save(component);
|
||||
|
||||
var category = MockedContentTypes.CreateSimpleContentType("category", "Category", global);
|
||||
service.Save(category);
|
||||
|
||||
var success = category.AddContentType(component);
|
||||
|
||||
Assert.That(success, Is.False);
|
||||
}
|
||||
|
||||
private IEnumerable<IContentType> CreateContentTypeHierarchy()
|
||||
{
|
||||
//create the master type
|
||||
|
||||
@@ -162,6 +162,30 @@ namespace Umbraco.Tests.Services.Importing
|
||||
Assert.That(contentMaster.PropertyGroups["SEO"].PropertyTypes.Any(x => x.PropertyGroupId.Value != propertyGroupId), Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PackagingService_Can_Import_StandardMvc_ContentTypes_And_Templates_Xml()
|
||||
{
|
||||
// Arrange
|
||||
string strXml = ImportResources.StandardMvc_Package;
|
||||
var xml = XElement.Parse(strXml);
|
||||
var dataTypeElement = xml.Descendants("DataTypes").First();
|
||||
var templateElement = xml.Descendants("Templates").First();
|
||||
var docTypeElement = xml.Descendants("DocumentTypes").First();
|
||||
|
||||
// Act
|
||||
var dataTypeDefinitions = ServiceContext.PackagingService.ImportDataTypeDefinitions(dataTypeElement);
|
||||
var templates = ServiceContext.PackagingService.ImportTemplates(templateElement);
|
||||
var contentTypes = ServiceContext.PackagingService.ImportContentTypes(docTypeElement);
|
||||
var numberOfDocTypes = (from doc in docTypeElement.Elements("DocumentType") select doc).Count();
|
||||
|
||||
//Assert - Re-Import contenttypes doesn't throw
|
||||
Assert.DoesNotThrow(() => ServiceContext.PackagingService.ImportContentTypes(docTypeElement));
|
||||
Assert.That(contentTypes.Count(), Is.EqualTo(numberOfDocTypes));
|
||||
Assert.That(dataTypeDefinitions, Is.Not.Null);
|
||||
Assert.That(dataTypeDefinitions.Any(), Is.True);
|
||||
Assert.That(templates.Any(), Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PackagingService_Can_Import_Content_Package_Xml()
|
||||
{
|
||||
@@ -224,6 +248,29 @@ namespace Umbraco.Tests.Services.Importing
|
||||
Assert.That(contentTypes.Count(), Is.EqualTo(1));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PackagingService_Can_Export_Single_DocType()
|
||||
{
|
||||
// Arrange
|
||||
string strXml = ImportResources.SingleDocType;
|
||||
var docTypeElement = XElement.Parse(strXml);
|
||||
var packagingService = ServiceContext.PackagingService;
|
||||
|
||||
// Act
|
||||
var contentTypes = packagingService.ImportContentTypes(docTypeElement);
|
||||
var contentType = contentTypes.FirstOrDefault();
|
||||
var element = packagingService.Export(contentType);
|
||||
|
||||
// Assert
|
||||
Assert.That(element, Is.Not.Null);
|
||||
Assert.That(element.Element("Info"), Is.Not.Null);
|
||||
Assert.That(element.Element("Structure"), Is.Not.Null);
|
||||
Assert.That(element.Element("GenericProperties"), Is.Not.Null);
|
||||
Assert.That(element.Element("Tabs"), Is.Not.Null);
|
||||
//Can't compare this XElement because the templates are not imported (they don't exist)
|
||||
//Assert.That(XNode.DeepEquals(docTypeElement, element), Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PackagingService_Can_ReImport_Single_DocType()
|
||||
{
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
using System;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
|
||||
namespace Umbraco.Tests.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// Tests covering the UserService
|
||||
/// </summary>
|
||||
[TestFixture, RequiresSTA]
|
||||
public class UserServiceTests : BaseServiceTest
|
||||
{
|
||||
[SetUp]
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public override void TearDown()
|
||||
{
|
||||
base.TearDown();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UserService_Can_Persist_New_User()
|
||||
{
|
||||
// Arrange
|
||||
var userService = ServiceContext.UserService;
|
||||
var userType = userService.GetUserTypeByAlias("admin");
|
||||
|
||||
// Act
|
||||
var membershipUser = userService.CreateUser("John Doe", "john@umbraco.io", "12345", userType, "john@umbraco.io");
|
||||
|
||||
// Assert
|
||||
Assert.That(membershipUser.HasIdentity, Is.True);
|
||||
IUser user = membershipUser as User;
|
||||
Assert.That(user, Is.Not.Null);
|
||||
Assert.That(user.Permissions, Is.EqualTo(userType.Permissions));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UserService_Can_Persist_New_User_With_Hashed_Password()
|
||||
{
|
||||
// Arrange
|
||||
var userService = ServiceContext.UserService;
|
||||
var userType = userService.GetUserTypeByAlias("admin");
|
||||
|
||||
// Act
|
||||
// NOTE: Normally the hash'ing would be handled in the membership provider, so the service just saves the password
|
||||
var password = "123456";
|
||||
var hash = new HMACSHA1();
|
||||
hash.Key = Encoding.Unicode.GetBytes(password);
|
||||
var encodedPassword = Convert.ToBase64String(hash.ComputeHash(Encoding.Unicode.GetBytes(password)));
|
||||
var membershipUser = userService.CreateUser("John Doe", "john@umbraco.io", encodedPassword, userType, "john@umbraco.io");
|
||||
|
||||
// Assert
|
||||
Assert.That(membershipUser.HasIdentity, Is.True);
|
||||
Assert.That(membershipUser.Password, Is.Not.EqualTo(password));
|
||||
Assert.That(membershipUser.Password, Is.EqualTo(encodedPassword));
|
||||
IUser user = membershipUser as User;
|
||||
Assert.That(user, Is.Not.Null);
|
||||
Assert.That(user.Permissions, Is.EqualTo(userType.Permissions));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@ using NUnit.Framework;
|
||||
using SqlCE4Umbraco;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Tests;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
using Umbraco.Web.BaseRest;
|
||||
@@ -69,8 +70,7 @@ namespace Umbraco.Tests
|
||||
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
[Test]
|
||||
public void Find_Class_Of_Type_With_Attribute()
|
||||
{
|
||||
|
||||
|
||||
@@ -185,6 +185,7 @@
|
||||
<Compile Include="Configurations\FileSystemProviderTests.cs" />
|
||||
<Compile Include="CoreXml\FrameworkXmlTests.cs" />
|
||||
<Compile Include="Integration\CreateContent.cs" />
|
||||
<Compile Include="Services\UserServiceTests.cs" />
|
||||
<Compile Include="TestHelpers\BaseSeleniumTest.cs" />
|
||||
<Compile Include="Integration\InstallPackage.cs" />
|
||||
<Compile Include="PublishedCache\PublishedMediaCacheTests.cs" />
|
||||
|
||||
@@ -100,13 +100,13 @@
|
||||
<Project>{07fbc26b-2927-4a22-8d96-d644c667fecc}</Project>
|
||||
<Name>UmbracoExamine</Name>
|
||||
</ProjectReference>
|
||||
<Reference Include="ClientDependency.Core, Version=1.6.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<Reference Include="ClientDependency.Core, Version=1.7.0.1, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\ClientDependency.1.6.0.0\lib\ClientDependency.Core.dll</HintPath>
|
||||
<HintPath>..\packages\ClientDependency.1.7.0.1\lib\ClientDependency.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ClientDependency.Core.Mvc, Version=1.6.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<Reference Include="ClientDependency.Core.Mvc, Version=1.7.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\ClientDependency-Mvc.1.6.0.0\lib\ClientDependency.Core.Mvc.dll</HintPath>
|
||||
<HintPath>..\packages\ClientDependency-Mvc.1.7.0.0\lib\ClientDependency.Core.Mvc.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Examine, Version=0.1.51.2941, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
@@ -127,6 +127,10 @@
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\Microsoft.AspNet.Mvc.FixedDisplayModes.1.0.1\lib\net40\Microsoft.Web.Mvc.FixedDisplayModes.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="MiniProfiler, Version=2.1.0.0, Culture=neutral, PublicKeyToken=b44f9351044011a3, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\MiniProfiler.2.1.0\lib\net40\MiniProfiler.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="MySql.Data, Version=6.6.4.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\MySql.Data.6.6.4\lib\net40\MySql.Data.dll</HintPath>
|
||||
@@ -541,6 +545,10 @@
|
||||
</Compile>
|
||||
<Content Include="Config\Splashes\booting.aspx" />
|
||||
<Content Include="Config\Splashes\noNodes.aspx" />
|
||||
<Content Include="Umbraco\Xslt\Web.config">
|
||||
<SubType>
|
||||
</SubType>
|
||||
</Content>
|
||||
<None Include="Config\404handlers.Release.config">
|
||||
<DependentUpon>404handlers.config</DependentUpon>
|
||||
</None>
|
||||
@@ -2509,6 +2517,7 @@
|
||||
<Content Include="Config\log4net.config" />
|
||||
<Content Include="Config\FileSystemProviders.config" />
|
||||
<Content Include="Config\EmbeddedMedia.config" />
|
||||
<Content Include="Xslt\Web.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="App_Code\" />
|
||||
@@ -2522,7 +2531,6 @@
|
||||
<Folder Include="Umbraco_Client\FolderBrowser\Images\" />
|
||||
<Folder Include="Umbraco_Client\Tags\images\" />
|
||||
<Folder Include="UserControls\" />
|
||||
<Folder Include="Xslt\" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
||||
|
||||
@@ -10,7 +10,7 @@ NOTES:
|
||||
* Compression/Combination/Minification is not enabled unless debug="false" is specified on the 'compiliation' element in the web.config
|
||||
* A new version will invalidate both client and server cache and create new persisted files
|
||||
-->
|
||||
<clientDependency version="9" fileDependencyExtensions=".js,.css">
|
||||
<clientDependency version="11" fileDependencyExtensions=".js,.css" loggerType="Umbraco.Web.UI.CdfLogger, umbraco">
|
||||
|
||||
<fileRegistration defaultProvider="LoaderControlProvider">
|
||||
<providers>
|
||||
@@ -30,8 +30,8 @@ NOTES:
|
||||
<add name="LazyLoadRenderer" type="ClientDependency.Core.FileRegistration.Providers.LazyLoadRenderer, ClientDependency.Core" />
|
||||
</renderers>
|
||||
</mvc>
|
||||
|
||||
<!--
|
||||
|
||||
<!--
|
||||
The composite file section configures the compression/combination/minification of files.
|
||||
You can enable/disable minification of either JS/CSS files and you can enable/disable the
|
||||
persistence of composite files. By default, minification and persistence is enabled. Persisting files
|
||||
|
||||
@@ -7,12 +7,11 @@ Index/Search providers can be defined in the UmbracoSettings.config
|
||||
More information and documentation can be found on CodePlex: http://umbracoexamine.codeplex.com
|
||||
-->
|
||||
<ExamineLuceneIndexSets>
|
||||
|
||||
<!-- The internal index set used by Umbraco back-office - DO NOT REMOVE -->
|
||||
<IndexSet SetName="InternalIndexSet" IndexPath="~/App_Data/TEMP/ExamineIndexes/Internal/" />
|
||||
<IndexSet SetName="InternalIndexSet" IndexPath="~/App_Data/TEMP/ExamineIndexes/Internal/"/>
|
||||
|
||||
<!-- The internal index set used by Umbraco back-office for indexing members - DO NOT REMOVE -->
|
||||
<IndexSet SetName="InternalMemberIndexSet" IndexPath="~/App_Data/TEMP/ExamineIndexes/InternalMember/" >
|
||||
<IndexSet SetName="InternalMemberIndexSet" IndexPath="~/App_Data/TEMP/ExamineIndexes/InternalMember/">
|
||||
<IndexAttributeFields>
|
||||
<add Name="id" />
|
||||
<add Name="nodeName"/>
|
||||
|
||||
@@ -30,11 +30,11 @@ More information and documentation can be found on CodePlex: http://umbracoexami
|
||||
<add name="InternalSearcher" type="UmbracoExamine.UmbracoExamineSearcher, UmbracoExamine"
|
||||
analyzer="Lucene.Net.Analysis.WhitespaceAnalyzer, Lucene.Net"/>
|
||||
|
||||
<add name="ExternalSearcher" type="UmbracoExamine.UmbracoExamineSearcher, UmbracoExamine" />
|
||||
|
||||
<add name="InternalMemberSearcher" type="UmbracoExamine.UmbracoExamineSearcher, UmbracoExamine"
|
||||
analyzer="Lucene.Net.Analysis.Standard.StandardAnalyzer, Lucene.Net" enableLeadingWildcards="true"/>
|
||||
|
||||
<add name="ExternalSearcher" type="UmbracoExamine.UmbracoExamineSearcher, UmbracoExamine" />
|
||||
|
||||
</providers>
|
||||
</ExamineSearchProviders>
|
||||
|
||||
|
||||
@@ -7,5 +7,5 @@
|
||||
<add key="virtualRoot" value="~/media/" />
|
||||
</Parameters>
|
||||
</Provider>
|
||||
|
||||
|
||||
</FileSystemProviders>
|
||||
|
||||
@@ -8,5 +8,5 @@
|
||||
<ext assembly="umbraco" type="umbraco.presentation.xslt.Exslt.ExsltRegularExpressions" alias="Exslt.ExsltRegularExpressions" />
|
||||
<ext assembly="umbraco" type="umbraco.presentation.xslt.Exslt.ExsltStrings" alias="Exslt.ExsltStrings" />
|
||||
<ext assembly="umbraco" type="umbraco.presentation.xslt.Exslt.ExsltSets" alias="Exslt.ExsltSets" />
|
||||
<ext assembly="UmbracoExamine" type="UmbracoExamine.XsltExtensions" alias="Examine" />
|
||||
<ext assembly="UmbracoExamine" type="UmbracoExamine.XsltExtensions" alias="Examine" />
|
||||
</XsltExtensions>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="ClientDependency" version="1.6.0.0" targetFramework="net40" />
|
||||
<package id="ClientDependency-Mvc" version="1.6.0.0" targetFramework="net40" />
|
||||
<package id="ClientDependency" version="1.7.0.1" targetFramework="net40" />
|
||||
<package id="ClientDependency-Mvc" version="1.7.0.0" targetFramework="net40" />
|
||||
<package id="Examine" version="0.1.51.2941" targetFramework="net40" />
|
||||
<package id="log4net-mediumtrust" version="2.0.0" targetFramework="net40" />
|
||||
<package id="Lucene.Net" version="2.9.4.1" targetFramework="net40" />
|
||||
@@ -16,6 +16,7 @@
|
||||
<package id="Microsoft.Net.Http" version="2.0.20710.0" targetFramework="net40" />
|
||||
<package id="Microsoft.Web.Helpers" version="1.0.0" targetFramework="net40" />
|
||||
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net40" />
|
||||
<package id="MiniProfiler" version="2.1.0" targetFramework="net40" />
|
||||
<package id="MySql.Data" version="6.6.4" targetFramework="net40" />
|
||||
<package id="Newtonsoft.Json" version="4.5.11" targetFramework="net40" />
|
||||
<package id="SharpZipLib" version="0.86.0" targetFramework="net40" />
|
||||
|
||||
@@ -34,7 +34,7 @@ UmbracoSpeechBubble.prototype.ShowMessage = function (icon, header, message, don
|
||||
if (!dontAutoHide) {
|
||||
jQuery("#" + this.id).fadeIn("slow").animate({ opacity: 1.0 }, 5000).fadeOut("fast");
|
||||
} else {
|
||||
speechBubble.jQuery(".speechClose").show();
|
||||
jQuery(".speechClose").show();
|
||||
jQuery("#" + this.id).fadeIn("slow");
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -29,9 +29,8 @@
|
||||
|
||||
//bind save shortcut
|
||||
UmbClientMgr.appActions().bindSaveShortCut();
|
||||
});
|
||||
})(jQuery);
|
||||
|
||||
})(jQuery);
|
||||
|
||||
</script>
|
||||
</asp:Content>
|
||||
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
<%@ Import Namespace="System.Web.Script.Serialization" %>
|
||||
|
||||
<%@ Register Src="controls/Tree/TreeControl.ascx" TagName="TreeControl" TagPrefix="umbraco" %>
|
||||
<%@ Import Namespace="StackExchange.Profiling" %>
|
||||
<%@ Import Namespace="Umbraco.Core.Profiling" %>
|
||||
<%@ Import Namespace="Umbraco.Web" %>
|
||||
<%@ Register TagPrefix="cc1" Namespace="umbraco.uicontrols" Assembly="controls" %>
|
||||
<%@ Register TagPrefix="uc1" TagName="quickSearch" Src="Search/QuickSearch.ascx" %>
|
||||
<%@ Register TagPrefix="umb" Namespace="ClientDependency.Core.Controls" Assembly="ClientDependency.Core" %>
|
||||
@@ -388,9 +391,9 @@
|
||||
}
|
||||
|
||||
</script>
|
||||
<%if(!String.IsNullOrEmpty(Request["umbDebug"]) && umbraco.GlobalSettings.DebugMode)
|
||||
<%if(string.IsNullOrEmpty(Request["umbDebug"]) == false && umbraco.GlobalSettings.DebugMode)
|
||||
{
|
||||
Response.Write(Umbraco.Core.Profiling.Profiler.Instance.Render());
|
||||
Response.Write(Html.RenderProfiler());
|
||||
}%>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<!-- Blocks public downloading of anything in this folder and sub folders -->
|
||||
|
||||
<configuration>
|
||||
<system.web>
|
||||
<httpHandlers>
|
||||
<add path="*" verb="*" type="System.Web.HttpNotFoundHandler"/>
|
||||
</httpHandlers>
|
||||
</system.web>
|
||||
<system.webServer>
|
||||
<validation validateIntegratedModeConfiguration="false" />
|
||||
<handlers>
|
||||
<remove name="BlockViewHandler"/>
|
||||
<add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
|
||||
</handlers>
|
||||
</system.webServer>
|
||||
</configuration>
|
||||
@@ -173,7 +173,7 @@ Umbraco.Sys.registerNamespace("Umbraco.Controls");
|
||||
var self = this;
|
||||
|
||||
// Inject the upload overlay
|
||||
var instructions = 'draggable' in document.createElement('span') ? "<h1>Drag files here to upload</h1> \<p>Or, click the button below to chose the items to upload</p>" : "<h1>Click the browse button below to chose the items to upload</h1>";
|
||||
var instructions = 'draggable' in document.createElement('span') ? "<h1>Drag files here to upload</h1> \<p>Or, click the button below to choose the items to upload</p>" : "<h1>Click the browse button below to choose the items to upload</h1>";
|
||||
|
||||
var overlay = $("<div class='upload-overlay'>" +
|
||||
"<div class='upload-panel'>" +
|
||||
|
||||
@@ -7,7 +7,6 @@ var UmbracoEmbedDialog = {
|
||||
tinyMCEPopup.close();
|
||||
},
|
||||
showPreview: function () {
|
||||
|
||||
$('#insert').attr('disabled', 'disabled');
|
||||
|
||||
var url = $('#url').val();
|
||||
@@ -16,44 +15,39 @@ var UmbracoEmbedDialog = {
|
||||
|
||||
$('#preview').html('<img src="img/ajax-loader.gif" alt="loading"/>');
|
||||
$('#source').val('');
|
||||
$.ajax(
|
||||
{
|
||||
type: 'POST',
|
||||
async: true,
|
||||
url: '../../../../umbraco/webservices/api/mediaservice.asmx/Embed',
|
||||
data: '{ url: "' + url + '", width: "' + width + '", height: "' + height + '" }',
|
||||
contentType: 'application/json; charset=utf-8',
|
||||
dataType: 'json',
|
||||
success: function (msg) {
|
||||
var resultAsJson = msg.d;
|
||||
switch (resultAsJson.Status) {
|
||||
case 0:
|
||||
//not supported
|
||||
$('#preview').html('Not Supported');
|
||||
break;
|
||||
case 1:
|
||||
//error
|
||||
$('#preview').html('Error');
|
||||
break;
|
||||
case 2:
|
||||
$('#preview').html(resultAsJson.Markup);
|
||||
$('#source').val(resultAsJson.Markup);
|
||||
if (resultAsJson.SupportsDimensions) {
|
||||
$('#dimensions').show();
|
||||
} else {
|
||||
$('#dimensions').hide();
|
||||
}
|
||||
$('#insert').removeAttr('disabled');
|
||||
break;
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
async: true,
|
||||
url: '../../../../base/EmbedMediaService/Embed/',
|
||||
data: { url: url, width: width, height: height },
|
||||
dataType: 'json',
|
||||
success: function (result) {
|
||||
switch (result.Status) {
|
||||
case 0:
|
||||
//not supported
|
||||
$('#preview').html('Not Supported');
|
||||
break;
|
||||
case 1:
|
||||
//error
|
||||
$('#preview').html('Error');
|
||||
break;
|
||||
case 2:
|
||||
$('#preview').html(result.Markup);
|
||||
$('#source').val(result.Markup);
|
||||
if (result.SupportsDimensions) {
|
||||
$('#dimensions').show();
|
||||
} else {
|
||||
$('#dimensions').hide();
|
||||
}
|
||||
|
||||
},
|
||||
error: function (xhr, ajaxOptions, thrownError) {
|
||||
$('#preview').html("Error");
|
||||
//alert(xhr.status);
|
||||
//alert(thrownError);
|
||||
}
|
||||
});
|
||||
$('#insert').removeAttr('disabled');
|
||||
break;
|
||||
}
|
||||
},
|
||||
error: function (xhr, ajaxOptions, thrownError) {
|
||||
$('#preview').html("Error");
|
||||
}
|
||||
});
|
||||
},
|
||||
beforeResize: function () {
|
||||
this.width = parseInt($('#width').val(), 10);
|
||||
@@ -73,11 +67,9 @@ var UmbracoEmbedDialog = {
|
||||
$('#width').val(this.width);
|
||||
}
|
||||
}
|
||||
|
||||
if ($('#url').val() != '') {
|
||||
UmbracoEmbedDialog.showPreview();
|
||||
}
|
||||
|
||||
},
|
||||
changeSource: function (type) {
|
||||
if ($('#source').val() != '') {
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
tinyMCE.addI18n('da.umbracoembed', {
|
||||
desc: 'Inds\u00E6t ekstern mediefil',
|
||||
desc: 'Inds\u00E6t ekstern mediefil'
|
||||
});
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
tinyMCE.addI18n('en.umbracoembed', {
|
||||
desc: 'Embed third party media',
|
||||
desc: 'Embed third party media'
|
||||
});
|
||||
@@ -1,3 +1,3 @@
|
||||
tinyMCE.addI18n('en_us.umbracoembed', {
|
||||
desc: 'Embed third party media',
|
||||
desc: 'Embed third party media'
|
||||
});
|
||||
@@ -5,7 +5,7 @@
|
||||
<section name="microsoft.scripting" type="Microsoft.Scripting.Hosting.Configuration.Section, Microsoft.Scripting, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" />
|
||||
<section name="clientDependency" type="ClientDependency.Core.Config.ClientDependencySection, ClientDependency.Core" requirePermission="false"/>
|
||||
<section name="Examine" type="Examine.Config.ExamineSettings, Examine" requirePermission="false"/>
|
||||
<section name="ExamineLuceneIndexSets" type="Examine.LuceneEngine.Config.IndexSets, Examine" requirePermission="false" />
|
||||
<section name="ExamineLuceneIndexSets" type="Examine.LuceneEngine.Config.IndexSets, Examine" requirePermission="false"/>
|
||||
<section name="FileSystemProviders" type="Umbraco.Core.Configuration.FileSystemProvidersSection, Umbraco.Core" requirePermission="false"/>
|
||||
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" requirePermission="false" />
|
||||
<section name="BaseRestExtensions" type="Umbraco.Web.BaseRest.Configuration.BaseRestSection, umbraco" requirePermission="false" />
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<!-- Blocks public downloading of anything in this folder and sub folders -->
|
||||
|
||||
<configuration>
|
||||
<system.web>
|
||||
<httpHandlers>
|
||||
<add path="*" verb="*" type="System.Web.HttpNotFoundHandler"/>
|
||||
</httpHandlers>
|
||||
</system.web>
|
||||
<system.webServer>
|
||||
<validation validateIntegratedModeConfiguration="false" />
|
||||
<handlers>
|
||||
<remove name="BlockViewHandler"/>
|
||||
<add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
|
||||
</handlers>
|
||||
</system.webServer>
|
||||
</configuration>
|
||||
@@ -10,17 +10,29 @@ using System.Web.Routing;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Dynamics;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Profiling;
|
||||
using Umbraco.Web.Mvc;
|
||||
using umbraco;
|
||||
using umbraco.cms.businesslogic.member;
|
||||
|
||||
namespace Umbraco.Web
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
/// <summary>
|
||||
/// HtmlHelper extensions for use in templates
|
||||
/// </summary>
|
||||
public static class HtmlHelperRenderExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Renders the markup for the profiler
|
||||
/// </summary>
|
||||
/// <param name="helper"></param>
|
||||
/// <returns></returns>
|
||||
public static IHtmlString RenderProfiler(this HtmlHelper helper)
|
||||
{
|
||||
return new HtmlString(ProfilerResolver.Current.Profiler.Render());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Renders a partial view that is found in the specified area
|
||||
/// </summary>
|
||||
|
||||
@@ -22,6 +22,16 @@ namespace Umbraco.Web.Mvc
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the controller name from the controller instance
|
||||
/// </summary>
|
||||
/// <param name="controllerInstance"></param>
|
||||
/// <returns></returns>
|
||||
internal static string GetControllerName(this IController controllerInstance)
|
||||
{
|
||||
return GetControllerName(controllerInstance.GetType());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the controller name from the controller type
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
|
||||
@@ -114,7 +114,7 @@ namespace Umbraco.Web.Mvc
|
||||
else
|
||||
{
|
||||
//exit the loop
|
||||
currentRouteData = null;
|
||||
currentContext = null;
|
||||
}
|
||||
}
|
||||
return new Attempt<RouteDefinition>(
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using StackExchange.Profiling;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Dictionary;
|
||||
@@ -6,6 +7,7 @@ using Umbraco.Core.Dynamics;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Profiling;
|
||||
using Umbraco.Web.Models;
|
||||
|
||||
namespace Umbraco.Web.Mvc
|
||||
@@ -93,7 +95,7 @@ namespace Umbraco.Web.Mvc
|
||||
}
|
||||
else
|
||||
{
|
||||
var profilerMarkup = Core.Profiling.Profiler.Instance.Render();
|
||||
var profilerMarkup = this.Html.RenderProfiler();
|
||||
text = text.Substring(0, pos) + profilerMarkup + text.Substring(pos, text.Length - pos);
|
||||
}
|
||||
base.WriteLiteral(text);
|
||||
|
||||
@@ -325,7 +325,7 @@ namespace Umbraco.Web.Routing
|
||||
// the first successful finder, if any, will set this.PublishedContent, and may also set this.Template
|
||||
// some finders may implement caching
|
||||
|
||||
using (DisposableTimer.DebugDuration<PluginManager>(
|
||||
using (DisposableTimer.DebugDuration<PublishedContentRequestEngine>(
|
||||
() => string.Format("{0}Begin finders", tracePrefix),
|
||||
() => string.Format("{0}End finders, {1}", tracePrefix, (_pcr.HasPublishedContent ? "a document was found" : "no document was found"))))
|
||||
{
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
using System.Web.Security;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
namespace Umbraco.Web.Security.Providers
|
||||
{
|
||||
/// <summary>
|
||||
/// Custom Membership Provider for Umbraco Members (User authentication for Umbraco based Websites)
|
||||
/// </summary>
|
||||
internal class MembersMembershipProvider : MembershipProvider
|
||||
{
|
||||
private IMembershipMemberService _memberService;
|
||||
|
||||
protected IMembershipMemberService MemberService
|
||||
{
|
||||
get { return _memberService ?? (_memberService = ApplicationContext.Current.Services.MemberService); }
|
||||
}
|
||||
|
||||
public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer,
|
||||
bool isApproved, object providerUserKey, out MembershipCreateStatus status)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion,
|
||||
string newPasswordAnswer)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string GetPassword(string username, string answer)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override bool ChangePassword(string username, string oldPassword, string newPassword)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ResetPassword(string username, string answer)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override void UpdateUser(MembershipUser user)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override bool ValidateUser(string username, string password)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override bool UnlockUser(string userName)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override MembershipUser GetUser(string username, bool userIsOnline)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string GetUserNameByEmail(string email)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override bool DeleteUser(string username, bool deleteAllRelatedData)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override int GetNumberOfUsersOnline()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override bool EnablePasswordRetrieval
|
||||
{
|
||||
get { throw new System.NotImplementedException(); }
|
||||
}
|
||||
|
||||
public override bool EnablePasswordReset
|
||||
{
|
||||
get { throw new System.NotImplementedException(); }
|
||||
}
|
||||
|
||||
public override bool RequiresQuestionAndAnswer
|
||||
{
|
||||
get { throw new System.NotImplementedException(); }
|
||||
}
|
||||
|
||||
public override string ApplicationName { get; set; }
|
||||
|
||||
public override int MaxInvalidPasswordAttempts
|
||||
{
|
||||
get { throw new System.NotImplementedException(); }
|
||||
}
|
||||
|
||||
public override int PasswordAttemptWindow
|
||||
{
|
||||
get { throw new System.NotImplementedException(); }
|
||||
}
|
||||
|
||||
public override bool RequiresUniqueEmail
|
||||
{
|
||||
get { throw new System.NotImplementedException(); }
|
||||
}
|
||||
|
||||
public override MembershipPasswordFormat PasswordFormat
|
||||
{
|
||||
get { throw new System.NotImplementedException(); }
|
||||
}
|
||||
|
||||
public override int MinRequiredPasswordLength
|
||||
{
|
||||
get { throw new System.NotImplementedException(); }
|
||||
}
|
||||
|
||||
public override int MinRequiredNonAlphanumericCharacters
|
||||
{
|
||||
get { throw new System.NotImplementedException(); }
|
||||
}
|
||||
|
||||
public override string PasswordStrengthRegularExpression
|
||||
{
|
||||
get { throw new System.NotImplementedException(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
using System;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Web.Security;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
namespace Umbraco.Web.Security.Providers
|
||||
{
|
||||
/// <summary>
|
||||
/// Custom Membership Provider for Umbraco Users (User authentication for Umbraco Backend CMS)
|
||||
/// </summary>
|
||||
internal class UsersMembershipProvider : MembershipProvider
|
||||
{
|
||||
private IMembershipUserService _userService;
|
||||
|
||||
protected IMembershipUserService UserService
|
||||
{
|
||||
get { return _userService ?? (_userService = ApplicationContext.Current.Services.UserService); }
|
||||
}
|
||||
|
||||
public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer,
|
||||
bool isApproved, object providerUserKey, out MembershipCreateStatus status)
|
||||
{
|
||||
//Assuming the password is hashed
|
||||
var hash = new HMACSHA1();
|
||||
hash.Key = Encoding.Unicode.GetBytes(password);
|
||||
var encodedPassword = Convert.ToBase64String(hash.ComputeHash(Encoding.Unicode.GetBytes(password)));
|
||||
|
||||
//var user = _userService.CreateUser();
|
||||
//status = MembershipCreateStatus.Success;
|
||||
//return new UmbracoMembershipUser<User>(user);
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion,
|
||||
string newPasswordAnswer)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string GetPassword(string username, string answer)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override bool ChangePassword(string username, string oldPassword, string newPassword)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ResetPassword(string username, string answer)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override void UpdateUser(MembershipUser user)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override bool ValidateUser(string username, string password)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override bool UnlockUser(string userName)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override MembershipUser GetUser(string username, bool userIsOnline)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string GetUserNameByEmail(string email)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override bool DeleteUser(string username, bool deleteAllRelatedData)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override int GetNumberOfUsersOnline()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override bool EnablePasswordRetrieval
|
||||
{
|
||||
get { throw new System.NotImplementedException(); }
|
||||
}
|
||||
|
||||
public override bool EnablePasswordReset
|
||||
{
|
||||
get { throw new System.NotImplementedException(); }
|
||||
}
|
||||
|
||||
public override bool RequiresQuestionAndAnswer
|
||||
{
|
||||
get { throw new System.NotImplementedException(); }
|
||||
}
|
||||
|
||||
public override string ApplicationName { get; set; }
|
||||
|
||||
public override int MaxInvalidPasswordAttempts
|
||||
{
|
||||
get { throw new System.NotImplementedException(); }
|
||||
}
|
||||
|
||||
public override int PasswordAttemptWindow
|
||||
{
|
||||
get { throw new System.NotImplementedException(); }
|
||||
}
|
||||
|
||||
public override bool RequiresUniqueEmail
|
||||
{
|
||||
get { throw new System.NotImplementedException(); }
|
||||
}
|
||||
|
||||
public override MembershipPasswordFormat PasswordFormat
|
||||
{
|
||||
get { throw new System.NotImplementedException(); }
|
||||
}
|
||||
|
||||
public override int MinRequiredPasswordLength
|
||||
{
|
||||
get { throw new System.NotImplementedException(); }
|
||||
}
|
||||
|
||||
public override int MinRequiredNonAlphanumericCharacters
|
||||
{
|
||||
get { throw new System.NotImplementedException(); }
|
||||
}
|
||||
|
||||
public override string PasswordStrengthRegularExpression
|
||||
{
|
||||
get { throw new System.NotImplementedException(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -379,9 +379,16 @@ namespace Umbraco.Web.Security
|
||||
return encTicket.DecryptWithMachineKey();
|
||||
}
|
||||
}
|
||||
catch (HttpException ex)
|
||||
catch (Exception ex)
|
||||
{
|
||||
// we swallow this type of exception as it happens if a legacy (pre 4.8.1) cookie is set
|
||||
if (ex is ArgumentException || ex is FormatException || ex is HttpException)
|
||||
{
|
||||
StateHelper.Cookies.UserContext.Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user