diff --git a/src/Umbraco.Core/Models/Content.cs b/src/Umbraco.Core/Models/Content.cs
index 049461522d..034c9bb91d 100644
--- a/src/Umbraco.Core/Models/Content.cs
+++ b/src/Umbraco.Core/Models/Content.cs
@@ -275,57 +275,14 @@ namespace Umbraco.Core.Models
_publishedState = PublishedState.Publishing;
}
- internal virtual void CopyValues(IContentBase other, bool published = false)
+ internal virtual void CopyValues(IContentBase other, int? languageId, string segment, bool published = false)
{
// clear all existing properties
- ClearEditValues(null, null);
-
- // copy other properties
- var otherProperties = other.Properties;
- foreach (var otherProperty in otherProperties)
- {
- var alias = otherProperty.PropertyType.Alias;
- SetValue(alias, otherProperty.GetValue(published));
- }
- }
-
- internal virtual void CopyValues(IContentBase other, int? nLanguageId, bool published = false)
- {
- if (!nLanguageId.HasValue)
- {
- CopyValues(other);
- return;
- }
-
- var languageId = nLanguageId.Value;
-
- // clear all existing properties
- ClearEditValues(nLanguageId, null);
-
- // copy other properties
- var otherProperties = other.Properties;
- foreach (var otherProperty in otherProperties)
- {
- var alias = otherProperty.PropertyType.Alias;
- SetValue(alias, languageId, otherProperty.GetValue(languageId, published));
- }
- }
-
- internal virtual void CopyValues(IContentBase other, int? nLanguageId, string segment, bool published = false)
- {
- if (segment == null)
- {
- CopyValues(other, nLanguageId, published);
- return;
- }
-
- if (!nLanguageId.HasValue)
- throw new ArgumentException("Cannot be null when segment is not null.", nameof(nLanguageId));
-
- var languageId = nLanguageId.Value;
-
- // clear all existing properties
- ClearEditValues(nLanguageId, segment);
+ // note: use property.SetValue(), don't assign pvalue.EditValue, else change tracking fails
+ foreach (var property in Properties)
+ 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;
@@ -336,29 +293,13 @@ namespace Umbraco.Core.Models
}
}
- private void ClearEditValues()
- {
- // clear all existing properties
- // note: use property.SetValue(), don't assign pvalue.EditValue, else change tracking fails
- foreach (var property in Properties)
- foreach (var pvalue in property.Values)
- property.SetValue(pvalue.LanguageId, pvalue.Segment, null);
- }
-
- private void ClearEditValues(int? nLanguageId, string segment)
- {
- // clear all existing properties
- // note: use property.SetValue(), don't assign pvalue.EditValue, else change tracking fails
- foreach (var property in Properties)
- foreach (var pvalue in property.Values)
- if (pvalue.LanguageId == nLanguageId && pvalue.Segment == segment)
- property.SetValue(pvalue.LanguageId, pvalue.Segment, null);
- }
-
internal virtual void CopyAllValues(IContentBase other, bool published = false)
{
// clear all existing properties
- ClearEditValues();
+ // note: use property.SetValue(), don't assign pvalue.EditValue, else change tracking fails
+ foreach (var property in Properties)
+ foreach (var pvalue in property.Values)
+ property.SetValue(pvalue.LanguageId, pvalue.Segment, null);
// copy other properties
var otherProperties = other.Properties;
@@ -367,14 +308,8 @@ namespace Umbraco.Core.Models
var alias = otherProperty.PropertyType.Alias;
foreach (var pvalue in otherProperty.Values)
{
- // fixme can we update SetValue to accept null lang/segment and fallback?
var value = published ? pvalue.PublishedValue : pvalue.EditedValue;
- if (!pvalue.LanguageId.HasValue)
- SetValue(alias, value);
- else if (pvalue.Segment == null)
- SetValue(alias, pvalue.LanguageId.Value, value);
- else
- SetValue(alias, pvalue.LanguageId.Value, pvalue.Segment, value);
+ SetValue(alias, pvalue.LanguageId, pvalue.Segment, value);
}
}
}
diff --git a/src/Umbraco.Core/Models/ContentBase.cs b/src/Umbraco.Core/Models/ContentBase.cs
index 207f54c981..a981fb3387 100644
--- a/src/Umbraco.Core/Models/ContentBase.cs
+++ b/src/Umbraco.Core/Models/ContentBase.cs
@@ -275,23 +275,39 @@ namespace Umbraco.Core.Models
///
public virtual object GetValue(string propertyTypeAlias, bool published = false)
{
- return Properties.Contains(propertyTypeAlias) ? Properties[propertyTypeAlias].GetValue(published) : null;
+ 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)
+ public virtual object GetValue(string propertyTypeAlias, int? languageId, bool published = false)
{
- return Properties.Contains(propertyTypeAlias) ? Properties[propertyTypeAlias].GetValue(languageId, published) : null;
+ 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, int languageId, string segment, bool published = false)
+ public virtual object GetValue(string propertyTypeAlias, string segment, bool published = false)
{
- return Properties.Contains(propertyTypeAlias) ? Properties[propertyTypeAlias].GetValue(languageId, segment, published) : null;
+ 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)
+ {
+ return Properties.TryGetValue(propertyTypeAlias, out var property)
+ ? property.GetValue(languageId, segment, published)
+ : null;
}
///
@@ -299,34 +315,46 @@ namespace Umbraco.Core.Models
///
public virtual TPropertyValue GetValue(string propertyTypeAlias, bool published = false)
{
- if (Properties.Contains(propertyTypeAlias) == false)
+ if (!Properties.TryGetValue(propertyTypeAlias, out var property))
return default;
- var convertAttempt = Properties[propertyTypeAlias].GetValue(published).TryConvertTo();
+ var convertAttempt = property.GetValue(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 TPropertyValue GetValue(string propertyTypeAlias, int? languageId, bool published = false)
{
- if (Properties.Contains(propertyTypeAlias) == false)
+ if (!Properties.TryGetValue(propertyTypeAlias, out var property))
return default;
- var convertAttempt = Properties[propertyTypeAlias].GetValue(languageId, published).TryConvertTo();
+ var convertAttempt = property.GetValue(languageId, null, published).TryConvertTo();
return convertAttempt.Success ? convertAttempt.Result : default;
}
///
/// Gets the typed segment value of a property.
///
- public virtual TPropertyValue GetValue(string propertyTypeAlias, int languageId, string segment, bool published = false)
+ public virtual TPropertyValue GetValue(string propertyTypeAlias, string segment, bool published = false)
{
- if (Properties.Contains(propertyTypeAlias) == false)
+ if (!Properties.TryGetValue(propertyTypeAlias, out var property))
return default;
- var convertAttempt = Properties[propertyTypeAlias].GetValue(languageId, segment, published).TryConvertTo();
+ 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;
}
@@ -348,11 +376,11 @@ namespace Umbraco.Core.Models
///
/// Sets the culture (draft) value of a property.
///
- public virtual void SetValue(string propertyTypeAlias, int languageId, object value)
+ public virtual void SetValue(string propertyTypeAlias, int? languageId, object value)
{
if (value == null)
{
- SetValueOnProperty(propertyTypeAlias, languageId, null);
+ SetValueOnProperty(propertyTypeAlias, languageId, null, null);
return;
}
@@ -361,9 +389,24 @@ namespace Umbraco.Core.Models
}
///
- /// Sets the segment (draft) value of a property.
+ /// Sets the culture+segment (draft) value of a property.
///
- public virtual void SetValue(string propertyTypeAlias, int languageId, string segment, object value)
+ public virtual void SetValue(string propertyTypeAlias, string segment, object value)
+ {
+ if (value == null)
+ {
+ SetValueOnProperty(propertyTypeAlias, null, segment, null);
+ return;
+ }
+
+ // .NET magic to call one of the 'SetPropertyValue' handlers with matching signature
+ ((dynamic) this).SetPropertyValue(propertyTypeAlias, null, segment, (dynamic) value);
+ }
+
+ ///
+ /// Sets the culture+segment (draft) value of a property.
+ ///
+ public virtual void SetValue(string propertyTypeAlias, int? languageId, string segment, object value)
{
if (value == null)
{
@@ -375,6 +418,16 @@ namespace Umbraco.Core.Models
((dynamic) this).SetPropertyValue(propertyTypeAlias, languageId, segment, (dynamic) value);
}
+
+
+
+
+ // FIXME fix everything below
+
+
+
+
+
///
/// Sets the neutral (draft) string value of a Property
///
@@ -595,30 +648,10 @@ namespace Umbraco.Core.Models
Properties.Add(property);
}
- ///
- /// Sets the culture (draft) value of a property.
- ///
- private void SetValueOnProperty(string propertyTypeAlias, int languageId, object value)
- {
- if (Properties.Contains(propertyTypeAlias))
- {
- Properties[propertyTypeAlias].SetValue(languageId, 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, value);
- Properties.Add(property);
- }
-
///
/// Sets the segment (draft) value of a property.
///
- private void SetValueOnProperty(string propertyTypeAlias, int languageId, string segment, object value)
+ private void SetValueOnProperty(string propertyTypeAlias, int? languageId, string segment, object value)
{
if (Properties.Contains(propertyTypeAlias))
{
@@ -649,11 +682,16 @@ namespace Umbraco.Core.Models
return _invalidProperties.Any() == false;
}
+ public virtual bool Validate(int? languageId, string segment, out IEnumerable invalidProperties)
+ {
+ // fixme etc
+ }
+
///
/// Gets the properties marked as invalid during the last validation.
///
[IgnoreDataMember]
- internal IEnumerable InvalidProperties => _invalidProperties;
+ internal IEnumerable InvalidProperties => _invalidProperties; // fixme return it, don't keep it here!
#endregion
diff --git a/src/Umbraco.Core/Models/IContentBase.cs b/src/Umbraco.Core/Models/IContentBase.cs
index 8feda0d733..ea698bff7f 100644
--- a/src/Umbraco.Core/Models/IContentBase.cs
+++ b/src/Umbraco.Core/Models/IContentBase.cs
@@ -48,7 +48,7 @@ namespace Umbraco.Core.Models
///
/// Alias of the PropertyType
/// True if Property with given alias exists, otherwise False
- bool HasProperty(string propertyTypeAlias);
+ bool HasProperty(string propertyTypeAlias); // fixme - what does this mean????
///
/// Gets the neutral value of a Property
@@ -58,12 +58,17 @@ namespace Umbraco.Core.Models
///
/// Gets the culture value of a Property
///
- object GetValue(string propertyTypeAlias, int languageId, bool published = false);
+ object GetValue(string propertyTypeAlias, int? languageId, bool published = false);
///
/// Gets the segment value of a Property
///
- object GetValue(string propertyTypeAlias, int languageId, string segment, bool published = false);
+ object GetValue(string propertyTypeAlias, string segment, bool published = false);
+
+ ///
+ /// Gets the culture+segment value of a Property
+ ///
+ object GetValue(string propertyTypeAlias, int? languageId, string segment, bool published = false);
///
/// Gets the typed neutral value of a Property
@@ -71,34 +76,63 @@ namespace Umbraco.Core.Models
TPropertyValue GetValue(string propertyTypeAlias, bool published = false);
///
- /// Gets the typed neutral value of a Property
+ /// Gets the typed culture value of a Property
///
- TPropertyValue GetValue(string propertyTypeAlias, int languageId, bool published = false);
+ TPropertyValue GetValue(string propertyTypeAlias, int? languageId, bool published = false);
///
- /// Gets the typed neutral value of a Property
+ /// Gets the typed segment value of a Property
///
- TPropertyValue GetValue(string propertyTypeAlias, int languageId, string segment, bool published = false);
+ TPropertyValue GetValue(string propertyTypeAlias, string segment, bool published = false);
///
- /// Sets the neutral (draft) value of a Property
+ /// 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 (draft) value of a Property
+ /// Sets the culture (edited) value of a Property
///
- void SetValue(string propertyTypeAlias, int languageId, object value);
+ void SetValue(string propertyTypeAlias, int? languageId, object value);
///
- /// Sets the segment (draft) value of a Property
+ /// Sets the segment (edited) value of a Property
///
- void SetValue(string propertyTypeAlias, int languageId, string segment, object value);
+ void SetValue(string propertyTypeAlias, string segment, object value);
///
- /// Boolean indicating whether the content and its properties are valid
+ /// 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 neutral properties values are valid.
///
- /// True if content is valid otherwise false
bool Validate();
+
+ ///
+ /// Gets a value indicating whether the content and its culture properties values are valid.
+ ///
+ bool Validate(int? languageId);
+
+ ///
+ /// Gets a value indicating whether the content and its segment properties values are valid.
+ ///
+ bool Validate(string segment);
+
+ ///
+ /// Gets a value indicating whether the content and its culture+segment properties values are valid.
+ ///
+ bool Validate(int? languageId, string segment);
+
+ ///
+ /// Gets a value indicating whether the content and all its properties values are valid.
+ ///
+ bool ValidateAll();
}
}
diff --git a/src/Umbraco.Core/Models/Property.cs b/src/Umbraco.Core/Models/Property.cs
index 557a46afd9..3e20e633dc 100644
--- a/src/Umbraco.Core/Models/Property.cs
+++ b/src/Umbraco.Core/Models/Property.cs
@@ -91,9 +91,7 @@ namespace Umbraco.Core.Models
set
{
_values = value;
-
_pvalue = value.FirstOrDefault(x => !x.LanguageId.HasValue && x.Segment == null);
-
_vvalues = value.ToDictionary(x => (x.LanguageId, x.Segment), x => x);
}
}
@@ -349,7 +347,7 @@ namespace Umbraco.Core.Models
}
///
- /// Gets a value indicating whether the (edit) neutral value is valid.
+ /// Gets a value indicating whether the (edited) neutral value is valid.
///
/// An invalid value can be saved, but only valid values can be published.
public bool IsValid()
@@ -358,23 +356,41 @@ namespace Umbraco.Core.Models
}
///
- /// Gets a value indicating whether the (edit) culture value is valid.
+ /// 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)
+ public bool IsValid(int? languageId)
{
return IsValid(GetValue(languageId));
}
///
- /// Gets a value indicating whether the (edit) segment value is valid.
+ /// 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 IsValue(int languageId, string segment)
+ public bool IsValue(string segment)
+ {
+ return IsValid(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 IsValue(int? languageId, string segment)
{
return IsValid(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()
+ {
+ return _values.All(x => IsValid(x.EditedValue));
+ }
+
///
/// Boolean indicating whether the passed in value is valid
///
diff --git a/src/Umbraco.Core/Models/PropertyCollection.cs b/src/Umbraco.Core/Models/PropertyCollection.cs
index 1bedf57333..9c51ddbe79 100644
--- a/src/Umbraco.Core/Models/PropertyCollection.cs
+++ b/src/Umbraco.Core/Models/PropertyCollection.cs
@@ -156,6 +156,12 @@ namespace Umbraco.Core.Models
}
}
+ public bool TryGetValue(string propertyTypeAlias, out Property property)
+ {
+ property = this[propertyTypeAlias];
+ return property != null;
+ }
+
///
/// Occurs when the collection changes.
///