Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0

This commit is contained in:
Shannon
2014-03-06 18:26:10 +11:00
21 changed files with 680 additions and 37 deletions

View File

@@ -27,7 +27,7 @@ namespace Umbraco.Core
/// <summary>
/// Gets the <see cref="ICacheRefresher"/> implementations.
/// </summary>
public IEnumerable<ICacheRefresher> CacheResolvers
public IEnumerable<ICacheRefresher> CacheRefreshers
{
get
{

View File

@@ -54,7 +54,8 @@ namespace Umbraco.Core.Models
Trashed = trashed;
}
public UmbracoEntity(int trashed)
// for MySql
public UmbracoEntity(UInt64 trashed)
{
AdditionalData = new Dictionary<string, object>();
Trashed = trashed == 1;

View File

@@ -115,6 +115,11 @@ namespace Umbraco.Core.Strings
return InvalidFileNameChars.Contains(c) == false;
}
public static string CutMaxLength(string text, int length)
{
return text.Length <= length ? text : text.Substring(0, length);
}
#endregion
#region Configuration
@@ -168,6 +173,7 @@ namespace Umbraco.Core.Strings
return WithConfig(CleanStringType.UrlSegment, new Config
{
PreFilter = ApplyUrlReplaceCharacters,
PostFilter = x => CutMaxLength(x, 240),
IsTerm = (c, leading) => char.IsLetterOrDigit(c) || c == '_', // letter, digit or underscore
StringType = (UrlReplacingToAscii ? CleanStringType.Ascii : CleanStringType.Utf8) | CleanStringType.LowerCase,
BreakTermsOnUpper = false,
@@ -202,6 +208,7 @@ namespace Umbraco.Core.Strings
{
StringType = CleanStringType.Utf8 | CleanStringType.Unchanged;
PreFilter = null;
PostFilter = null;
IsTerm = (c, leading) => leading ? char.IsLetter(c) : char.IsLetterOrDigit(c);
BreakTermsOnUpper = false;
CutAcronymOnNonUpper = false;
@@ -214,6 +221,7 @@ namespace Umbraco.Core.Strings
return new Config
{
PreFilter = PreFilter,
PostFilter = PostFilter,
IsTerm = IsTerm,
StringType = StringType,
BreakTermsOnUpper = BreakTermsOnUpper,
@@ -224,6 +232,7 @@ namespace Umbraco.Core.Strings
}
public Func<string, string> PreFilter { get; set; }
public Func<string, string> PostFilter { get; set; }
public Func<char, bool, bool> IsTerm { get; set; }
public CleanStringType StringType { get; set; }
@@ -554,6 +563,10 @@ function validateSafeAlias(id, value, immediate, callback) {{
// clean
text = CleanCodeString(text, stringType, separator.Value, culture, config);
// apply post-filter
if (config.PostFilter != null)
text = config.PostFilter(text);
return text;
}

View File

@@ -99,6 +99,12 @@ namespace Umbraco.Tests.PublishedContent
{
return _content.Count > 0;
}
public IPublishedContent CreateFragment(string contentTypeAlias, IDictionary<string, object> dataValues,
bool isPreviewing, bool managed)
{
throw new NotImplementedException();
}
}
class SolidPublishedContent : IPublishedContent

View File

@@ -1,4 +1,5 @@
<%@ Page Language="c#" MasterPageFile="../../masterpages/umbracoPage.Master" Title="Edit data type"
ValidateRequest="false"
CodeBehind="editDatatype.aspx.cs" AutoEventWireup="True" Inherits="umbraco.cms.presentation.developer.editDatatype" %>
<%@ Register TagPrefix="cc1" Namespace="umbraco.uicontrols" Assembly="controls" %>

View File

@@ -141,6 +141,7 @@ namespace Umbraco.Web.Mvc
// maps model
protected override void SetViewData(ViewDataDictionary viewData)
{
// if view data contains no model, nothing to do
var source = viewData.Model;
if (source == null)
{
@@ -148,6 +149,8 @@ namespace Umbraco.Web.Mvc
return;
}
// get the type of the view data model (what we have)
// get the type of this view model (what we want)
var sourceType = source.GetType();
var targetType = typeof (TModel);
@@ -160,13 +163,15 @@ namespace Umbraco.Web.Mvc
// try to grab the content
// if no content is found, return, nothing we can do
var sourceContent = source as IPublishedContent;
var sourceContent = source as IPublishedContent; // check if what we have is an IPublishedContent
if (sourceContent == null && sourceType.Implements<IRenderModel>())
{
// else check if it's an IRenderModel => get the content
sourceContent = ((IRenderModel)source).Content;
}
if (sourceContent == null)
{
// else check if we can convert it to a content
var attempt = source.TryConvertTo<IPublishedContent>();
if (attempt.Success) sourceContent = attempt.Result;
}

View File

@@ -33,5 +33,53 @@ namespace Umbraco.Web.PublishedCache
/// <returns>The route.</returns>
/// <remarks>The value of <paramref name="preview"/> overrides the context.</remarks>
string GetRouteById(UmbracoContext umbracoContext, bool preview, int contentId);
/// <summary>
/// Creates a content fragment.
/// </summary>
/// <param name="contentTypeAlias">The content type alias.</param>
/// <param name="dataValues">The content property raw values.</param>
/// <param name="isPreviewing">A value indicating whether the fragment is previewing.</param>
/// <param name="managed">A value indicating whether the fragment is managed by the cache.</param>
/// <returns>The newly created content fragment.</returns>
//
// notes
//
// in XmlPublishedCache, IPublishedContent instances are not meant to survive longer
// that a request or else we cannot guarantee that the converted property values will
// be properly managed - because XmlPublishedProperty just stores the result of the
// conversion locally.
//
// in DrippingPublishedCache, IPublishedContent instances are meant to survive for as
// long as the content itself has not been modified, and the property respects the
// converter's indication ie whether the converted value should be cached at
// .Content - cache until the content changes
// .ContentCache - cache until any content changes
// .Request - cache for the current request
//
// a fragment can be either "detached" or "managed".
// detached: created from code, managed by code, converted property values are
// cached within the fragment itself for as long as the fragment lives
// managed: created from a property converter as part of a content, managed by
// the cache, converted property values can be cached...
//
// XmlPublishedCache: same as content properties, store the result of the
// conversion locally, neither content nor fragments should survive longer
// than a request
// DrippingPublishedCache: depends
// .Content: cache within the fragment
// .ContentCache, .Request: cache within the cache
//
// in the latter case, use a fragment-owned guid as the cache key. because we
// don't really have any other choice. this opens potential memory leaks: if the
// fragment is re-created on each request and has a property that caches its
// converted value at .ContentCache level then we'll flood that cache with data
// that's never removed (as long as no content is edited).
//
// so a requirement should be that any converter that creates fragment, should
// be marked .Content -- and nothing else
//
IPublishedContent CreateFragment(string contentTypeAlias, IDictionary<string, object> dataValues,
bool isPreviewing, bool managed);
}
}

View File

@@ -460,5 +460,15 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
}
#endregion
#region Fragments
public IPublishedContent CreateFragment(string contentTypeAlias, IDictionary<string, object> dataValues,
bool isPreviewing, bool managed)
{
return new PublishedFragment(contentTypeAlias, dataValues, isPreviewing, managed);
}
#endregion
}
}

View File

@@ -0,0 +1,169 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Web.Models;
namespace Umbraco.Web.PublishedCache.XmlPublishedCache
{
class PublishedFragment : PublishedContentBase
{
private readonly PublishedContentType _contentType;
private readonly IPublishedProperty[] _properties;
public PublishedFragment(string contentTypeAlias, IDictionary<string, object> dataValues,
bool isPreviewing, bool managed)
{
IsPreviewing = isPreviewing;
_contentType = PublishedContentType.Get(PublishedItemType.Content, contentTypeAlias);
// we don't care about managed because in both cases, XmlPublishedCache stores
// converted property values in the IPublishedContent, which is not meant to
// survive the request
var dataValues2 = new Dictionary<string, object>();
foreach (var kvp in dataValues)
dataValues2[kvp.Key.ToLowerInvariant()] = kvp.Value;
_properties = _contentType.PropertyTypes
.Select(x =>
{
object dataValue;
return dataValues2.TryGetValue(x.PropertyTypeAlias.ToLowerInvariant(), out dataValue)
? new PublishedFragmentProperty(x, this, dataValue)
: new PublishedFragmentProperty(x, this);
})
.Cast<IPublishedProperty>()
.ToArray();
}
#region IPublishedContent
public override int Id
{
get { throw new NotImplementedException(); }
}
public override int DocumentTypeId
{
get { return _contentType.Id; }
}
public override string DocumentTypeAlias
{
get { return _contentType.Alias; }
}
public override PublishedItemType ItemType
{
get { return PublishedItemType.Content; }
}
public override string Name
{
get { throw new NotImplementedException(); }
}
public override int Level
{
get { throw new NotImplementedException(); }
}
public override string Path
{
get { throw new NotImplementedException(); }
}
public override int SortOrder
{
// note - could a published fragment have a sort order?
get { throw new NotImplementedException(); }
}
public override Guid Version
{
get { throw new NotImplementedException(); }
}
public override int TemplateId
{
get { throw new NotImplementedException(); }
}
public override string UrlName
{
get { return string.Empty; }
}
public override DateTime CreateDate
{
get { throw new NotImplementedException(); }
}
public override DateTime UpdateDate
{
get { throw new NotImplementedException(); }
}
public override int CreatorId
{
get { throw new NotImplementedException(); }
}
public override string CreatorName
{
get { throw new NotImplementedException(); }
}
public override int WriterId
{
get { throw new NotImplementedException(); }
}
public override string WriterName
{
get { throw new NotImplementedException(); }
}
public override bool IsDraft
{
get { throw new NotImplementedException(); }
}
public override IPublishedContent Parent
{
get { throw new NotImplementedException(); }
}
public override IEnumerable<IPublishedContent> Children
{
get { throw new NotImplementedException(); }
}
public override ICollection<IPublishedProperty> Properties
{
get { return _properties; }
}
public override IPublishedProperty GetProperty(string alias)
{
return _properties.FirstOrDefault(x => x.PropertyTypeAlias.InvariantEquals(alias));
}
public override PublishedContentType ContentType
{
get { return _contentType; }
}
#endregion
#region Internal
// used by PublishedFragmentProperty
internal bool IsPreviewing { get; private set; }
#endregion
}
}

View File

@@ -0,0 +1,43 @@
using System;
using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Web.PublishedCache.XmlPublishedCache
{
class PublishedFragmentProperty : PublishedPropertyBase
{
private readonly object _dataValue;
private readonly PublishedFragment _content;
private readonly Lazy<object> _sourceValue;
private readonly Lazy<object> _objectValue;
private readonly Lazy<object> _xpathValue;
public PublishedFragmentProperty(PublishedPropertyType propertyType, PublishedFragment content)
: this(propertyType, content, null)
{ }
public PublishedFragmentProperty(PublishedPropertyType propertyType, PublishedFragment content, object dataValue)
: base(propertyType)
{
_dataValue = dataValue;
_content = content;
_sourceValue = new Lazy<object>(() => PropertyType.ConvertDataToSource(_dataValue, _content.IsPreviewing));
_objectValue = new Lazy<object>(() => PropertyType.ConvertSourceToObject(_sourceValue.Value, _content.IsPreviewing));
_xpathValue = new Lazy<object>(() => PropertyType.ConvertSourceToXPath(_sourceValue.Value, _content.IsPreviewing));
}
public override bool HasValue
{
get { return _dataValue != null && ((_dataValue is string) == false || string.IsNullOrWhiteSpace((string)_dataValue) == false); }
}
public override object DataValue
{
get { return _dataValue; }
}
public override object Value { get { return _objectValue.Value; } }
public override object XPathValue { get { return _xpathValue.Value; } }
}
}

View File

@@ -152,12 +152,21 @@ namespace Umbraco.Web.Routing
}
else
{
// look for the first domain that would be the base of the hint
var hintWithSlash = current.EndPathWithSlash();
// look for the first domain that would be the base of the current url
// ie current is www.example.com/foo/bar, look for domain www.example.com
var currentWithSlash = current.EndPathWithSlash();
domainAndUri = domainsAndUris
.FirstOrDefault(d => d.Uri.EndPathWithSlash().IsBaseOf(hintWithSlash));
.FirstOrDefault(d => d.Uri.EndPathWithSlash().IsBaseOf(currentWithSlash));
if (domainAndUri != null) return domainAndUri;
// look for the first domain that the current url would be the base of
// ie current is www.example.com, look for domain www.example.com/foo/bar
domainAndUri = domainsAndUris
.FirstOrDefault(d => currentWithSlash.IsBaseOf(d.Uri.EndPathWithSlash()));
if (domainAndUri != null) return domainAndUri;
// if none matches, then try to run the filter to pick a domain
if (domainAndUri == null && filter != null)
if (filter != null)
{
domainAndUri = filter(domainsAndUris);
// if still nothing, pick the first one?

View File

@@ -312,6 +312,16 @@ namespace Umbraco.Web.Routing
TemplateModel = template;
}
/// <summary>
/// Resets the template.
/// </summary>
/// <remarks>The <c>RenderingEngine</c> becomes unknown.</remarks>
public void ResetTemplate()
{
EnsureWriteable();
TemplateModel = null;
}
/// <summary>
/// Gets a value indicating whether the content request has a template.
/// </summary>

View File

@@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
namespace Umbraco.Web.Standalone
{
public static class PowershellAssemblyResolver
{
private static readonly Dictionary<string, string> Assemblies;
private static readonly object Locko = new object();
static PowershellAssemblyResolver()
{
var comparer = StringComparer.CurrentCultureIgnoreCase;
Assemblies = new Dictionary<string,string>(comparer);
AppDomain.CurrentDomain.AssemblyResolve += ResolveHandler;
}
public static void AddAssemblyLocation(string path)
{
if (string.IsNullOrWhiteSpace(path))
throw new ArgumentException("Arg is null or empty.", "path");
lock (Locko)
{
var name = Path.GetFileNameWithoutExtension(path);
Assemblies.Add(name, path);
}
}
private static Assembly ResolveHandler(object sender, ResolveEventArgs args)
{
var assemblyName = new AssemblyName(args.Name);
string assemblyFile;
return Assemblies.TryGetValue(assemblyName.Name, out assemblyFile)
? Assembly.LoadFrom(assemblyFile)
: null;
}
}
}

View File

@@ -59,7 +59,15 @@ namespace Umbraco.Web.Standalone
if (noerr) return;
throw new InvalidOperationException("Application has already started.");
}
Application_Start(this, EventArgs.Empty);
try
{
Application_Start(this, EventArgs.Empty);
}
catch
{
TerminateInternal();
throw;
}
_started = true;
}
}
@@ -74,14 +82,24 @@ namespace Umbraco.Web.Standalone
throw new InvalidOperationException("Application has already been terminated.");
}
TerminateInternal();
}
}
private void TerminateInternal()
{
if (ApplicationContext.Current != null)
{
ApplicationContext.Current.DisposeIfDisposable(); // should reset resolution, clear caches & resolvers...
ApplicationContext.Current = null;
}
if (UmbracoContext.Current != null)
{
UmbracoContext.Current.DisposeIfDisposable(); // dunno
UmbracoContext.Current = null;
_started = false;
_application = null;
}
_started = false;
_application = null;
}
#endregion

View File

@@ -0,0 +1,262 @@
using System;
using System.Collections.Specialized;
using System.Configuration;
using System.Configuration.Internal;
using System.Reflection;
using System.Threading;
namespace Umbraco.Web.Standalone
{
// see http://stackoverflow.com/questions/15653621/how-to-update-add-modify-delete-keys-in-appsettings-section-of-web-config-at-r
// see http://www.codeproject.com/Articles/69364/Override-Configuration-Manager
public sealed class WriteableConfigSystem : IInternalConfigSystem
{
private static readonly ReaderWriterLockSlim RwLock = new ReaderWriterLockSlim();
private static WriteableConfigSystem _installed;
private static IInternalConfigSystem _clientConfigSystem;
private object _appsettings;
private object _connectionStrings;
private static object _sInitStateOrig;
private static object _sConfigSystemOrig;
public static bool Installed
{
get
{
try
{
RwLock.EnterReadLock();
return _installed != null;
}
finally
{
RwLock.ExitReadLock();
}
}
}
/// <summary>
/// Re-initializes the ConfigurationManager, allowing us to merge in the settings from Core.Config
/// </summary>
public static void Install()
{
try
{
RwLock.EnterWriteLock();
if (_installed != null)
throw new InvalidOperationException("ConfigSystem is already installed.");
FieldInfo[] fiStateValues = null;
var tInitState = typeof(ConfigurationManager).GetNestedType("InitState", BindingFlags.NonPublic);
if (tInitState != null)
fiStateValues = tInitState.GetFields();
// 0: NotStarted
// 1: Started
// 2: Usable
// 3: Completed
var fiInit = typeof(ConfigurationManager).GetField("s_initState", BindingFlags.NonPublic | BindingFlags.Static);
var fiSystem = typeof(ConfigurationManager).GetField("s_configSystem", BindingFlags.NonPublic | BindingFlags.Static);
if (fiInit != null && fiSystem != null && fiStateValues != null)
{
_sInitStateOrig = fiInit.GetValue(null);
_sConfigSystemOrig = fiSystem.GetValue(null);
fiInit.SetValue(null, fiStateValues[1].GetValue(null)); // set to Started
fiSystem.SetValue(null, null); // clear current config system
}
_installed = new WriteableConfigSystem();
var configFactoryType = Type.GetType("System.Configuration.Internal.InternalConfigSettingsFactory, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", true);
var configSettingsFactory = (IInternalConfigSettingsFactory)Activator.CreateInstance(configFactoryType, true);
// just does ConfigurationManager.SetConfigurationSystem(_installed, false);
// 'false' turns initState to 2 ie usable (vs 3 ie completed)
configSettingsFactory.SetConfigurationSystem(_installed, false);
// note: prob. don't need the factory... see how we uninstall...
var clientConfigSystemType = Type.GetType("System.Configuration.ClientConfigurationSystem, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", true);
_clientConfigSystem = (IInternalConfigSystem)Activator.CreateInstance(clientConfigSystemType, true);
}
finally
{
RwLock.ExitWriteLock();
}
}
public static void Uninstall()
{
try
{
RwLock.EnterWriteLock();
if (_installed == null)
throw new InvalidOperationException("ConfigSystem is not installed.");
FieldInfo[] fiStateValues = null;
var tInitState = typeof(ConfigurationManager).GetNestedType("InitState", BindingFlags.NonPublic);
if (tInitState != null)
fiStateValues = tInitState.GetFields();
var fiInit = typeof(ConfigurationManager).GetField("s_initState", BindingFlags.NonPublic | BindingFlags.Static);
var fiSystem = typeof(ConfigurationManager).GetField("s_configSystem", BindingFlags.NonPublic | BindingFlags.Static);
if (fiInit != null && fiSystem != null && fiStateValues != null)
{
// reset - the hard way
fiInit.SetValue(null, _sInitStateOrig);
fiSystem.SetValue(null, _sConfigSystemOrig);
}
_installed = null;
_clientConfigSystem = null;
}
finally
{
RwLock.ExitWriteLock();
}
}
public static void Reset()
{
try
{
RwLock.EnterWriteLock();
if (_installed == null)
throw new InvalidOperationException("ConfigSystem is not installed.");
_installed._appsettings = null;
_installed._connectionStrings = null;
}
finally
{
RwLock.ExitWriteLock();
}
}
#region IInternalConfigSystem Members
public object GetSection(string configKey)
{
// get the section from the default location (web.config or app.config)
var section = _clientConfigSystem.GetSection(configKey);
try
{
RwLock.EnterReadLock();
switch (configKey)
{
case "appSettings":
// Return cached version if exists
if (_appsettings != null)
return _appsettings;
// create a new collection because the underlying collection is read-only
var cfg = new NameValueCollection();
// If an AppSettings section exists in Web.config, read and add values from it
var nvSection = section as NameValueCollection;
if (nvSection != null)
{
var localSettings = nvSection;
foreach (string key in localSettings)
cfg.Add(key, localSettings[key]);
}
//// --------------------------------------------------------------------
//// Here I read and decrypt keys and add them to secureConfig dictionary
//// To test assume the following line is a key stored in secure sotrage.
////secureConfig = SecureConfig.LoadConfig();
//secureConfig.Add("ACriticalKey", "VeryCriticalValue");
//// --------------------------------------------------------------------
//foreach (KeyValuePair<string, string> item in secureConfig)
//{
// if (cfg.AllKeys.Contains(item.Key))
// {
// cfg[item.Key] = item.Value;
// }
// else
// {
// cfg.Add(item.Key, item.Value);
// }
//}
//// --------------------------------------------------------------------
// Cach the settings for future use
_appsettings = cfg;
// return the merged version of the items from secure storage and appsettings
section = _appsettings;
break;
case "connectionStrings":
// Return cached version if exists
if (_connectionStrings != null)
return _connectionStrings;
// create a new collection because the underlying collection is read-only
var connectionStringsSection = new ConnectionStringsSection();
// copy the existing connection strings into the new collection
foreach (
ConnectionStringSettings connectionStringSetting in
((ConnectionStringsSection)section).ConnectionStrings)
connectionStringsSection.ConnectionStrings.Add(connectionStringSetting);
// --------------------------------------------------------------------
// Again Load connection strings from secure storage and merge like below
// connectionStringsSection.ConnectionStrings.Add(connectionStringSetting);
// --------------------------------------------------------------------
// Cach the settings for future use
_connectionStrings = connectionStringsSection;
// return the merged version of the items from secure storage and appsettings
section = _connectionStrings;
break;
}
}
finally
{
RwLock.ExitReadLock();
}
return section;
}
public void RefreshConfig(string sectionName)
{
try
{
RwLock.EnterWriteLock();
if (sectionName == "appSettings")
{
_appsettings = null;
}
if (sectionName == "connectionStrings")
{
_connectionStrings = null;
}
}
finally
{
RwLock.ExitWriteLock();
}
_clientConfigSystem.RefreshConfig(sectionName);
}
public bool SupportsUserConfig { get { return _clientConfigSystem.SupportsUserConfig; } }
#endregion
}
}

View File

@@ -299,6 +299,8 @@
<Compile Include="Models\ChangingPasswordModel.cs" />
<Compile Include="Models\IRenderModel.cs" />
<Compile Include="Models\PostRedirectModel.cs" />
<Compile Include="PublishedCache\XmlPublishedCache\PublishedFragment.cs" />
<Compile Include="PublishedCache\XmlPublishedCache\PublishedFragmentProperty.cs" />
<Compile Include="Models\RenderModelOfTContent.cs" />
<Compile Include="Mvc\EnsurePublishedContentRequestAttribute.cs" />
<Compile Include="Mvc\UmbracoTemplatePageOfTContent.cs" />
@@ -322,6 +324,7 @@
<Compile Include="Security\Providers\MembersRoleProvider.cs" />
<Compile Include="Security\Providers\UmbracoMembershipProvider.cs" />
<Compile Include="Security\Providers\UsersMembershipProvider.cs" />
<Compile Include="Standalone\PowershellAssemblyResolver.cs" />
<Compile Include="Standalone\ServiceContextManager.cs" />
<Compile Include="Standalone\StandaloneApplication.cs" />
<Compile Include="Standalone\StandaloneBootManager.cs" />
@@ -397,6 +400,7 @@
<Compile Include="Search\LuceneIndexerExtensions.cs" />
<Compile Include="Security\ValidateRequestAttempt.cs" />
<Compile Include="Security\WebSecurity.cs" />
<Compile Include="Standalone\WriteableConfigSystem.cs" />
<Compile Include="Strategies\Migrations\ClearMediaXmlCacheForDeletedItemsAfterUpgrade.cs" />
<Compile Include="Strategies\Migrations\RebuildMediaXmlCacheAfterUpgrade.cs" />
<Compile Include="Strategies\PublicAccessEventHandler.cs" />

View File

@@ -52,7 +52,7 @@ namespace umbraco.presentation.cache
/// <returns></returns>
public ICacheRefresher[] GetAll()
{
return CacheRefreshersResolver.Current.CacheResolvers.ToArray();
return CacheRefreshersResolver.Current.CacheRefreshers.ToArray();
}
#endregion

View File

@@ -115,7 +115,7 @@ namespace umbraco.presentation.webservices
{
var xd = new XmlDocument();
xd.LoadXml("<cacheRefreshers/>");
foreach (var cr in CacheRefreshersResolver.Current.CacheResolvers)
foreach (var cr in CacheRefreshersResolver.Current.CacheRefreshers)
{
var n = xmlHelper.addTextNode(xd, "cacheRefresher", cr.Name);
n.Attributes.Append(xmlHelper.addAttribute(xd, "uniqueIdentifier", cr.UniqueIdentifier.ToString()));

View File

@@ -532,5 +532,24 @@ namespace umbraco.cms.businesslogic
}
#endregion
}
// zb023 - utility method
public static string ReplaceKey(string text)
{
if (text.StartsWith("#") == false)
return text;
var lang = Language.GetByCultureCode(Thread.CurrentThread.CurrentCulture.Name);
if (lang == null)
return "[" + text + "]";
if (DictionaryItem.hasKey(text.Substring(1, text.Length - 1)) == false)
return "[" + text + "]";
var di = new DictionaryItem(text.Substring(1, text.Length - 1));
return di.Value(lang.id);
}
}
}

View File

@@ -143,7 +143,7 @@ namespace umbraco.cms.businesslogic.web
return GetDomains(false);
}
internal static IEnumerable<Domain> GetDomains(bool includeWildcards)
public static IEnumerable<Domain> GetDomains(bool includeWildcards)
{
var domains = ApplicationContext.Current.ApplicationCache.GetCacheItem(
CacheKeys.DomainCacheKey,
@@ -191,6 +191,11 @@ namespace umbraco.cms.businesslogic.web
return GetDomains().Where(d => d._root == nodeId).ToArray();
}
public static Domain[] GetDomainsById(int nodeId, bool includeWildcards)
{
return GetDomains(includeWildcards).Where(d => d._root == nodeId).ToArray();
}
public static bool Exists(string DomainName)
{
return GetDomain(DomainName) != null;

View File

@@ -59,7 +59,7 @@ namespace umbraco.editorControls
{
foreach (object key in _prevalues.Keys)
{
this.Items.Add(new ListItem(dropdown.DictionaryReplace(_prevalues[key].ToString()), key.ToString()));
this.Items.Add(new ListItem(Dictionary.ReplaceKey(_prevalues[key].ToString()), key.ToString()));
}
}
@@ -67,7 +67,7 @@ namespace umbraco.editorControls
{
foreach (KeyValuePair<int, String> item in Prevalues)
{
this.Items.Add(new ListItem(dropdown.DictionaryReplace(item.Value), item.Key.ToString()));
this.Items.Add(new ListItem(Dictionary.ReplaceKey(item.Value), item.Key.ToString()));
}
}
@@ -76,26 +76,5 @@ namespace umbraco.editorControls
if (_data != null && _data.Value != null)
this.SelectedValue = _data.Value.ToString();
}
static string DictionaryReplace(string text)
{
if (!text.StartsWith("#"))
return text;
else
{
Language lang = Language.GetByCultureCode(System.Threading.Thread.CurrentThread.CurrentCulture.Name);
if (lang != null)
{
if (Dictionary.DictionaryItem.hasKey(text.Substring(1, text.Length - 1)))
{
Dictionary.DictionaryItem di = new Dictionary.DictionaryItem(text.Substring(1, text.Length - 1));
return di.Value(lang.id);
}
}
return "[" + text + "]";
}
}
}
}