diff --git a/src/Umbraco.Core/Models/PublishedContent/IPublishedProperty.cs b/src/Umbraco.Core/Models/PublishedContent/IPublishedProperty.cs index d78ced95a7..1fd9cda069 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 { get; } + bool HasValue(int? languageId = 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 SourceValue { get; } + object GetSourceValue(int? languageId = 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 Value { get; } + object GetValue(int? languageId = 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 XPathValue { get; } + object GetXPathValue(int? languageId = null, string segment = null); } } diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedPropertyBase.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedPropertyBase.cs index 9166831862..34b2ba9495 100644 --- a/src/Umbraco.Core/Models/PublishedContent/PublishedPropertyBase.cs +++ b/src/Umbraco.Core/Models/PublishedContent/PublishedPropertyBase.cs @@ -40,9 +40,9 @@ namespace Umbraco.Core.Models.PublishedContent public PropertyCacheLevel ReferenceCacheLevel { get; } // these have to be provided by the actual implementation - public abstract bool HasValue { get; } - public abstract object SourceValue { get; } - public abstract object Value { get; } - public abstract object XPathValue { get; } + public abstract bool HasValue(int? languageId = null, string segment = null); + public abstract object GetSourceValue(int? languageId = null, string segment = null); + public abstract object GetValue(int? languageId = null, string segment = null); + public abstract object GetXPathValue(int? languageId = null, string segment = null); } } diff --git a/src/Umbraco.Core/Models/PublishedContent/RawValueProperty.cs b/src/Umbraco.Core/Models/PublishedContent/RawValueProperty.cs index cc7be8ad7f..d81a8962dc 100644 --- a/src/Umbraco.Core/Models/PublishedContent/RawValueProperty.cs +++ b/src/Umbraco.Core/Models/PublishedContent/RawValueProperty.cs @@ -15,13 +15,13 @@ namespace Umbraco.Core.Models.PublishedContent private readonly Lazy _objectValue; private readonly Lazy _xpathValue; - public override object SourceValue => _propertyData; + public override object GetSourceValue(int? languageId = null, string segment = null) => _propertyData; - public override bool HasValue => _propertyData is string s ? !string.IsNullOrWhiteSpace(s) : _propertyData != null; + public override bool HasValue(int? languageId = null, string segment = null) => _propertyData is string s ? !string.IsNullOrWhiteSpace(s) : _propertyData != null; - public override object Value => _objectValue.Value; + public override object GetValue(int? languageId = null, string segment = null) => _objectValue.Value; - public override object XPathValue => _xpathValue.Value; + public override object GetXPathValue(int? languageId = null, string segment = null) => _xpathValue.Value; public RawValueProperty(PublishedPropertyType propertyType, IPublishedElement content, object propertyData, bool isPreviewing = false) : base(propertyType, PropertyCacheLevel.Unknown) // cache level is ignored diff --git a/src/Umbraco.Tests/Published/NestedContentTests.cs b/src/Umbraco.Tests/Published/NestedContentTests.cs index 397b571fb2..7c5bb494d6 100644 --- a/src/Umbraco.Tests/Published/NestedContentTests.cs +++ b/src/Umbraco.Tests/Published/NestedContentTests.cs @@ -205,35 +205,37 @@ namespace Umbraco.Tests.Published class TestPublishedProperty : PublishedPropertyBase { private readonly bool _preview; + private readonly object _sourceValue; + private readonly bool _hasValue; private IPublishedElement _owner; public TestPublishedProperty(PublishedPropertyType propertyType, object source) : base(propertyType, PropertyCacheLevel.Element) // initial reference cache level always is .Content { - SourceValue = source; - HasValue = source != null && (!(source is string ssource) || !string.IsNullOrWhiteSpace(ssource)); + _sourceValue = source; + _hasValue = source != null && (!(source is string ssource) || !string.IsNullOrWhiteSpace(ssource)); } public TestPublishedProperty(PublishedPropertyType propertyType, IPublishedElement element, bool preview, PropertyCacheLevel referenceCacheLevel, object source) : base(propertyType, referenceCacheLevel) { - SourceValue = source; - HasValue = source != null && (!(source is string ssource) || !string.IsNullOrWhiteSpace(ssource)); + _sourceValue = source; + _hasValue = source != null && (!(source is string ssource) || !string.IsNullOrWhiteSpace(ssource)); _owner = element; _preview = preview; } - private object InterValue => PropertyType.ConvertSourceToInter(null, SourceValue, false); + private object InterValue => PropertyType.ConvertSourceToInter(null, _sourceValue, false); internal void SetOwner(IPublishedElement owner) { _owner = owner; } - public override bool HasValue { get; } - public override object SourceValue { get; } - public override object Value => PropertyType.ConvertInterToObject(_owner, ReferenceCacheLevel, InterValue, _preview); - public override object XPathValue => throw new WontImplementException(); + 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(); } class TestPublishedContent : PublishedContentBase diff --git a/src/Umbraco.Tests/Published/PublishedSnapshotTestObjects.cs b/src/Umbraco.Tests/Published/PublishedSnapshotTestObjects.cs index 84668f97a5..48495b2ae7 100644 --- a/src/Umbraco.Tests/Published/PublishedSnapshotTestObjects.cs +++ b/src/Umbraco.Tests/Published/PublishedSnapshotTestObjects.cs @@ -92,7 +92,7 @@ namespace Umbraco.Tests.Published IPublishedContent content = this; var firstNonNullProperty = property; - while (content != null && (property == null || property.HasValue == false)) + while (content != null && (property == null || property.HasValue() == false)) { content = content.Parent; property = content?.GetProperty(alias); @@ -104,7 +104,7 @@ namespace Umbraco.Tests.Published // if we find a content with the property without a value, return that property // have to save that first property while we look further up, hence firstNonNullProperty - return property != null && property.HasValue ? property : firstNonNullProperty; + return property != null && property.HasValue() ? property : firstNonNullProperty; } } diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentDataTableTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentDataTableTests.cs index a6d00e3935..9aa6037374 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedContentDataTableTests.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedContentDataTableTests.cs @@ -225,7 +225,7 @@ namespace Umbraco.Tests.PublishedContent if (recurse == false) return property; IPublishedContent content = this; - while (content != null && (property == null || property.HasValue == false)) + while (content != null && (property == null || property.HasValue() == false)) { content = content.Parent; property = content == null ? null : content.GetProperty(alias); diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs index 742b6bd4c6..cf82e0844d 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs @@ -220,9 +220,9 @@ namespace Umbraco.Tests.PublishedContent new SolidPublishedProperty { PropertyTypeAlias = "prop1", - HasValue = true, - Value = 1234, - SourceValue = "1234" + SolidHasValue = true, + SolidValue = 1234, + SolidSourceValue = "1234" } } }); @@ -243,9 +243,9 @@ namespace Umbraco.Tests.PublishedContent new SolidPublishedProperty { PropertyTypeAlias = "prop1", - HasValue = true, - Value = 1234, - SourceValue = "1234" + SolidHasValue = true, + SolidValue = 1234, + SolidSourceValue = "1234" } } }); @@ -266,9 +266,9 @@ namespace Umbraco.Tests.PublishedContent new SolidPublishedProperty { PropertyTypeAlias = "prop1", - HasValue = true, - Value = 1234, - SourceValue = "1234" + SolidHasValue = true, + SolidValue = 1234, + SolidSourceValue = "1234" } } }); diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentTestElements.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentTestElements.cs index b707467449..fa5ec7c160 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedContentTestElements.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedContentTestElements.cs @@ -224,7 +224,7 @@ namespace Umbraco.Tests.PublishedContent if (recurse == false) return property; IPublishedContent content = this; - while (content != null && (property == null || property.HasValue == false)) + while (content != null && (property == null || property.HasValue() == false)) { content = content.Parent; property = content == null ? null : content.GetProperty(alias); @@ -238,7 +238,7 @@ namespace Umbraco.Tests.PublishedContent get { var property = GetProperty(alias); - return property == null || property.HasValue == false ? null : property.Value; + return property == null || property.HasValue() == false ? null : property.GetValue(); } } @@ -247,16 +247,16 @@ namespace Umbraco.Tests.PublishedContent class SolidPublishedProperty : IPublishedProperty { - public SolidPublishedProperty() - { - // initialize boring stuff - } - public string PropertyTypeAlias { get; set; } - public object SourceValue { get; set; } - public object Value { get; set; } - public bool HasValue { get; set; } - public object XPathValue { get; set; } + public object SolidSourceValue { get; set; } + public object SolidValue { get; set; } + 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; } [PublishedModel("ContentType2")] diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs index d96034a8c4..40939630c1 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs @@ -556,8 +556,8 @@ namespace Umbraco.Tests.PublishedContent var pt = factory.CreatePropertyType("detached", 0, Constants.PropertyEditors.IntegerAlias); var ct = factory.CreateContentType(0, "alias", new[] { pt }); var prop = new PublishedElementPropertyBase(pt, null, false, PropertyCacheLevel.None, 5548); - Assert.IsInstanceOf(prop.Value); - Assert.AreEqual(5548, prop.Value); + Assert.IsInstanceOf(prop.GetValue()); + Assert.AreEqual(5548, prop.GetValue()); } public void Fragment1() diff --git a/src/Umbraco.Web/GridTemplateExtensions.cs b/src/Umbraco.Web/GridTemplateExtensions.cs index 6f37baa6ac..174ac3fc1f 100644 --- a/src/Umbraco.Web/GridTemplateExtensions.cs +++ b/src/Umbraco.Web/GridTemplateExtensions.cs @@ -21,11 +21,11 @@ namespace Umbraco.Web { public static MvcHtmlString GetGridHtml(this HtmlHelper html, IPublishedProperty property, string framework = "bootstrap3") { - var asString = property.Value as string; + var asString = property.GetValue() as string; if (asString != null && string.IsNullOrEmpty(asString)) return new MvcHtmlString(string.Empty); var view = "Grid/" + framework; - return html.Partial(view, property.Value); + return html.Partial(view, property.GetValue()); } public static MvcHtmlString GetGridHtml(this HtmlHelper html, IPublishedContent contentItem) @@ -47,7 +47,7 @@ namespace Umbraco.Web var view = "Grid/" + framework; var prop = contentItem.GetProperty(propertyAlias); if (prop == null) throw new NullReferenceException("No property type found with alias " + propertyAlias); - var model = prop.Value; + var model = prop.GetValue(); var asString = model as string; if (asString != null && string.IsNullOrEmpty(asString)) return new MvcHtmlString(string.Empty); @@ -57,11 +57,11 @@ namespace Umbraco.Web public static MvcHtmlString GetGridHtml(this IPublishedProperty property, HtmlHelper html, string framework = "bootstrap3") { - var asString = property.Value as string; + var asString = property.GetValue() as string; if (asString != null && string.IsNullOrEmpty(asString)) return new MvcHtmlString(string.Empty); var view = "Grid/" + framework; - return html.Partial(view, property.Value); + return html.Partial(view, property.GetValue()); } public static MvcHtmlString GetGridHtml(this IPublishedContent contentItem, HtmlHelper html) { @@ -80,7 +80,7 @@ namespace Umbraco.Web var view = "Grid/" + framework; var prop = contentItem.GetProperty(propertyAlias); if (prop == null) throw new NullReferenceException("No property type found with alias " + propertyAlias); - var model = prop.Value; + var model = prop.GetValue(); var asString = model as string; if (asString != null && string.IsNullOrEmpty(asString)) return new MvcHtmlString(string.Empty); @@ -92,10 +92,10 @@ namespace Umbraco.Web [Obsolete("This should not be used, GetGridHtml methods accepting HtmlHelper as a parameter or GetGridHtml extensions on HtmlHelper should be used instead")] public static MvcHtmlString GetGridHtml(this IPublishedProperty property, string framework = "bootstrap3") { - var asString = property.Value as string; + var asString = property.GetValue() as string; if (asString != null && string.IsNullOrEmpty(asString)) return new MvcHtmlString(string.Empty); - var htmlHelper = CreateHtmlHelper(property.Value); + var htmlHelper = CreateHtmlHelper(property.GetValue()); return htmlHelper.GetGridHtml(property, framework); } @@ -120,7 +120,7 @@ namespace Umbraco.Web var prop = contentItem.GetProperty(propertyAlias); if (prop == null) throw new NullReferenceException("No property type found with alias " + propertyAlias); - var model = prop.Value; + var model = prop.GetValue(); var asString = model as string; if (asString != null && string.IsNullOrEmpty(asString)) return new MvcHtmlString(string.Empty); diff --git a/src/Umbraco.Web/Models/PublishedContentBase.cs b/src/Umbraco.Web/Models/PublishedContentBase.cs index 8dd3c3ee5a..25f43ca42a 100644 --- a/src/Umbraco.Web/Models/PublishedContentBase.cs +++ b/src/Umbraco.Web/Models/PublishedContentBase.cs @@ -50,7 +50,7 @@ namespace Umbraco.Web.Models break; case PublishedItemType.Media: var prop = GetProperty(Constants.Conventions.Media.File); - if (prop == null || prop.Value == null) + if (prop == null || prop.GetValue() == null) { _url = string.Empty; return _url; @@ -63,26 +63,26 @@ namespace Umbraco.Web.Models switch (propType.PropertyEditorAlias) { case Constants.PropertyEditors.UploadFieldAlias: - _url = prop.Value.ToString(); + _url = prop.GetValue().ToString(); break; case Constants.PropertyEditors.ImageCropperAlias: //get the url from the json format - var stronglyTyped = prop.Value as ImageCropDataSet; + var stronglyTyped = prop.GetValue() as ImageCropDataSet; if (stronglyTyped != null) { _url = stronglyTyped.Src; break; } - var json = prop.Value as JObject; + var json = prop.GetValue() as JObject; if (json != null) { _url = json.ToObject(new JsonSerializer { Culture = CultureInfo.InvariantCulture, FloatParseHandling = FloatParseHandling.Decimal }).Src; break; } - _url = prop.Value.ToString(); + _url = prop.GetValue().ToString(); break; } break; @@ -175,7 +175,7 @@ namespace Umbraco.Web.Models IPublishedContent content = this; var firstNonNullProperty = property; - while (content != null && (property == null || property.HasValue == false)) + while (content != null && (property == null || property.HasValue() == false)) { content = content.Parent; property = content?.GetProperty(alias); @@ -187,7 +187,7 @@ namespace Umbraco.Web.Models // if we find a content with the property without a value, return that property // have to save that first property while we look further up, hence firstNonNullProperty - return property != null && property.HasValue ? property : firstNonNullProperty; + return property != null && property.HasValue() ? property : firstNonNullProperty; } #endregion diff --git a/src/Umbraco.Web/PublishedCache/NuCache/Navigable/NavigableContent.cs b/src/Umbraco.Web/PublishedCache/NuCache/Navigable/NavigableContent.cs index 9b72616536..b5a09d43ca 100644 --- a/src/Umbraco.Web/PublishedCache/NuCache/Navigable/NavigableContent.cs +++ b/src/Umbraco.Web/PublishedCache/NuCache/Navigable/NavigableContent.cs @@ -89,7 +89,7 @@ namespace Umbraco.Web.PublishedCache.NuCache.Navigable throw new ArgumentOutOfRangeException(nameof(index)); // custom property, ie element - return properties[index].XPathValue; + return properties[index].GetXPathValue(); } #endregion diff --git a/src/Umbraco.Web/PublishedCache/NuCache/Property.cs b/src/Umbraco.Web/PublishedCache/NuCache/Property.cs index 8a10051620..b3e4d61f4b 100644 --- a/src/Umbraco.Web/PublishedCache/NuCache/Property.cs +++ b/src/Umbraco.Web/PublishedCache/NuCache/Property.cs @@ -54,7 +54,7 @@ namespace Umbraco.Web.PublishedCache.NuCache _publishedSnapshotAccessor = origin._publishedSnapshotAccessor; } - public override bool HasValue => _sourceValue != null + public override bool HasValue(int? languageId = null, string segment = null) => _sourceValue != null && (!(_sourceValue is string) || string.IsNullOrWhiteSpace((string) _sourceValue) == false); private class CacheValues @@ -129,39 +129,33 @@ namespace Umbraco.Web.PublishedCache.NuCache return _interValue; } - public override object SourceValue => _sourceValue; + public override object GetSourceValue(int? languageId = null, string segment = null) => _sourceValue; - public override object Value + public override object GetValue(int? languageId = null, string segment = null) { - get + lock (_locko) { - lock (_locko) - { - var cacheValues = GetCacheValues(PropertyType.CacheLevel); - if (cacheValues.ObjectInitialized) return cacheValues.ObjectValue; + var cacheValues = GetCacheValues(PropertyType.CacheLevel); + if (cacheValues.ObjectInitialized) return cacheValues.ObjectValue; - // initial reference cache level always is .Content - cacheValues.ObjectValue = PropertyType.ConvertInterToObject(_content, PropertyCacheLevel.Element, GetInterValue(), _isPreviewing); - cacheValues.ObjectInitialized = true; - return cacheValues.ObjectValue; - } + // initial reference cache level always is .Content + cacheValues.ObjectValue = PropertyType.ConvertInterToObject(_content, PropertyCacheLevel.Element, GetInterValue(), _isPreviewing); + cacheValues.ObjectInitialized = true; + return cacheValues.ObjectValue; } } - public override object XPathValue + public override object GetXPathValue(int? languageId = null, string segment = null) { - get + lock (_locko) { - lock (_locko) - { - var cacheValues = GetCacheValues(PropertyType.CacheLevel); - if (cacheValues.XPathInitialized) return cacheValues.XPathValue; + var cacheValues = GetCacheValues(PropertyType.CacheLevel); + if (cacheValues.XPathInitialized) return cacheValues.XPathValue; - // initial reference cache level always is .Content - cacheValues.XPathValue = PropertyType.ConvertInterToXPath(_content, PropertyCacheLevel.Element, GetInterValue(), _isPreviewing); - cacheValues.XPathInitialized = true; - return cacheValues.XPathValue; - } + // initial reference cache level always is .Content + cacheValues.XPathValue = PropertyType.ConvertInterToXPath(_content, PropertyCacheLevel.Element, GetInterValue(), _isPreviewing); + cacheValues.XPathInitialized = true; + return cacheValues.XPathValue; } } } diff --git a/src/Umbraco.Web/PublishedCache/PublishedElementPropertyBase.cs b/src/Umbraco.Web/PublishedCache/PublishedElementPropertyBase.cs index 91681558ac..0dbbf4944c 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 + public override bool HasValue(int? languageId = null, string segment = null) => _sourceValue != null && (!(_sourceValue is string s) || !string.IsNullOrWhiteSpace(s)); // used to cache the CacheValues of this property @@ -136,39 +136,33 @@ namespace Umbraco.Web.PublishedCache return _interValue; } - public override object SourceValue => _sourceValue; + public override object GetSourceValue(int? languageId = null, string segment = null) => _sourceValue; - public override object Value + public override object GetValue(int? languageId = null, string segment = null) { - get - { - GetCacheLevels(out var cacheLevel, out var referenceCacheLevel); + GetCacheLevels(out var cacheLevel, out var referenceCacheLevel); - lock (_locko) - { - var cacheValues = GetCacheValues(cacheLevel); - if (cacheValues.ObjectInitialized) return cacheValues.ObjectValue; - cacheValues.ObjectValue = PropertyType.ConvertInterToObject(Element, referenceCacheLevel, GetInterValue(), IsPreviewing); - cacheValues.ObjectInitialized = true; - return cacheValues.ObjectValue; - } + lock (_locko) + { + var cacheValues = GetCacheValues(cacheLevel); + if (cacheValues.ObjectInitialized) return cacheValues.ObjectValue; + cacheValues.ObjectValue = PropertyType.ConvertInterToObject(Element, referenceCacheLevel, GetInterValue(), IsPreviewing); + cacheValues.ObjectInitialized = true; + return cacheValues.ObjectValue; } } - public override object XPathValue + public override object GetXPathValue(int? languageId = null, string segment = null) { - get - { - GetCacheLevels(out var cacheLevel, out var referenceCacheLevel); + GetCacheLevels(out var cacheLevel, out var referenceCacheLevel); - lock (_locko) - { - var cacheValues = GetCacheValues(cacheLevel); - if (cacheValues.XPathInitialized) return cacheValues.XPathValue; - cacheValues.XPathValue = PropertyType.ConvertInterToXPath(Element, referenceCacheLevel, GetInterValue(), IsPreviewing); - cacheValues.XPathInitialized = true; - return cacheValues.XPathValue; - } + lock (_locko) + { + var cacheValues = GetCacheValues(cacheLevel); + if (cacheValues.XPathInitialized) return cacheValues.XPathValue; + cacheValues.XPathValue = PropertyType.ConvertInterToXPath(Element, referenceCacheLevel, GetInterValue(), IsPreviewing); + cacheValues.XPathInitialized = true; + return cacheValues.XPathValue; } } } diff --git a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlPublishedProperty.cs b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlPublishedProperty.cs index b23919f0c5..632698c37e 100644 --- a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlPublishedProperty.cs +++ b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlPublishedProperty.cs @@ -27,31 +27,28 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache /// /// Gets the raw value of the property. /// - public override object SourceValue => _sourceValue; + public override object GetSourceValue(int? languageId = 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 => _sourceValue.Trim().Length > 0; + public override bool HasValue(int? languageId = null, string segment = null) => _sourceValue.Trim().Length > 0; - public override object Value + public override object GetValue(int? languageId = null, string segment = null) { - get - { - // NOT caching the source (intermediate) value since we'll never need it - // everything in Xml cache is per-request anyways - // also, properties should not be shared between requests and therefore - // are single threaded, so the following code should be safe & fast + // NOT caching the source (intermediate) value since we'll never need it + // everything in Xml cache is per-request anyways + // also, properties should not be shared between requests and therefore + // are single threaded, so the following code should be safe & fast - if (_objectValueComputed) return _objectValue; - var inter = PropertyType.ConvertSourceToInter(_content, _sourceValue, _isPreviewing); - // initial reference cache level always is .Content - _objectValue = PropertyType.ConvertInterToObject(_content, PropertyCacheLevel.Element, inter, _isPreviewing); - _objectValueComputed = true; - return _objectValue; - } + if (_objectValueComputed) return _objectValue; + var inter = PropertyType.ConvertSourceToInter(_content, _sourceValue, _isPreviewing); + // initial reference cache level always is .Content + _objectValue = PropertyType.ConvertInterToObject(_content, PropertyCacheLevel.Element, inter, _isPreviewing); + _objectValueComputed = true; + return _objectValue; } - public override object XPathValue { get { throw new NotImplementedException(); } } + public override object GetXPathValue(int? languageId = 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/PublishedContentExtensions.cs b/src/Umbraco.Web/PublishedContentExtensions.cs index 4f637d7dbd..edf32c2a1d 100644 --- a/src/Umbraco.Web/PublishedContentExtensions.cs +++ b/src/Umbraco.Web/PublishedContentExtensions.cs @@ -97,7 +97,7 @@ namespace Umbraco.Web public static bool HasValue(this IPublishedContent content, string alias, bool recurse) { var prop = content.GetProperty(alias, recurse); - return prop != null && prop.HasValue; + return prop != null && prop.HasValue(); } /// @@ -139,7 +139,7 @@ namespace Umbraco.Web public static object Value(this IPublishedContent content, string alias, bool recurse) { var property = content.GetProperty(alias, recurse); - return property?.Value; + return property?.GetValue(); } /// @@ -160,7 +160,7 @@ namespace Umbraco.Web public static object Value(this IPublishedContent content, string alias, bool recurse, object defaultValue) { var property = content.GetProperty(alias, recurse); - return property == null || property.HasValue == false ? defaultValue : property.Value; + return property == null || property.HasValue() == false ? defaultValue : property.GetValue(); } #endregion @@ -1137,10 +1137,10 @@ namespace Umbraco.Web }; var userVals = new Dictionary(); - foreach (var p in from IPublishedProperty p in n.Properties where p.SourceValue != null select p) + foreach (var p in from IPublishedProperty p in n.Properties where p.GetSourceValue() != null select p) { // probably want the "object value" of the property here... - userVals[p.PropertyTypeAlias] = p.Value; + userVals[p.PropertyTypeAlias] = p.GetValue(); } //add the row data Core.DataTableExtensions.AddRowData(tableData, standardVals, userVals); diff --git a/src/Umbraco.Web/PublishedContentPropertyExtension.cs b/src/Umbraco.Web/PublishedContentPropertyExtension.cs index 2575bcde04..3314bc09fc 100644 --- a/src/Umbraco.Web/PublishedContentPropertyExtension.cs +++ b/src/Umbraco.Web/PublishedContentPropertyExtension.cs @@ -1,7 +1,5 @@ using Umbraco.Core; -using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; -using Umbraco.Web.PropertyEditors; namespace Umbraco.Web { @@ -12,24 +10,24 @@ namespace Umbraco.Web { #region Value - public static T Value(this IPublishedProperty property) + public static T Value(this IPublishedProperty property, int? languageId = null, string segment = null) { - return property.Value(false, default(T)); + return property.Value(false, default(T), languageId, segment); } - public static T Value(this IPublishedProperty property, T defaultValue) + public static T Value(this IPublishedProperty property, T defaultValue, int? languageId = null, string segment = null) { - return property.Value(true, defaultValue); + return property.Value(true, defaultValue, languageId, segment); } - internal static T Value(this IPublishedProperty property, bool withDefaultValue, T defaultValue) + internal static T Value(this IPublishedProperty property, bool withDefaultValue, T defaultValue, int? languageId = null, string segment = null) { - if (property.HasValue == false && withDefaultValue) return defaultValue; + if (property.HasValue(languageId, 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.Value; + var value = property.GetValue(languageId, 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 7a21a7e1c3..c2a818a926 100644 --- a/src/Umbraco.Web/PublishedElementExtensions.cs +++ b/src/Umbraco.Web/PublishedElementExtensions.cs @@ -47,14 +47,11 @@ namespace Umbraco.Web /// /// Gets a value indicating whether the content has a value for a property identified by its alias. /// - /// The content. - /// The property alias. - /// A value indicating whether the content has a value for the property identified by the alias. /// Returns true if GetProperty(alias) is not null and GetProperty(alias).HasValue is true. - public static bool HasValue(this IPublishedElement content, string alias) + public static bool HasValue(this IPublishedElement content, string alias, int? languageId = null, string segment = null) { var prop = content.GetProperty(alias); - return prop != null && prop.HasValue; + return prop != null && prop.HasValue(languageId, segment); } /// @@ -83,6 +80,8 @@ namespace Umbraco.Web /// /// The content. /// The property alias. + /// The variation language. + /// The variation segment. /// The value of the content's property identified by the alias. /// /// The value comes from IPublishedProperty field Value ie it is suitable for use when rendering content. @@ -90,10 +89,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) + public static object Value(this IPublishedElement content, string alias, int? languageId = null, string segment = null) { var property = content.GetProperty(alias); - return property?.Value; + return property?.GetValue(languageId, segment); } /// @@ -102,6 +101,8 @@ namespace Umbraco.Web /// 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. @@ -109,10 +110,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) // fixme - kill + public static object Value(this IPublishedElement content, string alias, string defaultValue, int? languageId = null, string segment = null) // fixme - kill { var property = content.GetProperty(alias); - return property == null || property.HasValue == false ? defaultValue : property.Value; + return property == null || property.HasValue(languageId, segment) == false ? defaultValue : property.GetValue(languageId, segment); } /// @@ -121,6 +122,8 @@ namespace Umbraco.Web /// 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. @@ -128,10 +131,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, object defaultValue) + 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 == false ? defaultValue : property.Value; + return property == null || property.HasValue(languageId, segment) == false ? defaultValue : property.GetValue(languageId, segment); } #endregion @@ -144,6 +147,8 @@ namespace Umbraco.Web /// The target property type. /// The content. /// The property alias. + /// The variation language. + /// The variation segment. /// The value of the content's property identified by the alias, converted to the specified type. /// /// The value comes from IPublishedProperty field Value ie it is suitable for use when rendering content. @@ -151,9 +156,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) + public static T Value(this IPublishedElement content, string alias, int? languageId = null, string segment = null) { - return content.Value(alias, false, default(T)); + return content.Value(alias, false, default(T), languageId, segment); } /// @@ -163,6 +168,8 @@ namespace Umbraco.Web /// 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, converted to the specified type, if it exists, otherwise a default value. /// /// The value comes from IPublishedProperty field Value ie it is suitable for use when rendering content. @@ -170,22 +177,22 @@ 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) + public static T Value(this IPublishedElement content, string alias, T defaultValue, int? languageId = null, string segment = null) { - return content.Value(alias, true, defaultValue); + return content.Value(alias, true, defaultValue, languageId, segment); } - internal static T Value(this IPublishedElement content, string alias, bool withDefaultValue, T defaultValue) // fixme uh? + internal static T Value(this IPublishedElement content, string alias, bool withDefaultValue, T defaultValue, int? languageId = null, string segment = null) // fixme uh? { var property = content.GetProperty(alias); if (property == null) return defaultValue; - return property.Value(withDefaultValue, defaultValue); + return property.Value(withDefaultValue, defaultValue, languageId, segment); } #endregion - #region Value + #region Value or Umbraco.Field - WORK IN PROGRESS // trying to reproduce Umbraco.Field so we can get rid of it // diff --git a/src/Umbraco.Web/Routing/PublishedRouter.cs b/src/Umbraco.Web/Routing/PublishedRouter.cs index aef4c5e8a2..5f832fd97a 100644 --- a/src/Umbraco.Web/Routing/PublishedRouter.cs +++ b/src/Umbraco.Web/Routing/PublishedRouter.cs @@ -557,12 +557,12 @@ namespace Umbraco.Web.Routing if (valid == false) { // bad redirect - log and display the current page (legacy behavior) - _logger.Debug($"{tracePrefix}Failed to redirect to id={request.PublishedContent.GetProperty(Constants.Conventions.Content.InternalRedirectId).SourceValue}: value is not an int nor a GuidUdi."); + _logger.Debug($"{tracePrefix}Failed to redirect to id={request.PublishedContent.GetProperty(Constants.Conventions.Content.InternalRedirectId).GetSourceValue()}: value is not an int nor a GuidUdi."); } if (internalRedirectNode == null) { - _logger.Debug($"{tracePrefix}Failed to redirect to id={request.PublishedContent.GetProperty(Constants.Conventions.Content.InternalRedirectId).SourceValue}: no such published document."); + _logger.Debug($"{tracePrefix}Failed to redirect to id={request.PublishedContent.GetProperty(Constants.Conventions.Content.InternalRedirectId).GetSourceValue()}: no such published document."); } else if (internalRedirectId == request.PublishedContent.Id) { diff --git a/src/Umbraco.Web/umbraco.presentation/library.cs b/src/Umbraco.Web/umbraco.presentation/library.cs index c3a27f3438..af2a5359dc 100644 --- a/src/Umbraco.Web/umbraco.presentation/library.cs +++ b/src/Umbraco.Web/umbraco.presentation/library.cs @@ -213,7 +213,7 @@ namespace umbraco // // so, use Value.ToString() here. var prop = doc.GetProperty(alias); - return prop == null ? string.Empty : prop.Value.ToString(); + return prop == null ? string.Empty : prop.GetValue().ToString(); } /// diff --git a/src/Umbraco.Web/umbraco.presentation/page.cs b/src/Umbraco.Web/umbraco.presentation/page.cs index 258ae93d6c..1311e28ab5 100644 --- a/src/Umbraco.Web/umbraco.presentation/page.cs +++ b/src/Umbraco.Web/umbraco.presentation/page.cs @@ -213,7 +213,7 @@ namespace umbraco // to properly fix this, we'd need to turn the elements collection into some // sort of collection of lazy values. - _elements[p.PropertyTypeAlias] = p.SourceValue; + _elements[p.PropertyTypeAlias] = p.GetSourceValue(); } } } @@ -374,30 +374,27 @@ namespace umbraco _content = content; } - public override bool HasValue + public override bool HasValue(int? languageId = null, string segment = null) { - get { return _sourceValue != null && ((_sourceValue is string) == false || string.IsNullOrWhiteSpace((string)_sourceValue) == false); } + return _sourceValue != null && ((_sourceValue is string) == false || string.IsNullOrWhiteSpace((string)_sourceValue) == false); } - public override object SourceValue + public override object GetSourceValue(int? languageId = null, string segment = null) { - get { return _sourceValue; } + return _sourceValue; } - public override object Value + public override object GetValue(int? languageId = null, string segment = null) { - get - { - // isPreviewing is true here since we want to preview anyway... - const bool isPreviewing = true; - var source = PropertyType.ConvertSourceToInter(_content, _sourceValue, isPreviewing); - return PropertyType.ConvertInterToObject(_content, PropertyCacheLevel.Unknown, source, isPreviewing); - } + // isPreviewing is true here since we want to preview anyway... + const bool isPreviewing = true; + var source = PropertyType.ConvertSourceToInter(_content, _sourceValue, isPreviewing); + return PropertyType.ConvertInterToObject(_content, PropertyCacheLevel.Unknown, source, isPreviewing); } - public override object XPathValue + public override object GetXPathValue(int? languageId = null, string segment = null) { - get { throw new NotImplementedException(); } + throw new NotImplementedException(); } }