diff --git a/src/Umbraco.Core/Models/Content.cs b/src/Umbraco.Core/Models/Content.cs
index b7bc62f8da..67afd5974c 100644
--- a/src/Umbraco.Core/Models/Content.cs
+++ b/src/Umbraco.Core/Models/Content.cs
@@ -278,46 +278,6 @@ namespace Umbraco.Core.Models
}
}
- ///
- /// Set property values by alias with an annonymous object
- ///
- [IgnoreDataMember]
- public object PropertyValues
- {
- set
- {
- if (value == null)
- throw new Exception("No properties has been passed in");
-
- var propertyInfos = value.GetType().GetProperties();
- foreach (var propertyInfo in propertyInfos)
- {
- //Check if a PropertyType with alias exists thus being a valid property
- var propertyType = PropertyTypes.FirstOrDefault(x => x.Alias == propertyInfo.Name);
- if (propertyType == null)
- throw new Exception(
- string.Format(
- "The property alias {0} is not valid, because no PropertyType with this alias exists",
- propertyInfo.Name));
-
- //Check if a Property with the alias already exists in the collection thus being updated or inserted
- var item = Properties.FirstOrDefault(x => x.Alias == propertyInfo.Name);
- if (item != null)
- {
- item.Value = propertyInfo.GetValue(value, null);
- //Update item with newly added value
- Properties.Add(item);
- }
- else
- {
- //Create new Property to add to collection
- var property = propertyType.CreatePropertyFromValue(propertyInfo.GetValue(value, null));
- Properties.Add(property);
- }
- }
- }
- }
-
///
/// Collection of properties, which make up all the data available for this Content object
///
diff --git a/src/Umbraco.Core/Models/ContentExtensions.cs b/src/Umbraco.Core/Models/ContentExtensions.cs
new file mode 100644
index 0000000000..7a126dc154
--- /dev/null
+++ b/src/Umbraco.Core/Models/ContentExtensions.cs
@@ -0,0 +1,44 @@
+using System;
+using System.Linq;
+
+namespace Umbraco.Core.Models
+{
+ public static class ContentExtensions
+ {
+ ///
+ /// Set property values by alias with an annonymous object
+ ///
+ public static void PropertyValues(this IContent content, object value)
+ {
+ if (value == null)
+ throw new Exception("No properties has been passed in");
+
+ var propertyInfos = value.GetType().GetProperties();
+ foreach (var propertyInfo in propertyInfos)
+ {
+ //Check if a PropertyType with alias exists thus being a valid property
+ var propertyType = content.PropertyTypes.FirstOrDefault(x => x.Alias == propertyInfo.Name);
+ if (propertyType == null)
+ throw new Exception(
+ string.Format(
+ "The property alias {0} is not valid, because no PropertyType with this alias exists",
+ propertyInfo.Name));
+
+ //Check if a Property with the alias already exists in the collection thus being updated or inserted
+ var item = content.Properties.FirstOrDefault(x => x.Alias == propertyInfo.Name);
+ if (item != null)
+ {
+ item.Value = propertyInfo.GetValue(value, null);
+ //Update item with newly added value
+ content.Properties.Add(item);
+ }
+ else
+ {
+ //Create new Property to add to collection
+ var property = propertyType.CreatePropertyFromValue(propertyInfo.GetValue(value, null));
+ content.Properties.Add(property);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Models/EntityBase/Entity.cs b/src/Umbraco.Core/Models/EntityBase/Entity.cs
index 2ed10382df..cca3bc501e 100644
--- a/src/Umbraco.Core/Models/EntityBase/Entity.cs
+++ b/src/Umbraco.Core/Models/EntityBase/Entity.cs
@@ -13,7 +13,7 @@ namespace Umbraco.Core.Models.EntityBase
///
[Serializable]
[DataContract(IsReference = true)]
- public abstract class Entity : IEntity
+ public abstract class Entity : IEntity, ICanBeDirty
{
private bool _hasIdentity;
private int? _hash;
@@ -59,13 +59,13 @@ namespace Umbraco.Core.Models.EntityBase
/// Gets or sets the Created Date
///
[DataMember]
- public DateTime CreatedDate { get; set; }
+ public DateTime CreateDate { get; set; }
///
/// Gets or sets the Modified Date
///
[DataMember]
- public DateTime ModifiedDate { get; set; }
+ public DateTime UpdateDate { get; set; }
///
/// Property changed event
@@ -91,8 +91,8 @@ namespace Umbraco.Core.Models.EntityBase
///
internal virtual void AddingEntity()
{
- CreatedDate = DateTime.UtcNow;
- ModifiedDate = DateTime.UtcNow;
+ CreateDate = DateTime.UtcNow;
+ UpdateDate = DateTime.UtcNow;
}
///
@@ -100,7 +100,7 @@ namespace Umbraco.Core.Models.EntityBase
///
internal virtual void UpdatingEntity()
{
- ModifiedDate = DateTime.UtcNow;
+ UpdateDate = DateTime.UtcNow;
}
///
diff --git a/src/Umbraco.Core/Models/EntityBase/IEntity.cs b/src/Umbraco.Core/Models/EntityBase/IEntity.cs
index 2f0d81ee3f..9557d6fb0e 100644
--- a/src/Umbraco.Core/Models/EntityBase/IEntity.cs
+++ b/src/Umbraco.Core/Models/EntityBase/IEntity.cs
@@ -29,13 +29,13 @@ namespace Umbraco.Core.Models.EntityBase
/// Gets or sets the Created Date
///
[DataMember]
- DateTime CreatedDate { get; set; }
+ DateTime CreateDate { get; set; }
///
/// Gets or sets the Modified Date
///
[DataMember]
- DateTime ModifiedDate { get; set; }
+ DateTime UpdateDate { get; set; }
///
/// Indicates whether the current entity has an identity, eg. Id.
diff --git a/src/Umbraco.Core/Models/IContentBase.cs b/src/Umbraco.Core/Models/IContentBase.cs
index cca054c542..53acf4eb81 100644
--- a/src/Umbraco.Core/Models/IContentBase.cs
+++ b/src/Umbraco.Core/Models/IContentBase.cs
@@ -74,12 +74,6 @@ namespace Umbraco.Core.Models
/// PropertyTypes are kind of lazy loaded as part of the object graph
IEnumerable PropertyTypes { get; }
- ///
- /// Set property values by alias with an annonymous object
- ///
- [IgnoreDataMember]
- object PropertyValues { set; }
-
///
/// Indicates whether the content object has a property with the supplied alias
///
diff --git a/src/Umbraco.Core/Models/Media.cs b/src/Umbraco.Core/Models/Media.cs
index 8b8b711957..7040d631e2 100644
--- a/src/Umbraco.Core/Models/Media.cs
+++ b/src/Umbraco.Core/Models/Media.cs
@@ -185,46 +185,6 @@ namespace Umbraco.Core.Models
}
}
- ///
- /// Set property values by alias with an annonymous object
- ///
- [IgnoreDataMember]
- public object PropertyValues
- {
- set
- {
- if (value == null)
- throw new Exception("No properties has been passed in");
-
- var propertyInfos = value.GetType().GetProperties();
- foreach (var propertyInfo in propertyInfos)
- {
- //Check if a PropertyType with alias exists thus being a valid property
- var propertyType = PropertyTypes.FirstOrDefault(x => x.Alias == propertyInfo.Name);
- if (propertyType == null)
- throw new Exception(
- string.Format(
- "The property alias {0} is not valid, because no PropertyType with this alias exists",
- propertyInfo.Name));
-
- //Check if a Property with the alias already exists in the collection thus being updated or inserted
- var item = Properties.FirstOrDefault(x => x.Alias == propertyInfo.Name);
- if (item != null)
- {
- item.Value = propertyInfo.GetValue(value, null);
- //Update item with newly added value
- Properties.Add(item);
- }
- else
- {
- //Create new Property to add to collection
- var property = propertyType.CreatePropertyFromValue(propertyInfo.GetValue(value, null));
- Properties.Add(property);
- }
- }
- }
- }
-
///
/// List of properties, which make up all the data available for this Media object
///
diff --git a/src/Umbraco.Core/Models/Relation.cs b/src/Umbraco.Core/Models/Relation.cs
index f886e3c890..38ad39393b 100644
--- a/src/Umbraco.Core/Models/Relation.cs
+++ b/src/Umbraco.Core/Models/Relation.cs
@@ -12,7 +12,7 @@ namespace Umbraco.Core.Models
[DataContract(IsReference = true)]
public class Relation : Entity
{
- //NOTE: The datetime column from umbracoRelation is set on CreatedDate on the Entity
+ //NOTE: The datetime column from umbracoRelation is set on CreateDate on the Entity
private int _parentId;
private int _childId;
private RelationType _relationType;
diff --git a/src/Umbraco.Core/Persistence/Factories/ContentFactory.cs b/src/Umbraco.Core/Persistence/Factories/ContentFactory.cs
index f336f8330c..51fbb6bb8b 100644
--- a/src/Umbraco.Core/Persistence/Factories/ContentFactory.cs
+++ b/src/Umbraco.Core/Persistence/Factories/ContentFactory.cs
@@ -31,8 +31,8 @@ namespace Umbraco.Core.Persistence.Factories
SortOrder = documentDto.ContentVersionDto.ContentDto.NodeDto.SortOrder,
Trashed = documentDto.ContentVersionDto.ContentDto.NodeDto.Trashed,
Published = documentDto.Published,
- CreatedDate = documentDto.ContentVersionDto.ContentDto.NodeDto.CreateDate,
- ModifiedDate = documentDto.ContentVersionDto.VersionDate,
+ CreateDate = documentDto.ContentVersionDto.ContentDto.NodeDto.CreateDate,
+ UpdateDate = documentDto.ContentVersionDto.VersionDate,
ExpireDate = documentDto.ExpiresDate,
ReleaseDate = documentDto.ReleaseDate,
Version = documentDto.ContentVersionDto.VersionId,
@@ -44,7 +44,7 @@ namespace Umbraco.Core.Persistence.Factories
{
var nodeDto = new NodeDto
{
- CreateDate = entity.CreatedDate,
+ CreateDate = entity.CreateDate,
NodeId = entity.Id,
Level = short.Parse(entity.Level.ToString(CultureInfo.InvariantCulture)),
NodeObjectType = new Guid(nodeObjectType),
@@ -64,7 +64,7 @@ namespace Umbraco.Core.Persistence.Factories
{
var nodeDto = new NodeDto
{
- CreateDate = entity.CreatedDate,
+ CreateDate = entity.CreateDate,
NodeId = entity.Id,
Level = short.Parse(level.ToString(CultureInfo.InvariantCulture)),
NodeObjectType = new Guid(nodeObjectType),
@@ -101,7 +101,7 @@ namespace Umbraco.Core.Persistence.Factories
var contentVersionDto = new ContentVersionDto
{
NodeId = entity.Id,
- VersionDate = entity.ModifiedDate,
+ VersionDate = entity.UpdateDate,
VersionId = entity.Version
};
return contentVersionDto;
@@ -118,7 +118,7 @@ namespace Umbraco.Core.Persistence.Factories
Published = entity.Published,
ReleaseDate = entity.ReleaseDate,
Text = entity.Name,
- UpdateDate = entity.ModifiedDate,
+ UpdateDate = entity.UpdateDate,
UserId = entity.UserId,
VersionId = entity.Version
};
diff --git a/src/Umbraco.Core/Persistence/Mappers/ModelDtoMapper.cs b/src/Umbraco.Core/Persistence/Mappers/ModelDtoMapper.cs
index d2ac50c91e..6f43b8e304 100644
--- a/src/Umbraco.Core/Persistence/Mappers/ModelDtoMapper.cs
+++ b/src/Umbraco.Core/Persistence/Mappers/ModelDtoMapper.cs
@@ -42,7 +42,7 @@ namespace Umbraco.Core.Persistence.Mappers
case "Key":
columnName = "[umbracoNode].[uniqueID]";
return true;
- case "CreatedDate":
+ case "CreateDate":
columnName = "[umbracoNode].[createDate]";
return true;
case "Name":
diff --git a/src/Umbraco.Core/PropertyEditors/Attributes/PropertyEditorAttribute.cs b/src/Umbraco.Core/PropertyEditors/Attributes/PropertyEditorAttribute.cs
new file mode 100644
index 0000000000..1e8dbb6c68
--- /dev/null
+++ b/src/Umbraco.Core/PropertyEditors/Attributes/PropertyEditorAttribute.cs
@@ -0,0 +1,48 @@
+using System;
+
+namespace Umbraco.Core.PropertyEditors.Attributes
+{
+ ///
+ /// Defines a PropertyEditor
+ ///
+ [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
+ internal sealed class PropertyEditorAttribute : Attribute
+ {
+ public PropertyEditorAttribute(string id, string alias, string name)
+ {
+ Mandate.ParameterNotNullOrEmpty(id, "id");
+ Mandate.ParameterNotNullOrEmpty(alias, "alias");
+ Mandate.ParameterNotNullOrEmpty(name, "name");
+
+ Id = Guid.Parse(id);
+ Alias = alias;
+ Name = name;
+
+ IsContentPropertyEditor = true;
+ }
+
+ public Guid Id { get; private set; }
+
+ ///
+ /// Gets or sets the name.
+ ///
+ /// The name.
+ public string Name { get; set; }
+
+ ///
+ /// Gets or sets the alias.
+ ///
+ /// The alias.
+ public string Alias { get; set; }
+
+ ///
+ /// Flag determining if this property editor is used to edit content
+ ///
+ public bool IsContentPropertyEditor { get; set; }
+
+ ///
+ /// Flag determining if this property editor is used to edit parameters
+ ///
+ public bool IsParameterEditor { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/PropertyEditors/Attributes/ShowLabelAttribute.cs b/src/Umbraco.Core/PropertyEditors/Attributes/ShowLabelAttribute.cs
new file mode 100644
index 0000000000..1e5306d19e
--- /dev/null
+++ b/src/Umbraco.Core/PropertyEditors/Attributes/ShowLabelAttribute.cs
@@ -0,0 +1,22 @@
+using System;
+
+namespace Umbraco.Core.PropertyEditors.Attributes
+{
+ ///
+ /// Attribute determining whether or not to hide/show the label of a property
+ ///
+ ///
+ /// This directly affects the meta data property: HideSurroundingHtml
+ ///
+ [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
+ internal class ShowLabelAttribute : Attribute
+ {
+ public ShowLabelAttribute(bool show)
+ {
+ ShowLabel = show;
+ }
+
+ public bool ShowLabel { get; private set; }
+
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/PropertyEditors/BlankPreValueModel.cs b/src/Umbraco.Core/PropertyEditors/BlankPreValueModel.cs
new file mode 100644
index 0000000000..1e0fdb5f5e
--- /dev/null
+++ b/src/Umbraco.Core/PropertyEditors/BlankPreValueModel.cs
@@ -0,0 +1,13 @@
+namespace Umbraco.Core.PropertyEditors
+{
+ ///
+ /// A class representing a blank, null or empty pre-value editor.
+ ///
+ ///
+ /// This class can be used for Property Editors who do not define a Pre value editor
+ ///
+ internal class BlankPreValueModel : PreValueModel
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/PropertyEditors/EditorModel.cs b/src/Umbraco.Core/PropertyEditors/EditorModel.cs
new file mode 100644
index 0000000000..567d8e5573
--- /dev/null
+++ b/src/Umbraco.Core/PropertyEditors/EditorModel.cs
@@ -0,0 +1,147 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Web.Mvc;
+
+namespace Umbraco.Core.PropertyEditors
+{
+ internal abstract class EditorModel where TValueModel : IValueModel, new()
+ {
+ protected EditorModel()
+ {
+ // Set the UI Elements collection to an empty list
+ //UIElements = new List();
+ }
+
+ [ReadOnly(true)]
+ public virtual bool ShowUmbracoLabel
+ {
+ get { return true; }
+ }
+
+ ///
+ /// Gets a list of UI Elements for the property editor.
+ ///
+ //[ScaffoldColumn(false)]
+ //public virtual IList UIElements { get; protected internal set; }
+
+ private ModelMetadata _modelMetadata;
+
+ ///
+ /// Returns the meta data for the current editor model
+ ///
+ protected internal ModelMetadata MetaData
+ {
+ get
+ {
+ return _modelMetadata ?? (_modelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => this, GetType()));
+ }
+ }
+
+ ///
+ /// Returns the serialized value for the PropertyEditor
+ ///
+ ///
+ public virtual IDictionary GetSerializedValue()
+ {
+ var editableProps = MetaData.Properties.Where(x => x.ShowForEdit && !x.IsReadOnly);
+ var d = new Dictionary();
+ foreach (var p in editableProps)
+ {
+ //by default, we will not support complex modelled properties, developers will need to override
+ //the GetSerializedValue method if they need support for this.
+ if (p.IsComplexType)
+ {
+ //TODO: We should magically support this
+ throw new NotSupportedException("The default serialization implementation of EditorModel does not support properties that are complex models");
+ }
+
+ d.Add(p.PropertyName, p.Model);
+ }
+ return d;
+ }
+
+ public virtual void SetModelValues(IDictionary serializedVal)
+ {
+ if (serializedVal == null || serializedVal.Count == 0)
+ {
+ return;
+ }
+
+ var modelProperties = GetType().GetProperties();
+
+ var editableProps = MetaData.Properties.Where(x => x.ShowForEdit && !x.IsReadOnly);
+
+ foreach (var i in serializedVal)
+ {
+ if (i.Value == null)
+ continue;
+
+ //get the property with the name
+ var prop = editableProps.Where(x => x.PropertyName == i.Key).SingleOrDefault();
+ if (prop != null)
+ {
+ //set the property value
+ var toConverter = TypeDescriptor.GetConverter(prop.ModelType);
+ if (toConverter != null)
+ {
+ //get the model property for this property meta data to set its value
+ var propInfo = modelProperties.Where(x => x.Name == prop.PropertyName).Single();
+ object convertedVal;
+
+ //if value is already of the same type, just use the current value, otherwise try and convert it
+ if (i.Value.GetType() == propInfo.PropertyType)
+ {
+ convertedVal = i.Value;
+ }
+ else
+ {
+ try
+ {
+ convertedVal = toConverter.ConvertFrom(i.Value);
+ }
+ catch (NotSupportedException)
+ {
+ //this occurs when the converter doesn't know how, so we can try the opposite way as a last ditch effort
+ var fromConverter = TypeDescriptor.GetConverter(i.Value.GetType());
+ if (fromConverter == null)
+ {
+ throw;
+ }
+ convertedVal = fromConverter.ConvertTo(i.Value, prop.ModelType);
+
+ }
+ }
+ propInfo.SetValue(this, convertedVal, null);
+
+ }
+ }
+
+ }
+ }
+
+ public virtual TValueModel GetValueModel()
+ {
+ var editableProps = MetaData.Properties.Where(x => x.ShowForEdit && !x.IsReadOnly);
+ var d = new TValueModel();
+ foreach (var p in editableProps)
+ {
+ //by default, we will not support complex modelled properties, developers will need to override
+ //the GetSerializedValue method if they need support for this.
+ //TODO Test if this exception is still valid
+ if (p.IsComplexType)
+ {
+ throw new NotSupportedException("The default serialization implementation of EditorModel does not support properties that are complex models");
+ }
+
+ var property = d.GetType().GetProperty(p.PropertyName);
+ if(property != null)
+ {
+ property.SetValue(d, p.Model, null);
+ }
+ }
+ return d;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/PropertyEditors/EditorModel`T.cs b/src/Umbraco.Core/PropertyEditors/EditorModel`T.cs
new file mode 100644
index 0000000000..1a5b2c6daf
--- /dev/null
+++ b/src/Umbraco.Core/PropertyEditors/EditorModel`T.cs
@@ -0,0 +1,27 @@
+namespace Umbraco.Core.PropertyEditors
+{
+ ///
+ /// An abstract class representing the model to render a Property Editor's content editor with PreValues
+ ///
+ /// The type of the PreValue model.
+ ///
+ internal abstract class EditorModel : EditorModel
+ where TValueModel : IValueModel, new()
+ where TPreValueModel : PreValueModel
+ {
+ ///
+ /// Constructor
+ ///
+ /// The pre value options used to construct the editor
+ protected EditorModel(TPreValueModel preValues)
+ {
+ PreValueModel = preValues;
+ }
+
+ ///
+ /// The pre value options used to configure the editor
+ ///
+ /// The pre value model.
+ public TPreValueModel PreValueModel { get; protected internal set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/PropertyEditors/IValueModel.cs b/src/Umbraco.Core/PropertyEditors/IValueModel.cs
new file mode 100644
index 0000000000..8ddd076fd5
--- /dev/null
+++ b/src/Umbraco.Core/PropertyEditors/IValueModel.cs
@@ -0,0 +1,7 @@
+namespace Umbraco.Core.PropertyEditors
+{
+ internal interface IValueModel
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/PropertyEditors/PreValueDefinition.cs b/src/Umbraco.Core/PropertyEditors/PreValueDefinition.cs
new file mode 100644
index 0000000000..43cbb31c9d
--- /dev/null
+++ b/src/Umbraco.Core/PropertyEditors/PreValueDefinition.cs
@@ -0,0 +1,21 @@
+using System;
+
+namespace Umbraco.Core.PropertyEditors
+{
+ ///
+ /// A class representing a single value of a Pre-Value editor to be saved
+ ///
+ internal class PreValueDefinition
+ {
+ public PreValueDefinition(string propertyName, Type modeType, object modelValue)
+ {
+ ModelType = modeType;
+ PropertyName = propertyName;
+ ModelValue = modelValue;
+ }
+
+ public Type ModelType { get; private set; }
+ public string PropertyName { get; private set; }
+ public object ModelValue { get; private set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/PropertyEditors/PreValueModel.cs b/src/Umbraco.Core/PropertyEditors/PreValueModel.cs
new file mode 100644
index 0000000000..d2204ca28c
--- /dev/null
+++ b/src/Umbraco.Core/PropertyEditors/PreValueModel.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+
+namespace Umbraco.Core.PropertyEditors
+{
+ ///
+ /// Abstract class representing a Property Editor's model to render it's Pre value editor
+ ///
+ internal abstract class PreValueModel
+ {
+ protected virtual IEnumerable GetValueDefinitions()
+ {
+ throw new NotImplementedException();
+ }
+
+ public virtual string GetSerializedValue()
+ {
+ throw new NotImplementedException();
+ }
+
+ protected virtual void SetModelPropertyValue(PreValueDefinition def, Action