Refactor - IPublishedContent, converters, fragments
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using Umbraco.Core.Models;
|
||||
using System.Web;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Core.Dynamics
|
||||
{
|
||||
@@ -32,7 +33,7 @@ namespace Umbraco.Core.Dynamics
|
||||
internal PropertyResultType PropertyType { get { return _type; } }
|
||||
|
||||
public string PropertyTypeAlias { get { return _source == null ? _alias : _source.PropertyTypeAlias; } }
|
||||
public object DataValue { get { return _source == null ? _value : _source.DataValue; } }
|
||||
public object SourceValue { get { return _source == null ? _value : _source.SourceValue; } }
|
||||
public bool HasValue { get { return _source == null || _source.HasValue; } }
|
||||
public object Value { get { return _source == null ? _value : _source.Value; } }
|
||||
public object XPathValue { get { return Value == null ? null : Value.ToString(); } }
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
namespace Umbraco.Core.Models.PublishedContent
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a cached content.
|
||||
@@ -14,21 +13,11 @@ namespace Umbraco.Core.Models
|
||||
/// cached preview (so, maybe unpublished) content. A better name would therefore be ICachedContent, as
|
||||
/// has been suggested. However, can't change now. Maybe in v7?</para>
|
||||
/// </remarks>
|
||||
public interface IPublishedContent
|
||||
public interface IPublishedContent : IPublishedFragment
|
||||
{
|
||||
#region ContentType
|
||||
|
||||
/// <summary>
|
||||
/// Gets the content type.
|
||||
/// </summary>
|
||||
PublishedContentType ContentType { get; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Content
|
||||
|
||||
int Id { get; }
|
||||
Guid Key { get; }
|
||||
int TemplateId { get; }
|
||||
int SortOrder { get; }
|
||||
string Name { get; }
|
||||
@@ -78,29 +67,6 @@ namespace Umbraco.Core.Models
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets the properties of the content.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>Contains one <c>IPublishedProperty</c> for each property defined for the content type, including
|
||||
/// inherited properties. Some properties may have no value.</para>
|
||||
/// <para>The properties collection of an IPublishedContent instance should be read-only ie it is illegal
|
||||
/// to add properties to the collection.</para>
|
||||
/// </remarks>
|
||||
ICollection<IPublishedProperty> Properties { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a property identified by its alias.
|
||||
/// </summary>
|
||||
/// <param name="alias">The property alias.</param>
|
||||
/// <returns>The property identified by the alias.</returns>
|
||||
/// <remarks>
|
||||
/// <para>If the content type has no property with that alias, including inherited properties, returns <c>null</c>,</para>
|
||||
/// <para>otherwise return a property -- that may have no value (ie <c>HasValue</c> is <c>false</c>).</para>
|
||||
/// <para>The alias is case-insensitive.</para>
|
||||
/// </remarks>
|
||||
IPublishedProperty GetProperty(string alias);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a property identified by its alias.
|
||||
/// </summary>
|
||||
@@ -115,21 +81,6 @@ namespace Umbraco.Core.Models
|
||||
/// </remarks>
|
||||
IPublishedProperty GetProperty(string alias, bool recurse);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of a property identified by its alias.
|
||||
/// </summary>
|
||||
/// <param name="alias">The property alias.</param>
|
||||
/// <returns>The value of the property identified by the alias.</returns>
|
||||
/// <remarks>
|
||||
/// <para>If <c>GetProperty(alias)</c> is <c>null</c> then returns <c>null</c> else return <c>GetProperty(alias).Value</c>.</para>
|
||||
/// <para>So if the property has no value, returns the default value for that property type.</para>
|
||||
/// <para>This one is defined here really because we cannot define index extension methods, but all it should do is:
|
||||
/// <code>var p = GetProperty(alias); return p == null ? null : p.Value;</code> and nothing else.</para>
|
||||
/// <para>The recursive syntax (eg "_title") is _not_ supported here.</para>
|
||||
/// <para>The alias is case-insensitive.</para>
|
||||
/// </remarks>
|
||||
object this[string alias] { get; } // todo - should obsolete this[alias] (when?)
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Umbraco.Core.Models.PublishedContent
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a facade fragment.
|
||||
/// </summary>
|
||||
public interface IPublishedFragment
|
||||
{
|
||||
#region ContentType
|
||||
|
||||
/// <summary>
|
||||
/// Gets the content type.
|
||||
/// </summary>
|
||||
PublishedContentType ContentType { get; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Content
|
||||
|
||||
/// <summary>
|
||||
/// Gets the unique key of the facade item.
|
||||
/// </summary>
|
||||
Guid Key { get; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets the properties of the content.
|
||||
/// </summary>
|
||||
/// <remarks>Contains one <c>IPublishedProperty</c> for each property defined for the content type, including
|
||||
/// inherited properties. Some properties may have no value.</remarks>
|
||||
IEnumerable<IPublishedProperty> Properties { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a property identified by its alias.
|
||||
/// </summary>
|
||||
/// <param name="alias">The property alias.</param>
|
||||
/// <returns>The property identified by the alias.</returns>
|
||||
/// <remarks>
|
||||
/// <para>If the content type has no property with that alias, including inherited properties, returns <c>null</c>,</para>
|
||||
/// <para>otherwise return a property -- that may have no value (ie <c>HasValue</c> is <c>false</c>).</para>
|
||||
/// <para>The alias is case-insensitive.</para>
|
||||
/// </remarks>
|
||||
IPublishedProperty GetProperty(string alias);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Umbraco.Core.Models
|
||||
namespace Umbraco.Core.Models.PublishedContent
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a property of an <c>IPublishedContent</c>.
|
||||
@@ -24,18 +24,18 @@ namespace Umbraco.Core.Models
|
||||
bool HasValue { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the data value of the property.
|
||||
/// Gets the source value of the property.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>The data value is whatever was passed to the property when it was instanciated, and it is
|
||||
/// <para>The source value is whatever was passed to the property when it was instanciated, and it is
|
||||
/// somewhat implementation-dependent -- depending on how the IPublishedCache is implemented.</para>
|
||||
/// <para>The XmlPublishedCache raw values are strings exclusively since they come from the Xml cache.</para>
|
||||
/// <para>For other caches that get their raw value from the database, it would be either a string,
|
||||
/// an integer (Int32), or a date and time (DateTime).</para>
|
||||
/// <para>The XmlPublishedCache source values are strings exclusively since they come from the Xml cache.</para>
|
||||
/// <para>For other caches that get their source value from the database, it would be either a string,
|
||||
/// an integer (Int32), a date and time (DateTime) or a decimal (double).</para>
|
||||
/// <para>If you're using that value, you're probably wrong, unless you're doing some internal
|
||||
/// Umbraco stuff.</para>
|
||||
/// </remarks>
|
||||
object DataValue { get; }
|
||||
object SourceValue { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the object value of the property.
|
||||
@@ -87,10 +87,7 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
_properties.Add(property);
|
||||
}
|
||||
|
||||
bool IPublishedContentExtended.HasAddedProperties
|
||||
{
|
||||
get { return _properties != null; }
|
||||
}
|
||||
bool IPublishedContentExtended.HasAddedProperties => _properties != null;
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -98,28 +95,9 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
|
||||
private ICollection<IPublishedProperty> _properties;
|
||||
|
||||
public override ICollection<IPublishedProperty> Properties
|
||||
{
|
||||
get
|
||||
{
|
||||
return _properties == null
|
||||
public override IEnumerable<IPublishedProperty> Properties => _properties == null
|
||||
? Content.Properties
|
||||
: Content.Properties.Union(_properties).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
public override object this[string alias]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_properties != null)
|
||||
{
|
||||
var property = _properties.FirstOrDefault(prop => prop.PropertyTypeAlias.InvariantEquals(alias));
|
||||
if (property != null) return property.HasValue ? property.Value : null;
|
||||
}
|
||||
return Content[alias];
|
||||
}
|
||||
}
|
||||
|
||||
public override IPublishedProperty GetProperty(string alias)
|
||||
{
|
||||
|
||||
@@ -70,7 +70,7 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
InitializeIndexes();
|
||||
}
|
||||
|
||||
// create detached content type - ie does not match anything in the DB
|
||||
// create floating content type - ie does not match anything in the DB
|
||||
internal PublishedContentType(string alias, IEnumerable<string> compositionAliases, IEnumerable<PublishedPropertyType> propertyTypes)
|
||||
: this(0, alias, compositionAliases, propertyTypes)
|
||||
{ }
|
||||
|
||||
@@ -108,9 +108,7 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
|
||||
#region Properties
|
||||
|
||||
public virtual ICollection<IPublishedProperty> Properties => Content.Properties;
|
||||
|
||||
public virtual object this[string alias] => Content[alias];
|
||||
public virtual IEnumerable<IPublishedProperty> Properties => Content.Properties;
|
||||
|
||||
public virtual IPublishedProperty GetProperty(string alias)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Umbraco.Core.Models
|
||||
namespace Umbraco.Core.Models.PublishedContent
|
||||
{
|
||||
/// <summary>
|
||||
/// The type of published content, ie whether it is a content or a media.
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
|
||||
namespace Umbraco.Core.Models.PublishedContent
|
||||
{
|
||||
@@ -8,23 +9,20 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
/// </summary>
|
||||
internal abstract class PublishedPropertyBase : IPublishedProperty
|
||||
{
|
||||
public readonly PublishedPropertyType PropertyType;
|
||||
|
||||
protected PublishedPropertyBase(PublishedPropertyType propertyType)
|
||||
protected PublishedPropertyBase(PublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel)
|
||||
{
|
||||
if (propertyType == null)
|
||||
throw new ArgumentNullException("propertyType");
|
||||
if (propertyType == null) throw new ArgumentNullException(nameof(propertyType));
|
||||
PropertyType = propertyType;
|
||||
ReferenceCacheLevel = referenceCacheLevel;
|
||||
}
|
||||
|
||||
public string PropertyTypeAlias
|
||||
{
|
||||
get { return PropertyType.PropertyTypeAlias; }
|
||||
}
|
||||
public PublishedPropertyType PropertyType { get; }
|
||||
public string PropertyTypeAlias => PropertyType.PropertyTypeAlias;
|
||||
public PropertyCacheLevel ReferenceCacheLevel { get; }
|
||||
|
||||
// these have to be provided by the actual implementation
|
||||
public abstract bool HasValue { get; }
|
||||
public abstract object DataValue { get; }
|
||||
public abstract object SourceValue { get; }
|
||||
public abstract object Value { get; }
|
||||
public abstract object XPathValue { get; }
|
||||
}
|
||||
|
||||
@@ -18,24 +18,6 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
{
|
||||
#region Constructors
|
||||
|
||||
// clone
|
||||
private PublishedPropertyType(PublishedPropertyType orig)
|
||||
{
|
||||
ContentType = orig.ContentType;
|
||||
PropertyTypeAlias = orig.PropertyTypeAlias;
|
||||
DataTypeId = orig.DataTypeId;
|
||||
PropertyEditorAlias = orig.PropertyEditorAlias;
|
||||
_converter = orig._converter;
|
||||
_sourceCacheLevel = orig._sourceCacheLevel;
|
||||
_objectCacheLevel = orig._objectCacheLevel;
|
||||
_xpathCacheLevel = orig._xpathCacheLevel;
|
||||
_clrType = orig._clrType;
|
||||
_initialized = true;
|
||||
|
||||
// do NOT copy the reduced cache levels
|
||||
// as we should NOT clone a nested / detached type
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialize a new instance of the <see cref="PublishedPropertyType"/> class within a <see cref="PublishedContentType"/>,
|
||||
/// with a <see cref="PropertyType"/>.
|
||||
@@ -115,7 +97,6 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
{
|
||||
// ContentType
|
||||
// - in unit tests, to be set by PublishedContentType when creating it
|
||||
// - in detached types, remains null
|
||||
|
||||
PropertyTypeAlias = propertyTypeAlias;
|
||||
|
||||
@@ -161,10 +142,7 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
private readonly object _locker = new object();
|
||||
private volatile bool _initialized;
|
||||
private IPropertyValueConverter _converter;
|
||||
|
||||
private PropertyCacheLevel _sourceCacheLevel;
|
||||
private PropertyCacheLevel _objectCacheLevel;
|
||||
private PropertyCacheLevel _xpathCacheLevel;
|
||||
private PropertyCacheLevel _cacheLevel;
|
||||
|
||||
private Type _clrType = typeof (object);
|
||||
|
||||
@@ -242,129 +220,68 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
|
||||
}
|
||||
|
||||
var converterMeta = _converter as IPropertyValueConverterMeta;
|
||||
_cacheLevel = _converter?.GetPropertyCacheLevel(this) ?? PropertyCacheLevel.Facade;
|
||||
_clrType = _converter?.GetPropertyValueType(this) ?? typeof(object);
|
||||
}
|
||||
|
||||
// get the cache levels, quietely fixing the inconsistencies (no need to throw, really)
|
||||
if (converterMeta != null)
|
||||
// gets the cache level
|
||||
public PropertyCacheLevel CacheLevel
|
||||
{
|
||||
_sourceCacheLevel = converterMeta.GetPropertyCacheLevel(this, PropertyCacheValue.Source);
|
||||
_objectCacheLevel = converterMeta.GetPropertyCacheLevel(this, PropertyCacheValue.Object);
|
||||
_xpathCacheLevel = converterMeta.GetPropertyCacheLevel(this, PropertyCacheValue.XPath);
|
||||
}
|
||||
else
|
||||
get
|
||||
{
|
||||
_sourceCacheLevel = GetCacheLevel(_converter, PropertyCacheValue.Source);
|
||||
_objectCacheLevel = GetCacheLevel(_converter, PropertyCacheValue.Object);
|
||||
_xpathCacheLevel = GetCacheLevel(_converter, PropertyCacheValue.XPath);
|
||||
}
|
||||
if (_objectCacheLevel < _sourceCacheLevel) _objectCacheLevel = _sourceCacheLevel;
|
||||
if (_xpathCacheLevel < _sourceCacheLevel) _xpathCacheLevel = _sourceCacheLevel;
|
||||
|
||||
// get the CLR type of the converted value
|
||||
if (_converter != null)
|
||||
{
|
||||
if (converterMeta != null)
|
||||
{
|
||||
_clrType = converterMeta.GetPropertyValueType(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
var attr = _converter.GetType().GetCustomAttribute<PropertyValueTypeAttribute>(false);
|
||||
if (attr != null)
|
||||
_clrType = attr.Type;
|
||||
}
|
||||
EnsureInitialized();
|
||||
return _cacheLevel;
|
||||
}
|
||||
}
|
||||
|
||||
static PropertyCacheLevel GetCacheLevel(IPropertyValueConverter converter, PropertyCacheValue value)
|
||||
{
|
||||
if (converter == null)
|
||||
return PropertyCacheLevel.Request;
|
||||
|
||||
var attr = converter.GetType().GetCustomAttributes<PropertyValueCacheAttribute>(false)
|
||||
.FirstOrDefault(x => x.Value == value || x.Value == PropertyCacheValue.All);
|
||||
|
||||
return attr?.Level ?? PropertyCacheLevel.Request;
|
||||
}
|
||||
|
||||
// converts the raw value into the source value
|
||||
// converts the source value into the inter value
|
||||
// uses converters, else falls back to dark (& performance-wise expensive) magic
|
||||
// source: the property raw value
|
||||
// source: the property source value
|
||||
// preview: whether we are previewing or not
|
||||
public object ConvertDataToSource(object source, bool preview)
|
||||
public object ConvertSourceToInter(object source, bool preview)
|
||||
{
|
||||
EnsureInitialized();
|
||||
|
||||
// use the converter else use dark (& performance-wise expensive) magic
|
||||
return _converter != null
|
||||
? _converter.ConvertDataToSource(this, source, preview)
|
||||
? _converter.ConvertSourceToInter(this, source, preview)
|
||||
: ConvertUsingDarkMagic(source);
|
||||
}
|
||||
|
||||
// gets the source cache level
|
||||
public PropertyCacheLevel SourceCacheLevel
|
||||
{
|
||||
get
|
||||
{
|
||||
EnsureInitialized();
|
||||
return _sourceCacheLevel;
|
||||
}
|
||||
}
|
||||
|
||||
// converts the source value into the clr value
|
||||
// uses converters, else returns the source value
|
||||
// source: the property source value
|
||||
// converts the inter value into the clr value
|
||||
// uses converters, else returns the inter value
|
||||
// inter: the property inter value
|
||||
// preview: whether we are previewing or not
|
||||
public object ConvertSourceToObject(object source, bool preview)
|
||||
public object ConvertInterToObject(PropertyCacheLevel referenceCacheLevel, object inter, bool preview)
|
||||
{
|
||||
EnsureInitialized();
|
||||
|
||||
// use the converter if any
|
||||
// else just return the source value
|
||||
// else just return the inter value
|
||||
return _converter != null
|
||||
? _converter.ConvertSourceToObject(this, source, preview)
|
||||
: source;
|
||||
? _converter.ConvertInterToObject(this, referenceCacheLevel, inter, preview)
|
||||
: inter;
|
||||
}
|
||||
|
||||
// gets the value cache level
|
||||
public PropertyCacheLevel ObjectCacheLevel
|
||||
{
|
||||
get
|
||||
{
|
||||
EnsureInitialized();
|
||||
return _objectCacheLevel;
|
||||
}
|
||||
}
|
||||
|
||||
// converts the source value into the xpath value
|
||||
// uses the converter else returns the source value as a string
|
||||
// converts the inter value into the xpath value
|
||||
// uses the converter else returns the inter value as a string
|
||||
// if successful, returns either a string or an XPathNavigator
|
||||
// source: the property source value
|
||||
// inter: the property inter value
|
||||
// preview: whether we are previewing or not
|
||||
public object ConvertSourceToXPath(object source, bool preview)
|
||||
public object ConvertInterToXPath(PropertyCacheLevel referenceCacheLevel, object inter, bool preview)
|
||||
{
|
||||
EnsureInitialized();
|
||||
|
||||
// use the converter if any
|
||||
if (_converter != null)
|
||||
return _converter.ConvertSourceToXPath(this, source, preview);
|
||||
return _converter.ConvertInterToXPath(this, referenceCacheLevel, inter, preview);
|
||||
|
||||
// else just return the source value as a string or an XPathNavigator
|
||||
if (source == null) return null;
|
||||
var xElement = source as XElement;
|
||||
// else just return the inter value as a string or an XPathNavigator
|
||||
if (inter == null) return null;
|
||||
var xElement = inter as XElement;
|
||||
if (xElement != null)
|
||||
return xElement.CreateNavigator();
|
||||
return source.ToString().Trim();
|
||||
}
|
||||
|
||||
// gets the xpath cache level
|
||||
public PropertyCacheLevel XPathCacheLevel
|
||||
{
|
||||
get
|
||||
{
|
||||
EnsureInitialized();
|
||||
return _xpathCacheLevel;
|
||||
}
|
||||
return inter.ToString().Trim();
|
||||
}
|
||||
|
||||
internal static object ConvertUsingDarkMagic(object source)
|
||||
@@ -409,128 +326,5 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Detached
|
||||
|
||||
private PropertyCacheLevel _sourceCacheLevelReduced = 0;
|
||||
private PropertyCacheLevel _objectCacheLevelReduced = 0;
|
||||
private PropertyCacheLevel _xpathCacheLevelReduced = 0;
|
||||
|
||||
internal bool IsDetachedOrNested => _sourceCacheLevelReduced != 0;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a detached clone of this published property type.
|
||||
/// </summary>
|
||||
/// <returns>A detached clone of this published property type.</returns>
|
||||
/// <remarks>
|
||||
/// <para>Only a published property type that has not already been detached or nested, can be detached.</para>
|
||||
/// <para>Use detached published property type when creating detached properties outside of a published content.</para>
|
||||
/// </remarks>
|
||||
internal PublishedPropertyType Detached()
|
||||
{
|
||||
// verify
|
||||
if (IsDetachedOrNested)
|
||||
throw new Exception("PublishedPropertyType is already detached/nested.");
|
||||
|
||||
var detached = new PublishedPropertyType(this);
|
||||
detached._sourceCacheLevel
|
||||
= detached._objectCacheLevel
|
||||
= detached._xpathCacheLevel
|
||||
= PropertyCacheLevel.Content;
|
||||
// set to none to a) indicate it's detached / nested and b) make sure any nested
|
||||
// types switch all their cache to .Content
|
||||
detached._sourceCacheLevelReduced
|
||||
= detached._objectCacheLevelReduced
|
||||
= detached._xpathCacheLevelReduced
|
||||
= PropertyCacheLevel.None;
|
||||
|
||||
return detached;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a nested clone of this published property type within a specified container published property type.
|
||||
/// </summary>
|
||||
/// <param name="containerType">The container published property type.</param>
|
||||
/// <returns>A nested clone of this published property type</returns>
|
||||
/// <remarks>
|
||||
/// <para>Only a published property type that has not already been detached or nested, can be nested.</para>
|
||||
/// <para>Use nested published property type when creating detached properties within a published content.</para>
|
||||
/// </remarks>
|
||||
internal PublishedPropertyType Nested(PublishedPropertyType containerType)
|
||||
{
|
||||
// verify
|
||||
if (IsDetachedOrNested)
|
||||
throw new Exception("PublishedPropertyType is already detached/nested.");
|
||||
|
||||
var nested = new PublishedPropertyType(this);
|
||||
|
||||
// before we reduce, both xpath and object are >= source, and
|
||||
// the way reduce works, the relative order of resulting xpath, object and source are preserved
|
||||
|
||||
// Reduce() will set _xxxCacheLevelReduced thus indicating that the type is detached / nested
|
||||
|
||||
Reduce(_sourceCacheLevel, _sourceCacheLevelReduced, ref nested._sourceCacheLevel, ref nested._sourceCacheLevelReduced);
|
||||
Reduce(_objectCacheLevel, _objectCacheLevelReduced, ref nested._objectCacheLevel, ref nested._objectCacheLevelReduced);
|
||||
Reduce(_xpathCacheLevel, _xpathCacheLevelReduced, ref nested._xpathCacheLevel, ref nested._xpathCacheLevelReduced);
|
||||
|
||||
return nested;
|
||||
}
|
||||
|
||||
private static void Reduce(
|
||||
PropertyCacheLevel containerCacheLevel, PropertyCacheLevel containerCacheLevelReduced,
|
||||
ref PropertyCacheLevel nestedCacheLevel, ref PropertyCacheLevel nestedCacheLevelReduced)
|
||||
{
|
||||
// initialize if required
|
||||
if (containerCacheLevelReduced == 0)
|
||||
containerCacheLevelReduced = containerCacheLevel;
|
||||
|
||||
switch (containerCacheLevelReduced)
|
||||
{
|
||||
case PropertyCacheLevel.None:
|
||||
// once .None, force .Content for everything
|
||||
nestedCacheLevel = PropertyCacheLevel.Content;
|
||||
nestedCacheLevelReduced = PropertyCacheLevel.None; // and propagate
|
||||
break;
|
||||
|
||||
case PropertyCacheLevel.Request:
|
||||
// once .Request, force .Content for everything
|
||||
nestedCacheLevel = PropertyCacheLevel.Content;
|
||||
nestedCacheLevelReduced = PropertyCacheLevel.Request; // and propagate
|
||||
break;
|
||||
|
||||
case PropertyCacheLevel.Content:
|
||||
// as long as .Content, accept anything
|
||||
nestedCacheLevelReduced = nestedCacheLevel; // and it becomes the nested reduced
|
||||
break;
|
||||
|
||||
case PropertyCacheLevel.ContentCache:
|
||||
// once .ContentCache, accept .Request and .Content but not .ContentCache
|
||||
switch (nestedCacheLevel)
|
||||
{
|
||||
case PropertyCacheLevel.Request:
|
||||
case PropertyCacheLevel.None:
|
||||
// accept
|
||||
nestedCacheLevelReduced = nestedCacheLevel; // and it becomes the nested reduced
|
||||
break;
|
||||
case PropertyCacheLevel.Content:
|
||||
// accept
|
||||
nestedCacheLevelReduced = PropertyCacheLevel.ContentCache; // and propagate
|
||||
break;
|
||||
case PropertyCacheLevel.ContentCache:
|
||||
// force .Content
|
||||
nestedCacheLevel = PropertyCacheLevel.Content;
|
||||
nestedCacheLevelReduced = PropertyCacheLevel.ContentCache; // and propagate
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Unsupported PropertyCacheLevel value.");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Exception("Unsupported PropertyCacheLevel value.");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using System;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Core.PropertyEditors
|
||||
{
|
||||
@@ -14,6 +15,20 @@ namespace Umbraco.Core.PropertyEditors
|
||||
/// <returns>A value indicating whether the converter supports a property type.</returns>
|
||||
bool IsConverter(PublishedPropertyType propertyType);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type of values returned by the converter.
|
||||
/// </summary>
|
||||
/// <param name="propertyType">The property type.</param>
|
||||
/// <returns>The CLR type of values returned by the converter.</returns>
|
||||
Type GetPropertyValueType(PublishedPropertyType propertyType);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the property cache level of a specified value.
|
||||
/// </summary>
|
||||
/// <param name="propertyType">The property type.</param>
|
||||
/// <returns>The property cache level of the specified value.</returns>
|
||||
PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType);
|
||||
|
||||
/// <summary>
|
||||
/// Converts a property Data value to a Source value.
|
||||
/// </summary>
|
||||
@@ -32,25 +47,27 @@ namespace Umbraco.Core.PropertyEditors
|
||||
/// strings, and xml-whitespace strings appropriately, ie it should know whether to preserve
|
||||
/// whitespaces.</para>
|
||||
/// </remarks>
|
||||
object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview);
|
||||
object ConvertSourceToInter(PublishedPropertyType propertyType, object source, bool preview);
|
||||
|
||||
/// <summary>
|
||||
/// Converts a property Source value to an Object value.
|
||||
/// </summary>
|
||||
/// <param name="propertyType">The property type.</param>
|
||||
/// <param name="source">The source value.</param>
|
||||
/// <param name="referenceCacheLevel">fixme</param>
|
||||
/// <param name="inter">The source value.</param>
|
||||
/// <param name="preview">A value indicating whether conversion should take place in preview mode.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
/// <remarks>The converter should know how to convert a <c>null</c> source value, or any source value
|
||||
/// indicating that no value has been assigned to the property. It is up to the converter to determine
|
||||
/// what to return in that case: either <c>null</c>, or the default value...</remarks>
|
||||
object ConvertSourceToObject(PublishedPropertyType propertyType, object source, bool preview);
|
||||
object ConvertInterToObject(PublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview);
|
||||
|
||||
/// <summary>
|
||||
/// Converts a property Source value to an XPath value.
|
||||
/// </summary>
|
||||
/// <param name="propertyType">The property type.</param>
|
||||
/// <param name="source">The source value.</param>
|
||||
/// <param name="referenceCacheLevel">fixme</param>
|
||||
/// <param name="inter">The source value.</param>
|
||||
/// <param name="preview">A value indicating whether conversion should take place in preview mode.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
/// <remarks>
|
||||
@@ -63,6 +80,6 @@ namespace Umbraco.Core.PropertyEditors
|
||||
/// <para>The converter may want to return an XML fragment that represent a part of the content tree,
|
||||
/// but should pay attention not to create infinite loops that would kill XPath and XSLT.</para>
|
||||
/// </remarks>
|
||||
object ConvertSourceToXPath(PublishedPropertyType propertyType, object source, bool preview);
|
||||
object ConvertInterToXPath(PublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Core.PropertyEditors
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides published content properties converter meta data.
|
||||
/// </summary>
|
||||
public interface IPropertyValueConverterMeta : IPropertyValueConverter
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the type of values returned by the converter.
|
||||
/// </summary>
|
||||
/// <param name="propertyType">The property type.</param>
|
||||
/// <returns>The CLR type of values returned by the converter.</returns>
|
||||
Type GetPropertyValueType(PublishedPropertyType propertyType);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the property cache level of a specified value.
|
||||
/// </summary>
|
||||
/// <param name="propertyType">The property type.</param>
|
||||
/// <param name="cacheValue">The property value.</param>
|
||||
/// <returns>The property cache level of the specified value.</returns>
|
||||
PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType, PropertyCacheValue cacheValue);
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,11 @@
|
||||
// object level >= source level
|
||||
// xpath level >= source level
|
||||
|
||||
/// <summary>
|
||||
/// Default value.
|
||||
/// </summary>
|
||||
Unknown = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the property value can be cached at the content level, ie it can be
|
||||
/// cached until the content itself is modified.
|
||||
@@ -17,16 +22,16 @@
|
||||
Content = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the property value can be cached at the content cache level, ie it can
|
||||
/// Indicates that the property value can be cached at the snapshot level, ie it can
|
||||
/// be cached until any content in the cache is modified.
|
||||
/// </summary>
|
||||
ContentCache = 2,
|
||||
Snapshot = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the property value can be cached at the request level, ie it can be
|
||||
/// cached for the duration of the current request.
|
||||
/// Indicates that the property value can be cached at the facade level, ie it can be
|
||||
/// cached for the duration of the current facade (ie, in most cases, request).
|
||||
/// </summary>
|
||||
Request = 3,
|
||||
Facade = 3,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the property value cannot be cached and has to be converted any time
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
namespace Umbraco.Core.PropertyEditors
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies the different types of property cacheable values.
|
||||
/// </summary>
|
||||
public enum PropertyCacheValue
|
||||
{
|
||||
/// <summary>
|
||||
/// All of them.
|
||||
/// </summary>
|
||||
All,
|
||||
|
||||
/// <summary>
|
||||
/// The source value ie the internal value that can be used to create both the
|
||||
/// object value and the xpath value.
|
||||
/// </summary>
|
||||
Source,
|
||||
|
||||
/// <summary>
|
||||
/// The object value ie the strongly typed value of the property as seen when accessing content via C#.
|
||||
/// </summary>
|
||||
Object,
|
||||
|
||||
/// <summary>
|
||||
/// The XPath value ie the value of the property as seen when accessing content via XPath.
|
||||
/// </summary>
|
||||
XPath
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
using System;
|
||||
using log4net.Core;
|
||||
|
||||
namespace Umbraco.Core.PropertyEditors
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates the cache level for a property cacheable value.
|
||||
/// </summary>
|
||||
/// <remarks>Use this attribute to mark property values converters.</remarks>
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
|
||||
public class PropertyValueCacheAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PropertyValueCacheAttribute"/> class with a cacheable value and a cache level.
|
||||
/// </summary>
|
||||
/// <param name="value">The cacheable value.</param>
|
||||
/// <param name="level">The cache level.</param>
|
||||
public PropertyValueCacheAttribute(PropertyCacheValue value, PropertyCacheLevel level)
|
||||
{
|
||||
Value = value;
|
||||
Level = level;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the cacheable value.
|
||||
/// </summary>
|
||||
public PropertyCacheValue Value { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the cache level;
|
||||
/// </summary>
|
||||
public PropertyCacheLevel Level { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using System;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Core.PropertyEditors
|
||||
{
|
||||
@@ -12,19 +13,29 @@ namespace Umbraco.Core.PropertyEditors
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
|
||||
public virtual Type GetPropertyValueType(PublishedPropertyType propertyType)
|
||||
{
|
||||
return typeof (object);
|
||||
}
|
||||
|
||||
public virtual PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType)
|
||||
{
|
||||
return PropertyCacheLevel.Facade;
|
||||
}
|
||||
|
||||
public virtual object ConvertSourceToInter(PublishedPropertyType propertyType, object source, bool preview)
|
||||
{
|
||||
return PublishedPropertyType.ConvertUsingDarkMagic(source);
|
||||
}
|
||||
|
||||
public virtual object ConvertSourceToObject(PublishedPropertyType propertyType, object source, bool preview)
|
||||
public virtual object ConvertInterToObject(PublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview)
|
||||
{
|
||||
return source;
|
||||
return inter;
|
||||
}
|
||||
|
||||
public virtual object ConvertSourceToXPath(PublishedPropertyType propertyType, object source, bool preview)
|
||||
public virtual object ConvertInterToXPath(PublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview)
|
||||
{
|
||||
return source?.ToString() ?? string.Empty;
|
||||
return inter?.ToString() ?? string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.PropertyEditors
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates the CLR type of property object values returned by a converter.
|
||||
/// </summary>
|
||||
/// <remarks>Use this attribute to mark property values converters.</remarks>
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
|
||||
public class PropertyValueTypeAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PropertyValueTypeAttribute"/> class with a type.
|
||||
/// </summary>
|
||||
/// <param name="type">The type.</param>
|
||||
public PropertyValueTypeAttribute(Type type)
|
||||
{
|
||||
Type = type;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the type.
|
||||
/// </summary>
|
||||
public Type Type { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
return propertyType.PropertyEditorAlias.InvariantEquals(Constants.PropertyEditors.ColorPickerAlias);
|
||||
}
|
||||
|
||||
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
|
||||
public override object ConvertSourceToInter(PublishedPropertyType propertyType, object source, bool preview)
|
||||
{
|
||||
// make sure it's a string
|
||||
return source?.ToString() ?? string.Empty;
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
{
|
||||
[PropertyValueType(typeof(DateTime))]
|
||||
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
|
||||
public class DatePickerValueConverter : PropertyValueConverterBase
|
||||
{
|
||||
private static readonly string[] PropertyEditorAliases =
|
||||
@@ -21,7 +18,17 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
return PropertyEditorAliases.Contains(propertyType.PropertyEditorAlias);
|
||||
}
|
||||
|
||||
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
|
||||
public override Type GetPropertyValueType(PublishedPropertyType propertyType)
|
||||
{
|
||||
return typeof (DateTime);
|
||||
}
|
||||
|
||||
public override PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType)
|
||||
{
|
||||
return PropertyCacheLevel.Content;
|
||||
}
|
||||
|
||||
public override object ConvertSourceToInter(PublishedPropertyType propertyType, object source, bool preview)
|
||||
{
|
||||
if (source == null) return DateTime.MinValue;
|
||||
|
||||
@@ -45,10 +52,10 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
|
||||
// default ConvertSourceToObject just returns source ie a DateTime value
|
||||
|
||||
public override object ConvertSourceToXPath(PublishedPropertyType propertyType, object source, bool preview)
|
||||
public override object ConvertInterToXPath(PublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview)
|
||||
{
|
||||
// source should come from ConvertSource and be a DateTime already
|
||||
return XmlConvert.ToString((DateTime)source, XmlDateTimeSerializationMode.Unspecified);
|
||||
return XmlConvert.ToString((DateTime)inter, XmlDateTimeSerializationMode.Unspecified);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,9 @@
|
||||
using System.Globalization;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
{
|
||||
[PropertyValueType(typeof(decimal))]
|
||||
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
|
||||
public class DecimalValueConverter : PropertyValueConverterBase
|
||||
{
|
||||
public override bool IsConverter(PublishedPropertyType propertyType)
|
||||
@@ -12,7 +11,17 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
return Constants.PropertyEditors.DecimalAlias.Equals(propertyType.PropertyEditorAlias);
|
||||
}
|
||||
|
||||
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
|
||||
public override Type GetPropertyValueType(PublishedPropertyType propertyType)
|
||||
{
|
||||
return typeof (decimal);
|
||||
}
|
||||
|
||||
public override PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType)
|
||||
{
|
||||
return PropertyCacheLevel.Content;
|
||||
}
|
||||
|
||||
public override object ConvertSourceToInter(PublishedPropertyType propertyType, object source, bool preview)
|
||||
{
|
||||
if (source == null) return 0M;
|
||||
|
||||
|
||||
@@ -16,8 +16,6 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
/// This ensures that the grid config is merged in with the front-end value
|
||||
/// </summary>
|
||||
[DefaultPropertyValueConverter(typeof(JsonValueConverter))] //this shadows the JsonValueConverter
|
||||
[PropertyValueType(typeof(JToken))]
|
||||
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
|
||||
public class GridValueConverter : JsonValueConverter
|
||||
{
|
||||
public override bool IsConverter(PublishedPropertyType propertyType)
|
||||
@@ -25,7 +23,17 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
return propertyType.PropertyEditorAlias.InvariantEquals(Constants.PropertyEditors.GridAlias);
|
||||
}
|
||||
|
||||
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
|
||||
public override Type GetPropertyValueType(PublishedPropertyType propertyType)
|
||||
{
|
||||
return typeof (JToken);
|
||||
}
|
||||
|
||||
public override PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType)
|
||||
{
|
||||
return PropertyCacheLevel.Content;
|
||||
}
|
||||
|
||||
public override object ConvertSourceToInter(PublishedPropertyType propertyType, object source, bool preview)
|
||||
{
|
||||
if (source == null) return null;
|
||||
var sourceString = source.ToString();
|
||||
|
||||
@@ -13,12 +13,25 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
/// This ensures that the cropper config (pre-values/crops) are merged in with the front-end value.
|
||||
/// </summary>
|
||||
[DefaultPropertyValueConverter(typeof (JsonValueConverter))] //this shadows the JsonValueConverter
|
||||
[PropertyValueType(typeof (JToken))]
|
||||
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
|
||||
public class ImageCropperValueConverter : JsonValueConverter
|
||||
{
|
||||
private readonly IDataTypeService _dataTypeService;
|
||||
|
||||
public override bool IsConverter(PublishedPropertyType propertyType)
|
||||
{
|
||||
return propertyType.PropertyEditorAlias.InvariantEquals(Constants.PropertyEditors.ImageCropperAlias);
|
||||
}
|
||||
|
||||
public override Type GetPropertyValueType(PublishedPropertyType propertyType)
|
||||
{
|
||||
return typeof (JToken);
|
||||
}
|
||||
|
||||
public override PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType)
|
||||
{
|
||||
return PropertyCacheLevel.Content;
|
||||
}
|
||||
|
||||
public ImageCropperValueConverter()
|
||||
{
|
||||
_dataTypeService = ApplicationContext.Current.Services.DataTypeService;
|
||||
@@ -30,11 +43,6 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
_dataTypeService = dataTypeService;
|
||||
}
|
||||
|
||||
public override bool IsConverter(PublishedPropertyType propertyType)
|
||||
{
|
||||
return propertyType.PropertyEditorAlias.InvariantEquals(Constants.PropertyEditors.ImageCropperAlias);
|
||||
}
|
||||
|
||||
internal static void MergePreValues(JObject currentValue, IDataTypeService dataTypeService, int dataTypeId)
|
||||
{
|
||||
//need to lookup the pre-values for this data type
|
||||
@@ -91,7 +99,7 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
}
|
||||
}
|
||||
|
||||
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
|
||||
public override object ConvertSourceToInter(PublishedPropertyType propertyType, object source, bool preview)
|
||||
{
|
||||
if (source == null) return null;
|
||||
var sourceString = source.ToString();
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using System;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
{
|
||||
[PropertyValueType(typeof(int))]
|
||||
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
|
||||
public class IntegerValueConverter : PropertyValueConverterBase
|
||||
{
|
||||
public override bool IsConverter(PublishedPropertyType propertyType)
|
||||
@@ -11,7 +10,17 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
return Constants.PropertyEditors.IntegerAlias.Equals(propertyType.PropertyEditorAlias);
|
||||
}
|
||||
|
||||
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
|
||||
public override Type GetPropertyValueType(PublishedPropertyType propertyType)
|
||||
{
|
||||
return typeof (int);
|
||||
}
|
||||
|
||||
public override PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType)
|
||||
{
|
||||
return PropertyCacheLevel.Content;
|
||||
}
|
||||
|
||||
public override object ConvertSourceToInter(PublishedPropertyType propertyType, object source, bool preview)
|
||||
{
|
||||
if (source == null) return 0;
|
||||
|
||||
|
||||
@@ -13,8 +13,6 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
/// Since this is a default (umbraco) converter it will be ignored if another converter found conflicts with this one.
|
||||
/// </remarks>
|
||||
[DefaultPropertyValueConverter]
|
||||
[PropertyValueType(typeof(JToken))]
|
||||
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
|
||||
public class JsonValueConverter : PropertyValueConverterBase
|
||||
{
|
||||
/// <summary>
|
||||
@@ -29,7 +27,17 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
return propertyEditor.ValueEditor.ValueType.InvariantEquals(PropertyEditorValueTypes.Json);
|
||||
}
|
||||
|
||||
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
|
||||
public override Type GetPropertyValueType(PublishedPropertyType propertyType)
|
||||
{
|
||||
return typeof (JToken);
|
||||
}
|
||||
|
||||
public override PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType)
|
||||
{
|
||||
return PropertyCacheLevel.Content;
|
||||
}
|
||||
|
||||
public override object ConvertSourceToInter(PublishedPropertyType propertyType, object source, bool preview)
|
||||
{
|
||||
if (source == null) return null;
|
||||
var sourceString = source.ToString();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using System;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
{
|
||||
@@ -12,15 +13,24 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
/// Example: http://issues.umbraco.org/issue/U4-7929
|
||||
/// </remarks>
|
||||
[DefaultPropertyValueConverter]
|
||||
[PropertyValueType(typeof (string))]
|
||||
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
|
||||
public class LabelValueConverter : PropertyValueConverterBase
|
||||
{
|
||||
public override bool IsConverter(PublishedPropertyType propertyType)
|
||||
{
|
||||
return Constants.PropertyEditors.NoEditAlias.Equals(propertyType.PropertyEditorAlias);
|
||||
}
|
||||
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
|
||||
|
||||
public override Type GetPropertyValueType(PublishedPropertyType propertyType)
|
||||
{
|
||||
return typeof (string);
|
||||
}
|
||||
|
||||
public override PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType)
|
||||
{
|
||||
return PropertyCacheLevel.Content;
|
||||
}
|
||||
|
||||
public override object ConvertSourceToInter(PublishedPropertyType propertyType, object source, bool preview)
|
||||
{
|
||||
return source == null ? string.Empty : source.ToString();
|
||||
}
|
||||
|
||||
@@ -4,8 +4,6 @@ using Umbraco.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
{
|
||||
[PropertyValueType(typeof(IHtmlString))]
|
||||
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
|
||||
public class MarkdownEditorValueConverter : PropertyValueConverterBase
|
||||
{
|
||||
public override bool IsConverter(PublishedPropertyType propertyType)
|
||||
@@ -13,7 +11,18 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
return Constants.PropertyEditors.MarkdownEditorAlias.Equals(propertyType.PropertyEditorAlias);
|
||||
}
|
||||
|
||||
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
|
||||
public override Type GetPropertyValueType(PublishedPropertyType propertyType)
|
||||
{
|
||||
return typeof (IHtmlString);
|
||||
}
|
||||
|
||||
public override PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType)
|
||||
{
|
||||
// PropertyCacheLevel.Content is ok here because that converter does not parse {locallink} nor executes macros
|
||||
return PropertyCacheLevel.Content;
|
||||
}
|
||||
|
||||
public override object ConvertSourceToInter(PublishedPropertyType propertyType, object source, bool preview)
|
||||
{
|
||||
// in xml a string is: string
|
||||
// in the database a string is: string
|
||||
@@ -21,16 +30,16 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
return source;
|
||||
}
|
||||
|
||||
public override object ConvertSourceToObject(PublishedPropertyType propertyType, object source, bool preview)
|
||||
public override object ConvertInterToObject(PublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview)
|
||||
{
|
||||
// source should come from ConvertSource and be a string (or null) already
|
||||
return new HtmlString(source == null ? string.Empty : (string)source);
|
||||
return new HtmlString(inter == null ? string.Empty : (string) inter);
|
||||
}
|
||||
|
||||
public override object ConvertSourceToXPath(PublishedPropertyType propertyType, object source, bool preview)
|
||||
public override object ConvertInterToXPath(PublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview)
|
||||
{
|
||||
// source should come from ConvertSource and be a string (or null) already
|
||||
return source;
|
||||
return inter?.ToString() ?? string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
{
|
||||
[PropertyValueType(typeof(IEnumerable<string>))]
|
||||
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
|
||||
public class MultipleTextStringValueConverter : PropertyValueConverterBase
|
||||
{
|
||||
public override bool IsConverter(PublishedPropertyType propertyType)
|
||||
@@ -17,7 +13,17 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
return Constants.PropertyEditors.MultipleTextstringAlias.Equals(propertyType.PropertyEditorAlias);
|
||||
}
|
||||
|
||||
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
|
||||
public override Type GetPropertyValueType(PublishedPropertyType propertyType)
|
||||
{
|
||||
return typeof (IEnumerable<string>);
|
||||
}
|
||||
|
||||
public override PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType)
|
||||
{
|
||||
return PropertyCacheLevel.Content;
|
||||
}
|
||||
|
||||
public override object ConvertSourceToInter(PublishedPropertyType propertyType, object source, bool preview)
|
||||
{
|
||||
// data is (both in database and xml):
|
||||
// <keyFeatureList>
|
||||
@@ -58,13 +64,13 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
return values.ToArray();
|
||||
}
|
||||
|
||||
public override object ConvertSourceToXPath(PublishedPropertyType propertyType, object source, bool preview)
|
||||
public override object ConvertInterToXPath(PublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview)
|
||||
{
|
||||
var d = new XmlDocument();
|
||||
var e = d.CreateElement("values");
|
||||
d.AppendChild(e);
|
||||
|
||||
var values = (IEnumerable<string>) source;
|
||||
var values = (IEnumerable<string>) inter;
|
||||
foreach (var value in values)
|
||||
{
|
||||
var ee = d.CreateElement("value");
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Linq;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
@@ -14,8 +15,6 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
/// to use that converter for values whose .ToString() would depend on other content.</para>
|
||||
/// </remarks>
|
||||
[DefaultPropertyValueConverter]
|
||||
[PropertyValueType(typeof(string))]
|
||||
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
|
||||
public class MustBeStringValueConverter : PropertyValueConverterBase
|
||||
{
|
||||
private static readonly string[] Aliases =
|
||||
@@ -29,7 +28,17 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
return Aliases.Contains(propertyType.PropertyEditorAlias);
|
||||
}
|
||||
|
||||
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
|
||||
public override Type GetPropertyValueType(PublishedPropertyType propertyType)
|
||||
{
|
||||
return typeof (string);
|
||||
}
|
||||
|
||||
public override PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType)
|
||||
{
|
||||
return PropertyCacheLevel.Content;
|
||||
}
|
||||
|
||||
public override object ConvertSourceToInter(PublishedPropertyType propertyType, object source, bool preview)
|
||||
{
|
||||
if (source == null) return null;
|
||||
return source.ToString();
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
{
|
||||
[PropertyValueType(typeof(string))]
|
||||
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
|
||||
public class TextStringValueConverter : PropertyValueConverterBase
|
||||
{
|
||||
private readonly static string[] PropertyTypeAliases =
|
||||
@@ -21,7 +17,17 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
return PropertyTypeAliases.Contains(propertyType.PropertyEditorAlias);
|
||||
}
|
||||
|
||||
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
|
||||
public override Type GetPropertyValueType(PublishedPropertyType propertyType)
|
||||
{
|
||||
return typeof (string);
|
||||
}
|
||||
|
||||
public override PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType)
|
||||
{
|
||||
return PropertyCacheLevel.Content;
|
||||
}
|
||||
|
||||
public override object ConvertSourceToInter(PublishedPropertyType propertyType, object source, bool preview)
|
||||
{
|
||||
// in xml a string is: string
|
||||
// in the database a string is: string
|
||||
@@ -29,16 +35,16 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
return source;
|
||||
}
|
||||
|
||||
public override object ConvertSourceToObject(PublishedPropertyType propertyType, object source, bool preview)
|
||||
public override object ConvertInterToObject(PublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview)
|
||||
{
|
||||
// source should come from ConvertSource and be a string (or null) already
|
||||
return source ?? string.Empty;
|
||||
return inter ?? string.Empty;
|
||||
}
|
||||
|
||||
public override object ConvertSourceToXPath(PublishedPropertyType propertyType, object source, bool preview)
|
||||
public override object ConvertInterToXPath(PublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview)
|
||||
{
|
||||
// source should come from ConvertSource and be a string (or null) already
|
||||
return source;
|
||||
return inter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,9 +7,6 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
/// <summary>
|
||||
/// Value converter for the RTE so that it always returns IHtmlString so that Html.Raw doesn't have to be used.
|
||||
/// </summary>
|
||||
// PropertyCacheLevel.Content is ok here because that version of RTE converter does not parse {locallink} nor executes macros
|
||||
[PropertyValueType(typeof(IHtmlString))]
|
||||
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
|
||||
public class TinyMceValueConverter : PropertyValueConverterBase
|
||||
{
|
||||
public override bool IsConverter(PublishedPropertyType propertyType)
|
||||
@@ -17,7 +14,18 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
return propertyType.PropertyEditorAlias == Constants.PropertyEditors.TinyMCEAlias;
|
||||
}
|
||||
|
||||
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
|
||||
public override Type GetPropertyValueType(PublishedPropertyType propertyType)
|
||||
{
|
||||
return typeof (IHtmlString);
|
||||
}
|
||||
|
||||
public override PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType)
|
||||
{
|
||||
// PropertyCacheLevel.Content is ok here because that converter does not parse {locallink} nor executes macros
|
||||
return PropertyCacheLevel.Content;
|
||||
}
|
||||
|
||||
public override object ConvertSourceToInter(PublishedPropertyType propertyType, object source, bool preview)
|
||||
{
|
||||
// in xml a string is: string
|
||||
// in the database a string is: string
|
||||
@@ -25,16 +33,16 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
return source;
|
||||
}
|
||||
|
||||
public override object ConvertSourceToObject(PublishedPropertyType propertyType, object source, bool preview)
|
||||
public override object ConvertInterToObject(PublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview)
|
||||
{
|
||||
// source should come from ConvertSource and be a string (or null) already
|
||||
return new HtmlString(source == null ? string.Empty : (string)source);
|
||||
return new HtmlString(inter == null ? string.Empty : (string)inter);
|
||||
}
|
||||
|
||||
public override object ConvertSourceToXPath(PublishedPropertyType propertyType, object source, bool preview)
|
||||
public override object ConvertInterToXPath(PublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview)
|
||||
{
|
||||
// source should come from ConvertSource and be a string (or null) already
|
||||
return source;
|
||||
return inter;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,8 +3,6 @@ using Umbraco.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
{
|
||||
[PropertyValueType(typeof(bool))]
|
||||
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
|
||||
public class YesNoValueConverter : PropertyValueConverterBase
|
||||
{
|
||||
public override bool IsConverter(PublishedPropertyType propertyType)
|
||||
@@ -12,7 +10,17 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
return propertyType.PropertyEditorAlias == Constants.PropertyEditors.TrueFalseAlias;
|
||||
}
|
||||
|
||||
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
|
||||
public override Type GetPropertyValueType(PublishedPropertyType propertyType)
|
||||
{
|
||||
return typeof (bool);
|
||||
}
|
||||
|
||||
public override PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType)
|
||||
{
|
||||
return PropertyCacheLevel.Content;
|
||||
}
|
||||
|
||||
public override object ConvertSourceToInter(PublishedPropertyType propertyType, object source, bool preview)
|
||||
{
|
||||
// in xml a boolean is: string
|
||||
// in the database a boolean is: string "1" or "0" or empty
|
||||
@@ -48,10 +56,10 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
|
||||
// default ConvertSourceToObject just returns source ie a boolean value
|
||||
|
||||
public override object ConvertSourceToXPath(PublishedPropertyType propertyType, object source, bool preview)
|
||||
public override object ConvertInterToXPath(PublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview)
|
||||
{
|
||||
// source should come from ConvertSource and be a boolean already
|
||||
return (bool)source ? "1" : "0";
|
||||
return (bool)inter ? "1" : "0";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,6 +260,7 @@
|
||||
<DependentUpon>Files.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Models\DictionaryItemExtensions.cs" />
|
||||
<Compile Include="Models\PublishedContent\IPublishedFragment.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionEight\AddContentNuTable.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionEight\RefactorXmlColumns.cs" />
|
||||
<Compile Include="Plugins\HideFromTypeFinderAttribute.cs" />
|
||||
@@ -540,7 +541,7 @@
|
||||
<Compile Include="Models\EntityExtensions.cs" />
|
||||
<Compile Include="Models\Folder.cs" />
|
||||
<Compile Include="Models\IMemberGroup.cs" />
|
||||
<Compile Include="Models\IPublishedProperty.cs" />
|
||||
<Compile Include="Models\PublishedContent\IPublishedProperty.cs" />
|
||||
<Compile Include="Models\IRelation.cs" />
|
||||
<Compile Include="Models\IRelationType.cs" />
|
||||
<Compile Include="Models\Membership\EntityPermissionSet.cs" />
|
||||
@@ -610,9 +611,6 @@
|
||||
<Compile Include="Persistence\SqlSyntax\SqlServerVersionName.cs" />
|
||||
<Compile Include="Persistence\SqlSyntax\SqlSyntaxProviderExtensions.cs" />
|
||||
<Compile Include="PropertyEditors\LegacyPropertyEditorIdToAliasConverter.cs" />
|
||||
<Compile Include="PropertyEditors\PropertyCacheValue.cs" />
|
||||
<Compile Include="PropertyEditors\PropertyValueCacheAttribute.cs" />
|
||||
<Compile Include="PropertyEditors\PropertyValueTypeAttribute.cs" />
|
||||
<Compile Include="PropertyEditors\PropertyCacheLevel.cs" />
|
||||
<Compile Include="PropertyEditors\PropertyValueConverterBase.cs" />
|
||||
<Compile Include="PropertyEditors\SupportTagsAttribute.cs" />
|
||||
@@ -620,7 +618,6 @@
|
||||
<Compile Include="PropertyEditors\TagValueType.cs" />
|
||||
<Compile Include="PropertyEditors\ValueConverters\ColorPickerValueConverter.cs" />
|
||||
<Compile Include="PropertyEditors\ValueConverters\IntegerValueConverter.cs" />
|
||||
<Compile Include="PropertyEditors\IPropertyValueConverterMeta.cs" />
|
||||
<Compile Include="PropertyEditors\ValueConverters\JsonValueConverter.cs" />
|
||||
<Compile Include="PropertyEditors\ValueConverters\MultipleTextStringValueConverter.cs" />
|
||||
<Compile Include="PropertyEditors\ValueConverters\MarkdownEditorValueConverter.cs" />
|
||||
@@ -682,7 +679,7 @@
|
||||
<Compile Include="Models\Membership\User.cs" />
|
||||
<Compile Include="Models\Membership\UserType.cs" />
|
||||
<Compile Include="Models\PropertyExtensions.cs" />
|
||||
<Compile Include="Models\PublishedItemType.cs" />
|
||||
<Compile Include="Models\PublishedContent\PublishedItemType.cs" />
|
||||
<Compile Include="Models\PublishedState.cs" />
|
||||
<Compile Include="Models\Rdbms\ContentType2ContentTypeDto.cs" />
|
||||
<Compile Include="Models\Rdbms\PropertyTypeGroupDto.cs" />
|
||||
@@ -1124,7 +1121,7 @@
|
||||
<Compile Include="Dynamics\Res.cs" />
|
||||
<Compile Include="Dynamics\Signature.cs" />
|
||||
<Compile Include="ExpressionExtensions.cs" />
|
||||
<Compile Include="Models\IPublishedContent.cs" />
|
||||
<Compile Include="Models\PublishedContent\IPublishedContent.cs" />
|
||||
<Compile Include="Cache\CacheRefreshersResolver.cs" />
|
||||
<Compile Include="Configuration\GlobalSettings.cs" />
|
||||
<Compile Include="CustomBooleanTypeConverter.cs" />
|
||||
|
||||
@@ -17,6 +17,7 @@ using Umbraco.Core.Profiling;
|
||||
using Umbraco.Core.Services;
|
||||
using Moq;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
using Umbraco.Web;
|
||||
using Umbraco.Web.PublishedCache;
|
||||
|
||||
@@ -149,7 +149,7 @@ namespace Umbraco.Tests.PropertyEditors
|
||||
dataTypeService.Setup(x => x.GetPreValuesCollectionByDataTypeId(It.IsAny<int>())).Returns(new PreValueCollection(Enumerable.Empty<PreValue>()));
|
||||
|
||||
var converter = new Umbraco.Web.PropertyEditors.ValueConverters.ImageCropperValueConverter(dataTypeService.Object);
|
||||
var result = converter.ConvertDataToSource(new PublishedPropertyType("test", 0, "test"), val1, false); // does not use type for conversion
|
||||
var result = converter.ConvertSourceToInter(new PublishedPropertyType("test", 0, "test"), val1, false); // does not use type for conversion
|
||||
|
||||
var resultShouldMatch = val2.SerializeToCropDataSet();
|
||||
if (expected)
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace Umbraco.Tests.PropertyEditors
|
||||
{
|
||||
var converter = new DatePickerValueConverter();
|
||||
var dateTime = new DateTime(2012, 11, 10, 13, 14, 15);
|
||||
var result = converter.ConvertDataToSource(null, date, false); // does not use type for conversion
|
||||
var result = converter.ConvertSourceToInter(null, date, false); // does not use type for conversion
|
||||
|
||||
if (expected)
|
||||
Assert.AreEqual(dateTime.Date, ((DateTime) result).Date);
|
||||
@@ -54,7 +54,7 @@ namespace Umbraco.Tests.PropertyEditors
|
||||
public void CanConvertYesNoPropertyEditor(object value, bool expected)
|
||||
{
|
||||
var converter = new YesNoValueConverter();
|
||||
var result = converter.ConvertDataToSource(null, value, false); // does not use type for conversion
|
||||
var result = converter.ConvertSourceToInter(null, value, false); // does not use type for conversion
|
||||
|
||||
Assert.AreEqual(expected, result);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Web;
|
||||
using Umbraco.Web.Models;
|
||||
using Umbraco.Web.PublishedCache;
|
||||
|
||||
@@ -159,11 +159,11 @@ namespace Umbraco.Tests.PublishedContent
|
||||
if (!createChildren)
|
||||
{
|
||||
//create additional columns, used to test the different columns for child nodes
|
||||
d.Properties.Add(new PropertyResult("property4", "value" + (indexVals + 2), PropertyResultType.UserProperty));
|
||||
((Collection<IPublishedProperty>)d.Properties).Add(new PropertyResult("property4", "value" + (indexVals + 2), PropertyResultType.UserProperty));
|
||||
}
|
||||
else
|
||||
{
|
||||
d.Properties.Add(new PropertyResult("property3", "value" + (indexVals + 2), PropertyResultType.UserProperty));
|
||||
((Collection<IPublishedProperty>)d.Properties).Add(new PropertyResult("property3", "value" + (indexVals + 2), PropertyResultType.UserProperty));
|
||||
}
|
||||
return d;
|
||||
}
|
||||
@@ -204,14 +204,8 @@ namespace Umbraco.Tests.PublishedContent
|
||||
public Guid Version { get; set; }
|
||||
public int Level { get; set; }
|
||||
public bool IsDraft { get; set; }
|
||||
public int GetIndex() { throw new NotImplementedException();}
|
||||
|
||||
public ICollection<IPublishedProperty> Properties { get; set; }
|
||||
|
||||
public object this[string propertyAlias]
|
||||
{
|
||||
get { return GetProperty(propertyAlias).Value; }
|
||||
}
|
||||
public IEnumerable<IPublishedProperty> Properties { get; set; }
|
||||
|
||||
public IEnumerable<IPublishedContent> Children { get; set; }
|
||||
|
||||
@@ -235,11 +229,6 @@ namespace Umbraco.Tests.PublishedContent
|
||||
return property;
|
||||
}
|
||||
|
||||
public IEnumerable<IPublishedContent> ContentSet
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
public PublishedContentType ContentType
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
|
||||
@@ -226,7 +226,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
PropertyTypeAlias = "prop1",
|
||||
HasValue = true,
|
||||
Value = 1234,
|
||||
DataValue = "1234"
|
||||
SourceValue = "1234"
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -249,7 +249,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
PropertyTypeAlias = "prop1",
|
||||
HasValue = true,
|
||||
Value = 1234,
|
||||
DataValue = "1234"
|
||||
SourceValue = "1234"
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -272,7 +272,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
PropertyTypeAlias = "prop1",
|
||||
HasValue = true,
|
||||
Value = 1234,
|
||||
DataValue = "1234"
|
||||
SourceValue = "1234"
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -7,6 +7,7 @@ using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
using Umbraco.Web.Routing;
|
||||
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Web;
|
||||
using Umbraco.Web.PublishedCache;
|
||||
|
||||
@@ -16,31 +14,24 @@ namespace Umbraco.Tests.PublishedContent
|
||||
public readonly SolidPublishedContentCache InnerContentCache = new SolidPublishedContentCache();
|
||||
public readonly SolidPublishedContentCache InnerMediaCache = new SolidPublishedContentCache();
|
||||
|
||||
public IPublishedContentCache ContentCache
|
||||
{
|
||||
get { return InnerContentCache; }
|
||||
}
|
||||
public IPublishedContentCache ContentCache => InnerContentCache;
|
||||
|
||||
public IPublishedMediaCache MediaCache
|
||||
{
|
||||
get { return InnerMediaCache; }
|
||||
}
|
||||
public IPublishedMediaCache MediaCache => InnerMediaCache;
|
||||
|
||||
public IPublishedMemberCache MemberCache
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
public IPublishedMemberCache MemberCache => null;
|
||||
|
||||
public IDomainCache DomainCache
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
public IDomainCache DomainCache => null;
|
||||
|
||||
public IDisposable ForcedPreview(bool forcedPreview, Action<bool> callback = null)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IPublishedProperty CreateFragmentProperty(PublishedPropertyType propertyType, Guid itemKey, bool previewing, PropertyCacheLevel referenceCacheLevel, object sourceValue = null)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Resync()
|
||||
{ }
|
||||
}
|
||||
@@ -133,11 +124,6 @@ namespace Umbraco.Tests.PublishedContent
|
||||
return _content.Count > 0;
|
||||
}
|
||||
|
||||
public IPublishedProperty CreateDetachedProperty(PublishedPropertyType propertyType, object value, bool isPreviewing)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override PublishedContentType GetContentType(int id)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
@@ -219,7 +205,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
|
||||
#region Properties
|
||||
|
||||
public ICollection<IPublishedProperty> Properties { get; set; }
|
||||
public IEnumerable<IPublishedProperty> Properties { get; set; }
|
||||
|
||||
public IPublishedProperty GetProperty(string alias)
|
||||
{
|
||||
@@ -261,7 +247,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
}
|
||||
|
||||
public string PropertyTypeAlias { get; set; }
|
||||
public object DataValue { get; set; }
|
||||
public object SourceValue { get; set; }
|
||||
public object Value { get; set; }
|
||||
public bool HasValue { get; set; }
|
||||
public object XPathValue { get; set; }
|
||||
@@ -278,11 +264,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
|
||||
#endregion
|
||||
|
||||
// fast, if you know that the appropriate IPropertyEditorValueConverter is wired
|
||||
public int Prop1 { get { return (int)this["prop1"]; } }
|
||||
|
||||
// almost as fast, not sure I like it as much, though
|
||||
//public int Prop1 { get { return this.GetPropertyValue<int>("prop1"); } }
|
||||
public int Prop1 => this.GetPropertyValue<int>("prop1");
|
||||
}
|
||||
|
||||
[PublishedContentModel("ContentType2Sub")]
|
||||
@@ -303,7 +285,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
: base(content)
|
||||
{ }
|
||||
|
||||
public int StrongValue { get { return (int)this["strongValue"]; } }
|
||||
public int StrongValue => this.GetPropertyValue<int>("strongValue");
|
||||
}
|
||||
|
||||
class PublishedContentStrong1Sub : PublishedContentStrong1
|
||||
@@ -312,7 +294,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
: base(content)
|
||||
{ }
|
||||
|
||||
public int AnotherValue { get { return (int)this["anotherValue"]; } }
|
||||
public int AnotherValue => this.GetPropertyValue<int>("anotherValue");
|
||||
}
|
||||
|
||||
class PublishedContentStrong2 : PublishedContentExtended
|
||||
@@ -321,7 +303,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
: base(content)
|
||||
{ }
|
||||
|
||||
public int StrongValue { get { return (int)this["strongValue"]; } }
|
||||
public int StrongValue => this.GetPropertyValue<int>("strongValue");
|
||||
}
|
||||
|
||||
class AutoPublishedContentType : PublishedContentType
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Linq;
|
||||
using System.Web;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.Plugins;
|
||||
using Umbraco.Web;
|
||||
@@ -50,7 +49,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
};
|
||||
var compositionAliases = new[] {"MyCompositionAlias"};
|
||||
var type = new AutoPublishedContentType(0, "anything", compositionAliases, propertyTypes);
|
||||
ContentTypesCache.GetPublishedContentTypeByAlias = (alias) => type;
|
||||
ContentTypesCache.GetPublishedContentTypeByAlias = alias => type;
|
||||
}
|
||||
|
||||
public override void TearDown()
|
||||
@@ -197,7 +196,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
.Where(x => x.IsVisible()) // so, here it's linq again :-(
|
||||
.ToIndexedArray(); // so, we need that one for the test to pass
|
||||
|
||||
Assert.AreEqual(1, items.Count());
|
||||
Assert.AreEqual(1, items.Length);
|
||||
|
||||
foreach (var d in items)
|
||||
{
|
||||
@@ -288,11 +287,11 @@ namespace Umbraco.Tests.PublishedContent
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_Get_Recursive_Val()
|
||||
public void GetPropertyValueRecursiveTest()
|
||||
{
|
||||
var doc = GetNode(1174);
|
||||
var rVal = doc.GetRecursiveValue("testRecursive");
|
||||
var nullVal = doc.GetRecursiveValue("DoNotFindThis");
|
||||
var rVal = doc.GetPropertyValue("testRecursive", true);
|
||||
var nullVal = doc.GetPropertyValue("DoNotFindThis", true);
|
||||
Assert.AreEqual("This is the recursive val", rVal);
|
||||
Assert.AreEqual("", nullVal);
|
||||
}
|
||||
@@ -333,9 +332,9 @@ namespace Umbraco.Tests.PublishedContent
|
||||
{
|
||||
var doc = GetNode(1046);
|
||||
|
||||
var found1 = doc.Children.GroupBy("DocumentTypeAlias");
|
||||
var found1 = doc.Children.GroupBy("DocumentTypeAlias").ToArray();
|
||||
|
||||
Assert.AreEqual(2, found1.Count());
|
||||
Assert.AreEqual(2, found1.Length);
|
||||
Assert.AreEqual(2, found1.Single(x => x.Key.ToString() == "Home").Count());
|
||||
Assert.AreEqual(1, found1.Single(x => x.Key.ToString() == "CustomDocument").Count());
|
||||
}
|
||||
@@ -460,11 +459,11 @@ namespace Umbraco.Tests.PublishedContent
|
||||
{
|
||||
var doc = GetNode(1174);
|
||||
|
||||
var result = doc.AncestorsOrSelf();
|
||||
var result = doc.AncestorsOrSelf().ToArray();
|
||||
|
||||
Assert.IsNotNull(result);
|
||||
|
||||
Assert.AreEqual(3, result.Count());
|
||||
Assert.AreEqual(3, result.Length);
|
||||
Assert.IsTrue(result.Select(x => ((dynamic)x).Id).ContainsAll(new dynamic[] { 1174, 1173, 1046 }));
|
||||
}
|
||||
|
||||
@@ -473,11 +472,11 @@ namespace Umbraco.Tests.PublishedContent
|
||||
{
|
||||
var doc = GetNode(1174);
|
||||
|
||||
var result = doc.Ancestors();
|
||||
var result = doc.Ancestors().ToArray();
|
||||
|
||||
Assert.IsNotNull(result);
|
||||
|
||||
Assert.AreEqual(2, result.Count());
|
||||
Assert.AreEqual(2, result.Length);
|
||||
Assert.IsTrue(result.Select(x => ((dynamic)x).Id).ContainsAll(new dynamic[] { 1173, 1046 }));
|
||||
}
|
||||
|
||||
@@ -486,11 +485,11 @@ namespace Umbraco.Tests.PublishedContent
|
||||
{
|
||||
var doc = GetNode(1046);
|
||||
|
||||
var result = doc.DescendantsOrSelf();
|
||||
var result = doc.DescendantsOrSelf().ToArray();
|
||||
|
||||
Assert.IsNotNull(result);
|
||||
|
||||
Assert.AreEqual(8, result.Count());
|
||||
Assert.AreEqual(8, result.Length);
|
||||
Assert.IsTrue(result.Select(x => ((dynamic)x).Id).ContainsAll(new dynamic[] { 1046, 1173, 1174, 1176, 1175 }));
|
||||
}
|
||||
|
||||
@@ -499,11 +498,11 @@ namespace Umbraco.Tests.PublishedContent
|
||||
{
|
||||
var doc = GetNode(1046);
|
||||
|
||||
var result = doc.Descendants();
|
||||
var result = doc.Descendants().ToArray();
|
||||
|
||||
Assert.IsNotNull(result);
|
||||
|
||||
Assert.AreEqual(7, result.Count());
|
||||
Assert.AreEqual(7, result.Length);
|
||||
Assert.IsTrue(result.Select(x => ((dynamic)x).Id).ContainsAll(new dynamic[] { 1173, 1174, 1176, 1175, 4444 }));
|
||||
}
|
||||
|
||||
@@ -516,7 +515,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
|
||||
Assert.IsNotNull(result);
|
||||
|
||||
Assert.AreEqual((int)1046, (int)result.Id);
|
||||
Assert.AreEqual(1046, result.Id);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -528,7 +527,13 @@ namespace Umbraco.Tests.PublishedContent
|
||||
|
||||
Assert.IsNotNull(result);
|
||||
|
||||
Assert.AreEqual((int)1174, (int)result.Id);
|
||||
Assert.AreEqual(1174, result.Id);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FragmentTest()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -574,8 +579,8 @@ namespace Umbraco.Tests.PublishedContent
|
||||
|
||||
class ImageWithLegendModel
|
||||
{
|
||||
private IPublishedProperty _legendProperty;
|
||||
private IPublishedProperty _imageProperty;
|
||||
private readonly IPublishedProperty _legendProperty;
|
||||
private readonly IPublishedProperty _imageProperty;
|
||||
|
||||
public ImageWithLegendModel(IPublishedProperty legendProperty, IPublishedProperty imageProperty)
|
||||
{
|
||||
@@ -583,8 +588,8 @@ namespace Umbraco.Tests.PublishedContent
|
||||
_imageProperty = imageProperty;
|
||||
}
|
||||
|
||||
public string Legend { get { return _legendProperty.GetValue<string>(); } }
|
||||
public IPublishedContent Image { get { return _imageProperty.GetValue<IPublishedContent>(); } }
|
||||
public string Legend => _legendProperty.GetValue<string>();
|
||||
public IPublishedContent Image => _imageProperty.GetValue<IPublishedContent>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ using Examine.Session;
|
||||
using LightInject;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.Strings;
|
||||
using UmbracoExamine;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Tests.PublishedContent.StronglyTypedModels
|
||||
{
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Tests.PublishedContent.StronglyTypedModels
|
||||
{
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Web.Mvc;
|
||||
|
||||
namespace Umbraco.Tests.PublishedContent.StronglyTypedModels
|
||||
|
||||
@@ -12,6 +12,7 @@ using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
using Umbraco.Core.Dictionary;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
using Umbraco.Core.Profiling;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Linq;
|
||||
using System.Collections;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Web.Models;
|
||||
|
||||
namespace Umbraco.Web.Dynamics
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Web.Models;
|
||||
|
||||
namespace Umbraco.Web.Dynamics
|
||||
|
||||
@@ -7,6 +7,7 @@ using Umbraco.Web.WebApi.Filters;
|
||||
using Umbraco.Web.WebApi;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Web.Dynamics;
|
||||
using Umbraco.Web.Models.TemplateQuery;
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ using System.Web.Mvc;
|
||||
using Umbraco.Web.Templates;
|
||||
using System.IO;
|
||||
using System.Web.Routing;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Web.Mvc;
|
||||
|
||||
namespace Umbraco.Web
|
||||
|
||||
@@ -13,6 +13,7 @@ using Umbraco.Core.Dynamics;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.Profiling;
|
||||
using Umbraco.Web.Models;
|
||||
using Umbraco.Web.Mvc;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Web.Models;
|
||||
|
||||
namespace Umbraco.Web
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.XPath;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.Xml;
|
||||
|
||||
namespace Umbraco.Web
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Web;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Web
|
||||
{
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Globalization;
|
||||
using System.Text;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Web.Models;
|
||||
|
||||
namespace Umbraco.Web
|
||||
|
||||
@@ -5,6 +5,7 @@ using Umbraco.Web.Models;
|
||||
using Umbraco.Web.Mvc;
|
||||
using umbraco.cms.businesslogic.macro;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Web.Macros
|
||||
{
|
||||
|
||||
@@ -9,6 +9,7 @@ using umbraco.cms.businesslogic.macro;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Web.Mvc;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Web.Macros
|
||||
{
|
||||
|
||||
@@ -1,115 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Web.Models
|
||||
{
|
||||
internal class DetachedContent
|
||||
{
|
||||
private readonly Dictionary<string, IPublishedProperty> _properties;
|
||||
|
||||
/// <summary>
|
||||
/// Initialized a new instance of the <see cref="DetachedContent"/> class with properties.
|
||||
/// </summary>
|
||||
/// <param name="properties">The properties</param>
|
||||
/// <remarks>Properties must be detached or nested properties ie their property type must be detached or nested.
|
||||
/// Such a detached content can be part of a published property value.</remarks>
|
||||
public DetachedContent(IEnumerable<IPublishedProperty> properties)
|
||||
{
|
||||
_properties = properties.ToDictionary(x => x.PropertyTypeAlias, x => x, StringComparer.InvariantCultureIgnoreCase);
|
||||
}
|
||||
|
||||
// don't uncomment until you know what you are doing
|
||||
/*
|
||||
public DetachedContent(IPublishedContent content)
|
||||
{
|
||||
_properties = content.Properties.ToDictionary(x => x.PropertyTypeAlias, x => x, StringComparer.InvariantCultureIgnoreCase);
|
||||
}
|
||||
*/
|
||||
|
||||
// don't uncomment until you know what you are doing
|
||||
// at the moment, I don't fully
|
||||
/*
|
||||
public DetachedContent(IContent content, bool isPreviewing)
|
||||
{
|
||||
var publishedContentType = PublishedContentType.Get(PublishedItemType.Content, content.ContentType.Alias);
|
||||
_properties = PublishedProperty.MapProperties(publishedContentType.PropertyTypes, content.Properties,
|
||||
(t, v) => PublishedProperty.GetDetached(t.Detached(), v, isPreviewing))
|
||||
.ToDictionary(x => x.PropertyTypeAlias, x => x, StringComparer.InvariantCultureIgnoreCase);
|
||||
}
|
||||
|
||||
public DetachedContent(IMedia media, bool isPreviewing)
|
||||
{
|
||||
var publishedContentType = PublishedContentType.Get(PublishedItemType.Media, media.ContentType.Alias);
|
||||
_properties = PublishedProperty.MapProperties(publishedContentType.PropertyTypes, media.Properties,
|
||||
(t, v) => PublishedProperty.GetDetached(t.Detached(), v, isPreviewing))
|
||||
.ToDictionary(x => x.PropertyTypeAlias, x => x, StringComparer.InvariantCultureIgnoreCase);
|
||||
}
|
||||
|
||||
public DetachedContent(IMember member, bool isPreviewing)
|
||||
{
|
||||
var publishedContentType = PublishedContentType.Get(PublishedItemType.Member, member.ContentType.Alias);
|
||||
_properties = PublishedProperty.MapProperties(publishedContentType.PropertyTypes, member.Properties,
|
||||
(t, v) => PublishedProperty.GetDetached(t.Detached(), v, isPreviewing))
|
||||
.ToDictionary(x => x.PropertyTypeAlias, x => x, StringComparer.InvariantCultureIgnoreCase);
|
||||
}
|
||||
*/
|
||||
|
||||
public ICollection<IPublishedProperty> Properties
|
||||
{
|
||||
get { return _properties.Values; }
|
||||
}
|
||||
|
||||
public IPublishedProperty GetProperty(string alias)
|
||||
{
|
||||
IPublishedProperty property;
|
||||
return _properties.TryGetValue(alias, out property) ? property : null;
|
||||
}
|
||||
|
||||
public bool HasProperty(string alias)
|
||||
{
|
||||
var property = GetProperty(alias);
|
||||
return property != null;
|
||||
}
|
||||
|
||||
public bool HasValue(string alias)
|
||||
{
|
||||
var property = GetProperty(alias);
|
||||
return property != null && property.HasValue;
|
||||
}
|
||||
|
||||
public object GetPropertyValue(string alias)
|
||||
{
|
||||
var property = GetProperty(alias);
|
||||
return property == null ? null : property.Value;
|
||||
}
|
||||
|
||||
public object GetPropertyValue(string alias, string defaultValue)
|
||||
{
|
||||
var property = GetProperty(alias);
|
||||
return property == null || property.HasValue == false ? defaultValue : property.Value;
|
||||
}
|
||||
|
||||
public object GetPropertyValue(string alias, object defaultValue)
|
||||
{
|
||||
var property = GetProperty(alias);
|
||||
return property == null || property.HasValue == false ? defaultValue : property.Value;
|
||||
}
|
||||
|
||||
public T GetPropertyValue<T>(string alias)
|
||||
{
|
||||
var property = GetProperty(alias);
|
||||
if (property == null) return default(T);
|
||||
return property.GetValue(false, default(T));
|
||||
}
|
||||
|
||||
public T GetPropertyValue<T>(string alias, T defaultValue)
|
||||
{
|
||||
var property = GetProperty(alias);
|
||||
if (property == null) return defaultValue;
|
||||
return property.GetValue(true, defaultValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -46,15 +46,6 @@ namespace Umbraco.Web.Models
|
||||
|
||||
#endregion
|
||||
|
||||
// these two here have leaked in v6 and so we cannot remove them anymore
|
||||
// without breaking compatibility but... TODO: remove them in v7
|
||||
|
||||
[Obsolete("Will be removing in future versions")]
|
||||
public DynamicPublishedContentList ChildrenAsList { get { return Children; } }
|
||||
|
||||
[Obsolete("Will be removing in future versions")]
|
||||
public int parentId { get { return PublishedContent.Parent.Id; } }
|
||||
|
||||
#region DynamicObject
|
||||
|
||||
private readonly ConcurrentDictionary<string, object> _cachedMemberOutput = new ConcurrentDictionary<string, object>();
|
||||
@@ -428,7 +419,7 @@ namespace Umbraco.Web.Models
|
||||
get { return PublishedContent.IsDraft; }
|
||||
}
|
||||
|
||||
ICollection<IPublishedProperty> IPublishedContent.Properties
|
||||
IEnumerable<IPublishedProperty> IPublishedFragment.Properties
|
||||
{
|
||||
get { return PublishedContent.Properties; }
|
||||
}
|
||||
@@ -438,7 +429,7 @@ namespace Umbraco.Web.Models
|
||||
get { return PublishedContent.Children; }
|
||||
}
|
||||
|
||||
IPublishedProperty IPublishedContent.GetProperty(string alias)
|
||||
IPublishedProperty IPublishedFragment.GetProperty(string alias)
|
||||
{
|
||||
return PublishedContent.GetProperty(alias);
|
||||
}
|
||||
@@ -548,11 +539,6 @@ namespace Umbraco.Web.Models
|
||||
get { return PublishedContent.Properties; }
|
||||
}
|
||||
|
||||
public object this[string propertyAlias]
|
||||
{
|
||||
get { return PublishedContent[propertyAlias]; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region GetProperty
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Web.Models
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Web.Models
|
||||
{
|
||||
|
||||
@@ -143,30 +143,7 @@ namespace Umbraco.Web.Models
|
||||
/// <summary>
|
||||
/// Gets the properties of the content.
|
||||
/// </summary>
|
||||
public abstract ICollection<IPublishedProperty> Properties { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of a property identified by its alias.
|
||||
/// </summary>
|
||||
/// <param name="alias">The property alias.</param>
|
||||
/// <returns>The value of the property identified by the alias.</returns>
|
||||
/// <remarks>
|
||||
/// <para>If <c>GetProperty(alias)</c> is <c>null</c> then returns <c>null</c> else return <c>GetProperty(alias).Value</c>.</para>
|
||||
/// <para>So if the property has no value, returns the default value for that property type.</para>
|
||||
/// <para>This one is defined here really because we cannot define index extension methods, but all it should do is:
|
||||
/// <code>var p = GetProperty(alias); return p == null ? null : p.Value;</code> and nothing else.</para>
|
||||
/// <para>The recursive syntax (eg "_title") is _not_ supported here.</para>
|
||||
/// <para>The alias is case-insensitive.</para>
|
||||
/// </remarks>
|
||||
public virtual object this[string alias]
|
||||
{
|
||||
get
|
||||
{
|
||||
// no cache here: GetProperty should be fast, and .Value cache should be managed by the property.
|
||||
var property = GetProperty(alias);
|
||||
return property == null ? null : property.Value;
|
||||
}
|
||||
}
|
||||
public abstract IEnumerable<IPublishedProperty> Properties { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a property identified by its alias.
|
||||
|
||||
@@ -1,33 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
namespace Umbraco.Web.Models
|
||||
{
|
||||
public static class PublishedProperty
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a detached published property.
|
||||
/// </summary>
|
||||
/// <param name="propertyType">A published property type.</param>
|
||||
/// <param name="value">The property data raw value.</param>
|
||||
/// <param name="isPreviewing">A value indicating whether to evaluate the property value in previewing context.</param>
|
||||
/// <returns>A detached published property holding the value.</returns>
|
||||
internal static IPublishedProperty GetDetached(PublishedPropertyType propertyType, object value, bool isPreviewing = false)
|
||||
{
|
||||
if (propertyType.IsDetachedOrNested == false)
|
||||
throw new ArgumentException("Property type is neither detached nor nested.", "propertyType");
|
||||
var property = UmbracoContext.Current.ContentCache.CreateDetachedProperty(propertyType, value, isPreviewing);
|
||||
return property;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Maps a collection of Property to a collection of IPublishedProperty for a specified collection of PublishedPropertyType.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Web.Mvc;
|
||||
|
||||
namespace Umbraco.Web.Models
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Globalization;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Web.Mvc;
|
||||
|
||||
namespace Umbraco.Web.Models
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.Web.Mvc;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Web.Routing;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Language = umbraco.cms.businesslogic.language.Language;
|
||||
|
||||
namespace Umbraco.Web.Mvc
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.Web;
|
||||
using System.Web.Mvc;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Web.Mvc
|
||||
{
|
||||
|
||||
@@ -6,6 +6,7 @@ using System.Web;
|
||||
using System.Web.Mvc;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Web.Models;
|
||||
|
||||
namespace Umbraco.Web.Mvc
|
||||
|
||||
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Web.Mvc;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Web.Models;
|
||||
using Umbraco.Web.Routing;
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ using Umbraco.Core.Models;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Web.Security;
|
||||
using System.Collections.Specialized;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Web.Mvc
|
||||
{
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Umbraco.Core.Dynamics;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Web.Models;
|
||||
|
||||
namespace Umbraco.Web.Mvc
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Web.Mvc
|
||||
{
|
||||
|
||||
@@ -8,6 +8,7 @@ using Umbraco.Core;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Web.Models;
|
||||
using Umbraco.Web.Routing;
|
||||
using Umbraco.Web.Security;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Web.Routing;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Web.Mvc
|
||||
{
|
||||
|
||||
@@ -6,6 +6,7 @@ using System.Web.Routing;
|
||||
using System.Web.Security;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Web.Models;
|
||||
using Umbraco.Web.Routing;
|
||||
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Web.PublishedCache;
|
||||
|
||||
namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
{
|
||||
internal class ContentPickerValueConverter : PropertyValueConverterBase
|
||||
{
|
||||
private readonly IFacadeAccessor _facadeAccessor;
|
||||
|
||||
public ContentPickerValueConverter(IFacadeAccessor facadeAccessor)
|
||||
{
|
||||
_facadeAccessor = facadeAccessor;
|
||||
}
|
||||
|
||||
public override bool IsConverter(PublishedPropertyType propertyType)
|
||||
{
|
||||
return propertyType.PropertyEditorAlias.InvariantEquals(Constants.PropertyEditors.ContentPickerAlias);
|
||||
}
|
||||
|
||||
public override Type GetPropertyValueType(PublishedPropertyType propertyType)
|
||||
{
|
||||
return typeof (IPublishedContent);
|
||||
}
|
||||
|
||||
public override PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType)
|
||||
{
|
||||
return PropertyCacheLevel.Snapshot;
|
||||
}
|
||||
|
||||
public override object ConvertSourceToInter(PublishedPropertyType propertyType, object source, bool preview)
|
||||
{
|
||||
if (source == null) return null;
|
||||
|
||||
int id;
|
||||
return int.TryParse(source.ToString(), out id) ? id : -1;
|
||||
}
|
||||
|
||||
public override object ConvertInterToObject(PublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview)
|
||||
{
|
||||
var id = (int) inter;
|
||||
return id < 0 ? null : _facadeAccessor.Facade.ContentCache.GetById(id);
|
||||
}
|
||||
|
||||
public override object ConvertInterToXPath(PublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview)
|
||||
{
|
||||
return inter.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
@@ -16,21 +17,22 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
/// Used to strongly type the value for the image cropper
|
||||
/// </summary>
|
||||
[DefaultPropertyValueConverter(typeof (JsonValueConverter))] //this shadows the JsonValueConverter
|
||||
[PropertyValueType(typeof (ImageCropDataSet))]
|
||||
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
|
||||
public class ImageCropperValueConverter : Core.PropertyEditors.ValueConverters.ImageCropperValueConverter
|
||||
{
|
||||
public ImageCropperValueConverter()
|
||||
{
|
||||
}
|
||||
{ }
|
||||
|
||||
public ImageCropperValueConverter(IDataTypeService dataTypeService) : base(dataTypeService)
|
||||
{ }
|
||||
|
||||
public override Type GetPropertyValueType(PublishedPropertyType propertyType)
|
||||
{
|
||||
return typeof (ImageCropDataSet);
|
||||
}
|
||||
|
||||
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
|
||||
public override object ConvertSourceToInter(PublishedPropertyType propertyType, object source, bool preview)
|
||||
{
|
||||
var baseVal = base.ConvertDataToSource(propertyType, source, preview);
|
||||
var baseVal = base.ConvertSourceToInter(propertyType, source, preview);
|
||||
var json = baseVal as JObject;
|
||||
if (json == null) return baseVal;
|
||||
|
||||
|
||||
@@ -12,8 +12,6 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
/// Ensures macro syntax is parsed for the macro container which will work when getting the field
|
||||
/// values in any way (i.e. dynamically, using Field(), or IPublishedContent)
|
||||
/// </summary>
|
||||
[PropertyValueType(typeof (IHtmlString))]
|
||||
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Request)]
|
||||
[DefaultPropertyValueConverter]
|
||||
public class MacroContainerValueConverter : PropertyValueConverterBase
|
||||
{
|
||||
@@ -29,6 +27,16 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
return propertyType.PropertyEditorAlias == Constants.PropertyEditors.MacroContainerAlias;
|
||||
}
|
||||
|
||||
public override Type GetPropertyValueType(PublishedPropertyType propertyType)
|
||||
{
|
||||
return typeof (IHtmlString);
|
||||
}
|
||||
|
||||
public override PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType)
|
||||
{
|
||||
return PropertyCacheLevel.Facade;
|
||||
}
|
||||
|
||||
// NOT thread-safe over a request because it modifies the
|
||||
// global UmbracoContext.Current.InPreviewMode status. So it
|
||||
// should never execute in // over the same UmbracoContext with
|
||||
@@ -54,7 +62,7 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
}
|
||||
}
|
||||
|
||||
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
|
||||
public override object ConvertSourceToInter(PublishedPropertyType propertyType, object source, bool preview)
|
||||
{
|
||||
if (source == null) return null;
|
||||
var sourceString = source.ToString();
|
||||
|
||||
@@ -8,8 +8,6 @@ using Umbraco.Web.Templates;
|
||||
|
||||
namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
{
|
||||
[PropertyValueType(typeof(IHtmlString))]
|
||||
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Request)]
|
||||
[DefaultPropertyValueConverter]
|
||||
public class MarkdownEditorValueConverter : PropertyValueConverterBase
|
||||
{
|
||||
@@ -18,7 +16,17 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
return Constants.PropertyEditors.MarkdownEditorAlias.Equals(propertyType.PropertyEditorAlias);
|
||||
}
|
||||
|
||||
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
|
||||
public override Type GetPropertyValueType(PublishedPropertyType propertyType)
|
||||
{
|
||||
return typeof (IHtmlString);
|
||||
}
|
||||
|
||||
public override PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType)
|
||||
{
|
||||
return PropertyCacheLevel.Facade;
|
||||
}
|
||||
|
||||
public override object ConvertSourceToInter(PublishedPropertyType propertyType, object source, bool preview)
|
||||
{
|
||||
if (source == null) return null;
|
||||
var sourceString = source.ToString();
|
||||
@@ -30,19 +38,19 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
return sourceString;
|
||||
}
|
||||
|
||||
public override object ConvertSourceToObject(PublishedPropertyType propertyType, object source, bool preview)
|
||||
public override object ConvertInterToObject(PublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview)
|
||||
{
|
||||
// Convert markup to html for frontend rendering.
|
||||
Markdown mark = new Markdown();
|
||||
|
||||
// source should come from ConvertSource and be a string (or null) already
|
||||
return new HtmlString(source == null ? string.Empty : mark.Transform((string)source));
|
||||
return new HtmlString(inter == null ? string.Empty : mark.Transform((string)inter));
|
||||
}
|
||||
|
||||
public override object ConvertSourceToXPath(PublishedPropertyType propertyType, object source, bool preview)
|
||||
public override object ConvertInterToXPath(PublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview)
|
||||
{
|
||||
// source should come from ConvertSource and be a string (or null) already
|
||||
return source;
|
||||
return inter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
@@ -14,8 +11,6 @@ using Umbraco.Core.PropertyEditors.ValueConverters;
|
||||
|
||||
namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
{
|
||||
[PropertyValueType(typeof(JArray))]
|
||||
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
|
||||
[DefaultPropertyValueConverter(typeof(JsonValueConverter))] //this shadows the JsonValueConverter
|
||||
public class RelatedLinksEditorValueConvertor : PropertyValueConverterBase
|
||||
{
|
||||
@@ -31,7 +26,17 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
return Constants.PropertyEditors.RelatedLinksAlias.Equals(propertyType.PropertyEditorAlias);
|
||||
}
|
||||
|
||||
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
|
||||
public override Type GetPropertyValueType(PublishedPropertyType propertyType)
|
||||
{
|
||||
return typeof (JArray);
|
||||
}
|
||||
|
||||
public override PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType)
|
||||
{
|
||||
return PropertyCacheLevel.Content;
|
||||
}
|
||||
|
||||
public override object ConvertSourceToInter(PublishedPropertyType propertyType, object source, bool preview)
|
||||
{
|
||||
if (source == null) return null;
|
||||
var sourceString = source.ToString();
|
||||
@@ -68,10 +73,10 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
return sourceString;
|
||||
}
|
||||
|
||||
public override object ConvertSourceToXPath(PublishedPropertyType propertyType, object source, bool preview)
|
||||
public override object ConvertInterToXPath(PublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview)
|
||||
{
|
||||
if (source == null) return null;
|
||||
var sourceString = source.ToString();
|
||||
if (inter == null) return null;
|
||||
var sourceString = inter.ToString();
|
||||
|
||||
if (sourceString.DetectIsJson())
|
||||
{
|
||||
@@ -83,7 +88,7 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
var e = d.CreateElement("links");
|
||||
d.AppendChild(e);
|
||||
|
||||
var values = (IEnumerable<string>)source;
|
||||
var values = (IEnumerable<string>)inter;
|
||||
foreach (dynamic link in obj)
|
||||
{
|
||||
var ee = d.CreateElement("link");
|
||||
|
||||
@@ -18,17 +18,17 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
/// A value converter for TinyMCE that will ensure any macro content is rendered properly even when
|
||||
/// used dynamically.
|
||||
/// </summary>
|
||||
// because that version of RTE converter parses {locallink} and executes macros, when going from
|
||||
// data to source, its source value has to be cached at the request level, because we have no idea
|
||||
// what the macros may depend on actually. An so, object and xpath need to follow... request, too.
|
||||
// note: the TinyMceValueConverter is NOT inherited, so the PropertyValueCache attribute here is not
|
||||
// actually required (since Request is default) but leave it here to be absolutely explicit.
|
||||
[PropertyValueType(typeof(IHtmlString))]
|
||||
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Request)]
|
||||
public class RteMacroRenderingValueConverter : TinyMceValueConverter
|
||||
{
|
||||
private readonly UmbracoContext _umbracoContext;
|
||||
|
||||
public override PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType)
|
||||
{
|
||||
// because that version of RTE converter parses {locallink} and executes macros, its value has
|
||||
// to be cached at the facade level, because we have no idea what the macros may depend on actually.
|
||||
return PropertyCacheLevel.Facade;
|
||||
}
|
||||
|
||||
public RteMacroRenderingValueConverter(UmbracoContext umbracoContext)
|
||||
{
|
||||
_umbracoContext = umbracoContext;
|
||||
@@ -59,7 +59,7 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
}
|
||||
}
|
||||
|
||||
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
|
||||
public override object ConvertSourceToInter(PublishedPropertyType propertyType, object source, bool preview)
|
||||
{
|
||||
if (source == null)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Web.PublishedCache;
|
||||
using Umbraco.Web.PublishedCache.NuCache;
|
||||
|
||||
namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
{
|
||||
// fixme
|
||||
// this is an experimental converter to work with nested etc.
|
||||
internal class TempValueConverter : PropertyValueConverterBase
|
||||
{
|
||||
private readonly IFacadeAccessor _facadeAccessor;
|
||||
|
||||
public TempValueConverter(IFacadeAccessor facadeAccessor)
|
||||
{
|
||||
_facadeAccessor = facadeAccessor;
|
||||
}
|
||||
|
||||
public override bool IsConverter(PublishedPropertyType propertyType)
|
||||
{
|
||||
return propertyType.PropertyEditorAlias.InvariantEquals(Constants.PropertyEditors.ContentPickerAlias);
|
||||
}
|
||||
|
||||
public override Type GetPropertyValueType(PublishedPropertyType propertyType)
|
||||
{
|
||||
return typeof (IPublishedFragment);
|
||||
}
|
||||
|
||||
public override PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType)
|
||||
{
|
||||
return PropertyCacheLevel.Snapshot;
|
||||
}
|
||||
|
||||
public override object ConvertSourceToInter(PublishedPropertyType propertyType, object source, bool preview)
|
||||
{
|
||||
var json = source as string;
|
||||
return json == null ? null : JsonConvert.DeserializeObject<TempData>(json);
|
||||
}
|
||||
|
||||
public override object ConvertInterToObject(PublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview)
|
||||
{
|
||||
var data = (TempData) inter;
|
||||
if (data == null) return null;
|
||||
|
||||
var contentType = _facadeAccessor.Facade.ContentCache.GetContentType(data.ContentTypeAlias);
|
||||
if (contentType == null) return null;
|
||||
|
||||
// fixme
|
||||
// note: if we wanted to returned a strongly-typed model here, we'd have to be explicit about it
|
||||
// so that we can tell GetPropertyValueType what we return - just relying on a factory is not
|
||||
// going to make it in any helpful way?
|
||||
|
||||
return new PublishedFragment(contentType, _facadeAccessor, referenceCacheLevel, data.Key, data.Values, preview);
|
||||
}
|
||||
|
||||
public override object ConvertInterToXPath(PublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview)
|
||||
{
|
||||
return inter == null ? null : JsonConvert.SerializeObject((TempData) inter);
|
||||
}
|
||||
|
||||
public class TempData
|
||||
{
|
||||
public string ContentTypeAlias { get; set; }
|
||||
public Guid Key { get; set; }
|
||||
public Dictionary<string, object> Values { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.PropertyEditors.ValueConverters;
|
||||
using Umbraco.Web.Templates;
|
||||
|
||||
namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
{
|
||||
[PropertyValueType(typeof(string))]
|
||||
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Request)]
|
||||
public class TextStringValueConverter : PropertyValueConverterBase
|
||||
{
|
||||
private readonly static string[] PropertyTypeAliases =
|
||||
@@ -25,7 +20,17 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
return PropertyTypeAliases.Contains(propertyType.PropertyEditorAlias);
|
||||
}
|
||||
|
||||
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
|
||||
public override Type GetPropertyValueType(PublishedPropertyType propertyType)
|
||||
{
|
||||
return typeof (string);
|
||||
}
|
||||
|
||||
public override PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType)
|
||||
{
|
||||
return PropertyCacheLevel.Facade;
|
||||
}
|
||||
|
||||
public override object ConvertSourceToInter(PublishedPropertyType propertyType, object source, bool preview)
|
||||
{
|
||||
if (source == null) return null;
|
||||
var sourceString = source.ToString();
|
||||
@@ -37,16 +42,16 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
return sourceString;
|
||||
}
|
||||
|
||||
public override object ConvertSourceToObject(PublishedPropertyType propertyType, object source, bool preview)
|
||||
public override object ConvertInterToObject(PublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview)
|
||||
{
|
||||
// source should come from ConvertSource and be a string (or null) already
|
||||
return source ?? string.Empty;
|
||||
return inter ?? string.Empty;
|
||||
}
|
||||
|
||||
public override object ConvertSourceToXPath(PublishedPropertyType propertyType, object source, bool preview)
|
||||
public override object ConvertInterToXPath(PublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview)
|
||||
{
|
||||
// source should come from ConvertSource and be a string (or null) already
|
||||
return source;
|
||||
return inter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
namespace Umbraco.Web.PublishedCache
|
||||
using System;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
|
||||
namespace Umbraco.Web.PublishedCache
|
||||
{
|
||||
/// <summary>
|
||||
/// The Umbraco facade.
|
||||
@@ -35,5 +39,17 @@
|
||||
/// otherwise the facade keeps previewing according to whatever settings it is using already.</para>
|
||||
/// <para>Stops forcing preview when disposed.</para></remarks>
|
||||
IDisposable ForcedPreview(bool preview, Action<bool> callback = null);
|
||||
|
||||
// fixme - document
|
||||
/// <summary>
|
||||
/// Creates a fragment property.
|
||||
/// </summary>
|
||||
/// <param name="propertyType"></param>
|
||||
/// <param name="itemKey"></param>
|
||||
/// <param name="previewing"></param>
|
||||
/// <param name="referenceCacheLevel"></param>
|
||||
/// <param name="sourceValue"></param>
|
||||
/// <returns></returns>
|
||||
IPublishedProperty CreateFragmentProperty(PublishedPropertyType propertyType, Guid itemKey, bool previewing, PropertyCacheLevel referenceCacheLevel, object sourceValue = null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,15 +48,5 @@ namespace Umbraco.Web.PublishedCache
|
||||
/// <returns>The route.</returns>
|
||||
/// <remarks>Considers published or unpublished content depending on defaults.</remarks>
|
||||
string GetRouteById(int contentId);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a detached property.
|
||||
/// </summary>
|
||||
/// <param name="propertyType">The published property type.</param>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <param name="isPreviewing">A value indicating whether the property is created within a previewing context.</param>
|
||||
/// <returns>A detached property.</returns>
|
||||
/// <remarks>Implementations must check that propertyType.IsDetachedOrNested is true.</remarks>
|
||||
IPublishedProperty CreateDetachedProperty(PublishedPropertyType propertyType, object value, bool isPreviewing);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,9 +41,9 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
return "NuCache.Property.Recurse[" + DraftOrPub(previewing) + contentUid + ":" + typeAlias + "]";
|
||||
}
|
||||
|
||||
public static string PropertyValueSet(Guid contentUid, string typeAlias, bool previewing)
|
||||
public static string PropertyCacheValues(Guid contentUid, string typeAlias, bool previewing)
|
||||
{
|
||||
return "NuCache.Property.ValueSet[" + DraftOrPub(previewing) + contentUid + ":" + typeAlias + "]";
|
||||
return "NuCache.Property.CacheValues[" + DraftOrPub(previewing) + contentUid + ":" + typeAlias + "]";
|
||||
}
|
||||
|
||||
// routes still use int id and not Guid uid, because routable nodes must have
|
||||
|
||||
@@ -339,19 +339,6 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
|
||||
#endregion
|
||||
|
||||
#region Detached
|
||||
|
||||
// detached is something that needs to be refactored entirely eventually
|
||||
// detached property should accept the "container content" guid
|
||||
// etc
|
||||
|
||||
public IPublishedProperty CreateDetachedProperty(PublishedPropertyType propertyType, object value, bool isPreviewing)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Content types
|
||||
|
||||
public override PublishedContentType GetContentType(int id)
|
||||
|
||||
@@ -91,8 +91,8 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
var originDraft = origin.Draft == null ? null : PublishedContent.UnwrapIPublishedContent(origin.Draft);
|
||||
var originPublished = origin.Published == null ? null : PublishedContent.UnwrapIPublishedContent(origin.Published);
|
||||
|
||||
Draft = originDraft == null ? null : new PublishedContent(this, originDraft, facadeAccessor).CreateModel();
|
||||
Published = originPublished == null ? null : new PublishedContent(this, originPublished, facadeAccessor).CreateModel();
|
||||
Draft = originDraft == null ? null : new PublishedContent(this, originDraft).CreateModel();
|
||||
Published = originPublished == null ? null : new PublishedContent(this, originPublished).CreateModel();
|
||||
|
||||
ChildContentIds = new List<int>(origin.ChildContentIds); // needs to be *another* list
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
|
||||
namespace Umbraco.Web.PublishedCache.NuCache
|
||||
{
|
||||
@@ -94,6 +96,11 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
}
|
||||
}
|
||||
|
||||
public IPublishedProperty CreateFragmentProperty(PublishedPropertyType propertyType, Guid itemKey, bool previewing, PropertyCacheLevel referenceCacheLevel, object sourceValue = null)
|
||||
{
|
||||
return _service.CreateFragmentProperty(propertyType, itemKey, previewing, referenceCacheLevel, sourceValue);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IDisposable
|
||||
|
||||
@@ -17,6 +17,7 @@ using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
|
||||
using Umbraco.Core.Persistence.Repositories;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Services.Changes;
|
||||
using Umbraco.Web.Cache;
|
||||
@@ -1478,5 +1479,14 @@ AND cmsContentNu.nodeId IS NULL
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Fragments
|
||||
|
||||
public IPublishedProperty CreateFragmentProperty(PublishedPropertyType propertyType, Guid itemKey, bool previewing, PropertyCacheLevel referenceCacheLevel, object sourceValue = null)
|
||||
{
|
||||
return new PublishedFragmentProperty(_facadeAccessor, propertyType, itemKey, previewing, referenceCacheLevel, sourceValue);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Web.PublishedCache.NuCache.Navigable
|
||||
{
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.Xml.XPath;
|
||||
|
||||
namespace Umbraco.Web.PublishedCache.NuCache.Navigable
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Xml.Serialization;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
|
||||
@@ -12,27 +11,29 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
class Property : PublishedPropertyBase
|
||||
{
|
||||
private readonly IFacadeAccessor _facadeAccessor;
|
||||
private readonly object _dataValue;
|
||||
private readonly object _sourceValue;
|
||||
private readonly Guid _contentUid;
|
||||
private readonly bool _isPreviewing;
|
||||
private readonly bool _isMember;
|
||||
|
||||
readonly object _locko = new object();
|
||||
private readonly object _locko = new object();
|
||||
|
||||
private ValueSet _valueSet;
|
||||
private string _valueSetCacheKey;
|
||||
private bool _interInitialized;
|
||||
private object _interValue;
|
||||
private CacheValues _cacheValues;
|
||||
private string _valuesCacheKey;
|
||||
private string _recurseCacheKey;
|
||||
|
||||
// initializes a published content property with no value
|
||||
public Property(PublishedPropertyType propertyType, PublishedContent content, IFacadeAccessor facadeAccessor)
|
||||
: this(propertyType, content, null, facadeAccessor)
|
||||
public Property(PublishedPropertyType propertyType, IPublishedContent content, IFacadeAccessor facadeAccessor, PropertyCacheLevel referenceCacheLevel = PropertyCacheLevel.Content)
|
||||
: this(propertyType, content, null, facadeAccessor, referenceCacheLevel)
|
||||
{ }
|
||||
|
||||
// initializes a published content property with a value
|
||||
public Property(PublishedPropertyType propertyType, PublishedContent content, object valueSource, IFacadeAccessor facadeAccessor)
|
||||
: base(propertyType)
|
||||
public Property(PublishedPropertyType propertyType, IPublishedContent content, object sourceValue, IFacadeAccessor facadeAccessor, PropertyCacheLevel referenceCacheLevel = PropertyCacheLevel.Content)
|
||||
: base(propertyType, referenceCacheLevel)
|
||||
{
|
||||
_dataValue = valueSource;
|
||||
_sourceValue = sourceValue;
|
||||
_contentUid = content.Key;
|
||||
var inner = PublishedContent.UnwrapIPublishedContent(content);
|
||||
_isPreviewing = inner.IsPreviewing;
|
||||
@@ -42,60 +43,50 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
|
||||
// clone for previewing as draft a published content that is published and has no draft
|
||||
public Property(Property origin)
|
||||
: base(origin.PropertyType)
|
||||
: base(origin.PropertyType, origin.ReferenceCacheLevel)
|
||||
{
|
||||
_dataValue = origin._dataValue;
|
||||
_sourceValue = origin._sourceValue;
|
||||
_contentUid = origin._contentUid;
|
||||
_isPreviewing = true;
|
||||
_isMember = origin._isMember;
|
||||
_facadeAccessor = origin._facadeAccessor;
|
||||
}
|
||||
|
||||
// detached
|
||||
//internal Property(PublishedPropertyType propertyType, Guid contentUid, object valueSource, bool isPreviewing, bool isMember)
|
||||
// : base(propertyType)
|
||||
//{
|
||||
// _dataValue = valueSource;
|
||||
// _contentUid = contentUid;
|
||||
// _isPreviewing = isPreviewing;
|
||||
// _isMember = isMember;
|
||||
//}
|
||||
public override bool HasValue => _sourceValue != null
|
||||
&& ((_sourceValue is string) == false || string.IsNullOrWhiteSpace((string)_sourceValue) == false);
|
||||
|
||||
public override bool HasValue => _dataValue != null
|
||||
&& ((_dataValue is string) == false || string.IsNullOrWhiteSpace((string)_dataValue) == false);
|
||||
|
||||
private class ValueSet
|
||||
private class CacheValues
|
||||
{
|
||||
public bool SourceInitialized;
|
||||
public object Source;
|
||||
public bool ValueInitialized;
|
||||
public object Value;
|
||||
public bool ObjectInitialized;
|
||||
public object ObjectValue;
|
||||
public bool XPathInitialized;
|
||||
public object XPath;
|
||||
public object XPathValue;
|
||||
}
|
||||
|
||||
// used to cache the recursive *property* for this property
|
||||
internal string RecurseCacheKey => _recurseCacheKey
|
||||
?? (_recurseCacheKey = CacheKeys.PropertyRecurse(_contentUid, PropertyTypeAlias, _isPreviewing));
|
||||
|
||||
internal string ValueSetCacheKey => _valueSetCacheKey
|
||||
?? (_valueSetCacheKey = CacheKeys.PropertyValueSet(_contentUid, PropertyTypeAlias, _isPreviewing));
|
||||
// used to cache the CacheValues of this property
|
||||
internal string ValuesCacheKey => _valuesCacheKey
|
||||
?? (_valuesCacheKey = CacheKeys.PropertyCacheValues(_contentUid, PropertyTypeAlias, _isPreviewing));
|
||||
|
||||
private ValueSet GetValueSet(PropertyCacheLevel cacheLevel)
|
||||
private CacheValues GetCacheValues(PropertyCacheLevel cacheLevel)
|
||||
{
|
||||
ValueSet valueSet;
|
||||
CacheValues cacheValues;
|
||||
Facade facade;
|
||||
ICacheProvider cache;
|
||||
switch (cacheLevel)
|
||||
{
|
||||
case PropertyCacheLevel.None:
|
||||
// never cache anything
|
||||
valueSet = new ValueSet();
|
||||
cacheValues = new CacheValues();
|
||||
break;
|
||||
case PropertyCacheLevel.Content:
|
||||
// cache within the property object itself, ie within the content object
|
||||
valueSet = _valueSet ?? (_valueSet = new ValueSet());
|
||||
cacheValues = _cacheValues ?? (_cacheValues = new CacheValues());
|
||||
break;
|
||||
case PropertyCacheLevel.ContentCache:
|
||||
case PropertyCacheLevel.Snapshot:
|
||||
// cache within the snapshot cache, unless previewing, then use the facade or
|
||||
// snapshot cache (if we don't want to pollute the snapshot cache with short-lived
|
||||
// data) depending on settings
|
||||
@@ -106,39 +97,37 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
: ((_isPreviewing == false || FacadeService.FullCacheWhenPreviewing) && (_isMember == false)
|
||||
? facade.SnapshotCache
|
||||
: facade.FacadeCache);
|
||||
valueSet = GetValueSet(cache);
|
||||
cacheValues = GetCacheValues(cache);
|
||||
break;
|
||||
case PropertyCacheLevel.Request:
|
||||
case PropertyCacheLevel.Facade:
|
||||
// cache within the facade cache
|
||||
facade = (Facade)_facadeAccessor.Facade;
|
||||
facade = (Facade) _facadeAccessor.Facade;
|
||||
cache = facade?.FacadeCache;
|
||||
valueSet = GetValueSet(cache);
|
||||
cacheValues = GetCacheValues(cache);
|
||||
break;
|
||||
default:
|
||||
throw new InvalidOperationException("Invalid cache level.");
|
||||
}
|
||||
return valueSet;
|
||||
return cacheValues;
|
||||
}
|
||||
|
||||
private ValueSet GetValueSet(ICacheProvider cache)
|
||||
private CacheValues GetCacheValues(ICacheProvider cache)
|
||||
{
|
||||
if (cache == null) // no cache, don't cache
|
||||
return new ValueSet();
|
||||
return (ValueSet) cache.GetCacheItem(ValueSetCacheKey, () => new ValueSet());
|
||||
return new CacheValues();
|
||||
return (CacheValues) cache.GetCacheItem(ValuesCacheKey, () => new CacheValues());
|
||||
}
|
||||
|
||||
private object GetSourceValue()
|
||||
private object GetInterValue()
|
||||
{
|
||||
var valueSet = GetValueSet(PropertyType.SourceCacheLevel);
|
||||
if (valueSet.SourceInitialized == false)
|
||||
{
|
||||
valueSet.Source = PropertyType.ConvertDataToSource(_dataValue, _isPreviewing);
|
||||
valueSet.SourceInitialized = true;
|
||||
}
|
||||
return valueSet.Source;
|
||||
if (_interInitialized) return _interValue;
|
||||
|
||||
_interValue = PropertyType.ConvertSourceToInter(_sourceValue, _isPreviewing);
|
||||
_interInitialized = true;
|
||||
return _interValue;
|
||||
}
|
||||
|
||||
public override object DataValue => _dataValue;
|
||||
public override object SourceValue => _sourceValue;
|
||||
|
||||
public override object Value
|
||||
{
|
||||
@@ -146,13 +135,13 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
{
|
||||
lock (_locko)
|
||||
{
|
||||
var valueSet = GetValueSet(PropertyType.ObjectCacheLevel);
|
||||
if (valueSet.ValueInitialized == false)
|
||||
{
|
||||
valueSet.Value = PropertyType.ConvertSourceToObject(GetSourceValue(), _isPreviewing);
|
||||
valueSet.ValueInitialized = true;
|
||||
}
|
||||
return valueSet.Value;
|
||||
var cacheValues = GetCacheValues(PropertyType.CacheLevel);
|
||||
if (cacheValues.ObjectInitialized) return cacheValues.ObjectValue;
|
||||
|
||||
// initial reference cache level always is .Content
|
||||
cacheValues.ObjectValue = PropertyType.ConvertInterToObject(PropertyCacheLevel.Content, GetInterValue(), _isPreviewing);
|
||||
cacheValues.ObjectInitialized = true;
|
||||
return cacheValues.ObjectValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -163,13 +152,13 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
{
|
||||
lock (_locko)
|
||||
{
|
||||
var valueSet = GetValueSet(PropertyType.XPathCacheLevel);
|
||||
if (valueSet.XPathInitialized == false)
|
||||
{
|
||||
valueSet.XPath = PropertyType.ConvertSourceToXPath(GetSourceValue(), _isPreviewing);
|
||||
valueSet.XPathInitialized = true;
|
||||
}
|
||||
return valueSet.XPath;
|
||||
var cacheValues = GetCacheValues(PropertyType.CacheLevel);
|
||||
if (cacheValues.XPathInitialized) return cacheValues.XPathValue;
|
||||
|
||||
// initial reference cache level always is .Content
|
||||
cacheValues.XPathValue = PropertyType.ConvertInterToXPath(PropertyCacheLevel.Content, GetInterValue(), _isPreviewing);
|
||||
cacheValues.XPathInitialized = true;
|
||||
return cacheValues.XPathValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Web.Models;
|
||||
using Umbraco.Web.PublishedCache.NuCache.DataSource;
|
||||
@@ -29,7 +28,18 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
|
||||
_urlName = _contentData.Name.ToUrlSegment();
|
||||
IsPreviewing = _contentData.Published == false;
|
||||
PropertiesArray = CreateProperties(this, contentData.Properties);
|
||||
|
||||
var values = contentData.Properties;
|
||||
PropertiesArray = _contentNode.ContentType
|
||||
.PropertyTypes
|
||||
.Select(propertyType =>
|
||||
{
|
||||
object value;
|
||||
return values.TryGetValue(propertyType.PropertyTypeAlias, out value) && value != null
|
||||
? new Property(propertyType, this, value, _facadeAccessor) as IPublishedProperty
|
||||
: new Property(propertyType, this, _facadeAccessor) as IPublishedProperty;
|
||||
})
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
private string GetProfileNameById(int id)
|
||||
@@ -56,25 +66,11 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
return user?.Name;
|
||||
}
|
||||
|
||||
private IPublishedProperty[] CreateProperties(PublishedContent content, IDictionary<string, object> values)
|
||||
{
|
||||
return content._contentNode.ContentType
|
||||
.PropertyTypes
|
||||
.Select(propertyType =>
|
||||
{
|
||||
object value;
|
||||
return values.TryGetValue(propertyType.PropertyTypeAlias, out value)
|
||||
? new Property(propertyType, content, value, _facadeAccessor) as IPublishedProperty
|
||||
: new Property(propertyType, content, _facadeAccessor) as IPublishedProperty;
|
||||
})
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
// (see ContentNode.CloneParent)
|
||||
public PublishedContent(ContentNode contentNode, PublishedContent origin, IFacadeAccessor facadeAccessor)
|
||||
public PublishedContent(ContentNode contentNode, PublishedContent origin)
|
||||
{
|
||||
_contentNode = contentNode;
|
||||
_facadeAccessor = facadeAccessor;
|
||||
_facadeAccessor = origin._facadeAccessor;
|
||||
_contentData = origin._contentData;
|
||||
|
||||
_urlName = origin._urlName;
|
||||
@@ -87,9 +83,9 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
}
|
||||
|
||||
// clone for previewing as draft a published content that is published and has no draft
|
||||
private PublishedContent(PublishedContent origin, IFacadeAccessor facadeAccessor)
|
||||
private PublishedContent(PublishedContent origin)
|
||||
{
|
||||
_facadeAccessor = facadeAccessor;
|
||||
_facadeAccessor = origin._facadeAccessor;
|
||||
_contentNode = origin._contentNode;
|
||||
_contentData = origin._contentData;
|
||||
|
||||
@@ -106,32 +102,16 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
|
||||
// this is for tests purposes
|
||||
// args are: current facade (may be null), previewing, content id - returns: content
|
||||
private static Func<IFacade, bool, int, IPublishedContent> _getContentByIdFunc =
|
||||
(facade, previewing, id) => facade.ContentCache.GetById(previewing, id);
|
||||
private static Func<IFacade, bool, int, IPublishedContent> _getMediaByIdFunc =
|
||||
(facade, previewing, id) => facade.MediaCache.GetById(previewing, id);
|
||||
|
||||
internal static Func<IFacade, bool, int, IPublishedContent> GetContentByIdFunc
|
||||
{
|
||||
get { return _getContentByIdFunc; }
|
||||
set
|
||||
{
|
||||
_getContentByIdFunc = value;
|
||||
}
|
||||
}
|
||||
internal static Func<IFacade, bool, int, IPublishedContent> GetContentByIdFunc { get; set; }
|
||||
= (facade, previewing, id) => facade.ContentCache.GetById(previewing, id);
|
||||
|
||||
internal static Func<IFacade, bool, int, IPublishedContent> GetMediaByIdFunc
|
||||
{
|
||||
get { return _getMediaByIdFunc; }
|
||||
set
|
||||
{
|
||||
_getMediaByIdFunc = value;
|
||||
}
|
||||
}
|
||||
internal static Func<IFacade, bool, int, IPublishedContent> GetMediaByIdFunc { get; set; }
|
||||
= (facade, previewing, id) => facade.MediaCache.GetById(previewing, id);
|
||||
|
||||
private IPublishedContent GetContentById(bool previewing, int id)
|
||||
{
|
||||
return _getContentByIdFunc(_facadeAccessor.Facade, previewing, id);
|
||||
return GetContentByIdFunc(_facadeAccessor.Facade, previewing, id);
|
||||
}
|
||||
|
||||
private IEnumerable<IPublishedContent> GetContentByIds(bool previewing, IEnumerable<int> ids)
|
||||
@@ -147,14 +127,14 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
// ReSharper disable once LoopCanBeConvertedToQuery
|
||||
foreach (var id in ids)
|
||||
{
|
||||
var content = _getContentByIdFunc(facade, previewing, id);
|
||||
var content = GetContentByIdFunc(facade, previewing, id);
|
||||
if (content != null) yield return content;
|
||||
}
|
||||
}
|
||||
|
||||
private IPublishedContent GetMediaById(bool previewing, int id)
|
||||
{
|
||||
return _getMediaByIdFunc(_facadeAccessor.Facade, previewing, id);
|
||||
return GetMediaByIdFunc(_facadeAccessor.Facade, previewing, id);
|
||||
}
|
||||
|
||||
private IEnumerable<IPublishedContent> GetMediaByIds(bool previewing, IEnumerable<int> ids)
|
||||
@@ -166,7 +146,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
// ReSharper disable once LoopCanBeConvertedToQuery
|
||||
foreach (var id in ids)
|
||||
{
|
||||
var content = _getMediaByIdFunc(facade, previewing, id);
|
||||
var content = GetMediaByIdFunc(facade, previewing, id);
|
||||
if (content != null) yield return content;
|
||||
}
|
||||
}
|
||||
@@ -226,7 +206,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
{
|
||||
get
|
||||
{
|
||||
var cache = GetAppropriateCurrentFacadeCache();
|
||||
var cache = GetAppropriateCache();
|
||||
if (cache == null || FacadeService.CachePublishedContentChildren == false)
|
||||
return GetChildren();
|
||||
|
||||
@@ -258,7 +238,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
// Q: perfs-wise, is it better than having the store managed an ordered list
|
||||
}
|
||||
|
||||
public override ICollection<IPublishedProperty> Properties => PropertiesArray;
|
||||
public override IEnumerable<IPublishedProperty> Properties => PropertiesArray;
|
||||
|
||||
public override IPublishedProperty GetProperty(string alias)
|
||||
{
|
||||
@@ -272,7 +252,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
var property = GetProperty(alias);
|
||||
if (recurse == false) return property;
|
||||
|
||||
var cache = GetAppropriateCurrentFacadeCache();
|
||||
var cache = GetAppropriateCache();
|
||||
if (cache == null)
|
||||
return base.GetProperty(alias, true);
|
||||
|
||||
@@ -287,7 +267,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
#region Caching
|
||||
|
||||
// beware what you use that one for - you don't want to cache its result
|
||||
private ICacheProvider GetAppropriateCurrentFacadeCache()
|
||||
private ICacheProvider GetAppropriateCache()
|
||||
{
|
||||
var facade = (Facade) _facadeAccessor.Facade;
|
||||
var cache = facade == null
|
||||
@@ -335,9 +315,9 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
if (IsPreviewing)
|
||||
return this;
|
||||
|
||||
var cache = GetAppropriateCurrentFacadeCache();
|
||||
if (cache == null) return new PublishedContent(this, _facadeAccessor).CreateModel();
|
||||
return (IPublishedContent) cache.GetCacheItem(AsPreviewingCacheKey, () => new PublishedContent(this, _facadeAccessor).CreateModel());
|
||||
var cache = GetAppropriateCache();
|
||||
if (cache == null) return new PublishedContent(this).CreateModel();
|
||||
return (IPublishedContent) cache.GetCacheItem(AsPreviewingCacheKey, () => new PublishedContent(this).CreateModel());
|
||||
}
|
||||
|
||||
// used by Navigable.Source,...
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
using System;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
|
||||
namespace Umbraco.Web.PublishedCache.NuCache
|
||||
{
|
||||
internal class PublishedFragmentProperty : PublishedCache.PublishedFragmentProperty
|
||||
{
|
||||
private readonly IFacadeAccessor _facadeAccessor;
|
||||
private string _valuesCacheKey;
|
||||
|
||||
// initializes a published item property
|
||||
public PublishedFragmentProperty(IFacadeAccessor facadeAccessor, PublishedPropertyType propertyType, Guid itemKey, bool previewing, PropertyCacheLevel referenceCacheLevel, object sourceValue = null)
|
||||
: base(propertyType, itemKey, previewing, referenceCacheLevel, sourceValue)
|
||||
{
|
||||
_facadeAccessor = facadeAccessor;
|
||||
}
|
||||
|
||||
// used to cache the CacheValues of this property
|
||||
internal string ValuesCacheKey => _valuesCacheKey
|
||||
?? (_valuesCacheKey = CacheKeys.PropertyCacheValues(ItemUid, PropertyTypeAlias, IsPreviewing));
|
||||
|
||||
protected override CacheValues GetSnapshotCacheValues()
|
||||
{
|
||||
// cache within the snapshot cache, unless previewing, then use the facade or
|
||||
// snapshot cache (if we don't want to pollute the snapshot cache with short-lived
|
||||
// data) depending on settings
|
||||
// for members, always cache in the facade cache - never pollute snapshot cache
|
||||
var facade = (Facade)_facadeAccessor.Facade;
|
||||
var cache = facade == null
|
||||
? null
|
||||
: ((IsPreviewing == false || FacadeService.FullCacheWhenPreviewing) && (IsMember == false)
|
||||
? facade.SnapshotCache
|
||||
: facade.FacadeCache);
|
||||
return GetCacheValues(cache);
|
||||
}
|
||||
|
||||
protected override CacheValues GetFacadeCacheValues()
|
||||
{
|
||||
// cache within the facade cache
|
||||
var facade = (Facade) _facadeAccessor.Facade;
|
||||
var cache = facade?.FacadeCache;
|
||||
return GetCacheValues(cache);
|
||||
}
|
||||
|
||||
private CacheValues GetCacheValues(ICacheProvider cache)
|
||||
{
|
||||
// no cache, don't cache
|
||||
return cache == null
|
||||
? new CacheValues()
|
||||
: (CacheValues) cache.GetCacheItem(ValuesCacheKey, () => new CacheValues());
|
||||
}
|
||||
}
|
||||
}
|
||||
79
src/Umbraco.Web/PublishedCache/PublishedFragment.cs
Normal file
79
src/Umbraco.Web/PublishedCache/PublishedFragment.cs
Normal file
@@ -0,0 +1,79 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
|
||||
namespace Umbraco.Web.PublishedCache
|
||||
{
|
||||
// fixme document & review
|
||||
//
|
||||
// these things should NOT manage any tree-like elements (fixme:discuss?)
|
||||
// Lee's NestedContent package DetachedPublishedContent does NOT
|
||||
// and yet we need to be able to figure out what happens when nesting things?
|
||||
//
|
||||
// how would we create MODELS for published items? should it be automatic
|
||||
// or explicit when creating the items? probably cannot be automatic because
|
||||
// then, how would we cast the returned object?
|
||||
//
|
||||
// note: could also have a totally detached one in Core?
|
||||
//
|
||||
internal class PublishedFragment : IPublishedFragment
|
||||
{
|
||||
private readonly IFacadeAccessor _facadeAccessor;
|
||||
|
||||
public PublishedFragment(PublishedContentType contentType,
|
||||
IFacadeAccessor facadeAccessor, PropertyCacheLevel referenceCacheLevel,
|
||||
Guid key, Dictionary<string, object> values,
|
||||
bool previewing)
|
||||
{
|
||||
ContentType = contentType;
|
||||
_facadeAccessor = facadeAccessor;
|
||||
Key = key;
|
||||
|
||||
// ensure we ignore case for property aliases
|
||||
var comparer = values.Comparer;
|
||||
var ignoreCase = comparer == StringComparer.OrdinalIgnoreCase || comparer == StringComparer.InvariantCultureIgnoreCase || comparer == StringComparer.CurrentCultureIgnoreCase;
|
||||
if (ignoreCase == false)
|
||||
values = new Dictionary<string, object>(values, StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
_propertiesArray = contentType
|
||||
.PropertyTypes
|
||||
.Select(propertyType =>
|
||||
{
|
||||
object value;
|
||||
values.TryGetValue(propertyType.PropertyTypeAlias, out value);
|
||||
return _facadeAccessor.Facade.CreateFragmentProperty(propertyType, Key, previewing, referenceCacheLevel, value);
|
||||
})
|
||||
.ToArray();
|
||||
|
||||
}
|
||||
|
||||
#region ContentType
|
||||
|
||||
public PublishedContentType ContentType { get; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Content
|
||||
|
||||
public Guid Key { get; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
private readonly IPublishedProperty[] _propertiesArray;
|
||||
|
||||
public IEnumerable<IPublishedProperty> Properties => _propertiesArray;
|
||||
|
||||
public IPublishedProperty GetProperty(string alias)
|
||||
{
|
||||
var index = ContentType.GetPropertyIndex(alias);
|
||||
var property = index < 0 ? null : _propertiesArray[index];
|
||||
return property;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
165
src/Umbraco.Web/PublishedCache/PublishedFragmentProperty.cs
Normal file
165
src/Umbraco.Web/PublishedCache/PublishedFragmentProperty.cs
Normal file
@@ -0,0 +1,165 @@
|
||||
using System;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
|
||||
namespace Umbraco.Web.PublishedCache
|
||||
{
|
||||
internal abstract class PublishedFragmentProperty : PublishedPropertyBase
|
||||
{
|
||||
private readonly object _locko = new object();
|
||||
private readonly object _sourceValue;
|
||||
|
||||
protected readonly Guid ItemUid;
|
||||
protected readonly bool IsPreviewing;
|
||||
protected readonly bool IsMember;
|
||||
|
||||
private bool _interInitialized;
|
||||
private object _interValue;
|
||||
private CacheValues _cacheValues;
|
||||
|
||||
// initializes a published item property
|
||||
protected PublishedFragmentProperty(PublishedPropertyType propertyType, Guid itemKey, bool previewing, PropertyCacheLevel referenceCacheLevel, object sourceValue = null)
|
||||
: base(propertyType, referenceCacheLevel)
|
||||
{
|
||||
_sourceValue = sourceValue;
|
||||
ItemUid = itemKey;
|
||||
IsPreviewing = previewing;
|
||||
IsMember = propertyType.ContentType.ItemType == PublishedItemType.Member;
|
||||
}
|
||||
|
||||
public override bool HasValue => _sourceValue != null
|
||||
&& ((_sourceValue is string) == false || string.IsNullOrWhiteSpace((string)_sourceValue) == false);
|
||||
|
||||
protected class CacheValues
|
||||
{
|
||||
public bool ObjectInitialized;
|
||||
public object ObjectValue;
|
||||
public bool XPathInitialized;
|
||||
public object XPathValue;
|
||||
}
|
||||
|
||||
private static void ValidateCacheLevel(PropertyCacheLevel cacheLevel)
|
||||
{
|
||||
switch (cacheLevel)
|
||||
{
|
||||
case PropertyCacheLevel.Content:
|
||||
case PropertyCacheLevel.Snapshot:
|
||||
case PropertyCacheLevel.Facade:
|
||||
case PropertyCacheLevel.None:
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Invalid cache level.");
|
||||
}
|
||||
}
|
||||
|
||||
private void GetCacheLevels(out PropertyCacheLevel cacheLevel, out PropertyCacheLevel referenceCacheLevel)
|
||||
{
|
||||
// based upon the current reference cache level (ReferenceCacheLevel) and this property
|
||||
// cache level (PropertyType.CacheLevel), determines both the actual cache level for the
|
||||
// property, and the new reference cache level.
|
||||
|
||||
// sanity checks
|
||||
ValidateCacheLevel(ReferenceCacheLevel);
|
||||
ValidateCacheLevel(PropertyType.CacheLevel);
|
||||
|
||||
// if the property cache level is 'shorter-termed' that the reference
|
||||
// then use it and it becomes the new reference, else use Content and
|
||||
// don't change the reference.
|
||||
//
|
||||
// examples:
|
||||
// currently (reference) caching at facade, property specifies
|
||||
// snapshot, ok to use content. OTOH, currently caching at snapshot,
|
||||
// property specifies facade, need to use facade.
|
||||
//
|
||||
if (PropertyType.CacheLevel > ReferenceCacheLevel)
|
||||
{
|
||||
cacheLevel = PropertyType.CacheLevel;
|
||||
referenceCacheLevel = cacheLevel;
|
||||
}
|
||||
else
|
||||
{
|
||||
cacheLevel = PropertyCacheLevel.Content;
|
||||
referenceCacheLevel = ReferenceCacheLevel;
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract CacheValues GetSnapshotCacheValues();
|
||||
protected abstract CacheValues GetFacadeCacheValues();
|
||||
|
||||
private CacheValues GetCacheValues(PropertyCacheLevel cacheLevel)
|
||||
{
|
||||
CacheValues cacheValues;
|
||||
switch (cacheLevel)
|
||||
{
|
||||
case PropertyCacheLevel.None:
|
||||
// never cache anything
|
||||
cacheValues = new CacheValues();
|
||||
break;
|
||||
case PropertyCacheLevel.Content:
|
||||
// cache within the property object itself, ie within the content object
|
||||
cacheValues = _cacheValues ?? (_cacheValues = new CacheValues());
|
||||
break;
|
||||
case PropertyCacheLevel.Snapshot:
|
||||
// cache within the snapshot cache, depending...
|
||||
cacheValues = GetSnapshotCacheValues();
|
||||
break;
|
||||
case PropertyCacheLevel.Facade:
|
||||
// cache within the facade cache
|
||||
cacheValues = GetFacadeCacheValues();
|
||||
break;
|
||||
default:
|
||||
throw new InvalidOperationException("Invalid cache level.");
|
||||
}
|
||||
return cacheValues;
|
||||
}
|
||||
|
||||
private object GetInterValue()
|
||||
{
|
||||
if (_interInitialized) return _interValue;
|
||||
|
||||
_interValue = PropertyType.ConvertSourceToInter(_sourceValue, IsPreviewing);
|
||||
_interInitialized = true;
|
||||
return _interValue;
|
||||
}
|
||||
|
||||
public override object SourceValue => _sourceValue;
|
||||
|
||||
public override object Value
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_locko)
|
||||
{
|
||||
PropertyCacheLevel cacheLevel, referenceCacheLevel;
|
||||
GetCacheLevels(out cacheLevel, out referenceCacheLevel);
|
||||
|
||||
var cacheValues = GetCacheValues(cacheLevel);
|
||||
if (cacheValues.ObjectInitialized) return cacheValues.ObjectValue;
|
||||
|
||||
cacheValues.ObjectValue = PropertyType.ConvertInterToObject(referenceCacheLevel, GetInterValue(), IsPreviewing);
|
||||
cacheValues.ObjectInitialized = true;
|
||||
return cacheValues.ObjectValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override object XPathValue
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_locko)
|
||||
{
|
||||
PropertyCacheLevel cacheLevel, referenceCacheLevel;
|
||||
GetCacheLevels(out cacheLevel, out referenceCacheLevel);
|
||||
|
||||
var cacheValues = GetCacheValues(cacheLevel);
|
||||
if (cacheValues.XPathInitialized) return cacheValues.XPathValue;
|
||||
|
||||
cacheValues.XPathValue = PropertyType.ConvertInterToXPath(referenceCacheLevel, GetInterValue(), IsPreviewing);
|
||||
cacheValues.XPathInitialized = true;
|
||||
return cacheValues.XPathValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -70,7 +70,7 @@ namespace Umbraco.Web.PublishedCache
|
||||
|
||||
public override IEnumerable<IPublishedContent> Children => Enumerable.Empty<IPublishedContent>();
|
||||
|
||||
public override ICollection<IPublishedProperty> Properties => _properties;
|
||||
public override IEnumerable<IPublishedProperty> Properties => _properties;
|
||||
|
||||
public override IPublishedProperty GetProperty(string alias, bool recurse)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
|
||||
namespace Umbraco.Web.PublishedCache
|
||||
{
|
||||
@@ -16,7 +17,7 @@ namespace Umbraco.Web.PublishedCache
|
||||
private readonly Lazy<object> _xpathValue;
|
||||
private readonly bool _isPreviewing;
|
||||
|
||||
public override object DataValue => _dbVal;
|
||||
public override object SourceValue => _dbVal;
|
||||
|
||||
public override bool HasValue => _dbVal != null && _dbVal.ToString().Trim().Length > 0;
|
||||
|
||||
@@ -35,14 +36,14 @@ namespace Umbraco.Web.PublishedCache
|
||||
|
||||
// note: maintaining two ctors to make sure we understand what we do when calling them
|
||||
public RawValueProperty(PublishedPropertyType propertyType, bool isPreviewing = false)
|
||||
: base(propertyType)
|
||||
: base(propertyType, PropertyCacheLevel.Unknown) // cache level is ignored
|
||||
{
|
||||
_dbVal = null;
|
||||
_isPreviewing = isPreviewing;
|
||||
|
||||
_sourceValue = new Lazy<object>(() => PropertyType.ConvertDataToSource(_dbVal, _isPreviewing));
|
||||
_objectValue = new Lazy<object>(() => PropertyType.ConvertSourceToObject(_sourceValue.Value, _isPreviewing));
|
||||
_xpathValue = new Lazy<object>(() => PropertyType.ConvertSourceToXPath(_sourceValue.Value, _isPreviewing));
|
||||
_sourceValue = new Lazy<object>(() => PropertyType.ConvertSourceToInter(_dbVal, _isPreviewing));
|
||||
_objectValue = new Lazy<object>(() => PropertyType.ConvertInterToObject(PropertyCacheLevel.Unknown, _sourceValue.Value, _isPreviewing));
|
||||
_xpathValue = new Lazy<object>(() => PropertyType.ConvertInterToXPath(PropertyCacheLevel.Unknown, _sourceValue.Value, _isPreviewing));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -57,5 +57,12 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
protected override void DisposeResources()
|
||||
{ }
|
||||
}
|
||||
|
||||
public IPublishedProperty CreateFragmentProperty(PublishedPropertyType propertyType, Guid itemKey, bool previewing, PropertyCacheLevel referenceCacheLevel, object sourceValue = null)
|
||||
{
|
||||
// fixme
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user