2012-10-10 08:42:54 -02:00
using System ;
using System.Collections.Generic ;
using System.Collections.Specialized ;
2013-10-09 13:32:58 +11:00
using System.ComponentModel ;
2013-02-09 04:05:01 +06:00
using System.Diagnostics ;
2012-10-10 08:42:54 -02:00
using System.Linq ;
using System.Reflection ;
using System.Runtime.Serialization ;
2013-01-14 11:02:12 -01:00
using System.Web ;
2012-10-10 08:42:54 -02:00
using Umbraco.Core.Models.EntityBase ;
2016-05-18 16:06:59 +02:00
using Umbraco.Core.Services ;
2012-10-10 08:42:54 -02:00
namespace Umbraco.Core.Models
{
/// <summary>
/// Represents an abstract class for base Content properties and methods
/// </summary>
2014-02-20 22:34:54 +11:00
[Serializable]
[DataContract(IsReference = true)]
2013-02-09 04:05:01 +06:00
[DebuggerDisplay("Id: {Id}, Name: {Name}, ContentType: {ContentTypeBase.Alias}")]
2012-10-10 08:42:54 -02:00
public abstract class ContentBase : Entity , IContentBase
{
2017-11-07 19:49:14 +01:00
private static readonly Lazy < PropertySelectors > Ps = new Lazy < PropertySelectors > ( ) ;
private int _contentTypeId ;
2012-10-10 08:42:54 -02:00
protected IContentTypeComposition ContentTypeBase ;
2016-11-03 10:31:44 +01:00
2012-11-13 14:30:05 -01:00
private Lazy < int > _parentId ;
2012-10-10 08:42:54 -02:00
private int _level ;
private string _path ;
2017-11-07 19:49:14 +01:00
private int _sortOrder ;
2012-10-10 08:42:54 -02:00
private bool _trashed ;
2017-11-07 19:49:14 +01:00
private int _creatorId ;
2017-11-10 11:27:12 +01:00
private int _writerId ;
2017-11-07 19:49:14 +01:00
// fixme need to deal with localized names, how?
// for the time being, this is the node text = unique
private string _name ;
2012-10-10 08:42:54 -02:00
private PropertyCollection _properties ;
2017-11-07 19:49:14 +01:00
private readonly List < Property > _invalidProperties = new List < Property > ( ) ;
[EditorBrowsable(EditorBrowsableState.Never)]
IDictionary < string , object > IUmbracoEntity . AdditionalData = > _lazyAdditionalData . Value ;
private readonly Lazy < Dictionary < string , object > > _lazyAdditionalData = new Lazy < Dictionary < string , object > > ( ) ;
2012-10-10 08:42:54 -02:00
2013-01-15 10:12:23 -01:00
/// <summary>
2017-11-07 19:49:14 +01:00
/// Initializes a new instance of the <see cref="ContentBase"/> class.
2013-01-15 10:12:23 -01:00
/// </summary>
protected ContentBase ( string name , int parentId , IContentTypeComposition contentType , PropertyCollection properties )
2017-11-07 19:49:14 +01:00
: this ( name , contentType , properties )
2012-10-10 08:42:54 -02:00
{
2017-05-31 09:18:09 +02:00
if ( parentId = = 0 ) throw new ArgumentOutOfRangeException ( nameof ( parentId ) ) ;
2012-11-13 14:30:05 -01:00
_parentId = new Lazy < int > ( ( ) = > parentId ) ;
2012-10-10 08:42:54 -02:00
}
2013-01-15 10:12:23 -01:00
/// <summary>
2017-11-07 19:49:14 +01:00
/// Initializes a new instance of the <see cref="ContentBase"/> class.
2013-01-15 10:12:23 -01:00
/// </summary>
protected ContentBase ( string name , IContentBase parent , IContentTypeComposition contentType , PropertyCollection properties )
2017-11-07 19:49:14 +01:00
: this ( name , contentType , properties )
2017-07-20 11:21:28 +02:00
{
if ( parent = = null ) throw new ArgumentNullException ( nameof ( parent ) ) ;
2017-11-07 19:49:14 +01:00
_parentId = new Lazy < int > ( ( ) = > parent . Id ) ;
}
2012-12-16 04:02:29 +05:00
2017-11-07 19:49:14 +01:00
private ContentBase ( string name , IContentTypeComposition contentType , PropertyCollection properties )
{
2017-07-20 11:21:28 +02:00
ContentTypeBase = contentType ? ? throw new ArgumentNullException ( nameof ( contentType ) ) ;
2013-01-15 10:21:24 -01:00
2017-11-07 19:49:14 +01:00
// initially, all new instances have
Id = 0 ; // no identity
Version = Guid . NewGuid ( ) ; // a new unique version id
2013-01-15 10:12:23 -01:00
_name = name ;
2017-07-20 11:21:28 +02:00
_contentTypeId = contentType . Id ;
_properties = properties ? ? throw new ArgumentNullException ( nameof ( properties ) ) ;
_properties . EnsurePropertyTypes ( PropertyTypes ) ;
}
2012-12-16 04:02:29 +05:00
2017-11-07 19:49:14 +01:00
// ReSharper disable once ClassNeverInstantiated.Local
2016-06-21 18:11:03 +02:00
private class PropertySelectors
{
public readonly PropertyInfo ParentIdSelector = ExpressionHelper . GetPropertyInfo < ContentBase , int > ( x = > x . ParentId ) ;
public readonly PropertyInfo LevelSelector = ExpressionHelper . GetPropertyInfo < ContentBase , int > ( x = > x . Level ) ;
public readonly PropertyInfo PathSelector = ExpressionHelper . GetPropertyInfo < ContentBase , string > ( x = > x . Path ) ;
2017-11-07 19:49:14 +01:00
public readonly PropertyInfo SortOrderSelector = ExpressionHelper . GetPropertyInfo < ContentBase , int > ( x = > x . SortOrder ) ;
2016-06-21 18:11:03 +02:00
public readonly PropertyInfo TrashedSelector = ExpressionHelper . GetPropertyInfo < ContentBase , bool > ( x = > x . Trashed ) ;
2017-11-07 19:49:14 +01:00
public readonly PropertyInfo NameSelector = ExpressionHelper . GetPropertyInfo < ContentBase , string > ( x = > x . Name ) ;
public readonly PropertyInfo CreatorIdSelector = ExpressionHelper . GetPropertyInfo < ContentBase , int > ( x = > x . CreatorId ) ;
2016-06-21 18:11:03 +02:00
public readonly PropertyInfo DefaultContentTypeIdSelector = ExpressionHelper . GetPropertyInfo < ContentBase , int > ( x = > x . ContentTypeId ) ;
public readonly PropertyInfo PropertyCollectionSelector = ExpressionHelper . GetPropertyInfo < ContentBase , PropertyCollection > ( x = > x . Properties ) ;
2017-11-10 11:27:12 +01:00
public readonly PropertyInfo WriterSelector = ExpressionHelper . GetPropertyInfo < ContentBase , int > ( x = > x . WriterId ) ;
2016-11-03 10:31:44 +01:00
}
2012-10-10 08:42:54 -02:00
protected void PropertiesChanged ( object sender , NotifyCollectionChangedEventArgs e )
{
2016-06-21 18:11:03 +02:00
OnPropertyChanged ( Ps . Value . PropertyCollectionSelector ) ;
2012-10-10 08:42:54 -02:00
}
/// <summary>
2017-11-07 19:49:14 +01:00
/// Gets or sets the identifier of the parent entity.
2012-10-10 08:42:54 -02:00
/// </summary>
[DataMember]
public virtual int ParentId
{
2012-12-16 04:02:29 +05:00
get
{
2017-07-20 11:21:28 +02:00
var val = _parentId . Value ;
if ( val = = 0 )
{
throw new InvalidOperationException ( "The ParentId cannot have a value of 0. Perhaps the parent object used to instantiate this object has not been persisted to the data store." ) ;
}
return val ;
2012-12-16 04:02:29 +05:00
}
2012-10-10 08:42:54 -02:00
set
{
2012-11-13 14:30:05 -01:00
_parentId = new Lazy < int > ( ( ) = > value ) ;
2016-06-21 18:11:03 +02:00
OnPropertyChanged ( Ps . Value . ParentIdSelector ) ;
2012-10-10 08:42:54 -02:00
}
}
2016-05-18 10:55:19 +02:00
/// <summary>
2017-11-07 19:49:14 +01:00
/// Sets the identifier of the parent entity.
2016-05-18 10:55:19 +02:00
/// </summary>
2016-07-08 17:58:01 +02:00
/// <param name="parentId">Id of the Parent</param>
2017-11-07 19:49:14 +01:00
protected internal void SetLazyParentId ( Lazy < int > parentId )
2016-05-18 10:55:19 +02:00
{
_parentId = parentId ;
2016-07-08 17:58:01 +02:00
OnPropertyChanged ( Ps . Value . ParentIdSelector ) ;
2016-05-18 10:55:19 +02:00
}
2012-10-10 08:42:54 -02:00
/// <summary>
2017-11-07 19:49:14 +01:00
/// Gets or sets the level of the entity.
2012-10-10 08:42:54 -02:00
/// </summary>
[DataMember]
2017-11-07 19:49:14 +01:00
public virtual int Level
2012-10-10 08:42:54 -02:00
{
2017-11-07 19:49:14 +01:00
get = > _level ;
set = > SetPropertyValueAndDetectChanges ( value , ref _level , Ps . Value . LevelSelector ) ;
2012-10-10 08:42:54 -02:00
}
/// <summary>
2017-11-07 19:49:14 +01:00
/// Gets or sets the path of the entity.
2012-10-10 08:42:54 -02:00
/// </summary>
[DataMember]
2017-11-07 19:49:14 +01:00
public virtual string Path //Setting this value should be handled by the class not the user
2012-10-10 08:42:54 -02:00
{
2017-11-07 19:49:14 +01:00
get = > _path ;
set = > SetPropertyValueAndDetectChanges ( value , ref _path , Ps . Value . PathSelector ) ;
2012-10-10 08:42:54 -02:00
}
/// <summary>
2017-11-07 19:49:14 +01:00
/// Gets or sets the sort order of the entity.
2012-10-10 08:42:54 -02:00
/// </summary>
[DataMember]
2017-11-07 19:49:14 +01:00
public virtual int SortOrder
2012-10-10 08:42:54 -02:00
{
2017-11-07 19:49:14 +01:00
get = > _sortOrder ;
set = > SetPropertyValueAndDetectChanges ( value , ref _sortOrder , Ps . Value . SortOrderSelector ) ;
2012-10-10 08:42:54 -02:00
}
/// <summary>
2017-11-07 19:49:14 +01:00
/// Gets or sets a value indicating whether the entity is trashed.
2012-10-10 08:42:54 -02:00
/// </summary>
2017-11-07 19:49:14 +01:00
/// <remarks>A trashed entity is unpublished and in the recycle bin.</remarks>
2012-10-10 08:42:54 -02:00
[DataMember]
2017-11-07 19:49:14 +01:00
public virtual bool Trashed // fixme setting this value should be handled by the class not the user
2012-10-10 08:42:54 -02:00
{
2017-11-07 19:49:14 +01:00
get = > _trashed ;
internal set = > SetPropertyValueAndDetectChanges ( value , ref _trashed , Ps . Value . TrashedSelector ) ;
2012-10-10 08:42:54 -02:00
}
/// <summary>
2017-11-07 19:49:14 +01:00
/// Gets or sets the name of the entity.
2012-10-10 08:42:54 -02:00
/// </summary>
[DataMember]
2017-11-07 19:49:14 +01:00
public virtual string Name
2012-10-10 08:42:54 -02:00
{
2017-11-07 19:49:14 +01:00
get = > _name ;
set = > SetPropertyValueAndDetectChanges ( value , ref _name , Ps . Value . NameSelector ) ;
2012-10-10 08:42:54 -02:00
}
2016-11-03 10:31:44 +01:00
2012-10-10 08:42:54 -02:00
/// <summary>
2017-11-07 19:49:14 +01:00
/// Gets or sets the identifier of the user who created the entity.
2012-10-10 08:42:54 -02:00
/// </summary>
[DataMember]
2017-11-07 19:49:14 +01:00
public virtual int CreatorId
2012-10-10 08:42:54 -02:00
{
2017-11-07 19:49:14 +01:00
get = > _creatorId ;
set = > SetPropertyValueAndDetectChanges ( value , ref _creatorId , Ps . Value . CreatorIdSelector ) ;
2012-10-10 08:42:54 -02:00
}
2017-11-10 11:27:12 +01:00
/// <summary>
/// Id of the user who wrote/updated this entity
/// </summary>
[DataMember]
public virtual int WriterId
{
get = > _writerId ;
set = > SetPropertyValueAndDetectChanges ( value , ref _writerId , Ps . Value . WriterSelector ) ;
}
2012-10-10 08:42:54 -02:00
/// <summary>
2017-11-07 19:49:14 +01:00
/// Gets or sets the identifier of the version.
2012-10-10 08:42:54 -02:00
/// </summary>
[DataMember]
public Guid Version { get ; internal set ; }
/// <summary>
/// Integer Id of the default ContentType
/// </summary>
[DataMember]
public virtual int ContentTypeId
{
2014-10-01 10:18:51 +10:00
get
{
//There will be cases where this has not been updated to reflect the true content type ID.
//This will occur when inserting new content.
if ( _contentTypeId = = 0 & & ContentTypeBase ! = null & & ContentTypeBase . HasIdentity )
{
_contentTypeId = ContentTypeBase . Id ;
}
return _contentTypeId ;
}
2016-06-21 20:43:02 +02:00
protected set { SetPropertyValueAndDetectChanges ( value , ref _contentTypeId , Ps . Value . DefaultContentTypeIdSelector ) ; }
2012-10-10 08:42:54 -02:00
}
/// <summary>
2017-11-07 19:49:14 +01:00
/// Gets or sets the collection of properties for the entity.
2012-10-10 08:42:54 -02:00
/// </summary>
[DataMember]
public virtual PropertyCollection Properties
{
2017-11-07 19:49:14 +01:00
get = > _properties ;
2012-10-10 08:42:54 -02:00
set
{
_properties = value ;
_properties . CollectionChanged + = PropertiesChanged ;
}
}
2017-11-07 19:49:14 +01:00
/// <summary>
/// Gets the enumeration of property groups for the entity.
/// fixme is a proxy, kill this
/// </summary>
[IgnoreDataMember]
public IEnumerable < PropertyGroup > PropertyGroups = > ContentTypeBase . CompositionPropertyGroups ;
2014-02-20 22:34:54 +11:00
2013-10-09 13:32:58 +11:00
/// <summary>
2017-11-07 19:49:14 +01:00
/// Gets the numeration of property types for the entity.
/// fixme is a proxy, kill this
2013-10-09 13:32:58 +11:00
/// </summary>
2017-11-07 19:49:14 +01:00
[IgnoreDataMember]
public IEnumerable < PropertyType > PropertyTypes = > ContentTypeBase . CompositionPropertyTypes ;
2017-11-10 11:27:12 +01:00
#region Has , Get , Set , Publish Property Value
2017-11-07 19:49:14 +01:00
/// <summary>
/// Gets a value indicating whether the content entity has a property with the supplied alias.
/// fixme with a value, or just the property?
/// </summary>
public virtual bool HasProperty ( string propertyTypeAlias )
= > Properties . Contains ( propertyTypeAlias ) ;
/// <summary>
/// Gets the neutral value of a property.
/// </summary>
public virtual object GetValue ( string propertyTypeAlias , bool published = false )
2013-10-09 13:32:58 +11:00
{
2017-11-07 19:49:14 +01:00
return Properties . Contains ( propertyTypeAlias ) ? Properties [ propertyTypeAlias ] . GetValue ( published ) : null ;
2013-10-09 13:32:58 +11:00
}
2012-10-10 08:42:54 -02:00
/// <summary>
2017-11-07 19:49:14 +01:00
/// Gets the culture value of a property.
2012-10-10 08:42:54 -02:00
/// </summary>
2017-11-07 19:49:14 +01:00
public virtual object GetValue ( string propertyTypeAlias , int languageId , bool published = false )
{
return Properties . Contains ( propertyTypeAlias ) ? Properties [ propertyTypeAlias ] . GetValue ( languageId , published ) : null ;
}
2012-10-10 08:42:54 -02:00
/// <summary>
2017-11-07 19:49:14 +01:00
/// Gets the segment value of a property.
2012-10-10 08:42:54 -02:00
/// </summary>
2017-11-07 19:49:14 +01:00
public virtual object GetValue ( string propertyTypeAlias , int languageId , string segment , bool published = false )
{
return Properties . Contains ( propertyTypeAlias ) ? Properties [ propertyTypeAlias ] . GetValue ( languageId , segment , published ) : null ;
}
2012-10-10 08:42:54 -02:00
/// <summary>
2017-11-07 19:49:14 +01:00
/// Gets the typed neutral value of a property.
2012-10-10 08:42:54 -02:00
/// </summary>
2017-11-07 19:49:14 +01:00
public virtual TPropertyValue GetValue < TPropertyValue > ( string propertyTypeAlias , bool published = false )
2012-10-10 08:42:54 -02:00
{
2017-11-07 19:49:14 +01:00
if ( Properties . Contains ( propertyTypeAlias ) = = false )
return default ;
var convertAttempt = Properties [ propertyTypeAlias ] . GetValue ( published ) . TryConvertTo < TPropertyValue > ( ) ;
return convertAttempt . Success ? convertAttempt . Result : default ;
2012-10-10 08:42:54 -02:00
}
/// <summary>
2017-11-07 19:49:14 +01:00
/// Gets the typed culture value of a property.
2012-10-10 08:42:54 -02:00
/// </summary>
2017-11-07 19:49:14 +01:00
public virtual TPropertyValue GetValue < TPropertyValue > ( string propertyTypeAlias , int languageId , bool published = false )
2012-10-10 08:42:54 -02:00
{
2017-11-07 19:49:14 +01:00
if ( Properties . Contains ( propertyTypeAlias ) = = false )
return default ;
var convertAttempt = Properties [ propertyTypeAlias ] . GetValue ( languageId , published ) . TryConvertTo < TPropertyValue > ( ) ;
return convertAttempt . Success ? convertAttempt . Result : default ;
2012-10-10 08:42:54 -02:00
}
/// <summary>
2017-11-07 19:49:14 +01:00
/// Gets the typed segment value of a property.
2012-10-10 08:42:54 -02:00
/// </summary>
2017-11-07 19:49:14 +01:00
public virtual TPropertyValue GetValue < TPropertyValue > ( string propertyTypeAlias , int languageId , string segment , bool published = false )
2012-10-10 08:42:54 -02:00
{
2017-09-15 18:22:19 +02:00
if ( Properties . Contains ( propertyTypeAlias ) = = false )
2017-11-07 19:49:14 +01:00
return default ;
var convertAttempt = Properties [ propertyTypeAlias ] . GetValue ( languageId , segment , published ) . TryConvertTo < TPropertyValue > ( ) ;
return convertAttempt . Success ? convertAttempt . Result : default ;
}
2017-11-10 11:27:12 +01:00
/// <summary>
/// Publish the neutral value.
/// </summary>
internal virtual void PublishValues ( )
{
foreach ( var property in Properties )
property . PublishValues ( ) ;
}
/// <summary>
/// Publish the culture value.
/// </summary>
internal virtual void PublishValues ( int? nLanguageId )
{
foreach ( var property in Properties )
property . PublishValues ( nLanguageId ) ;
}
/// <summary>
/// Publish the segment value.
/// </summary>
internal virtual void PublishValues ( int? nLanguageId , string segment )
{
foreach ( var property in Properties )
property . PublishValues ( nLanguageId , segment ) ;
}
/// <summary>
/// Publish all values.
/// </summary>
internal virtual void PublishAllValues ( )
{
foreach ( var property in Properties )
property . PublishAllValues ( ) ;
}
2017-11-07 19:49:14 +01:00
/// <summary>
/// Sets the neutral (draft) value of a property.
/// </summary>
public virtual void SetValue ( string propertyTypeAlias , object value )
{
if ( value = = null )
2017-09-15 18:22:19 +02:00
{
2017-11-07 19:49:14 +01:00
SetValueOnProperty ( propertyTypeAlias , null ) ;
return ;
2017-09-15 18:22:19 +02:00
}
2017-11-07 19:49:14 +01:00
// .NET magic to call one of the 'SetPropertyValue' handlers with matching signature
( ( dynamic ) this ) . SetPropertyValue ( propertyTypeAlias , ( dynamic ) value ) ;
2012-10-10 08:42:54 -02:00
}
/// <summary>
2017-11-07 19:49:14 +01:00
/// Sets the culture (draft) value of a property.
2012-10-10 08:42:54 -02:00
/// </summary>
2017-11-07 19:49:14 +01:00
public virtual void SetValue ( string propertyTypeAlias , int languageId , object value )
2013-01-14 11:02:12 -01:00
{
2013-01-15 11:56:25 -01:00
if ( value = = null )
{
2017-11-07 19:49:14 +01:00
SetValueOnProperty ( propertyTypeAlias , languageId , null ) ;
2013-01-15 11:56:25 -01:00
return ;
}
2016-11-03 10:31:44 +01:00
// .NET magic to call one of the 'SetPropertyValue' handlers with matching signature
2017-11-07 19:49:14 +01:00
( ( dynamic ) this ) . SetPropertyValue ( propertyTypeAlias , languageId , ( dynamic ) value ) ;
2013-01-14 11:02:12 -01:00
}
/// <summary>
2017-11-07 19:49:14 +01:00
/// Sets the segment (draft) value of a property.
/// </summary>
public virtual void SetValue ( string propertyTypeAlias , int languageId , string segment , object value )
{
if ( value = = null )
{
SetValueOnProperty ( propertyTypeAlias , languageId , segment , null ) ;
return ;
}
// .NET magic to call one of the 'SetPropertyValue' handlers with matching signature
( ( dynamic ) this ) . SetPropertyValue ( propertyTypeAlias , languageId , segment , ( dynamic ) value ) ;
}
/// <summary>
/// Sets the neutral (draft) string value of a Property
2013-01-14 11:02:12 -01:00
/// </summary>
public virtual void SetPropertyValue ( string propertyTypeAlias , string value )
{
SetValueOnProperty ( propertyTypeAlias , value ) ;
}
/// <summary>
2017-11-07 19:49:14 +01:00
/// Sets the culture (draft) string value of a Property
/// </summary>
public virtual void SetPropertyValue ( string propertyTypeAlias , int languageId , string value )
{
SetValueOnProperty ( propertyTypeAlias , languageId , value ) ;
}
/// <summary>
/// Sets the segment (draft) string value of a Property
/// </summary>
public virtual void SetPropertyValue ( string propertyTypeAlias , int languageId , string segment , string value )
{
SetValueOnProperty ( propertyTypeAlias , languageId , segment , value ) ;
}
/// <summary>
/// Sets the neutral (draft) int value of a Property
2013-01-14 11:02:12 -01:00
/// </summary>
public virtual void SetPropertyValue ( string propertyTypeAlias , int value )
{
SetValueOnProperty ( propertyTypeAlias , value ) ;
}
2013-01-18 09:03:58 -01:00
/// <summary>
2017-11-07 19:49:14 +01:00
/// Sets the culture (draft) int value of a Property
/// </summary>
public virtual void SetPropertyValue ( string propertyTypeAlias , int languageId , int value )
{
SetValueOnProperty ( propertyTypeAlias , languageId , value ) ;
}
/// <summary>
/// Sets the segment (draft) int value of a Property
/// </summary>
public virtual void SetPropertyValue ( string propertyTypeAlias , int languageId , string segment , int value )
{
SetValueOnProperty ( propertyTypeAlias , languageId , segment , value ) ;
}
/// <summary>
/// Sets the neutral (draft) long value of a Property
2013-01-18 09:03:58 -01:00
/// </summary>
public virtual void SetPropertyValue ( string propertyTypeAlias , long value )
{
2016-01-25 14:11:00 +01:00
SetValueOnProperty ( propertyTypeAlias , value ) ;
2013-01-18 09:03:58 -01:00
}
2016-01-23 21:32:08 -07:00
/// <summary>
2017-11-07 19:49:14 +01:00
/// Sets the culture (draft) long value of a Property
/// </summary>
public virtual void SetPropertyValue ( string propertyTypeAlias , int languageId , long value )
{
SetValueOnProperty ( propertyTypeAlias , languageId , value ) ;
}
/// <summary>
/// Sets the segment (draft) long value of a Property
/// </summary>
public virtual void SetPropertyValue ( string propertyTypeAlias , int languageId , string segment , long value )
{
SetValueOnProperty ( propertyTypeAlias , languageId , segment , value ) ;
}
/// <summary>
/// Sets the neutral (draft) decimal value of a Property
2016-01-23 21:32:08 -07:00
/// </summary>
public virtual void SetPropertyValue ( string propertyTypeAlias , decimal value )
{
2016-01-25 14:11:00 +01:00
SetValueOnProperty ( propertyTypeAlias , value ) ;
2016-01-23 21:32:08 -07:00
}
/// <summary>
2017-11-07 19:49:14 +01:00
/// Sets the culture (draft) decimal value of a Property
/// </summary>
public virtual void SetPropertyValue ( string propertyTypeAlias , int languageId , decimal value )
{
SetValueOnProperty ( propertyTypeAlias , languageId , value ) ;
}
/// <summary>
/// Sets the segment (draft) decimal value of a Property
/// </summary>
public virtual void SetPropertyValue ( string propertyTypeAlias , int languageId , string segment , decimal value )
{
SetValueOnProperty ( propertyTypeAlias , languageId , segment , value ) ;
}
/// <summary>
/// Sets the neutral (draft) double value of a Property
2016-01-23 21:32:08 -07:00
/// </summary>
public virtual void SetPropertyValue ( string propertyTypeAlias , double value )
{
2016-01-25 14:11:00 +01:00
SetValueOnProperty ( propertyTypeAlias , value ) ;
2013-01-18 09:03:58 -01:00
}
2013-01-14 11:02:12 -01:00
/// <summary>
2017-11-07 19:49:14 +01:00
/// Sets the culture (draft) double value of a Property
/// </summary>
public virtual void SetPropertyValue ( string propertyTypeAlias , int languageId , double value )
{
SetValueOnProperty ( propertyTypeAlias , languageId , value ) ;
}
/// <summary>
/// Sets the segment (draft) double value of a Property
/// </summary>
public virtual void SetPropertyValue ( string propertyTypeAlias , int languageId , string segment , double value )
{
SetValueOnProperty ( propertyTypeAlias , languageId , segment , value ) ;
}
/// <summary>
/// Sets the neutral (draft) boolean value of a Property
2013-01-14 11:02:12 -01:00
/// </summary>
public virtual void SetPropertyValue ( string propertyTypeAlias , bool value )
{
2017-11-07 19:49:14 +01:00
var val = Convert . ToInt32 ( value ) ;
2013-01-14 11:02:12 -01:00
SetValueOnProperty ( propertyTypeAlias , val ) ;
}
/// <summary>
2017-11-07 19:49:14 +01:00
/// Sets the culture (draft) boolean value of a Property
/// </summary>
public virtual void SetPropertyValue ( string propertyTypeAlias , int languageId , bool value )
{
var val = Convert . ToInt32 ( value ) ;
SetValueOnProperty ( propertyTypeAlias , languageId , val ) ;
}
/// <summary>
/// Sets the segment (draft) boolean value of a Property
/// </summary>
public virtual void SetPropertyValue ( string propertyTypeAlias , int languageId , string segment , bool value )
{
var val = Convert . ToInt32 ( value ) ;
SetValueOnProperty ( propertyTypeAlias , languageId , segment , val ) ;
}
/// <summary>
/// Sets the neutral (draft) DateTime value of a Property
2013-01-14 11:02:12 -01:00
/// </summary>
public virtual void SetPropertyValue ( string propertyTypeAlias , DateTime value )
{
SetValueOnProperty ( propertyTypeAlias , value ) ;
}
/// <summary>
2017-11-07 19:49:14 +01:00
/// Sets the culture (draft) DateTime value of a Property
/// </summary>
public virtual void SetPropertyValue ( string propertyTypeAlias , int languageId , DateTime value )
{
SetValueOnProperty ( propertyTypeAlias , languageId , value ) ;
}
/// <summary>
/// Sets the segment (draft) DateTime value of a Property
/// </summary>
public virtual void SetPropertyValue ( string propertyTypeAlias , int languageId , string segment , DateTime value )
{
SetValueOnProperty ( propertyTypeAlias , languageId , segment , value ) ;
}
// fixme - these three use an extension method that needs to be adapted too
/// <summary>
/// Sets the posted file value of a Property
2013-01-14 11:02:12 -01:00
/// </summary>
public virtual void SetPropertyValue ( string propertyTypeAlias , HttpPostedFile value )
{
ContentExtensions . SetValue ( this , propertyTypeAlias , value ) ;
}
/// <summary>
2017-11-07 19:49:14 +01:00
/// Sets the posted file base value of a Property
2013-01-14 11:02:12 -01:00
/// </summary>
/// <param name="propertyTypeAlias">Alias of the PropertyType</param>
/// <param name="value">Value to set for the Property</param>
public virtual void SetPropertyValue ( string propertyTypeAlias , HttpPostedFileBase value )
{
ContentExtensions . SetValue ( this , propertyTypeAlias , value ) ;
}
/// <summary>
2017-11-07 19:49:14 +01:00
/// Sets the posted file wrapper value of a Property
2013-01-14 11:02:12 -01:00
/// </summary>
2013-09-03 16:35:36 +10:00
[Obsolete("There is no reason for this overload since HttpPostedFileWrapper inherits from HttpPostedFileBase")]
2013-01-14 11:02:12 -01:00
public virtual void SetPropertyValue ( string propertyTypeAlias , HttpPostedFileWrapper value )
{
ContentExtensions . SetValue ( this , propertyTypeAlias , value ) ;
}
/// <summary>
2017-11-07 19:49:14 +01:00
/// Sets the neutral (draft) value of a property.
2013-01-14 11:02:12 -01:00
/// </summary>
private void SetValueOnProperty ( string propertyTypeAlias , object value )
2012-10-10 08:42:54 -02:00
{
if ( Properties . Contains ( propertyTypeAlias ) )
{
2017-11-07 19:49:14 +01:00
Properties [ propertyTypeAlias ] . SetValue ( value ) ;
2012-10-10 08:42:54 -02:00
return ;
}
2015-04-01 12:37:28 +01:00
var propertyType = PropertyTypes . FirstOrDefault ( x = > x . Alias . InvariantEquals ( propertyTypeAlias ) ) ;
2012-10-10 08:42:54 -02:00
if ( propertyType = = null )
2017-11-07 19:49:14 +01:00
throw new InvalidOperationException ( $"No PropertyType exists with the supplied alias \" { propertyTypeAlias } \ "." ) ;
var property = propertyType . CreateProperty ( ) ;
property . SetValue ( value ) ;
Properties . Add ( property ) ;
}
/// <summary>
/// Sets the culture (draft) value of a property.
/// </summary>
private void SetValueOnProperty ( string propertyTypeAlias , int languageId , object value )
{
if ( Properties . Contains ( propertyTypeAlias ) )
2012-10-10 08:42:54 -02:00
{
2017-11-07 19:49:14 +01:00
Properties [ propertyTypeAlias ] . SetValue ( languageId , value ) ;
return ;
2012-10-10 08:42:54 -02:00
}
2017-11-07 19:49:14 +01:00
var propertyType = PropertyTypes . FirstOrDefault ( x = > x . Alias . InvariantEquals ( propertyTypeAlias ) ) ;
if ( propertyType = = null )
throw new InvalidOperationException ( $"No PropertyType exists with the supplied alias \" { propertyTypeAlias } \ "." ) ;
var property = propertyType . CreateProperty ( ) ;
property . SetValue ( languageId , value ) ;
Properties . Add ( property ) ;
2012-10-10 08:42:54 -02:00
}
2012-10-10 13:18:14 -02:00
/// <summary>
2017-11-07 19:49:14 +01:00
/// Sets the segment (draft) value of a property.
2012-10-10 13:18:14 -02:00
/// </summary>
2017-11-07 19:49:14 +01:00
private void SetValueOnProperty ( string propertyTypeAlias , int languageId , string segment , object value )
2012-10-10 13:18:14 -02:00
{
2017-11-07 19:49:14 +01:00
if ( Properties . Contains ( propertyTypeAlias ) )
{
Properties [ propertyTypeAlias ] . SetValue ( languageId , segment , value ) ;
return ;
}
var propertyType = PropertyTypes . FirstOrDefault ( x = > x . Alias . InvariantEquals ( propertyTypeAlias ) ) ;
if ( propertyType = = null )
throw new InvalidOperationException ( $"No PropertyType exists with the supplied alias \" { propertyTypeAlias } \ "." ) ;
var property = propertyType . CreateProperty ( ) ;
property . SetValue ( languageId , segment , value ) ;
Properties . Add ( property ) ;
2013-07-24 12:54:10 +10:00
}
2017-11-07 19:49:14 +01:00
#endregion
#region Validation
2013-07-24 12:54:10 +10:00
/// <summary>
2017-11-07 19:49:14 +01:00
/// Gets a value indicating whether the content and its properties are valid.
2013-07-24 12:54:10 +10:00
/// </summary>
2017-11-07 19:49:14 +01:00
public virtual bool Validate ( ) // fixme would it depends on the property varyBy? or would we validate for a given culture/segment?
2013-07-24 12:54:10 +10:00
{
2017-11-07 19:49:14 +01:00
_invalidProperties . Clear ( ) ;
_invalidProperties . AddRange ( Properties . Where ( property = > property . IsValid ( ) = = false ) ) ;
return _invalidProperties . Any ( ) = = false ;
2012-10-10 13:18:14 -02:00
}
2013-01-11 10:38:32 -01:00
2017-11-07 19:49:14 +01:00
/// <summary>
/// Gets the properties marked as invalid during the last validation.
/// </summary>
[IgnoreDataMember]
internal IEnumerable < Property > InvalidProperties = > _invalidProperties ;
#endregion
#region Dirty
2015-05-07 11:43:53 +10:00
2013-08-07 11:39:25 +10:00
/// <summary>
2017-11-07 19:49:14 +01:00
/// Resets dirty properties.
2013-08-07 11:39:25 +10:00
/// </summary>
2017-11-07 19:49:14 +01:00
public override void ResetDirtyProperties ( bool rememberDirty )
2013-08-07 11:39:25 +10:00
{
2017-11-07 19:49:14 +01:00
base . ResetDirtyProperties ( rememberDirty ) ;
2013-08-07 11:39:25 +10:00
2017-11-07 19:49:14 +01:00
// also reset dirty changes made to user's properties
2013-08-07 11:39:25 +10:00
foreach ( var prop in Properties )
2017-11-07 19:49:14 +01:00
prop . ResetDirtyProperties ( rememberDirty ) ;
2013-08-07 11:39:25 +10:00
}
2015-05-07 11:43:53 +10:00
/// <summary>
2017-11-07 19:49:14 +01:00
/// Gets a value indicating whether the current entity is dirty.
2015-05-07 11:43:53 +10:00
/// </summary>
public override bool IsDirty ( )
{
return IsEntityDirty ( ) | | this . IsAnyUserPropertyDirty ( ) ;
}
/// <summary>
2017-11-07 19:49:14 +01:00
/// Gets a value indicating whether the current entity was dirty.
2015-05-07 11:43:53 +10:00
/// </summary>
public override bool WasDirty ( )
{
return WasEntityDirty ( ) | | this . WasAnyUserPropertyDirty ( ) ;
}
/// <summary>
2017-11-07 19:49:14 +01:00
/// Gets a value indicating whether the current entity's own properties (not user) are dirty.
2015-05-07 11:43:53 +10:00
/// </summary>
public bool IsEntityDirty ( )
{
return base . IsDirty ( ) ;
}
/// <summary>
2017-11-07 19:49:14 +01:00
/// Gets a value indicating whether the current entity's own properties (not user) were dirty.
2015-05-07 11:43:53 +10:00
/// </summary>
public bool WasEntityDirty ( )
{
return base . WasDirty ( ) ;
}
/// <summary>
2017-11-07 19:49:14 +01:00
/// Gets a value indicating whether a user property is dirty.
2015-05-07 11:43:53 +10:00
/// </summary>
public override bool IsPropertyDirty ( string propertyName )
{
2017-11-07 19:49:14 +01:00
if ( base . IsPropertyDirty ( propertyName ) )
2015-05-07 11:43:53 +10:00
return true ;
2017-11-07 19:49:14 +01:00
return Properties . Contains ( propertyName ) & & Properties [ propertyName ] . IsDirty ( ) ;
2015-05-07 11:43:53 +10:00
}
/// <summary>
2017-11-07 19:49:14 +01:00
/// Gets a value indicating whether a user property was dirty.
2015-05-07 11:43:53 +10:00
/// </summary>
public override bool WasPropertyDirty ( string propertyName )
{
2017-11-07 19:49:14 +01:00
if ( base . WasPropertyDirty ( propertyName ) )
2015-05-07 11:43:53 +10:00
return true ;
2017-11-07 19:49:14 +01:00
return Properties . Contains ( propertyName ) & & Properties [ propertyName ] . WasDirty ( ) ;
2015-05-07 11:43:53 +10:00
}
#endregion
2012-10-10 08:42:54 -02:00
}
2017-07-20 11:21:28 +02:00
}