diff --git a/src/Umbraco.Core/Models/Content.cs b/src/Umbraco.Core/Models/Content.cs
index 316d2bb6b9..4a680eabc1 100644
--- a/src/Umbraco.Core/Models/Content.cs
+++ b/src/Umbraco.Core/Models/Content.cs
@@ -1,5 +1,6 @@
using System;
using System.ComponentModel;
+using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
@@ -225,97 +226,87 @@ namespace Umbraco.Core.Models
[DataMember]
public bool Blueprint { get; internal set; }
- ///
- /// Publish the neutral value.
- ///
- internal virtual void PublishValues()
+ ///
+ public virtual void PublishAllValues()
{
- foreach (var property in Properties)
- property.PublishValues(null, null);
- _publishedState = PublishedState.Publishing;
- }
+ if (ValidateAll().Any())
+ throw new InvalidOperationException("Values are not valid.");
- ///
- /// Publish the culture value.
- ///
- internal virtual void PublishValues(int? nLanguageId)
- {
- foreach (var property in Properties)
- property.PublishValues(nLanguageId, null);
- _publishedState = PublishedState.Publishing;
- }
-
- ///
- /// Publish the segment value.
- ///
- internal virtual void PublishValues(string segment)
- {
- foreach (var property in Properties)
- property.PublishValues(null, segment);
- _publishedState = PublishedState.Publishing;
- }
-
- ///
- /// Publish the culture+segment value.
- ///
- internal virtual void PublishValues(int? nLanguageId, string segment)
- {
- foreach (var property in Properties)
- property.PublishValues(nLanguageId, segment);
- _publishedState = PublishedState.Publishing;
- }
-
- ///
- /// Publish all values.
- ///
- internal virtual void PublishAllValues()
- {
foreach (var property in Properties)
property.PublishAllValues();
_publishedState = PublishedState.Publishing;
}
- internal virtual void CopyValues(IContentBase other, int? languageId, string segment, bool published = false)
+ ///
+ public virtual void PublishValues(int? languageId = null, string segment = null)
{
- if (other.ContentTypeId != ContentTypeId)
- throw new InvalidOperationException("Cannot copy values from a different content type.");
+ if (Validate(languageId, segment).Any())
+ throw new InvalidOperationException("Values are not valid.");
- // clear all existing properties
- // note: use property.SetValue(), don't assign pvalue.EditValue, else change tracking fails
foreach (var property in Properties)
- {
- // skip properties that don't support the specified variation
- if (!property.PropertyType.ValidateVariation(languageId, segment, false))
- continue;
-
- foreach (var pvalue in property.Values)
- if (pvalue.LanguageId == languageId && pvalue.Segment == segment)
- property.SetValue(pvalue.LanguageId, pvalue.Segment, null);
- }
-
- // copy other properties
- var otherProperties = other.Properties;
- foreach (var otherProperty in otherProperties)
- {
- // skip properties that don't support the specified variation
- if (!otherProperty.PropertyType.ValidateVariation(languageId, segment, false))
- continue;
-
- var alias = otherProperty.PropertyType.Alias;
- SetValue(alias, languageId, segment, otherProperty.GetValue(languageId, segment, published));
- }
+ property.PublishValue(languageId, segment);
+ _publishedState = PublishedState.Publishing;
}
- internal virtual void CopyAllValues(IContentBase other, bool published = false)
+ ///
+ public virtual void PublishCultureValues(int? languageId = null)
+ {
+ if (ValidateCulture(languageId).Any())
+ throw new InvalidOperationException("Values are not valid.");
+
+ foreach (var property in Properties)
+ property.PublishCultureValues(languageId);
+ _publishedState = PublishedState.Publishing;
+ }
+
+ ///
+ public virtual void ClearAllPublishedValues()
+ {
+ foreach (var property in Properties)
+ property.ClearPublishedAllValues();
+ _publishedState = PublishedState.Publishing;
+ }
+
+ ///
+ public virtual void ClearPublishedValues(int? languageId = null, string segment = null)
+ {
+ foreach (var property in Properties)
+ property.ClearPublishedValue(languageId, segment);
+ _publishedState = PublishedState.Publishing;
+ }
+
+ ///
+ public virtual void ClearCulturePublishedValues(int? languageId = null)
+ {
+ foreach (var property in Properties)
+ property.ClearPublishedCultureValues(languageId);
+ _publishedState = PublishedState.Publishing;
+ }
+
+ private bool IsCopyFromSelf(IContent other)
+ {
+ // copying from the same Id and VersionPk
+ return Id == other.Id && VersionPk == ((Content) other).VersionPk;
+ }
+
+ ///
+ public virtual void CopyAllValues(IContent other)
{
if (other.ContentTypeId != ContentTypeId)
throw new InvalidOperationException("Cannot copy values from a different content type.");
- // clear all existing properties
+ // we could copy from another document entirely,
+ // or from another version of the same document,
+ // in which case there is a special case.
+ var published = IsCopyFromSelf(other);
+
// note: use property.SetValue(), don't assign pvalue.EditValue, else change tracking fails
+
+ // clear all existing properties
foreach (var property in Properties)
foreach (var pvalue in property.Values)
- property.SetValue(pvalue.LanguageId, pvalue.Segment, null);
+ if (property.PropertyType.ValidateVariation(pvalue.LanguageId, pvalue.Segment, false))
+ property.SetValue(null, pvalue.LanguageId, pvalue.Segment);
// copy other properties
var otherProperties = other.Properties;
@@ -324,8 +315,74 @@ namespace Umbraco.Core.Models
var alias = otherProperty.PropertyType.Alias;
foreach (var pvalue in otherProperty.Values)
{
+ if (!otherProperty.PropertyType.ValidateVariation(pvalue.LanguageId, pvalue.Segment, false))
+ continue;
var value = published ? pvalue.PublishedValue : pvalue.EditedValue;
- SetValue(alias, pvalue.LanguageId, pvalue.Segment, value);
+ SetValue(alias, value, pvalue.LanguageId, pvalue.Segment);
+ }
+ }
+ }
+
+ ///
+ public virtual void CopyValues(IContent other, int? languageId = null, string segment = null)
+ {
+ if (other.ContentTypeId != ContentTypeId)
+ throw new InvalidOperationException("Cannot copy values from a different content type.");
+
+ var published = VersionPk > PublishedVersionPk;
+
+ // note: use property.SetValue(), don't assign pvalue.EditValue, else change tracking fails
+
+ // clear all existing properties
+ foreach (var property in Properties)
+ {
+ if (!property.PropertyType.ValidateVariation(languageId, segment, false))
+ continue;
+
+ foreach (var pvalue in property.Values)
+ if (pvalue.LanguageId == languageId && pvalue.Segment == segment)
+ property.SetValue(null, pvalue.LanguageId, pvalue.Segment);
+ }
+
+ // copy other properties
+ var otherProperties = other.Properties;
+ foreach (var otherProperty in otherProperties)
+ {
+ if (!otherProperty.PropertyType.ValidateVariation(languageId, segment, false))
+ continue;
+
+ var alias = otherProperty.PropertyType.Alias;
+ SetValue(alias, otherProperty.GetValue(languageId, segment, published), languageId, segment);
+ }
+ }
+
+ ///
+ public virtual void CopyCultureValues(IContent other, int? languageId = null)
+ {
+ if (other.ContentTypeId != ContentTypeId)
+ throw new InvalidOperationException("Cannot copy values from a different content type.");
+
+ var published = VersionPk > PublishedVersionPk;
+
+ // note: use property.SetValue(), don't assign pvalue.EditValue, else change tracking fails
+
+ // clear all existing properties
+ foreach (var property in Properties)
+ foreach (var pvalue in property.Values)
+ if (pvalue.LanguageId == languageId && property.PropertyType.ValidateVariation(pvalue.LanguageId, pvalue.Segment, false))
+ property.SetValue(null, pvalue.LanguageId, pvalue.Segment);
+
+ // copy other properties
+ var otherProperties = other.Properties;
+ foreach (var otherProperty in otherProperties)
+ {
+ var alias = otherProperty.PropertyType.Alias;
+ foreach (var pvalue in otherProperty.Values)
+ {
+ if (pvalue.LanguageId != languageId || !otherProperty.PropertyType.ValidateVariation(pvalue.LanguageId, pvalue.Segment, false))
+ continue;
+ var value = published ? pvalue.PublishedValue : pvalue.EditedValue;
+ SetValue(alias, value, pvalue.LanguageId, pvalue.Segment);
}
}
}
@@ -373,16 +430,6 @@ namespace Umbraco.Core.Models
_publishedState = _published ? PublishedState.Published : PublishedState.Unpublished;
}
- ///
- /// Creates a deep clone of the current entity with its identity and it's property identities reset
- ///
- ///
- [Obsolete("Use DeepCloneWithResetIdentities instead")]
- public IContent Clone()
- {
- return DeepCloneWithResetIdentities();
- }
-
///
/// Creates a deep clone of the current entity with its identity and it's property identities reset
///
diff --git a/src/Umbraco.Core/Models/ContentBase.cs b/src/Umbraco.Core/Models/ContentBase.cs
index b92f53ad6d..f7d643e9a3 100644
--- a/src/Umbraco.Core/Models/ContentBase.cs
+++ b/src/Umbraco.Core/Models/ContentBase.cs
@@ -39,7 +39,6 @@ namespace Umbraco.Core.Models
private string _name;
private PropertyCollection _properties;
- private readonly List _invalidProperties = new List();
[EditorBrowsable(EditorBrowsableState.Never)]
IDictionary IUmbracoEntity.AdditionalData => _lazyAdditionalData.Value;
@@ -263,132 +262,44 @@ namespace Umbraco.Core.Models
#region Has, Get, Set, Publish Property Value
- ///
- /// Gets a value indicating whether the content entity has a property with the supplied alias.
- ///
- /// Indicates that the content entity has a property with the supplied alias, but
- /// not necessarily that the content has a value for that property. Could be missing.
+ ///
public virtual bool HasProperty(string propertyTypeAlias)
=> Properties.Contains(propertyTypeAlias);
- ///
- /// Gets the neutral value of a property.
- ///
- public virtual object GetValue(string propertyTypeAlias, bool published = false)
- {
- return Properties.TryGetValue(propertyTypeAlias, out var property)
- ? property.GetValue(published)
- : null;
- }
-
- ///
- /// Gets the culture value of a property.
- ///
- public virtual object GetValue(string propertyTypeAlias, int? languageId, bool published = false)
- {
- return Properties.TryGetValue(propertyTypeAlias, out var property)
- ? property.GetValue(languageId, null, published)
- : null;
- }
-
- ///
- /// Gets the segment value of a property.
- ///
- public virtual object GetValue(string propertyTypeAlias, string segment, bool published = false)
- {
- return Properties.TryGetValue(propertyTypeAlias, out var property)
- ? property.GetValue(null, segment, published)
- : null;
- }
-
- ///
- /// Gets the culture+segment value of a property.
- ///
- public virtual object GetValue(string propertyTypeAlias, int? languageId, string segment, bool published = false)
+ ///
+ public virtual object GetValue(string propertyTypeAlias, int? languageId = null, string segment = null, bool published = false)
{
return Properties.TryGetValue(propertyTypeAlias, out var property)
? property.GetValue(languageId, segment, published)
: null;
}
- ///
- /// Gets the typed neutral value of a property.
- ///
- public virtual TPropertyValue GetValue(string propertyTypeAlias, bool published = false)
+ ///
+ public virtual TValue GetValue(string propertyTypeAlias, int? languageId = null, string segment = null, bool published = false)
{
if (!Properties.TryGetValue(propertyTypeAlias, out var property))
return default;
- var convertAttempt = property.GetValue(published).TryConvertTo();
+ var convertAttempt = property.GetValue(languageId, segment, published).TryConvertTo();
return convertAttempt.Success ? convertAttempt.Result : default;
}
- ///
- /// Gets the typed culture value of a property.
- ///
- public virtual TPropertyValue GetValue(string propertyTypeAlias, int? languageId, bool published = false)
+ ///
+ public virtual void SetValue(string propertyTypeAlias, object value, int? languageId = null, string segment = null)
{
- if (!Properties.TryGetValue(propertyTypeAlias, out var property))
- return default;
+ if (Properties.Contains(propertyTypeAlias))
+ {
+ Properties[propertyTypeAlias].SetValue(value, languageId, segment);
+ return;
+ }
- var convertAttempt = property.GetValue(languageId, null, published).TryConvertTo();
- return convertAttempt.Success ? convertAttempt.Result : default;
- }
+ var propertyType = PropertyTypes.FirstOrDefault(x => x.Alias.InvariantEquals(propertyTypeAlias));
+ if (propertyType == null)
+ throw new InvalidOperationException($"No PropertyType exists with the supplied alias \"{propertyTypeAlias}\".");
- ///
- /// Gets the typed segment value of a property.
- ///
- public virtual TPropertyValue GetValue(string propertyTypeAlias, string segment, bool published = false)
- {
- if (!Properties.TryGetValue(propertyTypeAlias, out var property))
- return default;
-
- var convertAttempt = property.GetValue(null, segment, published).TryConvertTo();
- return convertAttempt.Success ? convertAttempt.Result : default;
- }
-
- ///
- /// Gets the typed culture+segment value of a property.
- ///
- public virtual TPropertyValue GetValue(string propertyTypeAlias, int? languageId, string segment, bool published = false)
- {
- if (!Properties.TryGetValue(propertyTypeAlias, out var property))
- return default;
-
- var convertAttempt = property.GetValue(languageId, segment, published).TryConvertTo();
- return convertAttempt.Success ? convertAttempt.Result : default;
- }
-
- ///
- /// Sets the neutral (draft) value of a property.
- ///
- public virtual void SetValue(string propertyTypeAlias, object value)
- {
- SetValueOnProperty(propertyTypeAlias, null, null, value);
- }
-
- ///
- /// Sets the culture (draft) value of a property.
- ///
- public virtual void SetValue(string propertyTypeAlias, int? languageId, object value)
- {
- SetValueOnProperty(propertyTypeAlias, languageId, null, value);
- }
-
- ///
- /// Sets the culture+segment (draft) value of a property.
- ///
- public virtual void SetValue(string propertyTypeAlias, string segment, object value)
- {
- SetValueOnProperty(propertyTypeAlias, null, segment, value);
- }
-
- ///
- /// Sets the culture+segment (draft) value of a property.
- ///
- public virtual void SetValue(string propertyTypeAlias, int? languageId, string segment, object value)
- {
- SetValueOnProperty(propertyTypeAlias, languageId, segment, value);
+ var property = propertyType.CreateProperty();
+ property.SetValue(value, languageId, segment);
+ Properties.Add(property);
}
// fixme - these three use an extension method that needs to be adapted too
@@ -415,50 +326,25 @@ namespace Umbraco.Core.Models
ContentExtensions.SetValue(this, propertyTypeAlias, value);
}
- ///
- /// Sets the (edited) value of a property.
- ///
- private void SetValueOnProperty(string propertyTypeAlias, int? languageId, string segment, object value)
- {
- 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);
- }
-
#endregion
#region Validation
- public virtual Property[] Validate()
+ public virtual Property[] ValidateAll()
{
- return Properties.Where(x => !x.IsValid()).ToArray();
+ return Properties.Where(x => !x.IsAllValid()).ToArray();
}
- public virtual Property[] Validate(int? languageId)
- {
- return Properties.Where(x => !x.IsValid(languageId)).ToArray();
- }
-
- public virtual Property[] Validate(string segment)
- {
- return Properties.Where(x => !x.IsValid(segment)).ToArray();
- }
-
- public virtual Property[] Validate(int? languageId, string segment)
+ public virtual Property[] Validate(int? languageId = null, string segment = null)
{
return Properties.Where(x => !x.IsValid(languageId, segment)).ToArray();
}
+ public virtual Property[] ValidateCulture(int? languageId = null)
+ {
+ return Properties.Where(x => !x.IsCultureValid(languageId)).ToArray();
+ }
+
#endregion
#region Dirty
diff --git a/src/Umbraco.Core/Models/ContentTypeBase.cs b/src/Umbraco.Core/Models/ContentTypeBase.cs
index 53ec572aa4..c62f88af71 100644
--- a/src/Umbraco.Core/Models/ContentTypeBase.cs
+++ b/src/Umbraco.Core/Models/ContentTypeBase.cs
@@ -53,6 +53,8 @@ namespace Umbraco.Core.Models
// ReSharper disable once VirtualMemberCallInConstructor
_propertyTypes = new PropertyTypeCollection(IsPublishing);
_propertyTypes.CollectionChanged += PropertyTypesChanged;
+
+ _variations = ContentVariation.InvariantNeutral;
}
protected ContentTypeBase(IContentTypeBase parent)
@@ -73,6 +75,8 @@ namespace Umbraco.Core.Models
// ReSharper disable once VirtualMemberCallInConstructor
_propertyTypes = new PropertyTypeCollection(IsPublishing);
_propertyTypes.CollectionChanged += PropertyTypesChanged;
+
+ _variations = ContentVariation.InvariantNeutral;
}
///
diff --git a/src/Umbraco.Core/Models/IContent.cs b/src/Umbraco.Core/Models/IContent.cs
index bd21037cd6..d19bc1425c 100644
--- a/src/Umbraco.Core/Models/IContent.cs
+++ b/src/Umbraco.Core/Models/IContent.cs
@@ -31,15 +31,13 @@ namespace Umbraco.Core.Models
///
/// Gets the template used to render the published version of the content.
///
- /// When editing the content, the template can change, but this will
- /// not until the content is published.
+ /// When editing the content, the template can change, but this will not until the content is published.
ITemplate PublishTemplate { get; }
///
/// Gets the name of the published version of the content.
///
- /// When editing the content, the name can change, but this will
- /// not until the content is published.
+ /// When editing the content, the name can change, but this will not until the content is published.
string PublishName { get; }
///
@@ -98,5 +96,53 @@ namespace Umbraco.Core.Models
///
///
IContent DeepCloneWithResetIdentities();
+
+ ///
+ /// Publishes all values.
+ ///
+ /// The document must then be published via the content service.
+ void PublishAllValues();
+
+ ///
+ /// Publishes values.
+ ///
+ /// The document must then be published via the content service.
+ void PublishValues(int? languageId = null, string segment = null);
+
+ ///
+ /// Publishes the culture/any values.
+ ///
+ /// The document must then be published via the content service.
+ void PublishCultureValues(int? languageId = null);
+
+ ///
+ /// Clears all published values.
+ ///
+ void ClearAllPublishedValues();
+
+ ///
+ /// Clears published values.
+ ///
+ void ClearPublishedValues(int? languageId = null, string segment = null);
+
+ ///
+ /// Clears the culture/any published values.
+ ///
+ void ClearCulturePublishedValues(int? languageId = null);
+
+ ///
+ /// Copies values from another document.
+ ///
+ void CopyAllValues(IContent other);
+
+ ///
+ /// Copies values from another document.
+ ///
+ void CopyValues(IContent other, int? languageId = null, string segment = null);
+
+ ///
+ /// Copies culture/any values from another document.
+ ///
+ void CopyCultureValues(IContent other, int? languageId = null);
}
}
diff --git a/src/Umbraco.Core/Models/IContentBase.cs b/src/Umbraco.Core/Models/IContentBase.cs
index 1b01979f6f..ba0b86ea40 100644
--- a/src/Umbraco.Core/Models/IContentBase.cs
+++ b/src/Umbraco.Core/Models/IContentBase.cs
@@ -44,90 +44,40 @@ namespace Umbraco.Core.Models
IEnumerable PropertyTypes { get; }
///
- /// Gets a value indicating whether the content object has a property with the supplied alias.
+ /// Gets a value indicating whether the content entity has a property with the supplied alias.
///
- /// Alias of the PropertyType
- /// True if Property with given alias exists, otherwise False
- bool HasProperty(string propertyTypeAlias); // fixme - what does this mean????
+ /// Indicates that the content entity has a property with the supplied alias, but
+ /// not necessarily that the content has a value for that property. Could be missing.
+ bool HasProperty(string propertyTypeAlias);
///
- /// Gets the neutral value of a Property
+ /// Gets the value of a Property
///
- object GetValue(string propertyTypeAlias, bool published = false);
+ object GetValue(string propertyTypeAlias, int? languageId = null, string segment = null, bool published = false);
///
- /// Gets the culture value of a Property
+ /// Gets the typed value of a Property
///
- object GetValue(string propertyTypeAlias, int? languageId, bool published = false);
+ TValue GetValue(string propertyTypeAlias, int? languageId = null, string segment = null, bool published = false);
///
- /// Gets the segment value of a Property
+ /// Sets the (edited) value of a Property
///
- object GetValue(string propertyTypeAlias, string segment, bool published = false);
+ void SetValue(string propertyTypeAlias, object value, int? languageId = null, string segment = null);
///
- /// Gets the culture+segment value of a Property
+ /// Gets a value indicating whether the content and all its properties values are valid.
///
- object GetValue(string propertyTypeAlias, int? languageId, string segment, bool published = false);
+ Property[] ValidateAll();
///
- /// Gets the typed neutral value of a Property
+ /// Gets a value indicating whether the content and its properties values are valid.
///
- TPropertyValue GetValue(string propertyTypeAlias, bool published = false);
+ Property[] Validate(int? languageId = null, string segment = null);
///
- /// Gets the typed culture value of a Property
+ /// Gets a value indicating whether the content and its culture/any properties values are valid.
///
- TPropertyValue GetValue(string propertyTypeAlias, int? languageId, bool published = false);
-
- ///
- /// Gets the typed segment value of a Property
- ///
- TPropertyValue GetValue(string propertyTypeAlias, string segment, bool published = false);
-
- ///
- /// Gets the typed culture+segment value of a Property
- ///
- TPropertyValue GetValue(string propertyTypeAlias, int? languageId, string segment, bool published = false);
-
- ///
- /// Sets the neutral (edited) value of a Property
- ///
- void SetValue(string propertyTypeAlias, object value);
-
- ///
- /// Sets the culture (edited) value of a Property
- ///
- void SetValue(string propertyTypeAlias, int? languageId, object value);
-
- ///
- /// Sets the segment (edited) value of a Property
- ///
- void SetValue(string propertyTypeAlias, string segment, object value);
-
- ///
- /// Sets the culture+segment (edited) value of a Property
- ///
- void SetValue(string propertyTypeAlias, int? languageId, string segment, object value);
-
- ///
- /// Gets a value indicating whether the content and its invariant+neutral properties values are valid.
- ///
- Property[] Validate();
-
- ///
- /// Gets a value indicating whether the content and its culture+neutral properties values are valid for the specified culture.
- ///
- Property[] Validate(int? languageId);
-
- ///
- /// Gets a value indicating whether the content and its invariant+segment values are valid for the specified segment.
- ///
- Property[] Validate(string segment);
-
- ///
- /// Gets a value indicating whether the content and its culture+segment properties values are valid.
- ///
- Property[] Validate(int? languageId, string segment);
+ Property[] ValidateCulture(int? languageId = null);
}
}
diff --git a/src/Umbraco.Core/Models/Property.cs b/src/Umbraco.Core/Models/Property.cs
index 80be404bfa..4492ff507d 100644
--- a/src/Umbraco.Core/Models/Property.cs
+++ b/src/Umbraco.Core/Models/Property.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections;
using System.Collections.Generic;
-using System.Drawing.Printing;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
@@ -133,44 +132,12 @@ namespace Umbraco.Core.Models
internal DataTypeDatabaseType DataTypeDatabaseType => _propertyType.DataTypeDatabaseType;
///
- /// Gets the neutral value.
+ /// Gets the value.
///
- public object GetValue(bool published = false)
- {
- if (!_propertyType.ValidateVariation(null, null, false)) return null;
- return _pvalue == null ? null : GetPropertyValue(_pvalue, published);
- }
-
- ///
- /// Gets the culture value.
- ///
- public object GetValue(int? languageId, bool published = false)
- {
- if (!_propertyType.ValidateVariation(languageId, null, false)) return null;
- if (_vvalues == null) return null;
- return _vvalues.TryGetValue((languageId, null), out var pvalue)
- ? GetPropertyValue(pvalue, published)
- : null;
- }
-
- ///
- /// Gets the segment value.
- ///
- public object GetValue(string segment, bool published = false)
- {
- if (!_propertyType.ValidateVariation(null, segment, false)) return null;
- if (_vvalues == null) return null;
- return _vvalues.TryGetValue((null, segment), out var pvalue)
- ? GetPropertyValue(pvalue, published)
- : null;
- }
-
- ///
- /// Gets the culture+segment value.
- ///
- public object GetValue(int? languageId, string segment, bool published = false)
+ public object GetValue(int? languageId = null, string segment = null, bool published = false)
{
if (!_propertyType.ValidateVariation(languageId, segment, false)) return null;
+ if (!languageId.HasValue && segment == null) return GetPropertyValue(_pvalue, published);
if (_vvalues == null) return null;
return _vvalues.TryGetValue((languageId, segment), out var pvalue)
? GetPropertyValue(pvalue, published)
@@ -184,18 +151,101 @@ namespace Umbraco.Core.Models
: pvalue.EditedValue;
}
- internal void PublishValues(int? languageId, string segment)
+ // internal - must be invoked by the content item
+ internal void PublishAllValues()
{
+ // throw if some values are not valid
+ if (!IsAllValid()) throw new InvalidOperationException("Some values are not valid.");
+
+ // if invariant-neutral is supported, publish invariant-neutral
+ if (_propertyType.ValidateVariation(null, null, false))
+ PublishPropertyValue(_pvalue);
+
+ // publish everything not invariant-neutral that is supported
+ if (_vvalues != null)
+ {
+ var pvalues = _vvalues
+ .Where(x => _propertyType.ValidateVariation(x.Value.LanguageId, x.Value.Segment, false))
+ .Select(x => x.Value);
+ foreach (var pvalue in pvalues)
+ PublishPropertyValue(pvalue);
+ }
+ }
+
+ // internal - must be invoked by the content item
+ internal void PublishValue(int? languageId = null, string segment = null)
+ {
+ // throw if value is not valid, or if variation is not supported
+ if (!IsValid(languageId, segment)) throw new InvalidOperationException("Value is not valid.");
_propertyType.ValidateVariation(languageId, segment, true);
+
(var pvalue, _) = GetPValue(languageId, segment, false);
if (pvalue == null) return;
PublishPropertyValue(pvalue);
}
- internal void PublishAllValues()
+ // internal - must be invoked by the content item
+ internal void PublishCultureValues(int? languageId = null)
{
- foreach (var pvalue in Values)
- PublishPropertyValue(pvalue);
+ // throw if some values are not valid
+ if (!IsCultureValid(languageId)) throw new InvalidOperationException("Some values are not valid.");
+
+ // if invariant and invariant-neutral is supported, publish invariant-neutral
+ if (!languageId.HasValue && _propertyType.ValidateVariation(null, null, false))
+ PublishPropertyValue(_pvalue);
+
+ // publish everything not invariant-neutral that matches the culture and is supported
+ if (_vvalues != null)
+ {
+ var pvalues = _vvalues
+ .Where(x => x.Value.LanguageId == languageId)
+ .Where(x => _propertyType.ValidateVariation(languageId, x.Value.Segment, false))
+ .Select(x => x.Value);
+ foreach (var pvalue in pvalues)
+ PublishPropertyValue(pvalue);
+ }
+ }
+
+ // internal - must be invoked by the content item
+ internal void ClearPublishedAllValues()
+ {
+ if (_propertyType.ValidateVariation(null, null, false))
+ ClearPublishedPropertyValue(_pvalue);
+
+ if (_vvalues != null)
+ {
+ var pvalues = _vvalues
+ .Where(x => _propertyType.ValidateVariation(x.Value.LanguageId, x.Value.Segment, false))
+ .Select(x => x.Value);
+ foreach (var pvalue in pvalues)
+ ClearPublishedPropertyValue(pvalue);
+ }
+ }
+
+ // internal - must be invoked by the content item
+ internal void ClearPublishedValue(int? languageId = null, string segment = null)
+ {
+ _propertyType.ValidateVariation(languageId, segment, true);
+ (var pvalue, _) = GetPValue(languageId, segment, false);
+ if (pvalue == null) return;
+ ClearPublishedPropertyValue(pvalue);
+ }
+
+ // internal - must be invoked by the content item
+ internal void ClearPublishedCultureValues(int? languageId = null)
+ {
+ if (!languageId.HasValue && _propertyType.ValidateVariation(null, null, false))
+ ClearPublishedPropertyValue(_pvalue);
+
+ if (_vvalues != null)
+ {
+ var pvalues = _vvalues
+ .Where(x => x.Value.LanguageId == languageId)
+ .Where(x => _propertyType.ValidateVariation(languageId, x.Value.Segment, false))
+ .Select(x => x.Value);
+ foreach (var pvalue in pvalues)
+ ClearPublishedPropertyValue(pvalue);
+ }
}
private void PublishPropertyValue(PropertyValue pvalue)
@@ -207,48 +257,23 @@ namespace Umbraco.Core.Models
DetectChanges(pvalue.EditedValue, origValue, Ps.Value.ValuesSelector, Ps.Value.PropertyValueComparer, false);
}
- ///
- /// Sets a (edited) neutral value.
- ///
- public void SetValue(object value)
+ private void ClearPublishedPropertyValue(PropertyValue pvalue)
{
- _propertyType.ValidateVariation(null, null, true);
- (var pvalue, var change) = GetPValue(true);
- SetPropertyValue(pvalue, value, change);
+ if (!_propertyType.IsPublishing)
+ throw new NotSupportedException("Property type does not support publishing.");
+ var origValue = pvalue.PublishedValue;
+ pvalue.PublishedValue = ConvertSetValue(null);
+ DetectChanges(pvalue.EditedValue, origValue, Ps.Value.ValuesSelector, Ps.Value.PropertyValueComparer, false);
}
///
- /// Sets a (edited) culture value.
+ /// Sets a value.
///
- public void SetValue(int? languageId, object value)
- {
- _propertyType.ValidateVariation(languageId, null, true);
- (var pvalue, var change) = GetPValue(languageId, null, true);
- SetPropertyValue(pvalue, value, change);
- }
-
- ///
- /// Sets a (edited) culture value.
- ///
- public void SetValue(string segment, object value)
- {
- _propertyType.ValidateVariation(null, segment, true);
- (var pvalue, var change) = GetPValue(null, segment, true);
- SetPropertyValue(pvalue, value, change);
- }
-
- ///
- /// Sets a (edited) culture+segment value.
- ///
- public void SetValue(int? languageId, string segment, object value)
+ public void SetValue(object value, int? languageId = null, string segment = null)
{
_propertyType.ValidateVariation(languageId, segment, true);
(var pvalue, var change) = GetPValue(languageId, segment, true);
- SetPropertyValue(pvalue, value, change);
- }
- private void SetPropertyValue(PropertyValue pvalue, object value, bool change)
- {
var origValue = pvalue.EditedValue;
var setValue = ConvertSetValue(value);
@@ -257,15 +282,11 @@ namespace Umbraco.Core.Models
DetectChanges(setValue, origValue, Ps.Value.ValuesSelector, Ps.Value.PropertyValueComparer, change);
}
- // bypasses all changes detection and is the *only* to set the published value
+ // bypasses all changes detection and is the *only* way to set the published value
internal void FactorySetValue(int? languageId, string segment, bool published, object value)
{
(var pvalue, _) = GetPValue(languageId, segment, true);
- FactorySetPropertyValue(pvalue, published, value);
- }
- private void FactorySetPropertyValue(PropertyValue pvalue, bool published, object value)
- {
if (published && _propertyType.IsPublishing)
pvalue.PublishedValue = value;
else
@@ -297,7 +318,7 @@ namespace Umbraco.Core.Models
_vvalues = new Dictionary<(int?, string), PropertyValue>();
change = true;
}
- if (_vvalues.TryGetValue((languageId, segment), out var pvalue))
+ if (!_vvalues.TryGetValue((languageId, segment), out var pvalue))
{
if (!create) return (null, false);
pvalue = _vvalues[(languageId, segment)] = new PropertyValue();
@@ -361,49 +382,61 @@ namespace Umbraco.Core.Models
}
///
- /// Gets a value indicating whether the (edited) neutral value is valid.
+ /// Gets a value indicating whether everything is valid.
///
- /// An invalid value can be saved, but only valid values can be published.
- public bool IsValid()
- {
- return IsValidValue(GetValue());
- }
-
- ///
- /// Gets a value indicating whether the (edited) culture value is valid.
- ///
- /// An invalid value can be saved, but only valid values can be published.
- public bool IsValid(int? languageId)
- {
- return IsValidValue(GetValue(languageId));
- }
-
- ///
- /// Gets a value indicating whether the (edited) segment value is valid.
- ///
- /// An invalid value can be saved, but only valid values can be published.
- public bool IsValid(string segment)
- {
- return IsValidValue(GetValue(segment));
- }
-
- ///
- /// Gets a value indicating whether the (edited) culture+segment value is valid.
- ///
- /// An invalid value can be saved, but only valid values can be published.
- public bool IsValid(int? languageId, string segment)
- {
- return IsValidValue(GetValue(languageId, segment));
- }
-
- ///
- /// Gets a value indicating whether all (edited) values are valid.
- ///
- /// An invalid value can be saved, but only valid values can be published.
+ ///
public bool IsAllValid()
{
- // fixme - what about missing, required values?
- return _values.All(x => IsValidValue(x.EditedValue));
+ // if invariant-neutral is supported, validate invariant-neutral
+ if (_propertyType.ValidateVariation(null, null, false))
+ if (!IsValidValue(_pvalue)) return false;
+
+ if (_vvalues == null) return IsValidValue(null);
+
+ // validate everything not invariant-neutral that is supported
+ // fixme - broken - how can we figure out what is mandatory here?
+
+ var pvalues = _vvalues
+ .Where(x => _propertyType.ValidateVariation(x.Value.LanguageId, x.Value.Segment, false))
+ .Select(x => x.Value)
+ .ToArray();
+ return pvalues.Length == 0
+ ? IsValidValue(null)
+ : pvalues.All(x => IsValidValue(x.EditedValue));
+ }
+
+ ///
+ /// Gets a value indicating whether the culture/any values are valid.
+ ///
+ /// An invalid value can be saved, but only valid values can be published.
+ public bool IsCultureValid(int? languageId)
+ {
+ // if invariant and invariant-neutral is supported, validate invariant-neutral
+ if (!languageId.HasValue && _propertyType.ValidateVariation(null, null, false))
+ if (!IsValidValue(_pvalue)) return false;
+
+ // validate everything not invariant-neutral that matches the culture and is supported
+ // fixme - broken - how can we figure out what is mandatory here?
+
+ if (_vvalues == null) return IsValidValue(null);
+
+ var pvalues = _vvalues
+ .Where(x => x.Value.LanguageId == languageId)
+ .Where(x => _propertyType.ValidateVariation(languageId, x.Value.Segment, false))
+ .Select(x => x.Value)
+ .ToArray();
+ return pvalues.Length == 0
+ ? IsValidValue(null)
+ : pvalues.All(x => IsValidValue(x.EditedValue));
+ }
+
+ ///
+ /// Gets a value indicating whether the value is valid.
+ ///
+ /// An invalid value can be saved, but only valid values can be published.
+ public bool IsValid(int? languageId = null, string segment = null)
+ {
+ return IsValidValue(GetValue(languageId, segment));
}
///
diff --git a/src/Umbraco.Core/Models/PropertyType.cs b/src/Umbraco.Core/Models/PropertyType.cs
index 2582189068..cd5ac63bd3 100644
--- a/src/Umbraco.Core/Models/PropertyType.cs
+++ b/src/Umbraco.Core/Models/PropertyType.cs
@@ -42,6 +42,7 @@ namespace Umbraco.Core.Models
_propertyEditorAlias = dataTypeDefinition.PropertyEditorAlias;
_dataTypeDatabaseType = dataTypeDefinition.DatabaseType;
+ _variations = ContentVariation.InvariantNeutral;
}
public PropertyType(IDataTypeDefinition dataTypeDefinition, string propertyTypeAlias)
@@ -69,6 +70,7 @@ namespace Umbraco.Core.Models
_isExplicitDbType = isExplicitDbType;
_propertyEditorAlias = propertyEditorAlias;
_dataTypeDatabaseType = dataTypeDatabaseType;
+ _variations = ContentVariation.InvariantNeutral;
}
///
@@ -84,6 +86,7 @@ namespace Umbraco.Core.Models
_propertyEditorAlias = propertyEditorAlias;
_dataTypeDatabaseType = dataTypeDatabaseType;
_alias = GetAlias(propertyTypeAlias);
+ _variations = ContentVariation.InvariantNeutral;
}
// ReSharper disable once ClassNeverInstantiated.Local
@@ -241,7 +244,7 @@ namespace Umbraco.Core.Models
public ContentVariation Variations
{
get => _variations;
- internal set => SetPropertyValueAndDetectChanges(value, ref _variations, Ps.Value.VaryBy);
+ set => SetPropertyValueAndDetectChanges(value, ref _variations, Ps.Value.VaryBy);
}
public bool ValidateVariation(int? languageId, string segment, bool throwIfInvalid)
@@ -264,7 +267,7 @@ namespace Umbraco.Core.Models
if ((Variations & variation) == 0)
{
if (throwIfInvalid)
- throw new InvalidOperationException($"Variation {variation} is invalid for property type \"{Alias}\".");
+ throw new NotSupportedException($"Variation {variation} is invalid for property type \"{Alias}\".");
return false;
}
return true;
diff --git a/src/Umbraco.Core/Models/Rdbms/ContentTypeDto.cs b/src/Umbraco.Core/Models/Rdbms/ContentTypeDto.cs
index baa43ba3ae..840ab18122 100644
--- a/src/Umbraco.Core/Models/Rdbms/ContentTypeDto.cs
+++ b/src/Umbraco.Core/Models/Rdbms/ContentTypeDto.cs
@@ -44,7 +44,7 @@ namespace Umbraco.Core.Models.Rdbms
public bool AllowAtRoot { get; set; }
[Column("variations")]
- [Constraint(Default = "0")]
+ [Constraint(Default = "1" /*ContentVariation.InvariantNeutral*/)]
public byte Variations { get; set; }
[ResultColumn]
diff --git a/src/Umbraco.Core/Models/Rdbms/PropertyTypeDto.cs b/src/Umbraco.Core/Models/Rdbms/PropertyTypeDto.cs
index 06d203690f..6fab87ac96 100644
--- a/src/Umbraco.Core/Models/Rdbms/PropertyTypeDto.cs
+++ b/src/Umbraco.Core/Models/Rdbms/PropertyTypeDto.cs
@@ -52,7 +52,7 @@ namespace Umbraco.Core.Models.Rdbms
public string Description { get; set; }
[Column("variations")]
- [Constraint(Default = "0")]
+ [Constraint(Default = "1" /*ContentVariation.InvariantNeutral*/)]
public byte Variations { get; set; }
[ResultColumn]
diff --git a/src/Umbraco.Core/Persistence/Factories/ContentFactory.cs b/src/Umbraco.Core/Persistence/Factories/ContentBaseFactory.cs
similarity index 50%
rename from src/Umbraco.Core/Persistence/Factories/ContentFactory.cs
rename to src/Umbraco.Core/Persistence/Factories/ContentBaseFactory.cs
index 22f5191009..b49c8fe50e 100644
--- a/src/Umbraco.Core/Persistence/Factories/ContentFactory.cs
+++ b/src/Umbraco.Core/Persistence/Factories/ContentBaseFactory.cs
@@ -1,160 +1,281 @@
-using System;
-using Umbraco.Core.Models;
-using Umbraco.Core.Models.Rdbms;
-
-namespace Umbraco.Core.Persistence.Factories
-{
- internal static class ContentFactory
- {
- ///
- /// Builds an IContent item from a dto and content type.
- ///
- public static Content BuildEntity(DocumentDto dto, IContentType contentType)
- {
- var contentDto = dto.ContentDto;
- var nodeDto = contentDto.NodeDto;
- var documentVersionDto = dto.DocumentVersionDto;
- var contentVersionDto = documentVersionDto.ContentVersionDto;
- var publishedVersionDto = dto.PublishedVersionDto;
-
- var content = new Content(nodeDto.Text, nodeDto.ParentId, contentType);
-
- try
- {
- content.DisableChangeTracking();
-
- content.Id = dto.NodeId;
- content.Key = nodeDto.UniqueId;
- content.Version = contentVersionDto.VersionId;
- content.VersionPk = contentVersionDto.Id;
-
- content.Name = contentVersionDto.Text;
- content.NodeName = contentVersionDto.Text;
-
- content.Path = nodeDto.Path;
- content.Level = nodeDto.Level;
- content.ParentId = nodeDto.ParentId;
- content.SortOrder = nodeDto.SortOrder;
- content.Trashed = nodeDto.Trashed;
-
- content.CreatorId = nodeDto.UserId ?? 0;
- content.WriterId = contentVersionDto.UserId;
- content.CreateDate = nodeDto.CreateDate;
- content.UpdateDate = contentVersionDto.VersionDate;
-
- content.Published = dto.Published;
- content.Edited = dto.Edited;
- content.ExpireDate = dto.ExpiresDate;
- content.ReleaseDate = dto.ReleaseDate;
-
- if (dto.Published)
- {
- content.PublishedVersionPk = publishedVersionDto.Id;
- content.PublishDate = publishedVersionDto.ContentVersionDto.VersionDate;
- content.PublishName = publishedVersionDto.ContentVersionDto.Text;
- content.PublisherId = publishedVersionDto.ContentVersionDto.UserId;
- }
-
- // templates = ignored, managed by the repository
-
- // reset dirty initial properties (U4-1946)
- content.ResetDirtyProperties(false);
- return content;
- }
- finally
- {
- content.EnableChangeTracking();
- }
- }
-
- ///
- /// Buils a dto from an IContent item.
- ///
- public static DocumentDto BuildDto(IContent entity, Guid objectType)
- {
- var contentDto = BuildContentDto(entity, objectType);
-
- var dto = new DocumentDto
- {
- NodeId = entity.Id,
- Published = entity.Published,
- ReleaseDate = entity.ReleaseDate,
- ExpiresDate = entity.ExpireDate,
-
- ContentDto = contentDto,
- DocumentVersionDto = BuildDocumentVersionDto(entity, contentDto)
- };
-
- return dto;
- }
-
- private static ContentDto BuildContentDto(IContent entity, Guid objectType)
- {
- var dto = new ContentDto
- {
- NodeId = entity.Id,
- ContentTypeId = entity.ContentTypeId,
-
- NodeDto = BuildNodeDto(entity, objectType)
- };
-
- return dto;
- }
-
- private static NodeDto BuildNodeDto(IContent entity, Guid objectType)
- {
- var dto = new NodeDto
- {
- NodeId = entity.Id,
- UniqueId = entity.Key,
- ParentId = entity.ParentId,
- Level = Convert.ToInt16(entity.Level),
- Path = entity.Path,
- SortOrder = entity.SortOrder,
- Trashed = entity.Trashed,
- UserId = entity.CreatorId,
- Text = entity.Name,
- NodeObjectType = objectType,
- CreateDate = entity.CreateDate
- };
-
- return dto;
- }
-
- // always build the current / VersionPk dto
- // we're never going to build / save old versions (which are immutable)
- private static DocumentVersionDto BuildDocumentVersionDto(IContent entity, ContentDto contentDto)
- {
- var dto = new DocumentVersionDto
- {
- Id = ((ContentBase) entity).VersionPk,
- TemplateId = entity.Template?.Id,
- Published = false, // always building the current, unpublished one
-
- ContentVersionDto = BuildContentVersionDto(entity, contentDto)
- };
-
- return dto;
- }
-
- // always build the current / VersionPk dto
- // we're never going to build / save old versions (which are immutable)
- private static ContentVersionDto BuildContentVersionDto(IContent entity, ContentDto contentDto)
- {
- var dto = new ContentVersionDto
- {
- Id = ((ContentBase) entity).VersionPk,
- NodeId = entity.Id,
- VersionId = entity.Version,
- VersionDate = entity.UpdateDate,
- UserId = entity.WriterId,
- Current = true, // always building the current one
- Text = entity.Name,
-
- ContentDto = contentDto
- };
-
- return dto;
- }
- }
-}
+using System;
+using Umbraco.Core.Models;
+using Umbraco.Core.Models.Rdbms;
+
+namespace Umbraco.Core.Persistence.Factories
+{
+ internal class ContentBaseFactory
+ {
+ ///
+ /// Builds an IContent item from a dto and content type.
+ ///
+ public static Content BuildEntity(DocumentDto dto, IContentType contentType)
+ {
+ var contentDto = dto.ContentDto;
+ var nodeDto = contentDto.NodeDto;
+ var documentVersionDto = dto.DocumentVersionDto;
+ var contentVersionDto = documentVersionDto.ContentVersionDto;
+ var publishedVersionDto = dto.PublishedVersionDto;
+
+ var content = new Content(nodeDto.Text, nodeDto.ParentId, contentType);
+
+ try
+ {
+ content.DisableChangeTracking();
+
+ content.Id = dto.NodeId;
+ content.Key = nodeDto.UniqueId;
+ content.Version = contentVersionDto.VersionId;
+ content.VersionPk = contentVersionDto.Id;
+
+ content.Name = contentVersionDto.Text;
+ content.NodeName = contentVersionDto.Text;
+
+ content.Path = nodeDto.Path;
+ content.Level = nodeDto.Level;
+ content.ParentId = nodeDto.ParentId;
+ content.SortOrder = nodeDto.SortOrder;
+ content.Trashed = nodeDto.Trashed;
+
+ content.CreatorId = nodeDto.UserId ?? 0;
+ content.WriterId = contentVersionDto.UserId;
+ content.CreateDate = nodeDto.CreateDate;
+ content.UpdateDate = contentVersionDto.VersionDate;
+
+ content.Published = dto.Published;
+ content.Edited = dto.Edited;
+ content.ExpireDate = dto.ExpiresDate;
+ content.ReleaseDate = dto.ReleaseDate;
+
+ // fixme - shall we get published infos or not?
+ //if (dto.Published)
+ if (publishedVersionDto != null)
+ {
+ content.PublishedVersionPk = publishedVersionDto.Id;
+ content.PublishDate = publishedVersionDto.ContentVersionDto.VersionDate;
+ content.PublishName = publishedVersionDto.ContentVersionDto.Text;
+ content.PublisherId = publishedVersionDto.ContentVersionDto.UserId;
+ }
+
+ // templates = ignored, managed by the repository
+
+ // reset dirty initial properties (U4-1946)
+ content.ResetDirtyProperties(false);
+ return content;
+ }
+ finally
+ {
+ content.EnableChangeTracking();
+ }
+ }
+
+ ///
+ /// Builds an IMedia item from a dto and content type.
+ ///
+ public static Models.Media BuildEntity(ContentDto dto, IMediaType contentType)
+ {
+ var nodeDto = dto.NodeDto;
+ var contentVersionDto = dto.ContentVersionDto;
+
+ var content = new Models.Media(nodeDto.Text, nodeDto.ParentId, contentType);
+
+ try
+ {
+ content.DisableChangeTracking();
+
+ content.Id = dto.NodeId;
+ content.Key = nodeDto.UniqueId;
+ content.Version = contentVersionDto.VersionId;
+ content.VersionPk = contentVersionDto.Id;
+
+ // fixme missing names?
+
+ content.Path = nodeDto.Path;
+ content.Level = nodeDto.Level;
+ content.ParentId = nodeDto.ParentId;
+ content.SortOrder = nodeDto.SortOrder;
+ content.Trashed = nodeDto.Trashed;
+
+ content.CreatorId = nodeDto.UserId ?? 0;
+ content.WriterId = contentVersionDto.UserId;
+ content.CreateDate = nodeDto.CreateDate;
+ content.UpdateDate = contentVersionDto.VersionDate;
+
+ // reset dirty initial properties (U4-1946)
+ content.ResetDirtyProperties(false);
+ return content;
+ }
+ finally
+ {
+ content.EnableChangeTracking();
+ }
+ }
+
+ ///
+ /// Builds an IMedia item from a dto and content type.
+ ///
+ public static Member BuildEntity(MemberDto dto, IMemberType contentType)
+ {
+ var nodeDto = dto.ContentDto.NodeDto;
+ var contentVersionDto = dto.ContentVersionDto;
+
+ var content = new Member(nodeDto.Text, dto.Email, dto.LoginName, dto.Password, contentType);
+
+ try
+ {
+ content.DisableChangeTracking();
+
+ content.Id = dto.NodeId;
+ content.Key = nodeDto.UniqueId;
+ content.Version = contentVersionDto.VersionId;
+ content.VersionPk = contentVersionDto.Id;
+
+ // fixme missing names?
+
+ content.Path = nodeDto.Path;
+ content.Level = nodeDto.Level;
+ content.ParentId = nodeDto.ParentId;
+ content.SortOrder = nodeDto.SortOrder;
+ content.Trashed = nodeDto.Trashed;
+
+ content.CreatorId = nodeDto.UserId ?? 0;
+ content.WriterId = contentVersionDto.UserId;
+ content.CreateDate = nodeDto.CreateDate;
+ content.UpdateDate = contentVersionDto.VersionDate;
+
+ content.ProviderUserKey = content.Key; // fixme explain
+
+ // reset dirty initial properties (U4-1946)
+ content.ResetDirtyProperties(false);
+ return content;
+ }
+ finally
+ {
+ content.EnableChangeTracking();
+ }
+ }
+
+ ///
+ /// Buils a dto from an IContent item.
+ ///
+ public static DocumentDto BuildDto(IContent entity, Guid objectType)
+ {
+ var contentBase = (Content) entity;
+ var contentDto = BuildContentDto(contentBase, objectType);
+
+ var dto = new DocumentDto
+ {
+ NodeId = entity.Id,
+ Published = entity.Published,
+ ReleaseDate = entity.ReleaseDate,
+ ExpiresDate = entity.ExpireDate,
+
+ ContentDto = contentDto,
+ DocumentVersionDto = BuildDocumentVersionDto(contentBase, contentDto)
+ };
+
+ return dto;
+ }
+
+ ///
+ /// Buils a dto from an IMedia item.
+ ///
+ public static ContentDto BuildDto(IMedia entity)
+ {
+ var contentBase = (Models.Media) entity;
+ var dto = BuildContentDto(contentBase, Constants.ObjectTypes.Media);
+ dto.ContentVersionDto = BuildContentVersionDto(contentBase, dto);
+ return dto;
+ }
+
+ ///
+ /// Buils a dto from an IMember item.
+ ///
+ public static MemberDto BuildDto(IMember entity)
+ {
+ var member = (Member) entity;
+ var contentDto = BuildContentDto(member, Constants.ObjectTypes.Member);
+
+ var dto = new MemberDto
+ {
+ Email = entity.Email,
+ LoginName = entity.Username,
+ NodeId = entity.Id,
+ Password = entity.RawPasswordValue,
+
+ ContentDto = contentDto,
+ ContentVersionDto = BuildContentVersionDto(member, contentDto)
+ };
+ return dto;
+ }
+
+ private static ContentDto BuildContentDto(ContentBase entity, Guid objectType)
+ {
+ var dto = new ContentDto
+ {
+ NodeId = entity.Id,
+ ContentTypeId = entity.ContentTypeId,
+
+ NodeDto = BuildNodeDto(entity, objectType)
+ };
+
+ return dto;
+ }
+
+ private static NodeDto BuildNodeDto(ContentBase entity, Guid objectType)
+ {
+ var dto = new NodeDto
+ {
+ NodeId = entity.Id,
+ UniqueId = entity.Key,
+ ParentId = entity.ParentId,
+ Level = Convert.ToInt16(entity.Level),
+ Path = entity.Path,
+ SortOrder = entity.SortOrder,
+ Trashed = entity.Trashed,
+ UserId = entity.CreatorId,
+ Text = entity.Name,
+ NodeObjectType = objectType,
+ CreateDate = entity.CreateDate
+ };
+
+ return dto;
+ }
+
+ // always build the current / VersionPk dto
+ // we're never going to build / save old versions (which are immutable)
+ private static ContentVersionDto BuildContentVersionDto(ContentBase entity, ContentDto contentDto)
+ {
+ var dto = new ContentVersionDto
+ {
+ Id = entity.VersionPk,
+ NodeId = entity.Id,
+ VersionId = entity.Version,
+ VersionDate = entity.UpdateDate,
+ UserId = entity.WriterId,
+ Current = true, // always building the current one
+ Text = entity.Name,
+
+ ContentDto = contentDto
+ };
+
+ return dto;
+ }
+
+ // always build the current / VersionPk dto
+ // we're never going to build / save old versions (which are immutable)
+ private static DocumentVersionDto BuildDocumentVersionDto(Content entity, ContentDto contentDto)
+ {
+ var dto = new DocumentVersionDto
+ {
+ Id = entity.VersionPk,
+ TemplateId = entity.Template?.Id,
+ Published = false, // always building the current, unpublished one
+
+ ContentVersionDto = BuildContentVersionDto(entity, contentDto)
+ };
+
+ return dto;
+ }
+ }
+}
diff --git a/src/Umbraco.Core/Persistence/Factories/MediaFactory.cs b/src/Umbraco.Core/Persistence/Factories/MediaFactory.cs
deleted file mode 100644
index ef1a6abaa1..0000000000
--- a/src/Umbraco.Core/Persistence/Factories/MediaFactory.cs
+++ /dev/null
@@ -1,114 +0,0 @@
-using System;
-using Umbraco.Core.Models;
-using Umbraco.Core.Models.Rdbms;
-
-namespace Umbraco.Core.Persistence.Factories
-{
- internal class MediaFactory
- {
- ///
- /// Builds an IMedia item from a dto and content type.
- ///
- public static Models.Media BuildEntity(ContentDto dto, IMediaType contentType)
- {
- var nodeDto = dto.NodeDto;
- var contentVersionDto = dto.ContentVersionDto;
-
- var content = new Models.Media(nodeDto.Text, nodeDto.ParentId, contentType);
-
- try
- {
- content.DisableChangeTracking();
-
- content.Id = dto.NodeId;
- content.Key = nodeDto.UniqueId;
- content.Version = contentVersionDto.VersionId;
- content.VersionPk = contentVersionDto.Id;
-
- // fixme missing names?
-
- content.Path = nodeDto.Path;
- content.Level = nodeDto.Level;
- content.ParentId = nodeDto.ParentId;
- content.SortOrder = nodeDto.SortOrder;
- content.Trashed = nodeDto.Trashed;
-
- content.CreatorId = nodeDto.UserId ?? 0;
- content.WriterId = contentVersionDto.UserId;
- content.CreateDate = nodeDto.CreateDate;
- content.UpdateDate = contentVersionDto.VersionDate;
-
- // reset dirty initial properties (U4-1946)
- content.ResetDirtyProperties(false);
- return content;
- }
- finally
- {
- content.EnableChangeTracking();
- }
- }
-
- ///
- /// Buils a dto from an IMedia item.
- ///
- public static ContentDto BuildDto(IMedia entity)
- {
- var dto = BuildContentDto(entity, Constants.ObjectTypes.Media);
- dto.ContentVersionDto = BuildContentVersionDto(entity, dto);
- return dto;
- }
-
- private static ContentDto BuildContentDto(IMedia entity, Guid objectType)
- {
- var dto = new ContentDto
- {
- NodeId = entity.Id,
- ContentTypeId = entity.ContentTypeId,
-
- NodeDto = BuildNodeDto(entity, objectType)
- };
-
- return dto;
- }
-
- private static NodeDto BuildNodeDto(IMedia entity, Guid objectType)
- {
- var dto = new NodeDto
- {
- NodeId = entity.Id,
- UniqueId = entity.Key,
- ParentId = entity.ParentId,
- Level = Convert.ToInt16(entity.Level),
- Path = entity.Path,
- SortOrder = entity.SortOrder,
- Trashed = entity.Trashed,
- UserId = entity.CreatorId,
- Text = entity.Name,
- NodeObjectType = objectType,
- CreateDate = entity.CreateDate
- };
-
- return dto;
- }
-
- // always build the current / VersionPk dto
- // we're never going to build / save old versions (which are immutable)
- private static ContentVersionDto BuildContentVersionDto(IMedia entity, ContentDto contentDto)
- {
- var dto = new ContentVersionDto
- {
- Id = ((ContentBase) entity).VersionPk,
- NodeId = entity.Id,
- VersionId = entity.Version,
- VersionDate = entity.UpdateDate,
- UserId = entity.WriterId,
- Current = true, // always building the current one
- Text = entity.Name,
-
- ContentDto = contentDto
- };
-
- return dto;
- }
- }
-}
diff --git a/src/Umbraco.Core/Persistence/Factories/MemberFactory.cs b/src/Umbraco.Core/Persistence/Factories/MemberFactory.cs
deleted file mode 100644
index fd9b2fb6c0..0000000000
--- a/src/Umbraco.Core/Persistence/Factories/MemberFactory.cs
+++ /dev/null
@@ -1,124 +0,0 @@
-using System;
-using Umbraco.Core.Models;
-using Umbraco.Core.Models.Rdbms;
-
-namespace Umbraco.Core.Persistence.Factories
-{
- internal class MemberFactory
- {
- ///
- /// Builds an IMedia item from a dto and content type.
- ///
- public static Member BuildEntity(MemberDto dto, IMemberType contentType)
- {
- var nodeDto = dto.ContentDto.NodeDto;
- var contentVersionDto = dto.ContentVersionDto;
-
- var content = new Member(nodeDto.Text, dto.Email, dto.LoginName, dto.Password, contentType);
-
- try
- {
- content.DisableChangeTracking();
-
- content.Id = dto.NodeId;
- content.Key = nodeDto.UniqueId;
- content.Version = contentVersionDto.VersionId;
- content.VersionPk = contentVersionDto.Id;
-
- // fixme missing names?
-
- content.Path = nodeDto.Path;
- content.Level = nodeDto.Level;
- content.ParentId = nodeDto.ParentId;
- content.SortOrder = nodeDto.SortOrder;
- content.Trashed = nodeDto.Trashed;
-
- content.CreatorId = nodeDto.UserId ?? 0;
- content.WriterId = contentVersionDto.UserId;
- content.CreateDate = nodeDto.CreateDate;
- content.UpdateDate = contentVersionDto.VersionDate;
-
- content.ProviderUserKey = content.Key; // fixme explain
-
- // reset dirty initial properties (U4-1946)
- content.ResetDirtyProperties(false);
- return content;
- }
- finally
- {
- content.EnableChangeTracking();
- }
- }
-
- ///
- /// Buils a dto from an IMember item.
- ///
- public static MemberDto BuildDto(IMember entity)
- {
- var contentDto = BuildContentDto(entity, Constants.ObjectTypes.Member);
-
- var dto = new MemberDto
- {
- Email = entity.Email,
- LoginName = entity.Username,
- NodeId = entity.Id,
- Password = entity.RawPasswordValue,
-
- ContentDto = contentDto,
- ContentVersionDto = BuildContentVersionDto(entity, contentDto)
- };
- return dto;
- }
-
- private static ContentDto BuildContentDto(IMember entity, Guid objectType)
- {
- var dto = new ContentDto
- {
- NodeId = entity.Id,
- ContentTypeId = entity.ContentTypeId,
-
- NodeDto = BuildNodeDto(entity, objectType)
- };
-
- return dto;
- }
-
- private static NodeDto BuildNodeDto(IMember entity, Guid objectType)
- {
- var dto = new NodeDto
- {
- NodeId = entity.Id,
- UniqueId = entity.Key,
- ParentId = entity.ParentId,
- Level = Convert.ToInt16(entity.Level),
- Path = entity.Path,
- SortOrder = entity.SortOrder,
- Trashed = entity.Trashed,
- UserId = entity.CreatorId,
- Text = entity.Name,
- NodeObjectType = objectType,
- CreateDate = entity.CreateDate
- };
-
- return dto;
- }
-
- private static ContentVersionDto BuildContentVersionDto(IMember entity, ContentDto contentDto)
- {
- var dto = new ContentVersionDto
- {
- Id = ((ContentBase) entity).VersionPk,
- NodeId = entity.Id,
- VersionId = entity.Version,
- VersionDate = entity.UpdateDate,
- UserId = entity.WriterId,
- Current = true, // always building the current one
- Text = entity.Name,
-
- ContentDto = contentDto
- };
-
- return dto;
- }
- }
-}
diff --git a/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs b/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs
index 315e306cac..2f93313556 100644
--- a/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs
+++ b/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs
@@ -2,6 +2,7 @@
using NPoco;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
+using Umbraco.Core.Models;
using Umbraco.Core.Models.Rdbms;
namespace Umbraco.Core.Persistence.Migrations.Initial
@@ -137,10 +138,10 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
private void CreateContentTypeData()
{
- _database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 532, NodeId = 1031, Alias = Constants.Conventions.MediaTypes.Folder, Icon = "icon-folder", Thumbnail = "icon-folder", IsContainer = false, AllowAtRoot = true });
- _database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 533, NodeId = 1032, Alias = Constants.Conventions.MediaTypes.Image, Icon = "icon-picture", Thumbnail = "icon-picture", AllowAtRoot = true });
- _database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 534, NodeId = 1033, Alias = Constants.Conventions.MediaTypes.File, Icon = "icon-document", Thumbnail = "icon-document", AllowAtRoot = true });
- _database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 531, NodeId = 1044, Alias = Constants.Conventions.MemberTypes.DefaultAlias, Icon = "icon-user", Thumbnail = "icon-user" });
+ _database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 532, NodeId = 1031, Alias = Constants.Conventions.MediaTypes.Folder, Icon = "icon-folder", Thumbnail = "icon-folder", IsContainer = false, AllowAtRoot = true, Variations = (byte) ContentVariation.InvariantNeutral });
+ _database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 533, NodeId = 1032, Alias = Constants.Conventions.MediaTypes.Image, Icon = "icon-picture", Thumbnail = "icon-picture", AllowAtRoot = true, Variations = (byte) ContentVariation.InvariantNeutral });
+ _database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 534, NodeId = 1033, Alias = Constants.Conventions.MediaTypes.File, Icon = "icon-document", Thumbnail = "icon-document", AllowAtRoot = true, Variations = (byte) ContentVariation.InvariantNeutral });
+ _database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 531, NodeId = 1044, Alias = Constants.Conventions.MemberTypes.DefaultAlias, Icon = "icon-user", Thumbnail = "icon-user", Variations = (byte) ContentVariation.InvariantNeutral });
}
private void CreateUserData()
@@ -191,23 +192,23 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
private void CreatePropertyTypeData()
{
- _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 6, UniqueId = 6.ToGuid(), DataTypeId = 1043, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.File, Name = "Upload image", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null });
- _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 7, UniqueId = 7.ToGuid(), DataTypeId = -92, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.Width, Name = "Width", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null });
- _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 8, UniqueId = 8.ToGuid(), DataTypeId = -92, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.Height, Name = "Height", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null });
- _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 9, UniqueId = 9.ToGuid(), DataTypeId = -92, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.Bytes, Name = "Size", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null });
- _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 10, UniqueId = 10.ToGuid(), DataTypeId = -92, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.Extension, Name = "Type", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null });
- _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 24, UniqueId = 24.ToGuid(), DataTypeId = -90, ContentTypeId = 1033, PropertyTypeGroupId = 4, Alias = Constants.Conventions.Media.File, Name = "Upload file", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null });
- _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 25, UniqueId = 25.ToGuid(), DataTypeId = -92, ContentTypeId = 1033, PropertyTypeGroupId = 4, Alias = Constants.Conventions.Media.Extension, Name = "Type", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null });
- _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 26, UniqueId = 26.ToGuid(), DataTypeId = -92, ContentTypeId = 1033, PropertyTypeGroupId = 4, Alias = Constants.Conventions.Media.Bytes, Name = "Size", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null });
- _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 27, UniqueId = 27.ToGuid(), DataTypeId = Constants.DataTypes.DefaultMediaListView, ContentTypeId = 1031, PropertyTypeGroupId = 5, Alias = "contents", Name = "Contents:", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null });
+ _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 6, UniqueId = 6.ToGuid(), DataTypeId = 1043, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.File, Name = "Upload image", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.InvariantNeutral });
+ _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 7, UniqueId = 7.ToGuid(), DataTypeId = -92, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.Width, Name = "Width", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.InvariantNeutral });
+ _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 8, UniqueId = 8.ToGuid(), DataTypeId = -92, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.Height, Name = "Height", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.InvariantNeutral });
+ _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 9, UniqueId = 9.ToGuid(), DataTypeId = -92, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.Bytes, Name = "Size", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.InvariantNeutral });
+ _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 10, UniqueId = 10.ToGuid(), DataTypeId = -92, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.Extension, Name = "Type", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.InvariantNeutral });
+ _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 24, UniqueId = 24.ToGuid(), DataTypeId = -90, ContentTypeId = 1033, PropertyTypeGroupId = 4, Alias = Constants.Conventions.Media.File, Name = "Upload file", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.InvariantNeutral });
+ _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 25, UniqueId = 25.ToGuid(), DataTypeId = -92, ContentTypeId = 1033, PropertyTypeGroupId = 4, Alias = Constants.Conventions.Media.Extension, Name = "Type", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.InvariantNeutral });
+ _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 26, UniqueId = 26.ToGuid(), DataTypeId = -92, ContentTypeId = 1033, PropertyTypeGroupId = 4, Alias = Constants.Conventions.Media.Bytes, Name = "Size", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.InvariantNeutral });
+ _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 27, UniqueId = 27.ToGuid(), DataTypeId = Constants.DataTypes.DefaultMediaListView, ContentTypeId = 1031, PropertyTypeGroupId = 5, Alias = "contents", Name = "Contents:", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.InvariantNeutral });
//membership property types
- _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 28, UniqueId = 28.ToGuid(), DataTypeId = -89, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.Comments, Name = Constants.Conventions.Member.CommentsLabel, SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null });
- _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 29, UniqueId = 29.ToGuid(), DataTypeId = -92, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.FailedPasswordAttempts, Name = Constants.Conventions.Member.FailedPasswordAttemptsLabel, SortOrder = 1, Mandatory = false, ValidationRegExp = null, Description = null });
- _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 30, UniqueId = 30.ToGuid(), DataTypeId = -49, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.IsApproved, Name = Constants.Conventions.Member.IsApprovedLabel, SortOrder = 2, Mandatory = false, ValidationRegExp = null, Description = null });
- _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 31, UniqueId = 31.ToGuid(), DataTypeId = -49, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.IsLockedOut, Name = Constants.Conventions.Member.IsLockedOutLabel, SortOrder = 3, Mandatory = false, ValidationRegExp = null, Description = null });
- _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 32, UniqueId = 32.ToGuid(), DataTypeId = -92, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.LastLockoutDate, Name = Constants.Conventions.Member.LastLockoutDateLabel, SortOrder = 4, Mandatory = false, ValidationRegExp = null, Description = null });
- _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 33, UniqueId = 33.ToGuid(), DataTypeId = -92, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.LastLoginDate, Name = Constants.Conventions.Member.LastLoginDateLabel, SortOrder = 5, Mandatory = false, ValidationRegExp = null, Description = null });
- _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 34, UniqueId = 34.ToGuid(), DataTypeId = -92, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.LastPasswordChangeDate, Name = Constants.Conventions.Member.LastPasswordChangeDateLabel, SortOrder = 6, Mandatory = false, ValidationRegExp = null, Description = null });
+ _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 28, UniqueId = 28.ToGuid(), DataTypeId = -89, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.Comments, Name = Constants.Conventions.Member.CommentsLabel, SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.InvariantNeutral });
+ _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 29, UniqueId = 29.ToGuid(), DataTypeId = -92, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.FailedPasswordAttempts, Name = Constants.Conventions.Member.FailedPasswordAttemptsLabel, SortOrder = 1, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.InvariantNeutral });
+ _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 30, UniqueId = 30.ToGuid(), DataTypeId = -49, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.IsApproved, Name = Constants.Conventions.Member.IsApprovedLabel, SortOrder = 2, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.InvariantNeutral });
+ _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 31, UniqueId = 31.ToGuid(), DataTypeId = -49, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.IsLockedOut, Name = Constants.Conventions.Member.IsLockedOutLabel, SortOrder = 3, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.InvariantNeutral });
+ _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 32, UniqueId = 32.ToGuid(), DataTypeId = -92, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.LastLockoutDate, Name = Constants.Conventions.Member.LastLockoutDateLabel, SortOrder = 4, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.InvariantNeutral });
+ _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 33, UniqueId = 33.ToGuid(), DataTypeId = -92, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.LastLoginDate, Name = Constants.Conventions.Member.LastLoginDateLabel, SortOrder = 5, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.InvariantNeutral });
+ _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 34, UniqueId = 34.ToGuid(), DataTypeId = -92, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.LastPasswordChangeDate, Name = Constants.Conventions.Member.LastPasswordChangeDateLabel, SortOrder = 6, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.InvariantNeutral });
}
diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionEight/VariantsMigration.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionEight/VariantsMigration.cs
index 561bd13250..1ff5cc8749 100644
--- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionEight/VariantsMigration.cs
+++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionEight/VariantsMigration.cs
@@ -27,6 +27,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionEight
Execute.DropKeysAndIndexes();
MigratePropertyData();
+ MigrateContentAndPropertyTypes();
MigrateContent();
MigrateVersions();
@@ -108,6 +109,14 @@ HAVING COUNT(v2.id) <> 1").Any())
Rename.Table(PreTables.PropertyData).To(Constants.DatabaseSchema.Tables.PropertyData);
}
+ private void MigrateContentAndPropertyTypes()
+ {
+ if (!ColumnExists(PreTables.ContentType, "variations"))
+ AddColumn(PreTables.ContentType, "variations");
+ if (!ColumnExists(PreTables.PropertyType, "variations"))
+ AddColumn(PreTables.PropertyType, "variations");
+ }
+
private void MigrateContent()
{
// if the table has already been renamed, we're done
diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs
index 88ac07c448..1cd799836c 100644
--- a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs
@@ -202,7 +202,7 @@ namespace Umbraco.Core.Persistence.Repositories
return MapDtosToContent(Database.Fetch(sql), true);
}
- public override IContent GetByVersion(Guid versionId)
+ public override IContent GetVersion(Guid versionId)
{
var sql = GetBaseQuery(QueryType.Single, false)
.Where(x => x.VersionId == versionId);
@@ -245,7 +245,7 @@ namespace Umbraco.Core.Persistence.Repositories
entity.SanitizeEntityPropertiesForXmlStorage();
// create the dto
- var dto = ContentFactory.BuildDto(entity, NodeObjectTypeId);
+ var dto = ContentBaseFactory.BuildDto(entity, NodeObjectTypeId);
// derive path and level from parent
var parent = GetParentNodeDto(entity.ParentId);
@@ -323,7 +323,7 @@ namespace Umbraco.Core.Persistence.Repositories
if (content.PublishedState == PublishedState.Publishing)
dto.Published = true;
dto.NodeId = nodeDto.NodeId;
- content.Edited = dto.Edited = edited;
+ content.Edited = dto.Edited = !dto.Published || edited; // if not published, always edited
Database.Insert(dto);
// trigger here, before we reset Published etc
@@ -409,7 +409,7 @@ namespace Umbraco.Core.Persistence.Repositories
}
// create the dto
- var dto = ContentFactory.BuildDto(entity, NodeObjectTypeId);
+ var dto = ContentBaseFactory.BuildDto(entity, NodeObjectTypeId);
// update the node dto
var nodeDto = dto.ContentDto.NodeDto;
@@ -461,7 +461,7 @@ namespace Umbraco.Core.Persistence.Repositories
dto.Published = true;
else if (content.PublishedState == PublishedState.Unpublishing)
dto.Published = false;
- content.Edited = dto.Edited = edited;
+ content.Edited = dto.Edited = !dto.Published || edited; // if not published, always edited
Database.Update(dto);
// if entity is publishing, update tags, else leave tags there
@@ -783,7 +783,7 @@ namespace Umbraco.Core.Persistence.Repositories
if (contentTypes.TryGetValue(contentTypeId, out var contentType) == false)
contentTypes[contentTypeId] = contentType = _contentTypeRepository.Get(contentTypeId);
- var c = content[i] = ContentFactory.BuildEntity(dto, contentType);
+ var c = content[i] = ContentBaseFactory.BuildEntity(dto, contentType);
// need templates
var templateId = dto.DocumentVersionDto.TemplateId;
@@ -834,7 +834,7 @@ namespace Umbraco.Core.Persistence.Repositories
private IContent MapDtoToContent(DocumentDto dto)
{
var contentType = _contentTypeRepository.Get(dto.ContentDto.ContentTypeId);
- var content = ContentFactory.BuildEntity(dto, contentType);
+ var content = ContentBaseFactory.BuildEntity(dto, contentType);
// get template
if (dto.DocumentVersionDto.TemplateId.HasValue && dto.DocumentVersionDto.TemplateId.Value > 0)
@@ -842,7 +842,11 @@ namespace Umbraco.Core.Persistence.Repositories
// get properties - indexed by version id
var versionId = dto.DocumentVersionDto.Id;
- var publishedVersionId = dto.Published ? dto.PublishedVersionDto.Id : 0;
+
+ // fixme - shall we get published properties or not?
+ //var publishedVersionId = dto.Published ? dto.PublishedVersionDto.Id : 0;
+ var publishedVersionId = dto.PublishedVersionDto != null ? dto.PublishedVersionDto.Id : 0;
+
var temp = new TempContent(dto.NodeId, versionId, publishedVersionId, contentType);
var properties = GetPropertyCollections(new List> { temp });
content.Properties = properties[dto.DocumentVersionDto.Id];
diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentTypeRepositoryBase.cs b/src/Umbraco.Core/Persistence/Repositories/ContentTypeRepositoryBase.cs
index 78b5073e52..74c73bb980 100644
--- a/src/Umbraco.Core/Persistence/Repositories/ContentTypeRepositoryBase.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/ContentTypeRepositoryBase.cs
@@ -749,7 +749,7 @@ AND umbracoNode.id <> @id",
{
if (db == null) throw new ArgumentNullException(nameof(db));
- var sql = @"SELECT cmsContentType.pk as ctPk, cmsContentType.alias as ctAlias, cmsContentType.allowAtRoot as ctAllowAtRoot, cmsContentType.description as ctDesc,
+ var sql = @"SELECT cmsContentType.pk as ctPk, cmsContentType.alias as ctAlias, cmsContentType.allowAtRoot as ctAllowAtRoot, cmsContentType.description as ctDesc, cmsContentType.variations as ctVariations,
cmsContentType.icon as ctIcon, cmsContentType.isContainer as ctIsContainer, cmsContentType.nodeId as ctId, cmsContentType.thumbnail as ctThumb,
AllowedTypes.AllowedId as ctaAllowedId, AllowedTypes.SortOrder as ctaSortOrder, AllowedTypes.alias as ctaAlias,
ParentTypes.parentContentTypeId as chtParentId, ParentTypes.parentContentTypeKey as chtParentKey,
@@ -854,6 +854,7 @@ AND umbracoNode.id <> @id",
NodeId = currCt.ctId,
PrimaryKey = currCt.ctPk,
Thumbnail = currCt.ctThumb,
+ Variations = (byte) currCt.ctVariations,
//map the underlying node dto
NodeDto = new NodeDto
{
@@ -889,7 +890,7 @@ AND umbracoNode.id <> @id",
if (db == null) throw new ArgumentNullException(nameof(db));
var sql = @"SELECT cmsDocumentType.IsDefault as dtIsDefault, cmsDocumentType.templateNodeId as dtTemplateId,
- cmsContentType.pk as ctPk, cmsContentType.alias as ctAlias, cmsContentType.allowAtRoot as ctAllowAtRoot, cmsContentType.description as ctDesc,
+ cmsContentType.pk as ctPk, cmsContentType.alias as ctAlias, cmsContentType.allowAtRoot as ctAllowAtRoot, cmsContentType.description as ctDesc, cmsContentType.variations as ctVariations,
cmsContentType.icon as ctIcon, cmsContentType.isContainer as ctIsContainer, cmsContentType.nodeId as ctId, cmsContentType.thumbnail as ctThumb,
AllowedTypes.AllowedId as ctaAllowedId, AllowedTypes.SortOrder as ctaSortOrder, AllowedTypes.alias as ctaAlias,
ParentTypes.parentContentTypeId as chtParentId,ParentTypes.parentContentTypeKey as chtParentKey,
@@ -1030,6 +1031,7 @@ AND umbracoNode.id <> @id",
NodeId = currCt.ctId,
PrimaryKey = currCt.ctPk,
Thumbnail = currCt.ctThumb,
+ Variations = (byte) currCt.ctVariations,
//map the underlying node dto
NodeDto = new NodeDto
{
@@ -1092,7 +1094,7 @@ ORDER BY contentTypeId, id";
pt.id AS id, pt.uniqueID AS " + sqlSyntax.GetQuotedColumnName("key") + @",
pt.propertyTypeGroupId AS groupId,
pt.Alias AS alias, pt." + sqlSyntax.GetQuotedColumnName("Description") + @" AS " + sqlSyntax.GetQuotedColumnName("desc") + @", pt.mandatory AS mandatory,
- pt.Name AS name, pt.sortOrder AS sortOrder, pt.validationRegExp AS regexp,
+ pt.Name AS name, pt.sortOrder AS sortOrder, pt.validationRegExp AS regexp, pt.variations as variations,
dt.nodeId as dataTypeId, dt.dbType as dbType, dt.propertyEditorAlias as editorAlias
FROM cmsPropertyType pt
INNER JOIN cmsDataType as dt ON pt.dataTypeId = dt.nodeId
@@ -1161,7 +1163,8 @@ ORDER BY contentTypeId, groupId, id";
Name = prop.name,
PropertyGroupId = propertyGroup == null ? null : new Lazy(() => propertyGroup.Id),
SortOrder = prop.sortOrder,
- ValidationRegExp = prop.regexp
+ ValidationRegExp = prop.regexp,
+ Variations = (ContentVariation) prop.variations
};
propertyTypes.Add(propertyType);
}
diff --git a/src/Umbraco.Core/Persistence/Repositories/Interfaces/IRepositoryVersionable.cs b/src/Umbraco.Core/Persistence/Repositories/Interfaces/IRepositoryVersionable.cs
index da8beb6e59..29901dbe19 100644
--- a/src/Umbraco.Core/Persistence/Repositories/Interfaces/IRepositoryVersionable.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/Interfaces/IRepositoryVersionable.cs
@@ -35,31 +35,29 @@ namespace Umbraco.Core.Persistence.Repositories
IEnumerable GetAllVersions(int nodeId);
///
- /// Gets a list of all version Ids for the given content item
+ /// Gets a list of all version idenfitifers of an entity.
///
///
- /// The maximum number of rows to return
- ///
- IEnumerable GetVersionIds(int id, int maxRows);
+ /// The maximum number of rows to return
+ IEnumerable GetVersionIds(int id, int topRows);
///
- /// Gets a specific version of an .
+ /// Gets a specific version of an entity.
///
- /// Id of the version to retrieve
- /// An item
- TEntity GetByVersion(Guid versionId);
+ /// The identifier of the version.
+ TEntity GetVersion(Guid versionId);
///
- /// Deletes a specific version from an object.
+ /// Deletes a specific version of an entity.
///
- /// Id of the version to delete
+ /// The identifier of the version to delete.
void DeleteVersion(Guid versionId);
///
- /// Deletes versions from an object prior to a specific date.
+ /// Deletes all versions of an entity, older than a date.
///
- /// Id of the object to delete versions from
- /// Latest version date
+ /// The identifier of the entity.
+ /// The date.
void DeleteVersions(int nodeId, DateTime versionDate);
///
diff --git a/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs
index 65dc209067..0ec65e9028 100644
--- a/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs
@@ -167,7 +167,7 @@ namespace Umbraco.Core.Persistence.Repositories
return MapDtosToContent(Database.Fetch(sql), true);
}
- public override IMedia GetByVersion(Guid versionId)
+ public override IMedia GetVersion(Guid versionId)
{
var sql = GetBaseQuery(QueryType.Single)
.Where(x => x.VersionId == versionId);
@@ -241,7 +241,7 @@ namespace Umbraco.Core.Persistence.Repositories
entity.SanitizeEntityPropertiesForXmlStorage();
// create the dto
- var dto = MediaFactory.BuildDto(entity);
+ var dto = ContentBaseFactory.BuildDto(entity);
// derive path and level from parent
var parent = GetParentNodeDto(entity.ParentId);
@@ -332,7 +332,7 @@ namespace Umbraco.Core.Persistence.Repositories
}
// create the dto
- var dto = MediaFactory.BuildDto(entity);
+ var dto = ContentBaseFactory.BuildDto(entity);
// update the node dto
var nodeDto = dto.NodeDto;
@@ -519,7 +519,7 @@ namespace Umbraco.Core.Persistence.Repositories
if (contentTypes.TryGetValue(contentTypeId, out IMediaType contentType) == false)
contentTypes[contentTypeId] = contentType = _mediaTypeRepository.Get(contentTypeId);
- var c = content[i] = MediaFactory.BuildEntity(dto, contentType);
+ var c = content[i] = ContentBaseFactory.BuildEntity(dto, contentType);
// need properties
var versionId = dto.ContentVersionDto.Id;
@@ -544,7 +544,7 @@ namespace Umbraco.Core.Persistence.Repositories
private IMedia MapDtoToContent(ContentDto dto)
{
var contentType = _mediaTypeRepository.Get(dto.ContentTypeId);
- var media = MediaFactory.BuildEntity(dto, contentType);
+ var media = ContentBaseFactory.BuildEntity(dto, contentType);
// get properties - indexed by version id
var versionId = dto.ContentVersionDto.Id;
diff --git a/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs
index 8d0d3df40f..246080dd16 100644
--- a/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs
@@ -205,7 +205,7 @@ namespace Umbraco.Core.Persistence.Repositories
return MapDtosToContent(Database.Fetch(sql), true);
}
- public override IMember GetByVersion(Guid versionId)
+ public override IMember GetVersion(Guid versionId)
{
var sql = GetBaseQuery(QueryType.Single)
.Where(x => x.VersionId == versionId);
@@ -237,7 +237,7 @@ namespace Umbraco.Core.Persistence.Repositories
entity.SanitizeEntityPropertiesForXmlStorage();
// create the dto
- var dto = MemberFactory.BuildDto(entity);
+ var dto = ContentBaseFactory.BuildDto(entity);
// derive path and level from parent
var parent = GetParentNodeDto(entity.ParentId);
@@ -339,7 +339,7 @@ namespace Umbraco.Core.Persistence.Repositories
}
// create the dto
- var dto = MemberFactory.BuildDto(entity);
+ var dto = ContentBaseFactory.BuildDto(entity);
// update the node dto
var nodeDto = dto.ContentDto.NodeDto;
@@ -569,7 +569,7 @@ namespace Umbraco.Core.Persistence.Repositories
if (contentTypes.TryGetValue(contentTypeId, out var contentType) == false)
contentTypes[contentTypeId] = contentType = _memberTypeRepository.Get(contentTypeId);
- var c = content[i] = MemberFactory.BuildEntity(dto, contentType);
+ var c = content[i] = ContentBaseFactory.BuildEntity(dto, contentType);
// need properties
var versionId = dto.ContentVersionDto.Id;
@@ -594,7 +594,7 @@ namespace Umbraco.Core.Persistence.Repositories
private IMember MapDtoToContent(MemberDto dto)
{
var memberType = _memberTypeRepository.Get(dto.ContentDto.ContentTypeId);
- var member = MemberFactory.BuildEntity(dto, memberType);
+ var member = ContentBaseFactory.BuildEntity(dto, memberType);
// get properties - indexed by version id
var versionId = dto.ContentVersionDto.Id;
diff --git a/src/Umbraco.Core/Persistence/Repositories/VersionableRepositoryBase.cs b/src/Umbraco.Core/Persistence/Repositories/VersionableRepositoryBase.cs
index 11d4603212..550b26867e 100644
--- a/src/Umbraco.Core/Persistence/Repositories/VersionableRepositoryBase.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/VersionableRepositoryBase.cs
@@ -42,7 +42,7 @@ namespace Umbraco.Core.Persistence.Repositories
#region Versions
// gets a specific version
- public abstract TEntity GetByVersion(Guid versionId);
+ public abstract TEntity GetVersion(Guid versionId);
// gets all versions, current first
public abstract IEnumerable GetAllVersions(int nodeId);
@@ -82,7 +82,7 @@ namespace Umbraco.Core.Persistence.Repositories
PerformDeleteVersion(versionDto.NodeId, versionId);
}
- // deletes all version older than a date
+ // deletes all versions of an entity, older than a date.
public virtual void DeleteVersions(int nodeId, DateTime versionDate)
{
// fixme test object node type?
diff --git a/src/Umbraco.Core/Publishing/ScheduledPublisher.cs b/src/Umbraco.Core/Publishing/ScheduledPublisher.cs
index acc21c6c95..86530f54d7 100644
--- a/src/Umbraco.Core/Publishing/ScheduledPublisher.cs
+++ b/src/Umbraco.Core/Publishing/ScheduledPublisher.cs
@@ -28,6 +28,7 @@ namespace Umbraco.Core.Publishing
///
public int CheckPendingAndProcess()
{
+ // fixme isn't this done in ContentService already?
var counter = 0;
var contentForRelease = _contentService.GetContentForRelease().ToArray();
if (contentForRelease.Length > 0)
@@ -37,18 +38,12 @@ namespace Umbraco.Core.Publishing
try
{
d.ReleaseDate = null;
- var result = _contentService.SaveAndPublishWithStatus(d, d.GetWriterProfile().Id);
- _logger.Debug($"Result of publish attempt: {result.Result.StatusType}");
+ d.PublishValues(); // fixme variants?
+ var result = _contentService.SaveAndPublish(d, d.GetWriterProfile().Id);
+ _logger.Debug($"Result of publish attempt: {result.Result}");
if (result.Success == false)
{
- if (result.Exception != null)
- {
- _logger.Error("Could not published the document (" + d.Id + ") based on it's scheduled release, status result: " + result.Result.StatusType, result.Exception);
- }
- else
- {
- _logger.Warn("Could not published the document (" + d.Id + ") based on it's scheduled release. Status result: " + result.Result.StatusType);
- }
+ _logger.Error($"Error publishing node {d.Id}");
}
else
{
@@ -70,8 +65,8 @@ namespace Umbraco.Core.Publishing
try
{
d.ExpireDate = null;
- var result = _contentService.UnPublish(d, d.GetWriterProfile().Id);
- if (result)
+ var result = _contentService.Unpublish(d, d.GetWriterProfile().Id);
+ if (result.Success)
{
counter++;
}
diff --git a/src/Umbraco.Core/Services/ContentService.cs b/src/Umbraco.Core/Services/ContentService.cs
index 4c9c9bca16..0038739e6f 100644
--- a/src/Umbraco.Core/Services/ContentService.cs
+++ b/src/Umbraco.Core/Services/ContentService.cs
@@ -20,7 +20,7 @@ namespace Umbraco.Core.Services
///
/// Represents the Content Service, which is an easy access to operations involving
///
- public class ContentService : ScopeRepositoryService, IContentService, IContentServiceOperations
+ public class ContentService : ScopeRepositoryService, IContentService
{
private readonly MediaFileSystem _mediaFileSystem;
private IQuery _queryNotTrashed;
@@ -94,7 +94,7 @@ namespace Umbraco.Core.Services
/// assigned to an entity with a list of user id & permission pairs.
///
///
- public void ReplaceContentPermissions(EntityPermissionSet permissionSet)
+ public void SetPermissions(EntityPermissionSet permissionSet)
{
using (var uow = UowProvider.CreateUnitOfWork())
{
@@ -111,7 +111,7 @@ namespace Umbraco.Core.Services
///
///
///
- public void AssignContentPermission(IContent entity, char permission, IEnumerable groupIds)
+ public void SetPermission(IContent entity, char permission, IEnumerable groupIds)
{
using (var uow = UowProvider.CreateUnitOfWork())
{
@@ -127,7 +127,7 @@ namespace Umbraco.Core.Services
///
///
///
- public EntityPermissionCollection GetPermissionsForEntity(IContent content)
+ public EntityPermissionCollection GetPermissions(IContent content)
{
using (var uow = UowProvider.CreateUnitOfWork(readOnly: true))
{
@@ -155,10 +155,10 @@ namespace Umbraco.Core.Services
/// Alias of the
/// Optional id of the user creating the content
///
- public IContent CreateContent(string name, Guid parentId, string contentTypeAlias, int userId = 0)
+ public IContent Create(string name, Guid parentId, string contentTypeAlias, int userId = 0)
{
var parent = GetById(parentId);
- return CreateContent(name, parent, contentTypeAlias, userId);
+ return Create(name, parent, contentTypeAlias, userId);
}
///
@@ -173,7 +173,7 @@ namespace Umbraco.Core.Services
/// The alias of the content type.
/// The optional id of the user creating the content.
/// The content object.
- public IContent CreateContent(string name, int parentId, string contentTypeAlias, int userId = 0)
+ public IContent Create(string name, int parentId, string contentTypeAlias, int userId = 0)
{
var contentType = GetContentType(contentTypeAlias);
if (contentType == null)
@@ -233,7 +233,7 @@ namespace Umbraco.Core.Services
/// The alias of the content type.
/// The optional id of the user creating the content.
/// The content object.
- public IContent CreateContent(string name, IContent parent, string contentTypeAlias, int userId = 0)
+ public IContent Create(string name, IContent parent, string contentTypeAlias, int userId = 0)
{
if (parent == null) throw new ArgumentNullException(nameof(parent));
@@ -262,7 +262,7 @@ namespace Umbraco.Core.Services
/// The alias of the content type.
/// The optional id of the user creating the content.
/// The content object.
- public IContent CreateContentWithIdentity(string name, int parentId, string contentTypeAlias, int userId = 0)
+ public IContent CreateAndSave(string name, int parentId, string contentTypeAlias, int userId = 0)
{
using (var uow = UowProvider.CreateUnitOfWork())
{
@@ -294,7 +294,7 @@ namespace Umbraco.Core.Services
/// The alias of the content type.
/// The optional id of the user creating the content.
/// The content object.
- public IContent CreateContentWithIdentity(string name, IContent parent, string contentTypeAlias, int userId = 0)
+ public IContent CreateAndSave(string name, IContent parent, string contentTypeAlias, int userId = 0)
{
if (parent == null) throw new ArgumentNullException(nameof(parent));
@@ -442,7 +442,7 @@ namespace Umbraco.Core.Services
///
/// Id of the
/// An Enumerable list of objects
- public IEnumerable GetContentOfContentType(int id)
+ public IEnumerable GetByType(int id)
{
using (var uow = UowProvider.CreateUnitOfWork(readOnly: true))
{
@@ -486,13 +486,13 @@ namespace Umbraco.Core.Services
///
/// Id of the version to retrieve
/// An item
- public IContent GetByVersion(Guid versionId)
+ public IContent GetVersion(Guid versionId)
{
using (var uow = UowProvider.CreateUnitOfWork(readOnly: true))
{
uow.ReadLock(Constants.Locks.ContentTree);
var repository = uow.CreateRepository();
- return repository.GetByVersion(versionId);
+ return repository.GetVersion(versionId);
}
}
@@ -720,7 +720,7 @@ namespace Umbraco.Core.Services
/// Id of the Parent to retrieve Children from
/// Full or partial name of the children
/// An Enumerable list of objects
- public IEnumerable GetChildrenByName(int parentId, string name)
+ public IEnumerable GetChildren(int parentId, string name)
{
using (var uow = UowProvider.CreateUnitOfWork(readOnly: true))
{
@@ -896,7 +896,7 @@ namespace Umbraco.Core.Services
///
/// to check if anscestors are published
/// True if the Content can be published, otherwise False
- public bool IsPublishable(IContent content)
+ public bool IsPathPublishable(IContent content)
{
// fast
if (content.ParentId == Constants.System.Root) return true; // root content is always publishable
@@ -956,25 +956,15 @@ namespace Umbraco.Core.Services
#region Save, Publish, Unpublish
- ///
- /// Saves a single object
- ///
- /// The to save
- /// Optional Id of the User saving the Content
- /// Optional boolean indicating whether or not to raise events.
- public void Save(IContent content, int userId = 0, bool raiseEvents = true)
- {
- ((IContentServiceOperations) this).Save(content, userId, raiseEvents);
- }
+ // fixme - kill all those raiseEvents
- ///
- /// Saves a single object
- ///
- /// The to save
- /// Optional Id of the User saving the Content
- /// Optional boolean indicating whether or not to raise events.
- Attempt IContentServiceOperations.Save(IContent content, int userId, bool raiseEvents)
+ ///
+ public OperationResult Save(IContent content, int userId = 0, bool raiseEvents = true)
{
+ var publishedState = ((Content) content).PublishedState;
+ if (publishedState != PublishedState.Published && publishedState != PublishedState.Unpublished)
+ throw new InvalidOperationException("Cannot save a (un)publishing, use the dedicated (un)publish method.");
+
var evtMsgs = EventMessagesFactory.Get();
using (var uow = UowProvider.CreateUnitOfWork())
@@ -983,7 +973,7 @@ namespace Umbraco.Core.Services
if (raiseEvents && uow.Events.DispatchCancelable(Saving, this, saveEventArgs, "Saving"))
{
uow.Complete();
- return OperationStatus.Attempt.Cancel(evtMsgs);
+ return OperationResult.Cancel(evtMsgs);
}
if (string.IsNullOrWhiteSpace(content.Name))
@@ -1010,35 +1000,14 @@ namespace Umbraco.Core.Services
var changeType = isNew ? TreeChangeTypes.RefreshBranch : TreeChangeTypes.RefreshNode;
uow.Events.Dispatch(TreeChanged, this, new TreeChange(content, changeType).ToEventArgs());
Audit(uow, AuditType.Save, "Save Content performed by user", userId, content.Id);
-
uow.Complete();
}
- return OperationStatus.Attempt.Succeed(evtMsgs);
+ return OperationResult.Succeed(evtMsgs);
}
- ///
- /// Saves a collection of objects.
- ///
- ///
- /// If the collection of content contains new objects that references eachother by Id or ParentId,
- /// then use the overload Save method with a collection of Lazy .
- ///
- /// Collection of to save
- /// Optional Id of the User saving the Content
- /// Optional boolean indicating whether or not to raise events.
- public void Save(IEnumerable contents, int userId = 0, bool raiseEvents = true)
- {
- ((IContentServiceOperations) this).Save(contents, userId, raiseEvents);
- }
-
- ///
- /// Saves a collection of objects.
- ///
- /// Collection of to save
- /// Optional Id of the User saving the Content
- /// Optional boolean indicating whether or not to raise events.
- Attempt IContentServiceOperations.Save(IEnumerable contents, int userId, bool raiseEvents)
+ ///
+ public OperationResult Save(IEnumerable contents, int userId = 0, bool raiseEvents = true)
{
var evtMsgs = EventMessagesFactory.Get();
var contentsA = contents.ToArray();
@@ -1049,7 +1018,7 @@ namespace Umbraco.Core.Services
if (raiseEvents && uow.Events.DispatchCancelable(Saving, this, saveEventArgs, "Saving"))
{
uow.Complete();
- return OperationStatus.Attempt.Cancel(evtMsgs);
+ return OperationResult.Cancel(evtMsgs);
}
var treeChanges = contentsA.Select(x => new TreeChange(x,
@@ -1077,142 +1046,56 @@ namespace Umbraco.Core.Services
uow.Complete();
}
- return OperationStatus.Attempt.Succeed(evtMsgs);
+ return OperationResult.Succeed(evtMsgs);
}
- ///
- /// Saves and Publishes a single object
- ///
- /// The to save and publish
- /// Optional Id of the User issueing the publishing
- /// Optional boolean indicating whether or not to raise save events.
- /// True if publishing succeeded, otherwise False
- [Obsolete("Use SaveAndPublishWithStatus instead, that method will provide more detailed information on the outcome")]
- public bool SaveAndPublish(IContent content, int userId = 0, bool raiseEvents = true)
- {
- var result = SaveAndPublishDo(content, userId, raiseEvents);
- return result.Success;
- }
-
- ///
- /// Saves and Publishes a single object
- ///
- /// The to save and publish
- /// Optional Id of the User issueing the publishing
- /// Optional boolean indicating whether or not to raise save events.
- /// True if publishing succeeded, otherwise False
- Attempt IContentServiceOperations.SaveAndPublish(IContent content, int userId, bool raiseEvents)
+ ///
+ public PublishResult SaveAndPublish(IContent content, int userId = 0, bool raiseEvents = true)
{
return SaveAndPublishDo(content, userId, raiseEvents);
}
- ///
- /// Publishes a single object
- ///
- /// The to publish
- /// Optional Id of the User issueing the publishing
- /// True if publishing succeeded, otherwise False
- public bool Publish(IContent content, int userId = 0)
+ ///
+ public PublishResult Unpublish(IContent content, int userId = 0)
{
- var result = SaveAndPublishDo(content, userId);
- Logger.Info("Call was made to ContentService.Publish, use PublishWithStatus instead since that method will provide more detailed information on the outcome");
- return result.Success;
+ var evtMsgs = EventMessagesFactory.Get();
+
+ using (var uow = UowProvider.CreateUnitOfWork())
+ {
+ uow.WriteLock(Constants.Locks.ContentTree);
+ var repository = uow.CreateRepository();
+
+ var newest = GetById(content.Id); // ensure we have the newest version
+ if (content.Version != newest.Version) // but use the original object if it's already the newest version
+ content = newest;
+ if (content.Published == false)
+ {
+ uow.Complete();
+ return new PublishResult(PublishResultType.SuccessAlready, evtMsgs, content); // already unpublished
+ }
+
+ // strategy
+ // fixme should we still complete the uow? don't want to rollback here!
+ var attempt = StrategyCanUnPublish(uow, content, userId, evtMsgs);
+ if (attempt.Success == false) return attempt; // causes rollback
+ attempt = StrategyUnPublish(uow, content, true, userId, evtMsgs);
+ if (attempt.Success == false) return attempt; // causes rollback
+
+ content.WriterId = userId;
+ repository.AddOrUpdate(content);
+
+ uow.Events.Dispatch(UnPublished, this, new PublishEventArgs(content, false, false), "UnPublished");
+ uow.Events.Dispatch(TreeChanged, this, new TreeChange(content, TreeChangeTypes.RefreshBranch).ToEventArgs());
+ Audit(uow, AuditType.UnPublish, "UnPublish performed by user", userId, content.Id);
+
+ uow.Complete();
+ }
+
+ return new PublishResult(PublishResultType.Success, evtMsgs, content);
}
- ///
- /// Publishes a single object
- ///
- /// The to publish
- /// Optional Id of the User issueing the publishing
- /// The published status attempt
- Attempt IContentServiceOperations.Publish(IContent content, int userId)
- {
- return SaveAndPublishDo(content, userId);
- }
-
- ///
- /// UnPublishes a single object
- ///
- /// The to publish
- /// Optional Id of the User issueing the publishing
- /// True if unpublishing succeeded, otherwise False
- public bool UnPublish(IContent content, int userId = 0)
- {
- return ((IContentServiceOperations) this).UnPublish(content, userId).Success;
- }
-
- ///
- /// UnPublishes a single object
- ///
- /// The to publish
- /// Optional Id of the User issueing the publishing
- /// True if unpublishing succeeded, otherwise False
- Attempt IContentServiceOperations.UnPublish(IContent content, int userId)
- {
- return UnPublishDo(content, userId);
- }
-
- ///
- /// Saves and Publishes a single object
- ///
- /// The to save and publish
- /// Optional Id of the User issueing the publishing
- /// Optional boolean indicating whether or not to raise save events.
- /// True if publishing succeeded, otherwise False
- public Attempt SaveAndPublishWithStatus(IContent content, int userId = 0, bool raiseEvents = true)
- {
- return ((IContentServiceOperations) this).SaveAndPublish(content, userId, raiseEvents);
- }
-
- ///
- /// Publishes a single object
- ///
- /// The to publish
- /// Optional Id of the User issueing the publishing
- /// True if publishing succeeded, otherwise False
- public Attempt PublishWithStatus(IContent content, int userId = 0)
- {
- return ((IContentServiceOperations) this).Publish(content, userId);
- }
-
- ///
- /// Publishes a object and all its children
- ///
- /// The to publish along with its children
- /// Optional Id of the User issueing the publishing
- /// True if publishing succeeded, otherwise False
- [Obsolete("Use PublishWithChildrenWithStatus instead, that method will provide more detailed information on the outcome and also allows the includeUnpublished flag")]
- public bool PublishWithChildren(IContent content, int userId = 0)
- {
- // this used to just return false only when the parent content failed, otherwise would
- // always return true so we'll do the same thing for the moment
-
- var result = PublishWithChildrenDo(content, userId, true);
-
- // FirstOrDefault() is a pain to use with structs and result contain Attempt structs
- // so use this code, which is fast and works - and please ReSharper do NOT suggest otherwise
- // ReSharper disable once LoopCanBeConvertedToQuery
- foreach (var r in result)
- if (r.Result.ContentItem.Id == content.Id) return r.Success;
- return false;
- }
-
- ///
- /// Publishes a object and all its children
- ///
- /// The to publish along with its children
- /// Optional Id of the User issueing the publishing
- /// set to true if you want to also publish children that are currently unpublished
- /// True if publishing succeeded, otherwise False
- public IEnumerable> PublishWithChildrenWithStatus(IContent content, int userId = 0, bool includeUnpublished = false)
- {
- return ((IContentServiceOperations) this).PublishWithChildren(content, userId, includeUnpublished);
- }
-
- ///
- /// Used to perform scheduled publishing/unpublishing
- ///
- public IEnumerable> PerformScheduledPublish()
+ ///
+ public IEnumerable PerformScheduledPublish()
{
using (var uow = UowProvider.CreateUnitOfWork())
{
@@ -1220,18 +1103,19 @@ namespace Umbraco.Core.Services
foreach (var d in GetContentForRelease(uow))
{
- d.ReleaseDate = null;
- var result = ((IContentServiceOperations) this).SaveAndPublish(d, d.WriterId);
- if (result.Success == false)
+ PublishResult result;
+ try
{
- if (result.Exception != null)
- {
- Logger.Error("Could not published the document (" + d.Id + ") based on it's scheduled release, status result: " + result.Result.StatusType, result.Exception);
- }
- else
- {
- Logger.Warn("Could not published the document (" + d.Id + ") based on it's scheduled release. Status result: " + result.Result.StatusType);
- }
+ d.ReleaseDate = null;
+ d.PublishValues(); // fixme variants?
+ result = SaveAndPublish(d, d.WriterId);
+ if (result.Success == false)
+ Logger.Error($"Failed to publish document id={d.Id}, reason={result.Result}.");
+ }
+ catch (Exception e)
+ {
+ Logger.Error($"Failed to publish document id={d.Id}, an exception was thrown.", e);
+ throw;
}
yield return result;
}
@@ -1240,11 +1124,13 @@ namespace Umbraco.Core.Services
try
{
d.ExpireDate = null;
- ((IContentServiceOperations) this).UnPublish(d, d.WriterId);
+ var result = Unpublish(d, d.WriterId);
+ if (result.Success == false)
+ Logger.Error($"Failed to unpublish document id={d.Id}, reason={result.Result}.");
}
- catch (Exception ee)
+ catch (Exception e)
{
- Logger.Error($"Error unpublishing node {d.Id}", ee);
+ Logger.Error($"Failed to unpublish document id={d.Id}, an exception was thrown.", e);
throw;
}
}
@@ -1253,14 +1139,8 @@ namespace Umbraco.Core.Services
}
}
- ///
- /// Publishes a object and all its children
- ///
- /// The to publish along with its children
- /// Optional Id of the User issueing the publishing
- ///
- /// The list of statuses for all published items
- IEnumerable> IContentServiceOperations.PublishWithChildren(IContent content, int userId, bool includeUnpublished)
+ ///
+ public IEnumerable PublishWithChildren(IContent content, int userId, bool includeUnpublished)
{
return PublishWithChildrenDo(content, userId, includeUnpublished);
}
@@ -1269,30 +1149,8 @@ namespace Umbraco.Core.Services
#region Delete
- ///
- /// Permanently deletes an object as well as all of its Children.
- ///
- ///
- /// This method will also delete associated media files, child content and possibly associated domains.
- ///
- /// Please note that this method will completely remove the Content from the database
- /// The to delete
- /// Optional Id of the User deleting the Content
- public void Delete(IContent content, int userId = 0)
- {
- ((IContentServiceOperations) this).Delete(content, userId);
- }
-
- ///
- /// Permanently deletes an object.
- ///
- ///
- /// This method will also delete associated media files, child content and possibly associated domains.
- ///
- /// Please note that this method will completely remove the Content from the database
- /// The to delete
- /// Optional Id of the User deleting the Content
- Attempt IContentServiceOperations.Delete(IContent content, int userId)
+ ///
+ public OperationResult Delete(IContent content, int userId)
{
var evtMsgs = EventMessagesFactory.Get();
@@ -1302,7 +1160,7 @@ namespace Umbraco.Core.Services
if (uow.Events.DispatchCancelable(Deleting, this, deleteEventArgs))
{
uow.Complete();
- return OperationStatus.Attempt.Cancel(evtMsgs);
+ return OperationResult.Cancel(evtMsgs);
}
uow.WriteLock(Constants.Locks.ContentTree);
@@ -1322,7 +1180,7 @@ namespace Umbraco.Core.Services
uow.Complete();
}
- return OperationStatus.Attempt.Succeed(evtMsgs);
+ return OperationResult.Succeed(evtMsgs);
}
private void DeleteLocked(IScopeUnitOfWork uow, IContentRepository repository, IContent content)
@@ -1412,7 +1270,7 @@ namespace Umbraco.Core.Services
if (deletePriorVersions)
{
- var content = GetByVersion(versionId);
+ var content = GetVersion(versionId);
// fixme nesting uow?
DeleteVersions(id, content.UpdateDate, userId);
}
@@ -1434,24 +1292,8 @@ namespace Umbraco.Core.Services
#region Move, RecycleBin
- ///
- /// Deletes an object by moving it to the Recycle Bin
- ///
- /// Move an item to the Recycle Bin will result in the item being unpublished
- /// The to delete
- /// Optional Id of the User deleting the Content
- public void MoveToRecycleBin(IContent content, int userId = 0)
- {
- ((IContentServiceOperations) this).MoveToRecycleBin(content, userId);
- }
-
- ///
- /// Deletes an object by moving it to the Recycle Bin
- ///
- /// Move an item to the Recycle Bin will result in the item being unpublished
- /// The to delete
- /// Optional Id of the User deleting the Content
- Attempt IContentServiceOperations.MoveToRecycleBin(IContent content, int userId)
+ ///
+ public OperationResult MoveToRecycleBin(IContent content, int userId)
{
var evtMsgs = EventMessagesFactory.Get();
var moves = new List>();
@@ -1467,7 +1309,7 @@ namespace Umbraco.Core.Services
if (uow.Events.DispatchCancelable(Trashing, this, moveEventArgs))
{
uow.Complete();
- return OperationStatus.Attempt.Cancel(evtMsgs); // causes rollback
+ return OperationResult.Cancel(evtMsgs); // causes rollback
}
// if it's published we may want to force-unpublish it - that would be backward-compatible... but...
@@ -1491,7 +1333,7 @@ namespace Umbraco.Core.Services
uow.Complete();
}
- return OperationStatus.Attempt.Succeed(evtMsgs);
+ return OperationResult.Succeed(evtMsgs);
}
///
@@ -1723,7 +1565,7 @@ namespace Umbraco.Core.Services
copy.WriterId = userId;
//get the current permissions, if there are any explicit ones they need to be copied
- var currentPermissions = GetPermissionsForEntity(content);
+ var currentPermissions = GetPermissions(content);
currentPermissions.RemoveWhere(p => p.IsDefaultPermissions);
// save and flush because we need the ID for the recursive Copying events
@@ -1835,7 +1677,7 @@ namespace Umbraco.Core.Services
var repository = uow.CreateRepository();
var currContent = repository.Get(id);
- var origContent = repository.GetByVersion(versionId);
+ var origContent = repository.GetVersion(versionId);
var rollbackEventArgs = new RollbackEventArgs(origContent);
if (uow.Events.DispatchCancelable(RollingBack, this, rollbackEventArgs))
@@ -1850,8 +1692,11 @@ namespace Umbraco.Core.Services
// pk > published pk = special, rollback to current 'edit' version
//
// in that last case, we want to copy the published values
+ // what-if there's no 'published' version for now?
+ // fixme WE DON'T WANT TO DO THIS HERE!
var copyPublished = ((Content) origContent).VersionPk > ((Content) origContent).PublishedVersionPk;
- ((Content) currContent).CopyAllValues(origContent, copyPublished);
+ //((Content) currContent).CopyAllValues(origContent, copyPublished);
+ ((Content) currContent).CopyAllValues(origContent);
currContent.WriterId = userId;
// builtin values
@@ -2014,13 +1859,13 @@ namespace Umbraco.Core.Services
/// then the list will only contain one status item, otherwise it will contain status items for it and all of it's descendants that
/// are to be published.
///
- private IEnumerable> PublishWithChildrenDo(IContent content, int userId = 0, bool includeUnpublished = false)
+ private IEnumerable PublishWithChildrenDo(IContent content, int userId = 0, bool includeUnpublished = false)
{
if (content == null) throw new ArgumentNullException(nameof(content));
var evtMsgs = EventMessagesFactory.Get();
var publishedItems = new List(); // this is for events
- Attempt[] attempts;
+ PublishResult[] attempts;
using (var uow = UowProvider.CreateUnitOfWork())
{
@@ -2042,11 +1887,11 @@ namespace Umbraco.Core.Services
var alreadyChecked = new[] { content };
attempts = StrategyPublishWithChildren(uow, contents, alreadyChecked, userId, evtMsgs, includeUnpublished).ToArray();
- foreach (var status in attempts.Where(x => x.Success).Select(x => x.Result))
+ foreach (var status in attempts.Where(x => x.Success))
{
// save them all, even those that are .Success because of (.StatusType == PublishStatusType.SuccessAlreadyPublished)
// so we bump the date etc
- var publishedItem = status.ContentItem;
+ var publishedItem = status.Content;
publishedItem.WriterId = userId;
repository.AddOrUpdate(publishedItem);
publishedItems.Add(publishedItem);
@@ -2062,51 +1907,6 @@ namespace Umbraco.Core.Services
return attempts;
}
-
- ///
- /// UnPublishes a single object
- ///
- /// The to publish
- /// Optional Id of the User issueing the publishing
- /// True if unpublishing succeeded, otherwise False
- private Attempt UnPublishDo(IContent content, int userId = 0)
- {
- var evtMsgs = EventMessagesFactory.Get();
-
- using (var uow = UowProvider.CreateUnitOfWork())
- {
- uow.WriteLock(Constants.Locks.ContentTree);
- var repository = uow.CreateRepository();
-
- var newest = GetById(content.Id); // ensure we have the newest version
- if (content.Version != newest.Version) // but use the original object if it's already the newest version
- content = newest;
- if (content.Published == false)
- {
- uow.Complete();
- return Attempt.Succeed(new UnPublishStatus(UnPublishedStatusType.SuccessAlreadyUnPublished, evtMsgs, content)); // already unpublished
- }
-
- // strategy
- // fixme should we still complete the uow? don't want to rollback here!
- var attempt = StrategyCanUnPublish(uow, content, userId, evtMsgs);
- if (attempt == false) return attempt; // causes rollback
- attempt = StrategyUnPublish(uow, content, true, userId, evtMsgs);
- if (attempt == false) return attempt; // causes rollback
-
- content.WriterId = userId;
- repository.AddOrUpdate(content);
-
- uow.Events.Dispatch(UnPublished, this, new PublishEventArgs(content, false, false), "UnPublished");
- uow.Events.Dispatch(TreeChanged, this, new TreeChange(content, TreeChangeTypes.RefreshBranch).ToEventArgs());
- Audit(uow, AuditType.UnPublish, "UnPublish performed by user", userId, content.Id);
-
- uow.Complete();
- }
-
- return Attempt.Succeed(new UnPublishStatus(UnPublishedStatusType.Success, evtMsgs, content));
- }
-
///
/// Saves and Publishes a single object
///
@@ -2114,10 +1914,10 @@ namespace Umbraco.Core.Services
/// Optional Id of the User issueing the publishing
/// Optional boolean indicating whether or not to raise save events.
/// True if publishing succeeded, otherwise False
- private Attempt SaveAndPublishDo(IContent content, int userId = 0, bool raiseEvents = true)
+ private PublishResult SaveAndPublishDo(IContent content, int userId = 0, bool raiseEvents = true)
{
var evtMsgs = EventMessagesFactory.Get();
- Attempt status;
+ PublishResult status;
using (var uow = UowProvider.CreateUnitOfWork())
{
@@ -2125,7 +1925,7 @@ namespace Umbraco.Core.Services
if (raiseEvents && uow.Events.DispatchCancelable(Saving, this, saveEventArgs, "Saving"))
{
uow.Complete();
- return Attempt.Fail(new PublishStatus(PublishStatusType.FailedCancelledByEvent, evtMsgs, content));
+ return new PublishResult(PublishResultType.FailedCancelledByEvent, evtMsgs, content);
}
var isNew = content.IsNewEntity();
@@ -2148,10 +1948,6 @@ namespace Umbraco.Core.Services
content.CreatorId = userId;
content.WriterId = userId;
- // fixme - this should be done OUTSIDE the service
- // but for the time being... it needs to be done
- ((Content) content).PublishAllValues();
-
repository.AddOrUpdate(content);
if (raiseEvents) // always
@@ -2177,7 +1973,7 @@ namespace Umbraco.Core.Services
// if was not published and now is... descendants that were 'published' (but
// had an unpublished ancestor) are 're-published' ie not explicitely published
// but back as 'published' nevertheless
- if (isNew == false && previouslyPublished == false &&HasChildren(content.Id))
+ if (isNew == false && previouslyPublished == false && HasChildren(content.Id))
{
var descendants = GetPublishedDescendantsLocked(uow, repository, content).ToArray();
uow.Events.Dispatch(Published, this, new PublishEventArgs(descendants, false, false), "Published");
@@ -2341,12 +2137,12 @@ namespace Umbraco.Core.Services
// prob. want to find nicer names?
- internal Attempt StrategyCanPublish(IScopeUnitOfWork uow, IContent content, int userId, bool checkPath, EventMessages evtMsgs)
+ internal PublishResult StrategyCanPublish(IScopeUnitOfWork uow, IContent content, int userId, bool checkPath, EventMessages evtMsgs)
{
if (uow.Events.DispatchCancelable(Publishing, this, new PublishEventArgs(content, evtMsgs)))
{
Logger.Info($"Content '{content.Name}' with Id '{content.Id}' will not be published, the event was cancelled.");
- return Attempt.Fail(new PublishStatus(PublishStatusType.FailedCancelledByEvent, evtMsgs, content));
+ return new PublishResult(PublishResultType.FailedCancelledByEvent, evtMsgs, content);
}
// check if the content is valid
@@ -2354,31 +2150,31 @@ namespace Umbraco.Core.Services
if (invalidProperties.Any())
{
Logger.Info($"Content '{content.Name}' with Id '{content.Id}' could not be published because of invalid properties.");
- return Attempt.Fail(new PublishStatus(PublishStatusType.FailedContentInvalid, evtMsgs, content)
+ return new PublishResult(PublishResultType.FailedContentInvalid, evtMsgs, content)
{
InvalidProperties = invalidProperties
- });
+ };
}
// check if the Content is Expired
if (content.Status == ContentStatus.Expired)
{
Logger.Info($"Content '{content.Name}' with Id '{content.Id}' has expired and could not be published.");
- return Attempt.Fail(new PublishStatus(PublishStatusType.FailedHasExpired, evtMsgs, content));
+ return new PublishResult(PublishResultType.FailedHasExpired, evtMsgs, content);
}
// check if the Content is Awaiting Release
if (content.Status == ContentStatus.AwaitingRelease)
{
Logger.Info($"Content '{content.Name}' with Id '{content.Id}' is awaiting release and could not be published.");
- return Attempt.Fail(new PublishStatus(PublishStatusType.FailedAwaitingRelease, evtMsgs, content));
+ return new PublishResult(PublishResultType.FailedAwaitingRelease, evtMsgs, content);
}
// check if the Content is Trashed
if (content.Status == ContentStatus.Trashed)
{
Logger.Info($"Content '{content.Name}' with Id '{content.Id}' is trashed and could not be published.");
- return Attempt.Fail(new PublishStatus(PublishStatusType.FailedIsTrashed, evtMsgs, content));
+ return new PublishResult(PublishResultType.FailedIsTrashed, evtMsgs, content);
}
// check if the content can be path-published
@@ -2394,21 +2190,21 @@ namespace Umbraco.Core.Services
if (pathIsOk == false)
{
Logger.Info($"Content '{content.Name}' with Id '{content.Id}' could not be published because its parent is not published.");
- return Attempt.Fail(new PublishStatus(PublishStatusType.FailedPathNotPublished, evtMsgs, content));
+ return new PublishResult(PublishResultType.FailedPathNotPublished, evtMsgs, content);
}
}
- return Attempt.Succeed(new PublishStatus(content, evtMsgs));
+ return new PublishResult(evtMsgs, content);
}
- internal Attempt StrategyPublish(IScopeUnitOfWork uow, IContent content, bool alreadyCheckedCanPublish, int userId, EventMessages evtMsgs)
+ internal PublishResult StrategyPublish(IScopeUnitOfWork uow, IContent content, bool alreadyCheckedCanPublish, int userId, EventMessages evtMsgs)
{
// note: when used at top-level, StrategyCanPublish with checkPath=true should have run already
// and alreadyCheckedCanPublish should be true, so not checking again. when used at nested level,
// there is no need to check the path again. so, checkPath=false in StrategyCanPublish below is ok
var attempt = alreadyCheckedCanPublish
- ? Attempt.Succeed(new PublishStatus(content, evtMsgs)) // already know we can
+ ? new PublishResult(evtMsgs, content) // already know we can
: StrategyCanPublish(uow, content, userId, /*checkPath:*/ false, evtMsgs); // else check
if (attempt.Success == false)
return attempt;
@@ -2448,9 +2244,9 @@ namespace Umbraco.Core.Services
/// - if includeUnpublished is true, process the underlying branch
/// - else, do not process the underlying branch
///
- internal IEnumerable> StrategyPublishWithChildren(IScopeUnitOfWork uow, IEnumerable contents, IEnumerable alreadyChecked, int userId, EventMessages evtMsgs, bool includeUnpublished = true)
+ internal IEnumerable StrategyPublishWithChildren(IScopeUnitOfWork uow, IEnumerable contents, IEnumerable alreadyChecked, int userId, EventMessages evtMsgs, bool includeUnpublished = true)
{
- var statuses = new List>();
+ var statuses = new List();
var alreadyCheckedA = (alreadyChecked ?? Enumerable.Empty()).ToArray();
// list of ids that we exclude because they could not be published
@@ -2475,7 +2271,7 @@ namespace Umbraco.Core.Services
if (content.Published && content.Level > topLevel) // topLevel we DO want to (re)publish
{
// newest is published already
- statuses.Add(Attempt.Succeed(new PublishStatus(PublishStatusType.SuccessAlreadyPublished, evtMsgs, content)));
+ statuses.Add(new PublishResult(PublishResultType.SuccessAlready, evtMsgs, content));
continue;
}
@@ -2501,25 +2297,25 @@ namespace Umbraco.Core.Services
return statuses;
}
- internal Attempt StrategyCanUnPublish(IScopeUnitOfWork uow, IContent content, int userId, EventMessages evtMsgs)
+ internal PublishResult StrategyCanUnPublish(IScopeUnitOfWork uow, IContent content, int userId, EventMessages evtMsgs)
{
// fire UnPublishing event
if (uow.Events.DispatchCancelable(UnPublishing, this, new PublishEventArgs(content, evtMsgs)))
{
Logger.Info($"Content '{content.Name}' with Id '{content.Id}' will not be unpublished, the event was cancelled.");
- return Attempt.Fail(new UnPublishStatus(UnPublishedStatusType.FailedCancelledByEvent, evtMsgs, content));
+ return new PublishResult(PublishResultType.FailedCancelledByEvent, evtMsgs, content);
}
- return Attempt.Succeed(new UnPublishStatus(content, evtMsgs));
+ return new PublishResult(evtMsgs, content);
}
- internal Attempt StrategyUnPublish(IScopeUnitOfWork uow, IContent content, bool alreadyCheckedCanUnPublish, int userId, EventMessages evtMsgs)
+ internal PublishResult StrategyUnPublish(IScopeUnitOfWork uow, IContent content, bool alreadyCheckedCanUnPublish, int userId, EventMessages evtMsgs)
{
// content should (is assumed to) be the newest version, which may not be published,
// don't know how to test this, so it's not verified
var attempt = alreadyCheckedCanUnPublish
- ? Attempt.Succeed(new UnPublishStatus(content, evtMsgs)) // already know we can
+ ? new PublishResult(evtMsgs, content) // already know we can
: StrategyCanUnPublish(uow, content, userId, evtMsgs);
if (attempt.Success == false)
return attempt;
@@ -2541,7 +2337,7 @@ namespace Umbraco.Core.Services
return attempt;
}
- internal IEnumerable> StrategyUnPublish(IScopeUnitOfWork uow, IEnumerable content, int userId, EventMessages evtMsgs)
+ internal IEnumerable StrategyUnPublish(IScopeUnitOfWork uow, IEnumerable content, int userId, EventMessages evtMsgs)
{
return content.Select(x => StrategyUnPublish(uow, x, false, userId, evtMsgs));
}
@@ -2560,7 +2356,7 @@ namespace Umbraco.Core.Services
///
/// Id of the
/// Optional Id of the user issueing the delete operation
- public void DeleteContentOfTypes(IEnumerable contentTypeIds, int userId = 0)
+ public void DeleteOfTypes(IEnumerable contentTypeIds, int userId = 0)
{
//TODO: This currently this is called from the ContentTypeService but that needs to change,
// if we are deleting a content type, we should just delete the data and do this operation slightly differently.
@@ -2637,12 +2433,11 @@ namespace Umbraco.Core.Services
/// This needs extra care and attention as its potentially a dangerous and extensive operation
/// Id of the
/// Optional id of the user deleting the media
- public void DeleteContentOfType(int contentTypeId, int userId = 0)
+ public void DeleteOfType(int contentTypeId, int userId = 0)
{
- DeleteContentOfTypes(new[] { contentTypeId }, userId);
+ DeleteOfTypes(new[] { contentTypeId }, userId);
}
-
private IContentType GetContentType(IScopeUnitOfWork uow, string contentTypeAlias)
{
if (string.IsNullOrWhiteSpace(contentTypeAlias)) throw new ArgumentNullOrEmptyException(nameof(contentTypeAlias));
@@ -2761,16 +2556,16 @@ namespace Umbraco.Core.Services
return content;
}
- public IEnumerable GetBlueprintsForContentTypes(params int[] documentTypeIds)
+ public IEnumerable GetBlueprintsForContentTypes(params int[] contentTypeId)
{
using (var uow = UowProvider.CreateUnitOfWork(readOnly: true))
{
var repository = uow.CreateRepository();
var query = Query();
- if (documentTypeIds.Length > 0)
+ if (contentTypeId.Length > 0)
{
- query.Where(x => documentTypeIds.Contains(x.ContentTypeId));
+ query.Where(x => contentTypeId.Contains(x.ContentTypeId));
}
return repository.GetByQuery(query).Select(x =>
{
diff --git a/src/Umbraco.Core/Services/ContentServiceExtensions.cs b/src/Umbraco.Core/Services/ContentServiceExtensions.cs
index 3d5bbfa4ed..2f6e043c88 100644
--- a/src/Umbraco.Core/Services/ContentServiceExtensions.cs
+++ b/src/Umbraco.Core/Services/ContentServiceExtensions.cs
@@ -40,7 +40,7 @@ namespace Umbraco.Core.Services
if (guidUdi == null)
throw new InvalidOperationException("The UDI provided isn't of type " + typeof(GuidUdi) + " which is required by content");
var parent = contentService.GetById(guidUdi.Guid);
- return contentService.CreateContent(name, parent, mediaTypeAlias, userId);
+ return contentService.Create(name, parent, mediaTypeAlias, userId);
}
///
@@ -50,7 +50,7 @@ namespace Umbraco.Core.Services
///
public static void RemoveContentPermissions(this IContentService contentService, int contentId)
{
- contentService.ReplaceContentPermissions(new EntityPermissionSet(contentId, new EntityPermissionCollection()));
+ contentService.SetPermissions(new EntityPermissionSet(contentId, new EntityPermissionCollection()));
}
///
diff --git a/src/Umbraco.Core/Services/ContentTypeService.cs b/src/Umbraco.Core/Services/ContentTypeService.cs
index f2631918f1..24bf580fd6 100644
--- a/src/Umbraco.Core/Services/ContentTypeService.cs
+++ b/src/Umbraco.Core/Services/ContentTypeService.cs
@@ -31,7 +31,7 @@ namespace Umbraco.Core.Services
protected override void DeleteItemsOfTypes(IEnumerable typeIds)
{
foreach (var typeId in typeIds)
- ContentService.DeleteContentOfType(typeId);
+ ContentService.DeleteOfType(typeId);
}
///
diff --git a/src/Umbraco.Core/Services/ContentTypeServiceBaseOfTRepositoryTItemTService.cs b/src/Umbraco.Core/Services/ContentTypeServiceBaseOfTRepositoryTItemTService.cs
index 38bc1d695b..2319dd9e32 100644
--- a/src/Umbraco.Core/Services/ContentTypeServiceBaseOfTRepositoryTItemTService.cs
+++ b/src/Umbraco.Core/Services/ContentTypeServiceBaseOfTRepositoryTItemTService.cs
@@ -640,7 +640,7 @@ namespace Umbraco.Core.Services
return clone;
}
- public Attempt> Copy(TItem copying, int containerId)
+ public Attempt> Copy(TItem copying, int containerId)
{
var evtMsgs = EventMessagesFactory.Get();
@@ -684,18 +684,18 @@ namespace Umbraco.Core.Services
}
catch (DataOperationException ex)
{
- return OperationStatus.Attempt.Fail(ex.Operation, evtMsgs); // causes rollback
+ return OperationResult.Attempt.Fail(ex.Operation, evtMsgs); // causes rollback
}
}
- return OperationStatus.Attempt.Succeed(MoveOperationStatusType.Success, evtMsgs, copy);
+ return OperationResult.Attempt.Succeed(MoveOperationStatusType.Success, evtMsgs, copy);
}
#endregion
#region Move
- public Attempt> Move(TItem moving, int containerId)
+ public Attempt> Move(TItem moving, int containerId)
{
var evtMsgs = EventMessagesFactory.Get();
@@ -707,7 +707,7 @@ namespace Umbraco.Core.Services
if (OnMovingCancelled(uow, moveEventArgs))
{
uow.Complete();
- return OperationStatus.Attempt.Fail(MoveOperationStatusType.FailedCancelledByEvent, evtMsgs);
+ return OperationResult.Attempt.Fail(MoveOperationStatusType.FailedCancelledByEvent, evtMsgs);
}
uow.WriteLock(WriteLockIds); // also for containers
@@ -730,7 +730,7 @@ namespace Umbraco.Core.Services
catch (DataOperationException ex)
{
uow.Complete();
- return OperationStatus.Attempt.Fail(ex.Operation, evtMsgs);
+ return OperationResult.Attempt.Fail(ex.Operation, evtMsgs);
}
// note: not raising any Changed event here because moving a content type under another container
@@ -742,7 +742,7 @@ namespace Umbraco.Core.Services
OnMoved(uow, moveEventArgs);
}
- return OperationStatus.Attempt.Succeed(MoveOperationStatusType.Success, evtMsgs);
+ return OperationResult.Attempt.Succeed(MoveOperationStatusType.Success, evtMsgs);
}
#endregion
@@ -753,7 +753,7 @@ namespace Umbraco.Core.Services
protected Guid ContainerObjectType => EntityContainer.GetContainerObjectType(ContainedObjectType);
- public Attempt> CreateContainer(int parentId, string name, int userId = 0)
+ public Attempt> CreateContainer(int parentId, string name, int userId = 0)
{
var evtMsgs = EventMessagesFactory.Get();
using (var uow = UowProvider.CreateUnitOfWork())
@@ -774,7 +774,7 @@ namespace Umbraco.Core.Services
if (OnSavingContainerCancelled(uow, saveEventArgs))
{
uow.Complete();
- return OperationStatus.Attempt.Cancel(evtMsgs, container);
+ return OperationResult.Attempt.Cancel(evtMsgs, container);
}
repo.AddOrUpdate(container);
@@ -784,17 +784,17 @@ namespace Umbraco.Core.Services
OnSavedContainer(uow, saveEventArgs);
//TODO: Audit trail ?
- return OperationStatus.Attempt.Succeed(evtMsgs, container);
+ return OperationResult.Attempt.Succeed(evtMsgs, container);
}
catch (Exception ex)
{
uow.Complete();
- return OperationStatus.Attempt.Fail(OperationStatusType.FailedCancelledByEvent, evtMsgs, ex);
+ return OperationResult.Attempt.Fail(OperationResultType.FailedCancelledByEvent, evtMsgs, ex);
}
}
}
- public Attempt SaveContainer(EntityContainer container, int userId = 0)
+ public Attempt SaveContainer(EntityContainer container, int userId = 0)
{
var evtMsgs = EventMessagesFactory.Get();
@@ -802,13 +802,13 @@ namespace Umbraco.Core.Services
if (container.ContainerObjectType != containerObjectType)
{
var ex = new InvalidOperationException("Not a container of the proper type.");
- return OperationStatus.Attempt.Fail(evtMsgs, ex);
+ return OperationResult.Attempt.Fail(evtMsgs, ex);
}
if (container.HasIdentity && container.IsPropertyDirty("ParentId"))
{
var ex = new InvalidOperationException("Cannot save a container with a modified parent, move the container instead.");
- return OperationStatus.Attempt.Fail(evtMsgs, ex);
+ return OperationResult.Attempt.Fail(evtMsgs, ex);
}
using (var uow = UowProvider.CreateUnitOfWork())
@@ -816,7 +816,7 @@ namespace Umbraco.Core.Services
if (OnSavingContainerCancelled(uow, new SaveEventArgs(container, evtMsgs)))
{
uow.Complete();
- return OperationStatus.Attempt.Cancel(evtMsgs);
+ return OperationResult.Attempt.Cancel(evtMsgs);
}
uow.WriteLock(WriteLockIds); // also for containers
@@ -830,7 +830,7 @@ namespace Umbraco.Core.Services
//TODO: Audit trail ?
- return OperationStatus.Attempt.Succeed(evtMsgs);
+ return OperationResult.Attempt.Succeed(evtMsgs);
}
public EntityContainer GetContainer(int containerId)
@@ -891,7 +891,7 @@ namespace Umbraco.Core.Services
}
}
- public Attempt DeleteContainer(int containerId, int userId = 0)
+ public Attempt DeleteContainer(int containerId, int userId = 0)
{
var evtMsgs = EventMessagesFactory.Get();
using (var uow = UowProvider.CreateUnitOfWork())
@@ -900,7 +900,7 @@ namespace Umbraco.Core.Services
var repo = uow.CreateContainerRepository(ContainerObjectType);
var container = repo.Get(containerId);
- if (container == null) return OperationStatus.Attempt.NoOperation(evtMsgs);
+ if (container == null) return OperationResult.Attempt.NoOperation(evtMsgs);
var erepo = uow.CreateRepository();
var entity = erepo.Get(container.Id);
@@ -908,14 +908,14 @@ namespace Umbraco.Core.Services
{
// fixme - here and everywhere, original v8 would not Complete, thus causing rollback = ?
uow.Complete();
- return Attempt.Fail(new OperationStatus(OperationStatusType.FailedCannot, evtMsgs));
+ return Attempt.Fail(new OperationResult(OperationResultType.FailedCannot, evtMsgs));
}
var deleteEventArgs = new DeleteEventArgs(container, evtMsgs);
if (OnDeletingContainerCancelled(uow, deleteEventArgs))
{
uow.Complete();
- return Attempt.Fail(new OperationStatus(OperationStatusType.FailedCancelledByEvent, evtMsgs));
+ return Attempt.Fail(new OperationResult(OperationResultType.FailedCancelledByEvent, evtMsgs));
}
repo.Delete(container);
@@ -924,12 +924,12 @@ namespace Umbraco.Core.Services
deleteEventArgs.CanCancel = false;
OnDeletedContainer(uow, deleteEventArgs);
- return OperationStatus.Attempt.Succeed(evtMsgs);
+ return OperationResult.Attempt.Succeed(evtMsgs);
//TODO: Audit trail ?
}
}
- public Attempt> RenameContainer(int id, string name, int userId = 0)
+ public Attempt> RenameContainer(int id, string name, int userId = 0)
{
var evtMsgs = EventMessagesFactory.Get();
using (var uow = UowProvider.CreateUnitOfWork())
@@ -951,11 +951,11 @@ namespace Umbraco.Core.Services
OnRenamedContainer(uow, new SaveEventArgs(container, evtMsgs));
- return OperationStatus.Attempt.Succeed(OperationStatusType.Success, evtMsgs, container);
+ return OperationResult.Attempt.Succeed(OperationResultType.Success, evtMsgs, container);
}
catch (Exception ex)
{
- return OperationStatus.Attempt.Fail(evtMsgs, ex);
+ return OperationResult.Attempt.Fail(evtMsgs, ex);
}
}
}
diff --git a/src/Umbraco.Core/Services/DataTypeService.cs b/src/Umbraco.Core/Services/DataTypeService.cs
index dd18848d8a..6ed5c477c4 100644
--- a/src/Umbraco.Core/Services/DataTypeService.cs
+++ b/src/Umbraco.Core/Services/DataTypeService.cs
@@ -23,7 +23,7 @@ namespace Umbraco.Core.Services
#region Containers
- public Attempt> CreateContainer(int parentId, string name, int userId = 0)
+ public Attempt> CreateContainer(int parentId, string name, int userId = 0)
{
var evtMsgs = EventMessagesFactory.Get();
using (var uow = UowProvider.CreateUnitOfWork())
@@ -41,7 +41,7 @@ namespace Umbraco.Core.Services
if (uow.Events.DispatchCancelable(SavingContainer, this, new SaveEventArgs(container, evtMsgs)))
{
uow.Complete();
- return OperationStatus.Attempt.Cancel(evtMsgs, container);
+ return OperationResult.Attempt.Cancel(evtMsgs, container);
}
repo.AddOrUpdate(container);
@@ -50,11 +50,11 @@ namespace Umbraco.Core.Services
uow.Events.Dispatch(SavedContainer, this, new SaveEventArgs(container, evtMsgs));
//TODO: Audit trail ?
- return OperationStatus.Attempt.Succeed(evtMsgs, container);
+ return OperationResult.Attempt.Succeed(evtMsgs, container);
}
catch (Exception ex)
{
- return OperationStatus.Attempt.Fail(evtMsgs, ex);
+ return OperationResult.Attempt.Fail(evtMsgs, ex);
}
}
}
@@ -109,20 +109,20 @@ namespace Umbraco.Core.Services
}
}
- public Attempt SaveContainer(EntityContainer container, int userId = 0)
+ public Attempt SaveContainer(EntityContainer container, int userId = 0)
{
var evtMsgs = EventMessagesFactory.Get();
if (container.ContainedObjectType != Constants.ObjectTypes.DataType)
{
var ex = new InvalidOperationException("Not a " + Constants.ObjectTypes.DataType + " container.");
- return OperationStatus.Attempt.Fail(evtMsgs, ex);
+ return OperationResult.Attempt.Fail(evtMsgs, ex);
}
if (container.HasIdentity && container.IsPropertyDirty("ParentId"))
{
var ex = new InvalidOperationException("Cannot save a container with a modified parent, move the container instead.");
- return OperationStatus.Attempt.Fail(evtMsgs, ex);
+ return OperationResult.Attempt.Fail(evtMsgs, ex);
}
using (var uow = UowProvider.CreateUnitOfWork())
@@ -130,7 +130,7 @@ namespace Umbraco.Core.Services
if (uow.Events.DispatchCancelable(SavingContainer, this, new SaveEventArgs(container, evtMsgs)))
{
uow.Complete();
- return OperationStatus.Attempt.Cancel(evtMsgs);
+ return OperationResult.Attempt.Cancel(evtMsgs);
}
var repo = uow.CreateRepository();
@@ -141,27 +141,27 @@ namespace Umbraco.Core.Services
}
//TODO: Audit trail ?
- return OperationStatus.Attempt.Succeed(evtMsgs);
+ return OperationResult.Attempt.Succeed(evtMsgs);
}
- public Attempt DeleteContainer(int containerId, int userId = 0)
+ public Attempt DeleteContainer(int containerId, int userId = 0)
{
var evtMsgs = EventMessagesFactory.Get();
using (var uow = UowProvider.CreateUnitOfWork())
{
var repo = uow.CreateRepository();
var container = repo.Get(containerId);
- if (container == null) return OperationStatus.Attempt.NoOperation(evtMsgs);
+ if (container == null) return OperationResult.Attempt.NoOperation(evtMsgs);
var erepo = uow.CreateRepository();
var entity = erepo.Get(container.Id);
if (entity.HasChildren()) // because container.HasChildren() does not work?
- return Attempt.Fail(new OperationStatus(OperationStatusType.FailedCannot, evtMsgs)); // causes rollback
+ return Attempt.Fail(new OperationResult(OperationResultType.FailedCannot, evtMsgs)); // causes rollback
if (uow.Events.DispatchCancelable(DeletingContainer, this, new DeleteEventArgs(container, evtMsgs)))
{
uow.Complete();
- return Attempt.Fail(new OperationStatus(OperationStatusType.FailedCancelledByEvent, evtMsgs));
+ return Attempt.Fail(new OperationResult(OperationResultType.FailedCancelledByEvent, evtMsgs));
}
repo.Delete(container);
@@ -171,10 +171,10 @@ namespace Umbraco.Core.Services
}
//TODO: Audit trail ?
- return OperationStatus.Attempt.Succeed(evtMsgs);
+ return OperationResult.Attempt.Succeed(evtMsgs);
}
- public Attempt> RenameContainer(int id, string name, int userId = 0)
+ public Attempt> RenameContainer(int id, string name, int userId = 0)
{
var evtMsgs = EventMessagesFactory.Get();
using (var uow = UowProvider.CreateUnitOfWork())
@@ -197,11 +197,11 @@ namespace Umbraco.Core.Services
// fixme - triggering SavedContainer with a different name?!
uow.Events.Dispatch(SavedContainer, this, new SaveEventArgs(container, evtMsgs), "RenamedContainer");
- return OperationStatus.Attempt.Succeed(OperationStatusType.Success, evtMsgs, container);
+ return OperationResult.Attempt.Succeed(OperationResultType.Success, evtMsgs, container);
}
catch (Exception ex)
{
- return OperationStatus.Attempt.Fail(evtMsgs, ex);
+ return OperationResult.Attempt.Fail(evtMsgs, ex);
}
}
}
@@ -326,7 +326,7 @@ namespace Umbraco.Core.Services
}
}
- public Attempt> Move(IDataTypeDefinition toMove, int parentId)
+ public Attempt> Move(IDataTypeDefinition toMove, int parentId)
{
var evtMsgs = EventMessagesFactory.Get();
var moveInfo = new List>();
@@ -338,7 +338,7 @@ namespace Umbraco.Core.Services
if (uow.Events.DispatchCancelable(Moving, this, moveEventArgs))
{
uow.Complete();
- return OperationStatus.Attempt.Fail(MoveOperationStatusType.FailedCancelledByEvent, evtMsgs);
+ return OperationResult.Attempt.Fail(MoveOperationStatusType.FailedCancelledByEvent, evtMsgs);
}
var containerRepository = uow.CreateRepository();
@@ -363,11 +363,11 @@ namespace Umbraco.Core.Services
catch (DataOperationException ex)
{
uow.Complete(); // fixme what are we doing here exactly?
- return OperationStatus.Attempt.Fail(ex.Operation, evtMsgs);
+ return OperationResult.Attempt.Fail(ex.Operation, evtMsgs);
}
}
- return OperationStatus.Attempt.Succeed(MoveOperationStatusType.Success, evtMsgs);
+ return OperationResult.Attempt.Succeed(MoveOperationStatusType.Success, evtMsgs);
}
///
diff --git a/src/Umbraco.Core/Services/DomainService.cs b/src/Umbraco.Core/Services/DomainService.cs
index b241dbad60..57869e3772 100644
--- a/src/Umbraco.Core/Services/DomainService.cs
+++ b/src/Umbraco.Core/Services/DomainService.cs
@@ -27,7 +27,7 @@ namespace Umbraco.Core.Services
}
}
- public Attempt Delete(IDomain domain)
+ public Attempt Delete(IDomain domain)
{
var evtMsgs = EventMessagesFactory.Get();
@@ -37,7 +37,7 @@ namespace Umbraco.Core.Services
if (uow.Events.DispatchCancelable(Deleting, this, deleteEventArgs))
{
uow.Complete();
- return OperationStatus.Attempt.Cancel(evtMsgs);
+ return OperationResult.Attempt.Cancel(evtMsgs);
}
var repository = uow.CreateRepository();
@@ -48,7 +48,7 @@ namespace Umbraco.Core.Services
uow.Events.Dispatch(Deleted, this, deleteEventArgs);
}
- return OperationStatus.Attempt.Succeed(evtMsgs);
+ return OperationResult.Attempt.Succeed(evtMsgs);
}
public IDomain GetByName(string name)
@@ -87,7 +87,7 @@ namespace Umbraco.Core.Services
}
}
- public Attempt Save(IDomain domainEntity)
+ public Attempt Save(IDomain domainEntity)
{
var evtMsgs = EventMessagesFactory.Get();
@@ -97,7 +97,7 @@ namespace Umbraco.Core.Services
if (uow.Events.DispatchCancelable(Saving, this, saveEventArgs))
{
uow.Complete();
- return OperationStatus.Attempt.Cancel(evtMsgs);
+ return OperationResult.Attempt.Cancel(evtMsgs);
}
var repository = uow.CreateRepository();
@@ -107,7 +107,7 @@ namespace Umbraco.Core.Services
uow.Events.Dispatch(Saved, this, saveEventArgs);
}
- return OperationStatus.Attempt.Succeed(evtMsgs);
+ return OperationResult.Attempt.Succeed(evtMsgs);
}
#region Event Handlers
diff --git a/src/Umbraco.Core/Services/FileService.cs b/src/Umbraco.Core/Services/FileService.cs
index ec29b7ca38..76aca5f5e7 100644
--- a/src/Umbraco.Core/Services/FileService.cs
+++ b/src/Umbraco.Core/Services/FileService.cs
@@ -321,7 +321,7 @@ namespace Umbraco.Core.Services
///
/// The template created
///
- public Attempt> CreateTemplateForContentType(string contentTypeAlias, string contentTypeName, int userId = 0)
+ public Attempt> CreateTemplateForContentType(string contentTypeAlias, string contentTypeName, int userId = 0)
{
var template = new Template(contentTypeName,
//NOTE: We are NOT passing in the content type alias here, we want to use it's name since we don't
@@ -348,7 +348,7 @@ namespace Umbraco.Core.Services
if (uow.Events.DispatchCancelable(SavingTemplate, this, saveEventArgs))
{
uow.Complete();
- return OperationStatus.Attempt.Fail(OperationStatusType.FailedCancelledByEvent, evtMsgs, template);
+ return OperationResult.Attempt.Fail(OperationResultType.FailedCancelledByEvent, evtMsgs, template);
}
var repository = uow.CreateRepository();
@@ -360,7 +360,7 @@ namespace Umbraco.Core.Services
uow.Complete();
}
- return OperationStatus.Attempt.Succeed(OperationStatusType.Success, evtMsgs, template);
+ return OperationResult.Attempt.Succeed(OperationResultType.Success, evtMsgs, template);
}
public ITemplate CreateTemplateWithIdentity(string name, string content, ITemplate masterTemplate = null, int userId = 0)
diff --git a/src/Umbraco.Core/Services/IContentService.cs b/src/Umbraco.Core/Services/IContentService.cs
index dd1c137969..46e12784b2 100644
--- a/src/Umbraco.Core/Services/IContentService.cs
+++ b/src/Umbraco.Core/Services/IContentService.cs
@@ -1,8 +1,6 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
-using System.Xml;
-using System.Xml.Linq;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Membership;
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
@@ -10,605 +8,423 @@ using Umbraco.Core.Persistence.Querying;
namespace Umbraco.Core.Services
{
- ///
- /// A temporary interface until we are in v8, this is used to return a different result for the same method and this interface gets implemented
- /// explicitly. These methods will replace the normal ones in IContentService in v8 and this will be removed.
- ///
- public interface IContentServiceOperations
- {
- //TODO: Remove this class in v8
-
- //TODO: There's probably more that needs to be added like the EmptyRecycleBin, etc...
-
- ///
- /// Saves a single object
- ///
- /// The to save
- /// Optional Id of the User saving the Content
- /// Optional boolean indicating whether or not to raise events.
- Attempt Save(IContent content, int userId = 0, bool raiseEvents = true);
-
- ///
- /// Saves a collection of objects.
- ///
- /// Collection of to save
- /// Optional Id of the User saving the Content
- /// Optional boolean indicating whether or not to raise events.
- Attempt Save(IEnumerable contents, int userId = 0, bool raiseEvents = true);
-
- ///
- /// Permanently deletes an object.
- ///
- ///
- /// This method will also delete associated media files, child content and possibly associated domains.
- ///
- /// Please note that this method will completely remove the Content from the database
- /// The to delete
- /// Optional Id of the User deleting the Content
- Attempt Delete(IContent content, int userId = 0);
-
- ///
- /// Publishes a single object
- ///
- /// The to publish
- /// Optional Id of the User issueing the publishing
- /// The published status attempt
- Attempt Publish(IContent content, int userId = 0);
-
- ///
- /// Publishes a object and all its children
- ///
- /// The to publish along with its children
- /// Optional Id of the User issueing the publishing
- ///
- /// The list of statuses for all published items
- IEnumerable> PublishWithChildren(IContent content, int userId = 0, bool includeUnpublished = false);
-
- ///
- /// Used to perform scheduled publishing/unpublishing
- ///
- IEnumerable> PerformScheduledPublish();
-
- ///
- /// Saves and Publishes a single object
- ///
- /// The to save and publish
- /// Optional Id of the User issueing the publishing
- /// Optional boolean indicating whether or not to raise save events.
- /// True if publishing succeeded, otherwise False
- Attempt SaveAndPublish(IContent content, int userId = 0, bool raiseEvents = true);
-
- ///
- /// Deletes an object by moving it to the Recycle Bin
- ///
- /// Move an item to the Recycle Bin will result in the item being unpublished
- /// The to delete
- /// Optional Id of the User deleting the Content
- Attempt MoveToRecycleBin(IContent content, int userId = 0);
-
- ///
- /// UnPublishes a single object
- ///
- /// The to publish
- /// Optional Id of the User issueing the publishing
- /// True if unpublishing succeeded, otherwise False
- Attempt UnPublish(IContent content, int userId = 0);
- }
-
///
/// Defines the ContentService, which is an easy access to operations involving
///
public interface IContentService : IContentServiceBase
{
- IEnumerable GetBlueprintsForContentTypes(params int[] documentTypeIds);
+ #region Blueprints
+
+ ///
+ /// Gets a blueprint.
+ ///
IContent GetBlueprintById(int id);
+
+ ///
+ /// Gets a blueprint.
+ ///
IContent GetBlueprintById(Guid id);
+
+ ///
+ /// Gets blueprints for a content type.
+ ///
+ IEnumerable GetBlueprintsForContentTypes(params int[] documentTypeId);
+
+ ///
+ /// Saves a blueprint.
+ ///
void SaveBlueprint(IContent content, int userId = 0);
+
+ ///
+ /// Deletes a blueprint.
+ ///
void DeleteBlueprint(IContent content, int userId = 0);
+
+ ///
+ /// Creates a new content item from a blueprint.
+ ///
IContent CreateContentFromBlueprint(IContent blueprint, string name, int userId = 0);
- int CountPublished(string contentTypeAlias = null);
- int Count(string contentTypeAlias = null);
- int CountChildren(int parentId, string contentTypeAlias = null);
- int CountDescendants(int parentId, string contentTypeAlias = null);
+ #endregion
+
+ #region Get, Count Documents
///
- /// Used to bulk update the permissions set for a content item. This will replace all permissions
- /// assigned to an entity with a list of user group id & permission pairs.
+ /// Gets a document.
///
- ///
- void ReplaceContentPermissions(EntityPermissionSet permissionSet);
-
- ///
- /// Assigns a single permission to the current content item for the specified user group ids
- ///
- ///
- ///
- ///
- void AssignContentPermission(IContent entity, char permission, IEnumerable groupIds);
-
- ///
- /// Returns implicit/inherited permissions assigned to the content item for all user groups
- ///
- ///
- ///
- EntityPermissionCollection GetPermissionsForEntity(IContent content);
-
- bool SendToPublication(IContent content, int userId = 0);
-
- IEnumerable GetByIds(IEnumerable ids);
- IEnumerable GetByIds(IEnumerable ids);
-
- ///
- /// Creates an object using the alias of the
- /// that this Content should based on.
- ///
- ///
- /// Note that using this method will simply return a new IContent without any identity
- /// as it has not yet been persisted. It is intended as a shortcut to creating new content objects
- /// that does not invoke a save operation against the database.
- ///
- /// Name of the Content object
- /// Id of Parent for the new Content
- /// Alias of the
- /// Optional id of the user creating the content
- ///
- IContent CreateContent(string name, Guid parentId, string contentTypeAlias, int userId = 0);
-
- ///
- /// Creates an object using the alias of the
- /// that this Content should based on.
- ///
- ///
- /// Note that using this method will simply return a new IContent without any identity
- /// as it has not yet been persisted. It is intended as a shortcut to creating new content objects
- /// that does not invoke a save operation against the database.
- ///
- /// Name of the Content object
- /// Id of Parent for the new Content
- /// Alias of the
- /// Optional id of the user creating the content
- ///
- IContent CreateContent(string name, int parentId, string contentTypeAlias, int userId = 0);
-
- ///
- /// Creates an object using the alias of the
- /// that this Content should based on.
- ///
- ///
- /// Note that using this method will simply return a new IContent without any identity
- /// as it has not yet been persisted. It is intended as a shortcut to creating new content objects
- /// that does not invoke a save operation against the database.
- ///
- /// Name of the Content object
- /// Parent object for the new Content
- /// Alias of the
- /// Optional id of the user creating the content
- ///
- IContent CreateContent(string name, IContent parent, string contentTypeAlias, int userId = 0);
-
- ///
- /// Gets an object by Id
- ///
- /// Id of the Content to retrieve
- ///
IContent GetById(int id);
///
- /// Gets an object by its 'UniqueId'
+ /// Gets a document.
///
- /// Guid key of the Content to retrieve
- ///
IContent GetById(Guid key);
///
- /// Gets a collection of objects by the Id of the
+ /// Gets documents.
///
- /// Id of the
- /// An Enumerable list of objects
- IEnumerable GetContentOfContentType(int id);
+ IEnumerable GetByIds(IEnumerable ids);
///
- /// Gets a collection of objects by Level
+ /// Gets documents.
+ ///
+ IEnumerable GetByIds(IEnumerable ids);
+
+ ///
+ /// Gets documents of a given document type.
+ ///
+ IEnumerable GetByType(int documentTypeId);
+
+ ///
+ /// Gets documents at a given level.
///
- /// The level to retrieve Content from
- /// An Enumerable list of objects
IEnumerable GetByLevel(int level);
///
- /// Gets a collection of objects by Parent Id
+ /// Gets child documents of a given parent.
///
- /// Id of the Parent to retrieve Children from
- /// An Enumerable list of objects
- IEnumerable GetChildren(int id);
+ IEnumerable GetChildren(int parentId);
///
- /// Gets a collection of objects by Parent Id
+ /// Gets child documents of a document, (partially) matching a name.
///
- /// Id of the Parent to retrieve Children from
- /// Page number
- /// Page size
- /// Total records query would return without paging
- /// Field to order by
- /// Direction to order by
- /// Search text filter
- /// An Enumerable list of objects
+ IEnumerable GetChildren(int parentId, string name);
+
+ ///
+ /// Gets the parent of a document.
+ ///
+ IContent GetParent(int id);
+
+ ///
+ /// Gets the parent of a document.
+ ///
+ IContent GetParent(IContent content);
+
+ ///
+ /// Gets ancestor documents of a document.
+ ///
+ IEnumerable GetAncestors(int id);
+
+ ///
+ /// Gets ancestor documents of a document.
+ ///
+ IEnumerable GetAncestors(IContent content);
+
+ ///
+ /// Gets descendant documents of a document.
+ ///
+ IEnumerable GetDescendants(int id);
+
+ ///
+ /// Gets descendant documents of a document.
+ ///
+ IEnumerable GetDescendants(IContent content);
+
+ ///
+ /// Gets all versions of a document.
+ ///
+ /// Versions are ordered with current first, then most recent first.
+ IEnumerable GetVersions(int id);
+
+ ///
+ /// Gets top versions of a document.
+ ///
+ /// Versions are ordered with current first, then most recent first.
+ IEnumerable GetVersionIds(int id, int topRows);
+
+ ///
+ /// Gets a version of a document.
+ ///
+ IContent GetVersion(Guid versionId);
+
+ ///
+ /// Gets root-level documents.
+ ///
+ IEnumerable GetRootContent();
+
+ ///
+ /// Gets documents with an expiration date greater then today.
+ ///
+ IEnumerable GetContentForExpiration();
+
+ ///
+ /// Gets documents with a release date greater then today.
+ ///
+ IEnumerable GetContentForRelease();
+
+ ///
+ /// Gets documents in the recycle bin.
+ ///
+ IEnumerable GetContentInRecycleBin();
+
+ ///
+ /// Gets child documents of a given parent.
+ ///
+ /// The parent identifier.
+ /// The page number.
+ /// The page size.
+ /// Total number of documents.
+ /// A field to order by.
+ /// The ordering direction.
+ /// Search text filter.
IEnumerable GetPagedChildren(int id, long pageIndex, int pageSize, out long totalRecords,
string orderBy = "SortOrder", Direction orderDirection = Direction.Ascending, string filter = "");
///
- /// Gets a collection of objects by Parent Id
+ /// Gets child documents of a given parent.
///
- /// Id of the Parent to retrieve Children from
- /// Page number
- /// Page size
- /// Total records query would return without paging
- /// Field to order by
- /// Direction to order by
- /// Flag to indicate when ordering by system field
- /// Search text filter
- /// An Enumerable list of objects
+ /// The parent identifier.
+ /// The page number.
+ /// The page size.
+ /// Total number of documents.
+ /// A field to order by.
+ /// The ordering direction.
+ /// A flag indicating whether the ordering field is a system field.
+ /// Query filter.
IEnumerable GetPagedChildren(int id, long pageIndex, int pageSize, out long totalRecords,
string orderBy, Direction orderDirection, bool orderBySystemField, IQuery filter);
///
- /// Gets a collection of objects by Parent Id
+ /// Gets descendant documents of a given parent.
///
- /// Id of the Parent to retrieve Descendants from
- /// Page number
- /// Page size
- /// Total records query would return without paging
- /// Field to order by
- /// Direction to order by
- /// Search text filter
- /// An Enumerable list of objects
+ /// The parent identifier.
+ /// The page number.
+ /// The page size.
+ /// Total number of documents.
+ /// A field to order by.
+ /// The ordering direction.
+ /// Search text filter.
IEnumerable GetPagedDescendants(int id, long pageIndex, int pageSize, out long totalRecords,
string orderBy = "path", Direction orderDirection = Direction.Ascending, string filter = "");
///
- /// Gets a collection of objects by Parent Id
+ /// Gets descendant documents of a given parent.
///
- /// Id of the Parent to retrieve Descendants from
- /// Page number
- /// Page size
- /// Total records query would return without paging
- /// Field to order by
- /// Direction to order by
- /// Flag to indicate when ordering by system field
- ///
- /// An Enumerable list of objects
+ /// The parent identifier.
+ /// The page number.
+ /// The page size.
+ /// Total number of documents.
+ /// A field to order by.
+ /// The ordering direction.
+ /// A flag indicating whether the ordering field is a system field.
+ /// Query filter.
IEnumerable GetPagedDescendants(int id, long pageIndex, int pageSize, out long totalRecords,
string orderBy, Direction orderDirection, bool orderBySystemField, IQuery filter);
///
- /// Gets a collection of an objects versions by its Id
+ /// Counts documents of a given document type.
///
- ///
- /// An Enumerable list of objects
- IEnumerable GetVersions(int id);
+ int Count(string documentTypeAlias = null);
///
- /// Gets a list of all version Ids for the given content, item ordered so latest is first.
+ /// Counts published documents of a given document type.
///
- ///
- /// The maximum number of rows to return
- ///
- IEnumerable GetVersionIds(int id, int maxRows);
+ int CountPublished(string documentTypeAlias = null);
///
- /// Gets a collection of objects, which reside at the first level / root
+ /// Counts child documents of a given parent, of a given document type.
///
- /// An Enumerable list of objects
- IEnumerable GetRootContent();
+ int CountChildren(int parentId, string documentTypeAlias = null);
///
- /// Gets a collection of objects, which has an expiration date greater then today
+ /// Counts descendant documents of a given parent, of a given document type.
///
- /// An Enumerable list of objects
- IEnumerable GetContentForExpiration();
+ int CountDescendants(int parentId, string documentTypeAlias = null);
///
- /// Gets a collection of objects, which has a release date greater then today
+ /// Gets a value indicating whether a document has children.
///
- /// An Enumerable list of objects
- IEnumerable GetContentForRelease();
+ bool HasChildren(int id);
+
+ #endregion
+
+ #region Save, Delete Document
///
- /// Gets a collection of an objects, which resides in the Recycle Bin
+ /// Saves a document.
///
- /// An Enumerable list of objects
- IEnumerable GetContentInRecycleBin();
+ OperationResult Save(IContent content, int userId = 0, bool raiseEvents = true);
///
- /// Saves a single object
+ /// Saves documents.
///
- /// The to save
- /// Optional Id of the User saving the Content
- /// Optional boolean indicating whether or not to raise events.
- void Save(IContent content, int userId = 0, bool raiseEvents = true);
+ // fixme why only 1 result not 1 per content?!
+ OperationResult Save(IEnumerable contents, int userId = 0, bool raiseEvents = true);
///
- /// Saves a collection of objects.
+ /// Deletes a document.
///
- /// Collection of to save
- /// Optional Id of the User saving the Content
- /// Optional boolean indicating whether or not to raise events.
- void Save(IEnumerable contents, int userId = 0, bool raiseEvents = true);
+ ///
+ /// This method will also delete associated media files, child content and possibly associated domains.
+ /// This method entirely clears the content from the database.
+ ///
+ OperationResult Delete(IContent content, int userId = 0);
///
- /// Deletes all content of specified type. All children of deleted content is moved to Recycle Bin.
+ /// Deletes all documents of a given document type.
///
- /// This needs extra care and attention as its potentially a dangerous and extensive operation
- /// Id of the
- /// Optional Id of the user issueing the delete operation
- void DeleteContentOfType(int contentTypeId, int userId = 0);
+ ///
+ /// All non-deleted descendants of the deleted documents are moved to the recycle bin.
+ /// This operation is potentially dangerous and expensive.
+ ///
+ void DeleteOfType(int documentTypeId, int userId = 0);
///
- /// Deletes all content of the specified types. All Descendants of deleted content that is not of these types is moved to Recycle Bin.
+ /// Deletes all documents of given document types.
///
- /// This needs extra care and attention as its potentially a dangerous and extensive operation
- /// Ids of the s
- /// Optional Id of the user issueing the delete operation
- void DeleteContentOfTypes(IEnumerable contentTypeIds, int userId = 0);
+ ///
+ /// All non-deleted descendants of the deleted documents are moved to the recycle bin.
+ /// This operation is potentially dangerous and expensive.
+ ///
+ void DeleteOfTypes(IEnumerable contentTypeIds, int userId = 0);
///
- /// Permanently deletes versions from an object prior to a specific date.
+ /// Deletes versions of a document prior to a given date.
///
- /// Id of the object to delete versions from
- /// Latest version date
- /// Optional Id of the User deleting versions of a Content object
- void DeleteVersions(int id, DateTime versionDate, int userId = 0);
+ void DeleteVersions(int id, DateTime date, int userId = 0);
///
- /// Permanently deletes a specific version from an object.
+ /// Deletes a version of a document.
///
- /// Id of the object to delete a version from
- /// Id of the version to delete
- /// Boolean indicating whether to delete versions prior to the versionId
- /// Optional Id of the User deleting versions of a Content object
void DeleteVersion(int id, Guid versionId, bool deletePriorVersions, int userId = 0);
- ///
- /// Deletes an object by moving it to the Recycle Bin
- ///
- /// Move an item to the Recycle Bin will result in the item being unpublished
- /// The to delete
- /// Optional Id of the User deleting the Content
- void MoveToRecycleBin(IContent content, int userId = 0);
+ #endregion
+
+ #region Move, Copy, Sort Document
///
- /// Moves an object to a new location
+ /// Moves a document under a new parent.
///
- /// The to move
- /// Id of the Content's new Parent
- /// Optional Id of the User moving the Content
void Move(IContent content, int parentId, int userId = 0);
///
- /// Empties the Recycle Bin by deleting all that resides in the bin
+ /// Copies a document.
+ ///
+ ///
+ /// Recursively copies all children.
+ ///
+ IContent Copy(IContent content, int parentId, bool relateToOriginal, int userId = 0);
+
+ ///
+ /// Copies a document.
+ ///
+ ///
+ /// Optionaly recursively copies all children.
+ ///
+ IContent Copy(IContent content, int parentId, bool relateToOriginal, bool recursive, int userId = 0);
+
+ ///
+ /// Moves a document to the recycle bin.
+ ///
+ OperationResult MoveToRecycleBin(IContent content, int userId = 0);
+
+ ///
+ /// Empties the recycle bin.
///
void EmptyRecycleBin();
///
- /// Rollback an object to a previous version.
- /// This will create a new version, which is a copy of all the old data.
+ /// Sorts documents.
///
- /// Id of the being rolled back
- /// Id of the version to rollback to
- /// Optional Id of the User issueing the rollback of the Content
- /// The newly created object
- IContent Rollback(int id, Guid versionId, int userId = 0);
-
- ///
- /// Gets a collection of objects by its name or partial name
- ///
- /// Id of the Parent to retrieve Children from
- /// Full or partial name of the children
- /// An Enumerable list of objects
- IEnumerable GetChildrenByName(int parentId, string name);
-
- ///
- /// Gets a collection of objects by Parent Id
- ///
- /// Id of the Parent to retrieve Descendants from
- /// An Enumerable list of objects
- IEnumerable GetDescendants(int id);
-
- ///
- /// Gets a collection of objects by Parent Id
- ///
- /// item to retrieve Descendants from
- /// An Enumerable list of objects
- IEnumerable GetDescendants(IContent content);
-
- ///
- /// Gets a specific version of an item.
- ///
- /// Id of the version to retrieve
- /// An item
- IContent GetByVersion(Guid versionId);
-
- ///
- /// Checks whether an item has any children
- ///
- /// Id of the
- /// True if the content has any children otherwise False
- bool HasChildren(int id);
-
- ///
- /// Publishes a single object
- ///
- /// The to publish
- /// Optional Id of the User issueing the publishing
- /// True if publishing succeeded, otherwise False
- bool Publish(IContent content, int userId = 0);
-
- ///
- /// Publishes a single object
- ///
- /// The to publish
- /// Optional Id of the User issueing the publishing
- /// The published status attempt
- Attempt PublishWithStatus(IContent content, int userId = 0);
-
- ///
- /// Publishes a object and all its children
- ///
- /// The to publish along with its children
- /// Optional Id of the User issueing the publishing
- /// True if publishing succeeded, otherwise False
- [EditorBrowsable(EditorBrowsableState.Never)]
- [Obsolete("Use PublishWithChildrenWithStatus instead, that method will provide more detailed information on the outcome and also allows the includeUnpublished flag")]
- bool PublishWithChildren(IContent content, int userId = 0);
-
- ///
- /// Publishes a object and all its children
- ///
- /// The to publish along with its children
- /// Optional Id of the User issueing the publishing
- ///
- /// The list of statuses for all published items
- IEnumerable> PublishWithChildrenWithStatus(IContent content, int userId = 0, bool includeUnpublished = false);
-
- ///
- /// UnPublishes a single object
- ///
- /// The to publish
- /// Optional Id of the User issueing the publishing
- /// True if unpublishing succeeded, otherwise False
- bool UnPublish(IContent content, int userId = 0);
-
- ///
- /// Saves and Publishes a single object
- ///
- /// The to save and publish
- /// Optional Id of the User issueing the publishing
- /// Optional boolean indicating whether or not to raise save events.
- /// True if publishing succeeded, otherwise False
- [Obsolete("Use SaveAndPublishWithStatus instead, that method will provide more detailed information on the outcome")]
- [EditorBrowsable(EditorBrowsableState.Never)]
- bool SaveAndPublish(IContent content, int userId = 0, bool raiseEvents = true);
-
- ///
- /// Saves and Publishes a single object
- ///
- /// The to save and publish
- /// Optional Id of the User issueing the publishing
- /// Optional boolean indicating whether or not to raise save events.
- /// True if publishing succeeded, otherwise False
- Attempt SaveAndPublishWithStatus(IContent content, int userId = 0, bool raiseEvents = true);
-
- ///
- /// Permanently deletes an object.
- ///
- ///
- /// This method will also delete associated media files, child content and possibly associated domains.
- ///
- /// Please note that this method will completely remove the Content from the database
- /// The to delete
- /// Optional Id of the User deleting the Content
- void Delete(IContent content, int userId = 0);
-
- ///
- /// Copies an object by creating a new Content object of the same type and copies all data from the current
- /// to the new copy, which is returned. Recursively copies all children.
- ///
- /// The to copy
- /// Id of the Content's new Parent
- /// Boolean indicating whether the copy should be related to the original
- /// Optional Id of the User copying the Content
- /// The newly created object
- IContent Copy(IContent content, int parentId, bool relateToOriginal, int userId = 0);
-
- ///
- /// Copies an object by creating a new Content object of the same type and copies all data from the current
- /// to the new copy which is returned.
- ///
- /// The to copy
- /// Id of the Content's new Parent
- /// Boolean indicating whether the copy should be related to the original
- /// A value indicating whether to recursively copy children.
- /// Optional Id of the User copying the Content
- /// The newly created object
- IContent Copy(IContent content, int parentId, bool relateToOriginal, bool recursive, int userId = 0);
-
- ///
- /// Checks if the passed in can be published based on the anscestors publish state.
- ///
- /// to check if anscestors are published
- /// True if the Content can be published, otherwise False
- bool IsPublishable(IContent content);
-
- ///
- /// Gets a collection of objects, which are ancestors of the current content.
- ///
- /// Id of the to retrieve ancestors for
- /// An Enumerable list of objects
- IEnumerable GetAncestors(int id);
-
- ///
- /// Gets a collection of objects, which are ancestors of the current content.
- ///
- /// to retrieve ancestors for
- /// An Enumerable list of objects
- IEnumerable GetAncestors(IContent content);
-
- ///
- /// Sorts a collection of objects by updating the SortOrder according
- /// to the ordering of items in the passed in .
- ///
- ///
- /// Using this method will ensure that the Published-state is maintained upon sorting
- /// so the cache is updated accordingly - as needed.
- ///
- ///
- ///
- ///
- /// True if sorting succeeded, otherwise False
bool Sort(IEnumerable items, int userId = 0, bool raiseEvents = true);
- ///
- /// Gets the parent of the current content as an item.
- ///
- /// Id of the to retrieve the parent from
- /// Parent object
- IContent GetParent(int id);
+ #endregion
+
+ #region Publish Document
///
- /// Gets the parent of the current content as an item.
+ /// Saves and publishes a document.
///
- /// to retrieve the parent from
- /// Parent object
- IContent GetParent(IContent content);
+ /// Property values must first be published at document level.
+ PublishResult SaveAndPublish(IContent content, int userId = 0, bool raiseEvents = true);
///
- /// Creates and saves an object using the alias of the
- /// that this Content should based on.
+ /// Unpublishes a document.
///
- ///
- /// This method returns an object that has been persisted to the database
- /// and therefor has an identity.
- ///
- /// Name of the Content object
- /// Parent object for the new Content
- /// Alias of the
- /// Optional id of the user creating the content
- ///
- IContent CreateContentWithIdentity(string name, IContent parent, string contentTypeAlias, int userId = 0);
+ PublishResult Unpublish(IContent content, int userId = 0);
///
- /// Creates and saves an object using the alias of the
- /// that this Content should based on.
+ /// Publishes a document and all its children.
///
- ///
- /// This method returns an object that has been persisted to the database
- /// and therefor has an identity.
- ///
- /// Name of the Content object
- /// Id of Parent for the new Content
- /// Alias of the
- /// Optional id of the user creating the content
- ///
- IContent CreateContentWithIdentity(string name, int parentId, string contentTypeAlias, int userId = 0);
+ IEnumerable PublishWithChildren(IContent content, int userId = 0, bool includeUnpublished = false);
+
+ ///
+ /// Gets a value indicating whether a document is path-publishable.
+ ///
+ /// A document is path-publishable when all its ancestors are published.
+ bool IsPathPublishable(IContent content);
+
+ ///
+ /// Gets a value indicating whether a document is path-published.
+ ///
+ /// A document is path-published when all its ancestors, and the document itself, are published.
+ bool IsPathPublished(IContent content);
+
+ ///
+ /// Saves a document and raises the "sent to publication" events.
+ ///
+ bool SendToPublication(IContent content, int userId = 0);
+
+ ///
+ /// Publishes and unpublishes scheduled documents.
+ ///
+ IEnumerable PerformScheduledPublish();
+
+ // fixme missing the differnt type of properties - should we do it manually?
+ ///
+ /// Rolls a document back a previous version.
+ ///
+ IContent Rollback(int id, Guid versionId, int userId = 0);
+
+ #endregion
+
+ #region Permissions
+
+ ///
+ /// Gets permissions assigned to a document.
+ ///
+ EntityPermissionCollection GetPermissions(IContent content);
+
+ ///
+ /// Sets the permission of a document.
+ ///
+ /// Replaces all permissions with the new set of permissions.
+ void SetPermissions(EntityPermissionSet permissionSet);
+
+ ///
+ /// Assigns a permission to a document.
+ ///
+ /// Adds the permission to existing permissions.
+ void SetPermission(IContent entity, char permission, IEnumerable groupIds);
+
+ #endregion
+
+ #region Create
+
+ ///
+ /// Creates a document.
+ ///
+ IContent Create(string name, Guid parentId, string documentTypeAlias, int userId = 0);
+
+ ///
+ /// Creates a document.
+ ///
+ IContent Create(string name, int parentId, string documentTypeAlias, int userId = 0);
+
+ ///
+ /// Creates a document.
+ ///
+ IContent Create(string name, IContent parent, string documentTypeAlias, int userId = 0);
+
+ ///
+ /// Creates and saves a document.
+ ///
+ IContent CreateAndSave(string name, int parentId, string contentTypeAlias, int userId = 0);
+
+ ///
+ /// Creates and saves a document.
+ ///
+ IContent CreateAndSave(string name, IContent parent, string contentTypeAlias, int userId = 0);
+
+ #endregion
}
}
diff --git a/src/Umbraco.Core/Services/IContentTypeServiceBase.cs b/src/Umbraco.Core/Services/IContentTypeServiceBase.cs
index 80fe26c01b..bc091535d3 100644
--- a/src/Umbraco.Core/Services/IContentTypeServiceBase.cs
+++ b/src/Umbraco.Core/Services/IContentTypeServiceBase.cs
@@ -41,18 +41,18 @@ namespace Umbraco.Core.Services
///
bool HasContainerInPath(string contentPath);
- Attempt> CreateContainer(int parentContainerId, string name, int userId = 0);
- Attempt SaveContainer(EntityContainer container, int userId = 0);
+ Attempt> CreateContainer(int parentContainerId, string name, int userId = 0);
+ Attempt SaveContainer(EntityContainer container, int userId = 0);
EntityContainer GetContainer(int containerId);
EntityContainer GetContainer(Guid containerId);
IEnumerable GetContainers(int[] containerIds);
IEnumerable GetContainers(TItem contentType);
IEnumerable GetContainers(string folderName, int level);
- Attempt DeleteContainer(int containerId, int userId = 0);
- Attempt> RenameContainer(int id, string name, int userId = 0);
+ Attempt DeleteContainer(int containerId, int userId = 0);
+ Attempt> RenameContainer(int id, string name, int userId = 0);
- Attempt> Move(TItem moving, int containerId);
- Attempt> Copy(TItem copying, int containerId);
+ Attempt> Move(TItem moving, int containerId);
+ Attempt> Copy(TItem copying, int containerId);
TItem Copy(TItem original, string alias, string name, int parentId = -1);
TItem Copy(TItem original, string alias, string name, TItem parent);
}
diff --git a/src/Umbraco.Core/Services/IDataTypeService.cs b/src/Umbraco.Core/Services/IDataTypeService.cs
index 253bf845f2..660e06b365 100644
--- a/src/Umbraco.Core/Services/IDataTypeService.cs
+++ b/src/Umbraco.Core/Services/IDataTypeService.cs
@@ -9,15 +9,15 @@ namespace Umbraco.Core.Services
///
public interface IDataTypeService : IService
{
- Attempt> CreateContainer(int parentId, string name, int userId = 0);
- Attempt SaveContainer(EntityContainer container, int userId = 0);
+ Attempt> CreateContainer(int parentId, string name, int userId = 0);
+ Attempt SaveContainer(EntityContainer container, int userId = 0);
EntityContainer GetContainer(int containerId);
EntityContainer GetContainer(Guid containerId);
IEnumerable GetContainers(string folderName, int level);
IEnumerable GetContainers(IDataTypeDefinition dataTypeDefinition);
IEnumerable GetContainers(int[] containerIds);
- Attempt DeleteContainer(int containerId, int userId = 0);
- Attempt> RenameContainer(int id, string name, int userId = 0);
+ Attempt DeleteContainer(int containerId, int userId = 0);
+ Attempt> RenameContainer(int id, string name, int userId = 0);
///
/// Gets a by its Name
@@ -138,7 +138,7 @@ namespace Umbraco.Core.Services
/// PreValue as a string
string GetPreValueAsString(int id);
- Attempt> Move(IDataTypeDefinition toMove, int parentId);
+ Attempt> Move(IDataTypeDefinition toMove, int parentId);
}
}
diff --git a/src/Umbraco.Core/Services/IDomainService.cs b/src/Umbraco.Core/Services/IDomainService.cs
index 4c79f58016..70c986bf07 100644
--- a/src/Umbraco.Core/Services/IDomainService.cs
+++ b/src/Umbraco.Core/Services/IDomainService.cs
@@ -6,11 +6,11 @@ namespace Umbraco.Core.Services
public interface IDomainService : IService
{
bool Exists(string domainName);
- Attempt Delete(IDomain domain);
+ Attempt Delete(IDomain domain);
IDomain GetByName(string name);
IDomain GetById(int id);
IEnumerable GetAll(bool includeWildcards);
IEnumerable GetAssignedDomains(int contentId, bool includeWildcards);
- Attempt Save(IDomain domainEntity);
+ Attempt Save(IDomain domainEntity);
}
}
diff --git a/src/Umbraco.Core/Services/IFileService.cs b/src/Umbraco.Core/Services/IFileService.cs
index 09ff9869ad..91ac7c25ea 100644
--- a/src/Umbraco.Core/Services/IFileService.cs
+++ b/src/Umbraco.Core/Services/IFileService.cs
@@ -202,7 +202,7 @@ namespace Umbraco.Core.Services
///
/// The template created
///
- Attempt> CreateTemplateForContentType(string contentTypeAlias, string contentTypeName, int userId = 0);
+ Attempt> CreateTemplateForContentType(string contentTypeAlias, string contentTypeName, int userId = 0);
ITemplate CreateTemplateWithIdentity(string name, string content, ITemplate masterTemplate = null, int userId = 0);
diff --git a/src/Umbraco.Core/Services/IMediaService.cs b/src/Umbraco.Core/Services/IMediaService.cs
index 90b933c411..63cd816b16 100644
--- a/src/Umbraco.Core/Services/IMediaService.cs
+++ b/src/Umbraco.Core/Services/IMediaService.cs
@@ -25,7 +25,7 @@ namespace Umbraco.Core.Services
///
/// The to delete
/// Id of the User deleting the Media
- Attempt MoveToRecycleBin(IMedia media, int userId = 0);
+ Attempt MoveToRecycleBin(IMedia media, int userId = 0);
///
/// Permanently deletes an object
@@ -36,7 +36,7 @@ namespace Umbraco.Core.Services
///
/// The to delete
/// Id of the User deleting the Media
- Attempt Delete(IMedia media, int userId = 0);
+ Attempt Delete(IMedia media, int userId = 0);
///
/// Saves a single object
@@ -44,7 +44,7 @@ namespace Umbraco.Core.Services
/// The to save
/// Id of the User saving the Media
/// Optional boolean indicating whether or not to raise events.
- Attempt Save(IMedia media, int userId = 0, bool raiseEvents = true);
+ Attempt Save(IMedia media, int userId = 0, bool raiseEvents = true);
///
/// Saves a collection of objects
@@ -52,7 +52,7 @@ namespace Umbraco.Core.Services
/// Collection of to save
/// Id of the User saving the Media
/// Optional boolean indicating whether or not to raise events.
- Attempt Save(IEnumerable medias, int userId = 0, bool raiseEvents = true);
+ Attempt Save(IEnumerable medias, int userId = 0, bool raiseEvents = true);
}
///
@@ -312,7 +312,7 @@ namespace Umbraco.Core.Services
///
/// Id of the version to retrieve
/// An item
- IMedia GetByVersion(Guid versionId);
+ IMedia GetVersion(Guid versionId);
///
/// Gets a collection of an objects versions by Id
diff --git a/src/Umbraco.Core/Services/IPublicAccessService.cs b/src/Umbraco.Core/Services/IPublicAccessService.cs
index c66be1433b..6878e3f62d 100644
--- a/src/Umbraco.Core/Services/IPublicAccessService.cs
+++ b/src/Umbraco.Core/Services/IPublicAccessService.cs
@@ -50,7 +50,7 @@ namespace Umbraco.Core.Services
///
///
///
- Attempt> AddRule(IContent content, string ruleType, string ruleValue);
+ Attempt> AddRule(IContent content, string ruleType, string ruleValue);
///
/// Removes a rule
@@ -58,19 +58,19 @@ namespace Umbraco.Core.Services
///
///
///
- Attempt RemoveRule(IContent content, string ruleType, string ruleValue);
+ Attempt RemoveRule(IContent content, string ruleType, string ruleValue);
///
/// Saves the entry
///
///
- Attempt Save(PublicAccessEntry entry);
+ Attempt Save(PublicAccessEntry entry);
///
/// Deletes the entry and all associated rules
///
///
- Attempt Delete(PublicAccessEntry entry);
+ Attempt Delete(PublicAccessEntry entry);
}
}
diff --git a/src/Umbraco.Core/Services/MediaService.cs b/src/Umbraco.Core/Services/MediaService.cs
index 6c92bdda99..6eb9d24bae 100644
--- a/src/Umbraco.Core/Services/MediaService.cs
+++ b/src/Umbraco.Core/Services/MediaService.cs
@@ -417,13 +417,13 @@ namespace Umbraco.Core.Services
///
/// Id of the version to retrieve
/// An item
- public IMedia GetByVersion(Guid versionId)
+ public IMedia GetVersion(Guid versionId)
{
using (var uow = UowProvider.CreateUnitOfWork(readOnly: true))
{
uow.ReadLock(Constants.Locks.MediaTree);
var repository = uow.CreateRepository();
- return repository.GetByVersion(versionId);
+ return repository.GetVersion(versionId);
}
}
@@ -791,7 +791,7 @@ namespace Umbraco.Core.Services
/// The to save
/// Id of the User saving the Media
/// Optional boolean indicating whether or not to raise events.
- Attempt IMediaServiceOperations.Save(IMedia media, int userId, bool raiseEvents)
+ Attempt IMediaServiceOperations.Save(IMedia media, int userId, bool raiseEvents)
{
var evtMsgs = EventMessagesFactory.Get();
@@ -801,7 +801,7 @@ namespace Umbraco.Core.Services
if (raiseEvents && uow.Events.DispatchCancelable(Saving, this, saveEventArgs))
{
uow.Complete();
- return OperationStatus.Attempt.Cancel(evtMsgs);
+ return OperationResult.Attempt.Cancel(evtMsgs);
}
// poor man's validation?
@@ -829,7 +829,7 @@ namespace Umbraco.Core.Services
uow.Complete();
}
- return OperationStatus.Attempt.Succeed(evtMsgs);
+ return OperationResult.Attempt.Succeed(evtMsgs);
}
///
@@ -849,7 +849,7 @@ namespace Umbraco.Core.Services
/// Collection of to save
/// Id of the User saving the Media
/// Optional boolean indicating whether or not to raise events.
- Attempt IMediaServiceOperations.Save(IEnumerable medias, int userId, bool raiseEvents)
+ Attempt IMediaServiceOperations.Save(IEnumerable medias, int userId, bool raiseEvents)
{
var evtMsgs = EventMessagesFactory.Get();
var mediasA = medias.ToArray();
@@ -860,7 +860,7 @@ namespace Umbraco.Core.Services
if (raiseEvents && uow.Events.DispatchCancelable(Saving, this, new SaveEventArgs(mediasA, evtMsgs)))
{
uow.Complete();
- return OperationStatus.Attempt.Cancel(evtMsgs);
+ return OperationResult.Attempt.Cancel(evtMsgs);
}
var treeChanges = mediasA.Select(x => new TreeChange(x,
@@ -886,7 +886,7 @@ namespace Umbraco.Core.Services
uow.Complete();
}
- return OperationStatus.Attempt.Succeed(evtMsgs);
+ return OperationResult.Attempt.Succeed(evtMsgs);
}
#endregion
@@ -912,7 +912,7 @@ namespace Umbraco.Core.Services
///
/// The to delete
/// Id of the User deleting the Media
- Attempt IMediaServiceOperations.Delete(IMedia media, int userId)
+ Attempt IMediaServiceOperations.Delete(IMedia media, int userId)
{
var evtMsgs = EventMessagesFactory.Get();
@@ -921,7 +921,7 @@ namespace Umbraco.Core.Services
if (uow.Events.DispatchCancelable(Deleting, this, new DeleteEventArgs(media, evtMsgs)))
{
uow.Complete();
- return OperationStatus.Attempt.Cancel(evtMsgs);
+ return OperationResult.Attempt.Cancel(evtMsgs);
}
uow.WriteLock(Constants.Locks.MediaTree);
@@ -935,7 +935,7 @@ namespace Umbraco.Core.Services
uow.Complete();
}
- return OperationStatus.Attempt.Succeed(evtMsgs);
+ return OperationResult.Attempt.Succeed(evtMsgs);
}
private void DeleteLocked(IScopeUnitOfWork uow, IMediaRepository repository, IMedia media)
@@ -1047,7 +1047,7 @@ namespace Umbraco.Core.Services
IMediaRepository repository = null;
if (deletePriorVersions)
{
- var media = GetByVersion(versionId);
+ var media = GetVersion(versionId);
DeleteVersions(uow, ref repository, id, media.UpdateDate, userId);
}
@@ -1085,7 +1085,7 @@ namespace Umbraco.Core.Services
///
/// The to delete
/// Id of the User deleting the Media
- Attempt IMediaServiceOperations.MoveToRecycleBin(IMedia media, int userId)
+ Attempt IMediaServiceOperations.MoveToRecycleBin(IMedia media, int userId)
{
var evtMsgs = EventMessagesFactory.Get();
var moves = new List>();
@@ -1102,7 +1102,7 @@ namespace Umbraco.Core.Services
if (uow.Events.DispatchCancelable(Trashing, this, new MoveEventArgs(new MoveEventInfo(media, originalPath, Constants.System.RecycleBinMedia))))
{
uow.Complete();
- return OperationStatus.Attempt.Cancel(evtMsgs);
+ return OperationResult.Attempt.Cancel(evtMsgs);
}
PerformMoveLocked(repository, media, Constants.System.RecycleBinMedia, null, userId, moves, true);
@@ -1119,7 +1119,7 @@ namespace Umbraco.Core.Services
uow.Complete();
}
- return OperationStatus.Attempt.Succeed(evtMsgs);
+ return OperationResult.Attempt.Succeed(evtMsgs);
}
///
diff --git a/src/Umbraco.Core/Services/NotificationService.cs b/src/Umbraco.Core/Services/NotificationService.cs
index a89cafc5bf..906fbe03ec 100644
--- a/src/Umbraco.Core/Services/NotificationService.cs
+++ b/src/Umbraco.Core/Services/NotificationService.cs
@@ -116,7 +116,7 @@ namespace Umbraco.Core.Services
// we are only selecting the top 2 rows since that is all we need
var allVersions = _contentService.GetVersionIds(contentId, 2).ToList();
var prevVersionIndex = allVersions.Count > 1 ? 1 : 0;
- return _contentService.GetByVersion(allVersions[prevVersionIndex]);
+ return _contentService.GetVersion(allVersions[prevVersionIndex]);
}
///
diff --git a/src/Umbraco.Core/Services/OperationResult.cs b/src/Umbraco.Core/Services/OperationResult.cs
new file mode 100644
index 0000000000..d22fd0147f
--- /dev/null
+++ b/src/Umbraco.Core/Services/OperationResult.cs
@@ -0,0 +1,238 @@
+using System;
+using Umbraco.Core.Events;
+
+namespace Umbraco.Core.Services
+{
+ // FIXME
+ // no need for Attempt - the operation result SHOULD KNOW if it's a success or a failure!
+ // but then each WhateverResultType must
+
+ ///
+ /// Represents the result of a service operation.
+ ///
+ /// The type of the result type.
+ public class OperationResult
+ where TResultType : struct
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public OperationResult(TResultType result, EventMessages eventMessages)
+ {
+ Result = result;
+ EventMessages = eventMessages;
+ }
+
+ static OperationResult()
+ {
+ // ensure that TResultType is an enum and the underlying type is byte
+ // so we can safely cast in Success and test against 128 for failures
+ var type = typeof(TResultType);
+ if (type.IsEnum == false)
+ throw new InvalidOperationException($"Type {type} is not an enum.");
+ if (Enum.GetUnderlyingType(type) != typeof (byte))
+ throw new InvalidOperationException($"Enum {type} underlying type is not .");
+ }
+
+ ///
+ /// Gets a value indicating whether the operation was successful.
+ ///
+ public bool Success => ((byte) (object) Result & 128) == 0; // we *know* it's a byte
+
+ ///
+ /// Gets the result of the operation.
+ ///
+ public TResultType Result { get; }
+
+ ///
+ /// Gets the event messages produced by the operation.
+ ///
+ public EventMessages EventMessages { get; }
+ }
+
+ ///
+ ///
+ /// Represents the result of a service operation for a given entity.
+ ///
+ /// The type of the result type.
+ /// The type of the entity.
+ public class OperationResult : OperationResult
+ where TResultType : struct
+ {
+ ///
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The status of the operation.
+ /// Event messages produced by the operation.
+ public OperationResult(TResultType result, EventMessages eventMessages)
+ : base(result, eventMessages)
+ { }
+
+ ///
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public OperationResult(TResultType result, EventMessages eventMessages, TEntity entity)
+ : base(result, eventMessages)
+ {
+ Entity = entity;
+ }
+
+ ///
+ /// Gets the entity.
+ ///
+ public TEntity Entity { get; }
+ }
+
+ ///
+ ///
+ /// Represents the default operation result.
+ ///
+ public class OperationResult : OperationResult
+ {
+ ///
+ ///
+ /// Initializes a new instance of the class with a status and event messages.
+ ///
+ /// The status of the operation.
+ /// Event messages produced by the operation.
+ public OperationResult(OperationResultType result, EventMessages eventMessages)
+ : base(result, eventMessages)
+ { }
+
+ public static OperationResult Succeed(EventMessages eventMessages)
+ {
+ return new OperationResult(OperationResultType.Success, eventMessages);
+ }
+
+ public static OperationResult Cancel(EventMessages eventMessages)
+ {
+ return new OperationResult(OperationResultType.FailedCancelledByEvent, eventMessages);
+ }
+
+ // fixme wtf?
+ internal static class Attempt
+ {
+ ///
+ /// Creates a successful operation attempt.
+ ///
+ /// The event messages produced by the operation.
+ /// A new attempt instance.
+ public static Attempt Succeed(EventMessages eventMessages)
+ {
+ return Core.Attempt.Succeed(new OperationResult(OperationResultType.Success, eventMessages));
+ }
+
+ public static Attempt> Succeed(EventMessages eventMessages)
+ {
+ return Core.Attempt.Succeed(new OperationResult(OperationResultType.Success, eventMessages));
+ }
+
+ public static Attempt> Succeed(EventMessages eventMessages, TValue value)
+ {
+ return Core.Attempt.Succeed(new OperationResult(OperationResultType.Success, eventMessages, value));
+ }
+
+ public static Attempt> Succeed(TStatusType statusType, EventMessages eventMessages)
+ where TStatusType : struct
+ {
+ return Core.Attempt.Succeed(new OperationResult(statusType, eventMessages));
+ }
+
+ public static Attempt> Succeed(TStatusType statusType, EventMessages eventMessages, TValue value)
+ where TStatusType : struct
+ {
+ return Core.Attempt.Succeed(new OperationResult(statusType, eventMessages, value));
+ }
+
+ ///
+ /// Creates a successful operation attempt indicating that nothing was done.
+ ///
+ /// The event messages produced by the operation.
+ /// A new attempt instance.
+ public static Attempt NoOperation(EventMessages eventMessages)
+ {
+ return Core.Attempt.Succeed(new OperationResult(OperationResultType.NoOperation, eventMessages));
+ }
+
+ ///
+ /// Creates a failed operation attempt indicating that the operation has been cancelled.
+ ///
+ /// The event messages produced by the operation.
+ /// A new attempt instance.
+ public static Attempt Cancel(EventMessages eventMessages)
+ {
+ return Core.Attempt.Fail(new OperationResult(OperationResultType.FailedCancelledByEvent, eventMessages));
+ }
+
+ public static Attempt> Cancel(EventMessages eventMessages)
+ {
+ return Core.Attempt.Fail(new OperationResult(OperationResultType.FailedCancelledByEvent, eventMessages));
+ }
+
+ public static Attempt> Cancel(EventMessages eventMessages, TValue value)
+ {
+ return Core.Attempt.Fail(new OperationResult(OperationResultType.FailedCancelledByEvent, eventMessages, value));
+ }
+
+ ///
+ /// Creates a failed operation attempt indicating that an exception was thrown during the operation.
+ ///
+ /// The event messages produced by the operation.
+ /// The exception that caused the operation to fail.
+ /// A new attempt instance.
+ public static Attempt Fail(EventMessages eventMessages, Exception exception)
+ {
+ eventMessages.Add(new EventMessage("", exception.Message, EventMessageType.Error));
+ return Core.Attempt.Fail(new OperationResult(OperationResultType.FailedExceptionThrown, eventMessages), exception);
+ }
+
+ public static Attempt> Fail(EventMessages eventMessages, Exception exception)
+ {
+ return Core.Attempt.Fail(new OperationResult(OperationResultType.FailedExceptionThrown, eventMessages), exception);
+ }
+
+ public static Attempt> Fail(TStatusType statusType, EventMessages eventMessages)
+ where TStatusType : struct
+ {
+ return Core.Attempt.Fail(new OperationResult(statusType, eventMessages));
+ }
+
+ public static Attempt> Fail(TStatusType statusType, EventMessages eventMessages, Exception exception)
+ where TStatusType : struct
+ {
+ return Core.Attempt.Fail(new OperationResult(statusType, eventMessages), exception);
+ }
+
+ public static Attempt> Fail(TStatusType statusType, EventMessages eventMessages)
+ where TStatusType : struct
+ {
+ return Core.Attempt.Fail(new OperationResult(statusType, eventMessages));
+ }
+
+ public static Attempt> Fail(TStatusType statusType, EventMessages eventMessages, TValue value)
+ where TStatusType : struct
+ {
+ return Core.Attempt.Fail(new OperationResult(statusType, eventMessages, value));
+ }
+
+ public static Attempt> Fail(TStatusType statusType, EventMessages eventMessages, Exception exception)
+ where TStatusType : struct
+ {
+ return Core.Attempt.Fail(new OperationResult(statusType, eventMessages), exception);
+ }
+
+ public static Attempt> Fail(TStatusType statusType, EventMessages eventMessages, TValue value, Exception exception)
+ where TStatusType : struct
+ {
+ return Core.Attempt.Fail(new OperationResult(statusType, eventMessages, value), exception);
+ }
+
+ public static Attempt> Cannot(EventMessages eventMessages)
+ {
+ return Core.Attempt.Fail(new OperationResult(OperationResultType.FailedCannot, eventMessages));
+ }
+ }
+ }
+}
diff --git a/src/Umbraco.Core/Services/OperationResultType.cs b/src/Umbraco.Core/Services/OperationResultType.cs
new file mode 100644
index 0000000000..9310741ca5
--- /dev/null
+++ b/src/Umbraco.Core/Services/OperationResultType.cs
@@ -0,0 +1,45 @@
+namespace Umbraco.Core.Services
+{
+ ///
+ /// A value indicating the result of an operation.
+ ///
+ public enum OperationResultType : byte
+ {
+ // all "ResultType" enums must be byte-based, and declare Failed = 128, and declare
+ // every failure codes as >128 - see OperationResult and OperationResultType for details.
+
+ ///
+ /// The operation was successful.
+ ///
+ Success = 0,
+
+ ///
+ /// The operation failed.
+ ///
+ /// All values above this value indicate a failure.
+ Failed = 128,
+
+ ///
+ /// The operation could not complete because of invalid preconditions (eg creating a reference
+ /// to an item that does not exist).
+ ///
+ FailedCannot = Failed | 2,
+
+ ///
+ /// The operation has been cancelled by an event handler.
+ ///
+ FailedCancelledByEvent = Failed | 4,
+
+ ///
+ /// The operation could not complete due to an exception.
+ ///
+ FailedExceptionThrown = Failed | 5,
+
+ ///
+ /// No operation has been executed because it was not needed (eg deleting an item that doesn't exist).
+ ///
+ NoOperation = Failed | 6, // fixme shouldn't it be a success?
+
+ //TODO: In the future, we might need to add more operations statuses, potentially like 'FailedByPermissions', etc...
+ }
+}
diff --git a/src/Umbraco.Core/Services/OperationStatus.cs b/src/Umbraco.Core/Services/OperationStatus.cs
deleted file mode 100644
index 5b87852c24..0000000000
--- a/src/Umbraco.Core/Services/OperationStatus.cs
+++ /dev/null
@@ -1,214 +0,0 @@
-using System;
-using Umbraco.Core.Events;
-
-namespace Umbraco.Core.Services
-{
- ///
- /// Represents the status of a service operation.
- ///
- /// The type of the status type.
- public class OperationStatus
- where TStatusType : struct
- {
- ///
- /// Initializes a new instance of the class with a status and event messages.
- ///
- /// The status of the operation.
- /// Event messages produced by the operation.
- public OperationStatus(TStatusType statusType, EventMessages eventMessages)
- {
- StatusType = statusType;
- EventMessages = eventMessages ?? throw new ArgumentNullException(nameof(eventMessages));
- }
-
- ///
- /// Gets or sets the status of the operation.
- ///
- /// May be internally updated during the operation, but should NOT be updated once the operation has completed.
- public TStatusType StatusType { get; internal set; }
-
- ///
- /// Gets the event messages produced by the operation.
- ///
- public EventMessages EventMessages { get; }
- }
-
- ///
- ///
- /// Represents the status of a service operation that manages (processes, produces...) a value.
- ///
- /// The type of the status type.
- /// The type of the value.
- public class OperationStatus : OperationStatus
- where TStatusType : struct
- {
- ///
- ///
- /// Initializes a new instance of the class with a status type and event messages.
- ///
- /// The status of the operation.
- /// Event messages produced by the operation.
- public OperationStatus(TStatusType statusType, EventMessages eventMessages)
- : base(statusType, eventMessages)
- { }
-
- ///
- ///
- /// Initializes a new instance of the class with a status type, event messages and a value.
- ///
- /// The status of the operation.
- /// Event messages produced by the operation.
- /// The value managed by the operation.
- public OperationStatus(TStatusType statusType, EventMessages eventMessages, TValue value)
- : base(statusType, eventMessages)
- {
- Value = value;
- }
-
- ///
- /// Gets the value managed by the operation.
- ///
- public TValue Value { get; }
- }
-
- ///
- ///
- /// Represents the default operation status.
- ///
- /// Also provides static helper methods to create operation statuses.
- public class OperationStatus : OperationStatus
- {
- ///
- ///
- /// Initializes a new instance of the class with a status and event messages.
- ///
- /// The status of the operation.
- /// Event messages produced by the operation.
- public OperationStatus(OperationStatusType statusType, EventMessages eventMessages)
- : base(statusType, eventMessages)
- { }
-
- internal static class Attempt
- {
- ///
- /// Creates a successful operation attempt.
- ///
- /// The event messages produced by the operation.
- /// A new attempt instance.
- public static Attempt Succeed(EventMessages eventMessages)
- {
- return Core.Attempt.Succeed(new OperationStatus(OperationStatusType.Success, eventMessages));
- }
-
- public static Attempt> Succeed(EventMessages eventMessages)
- {
- return Core.Attempt.Succeed(new OperationStatus(OperationStatusType.Success, eventMessages));
- }
-
- public static Attempt> Succeed(EventMessages eventMessages, TValue value)
- {
- return Core.Attempt.Succeed(new OperationStatus(OperationStatusType.Success, eventMessages, value));
- }
-
- public static Attempt> Succeed(TStatusType statusType, EventMessages eventMessages)
- where TStatusType : struct
- {
- return Core.Attempt.Succeed(new OperationStatus(statusType, eventMessages));
- }
-
- public static Attempt> Succeed(TStatusType statusType, EventMessages eventMessages, TValue value)
- where TStatusType : struct
- {
- return Core.Attempt.Succeed(new OperationStatus(statusType, eventMessages, value));
- }
-
- ///
- /// Creates a successful operation attempt indicating that nothing was done.
- ///
- /// The event messages produced by the operation.
- /// A new attempt instance.
- public static Attempt NoOperation(EventMessages eventMessages)
- {
- return Core.Attempt.Succeed(new OperationStatus(OperationStatusType.NoOperation, eventMessages));
- }
-
- ///
- /// Creates a failed operation attempt indicating that the operation has been cancelled.
- ///
- /// The event messages produced by the operation.
- /// A new attempt instance.
- public static Attempt Cancel(EventMessages eventMessages)
- {
- return Core.Attempt.Fail(new OperationStatus(OperationStatusType.FailedCancelledByEvent, eventMessages));
- }
-
- public static Attempt> Cancel(EventMessages eventMessages)
- {
- return Core.Attempt.Fail(new OperationStatus(OperationStatusType.FailedCancelledByEvent, eventMessages));
- }
-
- public static Attempt> Cancel(EventMessages eventMessages, TValue value)
- {
- return Core.Attempt.Fail(new OperationStatus(OperationStatusType.FailedCancelledByEvent, eventMessages, value));
- }
-
- ///
- /// Creates a failed operation attempt indicating that an exception was thrown during the operation.
- ///
- /// The event messages produced by the operation.
- /// The exception that caused the operation to fail.
- /// A new attempt instance.
- public static Attempt Fail(EventMessages eventMessages, Exception exception)
- {
- eventMessages.Add(new EventMessage("", exception.Message, EventMessageType.Error));
- return Core.Attempt.Fail(new OperationStatus(OperationStatusType.FailedExceptionThrown, eventMessages), exception);
- }
-
- public static Attempt> Fail(EventMessages eventMessages, Exception exception)
- {
- return Core.Attempt.Fail(new OperationStatus