diff --git a/src/Umbraco.Core/Collections/CompositeStringStringKey.cs b/src/Umbraco.Core/Collections/CompositeStringStringKey.cs
new file mode 100644
index 0000000000..11f123f2d0
--- /dev/null
+++ b/src/Umbraco.Core/Collections/CompositeStringStringKey.cs
@@ -0,0 +1,41 @@
+using System;
+
+namespace Umbraco.Core.Collections
+{
+ ///
+ /// Represents a composite key of (string, string) for fast dictionaries.
+ ///
+ ///
+ /// The string parts of the key are case-insensitive.
+ /// Null is a valid value for both parts.
+ ///
+ public struct CompositeStringStringKey : IEquatable
+ {
+ private readonly string _key1;
+ private readonly string _key2;
+
+ ///
+ /// Initializes a new instance of the struct.
+ ///
+ public CompositeStringStringKey(string key1, string key2)
+ {
+ _key1 = key1?.ToLowerInvariant() ?? "NULL";
+ _key2 = key2?.ToLowerInvariant() ?? "NULL";
+ }
+
+ public bool Equals(CompositeStringStringKey other)
+ => _key2 == other._key2 && _key1 == other._key1;
+
+ public override bool Equals(object obj)
+ => obj is CompositeStringStringKey other && _key2 == other._key2 && _key1 == other._key1;
+
+ public override int GetHashCode()
+ => _key2.GetHashCode() * 31 + _key1.GetHashCode();
+
+ public static bool operator ==(CompositeStringStringKey key1, CompositeStringStringKey key2)
+ => key1._key2 == key2._key2 && key1._key1 == key2._key1;
+
+ public static bool operator !=(CompositeStringStringKey key1, CompositeStringStringKey key2)
+ => key1._key2 != key2._key2 || key1._key1 != key2._key1;
+ }
+}
diff --git a/src/Umbraco.Core/IO/MediaFileSystem.cs b/src/Umbraco.Core/IO/MediaFileSystem.cs
index b96b0d54bc..5534936a04 100644
--- a/src/Umbraco.Core/IO/MediaFileSystem.cs
+++ b/src/Umbraco.Core/IO/MediaFileSystem.cs
@@ -335,35 +335,35 @@ namespace Umbraco.Core.IO
// fixme - what's below belongs to the upload property editor, not the media filesystem!
- public void SetUploadFile(IContentBase content, string propertyTypeAlias, string filename, Stream filestream, int? languageId = null, string segment = null)
+ public void SetUploadFile(IContentBase content, string propertyTypeAlias, string filename, Stream filestream, string culture = null, string segment = null)
{
var property = GetProperty(content, propertyTypeAlias);
- var oldpath = property.GetValue(languageId, segment) is string svalue ? GetRelativePath(svalue) : null;
+ var oldpath = property.GetValue(culture, segment) is string svalue ? GetRelativePath(svalue) : null;
var filepath = StoreFile(content, property.PropertyType, filename, filestream, oldpath);
- property.SetValue(GetUrl(filepath), languageId, segment);
- SetUploadFile(content, property, filepath, filestream, languageId, segment);
+ property.SetValue(GetUrl(filepath), culture, segment);
+ SetUploadFile(content, property, filepath, filestream, culture, segment);
}
- public void SetUploadFile(IContentBase content, string propertyTypeAlias, string filepath, int? languageId = null, string segment = null)
+ public void SetUploadFile(IContentBase content, string propertyTypeAlias, string filepath, string culture = null, string segment = null)
{
var property = GetProperty(content, propertyTypeAlias);
// fixme delete?
- var oldpath = property.GetValue(languageId, segment) is string svalue ? GetRelativePath(svalue) : null;
+ var oldpath = property.GetValue(culture, segment) is string svalue ? GetRelativePath(svalue) : null;
if (string.IsNullOrWhiteSpace(oldpath) == false && oldpath != filepath)
DeleteFile(oldpath);
- property.SetValue(GetUrl(filepath), languageId, segment);
+ property.SetValue(GetUrl(filepath), culture, segment);
using (var filestream = OpenFile(filepath))
{
- SetUploadFile(content, property, filepath, filestream, languageId, segment);
+ SetUploadFile(content, property, filepath, filestream, culture, segment);
}
}
// sets a file for the FileUpload property editor
// ie generates thumbnails and populates autofill properties
- private void SetUploadFile(IContentBase content, Property property, string filepath, Stream filestream, int? languageId = null, string segment = null)
+ private void SetUploadFile(IContentBase content, Property property, string filepath, Stream filestream, string culture = null, string segment = null)
{
// will use filepath for extension, and filestream for length
- UploadAutoFillProperties.Populate(content, property.Alias, filepath, filestream, languageId, segment);
+ UploadAutoFillProperties.Populate(content, property.Alias, filepath, filestream, culture, segment);
}
#endregion
diff --git a/src/Umbraco.Core/Media/UploadAutoFillProperties.cs b/src/Umbraco.Core/Media/UploadAutoFillProperties.cs
index 3fdaf7b3d3..4ab2bf7a7c 100644
--- a/src/Umbraco.Core/Media/UploadAutoFillProperties.cs
+++ b/src/Umbraco.Core/Media/UploadAutoFillProperties.cs
@@ -41,9 +41,9 @@ namespace Umbraco.Core.Media
///
/// The content item.
/// The property type alias.
- /// Variation language.
+ /// Variation language.
/// Variation segment.
- public void Reset(IContentBase content, string propertyTypeAlias, int? languageId, string segment)
+ public void Reset(IContentBase content, string propertyTypeAlias, string culture, string segment)
{
if (content == null) throw new ArgumentNullException(nameof(content));
if (propertyTypeAlias == null) throw new ArgumentNullException(nameof(propertyTypeAlias));
@@ -53,7 +53,7 @@ namespace Umbraco.Core.Media
if (autoFillConfig == null) return; // nothing
// reset
- Reset(content, autoFillConfig, languageId, segment);
+ Reset(content, autoFillConfig, culture, segment);
}
///
@@ -61,14 +61,14 @@ namespace Umbraco.Core.Media
///
/// The content item.
/// The auto-fill configuration.
- /// Variation language.
+ /// Variation language.
/// Variation segment.
- public void Reset(IContentBase content, IImagingAutoFillUploadField autoFillConfig, int? languageId, string segment)
+ public void Reset(IContentBase content, IImagingAutoFillUploadField autoFillConfig, string culture, string segment)
{
if (content == null) throw new ArgumentNullException(nameof(content));
if (autoFillConfig == null) throw new ArgumentNullException(nameof(autoFillConfig));
- ResetProperties(content, autoFillConfig, languageId, segment);
+ ResetProperties(content, autoFillConfig, culture, segment);
}
///
@@ -77,9 +77,9 @@ namespace Umbraco.Core.Media
/// The content item.
/// The property type alias.
/// The filesystem-relative filepath, or null to clear properties.
- /// Variation language.
+ /// Variation language.
/// Variation segment.
- public void Populate(IContentBase content, string propertyTypeAlias, string filepath, int? languageId, string segment)
+ public void Populate(IContentBase content, string propertyTypeAlias, string filepath, string culture, string segment)
{
if (content == null) throw new ArgumentNullException(nameof(content));
if (propertyTypeAlias == null) throw new ArgumentNullException(nameof(propertyTypeAlias));
@@ -92,7 +92,7 @@ namespace Umbraco.Core.Media
if (autoFillConfig == null) return; // nothing
// populate
- Populate(content, autoFillConfig, filepath, languageId, segment);
+ Populate(content, autoFillConfig, filepath, culture, segment);
}
///
@@ -102,9 +102,9 @@ namespace Umbraco.Core.Media
/// The property type alias.
/// The filesystem-relative filepath, or null to clear properties.
/// The stream containing the file data.
- /// Variation language.
+ /// Variation language.
/// Variation segment.
- public void Populate(IContentBase content, string propertyTypeAlias, string filepath, Stream filestream, int? languageId, string segment)
+ public void Populate(IContentBase content, string propertyTypeAlias, string filepath, Stream filestream, string culture, string segment)
{
if (content == null) throw new ArgumentNullException(nameof(content));
if (propertyTypeAlias == null) throw new ArgumentNullException(nameof(propertyTypeAlias));
@@ -117,7 +117,7 @@ namespace Umbraco.Core.Media
if (autoFillConfig == null) return; // nothing
// populate
- Populate(content, autoFillConfig, filepath, filestream, languageId, segment);
+ Populate(content, autoFillConfig, filepath, filestream, culture, segment);
}
///
@@ -127,9 +127,9 @@ namespace Umbraco.Core.Media
/// The auto-fill configuration.
/// The filesystem path to the uploaded file.
/// The parameter is the path relative to the filesystem.
- /// Variation language.
+ /// Variation language.
/// Variation segment.
- public void Populate(IContentBase content, IImagingAutoFillUploadField autoFillConfig, string filepath, int? languageId, string segment)
+ public void Populate(IContentBase content, IImagingAutoFillUploadField autoFillConfig, string filepath, string culture, string segment)
{
if (content == null) throw new ArgumentNullException(nameof(content));
if (autoFillConfig == null) throw new ArgumentNullException(nameof(autoFillConfig));
@@ -137,7 +137,7 @@ namespace Umbraco.Core.Media
// no file = reset, file = auto-fill
if (filepath.IsNullOrWhiteSpace())
{
- ResetProperties(content, autoFillConfig, languageId, segment);
+ ResetProperties(content, autoFillConfig, culture, segment);
}
else
{
@@ -148,13 +148,13 @@ namespace Umbraco.Core.Media
{
var extension = (Path.GetExtension(filepath) ?? "").TrimStart('.');
var size = _mediaFileSystem.IsImageFile(extension) ? (Size?) _mediaFileSystem.GetDimensions(filestream) : null;
- SetProperties(content, autoFillConfig, size, filestream.Length, extension, languageId, segment);
+ SetProperties(content, autoFillConfig, size, filestream.Length, extension, culture, segment);
}
}
catch (Exception ex)
{
_logger.Error(typeof(UploadAutoFillProperties), $"Could not populate upload auto-fill properties for file \"{filepath}\".", ex);
- ResetProperties(content, autoFillConfig, languageId, segment);
+ ResetProperties(content, autoFillConfig, culture, segment);
}
}
}
@@ -166,9 +166,9 @@ namespace Umbraco.Core.Media
///
/// The filesystem-relative filepath, or null to clear properties.
/// The stream containing the file data.
- /// Variation language.
+ /// Variation language.
/// Variation segment.
- public void Populate(IContentBase content, IImagingAutoFillUploadField autoFillConfig, string filepath, Stream filestream, int? languageId, string segment)
+ public void Populate(IContentBase content, IImagingAutoFillUploadField autoFillConfig, string filepath, Stream filestream, string culture, string segment)
{
if (content == null) throw new ArgumentNullException(nameof(content));
if (autoFillConfig == null) throw new ArgumentNullException(nameof(autoFillConfig));
@@ -176,50 +176,50 @@ namespace Umbraco.Core.Media
// no file = reset, file = auto-fill
if (filepath.IsNullOrWhiteSpace() || filestream == null)
{
- ResetProperties(content, autoFillConfig, languageId, segment);
+ ResetProperties(content, autoFillConfig, culture, segment);
}
else
{
var extension = (Path.GetExtension(filepath) ?? "").TrimStart('.');
var size = _mediaFileSystem.IsImageFile(extension) ? (Size?)_mediaFileSystem.GetDimensions(filestream) : null;
- SetProperties(content, autoFillConfig, size, filestream.Length, extension, languageId, segment);
+ SetProperties(content, autoFillConfig, size, filestream.Length, extension, culture, segment);
}
}
- private static void SetProperties(IContentBase content, IImagingAutoFillUploadField autoFillConfig, Size? size, long length, string extension, int? languageId, string segment)
+ private static void SetProperties(IContentBase content, IImagingAutoFillUploadField autoFillConfig, Size? size, long length, string extension, string culture, string segment)
{
if (content == null) throw new ArgumentNullException(nameof(content));
if (autoFillConfig == null) throw new ArgumentNullException(nameof(autoFillConfig));
if (content.Properties.Contains(autoFillConfig.WidthFieldAlias))
- content.Properties[autoFillConfig.WidthFieldAlias].SetValue(size.HasValue ? size.Value.Width.ToInvariantString() : string.Empty, languageId, segment);
+ content.Properties[autoFillConfig.WidthFieldAlias].SetValue(size.HasValue ? size.Value.Width.ToInvariantString() : string.Empty, culture, segment);
if (content.Properties.Contains(autoFillConfig.HeightFieldAlias))
- content.Properties[autoFillConfig.HeightFieldAlias].SetValue(size.HasValue ? size.Value.Height.ToInvariantString() : string.Empty, languageId, segment);
+ content.Properties[autoFillConfig.HeightFieldAlias].SetValue(size.HasValue ? size.Value.Height.ToInvariantString() : string.Empty, culture, segment);
if (content.Properties.Contains(autoFillConfig.LengthFieldAlias))
- content.Properties[autoFillConfig.LengthFieldAlias].SetValue(length, languageId, segment);
+ content.Properties[autoFillConfig.LengthFieldAlias].SetValue(length, culture, segment);
if (content.Properties.Contains(autoFillConfig.ExtensionFieldAlias))
- content.Properties[autoFillConfig.ExtensionFieldAlias].SetValue(extension, languageId, segment);
+ content.Properties[autoFillConfig.ExtensionFieldAlias].SetValue(extension, culture, segment);
}
- private static void ResetProperties(IContentBase content, IImagingAutoFillUploadField autoFillConfig, int? languageId, string segment)
+ private static void ResetProperties(IContentBase content, IImagingAutoFillUploadField autoFillConfig, string culture, string segment)
{
if (content == null) throw new ArgumentNullException(nameof(content));
if (autoFillConfig == null) throw new ArgumentNullException(nameof(autoFillConfig));
if (content.Properties.Contains(autoFillConfig.WidthFieldAlias))
- content.Properties[autoFillConfig.WidthFieldAlias].SetValue(string.Empty, languageId, segment);
+ content.Properties[autoFillConfig.WidthFieldAlias].SetValue(string.Empty, culture, segment);
if (content.Properties.Contains(autoFillConfig.HeightFieldAlias))
- content.Properties[autoFillConfig.HeightFieldAlias].SetValue(string.Empty, languageId, segment);
+ content.Properties[autoFillConfig.HeightFieldAlias].SetValue(string.Empty, culture, segment);
if (content.Properties.Contains(autoFillConfig.LengthFieldAlias))
- content.Properties[autoFillConfig.LengthFieldAlias].SetValue(string.Empty, languageId, segment);
+ content.Properties[autoFillConfig.LengthFieldAlias].SetValue(string.Empty, culture, segment);
if (content.Properties.Contains(autoFillConfig.ExtensionFieldAlias))
- content.Properties[autoFillConfig.ExtensionFieldAlias].SetValue(string.Empty, languageId, segment);
+ content.Properties[autoFillConfig.ExtensionFieldAlias].SetValue(string.Empty, culture, segment);
}
}
}
diff --git a/src/Umbraco.Core/Models/Content.cs b/src/Umbraco.Core/Models/Content.cs
index 142d7540c2..1f106124b4 100644
--- a/src/Umbraco.Core/Models/Content.cs
+++ b/src/Umbraco.Core/Models/Content.cs
@@ -20,7 +20,7 @@ namespace Umbraco.Core.Models
private PublishedState _publishedState;
private DateTime? _releaseDate;
private DateTime? _expireDate;
- private Dictionary _publishNames;
+ private Dictionary _publishNames;
private static readonly Lazy Ps = new Lazy();
@@ -201,24 +201,24 @@ namespace Umbraco.Core.Models
///
[IgnoreDataMember]
- public IReadOnlyDictionary PublishNames => _publishNames ?? NoNames;
+ public IReadOnlyDictionary PublishNames => _publishNames ?? NoNames;
///
- public string GetPublishName(int? languageId)
+ public string GetPublishName(string culture)
{
- if (languageId == null) return PublishName;
+ if (culture == null) return PublishName;
if (_publishNames == null) return null;
- return _publishNames.TryGetValue(languageId.Value, out var name) ? name : null;
+ return _publishNames.TryGetValue(culture, out var name) ? name : null;
}
// sets a publish name
// internal for repositories
- internal void SetPublishName(int? languageId, string name)
+ internal void SetPublishName(string culture, string name)
{
if (string.IsNullOrWhiteSpace(name))
throw new ArgumentNullOrEmptyException(nameof(name));
- if (languageId == null)
+ if (culture == null)
{
PublishName = name;
return;
@@ -227,22 +227,22 @@ namespace Umbraco.Core.Models
// private method, assume that culture is valid
if (_publishNames == null)
- _publishNames = new Dictionary();
+ _publishNames = new Dictionary(StringComparer.OrdinalIgnoreCase);
- _publishNames[languageId.Value] = name;
+ _publishNames[culture] = name;
}
// clears a publish name
- private void ClearPublishName(int? languageId)
+ private void ClearPublishName(string culture)
{
- if (languageId == null)
+ if (culture == null)
{
PublishName = null;
return;
}
if (_publishNames == null) return;
- _publishNames.Remove(languageId.Value);
+ _publishNames.Remove(culture);
if (_publishNames.Count == 0)
_publishNames = null;
}
@@ -255,12 +255,12 @@ namespace Umbraco.Core.Models
}
///
- public bool IsCultureAvailable(int? languageId)
- => !string.IsNullOrWhiteSpace(GetName(languageId));
+ public bool IsCultureAvailable(string culture)
+ => !string.IsNullOrWhiteSpace(GetName(culture));
///
- public bool IsCulturePublished(int? languageId)
- => !string.IsNullOrWhiteSpace(GetPublishName(languageId));
+ public bool IsCulturePublished(string culture)
+ => !string.IsNullOrWhiteSpace(GetPublishName(culture));
[IgnoreDataMember]
public int PublishedVersionId { get; internal set; }
@@ -275,57 +275,72 @@ namespace Umbraco.Core.Models
if (ValidateAll().Any())
return false;
- // property.PublishAllValues only deals with supported variations (if any)
- foreach (var property in Properties)
- property.PublishAllValues();
-
// Name and PublishName are managed by the repository, but Names and PublishNames
// must be managed here as they depend on the existing / supported variations.
- PublishName = Name;
- foreach (var (languageId, name) in Names)
- SetPublishName(languageId, name);
+ if (string.IsNullOrWhiteSpace(Name))
+ throw new InvalidOperationException($"Cannot publish invariant culture without a name.");
+ PublishName = Name;
+ foreach (var (culture, name) in Names)
+ {
+ if (string.IsNullOrWhiteSpace(name))
+ throw new InvalidOperationException($"Cannot publish {culture ?? "invariant"} culture without a name.");
+ SetPublishName(culture, name);
+ }
+ // property.PublishAllValues only deals with supported variations (if any)
+ foreach (var property in Properties)
+ property.PublishAllValues();
+
_publishedState = PublishedState.Publishing;
return true;
}
///
- public virtual bool PublishValues(int? languageId = null, string segment = null)
+ public virtual bool PublishValues(string culture = null, string segment = null)
{
// the variation should be supported by the content type
- ContentType.ValidateVariation(languageId, segment, throwIfInvalid: true);
+ ContentType.ValidateVariation(culture, segment, throwIfInvalid: true);
// the values we want to publish should be valid
- if (Validate(languageId, segment).Any())
+ if (Validate(culture, segment).Any())
return false;
- // property.PublishValue throws on invalid variation, so filter them out
- foreach (var property in Properties.Where(x => x.PropertyType.ValidateVariation(languageId, segment, throwIfInvalid: false)))
- property.PublishValue(languageId, segment);
-
// Name and PublishName are managed by the repository, but Names and PublishNames
// must be managed here as they depend on the existing / supported variations.
- SetPublishName(languageId, GetName(languageId));
+ if (segment == null)
+ {
+ var name = GetName(culture);
+ if (string.IsNullOrWhiteSpace(name))
+ throw new InvalidOperationException($"Cannot publish {culture ?? "invariant"} culture without a name.");
+ SetPublishName(culture, name);
+ }
+ // property.PublishValue throws on invalid variation, so filter them out
+ foreach (var property in Properties.Where(x => x.PropertyType.ValidateVariation(culture, segment, throwIfInvalid: false)))
+ property.PublishValue(culture, segment);
+
_publishedState = PublishedState.Publishing;
return true;
}
///
- public virtual bool PublishCultureValues(int? languageId = null)
+ public virtual bool PublishCultureValues(string culture = null)
{
// the values we want to publish should be valid
- if (ValidateCulture(languageId).Any())
+ if (ValidateCulture(culture).Any())
return false;
- // property.PublishCultureValues only deals with supported variations (if any)
- foreach (var property in Properties)
- property.PublishCultureValues(languageId);
-
// Name and PublishName are managed by the repository, but Names and PublishNames
// must be managed here as they depend on the existing / supported variations.
- SetPublishName(languageId, GetName(languageId));
+ var name = GetName(culture);
+ if (string.IsNullOrWhiteSpace(name))
+ throw new InvalidOperationException($"Cannot publish {culture ?? "invariant"} culture without a name.");
+ SetPublishName(culture, name);
+ // property.PublishCultureValues only deals with supported variations (if any)
+ foreach (var property in Properties)
+ property.PublishCultureValues(culture);
+
_publishedState = PublishedState.Publishing;
return true;
}
@@ -345,32 +360,32 @@ namespace Umbraco.Core.Models
}
///
- public virtual void ClearPublishedValues(int? languageId = null, string segment = null)
+ public virtual void ClearPublishedValues(string culture = null, string segment = null)
{
// the variation should be supported by the content type
- ContentType.ValidateVariation(languageId, segment, throwIfInvalid: true);
+ ContentType.ValidateVariation(culture, segment, throwIfInvalid: true);
// property.ClearPublishedValue throws on invalid variation, so filter them out
- foreach (var property in Properties.Where(x => x.PropertyType.ValidateVariation(languageId, segment, throwIfInvalid: false)))
- property.ClearPublishedValue(languageId, segment);
+ foreach (var property in Properties.Where(x => x.PropertyType.ValidateVariation(culture, segment, throwIfInvalid: false)))
+ property.ClearPublishedValue(culture, segment);
// Name and PublishName are managed by the repository, but Names and PublishNames
// must be managed here as they depend on the existing / supported variations.
- ClearPublishName(languageId);
+ ClearPublishName(culture);
_publishedState = PublishedState.Publishing;
}
///
- public virtual void ClearCulturePublishedValues(int? languageId = null)
+ public virtual void ClearCulturePublishedValues(string culture = null)
{
// property.ClearPublishedCultureValues only deals with supported variations (if any)
foreach (var property in Properties)
- property.ClearPublishedCultureValues(languageId);
+ property.ClearPublishedCultureValues(culture);
// Name and PublishName are managed by the repository, but Names and PublishNames
// must be managed here as they depend on the existing / supported variations.
- ClearPublishName(languageId);
+ ClearPublishName(culture);
_publishedState = PublishedState.Publishing;
}
@@ -397,8 +412,8 @@ namespace Umbraco.Core.Models
// clear all existing properties
foreach (var property in Properties)
foreach (var pvalue in property.Values)
- if (property.PropertyType.ValidateVariation(pvalue.LanguageId, pvalue.Segment, false))
- property.SetValue(null, pvalue.LanguageId, pvalue.Segment);
+ if (property.PropertyType.ValidateVariation(pvalue.Culture, pvalue.Segment, false))
+ property.SetValue(null, pvalue.Culture, pvalue.Segment);
// copy other properties
var otherProperties = other.Properties;
@@ -407,10 +422,10 @@ namespace Umbraco.Core.Models
var alias = otherProperty.PropertyType.Alias;
foreach (var pvalue in otherProperty.Values)
{
- if (!otherProperty.PropertyType.ValidateVariation(pvalue.LanguageId, pvalue.Segment, false))
+ if (!otherProperty.PropertyType.ValidateVariation(pvalue.Culture, pvalue.Segment, false))
continue;
var value = published ? pvalue.PublishedValue : pvalue.EditedValue;
- SetValue(alias, value, pvalue.LanguageId, pvalue.Segment);
+ SetValue(alias, value, pvalue.Culture, pvalue.Segment);
}
}
@@ -422,7 +437,7 @@ namespace Umbraco.Core.Models
}
///
- public virtual void CopyValues(IContent other, int? languageId = null, string segment = null)
+ public virtual void CopyValues(IContent other, string culture = null, string segment = null)
{
if (other.ContentTypeId != ContentTypeId)
throw new InvalidOperationException("Cannot copy values from a different content type.");
@@ -437,31 +452,31 @@ namespace Umbraco.Core.Models
// clear all existing properties
foreach (var property in Properties)
{
- if (!property.PropertyType.ValidateVariation(languageId, segment, false))
+ if (!property.PropertyType.ValidateVariation(culture, segment, false))
continue;
foreach (var pvalue in property.Values)
- if (pvalue.LanguageId == languageId && pvalue.Segment == segment)
- property.SetValue(null, pvalue.LanguageId, pvalue.Segment);
+ if (pvalue.Culture.InvariantEquals(culture) && pvalue.Segment.InvariantEquals(segment))
+ property.SetValue(null, pvalue.Culture, pvalue.Segment);
}
// copy other properties
var otherProperties = other.Properties;
foreach (var otherProperty in otherProperties)
{
- if (!otherProperty.PropertyType.ValidateVariation(languageId, segment, false))
+ if (!otherProperty.PropertyType.ValidateVariation(culture, segment, false))
continue;
var alias = otherProperty.PropertyType.Alias;
- SetValue(alias, otherProperty.GetValue(languageId, segment, published), languageId, segment);
+ SetValue(alias, otherProperty.GetValue(culture, segment, published), culture, segment);
}
// copy name
- SetName(languageId, other.GetName(languageId));
+ SetName(culture, other.GetName(culture));
}
///
- public virtual void CopyCultureValues(IContent other, int? languageId = null)
+ public virtual void CopyCultureValues(IContent other, string culture = null)
{
if (other.ContentTypeId != ContentTypeId)
throw new InvalidOperationException("Cannot copy values from a different content type.");
@@ -473,8 +488,8 @@ namespace Umbraco.Core.Models
// 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);
+ if (pvalue.Culture.InvariantEquals(culture) && property.PropertyType.ValidateVariation(pvalue.Culture, pvalue.Segment, false))
+ property.SetValue(null, pvalue.Culture, pvalue.Segment);
// copy other properties
var otherProperties = other.Properties;
@@ -483,15 +498,15 @@ namespace Umbraco.Core.Models
var alias = otherProperty.PropertyType.Alias;
foreach (var pvalue in otherProperty.Values)
{
- if (pvalue.LanguageId != languageId || !otherProperty.PropertyType.ValidateVariation(pvalue.LanguageId, pvalue.Segment, false))
+ if (pvalue.Culture != culture || !otherProperty.PropertyType.ValidateVariation(pvalue.Culture, pvalue.Segment, false))
continue;
var value = published ? pvalue.PublishedValue : pvalue.EditedValue;
- SetValue(alias, value, pvalue.LanguageId, pvalue.Segment);
+ SetValue(alias, value, pvalue.Culture, pvalue.Segment);
}
}
// copy name
- SetName(languageId, other.GetName(languageId));
+ SetName(culture, other.GetName(culture));
}
///
diff --git a/src/Umbraco.Core/Models/ContentBase.cs b/src/Umbraco.Core/Models/ContentBase.cs
index 8203cba985..32a26f9dc0 100644
--- a/src/Umbraco.Core/Models/ContentBase.cs
+++ b/src/Umbraco.Core/Models/ContentBase.cs
@@ -18,14 +18,14 @@ namespace Umbraco.Core.Models
[DebuggerDisplay("Id: {Id}, Name: {Name}, ContentType: {ContentTypeBase.Alias}")]
public abstract class ContentBase : TreeEntityBase, IContentBase
{
- protected static readonly Dictionary NoNames = new Dictionary();
+ protected static readonly Dictionary NoNames = new Dictionary();
private static readonly Lazy Ps = new Lazy();
private int _contentTypeId;
protected IContentTypeComposition ContentTypeBase;
private int _writerId;
private PropertyCollection _properties;
- private Dictionary _names;
+ private Dictionary _names;
///
/// Initializes a new instance of the class.
@@ -67,7 +67,7 @@ namespace Umbraco.Core.Models
public readonly PropertyInfo DefaultContentTypeIdSelector = ExpressionHelper.GetPropertyInfo(x => x.ContentTypeId);
public readonly PropertyInfo PropertyCollectionSelector = ExpressionHelper.GetPropertyInfo(x => x.Properties);
public readonly PropertyInfo WriterSelector = ExpressionHelper.GetPropertyInfo(x => x.WriterId);
- public readonly PropertyInfo NamesSelector = ExpressionHelper.GetPropertyInfo>(x => x.Names);
+ public readonly PropertyInfo NamesSelector = ExpressionHelper.GetPropertyInfo>(x => x.Names);
}
protected void PropertiesChanged(object sender, NotifyCollectionChangedEventArgs e)
@@ -123,26 +123,26 @@ namespace Umbraco.Core.Models
///
[DataMember]
- public virtual IReadOnlyDictionary Names
+ public virtual IReadOnlyDictionary Names
{
get => _names ?? NoNames;
set
{
- foreach (var (languageId, name) in value)
- SetName(languageId, name);
+ foreach (var (culture, name) in value)
+ SetName(culture, name);
}
}
///
- public virtual void SetName(int? languageId, string name)
+ public virtual void SetName(string culture, string name)
{
if (string.IsNullOrWhiteSpace(name))
{
- ClearName(languageId);
+ ClearName(culture);
return;
}
- if (languageId == null)
+ if (culture == null)
{
Name = name;
return;
@@ -152,22 +152,22 @@ namespace Umbraco.Core.Models
throw new NotSupportedException("Content type does not support varying name by culture.");
if (_names == null)
- _names = new Dictionary();
+ _names = new Dictionary(StringComparer.OrdinalIgnoreCase);
- _names[languageId.Value] = name;
+ _names[culture] = name;
OnPropertyChanged(Ps.Value.NamesSelector);
}
- private void ClearName(int? languageId)
+ private void ClearName(string culture)
{
- if (languageId == null)
+ if (culture == null)
{
Name = null;
return;
}
if (_names == null) return;
- _names.Remove(languageId.Value);
+ _names.Remove(culture);
if (_names.Count == 0)
_names = null;
}
@@ -179,11 +179,11 @@ namespace Umbraco.Core.Models
}
///
- public virtual string GetName(int? languageId)
+ public virtual string GetName(string culture)
{
- if (languageId == null) return Name;
+ if (culture == null) return Name;
if (_names == null) return null;
- return _names.TryGetValue(languageId.Value, out var name) ? name : null;
+ return _names.TryGetValue(culture, out var name) ? name : null;
}
///
@@ -207,29 +207,29 @@ namespace Umbraco.Core.Models
=> Properties.Contains(propertyTypeAlias);
///
- public virtual object GetValue(string propertyTypeAlias, int? languageId = null, string segment = null, bool published = false)
+ public virtual object GetValue(string propertyTypeAlias, string culture = null, string segment = null, bool published = false)
{
return Properties.TryGetValue(propertyTypeAlias, out var property)
- ? property.GetValue(languageId, segment, published)
+ ? property.GetValue(culture, segment, published)
: null;
}
///
- public virtual TValue GetValue(string propertyTypeAlias, int? languageId = null, string segment = null, bool published = false)
+ public virtual TValue GetValue(string propertyTypeAlias, string culture = null, string segment = null, bool published = false)
{
if (!Properties.TryGetValue(propertyTypeAlias, out var property))
return default;
- var convertAttempt = property.GetValue(languageId, segment, published).TryConvertTo();
+ var convertAttempt = property.GetValue(culture, segment, published).TryConvertTo();
return convertAttempt.Success ? convertAttempt.Result : default;
}
///
- public virtual void SetValue(string propertyTypeAlias, object value, int? languageId = null, string segment = null)
+ public virtual void SetValue(string propertyTypeAlias, object value, string culture = null, string segment = null)
{
if (Properties.Contains(propertyTypeAlias))
{
- Properties[propertyTypeAlias].SetValue(value, languageId, segment);
+ Properties[propertyTypeAlias].SetValue(value, culture, segment);
return;
}
@@ -238,7 +238,7 @@ namespace Umbraco.Core.Models
throw new InvalidOperationException($"No PropertyType exists with the supplied alias \"{propertyTypeAlias}\".");
var property = propertyType.CreateProperty();
- property.SetValue(value, languageId, segment);
+ property.SetValue(value, culture, segment);
Properties.Add(property);
}
@@ -249,17 +249,17 @@ namespace Umbraco.Core.Models
///
/// Sets the posted file value of a property.
///
- public virtual void SetValue(string propertyTypeAlias, HttpPostedFile value, int? languageId = null, string segment = null)
+ public virtual void SetValue(string propertyTypeAlias, HttpPostedFile value, string culture = null, string segment = null)
{
- ContentExtensions.SetValue(this, propertyTypeAlias, new HttpPostedFileWrapper(value), languageId, segment);
+ ContentExtensions.SetValue(this, propertyTypeAlias, new HttpPostedFileWrapper(value), culture, segment);
}
///
/// Sets the posted file value of a property.
///
- public virtual void SetValue(string propertyTypeAlias, HttpPostedFileBase value, int? languageId = null, string segment = null)
+ public virtual void SetValue(string propertyTypeAlias, HttpPostedFileBase value, string culture = null, string segment = null)
{
- ContentExtensions.SetValue(this, propertyTypeAlias, value, languageId, segment);
+ ContentExtensions.SetValue(this, propertyTypeAlias, value, culture, segment);
}
#endregion
@@ -271,14 +271,14 @@ namespace Umbraco.Core.Models
return Properties.Where(x => !x.IsAllValid()).ToArray();
}
- public virtual Property[] Validate(int? languageId = null, string segment = null)
+ public virtual Property[] Validate(string culture = null, string segment = null)
{
- return Properties.Where(x => !x.IsValid(languageId, segment)).ToArray();
+ return Properties.Where(x => !x.IsValid(culture, segment)).ToArray();
}
- public virtual Property[] ValidateCulture(int? languageId = null)
+ public virtual Property[] ValidateCulture(string culture = null)
{
- return Properties.Where(x => !x.IsCultureValid(languageId)).ToArray();
+ return Properties.Where(x => !x.IsCultureValid(culture)).ToArray();
}
#endregion
diff --git a/src/Umbraco.Core/Models/ContentExtensions.cs b/src/Umbraco.Core/Models/ContentExtensions.cs
index 5b7e825d68..0940675346 100644
--- a/src/Umbraco.Core/Models/ContentExtensions.cs
+++ b/src/Umbraco.Core/Models/ContentExtensions.cs
@@ -284,7 +284,7 @@ namespace Umbraco.Core.Models
///
/// Sets the posted file value of a property.
///
- public static void SetValue(this IContentBase content, string propertyTypeAlias, HttpPostedFileBase value, int? languageId = null, string segment = null)
+ public static void SetValue(this IContentBase content, string propertyTypeAlias, HttpPostedFileBase value, string culture = null, string segment = null)
{
// ensure we get the filename without the path in IE in intranet mode
// http://stackoverflow.com/questions/382464/httppostedfile-filename-different-from-ie
@@ -303,7 +303,7 @@ namespace Umbraco.Core.Models
if (string.IsNullOrWhiteSpace(filename)) return;
filename = filename.ToLower(); // fixme - er... why?
- MediaFileSystem.SetUploadFile(content, propertyTypeAlias, filename, value.InputStream, languageId, segment);
+ MediaFileSystem.SetUploadFile(content, propertyTypeAlias, filename, value.InputStream, culture, segment);
}
///
@@ -312,7 +312,7 @@ namespace Umbraco.Core.Models
/// This really is for FileUpload fields only, and should be obsoleted. For anything else,
/// you need to store the file by yourself using Store and then figure out
/// how to deal with auto-fill properties (if any) and thumbnails (if any) by yourself.
- public static void SetValue(this IContentBase content, string propertyTypeAlias, string filename, Stream filestream, int? languageId = null, string segment = null)
+ public static void SetValue(this IContentBase content, string propertyTypeAlias, string filename, Stream filestream, string culture = null, string segment = null)
{
if (filename == null || filestream == null) return;
@@ -321,7 +321,7 @@ namespace Umbraco.Core.Models
if (string.IsNullOrWhiteSpace(filename)) return;
filename = filename.ToLower(); // fixme - er... why?
- MediaFileSystem.SetUploadFile(content, propertyTypeAlias, filename, filestream, languageId, segment);
+ MediaFileSystem.SetUploadFile(content, propertyTypeAlias, filename, filestream, culture, segment);
}
///
diff --git a/src/Umbraco.Core/Models/ContentTypeBase.cs b/src/Umbraco.Core/Models/ContentTypeBase.cs
index b686b97108..7d0ffea31e 100644
--- a/src/Umbraco.Core/Models/ContentTypeBase.cs
+++ b/src/Umbraco.Core/Models/ContentTypeBase.cs
@@ -204,10 +204,10 @@ namespace Umbraco.Core.Models
///
/// Validates that a variation is valid for the content type.
///
- public bool ValidateVariation(int? languageId, string segment, bool throwIfInvalid)
+ public bool ValidateVariation(string culture, string segment, bool throwIfInvalid)
{
ContentVariation variation;
- if (languageId.HasValue)
+ if (culture != null)
{
variation = segment != null
? ContentVariation.CultureSegment
diff --git a/src/Umbraco.Core/Models/IContent.cs b/src/Umbraco.Core/Models/IContent.cs
index 3f7a335620..3df81f7314 100644
--- a/src/Umbraco.Core/Models/IContent.cs
+++ b/src/Umbraco.Core/Models/IContent.cs
@@ -59,7 +59,7 @@ namespace Umbraco.Core.Models
/// Gets the date and time the content was published.
///
DateTime? PublishDate { get; }
-
+
///
/// Gets or sets the date and time the content item should be published.
///
@@ -87,7 +87,7 @@ namespace Umbraco.Core.Models
/// A culture becomes available whenever the content name for this culture is
/// non-null, and it becomes unavailable whenever the content name is null.
///
- bool IsCultureAvailable(int? languageId);
+ bool IsCultureAvailable(string culture);
///
/// Gets a value indicating whether a given culture is published.
@@ -97,17 +97,17 @@ namespace Umbraco.Core.Models
/// and the content published name for this culture is non-null. It becomes non-published
/// whenever values for this culture are unpublished.
///
- bool IsCulturePublished(int? languageId);
+ bool IsCulturePublished(string culture);
///
/// Gets the name of the published version of the content for a given culture.
///
///
/// When editing the content, the name can change, but this will not until the content is published.
- /// When is null, gets the invariant
+ /// When is null, gets the invariant
/// language, which is the value of the property.
///
- string GetPublishName(int? languageId);
+ string GetPublishName(string culture);
///
/// Gets the published names of the content.
@@ -116,7 +116,7 @@ namespace Umbraco.Core.Models
/// Because a dictionary key cannot be null this cannot get the invariant
/// name, which must be get via the property.
///
- IReadOnlyDictionary PublishNames { get; }
+ IReadOnlyDictionary PublishNames { get; }
// fixme - these two should move to some kind of service
@@ -159,7 +159,7 @@ namespace Umbraco.Core.Models
/// The document must then be published via the content service.
/// Values are not published if they are not valid.
///
- bool PublishValues(int? languageId = null, string segment = null);
+ bool PublishValues(string culture = null, string segment = null);
///
/// Publishes the culture/any values.
@@ -169,7 +169,7 @@ namespace Umbraco.Core.Models
/// The document must then be published via the content service.
/// Values are not published if they are not valie.
///
- bool PublishCultureValues(int? languageId = null);
+ bool PublishCultureValues(string culture = null);
///
/// Clears all published values.
@@ -179,12 +179,12 @@ namespace Umbraco.Core.Models
///
/// Clears published values.
///
- void ClearPublishedValues(int? languageId = null, string segment = null);
+ void ClearPublishedValues(string culture = null, string segment = null);
///
/// Clears the culture/any published values.
///
- void ClearCulturePublishedValues(int? languageId = null);
+ void ClearCulturePublishedValues(string culture = null);
///
/// Copies values from another document.
@@ -194,11 +194,11 @@ namespace Umbraco.Core.Models
///
/// Copies values from another document.
///
- void CopyValues(IContent other, int? languageId = null, string segment = null);
+ void CopyValues(IContent other, string culture = null, string segment = null);
///
/// Copies culture/any values from another document.
///
- void CopyCultureValues(IContent other, int? languageId = null);
+ void CopyCultureValues(IContent other, string culture = null);
}
}
diff --git a/src/Umbraco.Core/Models/IContentBase.cs b/src/Umbraco.Core/Models/IContentBase.cs
index aee8acd35e..f8bb0e6985 100644
--- a/src/Umbraco.Core/Models/IContentBase.cs
+++ b/src/Umbraco.Core/Models/IContentBase.cs
@@ -31,19 +31,19 @@ namespace Umbraco.Core.Models
/// Sets the name of the content item for a specified language.
///
///
- /// When is null, sets the invariant
+ /// When is null, sets the invariant
/// language, which sets the property.
///
- void SetName(int? languageId, string value);
+ void SetName(string culture, string value);
///
/// Gets the name of the content item for a specified language.
///
///
- /// When is null, gets the invariant
+ /// When is null, gets the invariant
/// language, which is the value of the property.
///
- string GetName(int? languageId);
+ string GetName(string culture);
///
/// Gets or sets the names of the content item.
@@ -52,7 +52,7 @@ namespace Umbraco.Core.Models
/// Because a dictionary key cannot be null this cannot get nor set the invariant
/// name, which must be get or set via the property.
///
- IReadOnlyDictionary Names { get; set; }
+ IReadOnlyDictionary Names { get; set; }
///
/// List of properties, which make up all the data available for this Content object
@@ -82,17 +82,17 @@ namespace Umbraco.Core.Models
///
/// Gets the value of a Property
///
- object GetValue(string propertyTypeAlias, int? languageId = null, string segment = null, bool published = false);
+ object GetValue(string propertyTypeAlias, string culture = null, string segment = null, bool published = false);
///
/// Gets the typed value of a Property
///
- TValue GetValue(string propertyTypeAlias, int? languageId = null, string segment = null, bool published = false);
+ TValue GetValue(string propertyTypeAlias, string culture = null, string segment = null, bool published = false);
///
/// Sets the (edited) value of a Property
///
- void SetValue(string propertyTypeAlias, object value, int? languageId = null, string segment = null);
+ void SetValue(string propertyTypeAlias, object value, string culture = null, string segment = null);
///
/// Gets a value indicating whether the content and all its properties values are valid.
@@ -102,11 +102,11 @@ namespace Umbraco.Core.Models
///
/// Gets a value indicating whether the content and its properties values are valid.
///
- Property[] Validate(int? languageId = null, string segment = null);
+ Property[] Validate(string culture = null, string segment = null);
///
/// Gets a value indicating whether the content and its culture/any properties values are valid.
///
- Property[] ValidateCulture(int? languageId = null);
+ Property[] ValidateCulture(string culture = null);
}
}
diff --git a/src/Umbraco.Core/Models/IContentTypeBase.cs b/src/Umbraco.Core/Models/IContentTypeBase.cs
index 68e5923d66..7c8cc8eafe 100644
--- a/src/Umbraco.Core/Models/IContentTypeBase.cs
+++ b/src/Umbraco.Core/Models/IContentTypeBase.cs
@@ -51,7 +51,7 @@ namespace Umbraco.Core.Models
///
/// Validates that a variation is valid for the content type.
///
- bool ValidateVariation(int? languageId, string segment, bool throwIfInvalid);
+ bool ValidateVariation(string culture, string segment, bool throwIfInvalid);
///
/// Gets or Sets a list of integer Ids of the ContentTypes allowed under the ContentType
diff --git a/src/Umbraco.Core/Models/Property.cs b/src/Umbraco.Core/Models/Property.cs
index 9e3f5fc2e0..709c37daaa 100644
--- a/src/Umbraco.Core/Models/Property.cs
+++ b/src/Umbraco.Core/Models/Property.cs
@@ -18,7 +18,7 @@ namespace Umbraco.Core.Models
{
private List _values = new List();
private PropertyValue _pvalue;
- private Dictionary _vvalues;
+ private Dictionary _vvalues;
private static readonly Lazy Ps = new Lazy();
@@ -38,9 +38,14 @@ namespace Umbraco.Core.Models
public class PropertyValue
{
+ private string _culture;
private string _segment;
- public int? LanguageId { get; internal set; }
+ public string Culture
+ {
+ get => _culture;
+ internal set => _culture = value?.ToLowerInvariant();
+ }
public string Segment
{
get => _segment;
@@ -50,7 +55,7 @@ namespace Umbraco.Core.Models
public object PublishedValue { get; internal set; }
public PropertyValue Clone()
- => new PropertyValue { LanguageId = LanguageId, _segment = _segment, PublishedValue = PublishedValue, EditedValue = EditedValue };
+ => new PropertyValue { _culture = _culture, _segment = _segment, PublishedValue = PublishedValue, EditedValue = EditedValue };
}
// ReSharper disable once ClassNeverInstantiated.Local
@@ -96,10 +101,10 @@ namespace Umbraco.Core.Models
{
// make sure we filter out invalid variations
// make sure we leave _vvalues null if possible
- _values = value.Where(x => PropertyType.ValidateVariation(x.LanguageId, x.Segment, false)).ToList();
- _pvalue = _values.FirstOrDefault(x => !x.LanguageId.HasValue && x.Segment == null);
+ _values = value.Where(x => PropertyType.ValidateVariation(x.Culture, x.Segment, false)).ToList();
+ _pvalue = _values.FirstOrDefault(x => x.Culture == null && x.Segment == null);
_vvalues = _values.Count > (_pvalue == null ? 0 : 1)
- ? _values.Where(x => x != _pvalue).ToDictionary(x => new CompositeIntStringKey(x.LanguageId, x.Segment), x => x)
+ ? _values.Where(x => x != _pvalue).ToDictionary(x => new CompositeStringStringKey(x.Culture, x.Segment), x => x)
: null;
}
}
@@ -128,12 +133,12 @@ namespace Umbraco.Core.Models
///
/// Gets the value.
///
- public object GetValue(int? languageId = null, string segment = null, bool published = false)
+ public object GetValue(string culture = 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 (!PropertyType.ValidateVariation(culture, segment, false)) return null;
+ if (culture == null && segment == null) return GetPropertyValue(_pvalue, published);
if (_vvalues == null) return null;
- return _vvalues.TryGetValue(new CompositeIntStringKey(languageId, segment), out var pvalue)
+ return _vvalues.TryGetValue(new CompositeStringStringKey(culture, segment), out var pvalue)
? GetPropertyValue(pvalue, published)
: null;
}
@@ -159,7 +164,7 @@ namespace Umbraco.Core.Models
if (_vvalues != null)
{
var pvalues = _vvalues
- .Where(x => PropertyType.ValidateVariation(x.Value.LanguageId, x.Value.Segment, false))
+ .Where(x => PropertyType.ValidateVariation(x.Value.Culture, x.Value.Segment, false))
.Select(x => x.Value);
foreach (var pvalue in pvalues)
PublishPropertyValue(pvalue);
@@ -168,29 +173,29 @@ namespace Umbraco.Core.Models
// internal - must be invoked by the content item
// does *not* validate the value - content item must validate first
- internal void PublishValue(int? languageId = null, string segment = null)
+ internal void PublishValue(string culture = null, string segment = null)
{
- PropertyType.ValidateVariation(languageId, segment, true);
+ PropertyType.ValidateVariation(culture, segment, true);
- (var pvalue, _) = GetPValue(languageId, segment, false);
+ (var pvalue, _) = GetPValue(culture, segment, false);
if (pvalue == null) return;
PublishPropertyValue(pvalue);
}
// internal - must be invoked by the content item
// does *not* validate the value - content item must validate first
- internal void PublishCultureValues(int? languageId = null)
+ internal void PublishCultureValues(string culture = null)
{
// if invariant and invariant-neutral is supported, publish invariant-neutral
- if (!languageId.HasValue && PropertyType.ValidateVariation(null, null, false))
+ if (culture == null && 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))
+ .Where(x => x.Value.Culture.InvariantEquals(culture))
+ .Where(x => PropertyType.ValidateVariation(culture, x.Value.Segment, false))
.Select(x => x.Value);
foreach (var pvalue in pvalues)
PublishPropertyValue(pvalue);
@@ -206,7 +211,7 @@ namespace Umbraco.Core.Models
if (_vvalues != null)
{
var pvalues = _vvalues
- .Where(x => PropertyType.ValidateVariation(x.Value.LanguageId, x.Value.Segment, false))
+ .Where(x => PropertyType.ValidateVariation(x.Value.Culture, x.Value.Segment, false))
.Select(x => x.Value);
foreach (var pvalue in pvalues)
ClearPublishedPropertyValue(pvalue);
@@ -214,25 +219,25 @@ namespace Umbraco.Core.Models
}
// internal - must be invoked by the content item
- internal void ClearPublishedValue(int? languageId = null, string segment = null)
+ internal void ClearPublishedValue(string culture = null, string segment = null)
{
- PropertyType.ValidateVariation(languageId, segment, true);
- (var pvalue, _) = GetPValue(languageId, segment, false);
+ PropertyType.ValidateVariation(culture, segment, true);
+ (var pvalue, _) = GetPValue(culture, segment, false);
if (pvalue == null) return;
ClearPublishedPropertyValue(pvalue);
}
// internal - must be invoked by the content item
- internal void ClearPublishedCultureValues(int? languageId = null)
+ internal void ClearPublishedCultureValues(string culture = null)
{
- if (!languageId.HasValue && PropertyType.ValidateVariation(null, null, false))
+ if (culture == null && 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))
+ .Where(x => x.Value.Culture.InvariantEquals(culture))
+ .Where(x => PropertyType.ValidateVariation(culture, x.Value.Segment, false))
.Select(x => x.Value);
foreach (var pvalue in pvalues)
ClearPublishedPropertyValue(pvalue);
@@ -264,10 +269,10 @@ namespace Umbraco.Core.Models
///
/// Sets a value.
///
- public void SetValue(object value, int? languageId = null, string segment = null)
+ public void SetValue(object value, string culture = null, string segment = null)
{
- PropertyType.ValidateVariation(languageId, segment, true);
- (var pvalue, var change) = GetPValue(languageId, segment, true);
+ PropertyType.ValidateVariation(culture, segment, true);
+ (var pvalue, var change) = GetPValue(culture, segment, true);
var origValue = pvalue.EditedValue;
var setValue = PropertyType.ConvertAssignedValue(value);
@@ -278,9 +283,9 @@ namespace Umbraco.Core.Models
}
// 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)
+ internal void FactorySetValue(string culture, string segment, bool published, object value)
{
- (var pvalue, _) = GetPValue(languageId, segment, true);
+ (var pvalue, _) = GetPValue(culture, segment, true);
if (published && PropertyType.IsPublishing)
pvalue.PublishedValue = value;
@@ -301,24 +306,24 @@ namespace Umbraco.Core.Models
return (_pvalue, change);
}
- private (PropertyValue, bool) GetPValue(int? languageId, string segment, bool create)
+ private (PropertyValue, bool) GetPValue(string culture, string segment, bool create)
{
- if (!languageId.HasValue && segment == null)
+ if (culture == null && segment == null)
return GetPValue(create);
var change = false;
if (_vvalues == null)
{
if (!create) return (null, false);
- _vvalues = new Dictionary();
+ _vvalues = new Dictionary();
change = true;
}
- var k = new CompositeIntStringKey(languageId, segment);
+ var k = new CompositeStringStringKey(culture, segment);
if (!_vvalues.TryGetValue(k, out var pvalue))
{
if (!create) return (null, false);
pvalue = _vvalues[k] = new PropertyValue();
- pvalue.LanguageId = languageId;
+ pvalue.Culture = culture;
pvalue.Segment = segment;
_values.Add(pvalue);
change = true;
@@ -343,7 +348,7 @@ namespace Umbraco.Core.Models
if (_vvalues == null) return true;
var pvalues = _vvalues
- .Where(x => PropertyType.ValidateVariation(x.Value.LanguageId, x.Value.Segment, false))
+ .Where(x => PropertyType.ValidateVariation(x.Value.Culture, x.Value.Segment, false))
.Select(x => x.Value)
.ToArray();
@@ -354,11 +359,11 @@ namespace Umbraco.Core.Models
/// 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)
+ public bool IsCultureValid(string culture)
{
// culture-neutral is supported, validate culture-neutral
// includes mandatory validation
- if (PropertyType.ValidateVariation(languageId, null, false) && !IsValidValue(GetValue(languageId)))
+ if (PropertyType.ValidateVariation(culture, null, false) && !IsValidValue(GetValue(culture)))
return false;
// either culture-neutral is not supported, or it is valid
@@ -368,8 +373,8 @@ namespace Umbraco.Core.Models
if (_vvalues == null) return true;
var pvalues = _vvalues
- .Where(x => x.Value.LanguageId == languageId)
- .Where(x => PropertyType.ValidateVariation(languageId, x.Value.Segment, false))
+ .Where(x => x.Value.Culture.InvariantEquals(culture))
+ .Where(x => PropertyType.ValidateVariation(culture, x.Value.Segment, false))
.Select(x => x.Value)
.ToArray();
@@ -380,10 +385,10 @@ namespace Umbraco.Core.Models
/// 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)
+ public bool IsValid(string culture = null, string segment = null)
{
// single value -> validates mandatory
- return IsValidValue(GetValue(languageId, segment));
+ return IsValidValue(GetValue(culture, segment));
}
///
diff --git a/src/Umbraco.Core/Models/PropertyType.cs b/src/Umbraco.Core/Models/PropertyType.cs
index 8c5e318719..b34eca7c57 100644
--- a/src/Umbraco.Core/Models/PropertyType.cs
+++ b/src/Umbraco.Core/Models/PropertyType.cs
@@ -226,10 +226,10 @@ namespace Umbraco.Core.Models
///
/// Validates that a variation is valid for the property type.
///
- public bool ValidateVariation(int? languageId, string segment, bool throwIfInvalid)
+ public bool ValidateVariation(string culture, string segment, bool throwIfInvalid)
{
ContentVariation variation;
- if (languageId.HasValue)
+ if (culture != null)
{
variation = segment != null
? ContentVariation.CultureSegment
diff --git a/src/Umbraco.Core/Models/PublishedContent/IPublishedProperty.cs b/src/Umbraco.Core/Models/PublishedContent/IPublishedProperty.cs
index 24c654604c..9d2cca3e6d 100644
--- a/src/Umbraco.Core/Models/PublishedContent/IPublishedProperty.cs
+++ b/src/Umbraco.Core/Models/PublishedContent/IPublishedProperty.cs
@@ -21,7 +21,7 @@
/// Other caches that get their raw value from the database would consider that a property has "no
/// value" if it is missing, null, or an empty string (including whitespace-only).
///
- bool HasValue(int? languageId = null, string segment = null);
+ bool HasValue(string culture = null, string segment = null);
///
/// Gets the source value of the property.
@@ -35,7 +35,7 @@
/// If you're using that value, you're probably wrong, unless you're doing some internal
/// Umbraco stuff.
///
- object GetSourceValue(int? languageId = null, string segment = null);
+ object GetSourceValue(string culture = null, string segment = null);
///
/// Gets the object value of the property.
@@ -45,7 +45,7 @@
/// It can be null, or any type of CLR object.
/// It has been fully prepared and processed by the appropriate converter.
///
- object GetValue(int? languageId = null, string segment = null);
+ object GetValue(string culture = null, string segment = null);
///
/// Gets the XPath value of the property.
@@ -55,6 +55,6 @@
/// It must be either null, or a string, or an XPathNavigator.
/// It has been fully prepared and processed by the appropriate converter.
///
- object GetXPathValue(int? languageId = null, string segment = null);
+ object GetXPathValue(string culture = null, string segment = null);
}
}
diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedPropertyBase.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedPropertyBase.cs
index 918bdb86e4..7e2a5b5498 100644
--- a/src/Umbraco.Core/Models/PublishedContent/PublishedPropertyBase.cs
+++ b/src/Umbraco.Core/Models/PublishedContent/PublishedPropertyBase.cs
@@ -53,15 +53,15 @@ namespace Umbraco.Core.Models.PublishedContent
public string Alias => PropertyType.Alias;
///
- public abstract bool HasValue(int? languageId = null, string segment = null);
+ public abstract bool HasValue(string culture = null, string segment = null);
///
- public abstract object GetSourceValue(int? languageId = null, string segment = null);
+ public abstract object GetSourceValue(string culture = null, string segment = null);
///
- public abstract object GetValue(int? languageId = null, string segment = null);
+ public abstract object GetValue(string culture = null, string segment = null);
///
- public abstract object GetXPathValue(int? languageId = null, string segment = null);
+ public abstract object GetXPathValue(string culture = null, string segment = null);
}
}
diff --git a/src/Umbraco.Core/Models/PublishedContent/RawValueProperty.cs b/src/Umbraco.Core/Models/PublishedContent/RawValueProperty.cs
index f938880060..e20d8cb49c 100644
--- a/src/Umbraco.Core/Models/PublishedContent/RawValueProperty.cs
+++ b/src/Umbraco.Core/Models/PublishedContent/RawValueProperty.cs
@@ -20,20 +20,20 @@ namespace Umbraco.Core.Models.PublishedContent
private readonly Lazy
internal class LanguageRepository : NPocoRepositoryBase, ILanguageRepository
{
- private readonly Dictionary _codeIdMap = new Dictionary();
+ private readonly Dictionary _codeIdMap = new Dictionary(StringComparer.OrdinalIgnoreCase);
private readonly Dictionary _idCodeMap = new Dictionary();
public LanguageRepository(IScopeAccessor scopeAccessor, CacheHelper cache, ILogger logger)
@@ -62,7 +62,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
foreach (var language in languages)
{
_codeIdMap[language.IsoCode] = language.Id;
- _idCodeMap[language.Id] = language.IsoCode;
+ _idCodeMap[language.Id] = language.IsoCode.ToLowerInvariant();
}
}
@@ -211,15 +211,17 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
{
TypedCachePolicy.GetAllCached(PerformGetAll); // ensure cache is populated, in a non-expensive way
var id = GetIdByIsoCode(isoCode, throwOnNotFound: false);
- return id > 0 ? Get(id) : null;
+ return id.HasValue ? Get(id.Value) : null;
}
// fast way of getting an id for an isoCode - avoiding cloning
// _codeIdMap is rebuilt whenever PerformGetAll runs
- public int GetIdByIsoCode(string isoCode) => GetIdByIsoCode(isoCode, throwOnNotFound: true);
+ public int? GetIdByIsoCode(string isoCode) => GetIdByIsoCode(isoCode, throwOnNotFound: true);
- private int GetIdByIsoCode(string isoCode, bool throwOnNotFound)
+ private int? GetIdByIsoCode(string isoCode, bool throwOnNotFound)
{
+ if (isoCode == null) return null;
+
TypedCachePolicy.GetAllCached(PerformGetAll); // ensure cache is populated, in a non-expensive way
lock (_codeIdMap)
{
@@ -232,14 +234,16 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
// fast way of getting an isoCode for an id - avoiding cloning
// _idCodeMap is rebuilt whenever PerformGetAll runs
- public string GetIsoCodeById(int id) => GetIsoCodeById(id, throwOnNotFound: true);
+ public string GetIsoCodeById(int? id) => GetIsoCodeById(id, throwOnNotFound: true);
- private string GetIsoCodeById(int id, bool throwOnNotFound)
+ private string GetIsoCodeById(int? id, bool throwOnNotFound)
{
+ if (id == null) return null;
+
TypedCachePolicy.GetAllCached(PerformGetAll); // ensure cache is populated, in a non-expensive way
lock (_codeIdMap) // yes, we want to lock _codeIdMap
{
- if (_idCodeMap.TryGetValue(id, out var isoCode)) return isoCode;
+ if (_idCodeMap.TryGetValue(id.Value, out var isoCode)) return isoCode;
}
if (throwOnNotFound)
throw new ArgumentException($"Id {id} does not correspond to an existing language.", nameof(id));
diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/MediaRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/MediaRepository.cs
index a08ecef98d..dfb30a9cb3 100644
--- a/src/Umbraco.Core/Persistence/Repositories/Implement/MediaRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/Implement/MediaRepository.cs
@@ -25,8 +25,8 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
private readonly ITagRepository _tagRepository;
private readonly MediaByGuidReadRepository _mediaByGuidReadRepository;
- public MediaRepository(IScopeAccessor scopeAccessor, CacheHelper cache, ILogger logger, IMediaTypeRepository mediaTypeRepository, ITagRepository tagRepository, IContentSection contentSection)
- : base(scopeAccessor, cache, logger)
+ public MediaRepository(IScopeAccessor scopeAccessor, CacheHelper cache, ILogger logger, IMediaTypeRepository mediaTypeRepository, ITagRepository tagRepository, IContentSection contentSection, ILanguageRepository languageRepository)
+ : base(scopeAccessor, cache, languageRepository, logger)
{
_mediaTypeRepository = mediaTypeRepository ?? throw new ArgumentNullException(nameof(mediaTypeRepository));
_tagRepository = tagRepository ?? throw new ArgumentNullException(nameof(tagRepository));
@@ -279,7 +279,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
Database.Insert(mediaVersionDto);
// persist the property data
- var propertyDataDtos = PropertyFactory.BuildDtos(media.VersionId, 0, entity.Properties, out _);
+ var propertyDataDtos = PropertyFactory.BuildDtos(media.VersionId, 0, entity.Properties, LanguageRepository, out _);
foreach (var propertyDataDto in propertyDataDtos)
Database.Insert(propertyDataDto);
@@ -336,7 +336,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
// replace the property data
var deletePropertyDataSql = SqlContext.Sql().Delete().Where(x => x.VersionId == media.VersionId);
Database.Execute(deletePropertyDataSql);
- var propertyDataDtos = PropertyFactory.BuildDtos(media.VersionId, 0, entity.Properties, out _);
+ var propertyDataDtos = PropertyFactory.BuildDtos(media.VersionId, 0, entity.Properties, LanguageRepository, out _);
foreach (var propertyDataDto in propertyDataDtos)
Database.Insert(propertyDataDto);
diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/MemberRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/MemberRepository.cs
index 67dbf758db..04e5d64b06 100644
--- a/src/Umbraco.Core/Persistence/Repositories/Implement/MemberRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/Implement/MemberRepository.cs
@@ -23,8 +23,8 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
private readonly ITagRepository _tagRepository;
private readonly IMemberGroupRepository _memberGroupRepository;
- public MemberRepository(IScopeAccessor scopeAccessor, CacheHelper cache, ILogger logger, IMemberTypeRepository memberTypeRepository, IMemberGroupRepository memberGroupRepository, ITagRepository tagRepository)
- : base(scopeAccessor, cache, logger)
+ public MemberRepository(IScopeAccessor scopeAccessor, CacheHelper cache, ILogger logger, IMemberTypeRepository memberTypeRepository, IMemberGroupRepository memberGroupRepository, ITagRepository tagRepository, ILanguageRepository languageRepository)
+ : base(scopeAccessor, cache, languageRepository, logger)
{
_memberTypeRepository = memberTypeRepository ?? throw new ArgumentNullException(nameof(memberTypeRepository));
_tagRepository = tagRepository ?? throw new ArgumentNullException(nameof(tagRepository));
@@ -306,7 +306,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
Database.Insert(dto);
// persist the property data
- var propertyDataDtos = PropertyFactory.BuildDtos(member.VersionId, 0, entity.Properties, out _);
+ var propertyDataDtos = PropertyFactory.BuildDtos(member.VersionId, 0, entity.Properties, LanguageRepository, out _);
foreach (var propertyDataDto in propertyDataDtos)
Database.Insert(propertyDataDto);
@@ -371,7 +371,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
// replace the property data
var deletePropertyDataSql = SqlContext.Sql().Delete().Where(x => x.VersionId == member.VersionId);
Database.Execute(deletePropertyDataSql);
- var propertyDataDtos = PropertyFactory.BuildDtos(member.VersionId, 0, entity.Properties, out _);
+ var propertyDataDtos = PropertyFactory.BuildDtos(member.VersionId, 0, entity.Properties, LanguageRepository, out _);
foreach (var propertyDataDto in propertyDataDtos)
Database.Insert(propertyDataDto);
diff --git a/src/Umbraco.Core/PropertyEditors/DataValueEditor.cs b/src/Umbraco.Core/PropertyEditors/DataValueEditor.cs
index ea95f8708f..f235a95aa8 100644
--- a/src/Umbraco.Core/PropertyEditors/DataValueEditor.cs
+++ b/src/Umbraco.Core/PropertyEditors/DataValueEditor.cs
@@ -272,16 +272,16 @@ namespace Umbraco.Core.PropertyEditors
///
///
///
- ///
+ ///
///
///
///
/// The object returned will automatically be serialized into json notation. For most property editors
/// the value returned is probably just a string but in some cases a json structure will be returned.
///
- public virtual object ToEditor(Property property, IDataTypeService dataTypeService, int? languageId = null, string segment = null)
+ public virtual object ToEditor(Property property, IDataTypeService dataTypeService, string culture = null, string segment = null)
{
- var val = property.GetValue(languageId, segment);
+ var val = property.GetValue(culture, segment);
if (val == null) return string.Empty;
switch (ValueTypes.ToStorageType(ValueType))
@@ -343,12 +343,8 @@ namespace Umbraco.Core.PropertyEditors
continue;
var xElement = new XElement(nodeName);
- if (pvalue.LanguageId.HasValue)
- {
- var language = localizationService.GetLanguageById(pvalue.LanguageId.Value);
- if (language == null) continue; // uh?
- xElement.Add(new XAttribute("lang", language.IsoCode));
- }
+ if (pvalue.Culture != null)
+ xElement.Add(new XAttribute("lang", pvalue.Culture));
if (pvalue.Segment != null)
xElement.Add(new XAttribute("segment", pvalue.Segment));
diff --git a/src/Umbraco.Core/PropertyEditors/IDataValueEditor.cs b/src/Umbraco.Core/PropertyEditors/IDataValueEditor.cs
index 9e31f94121..b5ed7c5917 100644
--- a/src/Umbraco.Core/PropertyEditors/IDataValueEditor.cs
+++ b/src/Umbraco.Core/PropertyEditors/IDataValueEditor.cs
@@ -61,7 +61,7 @@ namespace Umbraco.Core.PropertyEditors
///
/// Converts a property value to a value for the editor.
///
- object ToEditor(Property property, IDataTypeService dataTypeService, int? languageId = null, string segment = null);
+ object ToEditor(Property property, IDataTypeService dataTypeService, string culture = null, string segment = null);
// fixme - editing - document or remove these
// why property vs propertyType? services should be injected! etc...
diff --git a/src/Umbraco.Core/Services/IContentService.cs b/src/Umbraco.Core/Services/IContentService.cs
index cb56b39e2c..abbab0ef39 100644
--- a/src/Umbraco.Core/Services/IContentService.cs
+++ b/src/Umbraco.Core/Services/IContentService.cs
@@ -354,7 +354,7 @@ namespace Umbraco.Core.Services
///
/// Saves and publishes a document branch.
///
- IEnumerable SaveAndPublishBranch(IContent content, bool force, int? languageId = null, string segment = null, int userId = 0);
+ IEnumerable SaveAndPublishBranch(IContent content, bool force, string culture = null, string segment = null, int userId = 0);
///
/// Saves and publishes a document branch.
diff --git a/src/Umbraco.Core/Services/ILocalizationService.cs b/src/Umbraco.Core/Services/ILocalizationService.cs
index d61ee5e310..cda28d2818 100644
--- a/src/Umbraco.Core/Services/ILocalizationService.cs
+++ b/src/Umbraco.Core/Services/ILocalizationService.cs
@@ -120,7 +120,7 @@ namespace Umbraco.Core.Services
///
/// Gets a language identifier by its iso code.
///
- int GetLanguageIdByIsoCode(string isoCode);
+ int? GetLanguageIdByIsoCode(string isoCode);
///
/// Gets all available languages
diff --git a/src/Umbraco.Core/Services/Implement/ContentService.cs b/src/Umbraco.Core/Services/Implement/ContentService.cs
index bfa6c5916d..84e616d4d7 100644
--- a/src/Umbraco.Core/Services/Implement/ContentService.cs
+++ b/src/Umbraco.Core/Services/Implement/ContentService.cs
@@ -1103,14 +1103,14 @@ namespace Umbraco.Core.Services.Implement
}
///
- public IEnumerable SaveAndPublishBranch(IContent content, bool force, int? languageId = null, string segment = null, int userId = 0)
+ public IEnumerable SaveAndPublishBranch(IContent content, bool force, string culture = null, string segment = null, int userId = 0)
{
segment = segment?.ToLowerInvariant();
- bool IsEditing(IContent c, int? l, string s)
- => c.Properties.Any(x => x.Values.Where(y => y.LanguageId == l && y.Segment == s).Any(y => y.EditedValue != y.PublishedValue));
+ bool IsEditing(IContent c, string l, string s)
+ => c.Properties.Any(x => x.Values.Where(y => y.Culture == l && y.Segment == s).Any(y => y.EditedValue != y.PublishedValue));
- return SaveAndPublishBranch(content, force, document => IsEditing(document, languageId, segment), document => document.PublishValues(languageId, segment), userId);
+ return SaveAndPublishBranch(content, force, document => IsEditing(document, culture, segment), document => document.PublishValues(culture, segment), userId);
}
///
diff --git a/src/Umbraco.Core/Services/Implement/LocalizationService.cs b/src/Umbraco.Core/Services/Implement/LocalizationService.cs
index bf01605416..104268f5e8 100644
--- a/src/Umbraco.Core/Services/Implement/LocalizationService.cs
+++ b/src/Umbraco.Core/Services/Implement/LocalizationService.cs
@@ -317,7 +317,7 @@ namespace Umbraco.Core.Services.Implement
}
///
- public int GetLanguageIdByIsoCode(string isoCode)
+ public int? GetLanguageIdByIsoCode(string isoCode)
{
using (ScopeProvider.CreateScope(autoComplete: true))
{
diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj
index 77b78f355d..7549d4ba2b 100644
--- a/src/Umbraco.Core/Umbraco.Core.csproj
+++ b/src/Umbraco.Core/Umbraco.Core.csproj
@@ -137,6 +137,7 @@
+
diff --git a/src/Umbraco.Tests/Composing/TypeLoaderTests.cs b/src/Umbraco.Tests/Composing/TypeLoaderTests.cs
index 8965d60018..6fba071709 100644
--- a/src/Umbraco.Tests/Composing/TypeLoaderTests.cs
+++ b/src/Umbraco.Tests/Composing/TypeLoaderTests.cs
@@ -286,7 +286,7 @@ AnotherContentFinder
public void GetDataEditors()
{
var types = _typeLoader.GetDataEditors();
- Assert.AreEqual(42, types.Count());
+ Assert.AreEqual(43, types.Count());
}
[Test]
diff --git a/src/Umbraco.Tests/Models/VariationTests.cs b/src/Umbraco.Tests/Models/VariationTests.cs
index 3b293621d5..70e3d574b3 100644
--- a/src/Umbraco.Tests/Models/VariationTests.cs
+++ b/src/Umbraco.Tests/Models/VariationTests.cs
@@ -65,6 +65,8 @@ namespace Umbraco.Tests.Models
var propertyType = new PropertyType("editor", ValueStorageType.Nvarchar) { Alias = "prop" };
var prop = new Property(propertyType);
+ const string langFr = "fr-FR";
+
// can set value
// and get edited and published value
// because non-publishing
@@ -84,8 +86,8 @@ namespace Umbraco.Tests.Models
Assert.IsNull(prop.GetValue(published: true));
// cannot set non-supported variation value
- Assert.Throws(() => prop.SetValue("x", 1));
- Assert.IsNull(prop.GetValue(1));
+ Assert.Throws(() => prop.SetValue("x", langFr));
+ Assert.IsNull(prop.GetValue(langFr));
// can publish value
// and get edited and published values
@@ -109,41 +111,41 @@ namespace Umbraco.Tests.Models
// can set value
// and get values
- prop.SetValue("c", 1);
+ prop.SetValue("c", langFr);
Assert.AreEqual("b", prop.GetValue());
Assert.IsNull(prop.GetValue(published: true));
- Assert.AreEqual("c", prop.GetValue(1));
- Assert.IsNull(prop.GetValue(1, published: true));
+ Assert.AreEqual("c", prop.GetValue(langFr));
+ Assert.IsNull(prop.GetValue(langFr, published: true));
// can publish value
// and get edited and published values
- prop.PublishValue(1);
+ prop.PublishValue(langFr);
Assert.AreEqual("b", prop.GetValue());
Assert.IsNull(prop.GetValue(published: true));
- Assert.AreEqual("c", prop.GetValue(1));
- Assert.AreEqual("c", prop.GetValue(1, published: true));
+ Assert.AreEqual("c", prop.GetValue(langFr));
+ Assert.AreEqual("c", prop.GetValue(langFr, published: true));
// can clear all
prop.ClearPublishedAllValues();
Assert.AreEqual("b", prop.GetValue());
Assert.IsNull(prop.GetValue(published: true));
- Assert.AreEqual("c", prop.GetValue(1));
- Assert.IsNull(prop.GetValue(1, published: true));
+ Assert.AreEqual("c", prop.GetValue(langFr));
+ Assert.IsNull(prop.GetValue(langFr, published: true));
// can publish all
prop.PublishAllValues();
Assert.AreEqual("b", prop.GetValue());
Assert.AreEqual("b", prop.GetValue(published: true));
- Assert.AreEqual("c", prop.GetValue(1));
- Assert.AreEqual("c", prop.GetValue(1, published: true));
+ Assert.AreEqual("c", prop.GetValue(langFr));
+ Assert.AreEqual("c", prop.GetValue(langFr, published: true));
// same for culture
- prop.ClearPublishedCultureValues(1);
- Assert.AreEqual("c", prop.GetValue(1));
- Assert.IsNull(prop.GetValue(1, published: true));
- prop.PublishCultureValues(1);
- Assert.AreEqual("c", prop.GetValue(1));
- Assert.AreEqual("c", prop.GetValue(1, published: true));
+ prop.ClearPublishedCultureValues(langFr);
+ Assert.AreEqual("c", prop.GetValue(langFr));
+ Assert.IsNull(prop.GetValue(langFr, published: true));
+ prop.PublishCultureValues(langFr);
+ Assert.AreEqual("c", prop.GetValue(langFr));
+ Assert.AreEqual("c", prop.GetValue(langFr, published: true));
prop.ClearPublishedCultureValues();
Assert.AreEqual("b", prop.GetValue());
@@ -159,8 +161,8 @@ namespace Umbraco.Tests.Models
var contentType = new ContentType(-1) { Alias = "contentType" };
var content = new Content("content", -1, contentType) { Id = 1, VersionId = 1 };
- const int langFr = 1;
- const int langUk = 2;
+ const string langFr = "fr-FR";
+ const string langUk = "en-UK";
Assert.Throws(() => content.SetName(langFr, "name-fr"));
@@ -188,6 +190,8 @@ namespace Umbraco.Tests.Models
[Test]
public void ContentTests()
{
+ const string langFr = "fr-FR";
+
var propertyType = new PropertyType("editor", ValueStorageType.Nvarchar) { Alias = "prop" };
var contentType = new ContentType(-1) { Alias = "contentType" };
contentType.AddPropertyType(propertyType);
@@ -202,8 +206,8 @@ namespace Umbraco.Tests.Models
Assert.IsNull(content.GetValue("prop", published: true));
// cannot set non-supported variation value
- Assert.Throws(() => content.SetValue("prop", "x", 1));
- Assert.IsNull(content.GetValue("prop", 1));
+ Assert.Throws(() => content.SetValue("prop", "x", langFr));
+ Assert.IsNull(content.GetValue("prop", langFr));
// can publish value
// and get edited and published values
@@ -228,41 +232,43 @@ namespace Umbraco.Tests.Models
// can set value
// and get values
- content.SetValue("prop", "c", 1);
+ content.SetValue("prop", "c", langFr);
Assert.AreEqual("b", content.GetValue("prop"));
Assert.IsNull(content.GetValue("prop", published: true));
- Assert.AreEqual("c", content.GetValue("prop", 1));
- Assert.IsNull(content.GetValue("prop", 1, published: true));
+ Assert.AreEqual("c", content.GetValue("prop", langFr));
+ Assert.IsNull(content.GetValue("prop", langFr, published: true));
// can publish value
// and get edited and published values
- content.PublishValues(1);
+ Assert.Throws(() => content.PublishValues(langFr)); // no name
+ content.SetName(langFr, "name-fr");
+ content.PublishValues(langFr);
Assert.AreEqual("b", content.GetValue("prop"));
Assert.IsNull(content.GetValue("prop", published: true));
- Assert.AreEqual("c", content.GetValue("prop", 1));
- Assert.AreEqual("c", content.GetValue("prop", 1, published: true));
+ Assert.AreEqual("c", content.GetValue("prop", langFr));
+ Assert.AreEqual("c", content.GetValue("prop", langFr, published: true));
// can clear all
content.ClearAllPublishedValues();
Assert.AreEqual("b", content.GetValue("prop"));
Assert.IsNull(content.GetValue("prop", published: true));
- Assert.AreEqual("c", content.GetValue("prop", 1));
- Assert.IsNull(content.GetValue("prop", 1, published: true));
+ Assert.AreEqual("c", content.GetValue("prop", langFr));
+ Assert.IsNull(content.GetValue("prop", langFr, published: true));
// can publish all
content.PublishAllValues();
Assert.AreEqual("b", content.GetValue("prop"));
Assert.AreEqual("b", content.GetValue("prop", published: true));
- Assert.AreEqual("c", content.GetValue("prop", 1));
- Assert.AreEqual("c", content.GetValue("prop", 1, published: true));
+ Assert.AreEqual("c", content.GetValue("prop", langFr));
+ Assert.AreEqual("c", content.GetValue("prop", langFr, published: true));
// same for culture
- content.ClearCulturePublishedValues(1);
- Assert.AreEqual("c", content.GetValue("prop", 1));
- Assert.IsNull(content.GetValue("prop", 1, published: true));
- content.PublishCultureValues(1);
- Assert.AreEqual("c", content.GetValue("prop", 1));
- Assert.AreEqual("c", content.GetValue("prop", 1, published: true));
+ content.ClearCulturePublishedValues(langFr);
+ Assert.AreEqual("c", content.GetValue("prop", langFr));
+ Assert.IsNull(content.GetValue("prop", langFr, published: true));
+ content.PublishCultureValues(langFr);
+ Assert.AreEqual("c", content.GetValue("prop", langFr));
+ Assert.AreEqual("c", content.GetValue("prop", langFr, published: true));
content.ClearCulturePublishedValues();
Assert.AreEqual("b", content.GetValue("prop"));
@@ -273,21 +279,21 @@ namespace Umbraco.Tests.Models
var other = new Content("other", -1, contentType) { Id = 2, VersionId = 1 };
other.SetValue("prop", "o");
- other.SetValue("prop", "o1", 1);
+ other.SetValue("prop", "o1", langFr);
// can copy other's edited value
content.CopyAllValues(other);
Assert.AreEqual("o", content.GetValue("prop"));
Assert.AreEqual("b", content.GetValue("prop", published: true));
- Assert.AreEqual("o1", content.GetValue("prop", 1));
- Assert.AreEqual("c", content.GetValue("prop", 1, published: true));
+ Assert.AreEqual("o1", content.GetValue("prop", langFr));
+ Assert.AreEqual("c", content.GetValue("prop", langFr, published: true));
// can copy self's published value
content.CopyAllValues(content);
Assert.AreEqual("b", content.GetValue("prop"));
Assert.AreEqual("b", content.GetValue("prop", published: true));
- Assert.AreEqual("c", content.GetValue("prop", 1));
- Assert.AreEqual("c", content.GetValue("prop", 1, published: true));
+ Assert.AreEqual("c", content.GetValue("prop", langFr));
+ Assert.AreEqual("c", content.GetValue("prop", langFr, published: true));
}
[Test]
diff --git a/src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs
index 2e72a2e14c..53985b7897 100644
--- a/src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs
+++ b/src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs
@@ -36,7 +36,7 @@ namespace Umbraco.Tests.Persistence.Repositories
mediaTypeRepository = new MediaTypeRepository(scopeAccessor, cacheHelper, Logger);
var tagRepository = new TagRepository(scopeAccessor, cacheHelper, Logger);
- var repository = new MediaRepository(scopeAccessor, cacheHelper, Logger, mediaTypeRepository, tagRepository, Mock.Of());
+ var repository = new MediaRepository(scopeAccessor, cacheHelper, Logger, mediaTypeRepository, tagRepository, Mock.Of(), Mock.Of());
return repository;
}
diff --git a/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs
index 4f901935dc..d07d2dda9a 100644
--- a/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs
+++ b/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs
@@ -31,7 +31,7 @@ namespace Umbraco.Tests.Persistence.Repositories
memberTypeRepository = new MemberTypeRepository(accessor, DisabledCache, Logger);
memberGroupRepository = new MemberGroupRepository(accessor, DisabledCache, Logger);
var tagRepo = new TagRepository(accessor, DisabledCache, Logger);
- var repository = new MemberRepository(accessor, DisabledCache, Logger, memberTypeRepository, memberGroupRepository, tagRepo);
+ var repository = new MemberRepository(accessor, DisabledCache, Logger, memberTypeRepository, memberGroupRepository, tagRepo, Mock.Of());
return repository;
}
diff --git a/src/Umbraco.Tests/Persistence/Repositories/TagRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/TagRepositoryTest.cs
index 216fb08ecd..90230e15c7 100644
--- a/src/Umbraco.Tests/Persistence/Repositories/TagRepositoryTest.cs
+++ b/src/Umbraco.Tests/Persistence/Repositories/TagRepositoryTest.cs
@@ -4,6 +4,7 @@ using NUnit.Framework;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.IO;
using Umbraco.Core.Models;
+using Umbraco.Core.Persistence.Repositories;
using Umbraco.Core.Persistence.Repositories.Implement;
using Umbraco.Core.Scoping;
using Umbraco.Tests.TestHelpers;
@@ -964,7 +965,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var accessor = (IScopeAccessor) provider;
var tagRepository = new TagRepository(accessor, DisabledCache, Logger);
mediaTypeRepository = new MediaTypeRepository(accessor, DisabledCache, Logger);
- var repository = new MediaRepository(accessor, DisabledCache, Logger, mediaTypeRepository, tagRepository, Mock.Of());
+ var repository = new MediaRepository(accessor, DisabledCache, Logger, mediaTypeRepository, tagRepository, Mock.Of(), Mock.Of());
return repository;
}
}
diff --git a/src/Umbraco.Tests/Persistence/Repositories/UserRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/UserRepositoryTest.cs
index 56d5bfbc0c..2688629c5c 100644
--- a/src/Umbraco.Tests/Persistence/Repositories/UserRepositoryTest.cs
+++ b/src/Umbraco.Tests/Persistence/Repositories/UserRepositoryTest.cs
@@ -26,7 +26,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var accessor = (IScopeAccessor) provider;
mediaTypeRepository = new MediaTypeRepository(accessor, CacheHelper, Mock.Of());
var tagRepository = new TagRepository(accessor, CacheHelper, Mock.Of());
- var repository = new MediaRepository(accessor, CacheHelper, Mock.Of(), mediaTypeRepository, tagRepository, Mock.Of());
+ var repository = new MediaRepository(accessor, CacheHelper, Mock.Of(), mediaTypeRepository, tagRepository, Mock.Of(), Mock.Of());
return repository;
}
diff --git a/src/Umbraco.Tests/Published/NestedContentTests.cs b/src/Umbraco.Tests/Published/NestedContentTests.cs
index a916a2d51e..22e110dd20 100644
--- a/src/Umbraco.Tests/Published/NestedContentTests.cs
+++ b/src/Umbraco.Tests/Published/NestedContentTests.cs
@@ -242,10 +242,10 @@ namespace Umbraco.Tests.Published
_owner = owner;
}
- public override bool HasValue(int? languageId = null, string segment = null) => _hasValue;
- public override object GetSourceValue(int? languageId = null, string segment = null) => _sourceValue;
- public override object GetValue(int? languageId = null, string segment = null) => PropertyType.ConvertInterToObject(_owner, ReferenceCacheLevel, InterValue, _preview);
- public override object GetXPathValue(int? languageId = null, string segment = null) => throw new WontImplementException();
+ public override bool HasValue(string culture = null, string segment = null) => _hasValue;
+ public override object GetSourceValue(string culture = null, string segment = null) => _sourceValue;
+ public override object GetValue(string culture = null, string segment = null) => PropertyType.ConvertInterToObject(_owner, ReferenceCacheLevel, InterValue, _preview);
+ public override object GetXPathValue(string culture = null, string segment = null) => throw new WontImplementException();
}
class TestPublishedContent : PublishedContentBase
diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentTestElements.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentTestElements.cs
index 8f6ee5c2b1..7a6c684eb4 100644
--- a/src/Umbraco.Tests/PublishedContent/PublishedContentTestElements.cs
+++ b/src/Umbraco.Tests/PublishedContent/PublishedContentTestElements.cs
@@ -256,10 +256,10 @@ namespace Umbraco.Tests.PublishedContent
public bool SolidHasValue { get; set; }
public object SolidXPathValue { get; set; }
- public object GetSourceValue(int? languageId = null, string segment = null) => SolidSourceValue;
- public object GetValue(int? languageId = null, string segment = null) => SolidValue;
- public object GetXPathValue(int? languageId = null, string segment = null) => SolidXPathValue;
- public bool HasValue(int? languageId = null, string segment = null) => SolidHasValue;
+ public object GetSourceValue(string culture = null, string segment = null) => SolidSourceValue;
+ public object GetValue(string culture = null, string segment = null) => SolidValue;
+ public object GetXPathValue(string culture = null, string segment = null) => SolidXPathValue;
+ public bool HasValue(string culture = null, string segment = null) => SolidHasValue;
}
[PublishedModel("ContentType2")]
diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs
index 0e726064f4..04ed54d81c 100644
--- a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs
+++ b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs
@@ -356,7 +356,7 @@ namespace Umbraco.Tests.PublishedContent
var result = doc.Ancestors().OrderBy(x => x.Level)
.Single()
.Descendants()
- .FirstOrDefault(x => x.Value("selectedNodes", "").Split(',').Contains("1173"));
+ .FirstOrDefault(x => x.Value("selectedNodes", defaultValue: "").Split(',').Contains("1173"));
Assert.IsNotNull(result);
}
diff --git a/src/Umbraco.Tests/Services/ContentServiceTests.cs b/src/Umbraco.Tests/Services/ContentServiceTests.cs
index 79929ff29d..b3bdf4f1ba 100644
--- a/src/Umbraco.Tests/Services/ContentServiceTests.cs
+++ b/src/Umbraco.Tests/Services/ContentServiceTests.cs
@@ -2506,200 +2506,200 @@ namespace Umbraco.Tests.Services
var contentService = ServiceContext.ContentService;
var content = contentService.Create("Home US", - 1, "umbTextpage");
- // act
+ // act
- content.SetValue("author", "Barack Obama");
- content.SetValue("prop", "value-fr1", langFr.Id);
- content.SetValue("prop", "value-uk1", langUk.Id);
- content.SetName(langFr.Id, "name-fr");
- content.SetName(langUk.Id, "name-uk");
- contentService.Save(content);
+ content.SetValue("author", "Barack Obama");
+ content.SetValue("prop", "value-fr1", langFr.IsoCode);
+ content.SetValue("prop", "value-uk1", langUk.IsoCode);
+ content.SetName(langFr.IsoCode, "name-fr");
+ content.SetName(langUk.IsoCode, "name-uk");
+ contentService.Save(content);
- // content has been saved,
- // it has names, but no publishNames, and no published cultures
+ // content has been saved,
+ // it has names, but no publishNames, and no published cultures
- var content2 = contentService.GetById(content.Id);
+ var content2 = contentService.GetById(content.Id);
- Assert.AreEqual("Home US", content2.Name);
- Assert.AreEqual("name-fr", content2.GetName(langFr.Id));
- Assert.AreEqual("name-uk", content2.GetName(langUk.Id));
+ Assert.AreEqual("Home US", content2.Name);
+ Assert.AreEqual("name-fr", content2.GetName(langFr.IsoCode));
+ Assert.AreEqual("name-uk", content2.GetName(langUk.IsoCode));
- Assert.AreEqual("value-fr1", content2.GetValue("prop", langFr.Id));
- Assert.AreEqual("value-uk1", content2.GetValue("prop", langUk.Id));
- Assert.IsNull(content2.GetValue("prop", langFr.Id, published: true));
- Assert.IsNull(content2.GetValue("prop", langUk.Id, published: true));
+ Assert.AreEqual("value-fr1", content2.GetValue("prop", langFr.IsoCode));
+ Assert.AreEqual("value-uk1", content2.GetValue("prop", langUk.IsoCode));
+ Assert.IsNull(content2.GetValue("prop", langFr.IsoCode, published: true));
+ Assert.IsNull(content2.GetValue("prop", langUk.IsoCode, published: true));
- Assert.IsNull(content2.PublishName);
- Assert.IsNull(content2.GetPublishName(langFr.Id));
- Assert.IsNull(content2.GetPublishName(langUk.Id));
+ Assert.IsNull(content2.PublishName);
+ Assert.IsNull(content2.GetPublishName(langFr.IsoCode));
+ Assert.IsNull(content2.GetPublishName(langUk.IsoCode));
- Assert.IsTrue(content.IsCultureAvailable(langFr.Id));
- Assert.IsTrue(content.IsCultureAvailable(langUk.Id));
- Assert.IsFalse(content.IsCultureAvailable(langDe.Id));
+ Assert.IsTrue(content.IsCultureAvailable(langFr.IsoCode));
+ Assert.IsTrue(content.IsCultureAvailable(langUk.IsoCode));
+ Assert.IsFalse(content.IsCultureAvailable(langDe.IsoCode));
- Assert.IsFalse(content.IsCulturePublished(langFr.Id));
- Assert.IsFalse(content.IsCulturePublished(langUk.Id));
+ Assert.IsFalse(content.IsCulturePublished(langFr.IsoCode));
+ Assert.IsFalse(content.IsCulturePublished(langUk.IsoCode));
- // act
+ // act
- content.PublishValues(langFr.Id);
- content.PublishValues(langUk.Id);
- contentService.SaveAndPublish(content);
+ content.PublishValues(langFr.IsoCode);
+ content.PublishValues(langUk.IsoCode);
+ contentService.SaveAndPublish(content);
- // both FR and UK have been published,
- // and content has been published,
- // it has names, publishNames, and published cultures
+ // both FR and UK have been published,
+ // and content has been published,
+ // it has names, publishNames, and published cultures
- content2 = contentService.GetById(content.Id);
+ content2 = contentService.GetById(content.Id);
- Assert.AreEqual("Home US", content2.Name);
- Assert.AreEqual("name-fr", content2.GetName(langFr.Id));
- Assert.AreEqual("name-uk", content2.GetName(langUk.Id));
+ Assert.AreEqual("Home US", content2.Name);
+ Assert.AreEqual("name-fr", content2.GetName(langFr.IsoCode));
+ Assert.AreEqual("name-uk", content2.GetName(langUk.IsoCode));
- Assert.IsNull(content2.PublishName); // we haven't published InvariantNeutral
- Assert.AreEqual("name-fr", content2.GetPublishName(langFr.Id));
- Assert.AreEqual("name-uk", content2.GetPublishName(langUk.Id));
+ Assert.IsNull(content2.PublishName); // we haven't published InvariantNeutral
+ Assert.AreEqual("name-fr", content2.GetPublishName(langFr.IsoCode));
+ Assert.AreEqual("name-uk", content2.GetPublishName(langUk.IsoCode));
- Assert.AreEqual("value-fr1", content2.GetValue("prop", langFr.Id));
- Assert.AreEqual("value-uk1", content2.GetValue("prop", langUk.Id));
- Assert.AreEqual("value-fr1", content2.GetValue("prop", langFr.Id, published: true));
- Assert.AreEqual("value-uk1", content2.GetValue("prop", langUk.Id, published: true));
+ Assert.AreEqual("value-fr1", content2.GetValue("prop", langFr.IsoCode));
+ Assert.AreEqual("value-uk1", content2.GetValue("prop", langUk.IsoCode));
+ Assert.AreEqual("value-fr1", content2.GetValue("prop", langFr.IsoCode, published: true));
+ Assert.AreEqual("value-uk1", content2.GetValue("prop", langUk.IsoCode, published: true));
- Assert.IsTrue(content.IsCulturePublished(langFr.Id));
- Assert.IsTrue(content.IsCulturePublished(langUk.Id));
+ Assert.IsTrue(content.IsCulturePublished(langFr.IsoCode));
+ Assert.IsTrue(content.IsCulturePublished(langUk.IsoCode));
- // act
+ // act
- content.PublishValues();
- contentService.SaveAndPublish(content);
+ content.PublishValues();
+ contentService.SaveAndPublish(content);
- // now it has publish name for invariant neutral
+ // now it has publish name for invariant neutral
- content2 = contentService.GetById(content.Id);
+ content2 = contentService.GetById(content.Id);
- Assert.AreEqual("Home US", content2.PublishName);
+ Assert.AreEqual("Home US", content2.PublishName);
- // act
+ // act
- content.SetName(null, "Home US2");
- content.SetName(langFr.Id, "name-fr2");
- content.SetName(langUk.Id, "name-uk2");
- content.SetValue("author", "Barack Obama2");
- content.SetValue("prop", "value-fr2", langFr.Id);
- content.SetValue("prop", "value-uk2", langUk.Id);
- contentService.Save(content);
+ content.SetName(null, "Home US2");
+ content.SetName(langFr.IsoCode, "name-fr2");
+ content.SetName(langUk.IsoCode, "name-uk2");
+ content.SetValue("author", "Barack Obama2");
+ content.SetValue("prop", "value-fr2", langFr.IsoCode);
+ content.SetValue("prop", "value-uk2", langUk.IsoCode);
+ contentService.Save(content);
- // content has been saved,
- // it has updated names, unchanged publishNames, and published cultures
+ // content has been saved,
+ // it has updated names, unchanged publishNames, and published cultures
- content2 = contentService.GetById(content.Id);
+ content2 = contentService.GetById(content.Id);
- Assert.AreEqual("Home US2", content2.Name);
- Assert.AreEqual("name-fr2", content2.GetName(langFr.Id));
- Assert.AreEqual("name-uk2", content2.GetName(langUk.Id));
+ Assert.AreEqual("Home US2", content2.Name);
+ Assert.AreEqual("name-fr2", content2.GetName(langFr.IsoCode));
+ Assert.AreEqual("name-uk2", content2.GetName(langUk.IsoCode));
- Assert.AreEqual("Home US", content2.PublishName);
- Assert.AreEqual("name-fr", content2.GetPublishName(langFr.Id));
- Assert.AreEqual("name-uk", content2.GetPublishName(langUk.Id));
+ Assert.AreEqual("Home US", content2.PublishName);
+ Assert.AreEqual("name-fr", content2.GetPublishName(langFr.IsoCode));
+ Assert.AreEqual("name-uk", content2.GetPublishName(langUk.IsoCode));
- Assert.AreEqual("Barack Obama2", content2.GetValue("author"));
- Assert.AreEqual("Barack Obama", content2.GetValue("author", published: true));
+ Assert.AreEqual("Barack Obama2", content2.GetValue("author"));
+ Assert.AreEqual("Barack Obama", content2.GetValue("author", published: true));
- Assert.AreEqual("value-fr2", content2.GetValue("prop", langFr.Id));
- Assert.AreEqual("value-uk2", content2.GetValue("prop", langUk.Id));
- Assert.AreEqual("value-fr1", content2.GetValue("prop", langFr.Id, published: true));
- Assert.AreEqual("value-uk1", content2.GetValue("prop", langUk.Id, published: true));
+ Assert.AreEqual("value-fr2", content2.GetValue("prop", langFr.IsoCode));
+ Assert.AreEqual("value-uk2", content2.GetValue("prop", langUk.IsoCode));
+ Assert.AreEqual("value-fr1", content2.GetValue("prop", langFr.IsoCode, published: true));
+ Assert.AreEqual("value-uk1", content2.GetValue("prop", langUk.IsoCode, published: true));
- Assert.IsTrue(content.IsCulturePublished(langFr.Id));
- Assert.IsTrue(content.IsCulturePublished(langUk.Id));
+ Assert.IsTrue(content.IsCulturePublished(langFr.IsoCode));
+ Assert.IsTrue(content.IsCulturePublished(langUk.IsoCode));
- // act
- // cannot just 'save' since we are changing what's published!
+ // act
+ // cannot just 'save' since we are changing what's published!
- content.ClearPublishedValues(langFr.Id);
- contentService.SaveAndPublish(content);
+ content.ClearPublishedValues(langFr.IsoCode);
+ contentService.SaveAndPublish(content);
- // content has been published,
- // the french culture is gone
+ // content has been published,
+ // the french culture is gone
- content2 = contentService.GetById(content.Id);
+ content2 = contentService.GetById(content.Id);
- Assert.AreEqual("Home US2", content2.Name);
- Assert.AreEqual("name-fr2", content2.GetName(langFr.Id));
- Assert.AreEqual("name-uk2", content2.GetName(langUk.Id));
+ Assert.AreEqual("Home US2", content2.Name);
+ Assert.AreEqual("name-fr2", content2.GetName(langFr.IsoCode));
+ Assert.AreEqual("name-uk2", content2.GetName(langUk.IsoCode));
- Assert.AreEqual("Home US", content2.PublishName);
- Assert.IsNull(content2.GetPublishName(langFr.Id));
- Assert.AreEqual("name-uk", content2.GetPublishName(langUk.Id));
+ Assert.AreEqual("Home US", content2.PublishName);
+ Assert.IsNull(content2.GetPublishName(langFr.IsoCode));
+ Assert.AreEqual("name-uk", content2.GetPublishName(langUk.IsoCode));
- Assert.AreEqual("value-fr2", content2.GetValue("prop", langFr.Id));
- Assert.AreEqual("value-uk2", content2.GetValue("prop", langUk.Id));
- Assert.IsNull(content2.GetValue("prop", langFr.Id, published: true));
- Assert.AreEqual("value-uk1", content2.GetValue("prop", langUk.Id, published: true));
+ Assert.AreEqual("value-fr2", content2.GetValue("prop", langFr.IsoCode));
+ Assert.AreEqual("value-uk2", content2.GetValue("prop", langUk.IsoCode));
+ Assert.IsNull(content2.GetValue("prop", langFr.IsoCode, published: true));
+ Assert.AreEqual("value-uk1", content2.GetValue("prop", langUk.IsoCode, published: true));
- Assert.IsFalse(content.IsCulturePublished(langFr.Id));
- Assert.IsTrue(content.IsCulturePublished(langUk.Id));
+ Assert.IsFalse(content.IsCulturePublished(langFr.IsoCode));
+ Assert.IsTrue(content.IsCulturePublished(langUk.IsoCode));
- // act
+ // act
- contentService.Unpublish(content);
+ contentService.Unpublish(content);
- // content has been unpublished,
- // but properties, names, etc. retain their 'published' values so the content
- // can be re-published in its exact original state (before being unpublished)
- //
- // BEWARE!
- // in order for a content to be unpublished as a whole, and then republished in
- // its exact previous state, properties and names etc. retain their published
- // values even though the content is not published - hence many things being
- // non-null or true below - always check against content.Published to be sure
+ // content has been unpublished,
+ // but properties, names, etc. retain their 'published' values so the content
+ // can be re-published in its exact original state (before being unpublished)
+ //
+ // BEWARE!
+ // in order for a content to be unpublished as a whole, and then republished in
+ // its exact previous state, properties and names etc. retain their published
+ // values even though the content is not published - hence many things being
+ // non-null or true below - always check against content.Published to be sure
- content2 = contentService.GetById(content.Id);
+ content2 = contentService.GetById(content.Id);
- Assert.IsFalse(content2.Published);
+ Assert.IsFalse(content2.Published);
- Assert.AreEqual("Home US2", content2.Name);
- Assert.AreEqual("name-fr2", content2.GetName(langFr.Id));
- Assert.AreEqual("name-uk2", content2.GetName(langUk.Id));
+ Assert.AreEqual("Home US2", content2.Name);
+ Assert.AreEqual("name-fr2", content2.GetName(langFr.IsoCode));
+ Assert.AreEqual("name-uk2", content2.GetName(langUk.IsoCode));
- Assert.AreEqual("Home US", content2.PublishName); // not null, see note above
- Assert.IsNull(content2.GetPublishName(langFr.Id));
- Assert.AreEqual("name-uk", content2.GetPublishName(langUk.Id)); // not null, see note above
+ Assert.AreEqual("Home US", content2.PublishName); // not null, see note above
+ Assert.IsNull(content2.GetPublishName(langFr.IsoCode));
+ Assert.AreEqual("name-uk", content2.GetPublishName(langUk.IsoCode)); // not null, see note above
- Assert.AreEqual("value-fr2", content2.GetValue("prop", langFr.Id));
- Assert.AreEqual("value-uk2", content2.GetValue("prop", langUk.Id));
- Assert.IsNull(content2.GetValue("prop", langFr.Id, published: true));
- Assert.AreEqual("value-uk1", content2.GetValue("prop", langUk.Id, published: true)); // has value, see note above
+ Assert.AreEqual("value-fr2", content2.GetValue("prop", langFr.IsoCode));
+ Assert.AreEqual("value-uk2", content2.GetValue("prop", langUk.IsoCode));
+ Assert.IsNull(content2.GetValue("prop", langFr.IsoCode, published: true));
+ Assert.AreEqual("value-uk1", content2.GetValue("prop", langUk.IsoCode, published: true)); // has value, see note above
- Assert.IsFalse(content.IsCulturePublished(langFr.Id));
- Assert.IsTrue(content.IsCulturePublished(langUk.Id)); // still true, see note above
+ Assert.IsFalse(content.IsCulturePublished(langFr.IsoCode));
+ Assert.IsTrue(content.IsCulturePublished(langUk.IsoCode)); // still true, see note above
- // act
+ // act
- contentService.SaveAndPublish(content);
+ contentService.SaveAndPublish(content);
- // content has been re-published,
- // everything is back to what it was before being unpublished
+ // content has been re-published,
+ // everything is back to what it was before being unpublished
- content2 = contentService.GetById(content.Id);
+ content2 = contentService.GetById(content.Id);
- Assert.IsTrue(content2.Published);
+ Assert.IsTrue(content2.Published);
- Assert.AreEqual("Home US2", content2.Name);
- Assert.AreEqual("name-fr2", content2.GetName(langFr.Id));
- Assert.AreEqual("name-uk2", content2.GetName(langUk.Id));
+ Assert.AreEqual("Home US2", content2.Name);
+ Assert.AreEqual("name-fr2", content2.GetName(langFr.IsoCode));
+ Assert.AreEqual("name-uk2", content2.GetName(langUk.IsoCode));
- Assert.AreEqual("Home US", content2.PublishName);
- Assert.IsNull(content2.GetPublishName(langFr.Id));
- Assert.AreEqual("name-uk", content2.GetPublishName(langUk.Id));
+ Assert.AreEqual("Home US", content2.PublishName);
+ Assert.IsNull(content2.GetPublishName(langFr.IsoCode));
+ Assert.AreEqual("name-uk", content2.GetPublishName(langUk.IsoCode));
- Assert.AreEqual("value-fr2", content2.GetValue("prop", langFr.Id));
- Assert.AreEqual("value-uk2", content2.GetValue("prop", langUk.Id));
- Assert.IsNull(content2.GetValue("prop", langFr.Id, published: true));
- Assert.AreEqual("value-uk1", content2.GetValue("prop", langUk.Id, published: true));
+ Assert.AreEqual("value-fr2", content2.GetValue("prop", langFr.IsoCode));
+ Assert.AreEqual("value-uk2", content2.GetValue("prop", langUk.IsoCode));
+ Assert.IsNull(content2.GetValue("prop", langFr.IsoCode, published: true));
+ Assert.AreEqual("value-uk1", content2.GetValue("prop", langUk.IsoCode, published: true));
- Assert.IsFalse(content.IsCulturePublished(langFr.Id));
- Assert.IsTrue(content.IsCulturePublished(langUk.Id));
+ Assert.IsFalse(content.IsCulturePublished(langFr.IsoCode));
+ Assert.IsTrue(content.IsCulturePublished(langUk.IsoCode));
}
private IEnumerable CreateContentHierarchy()
diff --git a/src/Umbraco.Tests/TestHelpers/TestHelper.cs b/src/Umbraco.Tests/TestHelpers/TestHelper.cs
index 47a847ad43..25ac6314e2 100644
--- a/src/Umbraco.Tests/TestHelpers/TestHelper.cs
+++ b/src/Umbraco.Tests/TestHelpers/TestHelper.cs
@@ -140,8 +140,8 @@ namespace Umbraco.Tests.TestHelpers
{
// compare values
var actualProperty = (Property) actual;
- var expectedPropertyValues = expectedProperty.Values.OrderBy(x => x.LanguageId).ThenBy(x => x.Segment).ToArray();
- var actualPropertyValues = actualProperty.Values.OrderBy(x => x.LanguageId).ThenBy(x => x.Segment).ToArray();
+ var expectedPropertyValues = expectedProperty.Values.OrderBy(x => x.Culture).ThenBy(x => x.Segment).ToArray();
+ var actualPropertyValues = actualProperty.Values.OrderBy(x => x.Culture).ThenBy(x => x.Segment).ToArray();
if (expectedPropertyValues.Length != actualPropertyValues.Length)
Assert.Fail($"{property.DeclaringType.Name}.{property.Name}: Expected {expectedPropertyValues.Length} but got {actualPropertyValues.Length}.");
for (var i = 0; i < expectedPropertyValues.Length; i++)
diff --git a/src/Umbraco.Web/Editors/ContentController.cs b/src/Umbraco.Web/Editors/ContentController.cs
index dce9ca531d..6eb8db3c61 100644
--- a/src/Umbraco.Web/Editors/ContentController.cs
+++ b/src/Umbraco.Web/Editors/ContentController.cs
@@ -265,8 +265,8 @@ namespace Umbraco.Web.Editors
HandleContentNotFound(id);
return null;//irrelevant since the above throws
}
-
- var content = MapToDisplay(foundContent, languageId);
+
+ var content = MapToDisplay(foundContent, GetLanguageCulture(languageId));
return content;
}
@@ -606,7 +606,7 @@ namespace Umbraco.Web.Editors
{
//ok, so the absolute mandatory data is invalid and it's new, we cannot actually continue!
// add the modelstate to the outgoing object and throw a validation message
- var forDisplay = MapToDisplay(contentItem.PersistedContent, contentItem.LanguageId);
+ var forDisplay = MapToDisplay(contentItem.PersistedContent, GetLanguageCulture(contentItem.LanguageId));
forDisplay.Errors = ModelState.ToErrorDictionary();
throw new HttpResponseException(Request.CreateValidationErrorResponse(forDisplay));
@@ -643,14 +643,14 @@ namespace Umbraco.Web.Editors
else
{
//publish the item and check if it worked, if not we will show a diff msg below
- contentItem.PersistedContent.PublishValues(contentItem.LanguageId); //we are not checking for a return value here because we've alraedy pre-validated the property values
+ contentItem.PersistedContent.PublishValues(GetLanguageCulture(contentItem.LanguageId)); //we are not checking for a return value here because we've alraedy pre-validated the property values
//check if we are publishing other variants and validate them
var allLangs = Services.LocalizationService.GetAllLanguages().ToList();
var variantsToValidate = contentItem.PublishVariations.Where(x => x.LanguageId != contentItem.LanguageId).ToList();
foreach (var publishVariation in variantsToValidate)
{
- if (!contentItem.PersistedContent.PublishValues(publishVariation.LanguageId))
+ if (!contentItem.PersistedContent.PublishValues(GetLanguageCulture(publishVariation.LanguageId)))
{
var errMsg = Services.TextService.Localize("speechBubbles/contentLangValidationError", new[]{allLangs.First(x => x.Id == publishVariation.LanguageId).CultureName});
ModelState.AddModelError("publish_variant_" + publishVariation.LanguageId + "_", errMsg);
@@ -664,7 +664,7 @@ namespace Umbraco.Web.Editors
.Where(x => x.Mandatory);
foreach (var lang in mandatoryLangs)
{
- if (contentItem.PersistedContent.Validate(lang.Id).Length > 0)
+ if (contentItem.PersistedContent.Validate(GetLanguageCulture(lang.Id)).Length > 0)
{
var errMsg = Services.TextService.Localize("speechBubbles/contentReqLangValidationError", new[]{allLangs.First(x => x.Id == lang.Id).CultureName});
ModelState.AddModelError("publish_variant_" + lang.Id + "_", errMsg);
@@ -676,7 +676,7 @@ namespace Umbraco.Web.Editors
}
//get the updated model
- var display = MapToDisplay(contentItem.PersistedContent, contentItem.LanguageId);
+ var display = MapToDisplay(contentItem.PersistedContent, GetLanguageCulture(contentItem.LanguageId));
//lasty, if it is not valid, add the modelstate to the outgoing object and throw a 403
HandleInvalidModelState(display);
@@ -977,8 +977,8 @@ namespace Umbraco.Web.Editors
base.MapPropertyValues(
contentItem,
- (save, property) => property.GetValue(save.LanguageId), //get prop val
- (save, property, v) => property.SetValue(v, save.LanguageId)); //set prop val
+ (save, property) => property.GetValue(GetLanguageCulture(save.LanguageId)), //get prop val
+ (save, property, v) => property.SetValue(v, GetLanguageCulture(save.LanguageId))); //set prop val
}
///
@@ -1169,23 +1169,28 @@ namespace Umbraco.Web.Editors
/// Used to map an instance to a and ensuring a language is present if required
///
///
- ///
+ ///
///
- private ContentItemDisplay MapToDisplay(IContent content, int? languageId = null)
+ private ContentItemDisplay MapToDisplay(IContent content, string culture = null)
{
//a languageId must exist in the mapping context if this content item has any property type that can be varied by language
//otherwise the property validation will fail since it's expecting to be get/set with a language ID. If a languageId is not explicitly
//sent up, then it means that the user is editing the default variant language.
- if (!languageId.HasValue && content.HasPropertyTypeVaryingByCulture())
+ if (culture == null && content.HasPropertyTypeVaryingByCulture())
{
- languageId = Services.LocalizationService.GetDefaultVariantLanguage().Id;
+ culture = Services.LocalizationService.GetDefaultVariantLanguage().IsoCode;
}
var display = ContextMapper.Map(content, UmbracoContext,
- new Dictionary { { ContextMapper.LanguageKey, languageId } });
+ new Dictionary { { ContextMapper.CultureKey, culture } });
return display;
}
+ private string GetLanguageCulture(int? languageId)
+ {
+ if (languageId == null) return null;
+ return Core.Composing.Current.Services.LocalizationService.GetLanguageById(languageId.Value).IsoCode; // fixme optimize!
+ }
}
}
diff --git a/src/Umbraco.Web/Models/ContentExtensions.cs b/src/Umbraco.Web/Models/ContentExtensions.cs
index 4a016a895b..3fe81757a8 100644
--- a/src/Umbraco.Web/Models/ContentExtensions.cs
+++ b/src/Umbraco.Web/Models/ContentExtensions.cs
@@ -96,6 +96,5 @@ namespace Umbraco.Web.Models
var defaultLanguage = localizationService.GetAllLanguages().FirstOrDefault();
return defaultLanguage == null ? CultureInfo.CurrentUICulture : new CultureInfo(defaultLanguage.IsoCode);
}
-
}
}
diff --git a/src/Umbraco.Web/Models/Mapping/ContentPropertyBasicConverter.cs b/src/Umbraco.Web/Models/Mapping/ContentPropertyBasicConverter.cs
index 5f7cc0e052..10fec19b38 100644
--- a/src/Umbraco.Web/Models/Mapping/ContentPropertyBasicConverter.cs
+++ b/src/Umbraco.Web/Models/Mapping/ContentPropertyBasicConverter.cs
@@ -46,9 +46,9 @@ namespace Umbraco.Web.Models.Mapping
editor = _propertyEditors[Constants.PropertyEditors.Aliases.NoEdit];
}
- var languageId = context.GetLanguageId();
+ var culture = context.GetCulture();
- if (!languageId.HasValue && property.PropertyType.Variations == ContentVariation.CultureNeutral)
+ if (culture == null && property.PropertyType.Variations == ContentVariation.CultureNeutral)
{
//a language Id needs to be set for a property type that can be varried by language
throw new InvalidOperationException($"No languageId found in mapping operation when one is required for the culture neutral property type {property.PropertyType.Alias}");
@@ -74,7 +74,7 @@ namespace Umbraco.Web.Models.Mapping
}
// if no 'IncludeProperties' were specified or this property is set to be included - we will map the value and return.
- result.Value = editor.GetValueEditor().ToEditor(property, DataTypeService, languageId);
+ result.Value = editor.GetValueEditor().ToEditor(property, DataTypeService, culture);
return result;
}
}
diff --git a/src/Umbraco.Web/Models/Mapping/ContextMapper.cs b/src/Umbraco.Web/Models/Mapping/ContextMapper.cs
index b46cd219d8..5aa8af7668 100644
--- a/src/Umbraco.Web/Models/Mapping/ContextMapper.cs
+++ b/src/Umbraco.Web/Models/Mapping/ContextMapper.cs
@@ -11,7 +11,7 @@ namespace Umbraco.Web.Models.Mapping
internal static class ContextMapper
{
public const string UmbracoContextKey = "ContextMapper.UmbracoContext";
- public const string LanguageKey = "ContextMapper.LanguageId";
+ public const string CultureKey = "ContextMapper.Culture";
public static TDestination Map(TSource obj, UmbracoContext umbracoContext)
=> Mapper.Map(obj, opt => opt.Items[UmbracoContextKey] = umbracoContext);
@@ -77,12 +77,12 @@ namespace Umbraco.Web.Models.Mapping
///
///
///
- public static int? GetLanguageId(this ResolutionContext resolutionContext)
+ public static string GetCulture(this ResolutionContext resolutionContext)
{
- if (!resolutionContext.Options.Items.TryGetValue(LanguageKey, out var obj)) return null;
+ if (!resolutionContext.Options.Items.TryGetValue(CultureKey, out var obj)) return null;
- if (obj is int i)
- return i;
+ if (obj is string s)
+ return s;
return null;
}
diff --git a/src/Umbraco.Web/Models/Mapping/VariationResolver.cs b/src/Umbraco.Web/Models/Mapping/VariationResolver.cs
index 9d3de07d77..ece6f87a33 100644
--- a/src/Umbraco.Web/Models/Mapping/VariationResolver.cs
+++ b/src/Umbraco.Web/Models/Mapping/VariationResolver.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using AutoMapper;
+using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Core.Services;
using Umbraco.Web.Models.ContentEditing;
@@ -29,19 +30,19 @@ namespace Umbraco.Web.Models.Mapping
{
Language = x,
Mandatory = x.Mandatory,
- Name = source.GetName(x.Id),
- Exists = source.IsCultureAvailable(x.Id), // segments ??
+ Name = source.GetName(x.IsoCode),
+ Exists = source.IsCultureAvailable(x.IsoCode), // segments ??
PublishedState = source.PublishedState.ToString(),
//Segment = ?? We'll need to populate this one day when we support segments
}).ToList();
- var langId = context.GetLanguageId();
+ var culture = context.GetCulture();
//set the current variant being edited to the one found in the context or the default if nothing matches
var foundCurrent = false;
foreach (var variant in variants)
{
- if (langId.HasValue && langId.Value == variant.Language.Id)
+ if (culture.InvariantEquals(variant.Language.IsoCode))
{
variant.IsCurrent = true;
foundCurrent = true;
diff --git a/src/Umbraco.Web/PropertyEditors/DateValueEditor.cs b/src/Umbraco.Web/PropertyEditors/DateValueEditor.cs
index 31425fdadd..a03ad4aa00 100644
--- a/src/Umbraco.Web/PropertyEditors/DateValueEditor.cs
+++ b/src/Umbraco.Web/PropertyEditors/DateValueEditor.cs
@@ -18,9 +18,9 @@ namespace Umbraco.Web.PropertyEditors
Validators.Add(new DateTimeValidator());
}
- public override object ToEditor(Property property, IDataTypeService dataTypeService, int? languageId = null, string segment = null)
+ public override object ToEditor(Property property, IDataTypeService dataTypeService, string culture= null, string segment = null)
{
- var date = property.GetValue(languageId, segment).TryConvertTo();
+ var date = property.GetValue(culture, segment).TryConvertTo();
if (date.Success == false || date.Result == null)
{
return String.Empty;
diff --git a/src/Umbraco.Web/PropertyEditors/FileUploadPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/FileUploadPropertyEditor.cs
index e969d2e45b..0d5f6efaf5 100644
--- a/src/Umbraco.Web/PropertyEditors/FileUploadPropertyEditor.cs
+++ b/src/Umbraco.Web/PropertyEditors/FileUploadPropertyEditor.cs
@@ -93,11 +93,11 @@ namespace Umbraco.Web.PropertyEditors
//copy each of the property values (variants, segments) to the destination
foreach (var propertyValue in property.Values)
{
- var propVal = property.GetValue(propertyValue.LanguageId, propertyValue.Segment);
+ var propVal = property.GetValue(propertyValue.Culture, propertyValue.Segment);
if (propVal == null || !(propVal is string str) || str.IsNullOrWhiteSpace()) continue;
var sourcePath = _mediaFileSystem.GetRelativePath(str);
var copyPath = _mediaFileSystem.CopyFile(args.Copy, property.PropertyType, sourcePath);
- args.Copy.SetValue(property.Alias, _mediaFileSystem.GetUrl(copyPath), propertyValue.LanguageId, propertyValue.Segment);
+ args.Copy.SetValue(property.Alias, _mediaFileSystem.GetUrl(copyPath), propertyValue.Culture, propertyValue.Segment);
isUpdated = true;
}
}
@@ -153,11 +153,11 @@ namespace Umbraco.Web.PropertyEditors
foreach (var pvalue in property.Values)
{
- var svalue = property.GetValue(pvalue.LanguageId, pvalue.Segment) as string;
+ var svalue = property.GetValue(pvalue.Culture, pvalue.Segment) as string;
if (string.IsNullOrWhiteSpace(svalue))
- _mediaFileSystem.UploadAutoFillProperties.Reset(model, autoFillConfig, pvalue.LanguageId, pvalue.Segment);
+ _mediaFileSystem.UploadAutoFillProperties.Reset(model, autoFillConfig, pvalue.Culture, pvalue.Segment);
else
- _mediaFileSystem.UploadAutoFillProperties.Populate(model, autoFillConfig, _mediaFileSystem.GetRelativePath(svalue), pvalue.LanguageId, pvalue.Segment);
+ _mediaFileSystem.UploadAutoFillProperties.Populate(model, autoFillConfig, _mediaFileSystem.GetRelativePath(svalue), pvalue.Culture, pvalue.Segment);
}
}
}
diff --git a/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyEditor.cs
index 6d3c5b4f61..6183641aaf 100644
--- a/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyEditor.cs
+++ b/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyEditor.cs
@@ -148,13 +148,13 @@ namespace Umbraco.Web.PropertyEditors
//copy each of the property values (variants, segments) to the destination by using the edited value
foreach (var propertyValue in property.Values)
{
- var propVal = property.GetValue(propertyValue.LanguageId, propertyValue.Segment);
+ var propVal = property.GetValue(propertyValue.Culture, propertyValue.Segment);
var src = GetFileSrcFromPropertyValue(propVal, out var jo);
if (src == null) continue;
var sourcePath = _mediaFileSystem.GetRelativePath(src);
var copyPath = _mediaFileSystem.CopyFile(args.Copy, property.PropertyType, sourcePath);
jo["src"] = _mediaFileSystem.GetUrl(copyPath);
- args.Copy.SetValue(property.Alias, jo.ToString(), propertyValue.LanguageId, propertyValue.Segment);
+ args.Copy.SetValue(property.Alias, jo.ToString(), propertyValue.Culture, propertyValue.Segment);
isUpdated = true;
}
}
@@ -209,10 +209,10 @@ namespace Umbraco.Web.PropertyEditors
foreach (var pvalue in property.Values)
{
- var svalue = property.GetValue(pvalue.LanguageId, pvalue.Segment) as string;
+ var svalue = property.GetValue(pvalue.Culture, pvalue.Segment) as string;
if (string.IsNullOrWhiteSpace(svalue))
{
- _autoFillProperties.Reset(model, autoFillConfig, pvalue.LanguageId, pvalue.Segment);
+ _autoFillProperties.Reset(model, autoFillConfig, pvalue.Culture, pvalue.Segment);
continue;
}
diff --git a/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyValueEditor.cs b/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyValueEditor.cs
index bce989fb18..98e8346441 100644
--- a/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyValueEditor.cs
+++ b/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyValueEditor.cs
@@ -32,9 +32,9 @@ namespace Umbraco.Web.PropertyEditors
/// This is called to merge in the prevalue crops with the value that is saved - similar to the property value converter for the front-end
///
- public override object ToEditor(Property property, IDataTypeService dataTypeService, int? languageId = null, string segment = null)
+ public override object ToEditor(Property property, IDataTypeService dataTypeService, string culture = null, string segment = null)
{
- var val = property.GetValue(languageId, segment);
+ var val = property.GetValue(culture, segment);
if (val == null) return null;
ImageCropperValue value;
diff --git a/src/Umbraco.Web/PropertyEditors/MultipleTextStringPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/MultipleTextStringPropertyEditor.cs
index a6373bd87d..645296a354 100644
--- a/src/Umbraco.Web/PropertyEditors/MultipleTextStringPropertyEditor.cs
+++ b/src/Umbraco.Web/PropertyEditors/MultipleTextStringPropertyEditor.cs
@@ -85,9 +85,9 @@ namespace Umbraco.Web.PropertyEditors
///
/// The legacy property editor saved this data as new line delimited! strange but we have to maintain that.
///
- public override object ToEditor(Property property, IDataTypeService dataTypeService, int? languageId = null, string segment = null)
+ public override object ToEditor(Property property, IDataTypeService dataTypeService, string culture = null, string segment = null)
{
- var val = property.GetValue(languageId, segment);
+ var val = property.GetValue(culture, segment);
return val?.ToString().Split(new[] {Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries)
.Select(x => JObject.FromObject(new {value = x})) ?? new JObject[] { };
diff --git a/src/Umbraco.Web/PropertyEditors/NestedContentPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/NestedContentPropertyEditor.cs
index 52933e5846..4cb8fde97a 100644
--- a/src/Umbraco.Web/PropertyEditors/NestedContentPropertyEditor.cs
+++ b/src/Umbraco.Web/PropertyEditors/NestedContentPropertyEditor.cs
@@ -139,9 +139,9 @@ namespace Umbraco.Web.PropertyEditors
// note: there is NO variant support here
- public override object ToEditor(Property property, IDataTypeService dataTypeService, int? languageId = null, string segment = null)
+ public override object ToEditor(Property property, IDataTypeService dataTypeService, string culture = null, string segment = null)
{
- var val = property.GetValue(languageId, segment);
+ var val = property.GetValue(culture, segment);
if (val == null || string.IsNullOrWhiteSpace(val.ToString()))
return string.Empty;
diff --git a/src/Umbraco.Web/PropertyEditors/PublishValuesMultipleValueEditor.cs b/src/Umbraco.Web/PropertyEditors/PublishValuesMultipleValueEditor.cs
index 6cd9675f67..25a1c25284 100644
--- a/src/Umbraco.Web/PropertyEditors/PublishValuesMultipleValueEditor.cs
+++ b/src/Umbraco.Web/PropertyEditors/PublishValuesMultipleValueEditor.cs
@@ -70,12 +70,12 @@ namespace Umbraco.Web.PropertyEditors
///
///
///
- ///
+ ///
///
///
- public override object ToEditor(Property property, IDataTypeService dataTypeService, int? languageId = null, string segment = null)
+ public override object ToEditor(Property property, IDataTypeService dataTypeService, string culture = null, string segment = null)
{
- var delimited = base.ToEditor(property, dataTypeService, languageId, segment).ToString();
+ var delimited = base.ToEditor(property, dataTypeService, culture, segment).ToString();
return delimited.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
}
diff --git a/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs
index 181471b315..797d0eaf59 100644
--- a/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs
+++ b/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs
@@ -61,12 +61,12 @@ namespace Umbraco.Web.PropertyEditors
///
///
///
- ///
+ ///
///
///
- public override object ToEditor(Property property, IDataTypeService dataTypeService, int? languageId = null, string segment = null)
+ public override object ToEditor(Property property, IDataTypeService dataTypeService, string culture = null, string segment = null)
{
- var val = property.GetValue(languageId, segment);
+ var val = property.GetValue(culture, segment);
if (val == null)
return null;
diff --git a/src/Umbraco.Web/PropertyEditors/TextOnlyValueEditor.cs b/src/Umbraco.Web/PropertyEditors/TextOnlyValueEditor.cs
index f860a5abe7..754cef1f31 100644
--- a/src/Umbraco.Web/PropertyEditors/TextOnlyValueEditor.cs
+++ b/src/Umbraco.Web/PropertyEditors/TextOnlyValueEditor.cs
@@ -20,15 +20,15 @@ namespace Umbraco.Web.PropertyEditors
///
///
///
- ///
+ ///
///
///
///
/// The object returned will always be a string and if the database type is not a valid string type an exception is thrown
///
- public override object ToEditor(Property property, IDataTypeService dataTypeService, int? languageId = null, string segment = null)
+ public override object ToEditor(Property property, IDataTypeService dataTypeService, string culture = null, string segment = null)
{
- var val = property.GetValue(languageId, segment);
+ var val = property.GetValue(culture, segment);
if (val == null) return string.Empty;
diff --git a/src/Umbraco.Web/PublishedCache/NuCache/DataSource/BTree.cs b/src/Umbraco.Web/PublishedCache/NuCache/DataSource/BTree.cs
index 6fd731cbee..30bb553ae2 100644
--- a/src/Umbraco.Web/PublishedCache/NuCache/DataSource/BTree.cs
+++ b/src/Umbraco.Web/PublishedCache/NuCache/DataSource/BTree.cs
@@ -159,7 +159,7 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
pdatas.Add(pdata);
var type = PrimitiveSerializer.Char.ReadFrom(stream);
- pdata.LanguageId = (int?) ReadObject(type, stream);
+ pdata.Culture = (string) ReadObject(type, stream);
type = PrimitiveSerializer.Char.ReadFrom(stream);
pdata.Segment = (string) ReadObject(type, stream);
type = PrimitiveSerializer.Char.ReadFrom(stream);
@@ -211,7 +211,7 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
// write each value
foreach (var pdata in kvp.Value)
{
- WriteObject(pdata.LanguageId, stream);
+ WriteObject(pdata.Culture, stream);
WriteObject(pdata.Segment, stream);
WriteObject(pdata.Value, stream);
}
diff --git a/src/Umbraco.Web/PublishedCache/NuCache/DataSource/PropertyData.cs b/src/Umbraco.Web/PublishedCache/NuCache/DataSource/PropertyData.cs
index ab9d3cdcac..ddb9607575 100644
--- a/src/Umbraco.Web/PublishedCache/NuCache/DataSource/PropertyData.cs
+++ b/src/Umbraco.Web/PublishedCache/NuCache/DataSource/PropertyData.cs
@@ -4,8 +4,8 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
{
internal class PropertyData
{
- [JsonProperty("lang")]
- public int? LanguageId { get; set; }
+ [JsonProperty("culture")]
+ public string Culture { get; set; }
[JsonProperty("seg")]
public string Segment { get; set; }
@@ -13,4 +13,4 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
[JsonProperty("val")]
public object Value { get; set; }
}
-}
\ No newline at end of file
+}
diff --git a/src/Umbraco.Web/PublishedCache/NuCache/Property.cs b/src/Umbraco.Web/PublishedCache/NuCache/Property.cs
index 9a74b66897..7fe898b080 100644
--- a/src/Umbraco.Web/PublishedCache/NuCache/Property.cs
+++ b/src/Umbraco.Web/PublishedCache/NuCache/Property.cs
@@ -28,7 +28,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
private object _interValue;
// the variant source and inter values
- private Dictionary _sourceValues;
+ private Dictionary _sourceValues;
// the variant and non-variant object values
private CacheValues _cacheValues;
@@ -49,16 +49,16 @@ namespace Umbraco.Web.PublishedCache.NuCache
{
foreach (var sourceValue in sourceValues)
{
- if (sourceValue.LanguageId == null && sourceValue.Segment == null)
+ if (sourceValue.Culture == null && sourceValue.Segment == null)
{
_sourceValue = sourceValue.Value;
}
else
{
if (_sourceValues == null)
- _sourceValues = new Dictionary();
- _sourceValues[new CompositeIntStringKey(sourceValue.LanguageId, sourceValue.Segment)]
- = new SourceInterValue { LanguageId = sourceValue.LanguageId, Segment = sourceValue.Segment, SourceValue = sourceValue.Value };
+ _sourceValues = new Dictionary();
+ _sourceValues[new CompositeStringStringKey(sourceValue.Culture, sourceValue.Segment)]
+ = new SourceInterValue { Culture = sourceValue.Culture, Segment = sourceValue.Segment, SourceValue = sourceValue.Value };
}
}
}
@@ -84,7 +84,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
_publishedSnapshotAccessor = origin._publishedSnapshotAccessor;
}
- public override bool HasValue(int? languageId = null, string segment = null) => _sourceValue != null
+ public override bool HasValue(string culture = null, string segment = null) => _sourceValue != null
&& (!(_sourceValue is string) || string.IsNullOrWhiteSpace((string) _sourceValue) == false);
// used to cache the recursive *property* for this property
@@ -143,9 +143,9 @@ namespace Umbraco.Web.PublishedCache.NuCache
}
// this is always invoked from within a lock, so does not require its own lock
- private object GetInterValue(int? languageId, string segment)
+ private object GetInterValue(string culture, string segment)
{
- if (languageId == null && segment == null)
+ if (culture == null && segment == null)
{
if (_interInitialized) return _interValue;
_interValue = PropertyType.ConvertSourceToInter(_content, _sourceValue, _isPreviewing);
@@ -154,11 +154,11 @@ namespace Umbraco.Web.PublishedCache.NuCache
}
if (_sourceValues == null)
- _sourceValues = new Dictionary();
+ _sourceValues = new Dictionary();
- var k = new CompositeIntStringKey(languageId, segment);
+ var k = new CompositeStringStringKey(culture, segment);
if (!_sourceValues.TryGetValue(k, out var vvalue))
- _sourceValues[k] = vvalue = new SourceInterValue { LanguageId = languageId, Segment = segment };
+ _sourceValues[k] = vvalue = new SourceInterValue { Culture = culture, Segment = segment };
if (vvalue.InterInitialized) return vvalue.InterValue;
vvalue.InterValue = PropertyType.ConvertSourceToInter(_content, vvalue.SourceValue, _isPreviewing);
@@ -166,45 +166,45 @@ namespace Umbraco.Web.PublishedCache.NuCache
return vvalue.InterValue;
}
- public override object GetSourceValue(int? languageId = null, string segment = null)
+ public override object GetSourceValue(string culture = null, string segment = null)
{
- if (languageId == null && segment == null)
+ if (culture == null && segment == null)
return _sourceValue;
lock (_locko)
{
if (_sourceValues == null) return null;
- return _sourceValues.TryGetValue(new CompositeIntStringKey(languageId, segment), out var sourceValue) ? sourceValue.SourceValue : null;
+ return _sourceValues.TryGetValue(new CompositeStringStringKey(culture, segment), out var sourceValue) ? sourceValue.SourceValue : null;
}
}
- public override object GetValue(int? languageId = null, string segment = null)
+ public override object GetValue(string culture = null, string segment = null)
{
lock (_locko)
{
- var cacheValues = GetCacheValues(PropertyType.CacheLevel).For(languageId, segment);
+ var cacheValues = GetCacheValues(PropertyType.CacheLevel).For(culture, segment);
// initial reference cache level always is .Content
const PropertyCacheLevel initialCacheLevel = PropertyCacheLevel.Element;
if (cacheValues.ObjectInitialized) return cacheValues.ObjectValue;
- cacheValues.ObjectValue = PropertyType.ConvertInterToObject(_content, initialCacheLevel, GetInterValue(languageId, segment), _isPreviewing);
+ cacheValues.ObjectValue = PropertyType.ConvertInterToObject(_content, initialCacheLevel, GetInterValue(culture, segment), _isPreviewing);
cacheValues.ObjectInitialized = true;
return cacheValues.ObjectValue;
}
}
- public override object GetXPathValue(int? languageId = null, string segment = null)
+ public override object GetXPathValue(string culture = null, string segment = null)
{
lock (_locko)
{
- var cacheValues = GetCacheValues(PropertyType.CacheLevel).For(languageId, segment);
+ var cacheValues = GetCacheValues(PropertyType.CacheLevel).For(culture, segment);
// initial reference cache level always is .Content
const PropertyCacheLevel initialCacheLevel = PropertyCacheLevel.Element;
if (cacheValues.XPathInitialized) return cacheValues.XPathValue;
- cacheValues.XPathValue = PropertyType.ConvertInterToXPath(_content, initialCacheLevel, GetInterValue(languageId, segment), _isPreviewing);
+ cacheValues.XPathValue = PropertyType.ConvertInterToXPath(_content, initialCacheLevel, GetInterValue(culture, segment), _isPreviewing);
cacheValues.XPathInitialized = true;
return cacheValues.XPathValue;
}
@@ -222,18 +222,18 @@ namespace Umbraco.Web.PublishedCache.NuCache
private class CacheValues : CacheValue
{
- private Dictionary _values;
+ private Dictionary _values;
// this is always invoked from within a lock, so does not require its own lock
- public CacheValue For(int? languageId, string segment)
+ public CacheValue For(string culture, string segment)
{
- if (languageId == null && segment == null)
+ if (culture == null && segment == null)
return this;
if (_values == null)
- _values = new Dictionary();
+ _values = new Dictionary();
- var k = new CompositeIntStringKey(languageId, segment);
+ var k = new CompositeStringStringKey(culture, segment);
if (!_values.TryGetValue(k, out var value))
_values[k] = value = new CacheValue();
@@ -243,9 +243,14 @@ namespace Umbraco.Web.PublishedCache.NuCache
private class SourceInterValue
{
+ private string _culture;
private string _segment;
- public int? LanguageId { get; set; }
+ public string Culture
+ {
+ get => _culture;
+ internal set => _culture = value?.ToLowerInvariant();
+ }
public string Segment
{
get => _segment;
diff --git a/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs b/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs
index 992ac62733..7f26f3c753 100644
--- a/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs
+++ b/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs
@@ -1183,7 +1183,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
{
var value = published ? pvalue.PublishedValue : pvalue.EditedValue;
if (value != null)
- pdatas.Add(new PropertyData { LanguageId = pvalue.LanguageId, Segment = pvalue.Segment, Value = value });
+ pdatas.Add(new PropertyData { Culture = pvalue.Culture, Segment = pvalue.Segment, Value = value });
//Core.Composing.Current.Logger.Debug($"{content.Id} {prop.Alias} [{pvalue.LanguageId},{pvalue.Segment}] {value} {(published?"pub":"edit")}");
diff --git a/src/Umbraco.Web/PublishedCache/PublishedElementPropertyBase.cs b/src/Umbraco.Web/PublishedCache/PublishedElementPropertyBase.cs
index 2c5b93f219..d8db937ca8 100644
--- a/src/Umbraco.Web/PublishedCache/PublishedElementPropertyBase.cs
+++ b/src/Umbraco.Web/PublishedCache/PublishedElementPropertyBase.cs
@@ -36,7 +36,7 @@ namespace Umbraco.Web.PublishedCache
IsMember = propertyType.ContentType.ItemType == PublishedItemType.Member;
}
- public override bool HasValue(int? languageId = null, string segment = null)
+ public override bool HasValue(string culture = null, string segment = null)
=> _sourceValue != null && (!(_sourceValue is string s) || !string.IsNullOrWhiteSpace(s));
// used to cache the CacheValues of this property
@@ -136,9 +136,9 @@ namespace Umbraco.Web.PublishedCache
return _interValue;
}
- public override object GetSourceValue(int? languageId = null, string segment = null) => _sourceValue;
+ public override object GetSourceValue(string culture = null, string segment = null) => _sourceValue;
- public override object GetValue(int? languageId = null, string segment = null)
+ public override object GetValue(string culture = null, string segment = null)
{
GetCacheLevels(out var cacheLevel, out var referenceCacheLevel);
@@ -152,7 +152,7 @@ namespace Umbraco.Web.PublishedCache
}
}
- public override object GetXPathValue(int? languageId = null, string segment = null)
+ public override object GetXPathValue(string culture = null, string segment = null)
{
GetCacheLevels(out var cacheLevel, out var referenceCacheLevel);
diff --git a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlPublishedProperty.cs b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlPublishedProperty.cs
index 632698c37e..ea8ab925c6 100644
--- a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlPublishedProperty.cs
+++ b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlPublishedProperty.cs
@@ -27,13 +27,13 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
///
/// Gets the raw value of the property.
///
- public override object GetSourceValue(int? languageId = null, string segment = null) => _sourceValue;
+ public override object GetSourceValue(string culture = null, string segment = null) => _sourceValue;
// in the Xml cache, everything is a string, and to have a value
// you want to have a non-null, non-empty string.
- public override bool HasValue(int? languageId = null, string segment = null) => _sourceValue.Trim().Length > 0;
+ public override bool HasValue(string culture = null, string segment = null) => _sourceValue.Trim().Length > 0;
- public override object GetValue(int? languageId = null, string segment = null)
+ public override object GetValue(string culture = null, string segment = null)
{
// NOT caching the source (intermediate) value since we'll never need it
// everything in Xml cache is per-request anyways
@@ -48,7 +48,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
return _objectValue;
}
- public override object GetXPathValue(int? languageId = null, string segment = null) { throw new NotImplementedException(); }
+ public override object GetXPathValue(string culture = null, string segment = null) { throw new NotImplementedException(); }
public XmlPublishedProperty(PublishedPropertyType propertyType, IPublishedContent content, bool isPreviewing, XmlNode propertyXmlData)
: this(propertyType, content, isPreviewing)
diff --git a/src/Umbraco.Web/PublishedContentPropertyExtension.cs b/src/Umbraco.Web/PublishedContentPropertyExtension.cs
index 3314bc09fc..6d397ffaa3 100644
--- a/src/Umbraco.Web/PublishedContentPropertyExtension.cs
+++ b/src/Umbraco.Web/PublishedContentPropertyExtension.cs
@@ -10,24 +10,24 @@ namespace Umbraco.Web
{
#region Value
- public static T Value(this IPublishedProperty property, int? languageId = null, string segment = null)
+ public static T Value(this IPublishedProperty property, string culture = null, string segment = null)
{
- return property.Value(false, default(T), languageId, segment);
+ return property.Value(false, default(T), culture, segment);
}
- public static T Value(this IPublishedProperty property, T defaultValue, int? languageId = null, string segment = null)
+ public static T Value(this IPublishedProperty property, T defaultValue, string culture = null, string segment = null)
{
- return property.Value(true, defaultValue, languageId, segment);
+ return property.Value(true, defaultValue, culture, segment);
}
- internal static T Value(this IPublishedProperty property, bool withDefaultValue, T defaultValue, int? languageId = null, string segment = null)
+ internal static T Value(this IPublishedProperty property, bool withDefaultValue, T defaultValue, string culture = null, string segment = null)
{
- if (property.HasValue(languageId, segment) == false && withDefaultValue) return defaultValue;
+ if (property.HasValue(culture, segment) == false && withDefaultValue) return defaultValue;
// else we use .Value so we give the converter a chance to handle the default value differently
// eg for IEnumerable it may return Enumerable.Empty instead of null
- var value = property.GetValue(languageId, segment);
+ var value = property.GetValue(culture, segment);
// if value is null (strange but why not) it still is OK to call TryConvertTo
// because it's an extension method (hence no NullRef) which will return a
diff --git a/src/Umbraco.Web/PublishedElementExtensions.cs b/src/Umbraco.Web/PublishedElementExtensions.cs
index c2a818a926..bde74c0ab1 100644
--- a/src/Umbraco.Web/PublishedElementExtensions.cs
+++ b/src/Umbraco.Web/PublishedElementExtensions.cs
@@ -48,10 +48,10 @@ namespace Umbraco.Web
/// Gets a value indicating whether the content has a value for a property identified by its alias.
///
/// Returns true if GetProperty(alias) is not null and GetProperty(alias).HasValue is true.
- public static bool HasValue(this IPublishedElement content, string alias, int? languageId = null, string segment = null)
+ public static bool HasValue(this IPublishedElement content, string alias, string culture = null, string segment = null)
{
var prop = content.GetProperty(alias);
- return prop != null && prop.HasValue(languageId, segment);
+ return prop != null && prop.HasValue(culture, segment);
}
///
@@ -63,8 +63,7 @@ namespace Umbraco.Web
/// The value to return if the content has no value for the property.
/// Either or depending on whether the content
/// has a value for the property identified by the alias.
- public static IHtmlString HasValue(this IPublishedElement content, string alias,
- string valueIfTrue, string valueIfFalse = null)
+ public static IHtmlString IfHasValue(this IPublishedElement content, string alias, string valueIfTrue, string valueIfFalse = null)
{
return content.HasValue(alias)
? new HtmlString(valueIfTrue)
@@ -80,7 +79,7 @@ namespace Umbraco.Web
///
/// The content.
/// The property alias.
- /// The variation language.
+ /// The variation language.
/// The variation segment.
/// The value of the content's property identified by the alias.
///
@@ -89,10 +88,31 @@ namespace Umbraco.Web
/// If eg a numeric property wants to default to 0 when value source is empty, this has to be done in the converter.
/// The alias is case-insensitive.
///
- public static object Value(this IPublishedElement content, string alias, int? languageId = null, string segment = null)
+ public static object Value(this IPublishedElement content, string alias, string culture = null, string segment = null)
{
var property = content.GetProperty(alias);
- return property?.GetValue(languageId, segment);
+ return property?.GetValue(culture, segment);
+ }
+
+ ///
+ /// Gets the value of a content's property identified by its alias, if it exists, otherwise a default value.
+ ///
+ /// The content.
+ /// The property alias.
+ /// The default value.
+ /// The variation language.
+ /// The variation segment.
+ /// The value of the content's property identified by the alias, if it exists, otherwise a default value.
+ ///
+ /// The value comes from IPublishedProperty field Value ie it is suitable for use when rendering content.
+ /// If no property with the specified alias exists, or if the property has no value, returns .
+ /// If eg a numeric property wants to default to 0 when value source is empty, this has to be done in the converter.
+ /// The alias is case-insensitive.
+ ///
+ public static object Value(this IPublishedElement content, string alias, string defaultValue, string culture = null, string segment = null) // fixme - kill
+ {
+ var property = content.GetProperty(alias);
+ return property == null || property.HasValue(culture, segment) == false ? defaultValue : property.GetValue(culture, segment);
}
///
@@ -110,31 +130,10 @@ namespace Umbraco.Web
/// If eg a numeric property wants to default to 0 when value source is empty, this has to be done in the converter.
/// The alias is case-insensitive.
///
- public static object Value(this IPublishedElement content, string alias, string defaultValue, int? languageId = null, string segment = null) // fixme - kill
+ public static object Value(this IPublishedElement content, string alias, object defaultValue, string culture = null, string segment = null)
{
var property = content.GetProperty(alias);
- return property == null || property.HasValue(languageId, segment) == false ? defaultValue : property.GetValue(languageId, segment);
- }
-
- ///
- /// Gets the value of a content's property identified by its alias, if it exists, otherwise a default value.
- ///
- /// The content.
- /// The property alias.
- /// The default value.
- /// The variation language.
- /// The variation segment.
- /// The value of the content's property identified by the alias, if it exists, otherwise a default value.
- ///
- /// The value comes from IPublishedProperty field Value ie it is suitable for use when rendering content.
- /// If no property with the specified alias exists, or if the property has no value, returns .
- /// If eg a numeric property wants to default to 0 when value source is empty, this has to be done in the converter.
- /// The alias is case-insensitive.
- ///
- public static object Value(this IPublishedElement content, string alias, object defaultValue, int? languageId = null, string segment = null)
- {
- var property = content.GetProperty(alias);
- return property == null || property.HasValue(languageId, segment) == false ? defaultValue : property.GetValue(languageId, segment);
+ return property == null || property.HasValue(culture, segment) == false ? defaultValue : property.GetValue(culture, segment);
}
#endregion
@@ -147,7 +146,7 @@ namespace Umbraco.Web
/// The target property type.
/// The content.
/// The property alias.
- /// The variation language.
+ /// The variation language.
/// The variation segment.
/// The value of the content's property identified by the alias, converted to the specified type.
///
@@ -156,9 +155,9 @@ namespace Umbraco.Web
/// If eg a numeric property wants to default to 0 when value source is empty, this has to be done in the converter.
/// The alias is case-insensitive.
///
- public static T Value(this IPublishedElement content, string alias, int? languageId = null, string segment = null)
+ public static T Value(this IPublishedElement content, string alias, string culture = null, string segment = null)
{
- return content.Value(alias, false, default(T), languageId, segment);
+ return content.Value(alias, false, default(T), culture, segment);
}
///
@@ -168,7 +167,7 @@ namespace Umbraco.Web
/// The content.
/// The property alias.
/// The default value.
- /// The variation language.
+ /// The variation language.
/// The variation segment.
/// The value of the content's property identified by the alias, converted to the specified type, if it exists, otherwise a default value.
///
@@ -177,17 +176,17 @@ namespace Umbraco.Web
/// If eg a numeric property wants to default to 0 when value source is empty, this has to be done in the converter.
/// The alias is case-insensitive.
///
- public static T Value(this IPublishedElement content, string alias, T defaultValue, int? languageId = null, string segment = null)
+ public static T Value(this IPublishedElement content, string alias, T defaultValue, string culture = null, string segment = null)
{
- return content.Value(alias, true, defaultValue, languageId, segment);
+ return content.Value(alias, true, defaultValue, culture, segment);
}
- internal static T Value(this IPublishedElement content, string alias, bool withDefaultValue, T defaultValue, int? languageId = null, string segment = null) // fixme uh?
+ internal static T Value(this IPublishedElement content, string alias, bool withDefaultValue, T defaultValue, string culture = null, string segment = null) // fixme uh?
{
var property = content.GetProperty(alias);
if (property == null) return defaultValue;
- return property.Value(withDefaultValue, defaultValue, languageId, segment);
+ return property.Value(withDefaultValue, defaultValue, culture, segment);
}
#endregion
diff --git a/src/Umbraco.Web/WebApi/Binders/ContentItemBinder.cs b/src/Umbraco.Web/WebApi/Binders/ContentItemBinder.cs
index 0a399c24c5..525b1fcf2c 100644
--- a/src/Umbraco.Web/WebApi/Binders/ContentItemBinder.cs
+++ b/src/Umbraco.Web/WebApi/Binders/ContentItemBinder.cs
@@ -34,7 +34,7 @@ namespace Umbraco.Web.WebApi.Binders
{
return ContextMapper.Map>(content, new Dictionary
{
- [ContextMapper.LanguageKey] = languageId
+ [ContextMapper.CultureKey] = languageId
});
}
}
diff --git a/src/Umbraco.Web/umbraco.presentation/page.cs b/src/Umbraco.Web/umbraco.presentation/page.cs
index ad1ac877be..e940d01470 100644
--- a/src/Umbraco.Web/umbraco.presentation/page.cs
+++ b/src/Umbraco.Web/umbraco.presentation/page.cs
@@ -374,17 +374,17 @@ namespace umbraco
_content = content;
}
- public override bool HasValue(int? languageId = null, string segment = null)
+ public override bool HasValue(string culture = null, string segment = null)
{
return _sourceValue != null && ((_sourceValue is string) == false || string.IsNullOrWhiteSpace((string)_sourceValue) == false);
}
- public override object GetSourceValue(int? languageId = null, string segment = null)
+ public override object GetSourceValue(string culture = null, string segment = null)
{
return _sourceValue;
}
- public override object GetValue(int? languageId = null, string segment = null)
+ public override object GetValue(string culture = null, string segment = null)
{
// isPreviewing is true here since we want to preview anyway...
const bool isPreviewing = true;
@@ -392,7 +392,7 @@ namespace umbraco
return PropertyType.ConvertInterToObject(_content, PropertyCacheLevel.Unknown, source, isPreviewing);
}
- public override object GetXPathValue(int? languageId = null, string segment = null)
+ public override object GetXPathValue(string culture = null, string segment = null)
{
throw new NotImplementedException();
}