2012-12-09 03:22:11 +05:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
2013-05-07 18:56:24 -10:00
|
|
|
|
using System.Diagnostics;
|
2012-12-09 03:22:11 +05:00
|
|
|
|
using Umbraco.Core;
|
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;
|
2012-12-09 03:22:11 +05:00
|
|
|
|
|
|
|
|
|
|
namespace Umbraco.Web.Models
|
|
|
|
|
|
{
|
2013-03-02 01:02:38 +06:00
|
|
|
|
/// <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>
|
2013-05-07 18:56:24 -10:00
|
|
|
|
[DebuggerDisplay("Content Id: {Id}, Name: {Name}")]
|
2013-09-05 17:47:13 +02:00
|
|
|
|
public abstract class PublishedContentBase : IPublishedContent
|
|
|
|
|
|
{
|
2018-04-30 15:11:01 +02:00
|
|
|
|
private string _url; // fixme - cannot cache urls! depends on the current request!
|
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; }
|
2013-03-02 01:02:38 +06:00
|
|
|
|
|
2018-04-28 16:34:43 +02:00
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
|
public abstract DateTime UpdateDate { get; }
|
|
|
|
|
|
|
2018-04-29 20:02:38 +02:00
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
|
public virtual string Url => GetUrl();
|
|
|
|
|
|
|
2018-04-28 16:34:43 +02:00
|
|
|
|
/// <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>
|
2018-04-29 20:02:38 +02:00
|
|
|
|
public virtual string GetUrl(string culture = ".") // fixme - consider .GetCulture("fr-FR").Url
|
2017-07-20 11:21:28 +02:00
|
|
|
|
{
|
|
|
|
|
|
switch (ItemType)
|
|
|
|
|
|
{
|
2018-04-29 20:02:38 +02:00
|
|
|
|
case PublishedItemType.Content:
|
2018-04-30 15:11:01 +02:00
|
|
|
|
// fixme - consider injecting an umbraco context accessor
|
2017-07-20 11:21:28 +02:00
|
|
|
|
if (UmbracoContext.Current == null)
|
2018-04-29 20:02:38 +02:00
|
|
|
|
throw new InvalidOperationException("Cannot compute Url for a content item when UmbracoContext.Current is null.");
|
2017-07-20 11:21:28 +02:00
|
|
|
|
if (UmbracoContext.Current.UrlProvider == null)
|
2018-04-29 20:02:38 +02:00
|
|
|
|
throw new InvalidOperationException("Cannot compute Url for a content item when UmbracoContext.Current.UrlProvider is null.");
|
|
|
|
|
|
return UmbracoContext.Current.UrlProvider.GetUrl(this);
|
|
|
|
|
|
|
2017-07-20 11:21:28 +02:00
|
|
|
|
case PublishedItemType.Media:
|
2018-04-29 20:02:38 +02:00
|
|
|
|
if (_url != null) return _url; // assume it will not depend on current uri/culture
|
|
|
|
|
|
|
2017-07-20 11:21:28 +02:00
|
|
|
|
var prop = GetProperty(Constants.Conventions.Media.File);
|
2018-04-29 20:02:38 +02:00
|
|
|
|
if (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-04-30 15:11:01 +02:00
|
|
|
|
// fixme - consider implementing media url providers
|
|
|
|
|
|
// note: that one does not support variations
|
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
|
2018-01-10 12:48:51 +01:00
|
|
|
|
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;
|
|
|
|
|
|
}
|
2018-04-29 20:02:38 +02:00
|
|
|
|
|
|
|
|
|
|
return _url;
|
|
|
|
|
|
|
2017-07-20 11:21:28 +02:00
|
|
|
|
default:
|
|
|
|
|
|
throw new NotSupportedException();
|
|
|
|
|
|
}
|
2018-04-28 16:34:43 +02:00
|
|
|
|
}
|
2018-04-30 15:11:01 +02:00
|
|
|
|
|
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; }
|
2012-12-09 03:22:11 +05:00
|
|
|
|
|
2018-04-28 16:34:43 +02:00
|
|
|
|
/// <inheritdoc />
|
2013-09-05 17:47:13 +02:00
|
|
|
|
public abstract bool IsDraft { get; }
|
2016-06-09 19:38:51 +02:00
|
|
|
|
|
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"/>
|
2016-06-10 16:37:28 +02:00
|
|
|
|
public abstract IEnumerable<IPublishedProperty> Properties { get; }
|
2012-12-09 03:22:11 +05:00
|
|
|
|
|
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
|
|
|
|
{
|
2018-04-30 15:11:01 +02:00
|
|
|
|
// fixme - refactor with fallback
|
2018-04-28 16:34:43 +02:00
|
|
|
|
|
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-03-02 01:02:38 +06:00
|
|
|
|
|
2013-09-05 17:47:13 +02:00
|
|
|
|
#endregion
|
2013-03-02 01:02:38 +06:00
|
|
|
|
}
|
2012-12-09 03:22:11 +05:00
|
|
|
|
}
|