V17 - Properties and validators, removing obsoleted code (#19961)
* Removing obsoleted code from ApiMediaQueryService.cs * Removing obsoleted code from ApiRichTextMarkupParserTests.cs * Removing obsoleted code from ContentCacheRefresher.cs * Removing obsoleted code from ContentFinderByUrlAlias.cs and adjusting its tests to use the new logic * Removing obsoleted code from ContentFinderByUrl.cs & its dependencies * Removing obsoleted code from ApiRichTextMarkupParserTests.cs * Removing obsoleted code from DocumentCache.cs & its dependencies * Removing obsoleted code from MediaCache.cs & its dependencies * Removing obsoleted code from PublishedCacheBase.cs & its dependencies * Removing obsoleted code from RenderNoContentController.cs and its tests * Removing obsoleted code from UmbracoRouteValueTransformer.cs * Removing obsoleted constructors from DefaultUrlProvider.cs * Removing the RadioValueEditor.cs & RadioValueValidator.cs obsoleted classes. * Removing obsolete constructor from MultipleValueValidator.cs * Removing obsolete constructor from EmailValidator.cs * Removing obsoleted code from DataValueReferenceFactoryCollection.cs * Removing obsoleted code from ApiContentBuilderBase.cs * Fixing constructor missing attribute * Making use of the TryGet result * Fixing use of obsoleted constructor * Removing silly bookmark comment * Fixing deleted code and restructuring to use new cache * Making use of TryGetRootKeys bool, to return null if false. * Extending code to use new constructor * Updated PublishedContentQuery.cs to return empty array Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com> --------- Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>
This commit is contained in:
@@ -66,7 +66,12 @@ internal sealed class ApiMediaQueryService : IApiMediaQueryService
|
||||
private IPublishedContent? TryGetByPath(string path, IPublishedMediaCache mediaCache)
|
||||
{
|
||||
var segments = path.Split(Constants.CharArrays.ForwardSlash, StringSplitOptions.RemoveEmptyEntries);
|
||||
IEnumerable<IPublishedContent> currentChildren = mediaCache.GetAtRoot();
|
||||
if (_mediaNavigationQueryService.TryGetRootKeys(out IEnumerable<Guid> rootKeys) is false)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
IEnumerable<IPublishedContent> currentChildren = rootKeys.Select(x => mediaCache.GetById(false, x)).WhereNotNull();
|
||||
IPublishedContent? resolvedMedia = null;
|
||||
|
||||
foreach (var segment in segments)
|
||||
@@ -101,9 +106,9 @@ internal sealed class ApiMediaQueryService : IApiMediaQueryService
|
||||
}
|
||||
|
||||
IPublishedMediaCache mediaCache = GetRequiredPublishedMediaCache();
|
||||
if (childrenOf.Trim(Constants.CharArrays.ForwardSlash).Length == 0)
|
||||
if (childrenOf.Trim(Constants.CharArrays.ForwardSlash).Length == 0 && _mediaNavigationQueryService.TryGetRootKeys(out IEnumerable<Guid> rootKeys))
|
||||
{
|
||||
return mediaCache.GetAtRoot();
|
||||
return rootKeys.Select(x => mediaCache.GetById(false, x)).WhereNotNull();
|
||||
}
|
||||
|
||||
IPublishedContent? parent = Guid.TryParse(childrenOf, out Guid parentKey)
|
||||
|
||||
@@ -27,39 +27,6 @@ public sealed class ContentCacheRefresher : PayloadCacheRefresherBase<ContentCac
|
||||
private readonly IPublishStatusManagementService _publishStatusManagementService;
|
||||
private readonly IIdKeyMap _idKeyMap;
|
||||
|
||||
[Obsolete("Use the constructor with ICacheManager instead, scheduled for removal in V17.")]
|
||||
public ContentCacheRefresher(
|
||||
AppCaches appCaches,
|
||||
IJsonSerializer serializer,
|
||||
IIdKeyMap idKeyMap,
|
||||
IDomainService domainService,
|
||||
IEventAggregator eventAggregator,
|
||||
ICacheRefresherNotificationFactory factory,
|
||||
IDocumentUrlService documentUrlService,
|
||||
IDomainCacheService domainCacheService,
|
||||
IDocumentNavigationQueryService documentNavigationQueryService,
|
||||
IDocumentNavigationManagementService documentNavigationManagementService,
|
||||
IContentService contentService,
|
||||
IPublishStatusManagementService publishStatusManagementService,
|
||||
IDocumentCacheService documentCacheService)
|
||||
: this(
|
||||
appCaches,
|
||||
serializer,
|
||||
idKeyMap,
|
||||
domainService,
|
||||
eventAggregator,
|
||||
factory,
|
||||
documentUrlService,
|
||||
domainCacheService,
|
||||
documentNavigationQueryService,
|
||||
documentNavigationManagementService,
|
||||
contentService,
|
||||
publishStatusManagementService,
|
||||
documentCacheService,
|
||||
StaticServiceProvider.Instance.GetRequiredService<ICacheManager>())
|
||||
{
|
||||
}
|
||||
|
||||
public ContentCacheRefresher(
|
||||
AppCaches appCaches,
|
||||
IJsonSerializer serializer,
|
||||
|
||||
@@ -22,31 +22,6 @@ public sealed class MediaCacheRefresher : PayloadCacheRefresherBase<MediaCacheRe
|
||||
private readonly IMediaCacheService _mediaCacheService;
|
||||
private readonly ICacheManager _cacheManager;
|
||||
|
||||
[Obsolete("Use the constructor with ICacheManager instead, scheduled for removal in V17.")]
|
||||
public MediaCacheRefresher(
|
||||
AppCaches appCaches,
|
||||
IJsonSerializer serializer,
|
||||
IIdKeyMap idKeyMap,
|
||||
IEventAggregator eventAggregator,
|
||||
ICacheRefresherNotificationFactory factory,
|
||||
IMediaNavigationQueryService mediaNavigationQueryService,
|
||||
IMediaNavigationManagementService mediaNavigationManagementService,
|
||||
IMediaService mediaService,
|
||||
IMediaCacheService mediaCacheService)
|
||||
: this(
|
||||
appCaches,
|
||||
serializer,
|
||||
idKeyMap,
|
||||
eventAggregator,
|
||||
factory,
|
||||
mediaNavigationQueryService,
|
||||
mediaNavigationManagementService,
|
||||
mediaService,
|
||||
mediaCacheService,
|
||||
StaticServiceProvider.Instance.GetRequiredService<ICacheManager>())
|
||||
{
|
||||
}
|
||||
|
||||
public MediaCacheRefresher(
|
||||
AppCaches appCaches,
|
||||
IJsonSerializer serializer,
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Umbraco.Cms.Core.DependencyInjection;
|
||||
using Umbraco.Cms.Core.Models.DeliveryApi;
|
||||
using Umbraco.Cms.Core.Models.DeliveryApi;
|
||||
using Umbraco.Cms.Core.Models.PublishedContent;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
@@ -12,19 +10,6 @@ public abstract class ApiContentBuilderBase<T>
|
||||
private readonly IApiContentNameProvider _apiContentNameProvider;
|
||||
private readonly IOutputExpansionStrategyAccessor _outputExpansionStrategyAccessor;
|
||||
|
||||
[Obsolete("Please use the constructor that takes all parameters. Scheduled for removal in Umbraco 17.")]
|
||||
protected ApiContentBuilderBase(
|
||||
IApiContentNameProvider apiContentNameProvider,
|
||||
IApiContentRouteBuilder apiContentRouteBuilder,
|
||||
IOutputExpansionStrategyAccessor outputExpansionStrategyAccessor)
|
||||
: this(
|
||||
apiContentNameProvider,
|
||||
apiContentRouteBuilder,
|
||||
outputExpansionStrategyAccessor,
|
||||
StaticServiceProvider.Instance.GetRequiredService<IVariationContextAccessor>())
|
||||
{
|
||||
}
|
||||
|
||||
protected ApiContentBuilderBase(
|
||||
IApiContentNameProvider apiContentNameProvider,
|
||||
IApiContentRouteBuilder apiContentRouteBuilder,
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Umbraco.Cms.Core.Composing;
|
||||
using Umbraco.Cms.Core.DependencyInjection;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.Editors;
|
||||
|
||||
@@ -17,17 +15,6 @@ public class DataValueReferenceFactoryCollection : BuilderCollectionBase<IDataVa
|
||||
|
||||
private readonly ILogger<DataValueReferenceFactoryCollection> _logger;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DataValueReferenceFactoryCollection" /> class.
|
||||
/// </summary>
|
||||
/// <param name="items">The items.</param>
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 17.")]
|
||||
public DataValueReferenceFactoryCollection(Func<IEnumerable<IDataValueReferenceFactory>> items)
|
||||
: this(
|
||||
items,
|
||||
StaticServiceProvider.Instance.GetRequiredService<ILogger<DataValueReferenceFactoryCollection>>())
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DataValueReferenceFactoryCollection" /> class.
|
||||
/// </summary>
|
||||
@@ -159,17 +146,6 @@ public class DataValueReferenceFactoryCollection : BuilderCollectionBase<IDataVa
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all relation type aliases that are automatically tracked.
|
||||
/// </summary>
|
||||
/// <param name="propertyEditors">The property editors.</param>
|
||||
/// <returns>
|
||||
/// All relation type aliases that are automatically tracked.
|
||||
/// </returns>
|
||||
[Obsolete("Use GetAllAutomaticRelationTypesAliases. This will be removed in Umbraco 15.")]
|
||||
public ISet<string> GetAutomaticRelationTypesAliases(PropertyEditorCollection propertyEditors) =>
|
||||
GetAllAutomaticRelationTypesAliases(propertyEditors);
|
||||
|
||||
public ISet<string> GetAllAutomaticRelationTypesAliases(PropertyEditorCollection propertyEditors)
|
||||
{
|
||||
// Always add default automatic relation types
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
using Umbraco.Cms.Core.IO;
|
||||
using Umbraco.Cms.Core.PropertyEditors.Validators;
|
||||
using Umbraco.Cms.Core.Serialization;
|
||||
using Umbraco.Cms.Core.Strings;
|
||||
|
||||
namespace Umbraco.Cms.Core.PropertyEditors;
|
||||
|
||||
[Obsolete("This is no longer used and has been migrated to an internal class within RadioButtonsPropertyEditor. Scheduled for removal in Umbraco 17.")]
|
||||
public class RadioValueEditor : DataValueEditor
|
||||
{
|
||||
public RadioValueEditor(
|
||||
IShortStringHelper shortStringHelper,
|
||||
IJsonSerializer jsonSerializer,
|
||||
IIOHelper ioHelper,
|
||||
DataEditorAttribute attribute)
|
||||
: base(shortStringHelper, jsonSerializer, ioHelper, attribute) =>
|
||||
Validators.Add(new RadioValueValidator());
|
||||
}
|
||||
@@ -14,15 +14,6 @@ public sealed class EmailValidator : IValueValidator
|
||||
{
|
||||
private readonly ILocalizedTextService _localizedTextService;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="EmailValidator"/> class.
|
||||
/// </summary>
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 17.")]
|
||||
public EmailValidator()
|
||||
: this(StaticServiceProvider.Instance.GetRequiredService<ILocalizedTextService>())
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="EmailValidator"/> class.
|
||||
/// </summary>
|
||||
|
||||
@@ -14,15 +14,6 @@ public class MultipleValueValidator : IValueValidator
|
||||
{
|
||||
private readonly ILocalizedTextService _localizedTextService;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MultipleValueValidator"/> class.
|
||||
/// </summary>
|
||||
[Obsolete("Please use the constructor that takes all parameters. Scheduled for removal in Umbraco 17.")]
|
||||
public MultipleValueValidator()
|
||||
: this(StaticServiceProvider.Instance.GetRequiredService<ILocalizedTextService>())
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MultipleValueValidator"/> class.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Umbraco.Cms.Core.Models.Validation;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Core.PropertyEditors.Validators;
|
||||
|
||||
[Obsolete("This is no longer used and has been migrated to an internal class within RadioButtonsPropertyEditor. Scheduled for removal in Umbraco 17.")]
|
||||
public class RadioValueValidator : IValueValidator
|
||||
{
|
||||
public IEnumerable<ValidationResult> Validate(object? value, string? valueType, object? dataTypeConfiguration,
|
||||
PropertyValidationContext validationContext)
|
||||
{
|
||||
// don't validate if empty
|
||||
if (value == null || value.ToString().IsNullOrWhiteSpace())
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
if (dataTypeConfiguration is not ValueListConfiguration valueListConfiguration)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
if (value is not string valueAsString)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
if (valueListConfiguration.Items.Contains(valueAsString) is false)
|
||||
{
|
||||
yield return new ValidationResult(
|
||||
$"The value {valueAsString} is not a part of the pre-values", ["items"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,16 +25,6 @@ public interface IPublishedCache
|
||||
/// <remarks>The value of <paramref name="preview" /> overrides defaults.</remarks>
|
||||
IPublishedContent? GetById(bool preview, Guid contentId);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a content identified by its Udi identifier.
|
||||
/// </summary>
|
||||
/// <param name="preview">A value indicating whether to consider unpublished content.</param>
|
||||
/// <param name="contentId">The content Udi identifier.</param>
|
||||
/// <returns>The content, or null.</returns>
|
||||
/// <remarks>The value of <paramref name="preview" /> overrides defaults.</remarks>
|
||||
[Obsolete] // FIXME: Remove when replacing nucache
|
||||
IPublishedContent? GetById(bool preview, Udi contentId);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a content identified by its unique identifier.
|
||||
/// </summary>
|
||||
@@ -50,49 +40,4 @@ public interface IPublishedCache
|
||||
/// <returns>The content, or null.</returns>
|
||||
/// <remarks>Considers published or unpublished content depending on defaults.</remarks>
|
||||
IPublishedContent? GetById(Guid contentId);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a content identified by its unique identifier.
|
||||
/// </summary>
|
||||
/// <param name="contentId">The content unique identifier.</param>
|
||||
/// <returns>The content, or null.</returns>
|
||||
/// <remarks>Considers published or unpublished content depending on defaults.</remarks>
|
||||
[Obsolete] // FIXME: Remove when replacing nucache
|
||||
IPublishedContent? GetById(Udi contentId);
|
||||
|
||||
/// <summary>
|
||||
/// Gets contents at root.
|
||||
/// </summary>
|
||||
/// <param name="preview">A value indicating whether to consider unpublished content.</param>
|
||||
/// <param name="culture">A culture.</param>
|
||||
/// <returns>The contents.</returns>
|
||||
/// <remarks>The value of <paramref name="preview" /> overrides defaults.</remarks>
|
||||
[Obsolete("Scheduled for removal, use IDocumentNavigationQueryService instead in v17")]
|
||||
IEnumerable<IPublishedContent> GetAtRoot(bool preview, string? culture = null);
|
||||
|
||||
/// <summary>
|
||||
/// Gets contents at root.
|
||||
/// </summary>
|
||||
/// <param name="culture">A culture.</param>
|
||||
/// <returns>The contents.</returns>
|
||||
/// <remarks>Considers published or unpublished content depending on defaults.</remarks>
|
||||
[Obsolete("Scheduled for removal, use IDocumentNavigationQueryService instead in v17")]
|
||||
IEnumerable<IPublishedContent> GetAtRoot(string? culture = null);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the cache contains published content.
|
||||
/// </summary>
|
||||
/// <param name="preview">A value indicating whether to consider unpublished content.</param>
|
||||
/// <returns>A value indicating whether the cache contains published content.</returns>
|
||||
/// <remarks>The value of <paramref name="preview" /> overrides defaults.</remarks>
|
||||
[Obsolete("Scheduled for removal in v17")]
|
||||
bool HasContent(bool preview);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the cache contains published content.
|
||||
/// </summary>
|
||||
/// <returns>A value indicating whether the cache contains published content.</returns>
|
||||
/// <remarks>Considers published or unpublished content depending on defaults.</remarks>
|
||||
[Obsolete("Scheduled for removal in v17")]
|
||||
bool HasContent();
|
||||
}
|
||||
|
||||
@@ -44,46 +44,6 @@ public interface IPublishedContentCache : IPublishedCache
|
||||
/// <para>The value of <paramref name="preview" /> overrides defaults.</para>
|
||||
/// </remarks>
|
||||
[Obsolete]
|
||||
IPublishedContent? GetByRoute(bool preview, string route, bool? hideTopLevelNode = null, string? culture = null);
|
||||
|
||||
/// <summary>
|
||||
/// Gets content identified by a route.
|
||||
/// </summary>
|
||||
/// <param name="route">The route</param>
|
||||
/// <param name="hideTopLevelNode">A value forcing the HideTopLevelNode setting.</param>
|
||||
/// <param name="culture">The culture</param>
|
||||
/// <returns>The content, or null.</returns>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// A valid route is either a simple path eg <c>/foo/bar/nil</c> or a root node id and a path, eg
|
||||
/// <c>123/foo/bar/nil</c>.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// If
|
||||
/// <paramref name="hideTopLevelNode" />
|
||||
/// is <c>null</c> then the settings value is used.
|
||||
/// </para>
|
||||
/// <para>Considers published or unpublished content depending on defaults.</para>
|
||||
/// </remarks>
|
||||
[Obsolete]
|
||||
IPublishedContent? GetByRoute(string route, bool? hideTopLevelNode = null, string? culture = null);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the route for a content identified by its unique identifier.
|
||||
/// </summary>
|
||||
/// <param name="preview">A value indicating whether to consider unpublished content.</param>
|
||||
/// <param name="contentId">The content unique identifier.</param>
|
||||
/// <param name="culture">The culture</param>
|
||||
/// <returns>A special string formatted route path.</returns>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// The resulting string is a special encoded route string that may contain the domain ID
|
||||
/// for the current route. If a domain is present the string will be prefixed with the domain ID integer, example:
|
||||
/// {domainId}/route-path-of-item
|
||||
/// </para>
|
||||
/// <para>The value of <paramref name="preview" /> overrides defaults.</para>
|
||||
/// </remarks>
|
||||
[Obsolete]
|
||||
string? GetRouteById(bool preview, int contentId, string? culture = null);
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -24,21 +24,10 @@ public abstract class PublishedCacheBase : IPublishedCache
|
||||
public IPublishedContent? GetById(Guid contentId)
|
||||
=> GetById(PreviewDefault, contentId);
|
||||
|
||||
public abstract IPublishedContent? GetById(bool preview, Udi contentId);
|
||||
|
||||
public IPublishedContent? GetById(Udi contentId)
|
||||
=> GetById(PreviewDefault, contentId);
|
||||
|
||||
public abstract bool HasById(bool preview, int contentId);
|
||||
|
||||
public bool HasById(int contentId)
|
||||
=> HasById(PreviewDefault, contentId);
|
||||
|
||||
public abstract IEnumerable<IPublishedContent> GetAtRoot(bool preview, string? culture = null);
|
||||
|
||||
public IEnumerable<IPublishedContent> GetAtRoot(string? culture = null) => GetAtRoot(PreviewDefault, culture);
|
||||
|
||||
public abstract bool HasContent(bool preview);
|
||||
|
||||
public bool HasContent() => HasContent(PreviewDefault);
|
||||
}
|
||||
|
||||
@@ -15,28 +15,8 @@ namespace Umbraco.Cms.Core.PublishedCache;
|
||||
//
|
||||
public class PublishedElement : IPublishedElement
|
||||
{
|
||||
|
||||
private readonly IPublishedProperty[] _propertiesArray;
|
||||
|
||||
[Obsolete("Please use the non-obsolete constructor. Will be removed in V17.")]
|
||||
public PublishedElement(IPublishedContentType contentType, Guid key, Dictionary<string, object?> values, bool previewing)
|
||||
: this(contentType, key, values, previewing, PropertyCacheLevel.None, null)
|
||||
{
|
||||
}
|
||||
|
||||
[Obsolete("Please use the non-obsolete constructor. Will be removed in V17.")]
|
||||
public PublishedElement(IPublishedContentType contentType, Guid key, Dictionary<string, object?>? values, bool previewing, PropertyCacheLevel referenceCacheLevel, ICacheManager? cacheManager)
|
||||
: this(
|
||||
contentType,
|
||||
key,
|
||||
values,
|
||||
previewing,
|
||||
referenceCacheLevel,
|
||||
StaticServiceProvider.Instance.GetRequiredService<IVariationContextAccessor>().VariationContext ?? new VariationContext(),
|
||||
cacheManager)
|
||||
{
|
||||
}
|
||||
|
||||
// initializes a new instance of the PublishedElement class
|
||||
// within the context of a published snapshot service (eg a published content property value)
|
||||
public PublishedElement(IPublishedContentType contentType, Guid key, Dictionary<string, object?>? values, bool previewing, PropertyCacheLevel referenceCacheLevel, VariationContext variationContext, ICacheManager? cacheManager)
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace Umbraco.Cms.Core.Routing;
|
||||
/// <remarks>
|
||||
/// <para>Handles <c>/foo/bar</c> where <c>/foo/bar</c> is the nice URL of a document.</para>
|
||||
/// </remarks>
|
||||
[Obsolete("Scheduled for removal in Umbraco 18")]
|
||||
public class ContentFinderByUrl : IContentFinder
|
||||
{
|
||||
private readonly ILogger<ContentFinderByUrl> _logger;
|
||||
@@ -60,41 +61,5 @@ public class ContentFinderByUrl : IContentFinder
|
||||
/// Tries to find an Umbraco document for a <c>PublishedRequest</c> and a route.
|
||||
/// </summary>
|
||||
/// <returns>The document node, or null.</returns>
|
||||
protected IPublishedContent? FindContent(IPublishedRequestBuilder docreq, string route)
|
||||
{
|
||||
if (!UmbracoContextAccessor.TryGetUmbracoContext(out IUmbracoContext? umbracoContext))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (docreq == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(docreq));
|
||||
}
|
||||
|
||||
if (_logger.IsEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.LogDebug("Test route {Route}", route);
|
||||
}
|
||||
|
||||
IPublishedContent? node =
|
||||
umbracoContext.Content?.GetByRoute(umbracoContext.InPreviewMode, route, culture: docreq.Culture);
|
||||
if (node != null)
|
||||
{
|
||||
docreq.SetPublishedContent(node);
|
||||
if (_logger.IsEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.LogDebug("Got content, id={NodeId}", node.Id);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_logger.IsEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.LogDebug("No match.");
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
protected IPublishedContent? FindContent(IPublishedRequestBuilder docreq, string route) => null;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using Microsoft.Extensions.Logging;
|
||||
using Umbraco.Cms.Core.DependencyInjection;
|
||||
using Umbraco.Cms.Core.Models.PublishedContent;
|
||||
using Umbraco.Cms.Core.PublishedCache;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Services.Navigation;
|
||||
using Umbraco.Cms.Core.Web;
|
||||
using Umbraco.Extensions;
|
||||
@@ -26,7 +27,6 @@ public class ContentFinderByUrlAlias : IContentFinder
|
||||
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
|
||||
private readonly IDocumentNavigationQueryService _documentNavigationQueryService;
|
||||
private readonly IPublishedContentStatusFilteringService _publishedContentStatusFilteringService;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ContentFinderByUrlAlias" /> class.
|
||||
/// </summary>
|
||||
@@ -44,61 +44,6 @@ public class ContentFinderByUrlAlias : IContentFinder
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
[Obsolete("Please use tne non-obsolete constructor instead. Scheduled removal in v17")]
|
||||
public ContentFinderByUrlAlias(
|
||||
ILogger<ContentFinderByUrlAlias> logger,
|
||||
IPublishedValueFallback publishedValueFallback,
|
||||
IVariationContextAccessor variationContextAccessor,
|
||||
IUmbracoContextAccessor umbracoContextAccessor,
|
||||
IPublishedContentCache contentCache,
|
||||
IDocumentNavigationQueryService documentNavigationQueryService,
|
||||
IPublishStatusQueryService publishStatusQueryService,
|
||||
IPublishedContentStatusFilteringService publishedContentStatusFilteringService)
|
||||
: this(
|
||||
logger,
|
||||
publishedValueFallback,
|
||||
umbracoContextAccessor,
|
||||
documentNavigationQueryService,
|
||||
publishedContentStatusFilteringService)
|
||||
{
|
||||
}
|
||||
|
||||
[Obsolete("Please use tne non-obsolete constructor instead. Scheduled removal in v17")]
|
||||
public ContentFinderByUrlAlias(
|
||||
ILogger<ContentFinderByUrlAlias> logger,
|
||||
IPublishedValueFallback publishedValueFallback,
|
||||
IVariationContextAccessor variationContextAccessor,
|
||||
IUmbracoContextAccessor umbracoContextAccessor,
|
||||
IPublishedContentCache contentCache,
|
||||
IDocumentNavigationQueryService documentNavigationQueryService,
|
||||
IPublishStatusQueryService publishStatusQueryService)
|
||||
: this(
|
||||
logger,
|
||||
publishedValueFallback,
|
||||
umbracoContextAccessor,
|
||||
documentNavigationQueryService,
|
||||
StaticServiceProvider.Instance.GetRequiredService<IPublishedContentStatusFilteringService>())
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
[Obsolete("Please use tne non-obsolete constructor instead. Scheduled removal in v17")]
|
||||
public ContentFinderByUrlAlias(
|
||||
ILogger<ContentFinderByUrlAlias> logger,
|
||||
IPublishedValueFallback publishedValueFallback,
|
||||
IVariationContextAccessor variationContextAccessor,
|
||||
IUmbracoContextAccessor umbracoContextAccessor,
|
||||
IPublishedContentCache contentCache,
|
||||
IDocumentNavigationQueryService documentNavigationQueryService)
|
||||
: this(
|
||||
logger,
|
||||
publishedValueFallback,
|
||||
umbracoContextAccessor,
|
||||
documentNavigationQueryService,
|
||||
StaticServiceProvider.Instance.GetRequiredService<IPublishedContentStatusFilteringService>())
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to find and assign an Umbraco document to a <c>PublishedRequest</c>.
|
||||
/// </summary>
|
||||
@@ -204,7 +149,12 @@ public class ContentFinderByUrlAlias : IContentFinder
|
||||
|
||||
if (cache is not null)
|
||||
{
|
||||
foreach (IPublishedContent rootContent in cache.GetAtRoot())
|
||||
if (_documentNavigationQueryService.TryGetRootKeys(out IEnumerable<Guid> rootKeys) is false)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach (IPublishedContent rootContent in rootKeys.Select(x => cache.GetById(false, x)).WhereNotNull())
|
||||
{
|
||||
IPublishedContent? c = rootContent.DescendantsOrSelf(_documentNavigationQueryService, _publishedContentStatusFilteringService)
|
||||
.FirstOrDefault(x => IsMatch(x, test1, test2));
|
||||
|
||||
@@ -24,6 +24,7 @@ namespace Umbraco.Cms.Core.Routing;
|
||||
/// </para>
|
||||
/// <para>If successful, then the template of the document request is also assigned.</para>
|
||||
/// </remarks>
|
||||
[Obsolete("Scheduled for removal in Umbraco 18")]
|
||||
public class ContentFinderByUrlAndTemplate : ContentFinderByUrl
|
||||
{
|
||||
private readonly IContentTypeService _contentTypeService;
|
||||
|
||||
@@ -50,71 +50,6 @@ public class DefaultUrlProvider : IUrlProvider
|
||||
requestSettings.OnChange(x => _requestSettings = x);
|
||||
}
|
||||
|
||||
[Obsolete("Use the non-obsolete constructor. Scheduled for removal in V17.")]
|
||||
public DefaultUrlProvider(
|
||||
IOptionsMonitor<RequestHandlerSettings> requestSettings,
|
||||
ILogger<DefaultUrlProvider> logger,
|
||||
ISiteDomainMapper siteDomainMapper,
|
||||
IUmbracoContextAccessor umbracoContextAccessor,
|
||||
UriUtility uriUtility,
|
||||
ILocalizationService localizationService,
|
||||
IPublishedContentCache contentCache,
|
||||
IDocumentNavigationQueryService navigationQueryService,
|
||||
IPublishedContentStatusFilteringService publishedContentStatusFilteringService)
|
||||
: this(
|
||||
requestSettings,
|
||||
logger,
|
||||
siteDomainMapper,
|
||||
umbracoContextAccessor,
|
||||
uriUtility,
|
||||
localizationService,
|
||||
navigationQueryService,
|
||||
publishedContentStatusFilteringService)
|
||||
{
|
||||
}
|
||||
|
||||
[Obsolete("Use the non-obsolete constructor. Scheduled for removal in V17.")]
|
||||
public DefaultUrlProvider(
|
||||
IOptionsMonitor<RequestHandlerSettings> requestSettings,
|
||||
ILogger<DefaultUrlProvider> logger,
|
||||
ISiteDomainMapper siteDomainMapper,
|
||||
IUmbracoContextAccessor umbracoContextAccessor,
|
||||
UriUtility uriUtility,
|
||||
ILocalizationService localizationService,
|
||||
IPublishedContentCache contentCache,
|
||||
IDocumentNavigationQueryService navigationQueryService)
|
||||
: this(
|
||||
requestSettings,
|
||||
logger,
|
||||
siteDomainMapper,
|
||||
umbracoContextAccessor,
|
||||
uriUtility,
|
||||
localizationService,
|
||||
navigationQueryService,
|
||||
StaticServiceProvider.Instance.GetRequiredService<IPublishedContentStatusFilteringService>())
|
||||
{
|
||||
}
|
||||
|
||||
[Obsolete("Use the non-obsolete constructor. Scheduled for removal in V17.")]
|
||||
public DefaultUrlProvider(
|
||||
IOptionsMonitor<RequestHandlerSettings> requestSettings,
|
||||
ILogger<DefaultUrlProvider> logger,
|
||||
ISiteDomainMapper siteDomainMapper,
|
||||
IUmbracoContextAccessor umbracoContextAccessor,
|
||||
UriUtility uriUtility,
|
||||
ILocalizationService localizationService)
|
||||
: this(
|
||||
requestSettings,
|
||||
logger,
|
||||
siteDomainMapper,
|
||||
umbracoContextAccessor,
|
||||
uriUtility,
|
||||
localizationService,
|
||||
StaticServiceProvider.Instance.GetRequiredService<IDocumentNavigationQueryService>(),
|
||||
StaticServiceProvider.Instance.GetRequiredService<IPublishedContentStatusFilteringService>())
|
||||
{
|
||||
}
|
||||
|
||||
#region GetOtherUrls
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -36,6 +36,7 @@ using Umbraco.Cms.Core.Scoping;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Serialization;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Services.Navigation;
|
||||
using Umbraco.Cms.Core.Strings;
|
||||
using Umbraco.Cms.Core.Templates;
|
||||
using Umbraco.Cms.Core.Web;
|
||||
@@ -206,7 +207,8 @@ public static partial class UmbracoBuilderExtensions
|
||||
factory.GetRequiredService<IVariationContextAccessor>(),
|
||||
factory.GetRequiredService<IExamineManager>(),
|
||||
factory.GetRequiredService<IPublishedContentCache>(),
|
||||
factory.GetRequiredService<IPublishedMediaCache>());
|
||||
factory.GetRequiredService<IPublishedMediaCache>(),
|
||||
factory.GetRequiredService<IDocumentNavigationQueryService>());
|
||||
});
|
||||
|
||||
// register accessors for cultures
|
||||
|
||||
@@ -2,9 +2,12 @@ using System.Collections;
|
||||
using System.Globalization;
|
||||
using Examine;
|
||||
using Examine.Search;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.DependencyInjection;
|
||||
using Umbraco.Cms.Core.Models.PublishedContent;
|
||||
using Umbraco.Cms.Core.PublishedCache;
|
||||
using Umbraco.Cms.Core.Services.Navigation;
|
||||
using Umbraco.Cms.Infrastructure.Examine;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
@@ -20,6 +23,7 @@ public class PublishedContentQuery : IPublishedContentQuery
|
||||
private readonly IPublishedContentCache _publishedContent;
|
||||
private readonly IPublishedMediaCache _publishedMediaCache;
|
||||
private readonly IVariationContextAccessor _variationContextAccessor;
|
||||
private readonly IDocumentNavigationQueryService _documentNavigationQueryService;
|
||||
private static readonly HashSet<string> _returnedQueryFields =
|
||||
new() { ExamineFieldNames.ItemIdFieldName, ExamineFieldNames.CategoryFieldName };
|
||||
|
||||
@@ -30,13 +34,33 @@ public class PublishedContentQuery : IPublishedContentQuery
|
||||
IVariationContextAccessor variationContextAccessor,
|
||||
IExamineManager examineManager,
|
||||
IPublishedContentCache publishedContent,
|
||||
IPublishedMediaCache publishedMediaCache)
|
||||
IPublishedMediaCache publishedMediaCache,
|
||||
IDocumentNavigationQueryService documentNavigationQueryService)
|
||||
{
|
||||
_variationContextAccessor = variationContextAccessor ??
|
||||
throw new ArgumentNullException(nameof(variationContextAccessor));
|
||||
_examineManager = examineManager ?? throw new ArgumentNullException(nameof(examineManager));
|
||||
_publishedContent = publishedContent;
|
||||
_publishedMediaCache = publishedMediaCache;
|
||||
_documentNavigationQueryService = documentNavigationQueryService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PublishedContentQuery" /> class.
|
||||
/// </summary>
|
||||
[Obsolete("Scheduled for removal in Umbraco 18")]
|
||||
public PublishedContentQuery(
|
||||
IVariationContextAccessor variationContextAccessor,
|
||||
IExamineManager examineManager,
|
||||
IPublishedContentCache publishedContent,
|
||||
IPublishedMediaCache publishedMediaCache)
|
||||
: this(
|
||||
variationContextAccessor,
|
||||
examineManager,
|
||||
publishedContent,
|
||||
publishedMediaCache,
|
||||
StaticServiceProvider.Instance.GetRequiredService<IDocumentNavigationQueryService>())
|
||||
{
|
||||
}
|
||||
|
||||
#region Convert Helpers
|
||||
@@ -212,8 +236,9 @@ public class PublishedContentQuery : IPublishedContentQuery
|
||||
private IEnumerable<IPublishedContent> ItemsByIds(IPublishedCache? cache, IEnumerable<Guid> ids)
|
||||
=> ids.Select(eachId => ItemById(eachId, cache)).WhereNotNull();
|
||||
|
||||
private static IEnumerable<IPublishedContent> ItemsAtRoot(IPublishedCache? cache)
|
||||
=> cache?.GetAtRoot() ?? Array.Empty<IPublishedContent>();
|
||||
private IEnumerable<IPublishedContent> ItemsAtRoot(IPublishedCache? cache)
|
||||
=> _documentNavigationQueryService.TryGetRootKeys(out IEnumerable<Guid> rootKeys) is false ? []
|
||||
: rootKeys.Select(x => cache?.GetById(false, x)).WhereNotNull();
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
using System.Globalization;
|
||||
using Examine;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.DependencyInjection;
|
||||
using Umbraco.Cms.Core.Models.PublishedContent;
|
||||
using Umbraco.Cms.Core.PublishedCache;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Services.Navigation;
|
||||
using Umbraco.Cms.Core.Web;
|
||||
using Umbraco.Cms.Infrastructure;
|
||||
|
||||
@@ -19,7 +23,10 @@ public class ContentFinderByConfigured404 : IContentLastChanceFinder
|
||||
private readonly IExamineManager _examineManager;
|
||||
private readonly ILogger<ContentFinderByConfigured404> _logger;
|
||||
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
|
||||
private readonly IDocumentUrlService _documentUrlService;
|
||||
private readonly IPublishedContentCache _publishedContentCache;
|
||||
private readonly IVariationContextAccessor _variationContextAccessor;
|
||||
private readonly IDocumentNavigationQueryService _documentNavigationQueryService;
|
||||
private ContentSettings _contentSettings;
|
||||
|
||||
/// <summary>
|
||||
@@ -31,7 +38,10 @@ public class ContentFinderByConfigured404 : IContentLastChanceFinder
|
||||
IOptionsMonitor<ContentSettings> contentSettings,
|
||||
IExamineManager examineManager,
|
||||
IVariationContextAccessor variationContextAccessor,
|
||||
IUmbracoContextAccessor umbracoContextAccessor)
|
||||
IUmbracoContextAccessor umbracoContextAccessor,
|
||||
IDocumentUrlService documentUrlService,
|
||||
IPublishedContentCache publishedContentCache,
|
||||
IDocumentNavigationQueryService documentNavigationQueryService)
|
||||
{
|
||||
_logger = logger;
|
||||
_entityService = entityService;
|
||||
@@ -39,10 +49,34 @@ public class ContentFinderByConfigured404 : IContentLastChanceFinder
|
||||
_examineManager = examineManager;
|
||||
_variationContextAccessor = variationContextAccessor;
|
||||
_umbracoContextAccessor = umbracoContextAccessor;
|
||||
_documentUrlService = documentUrlService;
|
||||
_publishedContentCache = publishedContentCache;
|
||||
_documentNavigationQueryService = documentNavigationQueryService;
|
||||
|
||||
contentSettings.OnChange(x => _contentSettings = x);
|
||||
}
|
||||
|
||||
[Obsolete("Scheduled for removal in Umbraco 18")]
|
||||
public ContentFinderByConfigured404(
|
||||
ILogger<ContentFinderByConfigured404> logger,
|
||||
IEntityService entityService,
|
||||
IOptionsMonitor<ContentSettings> contentSettings,
|
||||
IExamineManager examineManager,
|
||||
IVariationContextAccessor variationContextAccessor,
|
||||
IUmbracoContextAccessor umbracoContextAccessor)
|
||||
: this(
|
||||
logger,
|
||||
entityService,
|
||||
contentSettings,
|
||||
examineManager,
|
||||
variationContextAccessor,
|
||||
umbracoContextAccessor,
|
||||
StaticServiceProvider.Instance.GetRequiredService<IDocumentUrlService>(),
|
||||
StaticServiceProvider.Instance.GetRequiredService<IPublishedContentCache>(),
|
||||
StaticServiceProvider.Instance.GetRequiredService<IDocumentNavigationQueryService>())
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to find and assign an Umbraco document to a <c>PublishedRequest</c>.
|
||||
/// </summary>
|
||||
@@ -77,8 +111,13 @@ public class ContentFinderByConfigured404 : IContentLastChanceFinder
|
||||
while (pos > 1)
|
||||
{
|
||||
route = route.Substring(0, pos);
|
||||
node = umbracoContext.Content?.GetByRoute(route, culture: frequest?.Culture);
|
||||
if (node != null)
|
||||
Guid? keyByRoute = _documentUrlService.GetDocumentKeyByRoute(route, frequest.Culture, null, false);
|
||||
if (keyByRoute is not null)
|
||||
{
|
||||
node = _publishedContentCache.GetById(keyByRoute.Value);
|
||||
}
|
||||
|
||||
if (node is not null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -100,7 +139,7 @@ public class ContentFinderByConfigured404 : IContentLastChanceFinder
|
||||
var error404 = NotFoundHandlerHelper.GetCurrentNotFoundPageId(
|
||||
_contentSettings.Error404Collection.ToArray(),
|
||||
_entityService,
|
||||
new PublishedContentQuery(_variationContextAccessor, _examineManager, umbracoContext.Content!, umbracoContext.Media),
|
||||
new PublishedContentQuery(_variationContextAccessor, _examineManager, umbracoContext.Content!, umbracoContext.Media, _documentNavigationQueryService),
|
||||
errorCulture,
|
||||
domainContentId);
|
||||
|
||||
|
||||
@@ -43,30 +43,6 @@ public sealed class DocumentCache : IPublishedContentCache
|
||||
|
||||
public IPublishedContent? GetById(Guid contentId) => GetByIdAsync(contentId).GetAwaiter().GetResult();
|
||||
|
||||
// TODO: These are all obsolete and should be removed
|
||||
|
||||
[Obsolete("Scheduled for removal in v17")]
|
||||
public IPublishedContent? GetById(bool preview, Udi contentId)
|
||||
{
|
||||
if(contentId is not GuidUdi guidUdi)
|
||||
{
|
||||
throw new NotSupportedException("Only GuidUdi is supported");
|
||||
}
|
||||
|
||||
return GetById(preview, guidUdi.Guid);
|
||||
}
|
||||
|
||||
[Obsolete("Scheduled for removal in v17")]
|
||||
public IPublishedContent? GetById(Udi contentId)
|
||||
{
|
||||
if(contentId is not GuidUdi guidUdi)
|
||||
{
|
||||
throw new NotSupportedException("Only GuidUdi is supported");
|
||||
}
|
||||
|
||||
return GetById(guidUdi.Guid);
|
||||
}
|
||||
|
||||
public IEnumerable<IPublishedContent> GetAtRoot(bool preview, string? culture = null)
|
||||
{
|
||||
_documentNavigationQueryService.TryGetRootKeys(out IEnumerable<Guid> rootKeys);
|
||||
@@ -75,34 +51,6 @@ public sealed class DocumentCache : IPublishedContentCache
|
||||
return culture is null ? rootContent : rootContent.Where(x => x.IsInvariantOrHasCulture(culture));
|
||||
}
|
||||
|
||||
public IEnumerable<IPublishedContent> GetAtRoot(string? culture = null)
|
||||
{
|
||||
_documentNavigationQueryService.TryGetRootKeys(out IEnumerable<Guid> rootKeys);
|
||||
|
||||
IEnumerable<IPublishedContent> rootContent = rootKeys.Select(key => GetById(key)).WhereNotNull();
|
||||
return culture is null ? rootContent : rootContent.Where(x => x.IsInvariantOrHasCulture(culture));
|
||||
}
|
||||
|
||||
[Obsolete("Scheduled for removal in v17")]
|
||||
public bool HasContent(bool preview) => HasContent();
|
||||
|
||||
[Obsolete("Scheduled for removal in v17")]
|
||||
public bool HasContent() => _documentUrlService.HasAny();
|
||||
|
||||
[Obsolete("Use IPublishedUrlProvider.GetUrl instead, scheduled for removal in v17")]
|
||||
public IPublishedContent? GetByRoute(bool preview, string route, bool? hideTopLevelNode = null, string? culture = null)
|
||||
{
|
||||
Guid? key = _documentUrlService.GetDocumentKeyByRoute(route, culture, null, preview);
|
||||
return key is not null ? GetById(preview, key.Value) : null;
|
||||
}
|
||||
|
||||
[Obsolete("Use IPublishedUrlProvider.GetUrl instead, scheduled for removal in v17")]
|
||||
public IPublishedContent? GetByRoute(string route, bool? hideTopLevelNode = null, string? culture = null)
|
||||
{
|
||||
Guid? key = _documentUrlService.GetDocumentKeyByRoute(route, culture, null, false);
|
||||
return key is not null ? GetById(key.Value) : null;
|
||||
}
|
||||
|
||||
[Obsolete("Use IPublishedUrlProvider.GetUrl instead, scheduled for removal in v17")]
|
||||
public string? GetRouteById(bool preview, int contentId, string? culture = null)
|
||||
{
|
||||
|
||||
@@ -33,29 +33,6 @@ public sealed class MediaCache : IPublishedMediaCache
|
||||
|
||||
public IPublishedContent? GetById(Guid contentId) => GetByIdAsync(contentId).GetAwaiter().GetResult();
|
||||
|
||||
|
||||
[Obsolete("Scheduled for removal in v17")]
|
||||
public IPublishedContent? GetById(bool preview, Udi contentId)
|
||||
{
|
||||
if(contentId is not GuidUdi guidUdi)
|
||||
{
|
||||
throw new NotSupportedException("Only GuidUdi is supported");
|
||||
}
|
||||
|
||||
return GetById(preview, guidUdi.Guid);
|
||||
}
|
||||
|
||||
[Obsolete("Scheduled for removal in v17")]
|
||||
public IPublishedContent? GetById(Udi contentId)
|
||||
{
|
||||
if(contentId is not GuidUdi guidUdi)
|
||||
{
|
||||
throw new NotSupportedException("Only GuidUdi is supported");
|
||||
}
|
||||
|
||||
return GetById(guidUdi.Guid);
|
||||
}
|
||||
|
||||
public IEnumerable<IPublishedContent> GetAtRoot(bool preview, string? culture = null)
|
||||
{
|
||||
_mediaNavigationQueryService.TryGetRootKeys(out IEnumerable<Guid> rootKeys);
|
||||
@@ -63,21 +40,4 @@ public sealed class MediaCache : IPublishedMediaCache
|
||||
IEnumerable<IPublishedContent> rootContent = rootKeys.Select(key => GetById(preview, key)).WhereNotNull();
|
||||
return culture is null ? rootContent : rootContent.Where(x => x.IsInvariantOrHasCulture(culture));
|
||||
}
|
||||
|
||||
public IEnumerable<IPublishedContent> GetAtRoot(string? culture = null)
|
||||
{
|
||||
_mediaNavigationQueryService.TryGetRootKeys(out IEnumerable<Guid> rootKeys);
|
||||
|
||||
IEnumerable<IPublishedContent> rootContent = rootKeys.Select(key => GetById(key)).WhereNotNull();
|
||||
return culture is null ? rootContent : rootContent.Where(x => x.IsInvariantOrHasCulture(culture));
|
||||
}
|
||||
|
||||
[Obsolete("Media does not support preview, this method will be removed in future versions")]
|
||||
public bool HasContent(bool preview) => HasContent();
|
||||
|
||||
public bool HasContent()
|
||||
{
|
||||
_mediaNavigationQueryService.TryGetRootKeys(out IEnumerable<Guid> rootKeys);
|
||||
return rootKeys.Any();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,36 +1,44 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.DependencyInjection;
|
||||
using Umbraco.Cms.Core.Hosting;
|
||||
using Umbraco.Cms.Core.PublishedCache;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Web;
|
||||
using Umbraco.Cms.Web.Website.Models;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Web.Website.Controllers;
|
||||
|
||||
public class RenderNoContentController : Controller
|
||||
{
|
||||
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
|
||||
private readonly IHostingEnvironment _hostingEnvironment;
|
||||
private readonly GlobalSettings _globalSettings;
|
||||
private readonly IDocumentUrlService _urlService;
|
||||
|
||||
[ActivatorUtilitiesConstructor]
|
||||
public RenderNoContentController(
|
||||
IHostingEnvironment hostingEnvironment,
|
||||
IOptionsSnapshot<GlobalSettings> globalSettings,
|
||||
IDocumentUrlService urlService)
|
||||
{
|
||||
_hostingEnvironment = hostingEnvironment ?? throw new ArgumentNullException(nameof(hostingEnvironment));
|
||||
_globalSettings = globalSettings.Value ?? throw new ArgumentNullException(nameof(globalSettings));
|
||||
_urlService = urlService;
|
||||
}
|
||||
|
||||
[Obsolete("Scheduled for removal in Umbraco 18")]
|
||||
public RenderNoContentController(
|
||||
IUmbracoContextAccessor umbracoContextAccessor,
|
||||
IHostingEnvironment hostingEnvironment,
|
||||
IOptionsSnapshot<GlobalSettings> globalSettings)
|
||||
: this(hostingEnvironment, globalSettings, StaticServiceProvider.Instance.GetRequiredService<IDocumentUrlService>())
|
||||
{
|
||||
_umbracoContextAccessor = umbracoContextAccessor ?? throw new ArgumentNullException(nameof(umbracoContextAccessor));
|
||||
_hostingEnvironment = hostingEnvironment ?? throw new ArgumentNullException(nameof(hostingEnvironment));
|
||||
_globalSettings = globalSettings.Value ?? throw new ArgumentNullException(nameof(globalSettings));
|
||||
}
|
||||
|
||||
public ActionResult Index()
|
||||
{
|
||||
IUmbracoContext umbracoContext = _umbracoContextAccessor.GetRequiredUmbracoContext();
|
||||
IPublishedContentCache? store = umbracoContext.Content;
|
||||
if (store?.HasContent() ?? false)
|
||||
if (_urlService.HasAny())
|
||||
{
|
||||
// If there is actually content, go to the root.
|
||||
return Redirect("~/");
|
||||
|
||||
@@ -59,7 +59,8 @@ public static partial class UmbracoBuilderExtensions
|
||||
x.GetRequiredService<IControllerActionSearcher>(),
|
||||
x.GetRequiredService<IPublicAccessRequestHandler>(),
|
||||
x.GetRequiredService<IUmbracoVirtualPageRoute>(),
|
||||
x.GetRequiredService<IOptionsMonitor<GlobalSettings>>()));
|
||||
x.GetRequiredService<IOptionsMonitor<GlobalSettings>>(),
|
||||
x.GetRequiredService<IDocumentUrlService>()));
|
||||
builder.Services.AddSingleton<IControllerActionSearcher, ControllerActionSearcher>();
|
||||
builder.Services.TryAddEnumerable(Singleton<MatcherPolicy, NotFoundSelectorPolicy>());
|
||||
builder.Services.AddSingleton<IUmbracoVirtualPageRoute, UmbracoVirtualPageRoute>();
|
||||
|
||||
@@ -5,9 +5,11 @@ using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||
using Microsoft.AspNetCore.Mvc.Routing;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.DependencyInjection;
|
||||
using Umbraco.Cms.Core.Routing;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Web;
|
||||
@@ -45,6 +47,7 @@ public class UmbracoRouteValueTransformer : DynamicRouteValueTransformer
|
||||
private readonly IRuntimeState _runtime;
|
||||
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
|
||||
private readonly IUmbracoVirtualPageRoute _umbracoVirtualPageRoute;
|
||||
private readonly IDocumentUrlService _urlService;
|
||||
private GlobalSettings _globalSettings;
|
||||
|
||||
/// <summary>
|
||||
@@ -61,7 +64,8 @@ public class UmbracoRouteValueTransformer : DynamicRouteValueTransformer
|
||||
IControllerActionSearcher controllerActionSearcher,
|
||||
IPublicAccessRequestHandler publicAccessRequestHandler,
|
||||
IUmbracoVirtualPageRoute umbracoVirtualPageRoute,
|
||||
IOptionsMonitor<GlobalSettings> globalSettings)
|
||||
IOptionsMonitor<GlobalSettings> globalSettings,
|
||||
IDocumentUrlService urlService)
|
||||
{
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
_umbracoContextAccessor =
|
||||
@@ -77,6 +81,39 @@ public class UmbracoRouteValueTransformer : DynamicRouteValueTransformer
|
||||
_umbracoVirtualPageRoute = umbracoVirtualPageRoute;
|
||||
_globalSettings = globalSettings.CurrentValue;
|
||||
globalSettings.OnChange(x => _globalSettings = x);
|
||||
_urlService = urlService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UmbracoRouteValueTransformer" /> class.
|
||||
/// </summary>
|
||||
[Obsolete("Scheduled for removal in Umbraco 18")]
|
||||
public UmbracoRouteValueTransformer(
|
||||
ILogger<UmbracoRouteValueTransformer> logger,
|
||||
IUmbracoContextAccessor umbracoContextAccessor,
|
||||
IPublishedRouter publishedRouter,
|
||||
IRuntimeState runtime,
|
||||
IUmbracoRouteValuesFactory routeValuesFactory,
|
||||
IRoutableDocumentFilter routableDocumentFilter,
|
||||
IDataProtectionProvider dataProtectionProvider,
|
||||
IControllerActionSearcher controllerActionSearcher,
|
||||
IPublicAccessRequestHandler publicAccessRequestHandler,
|
||||
IUmbracoVirtualPageRoute umbracoVirtualPageRoute,
|
||||
IOptionsMonitor<GlobalSettings> globalSettings)
|
||||
: this(
|
||||
logger,
|
||||
umbracoContextAccessor,
|
||||
publishedRouter,
|
||||
runtime,
|
||||
routeValuesFactory,
|
||||
routableDocumentFilter,
|
||||
dataProtectionProvider,
|
||||
controllerActionSearcher,
|
||||
publicAccessRequestHandler,
|
||||
umbracoVirtualPageRoute,
|
||||
globalSettings,
|
||||
StaticServiceProvider.Instance.GetRequiredService<IDocumentUrlService>())
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -100,8 +137,7 @@ public class UmbracoRouteValueTransformer : DynamicRouteValueTransformer
|
||||
}
|
||||
|
||||
// Check if there is no existing content and return the no content controller
|
||||
// FIXME: This should be changed to route cache, so instead, if there are any routes, we know there is content.
|
||||
if (!umbracoContext.Content?.HasContent() ?? false)
|
||||
if (!_urlService?.HasAny() ?? false)
|
||||
{
|
||||
return new RouteValueDictionary
|
||||
{
|
||||
|
||||
@@ -3,11 +3,11 @@ using Examine.Lucene;
|
||||
using Examine.Lucene.Directories;
|
||||
using Examine.Lucene.Providers;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Models.PublishedContent;
|
||||
using Umbraco.Cms.Core.PublishedCache;
|
||||
using Umbraco.Cms.Core.Services.Navigation;
|
||||
using Umbraco.Cms.Infrastructure;
|
||||
using Umbraco.Cms.Infrastructure.Examine;
|
||||
using Umbraco.Cms.Tests.Common.Attributes;
|
||||
@@ -80,7 +80,7 @@ internal sealed class PublishedContentQueryTests : ExamineBaseTest
|
||||
var variationContext = new VariationContext();
|
||||
var variationContextAccessor = Mock.Of<IVariationContextAccessor>(x => x.VariationContext == variationContext);
|
||||
|
||||
return new PublishedContentQuery(variationContextAccessor, examineManager.Object, contentCache.Object, Mock.Of<IPublishedMediaCache>());
|
||||
return new PublishedContentQuery(variationContextAccessor, examineManager.Object, contentCache.Object, Mock.Of<IPublishedMediaCache>(), Mock.Of<IDocumentNavigationQueryService>());
|
||||
}
|
||||
|
||||
[TestCase("fr-fr", ExpectedResult = "1, 3", Description = "Search Culture: fr-fr. Must return both fr-fr and invariant results")]
|
||||
|
||||
@@ -43,7 +43,7 @@ public class ContentFinderByUrlAliasTests
|
||||
var contentItem = rootContents[0];
|
||||
Mock.Get(umbracoContextAccessor).Setup(x => x.TryGetUmbracoContext(out umbracoContext)).Returns(true);
|
||||
Mock.Get(umbracoContext).Setup(x => x.Content).Returns(publishedContentCache);
|
||||
Mock.Get(publishedContentCache).Setup(x => x.GetAtRoot(null)).Returns(rootContents);
|
||||
Mock.Get(publishedContentCache).Setup(x => x.GetById(false, It.IsAny<Guid>())).Returns(contentItem);
|
||||
Mock.Get(contentItem).Setup(x => x.Id).Returns(nodeMatch);
|
||||
Mock.Get(contentItem).Setup(x => x.GetProperty(Constants.Conventions.Content.UrlAlias)).Returns(urlProperty);
|
||||
Mock.Get(contentItem).Setup(x => x.ItemType).Returns(PublishedItemType.Content);
|
||||
|
||||
@@ -112,20 +112,12 @@ public class ApiRichTextMarkupParserTests
|
||||
.Returns<bool, Guid>((preview, key) => mockData[key].PublishedContent);
|
||||
contentCacheMock.Setup(cc => cc.GetById(It.IsAny<Guid>()))
|
||||
.Returns<Guid>(key => mockData[key].PublishedContent);
|
||||
contentCacheMock.Setup(cc => cc.GetById(It.IsAny<bool>(), It.IsAny<Udi>()))
|
||||
.Returns<bool, Udi>((preview, udi) => mockData[((GuidUdi)udi).Guid].PublishedContent);
|
||||
contentCacheMock.Setup(cc => cc.GetById(It.IsAny<Udi>()))
|
||||
.Returns<Udi>(udi => mockData[((GuidUdi)udi).Guid].PublishedContent);
|
||||
|
||||
var mediaCacheMock = new Mock<IPublishedMediaCache>();
|
||||
mediaCacheMock.Setup(cc => cc.GetById(It.IsAny<bool>(), It.IsAny<Guid>()))
|
||||
.Returns<bool, Guid>((preview, key) => mockData[key].PublishedContent);
|
||||
mediaCacheMock.Setup(cc => cc.GetById(It.IsAny<Guid>()))
|
||||
.Returns<Guid>(key => mockData[key].PublishedContent);
|
||||
mediaCacheMock.Setup(cc => cc.GetById(It.IsAny<bool>(), It.IsAny<Udi>()))
|
||||
.Returns<bool, Udi>((preview, udi) => mockData[((GuidUdi)udi).Guid].PublishedContent);
|
||||
mediaCacheMock.Setup(cc => cc.GetById(It.IsAny<Udi>()))
|
||||
.Returns<Udi>(udi => mockData[((GuidUdi)udi).Guid].PublishedContent);
|
||||
|
||||
_apiMediaUrlProvider = new Mock<IApiMediaUrlProvider>();
|
||||
_apiMediaUrlProvider.Setup(mup => mup.GetUrl(It.IsAny<IPublishedContent>()))
|
||||
|
||||
@@ -7,6 +7,7 @@ using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.Hosting;
|
||||
using Umbraco.Cms.Core.IO;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Web;
|
||||
using Umbraco.Cms.Tests.Common;
|
||||
using Umbraco.Cms.Web.Website.Controllers;
|
||||
@@ -21,13 +22,13 @@ public class RenderNoContentControllerTests
|
||||
[Test]
|
||||
public void Redirects_To_Root_When_Content_Published()
|
||||
{
|
||||
var mockUmbracoContext = new Mock<IUmbracoContext>();
|
||||
mockUmbracoContext.Setup(x => x.Content.HasContent()).Returns(true);
|
||||
var mockUrlService = new Mock<IDocumentUrlService>();
|
||||
mockUrlService.Setup(x => x.HasAny()).Returns(true);
|
||||
var mockHostingEnvironment = new Mock<IHostingEnvironment>();
|
||||
var controller = new RenderNoContentController(
|
||||
new TestUmbracoContextAccessor(mockUmbracoContext.Object),
|
||||
mockHostingEnvironment.Object,
|
||||
new TestOptionsSnapshot<GlobalSettings>(new GlobalSettings()));
|
||||
new TestOptionsSnapshot<GlobalSettings>(new GlobalSettings()),
|
||||
mockUrlService.Object);
|
||||
|
||||
var result = controller.Index() as RedirectResult;
|
||||
|
||||
@@ -41,8 +42,8 @@ public class RenderNoContentControllerTests
|
||||
const string umbracoPathSetting = Constants.System.DefaultUmbracoPath;
|
||||
const string umbracoPath = "/umbraco";
|
||||
const string viewPath = "~/config/splashes/NoNodes.cshtml";
|
||||
var mockUmbracoContext = new Mock<IUmbracoContext>();
|
||||
mockUmbracoContext.Setup(x => x.Content.HasContent()).Returns(false);
|
||||
var mockUrlService = new Mock<IDocumentUrlService>();
|
||||
mockUrlService.Setup(x => x.HasAny()).Returns(false);
|
||||
var mockIOHelper = new Mock<IIOHelper>();
|
||||
mockIOHelper.Setup(x => x.ResolveUrl(It.Is<string>(y => y == umbracoPathSetting))).Returns(umbracoPath);
|
||||
var mockHostingEnvironment = new Mock<IHostingEnvironment>();
|
||||
@@ -53,7 +54,7 @@ public class RenderNoContentControllerTests
|
||||
{
|
||||
NoNodesViewPath = viewPath,
|
||||
});
|
||||
var controller = new RenderNoContentController(new TestUmbracoContextAccessor(mockUmbracoContext.Object), mockHostingEnvironment.Object, globalSettings);
|
||||
var controller = new RenderNoContentController(mockHostingEnvironment.Object, globalSettings, mockUrlService.Object);
|
||||
|
||||
var result = controller.Index() as ViewResult;
|
||||
Assert.IsNotNull(result);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using Lucene.Net.Search.Similarities;
|
||||
using Microsoft.AspNetCore.DataProtection;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||
@@ -38,15 +39,17 @@ public class UmbracoRouteValueTransformerTests
|
||||
IUmbracoContextAccessor ctx,
|
||||
IRoutableDocumentFilter filter = null,
|
||||
IPublishedRouter router = null,
|
||||
IUmbracoRouteValuesFactory routeValuesFactory = null)
|
||||
=> GetTransformer(ctx, Mock.Of<IRuntimeState>(x => x.Level == RuntimeLevel.Run), filter, router, routeValuesFactory);
|
||||
IUmbracoRouteValuesFactory routeValuesFactory = null,
|
||||
IDocumentUrlService documentUrlService = null)
|
||||
=> GetTransformer(ctx, Mock.Of<IRuntimeState>(x => x.Level == RuntimeLevel.Run), filter, router, routeValuesFactory, documentUrlService);
|
||||
|
||||
private UmbracoRouteValueTransformer GetTransformer(
|
||||
IUmbracoContextAccessor ctx,
|
||||
IRuntimeState state,
|
||||
IRoutableDocumentFilter filter = null,
|
||||
IPublishedRouter router = null,
|
||||
IUmbracoRouteValuesFactory routeValuesFactory = null)
|
||||
IUmbracoRouteValuesFactory routeValuesFactory = null,
|
||||
IDocumentUrlService documentUrlService = null)
|
||||
{
|
||||
var publicAccessRequestHandler = new Mock<IPublicAccessRequestHandler>();
|
||||
publicAccessRequestHandler.Setup(x =>
|
||||
@@ -67,13 +70,14 @@ public class UmbracoRouteValueTransformerTests
|
||||
Mock.Of<IControllerActionSearcher>(),
|
||||
publicAccessRequestHandler.Object,
|
||||
Mock.Of<IUmbracoVirtualPageRoute>(),
|
||||
Mock.Of<IOptionsMonitor<GlobalSettings>>());
|
||||
Mock.Of<IOptionsMonitor<GlobalSettings>>(),
|
||||
documentUrlService ?? Mock.Of<IDocumentUrlService>(x => x.HasAny() == true));
|
||||
return transformer;
|
||||
}
|
||||
|
||||
private IUmbracoContext GetUmbracoContext(bool hasContent)
|
||||
{
|
||||
var publishedContent = Mock.Of<IPublishedContentCache>(x => x.HasContent() == hasContent);
|
||||
var publishedContent = Mock.Of<IDocumentUrlService>(x => x.HasAny() == hasContent);
|
||||
var uri = new Uri("http://example.com");
|
||||
|
||||
var umbracoContext = Mock.Of<IUmbracoContext>(x =>
|
||||
@@ -142,7 +146,11 @@ public class UmbracoRouteValueTransformerTests
|
||||
var umbracoContext = GetUmbracoContext(false);
|
||||
|
||||
var transformer = GetTransformerWithRunState(
|
||||
Mock.Of<IUmbracoContextAccessor>(x => x.TryGetUmbracoContext(out umbracoContext)));
|
||||
Mock.Of<IUmbracoContextAccessor>(x => x.TryGetUmbracoContext(out umbracoContext)),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
Mock.Of<IDocumentUrlService>(x => x.HasAny() == false));
|
||||
|
||||
var result = await transformer.TransformAsync(new DefaultHttpContext(), new RouteValueDictionary());
|
||||
Assert.AreEqual(2, result.Count);
|
||||
|
||||
Reference in New Issue
Block a user