Files
Umbraco-CMS/src/Umbraco.Web/Models/PublishedContentBase.cs

202 lines
7.4 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using System.Diagnostics;
2016-02-04 17:14:29 +01:00
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Umbraco.Core;
using Umbraco.Core.Models;
2013-09-05 17:47:13 +02:00
using Umbraco.Core.Models.PublishedContent;
2018-01-24 13:37:14 +01:00
using Umbraco.Core.PropertyEditors.ValueConverters;
namespace Umbraco.Web.Models
{
/// <summary>
2013-09-05 17:47:13 +02:00
/// Provide an abstract base class for <c>IPublishedContent</c> implementations.
2017-07-20 11:21:28 +02:00
/// </summary>
/// <remarks>This base class does which (a) consitently resolves and caches the Url, (b) provides an implementation
2013-09-05 17:47:13 +02:00
/// for this[alias], and (c) provides basic content set management.</remarks>
[DebuggerDisplay("Content Id: {Id}, Name: {Name}")]
2013-09-05 17:47:13 +02:00
public abstract class PublishedContentBase : IPublishedContent
{
private string _url;
2018-04-28 16:34:43 +02:00
#region ContentType
public abstract PublishedContentType ContentType { get; }
#endregion
#region PublishedElement
/// <inheritdoc />
public abstract Guid Key { get; }
#endregion
#region PublishedContent
/// <inheritdoc />
public abstract int Id { get; }
/// <inheritdoc />
public abstract string Name { get; }
/// <inheritdoc />
2018-04-28 16:35:33 +02:00
public abstract string UrlSegment { get; }
2018-04-28 16:34:43 +02:00
/// <inheritdoc />
public abstract int SortOrder { get; }
/// <inheritdoc />
public abstract int Level { get; }
/// <inheritdoc />
public abstract string Path { get; }
/// <inheritdoc />
public abstract int TemplateId { get; }
/// <inheritdoc />
public abstract int CreatorId { get; }
/// <inheritdoc />
public abstract string CreatorName { get; }
/// <inheritdoc />
public abstract DateTime CreateDate { get; }
/// <inheritdoc />
public abstract int WriterId { get; }
/// <inheritdoc />
public abstract string WriterName { get; }
2018-04-28 16:34:43 +02:00
/// <inheritdoc />
public abstract DateTime UpdateDate { get; }
/// <inheritdoc />
2017-07-20 11:21:28 +02:00
/// <remarks>
2018-04-28 16:34:43 +02:00
/// The url of documents are computed by the document url providers. The url of medias are, at the moment,
/// computed here from the 'umbracoFile' property -- but we should move to media url providers at some point.
2017-07-20 11:21:28 +02:00
/// </remarks>
public virtual string Url
{
2018-04-28 16:34:43 +02:00
// fixme contextual!
2017-07-20 11:21:28 +02:00
get
{
// should be thread-safe although it won't prevent url from being resolved more than once
if (_url != null)
2018-04-28 16:34:43 +02:00
return _url; // fixme very bad idea with nucache? or?
2017-07-20 11:21:28 +02:00
switch (ItemType)
{
case PublishedItemType.Content:
if (UmbracoContext.Current == null)
throw new InvalidOperationException(
"Cannot resolve a Url for a content item when UmbracoContext.Current is null.");
if (UmbracoContext.Current.UrlProvider == null)
throw new InvalidOperationException(
"Cannot resolve a Url for a content item when UmbracoContext.Current.UrlProvider is null.");
_url = UmbracoContext.Current.UrlProvider.GetUrl(Id);
break;
case PublishedItemType.Media:
var prop = GetProperty(Constants.Conventions.Media.File);
2017-12-06 11:51:35 +01:00
if (prop == null || prop.GetValue() == null)
2017-07-20 11:21:28 +02:00
{
_url = string.Empty;
return _url;
}
var propType = ContentType.GetPropertyType(Constants.Conventions.Media.File);
2018-01-24 13:37:14 +01:00
// fixme this is horrible we need url providers for media too
2017-07-20 11:21:28 +02:00
//This is a hack - since we now have 2 properties that support a URL: upload and cropper, we need to detect this since we always
// want to return the normal URL and the cropper stores data as json
switch (propType.EditorAlias)
2017-07-20 11:21:28 +02:00
{
2018-01-20 12:09:15 +01:00
case Constants.PropertyEditors.Aliases.UploadField:
2017-12-06 11:51:35 +01:00
_url = prop.GetValue().ToString();
2017-07-20 11:21:28 +02:00
break;
2018-01-20 12:09:15 +01:00
case Constants.PropertyEditors.Aliases.ImageCropper:
2017-07-20 11:21:28 +02:00
//get the url from the json format
2018-01-24 13:37:14 +01:00
var stronglyTyped = prop.GetValue() as ImageCropperValue;
2017-07-20 11:21:28 +02:00
if (stronglyTyped != null)
{
2016-02-04 17:14:29 +01:00
_url = stronglyTyped.Src;
break;
}
2018-01-24 13:37:14 +01:00
_url = prop.GetValue()?.ToString();
2017-07-20 11:21:28 +02:00
break;
}
break;
default:
throw new NotSupportedException();
}
return _url;
}
2018-04-28 16:34:43 +02:00
}
/// <inheritdoc />
public abstract PublishedCultureInfos GetCulture(string culture = ".");
2017-07-20 11:21:28 +02:00
2018-04-28 16:34:43 +02:00
/// <inheritdoc />
public abstract IReadOnlyDictionary<string, PublishedCultureInfos> Cultures { get; }
/// <inheritdoc />
2017-07-20 11:21:28 +02:00
public abstract PublishedItemType ItemType { get; }
2018-04-28 16:34:43 +02:00
/// <inheritdoc />
2013-09-05 17:47:13 +02:00
public abstract bool IsDraft { get; }
2013-09-05 17:47:13 +02:00
#endregion
#region Tree
2018-04-28 16:34:43 +02:00
/// <inheritdoc />
2013-09-05 17:47:13 +02:00
public abstract IPublishedContent Parent { get; }
2018-04-28 16:34:43 +02:00
/// <inheritdoc />
2013-09-05 17:47:13 +02:00
public abstract IEnumerable<IPublishedContent> Children { get; }
#endregion
#region Properties
2018-04-28 16:34:43 +02:00
/// <inheritdoc cref="IPublishedElement.Properties"/>
public abstract IEnumerable<IPublishedProperty> Properties { get; }
2018-04-28 16:34:43 +02:00
/// <inheritdoc cref="IPublishedElement.GetProperty(string)"/>
2013-09-05 17:47:13 +02:00
public abstract IPublishedProperty GetProperty(string alias);
2018-04-28 16:34:43 +02:00
/// <inheritdoc cref="IPublishedContent.GetProperty(string, bool)"/>
2013-09-05 17:47:13 +02:00
public virtual IPublishedProperty GetProperty(string alias, bool recurse)
2018-04-28 16:34:43 +02:00
{
// fixme - but can this work with variants?
2013-09-05 17:47:13 +02:00
var property = GetProperty(alias);
if (recurse == false) return property;
IPublishedContent content = this;
var firstNonNullProperty = property;
2017-12-06 11:51:35 +01:00
while (content != null && (property == null || property.HasValue() == false))
2013-09-05 17:47:13 +02:00
{
content = content.Parent;
2017-07-27 11:09:53 +02:00
property = content?.GetProperty(alias);
2013-09-05 17:47:13 +02:00
if (firstNonNullProperty == null && property != null) firstNonNullProperty = property;
}
// if we find a content with the property with a value, return that property
// if we find no content with the property, return null
// 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
2017-12-06 11:51:35 +01:00
return property != null && property.HasValue() ? property : firstNonNullProperty;
2013-09-05 17:47:13 +02:00
}
2013-09-05 17:47:13 +02:00
#endregion
}
}