diff --git a/src/Umbraco.Core/Extensions/PublishedContentExtensions.cs b/src/Umbraco.Core/Extensions/PublishedContentExtensions.cs index 5139e23af964..2c110496f03d 100644 --- a/src/Umbraco.Core/Extensions/PublishedContentExtensions.cs +++ b/src/Umbraco.Core/Extensions/PublishedContentExtensions.cs @@ -2,7 +2,9 @@ // See LICENSE for more details. using System.Data; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.DependencyInjection; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Models.Membership; using Umbraco.Cms.Core.Models.PublishedContent; @@ -1898,5 +1900,491 @@ private static Dictionary GetAliasesAndNames(IContentTypeService private static Dictionary GetAliasesAndNames(IContentTypeBase? contentType) => contentType?.PropertyTypes.ToDictionary(x => x.Alias, x => x.Name) ?? new Dictionary(); + + #endregion + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IPublishedContent? Ancestor(this IPublishedContent content, int maxLevel) + { + return content.Ancestor(GetPublishedCache(content), GetNavigationQueryService(content), maxLevel); + } + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IPublishedContent? Ancestor(this IPublishedContent content, string contentTypeAlias) + { + return content.Ancestor(GetPublishedCache(content), GetNavigationQueryService(content), contentTypeAlias); + } + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static T? Ancestor(this IPublishedContent content, int maxLevel) + where T : class, IPublishedContent + { + return Ancestor(content, GetPublishedCache(content), GetNavigationQueryService(content), maxLevel); + } + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IEnumerable Ancestors(this IPublishedContent content, int maxLevel) + { + return content.Ancestors(GetPublishedCache(content), GetNavigationQueryService(content), maxLevel); + } + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IEnumerable Ancestors(this IPublishedContent content, string contentTypeAlias) + { + return content.Ancestors(GetPublishedCache(content), GetNavigationQueryService(content), contentTypeAlias); + } + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IEnumerable Ancestors(this IPublishedContent content) + where T : class, IPublishedContent + { + return Ancestors(content, GetPublishedCache(content), GetNavigationQueryService(content)); + } + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IEnumerable Ancestors(this IPublishedContent content, int maxLevel) + where T : class, IPublishedContent + { + return Ancestors(content, GetPublishedCache(content), GetNavigationQueryService(content), maxLevel); + } + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IPublishedContent AncestorOrSelf(this IPublishedContent content, int maxLevel) + { + return AncestorOrSelf(content, GetPublishedCache(content), GetNavigationQueryService(content), maxLevel); + } + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IPublishedContent AncestorOrSelf(this IPublishedContent content, string contentTypeAlias) + { + return AncestorOrSelf(content, GetPublishedCache(content), GetNavigationQueryService(content), contentTypeAlias); + } + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static T? AncestorOrSelf(this IPublishedContent content, int maxLevel) + where T : class, IPublishedContent + { + return AncestorOrSelf(content, GetPublishedCache(content), GetNavigationQueryService(content), maxLevel); + } + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IEnumerable AncestorsOrSelf(this IPublishedContent content, int maxLevel) + { + return content.AncestorsOrSelf(GetPublishedCache(content), GetNavigationQueryService(content), maxLevel); + } + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IEnumerable AncestorsOrSelf(this IPublishedContent content, string contentTypeAlias) + { + return content.Ancestors(GetPublishedCache(content), GetNavigationQueryService(content), contentTypeAlias); + } + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IEnumerable AncestorsOrSelf(this IPublishedContent content, int maxLevel) + where T : class, IPublishedContent + { + return AncestorsOrSelf(content, GetPublishedCache(content), GetNavigationQueryService(content), maxLevel); + } + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IEnumerable AncestorsOrSelf(this IPublishedContent content, bool orSelf, + Func? func) + { + return AncestorsOrSelf(content, GetPublishedCache(content), GetNavigationQueryService(content), orSelf, func); + } + + [Obsolete( + "Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IEnumerable Breadcrumbs( + this IPublishedContent content, + bool andSelf = true) => + content.Breadcrumbs(GetPublishedCache(content), GetNavigationQueryService(content), andSelf); + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IEnumerable Breadcrumbs( + this IPublishedContent content, + int minLevel, + bool andSelf = true) => + content.Breadcrumbs(GetPublishedCache(content), GetNavigationQueryService(content), minLevel, andSelf); + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IEnumerable Breadcrumbs( + this IPublishedContent content, + bool andSelf = true) + where T : class, IPublishedContent=> + content.Breadcrumbs(GetPublishedCache(content), GetNavigationQueryService(content), andSelf); + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IEnumerable Children( + this IPublishedContent content, + IVariationContextAccessor? variationContextAccessor, + string? culture = null) + => Children(content, variationContextAccessor, GetPublishedCache(content), GetNavigationQueryService(content), culture); + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IEnumerable Children( + this IPublishedContent content, + IVariationContextAccessor variationContextAccessor, + Func predicate, + string? culture = null) => + content.Children(variationContextAccessor, GetPublishedCache(content), GetNavigationQueryService(content), culture).Where(predicate); + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IEnumerable ChildrenOfType( + this IPublishedContent content, + IVariationContextAccessor variationContextAccessor, + string? contentTypeAlias, + string? culture = null) => + content.Children(variationContextAccessor, GetPublishedCache(content), + GetNavigationQueryService(content), x => x.ContentType.Alias.InvariantEquals(contentTypeAlias), + culture); + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IEnumerable Children( + this IPublishedContent content, + IVariationContextAccessor variationContextAccessor, + string? culture = null) + where T : class, IPublishedContent => + content.Children(variationContextAccessor, GetPublishedCache(content), + GetNavigationQueryService(content), culture).OfType(); + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static DataTable ChildrenAsTable( + this IPublishedContent content, + IVariationContextAccessor variationContextAccessor, + IContentTypeService contentTypeService, + IMediaTypeService mediaTypeService, + IMemberTypeService memberTypeService, + IPublishedUrlProvider publishedUrlProvider, + string contentTypeAliasFilter = "", + string? culture = null) + => GenerateDataTable(content, variationContextAccessor, GetPublishedCache(content), + GetNavigationQueryService(content), contentTypeService, mediaTypeService, memberTypeService, publishedUrlProvider, contentTypeAliasFilter, culture); + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IEnumerable DescendantsOrSelfOfType( + this IEnumerable parentNodes, + IVariationContextAccessor variationContextAccessor, + string docTypeAlias, + string? culture = null) => parentNodes.SelectMany(x => + x.DescendantsOrSelfOfType(variationContextAccessor, GetPublishedCache(parentNodes.First()), + GetNavigationQueryService(parentNodes.First()), docTypeAlias, culture)); + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IEnumerable DescendantsOrSelf( + this IEnumerable parentNodes, + IVariationContextAccessor variationContextAccessor, + string? culture = null) + where T : class, IPublishedContent => + parentNodes.SelectMany(x => x.DescendantsOrSelf(variationContextAccessor, GetPublishedCache(parentNodes.First()), + GetNavigationQueryService(parentNodes.First()), culture)); + + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IEnumerable Descendants( + this IPublishedContent content, + IVariationContextAccessor variationContextAccessor, + string? culture = null) => + content.DescendantsOrSelf(variationContextAccessor, GetPublishedCache(content), + GetNavigationQueryService(content), false, null, culture); + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IEnumerable Descendants( + this IPublishedContent content, + IVariationContextAccessor variationContextAccessor, + int level, + string? culture = null) => + content.DescendantsOrSelf(variationContextAccessor, GetPublishedCache(content), + GetNavigationQueryService(content), false, p => p.Level >= level, culture); + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IEnumerable DescendantsOfType( + this IPublishedContent content, + IVariationContextAccessor variationContextAccessor, + string contentTypeAlias, string? culture = null) => + content.DescendantsOrSelf(variationContextAccessor, GetPublishedCache(content), + GetNavigationQueryService(content), false, p => p.ContentType.Alias.InvariantEquals(contentTypeAlias), culture); + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IEnumerable Descendants( + this IPublishedContent content, + IVariationContextAccessor variationContextAccessor, + string? culture = null) + where T : class, IPublishedContent => + content.Descendants(variationContextAccessor, GetPublishedCache(content), + GetNavigationQueryService(content), culture).OfType(); + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IEnumerable Descendants( + this IPublishedContent content, + IVariationContextAccessor variationContextAccessor, + int level, + string? culture = null) + where T : class, IPublishedContent => + content.Descendants(variationContextAccessor, GetPublishedCache(content), + GetNavigationQueryService(content), level, culture).OfType(); + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IEnumerable DescendantsOrSelf( + this IPublishedContent content, + IVariationContextAccessor variationContextAccessor, + string? culture = null) => + content.DescendantsOrSelf(variationContextAccessor, GetPublishedCache(content), + GetNavigationQueryService(content), true, null, culture); + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IEnumerable DescendantsOrSelf( + this IPublishedContent content, + IVariationContextAccessor variationContextAccessor, + int level, + string? culture = null) => + content.DescendantsOrSelf(variationContextAccessor, GetPublishedCache(content), + GetNavigationQueryService(content), true, p => p.Level >= level, culture); + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IEnumerable DescendantsOrSelfOfType( + this IPublishedContent content, + IVariationContextAccessor variationContextAccessor, + string contentTypeAlias, + string? culture = null) => + content.DescendantsOrSelf(variationContextAccessor, GetPublishedCache(content), + GetNavigationQueryService(content), true, p => p.ContentType.Alias.InvariantEquals(contentTypeAlias), culture); + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IEnumerable DescendantsOrSelf( + this IPublishedContent content, + IVariationContextAccessor variationContextAccessor, + string? culture = null) + where T : class, IPublishedContent => + content.DescendantsOrSelf(variationContextAccessor, GetPublishedCache(content), + GetNavigationQueryService(content), culture).OfType(); + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IEnumerable DescendantsOrSelf( + this IPublishedContent content, + IVariationContextAccessor variationContextAccessor, + int level, + string? culture = null) + where T : class, IPublishedContent => + content.DescendantsOrSelf(variationContextAccessor, GetPublishedCache(content), + GetNavigationQueryService(content), level, culture).OfType(); + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IPublishedContent? Descendant( + this IPublishedContent content, + IVariationContextAccessor variationContextAccessor, + string? culture = null) => + content.Children(variationContextAccessor, GetPublishedCache(content), + GetNavigationQueryService(content), culture)?.FirstOrDefault(); + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IPublishedContent? Descendant( + this IPublishedContent content, + IVariationContextAccessor variationContextAccessor, + int level, + string? culture = null) => content + .EnumerateDescendants(variationContextAccessor, GetPublishedCache(content), + GetNavigationQueryService(content), false, culture).FirstOrDefault(x => x.Level == level); + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IPublishedContent? DescendantOfType( + this IPublishedContent content, + IVariationContextAccessor variationContextAccessor, + string contentTypeAlias, + string? culture = null) => content + .EnumerateDescendants(variationContextAccessor, GetPublishedCache(content), + GetNavigationQueryService(content), false, culture) + .FirstOrDefault(x => x.ContentType.Alias.InvariantEquals(contentTypeAlias)); + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static T? Descendant( + this IPublishedContent content, + IVariationContextAccessor variationContextAccessor, + string? culture = null) + where T : class, IPublishedContent => + content.EnumerateDescendants(variationContextAccessor, GetPublishedCache(content), + GetNavigationQueryService(content), false, culture).FirstOrDefault(x => x is T) as T; + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static T? Descendant( + this IPublishedContent content, + IVariationContextAccessor variationContextAccessor, + int level, + string? culture = null) + where T : class, IPublishedContent => + content.Descendant(variationContextAccessor, GetPublishedCache(content), + GetNavigationQueryService(content), level, culture) as T; + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IPublishedContent? DescendantOrSelf( + this IPublishedContent content, + IVariationContextAccessor variationContextAccessor, + int level, + string? culture = null) => content + .EnumerateDescendants(variationContextAccessor, GetPublishedCache(content), + GetNavigationQueryService(content), true, culture).FirstOrDefault(x => x.Level == level); + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IPublishedContent? DescendantOrSelfOfType( + this IPublishedContent content, + IVariationContextAccessor variationContextAccessor, + string contentTypeAlias, + string? culture = null) => content + .EnumerateDescendants(variationContextAccessor, GetPublishedCache(content), + GetNavigationQueryService(content), true, culture) + .FirstOrDefault(x => x.ContentType.Alias.InvariantEquals(contentTypeAlias)); + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static T? DescendantOrSelf( + this IPublishedContent content, + IVariationContextAccessor variationContextAccessor, + string? culture = null) + where T : class, IPublishedContent => + content.EnumerateDescendants(variationContextAccessor, GetPublishedCache(content), + GetNavigationQueryService(content), true, culture).FirstOrDefault(x => x is T) as T; + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static T? DescendantOrSelf( + this IPublishedContent content, + IVariationContextAccessor variationContextAccessor, + int level, + string? culture = null) + where T : class, IPublishedContent => + content.DescendantOrSelf(variationContextAccessor, GetPublishedCache(content), + GetNavigationQueryService(content), level, culture) as T; + + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IPublishedContent? FirstChild( + this IPublishedContent content, + IVariationContextAccessor variationContextAccessor, + string? culture = null) => + content.Children(variationContextAccessor, GetPublishedCache(content), + GetNavigationQueryService(content), culture)?.FirstOrDefault(); + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IPublishedContent? FirstChildOfType( + this IPublishedContent content, + IVariationContextAccessor variationContextAccessor, + string contentTypeAlias, + string? culture = null) => + content.ChildrenOfType(variationContextAccessor, GetPublishedCache(content), + GetNavigationQueryService(content), contentTypeAlias, culture)?.FirstOrDefault(); + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IPublishedContent? FirstChild( + this IPublishedContent content, + IVariationContextAccessor variationContextAccessor, + Func predicate, + string? culture = null) + => content.Children(variationContextAccessor, GetPublishedCache(content), + GetNavigationQueryService(content), predicate, culture)?.FirstOrDefault(); + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IPublishedContent? FirstChild( + this IPublishedContent content, + IVariationContextAccessor variationContextAccessor, + Guid uniqueId, + string? culture = null) => content + .Children(variationContextAccessor, GetPublishedCache(content), + GetNavigationQueryService(content), x => x.Key == uniqueId, culture)?.FirstOrDefault(); + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static T? FirstChild( + this IPublishedContent content, + IVariationContextAccessor variationContextAccessor, + string? culture = null) + where T : class, IPublishedContent => + content.Children(variationContextAccessor, GetPublishedCache(content), + GetNavigationQueryService(content), culture)?.FirstOrDefault(); + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static T? FirstChild( + this IPublishedContent content, + IVariationContextAccessor variationContextAccessor, + Func predicate, + string? culture = null) + where T : class, IPublishedContent => + content.Children(variationContextAccessor, GetPublishedCache(content), + GetNavigationQueryService(content), culture)?.FirstOrDefault(predicate); + + [Obsolete( + "Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IEnumerable Siblings( + this IPublishedContent content, + IVariationContextAccessor variationContextAccessor, + string? culture = null) => + Siblings(content, GetPublishedCache(content), GetNavigationQueryService(content), variationContextAccessor, culture); + + [Obsolete( + "Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IEnumerable SiblingsOfType( + this IPublishedContent content, + IVariationContextAccessor variationContextAccessor, + string contentTypeAlias, + string? culture = null) => + SiblingsOfType(content, variationContextAccessor, + GetPublishedCache(content), GetNavigationQueryService(content), contentTypeAlias, culture); + + [Obsolete( + "Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IEnumerable Siblings( + this IPublishedContent content, + IVariationContextAccessor variationContextAccessor, + string? culture = null) + where T : class, IPublishedContent => + Siblings(content, variationContextAccessor, GetPublishedCache(content), GetNavigationQueryService(content), culture); + + [Obsolete( + "Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IEnumerable? SiblingsAndSelf( + this IPublishedContent content, + IVariationContextAccessor variationContextAccessor, + string? culture = null) => SiblingsAndSelf(content, GetPublishedCache(content), GetNavigationQueryService(content), variationContextAccessor, culture); + + [Obsolete( + "Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IEnumerable SiblingsAndSelfOfType( + this IPublishedContent content, + IVariationContextAccessor variationContextAccessor, + string contentTypeAlias, + string? culture = null) => SiblingsAndSelfOfType(content, variationContextAccessor, GetPublishedCache(content), + GetNavigationQueryService(content), contentTypeAlias, culture); + + [Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")] + public static IEnumerable SiblingsAndSelf( + this IPublishedContent content, + IVariationContextAccessor variationContextAccessor, + string? culture = null) + where T : class, IPublishedContent => SiblingsAndSelf(content, variationContextAccessor, GetPublishedCache(content), + GetNavigationQueryService(content), culture); + + + private static INavigationQueryService GetNavigationQueryService(IPublishedContent content) + { + switch (content.ContentType.ItemType) + { + case PublishedItemType.Content: + return StaticServiceProvider.Instance.GetRequiredService(); + case PublishedItemType.Media: + return StaticServiceProvider.Instance.GetRequiredService(); + default: + throw new NotSupportedException("Unsupported content type."); + } + + } + + private static IPublishedCache GetPublishedCache(IPublishedContent content) + { + switch (content.ContentType.ItemType) + { + case PublishedItemType.Content: + return StaticServiceProvider.Instance.GetRequiredService(); + case PublishedItemType.Media: + return StaticServiceProvider.Instance.GetRequiredService(); + default: + throw new NotSupportedException("Unsupported content type."); + } + } } diff --git a/src/Umbraco.Web.Common/Extensions/FriendlyPublishedContentExtensions.cs b/src/Umbraco.Web.Common/Extensions/FriendlyPublishedContentExtensions.cs index 858c7d82cdea..60c7a27a57eb 100644 --- a/src/Umbraco.Web.Common/Extensions/FriendlyPublishedContentExtensions.cs +++ b/src/Umbraco.Web.Common/Extensions/FriendlyPublishedContentExtensions.cs @@ -22,9 +22,15 @@ public static class FriendlyPublishedContentExtensions private static IPublishedContentCache PublishedContentCache { get; } = StaticServiceProvider.Instance.GetRequiredService(); + private static IPublishedMediaCache PublishedMediaCache { get; } = + StaticServiceProvider.Instance.GetRequiredService(); + private static IDocumentNavigationQueryService DocumentNavigationQueryService { get; } = StaticServiceProvider.Instance.GetRequiredService(); + private static IMediaNavigationQueryService MediaNavigationQueryService { get; } = + StaticServiceProvider.Instance.GetRequiredService(); + private static IPublishedModelFactory PublishedModelFactory { get; } = StaticServiceProvider.Instance.GetRequiredService(); @@ -61,6 +67,33 @@ public static class FriendlyPublishedContentExtensions private static IMemberTypeService MemberTypeService { get; } = StaticServiceProvider.Instance.GetRequiredService(); + private static INavigationQueryService GetNavigationQueryService(IPublishedContent content) + { + switch (content.ContentType.ItemType) + { + case PublishedItemType.Content: + return DocumentNavigationQueryService; + case PublishedItemType.Media: + return MediaNavigationQueryService; + default: + throw new NotSupportedException("Unsupported content type."); + } + + } + + private static IPublishedCache GetPublishedCache(IPublishedContent content) + { + switch (content.ContentType.ItemType) + { + case PublishedItemType.Content: + return PublishedContentCache; + case PublishedItemType.Media: + return PublishedMediaCache; + default: + throw new NotSupportedException("Unsupported content type."); + } + } + /// /// Creates a strongly typed published content model for an internal published content. /// @@ -207,7 +240,7 @@ public static bool HasValue( /// set to 1. /// public static IPublishedContent Root(this IPublishedContent content) - => content.Root(PublishedContentCache, DocumentNavigationQueryService); + => content.Root(GetPublishedCache(content), GetNavigationQueryService(content)); /// /// Gets the root content (ancestor or self at level 1) for the specified if it's of the @@ -226,7 +259,7 @@ public static IPublishedContent Root(this IPublishedContent content) /// public static T? Root(this IPublishedContent content) where T : class, IPublishedContent - => content.Root(PublishedContentCache, DocumentNavigationQueryService); + => content.Root(GetPublishedCache(content), GetNavigationQueryService(content)); /// /// Gets the parent of the content item. @@ -236,7 +269,7 @@ public static IPublishedContent Root(this IPublishedContent content) /// The parent of content of the specified content type or null. public static T? Parent(this IPublishedContent content) where T : class, IPublishedContent - => content.Parent(PublishedContentCache, DocumentNavigationQueryService); + => content.Parent(GetPublishedCache(content), GetNavigationQueryService(content)); /// /// Gets the ancestors of the content. @@ -245,7 +278,7 @@ public static IPublishedContent Root(this IPublishedContent content) /// The ancestors of the content, in down-top order. /// Does not consider the content itself. public static IEnumerable Ancestors(this IPublishedContent content) - => content.Ancestors(PublishedContentCache, DocumentNavigationQueryService); + => content.Ancestors(GetPublishedCache(content), GetNavigationQueryService(content)); /// /// Gets the content and its ancestors. @@ -253,7 +286,7 @@ public static IEnumerable Ancestors(this IPublishedContent co /// The content. /// The content and its ancestors, in down-top order. public static IEnumerable AncestorsOrSelf(this IPublishedContent content) - => content.AncestorsOrSelf(PublishedContentCache, DocumentNavigationQueryService); + => content.AncestorsOrSelf(GetPublishedCache(content), GetNavigationQueryService(content)); /// /// Gets the content and its ancestors, of a specified content type. @@ -264,7 +297,7 @@ public static IEnumerable AncestorsOrSelf(this IPublishedCont /// May or may not begin with the content itself, depending on its content type. public static IEnumerable AncestorsOrSelf(this IPublishedContent content) where T : class, IPublishedContent - => content.AncestorsOrSelf(PublishedContentCache, DocumentNavigationQueryService); + => content.AncestorsOrSelf(GetPublishedCache(content), GetNavigationQueryService(content)); /// /// Gets the ancestor of the content, i.e. its parent. @@ -272,7 +305,7 @@ public static IEnumerable AncestorsOrSelf(this IPublishedContent content) /// The content. /// The ancestor of the content. public static IPublishedContent? Ancestor(this IPublishedContent content) - => content.Ancestor(PublishedContentCache, DocumentNavigationQueryService); + => content.Ancestor(GetPublishedCache(content), GetNavigationQueryService(content)); /// /// Gets the nearest ancestor of the content, of a specified content type. @@ -283,7 +316,7 @@ public static IEnumerable AncestorsOrSelf(this IPublishedContent content) /// Does not consider the content itself. May return null. public static T? Ancestor(this IPublishedContent content) where T : class, IPublishedContent - => content.Ancestor(PublishedContentCache, DocumentNavigationQueryService); + => content.Ancestor(GetPublishedCache(content), GetNavigationQueryService(content)); /// /// Gets the content or its nearest ancestor, of a specified content type. @@ -294,7 +327,7 @@ public static IEnumerable AncestorsOrSelf(this IPublishedContent content) /// May or may not return the content itself depending on its content type. May return null. public static T? AncestorOrSelf(this IPublishedContent content) where T : class, IPublishedContent - => content.AncestorOrSelf(PublishedContentCache, DocumentNavigationQueryService); + => content.AncestorOrSelf(GetPublishedCache(content), GetNavigationQueryService(content)); /// /// Returns all DescendantsOrSelf of all content referenced @@ -311,7 +344,7 @@ public static IEnumerable AncestorsOrSelf(this IPublishedContent content) /// public static IEnumerable DescendantsOrSelfOfType( this IEnumerable parentNodes, string docTypeAlias, string? culture = null) - => parentNodes.DescendantsOrSelfOfType(VariationContextAccessor, PublishedContentCache, DocumentNavigationQueryService, docTypeAlias, culture); + => parentNodes.DescendantsOrSelfOfType(VariationContextAccessor, GetPublishedCache(parentNodes.First()), GetNavigationQueryService(parentNodes.First()), docTypeAlias, culture); /// /// Returns all DescendantsOrSelf of all content referenced @@ -329,77 +362,77 @@ public static IEnumerable DescendantsOrSelf( this IEnumerable parentNodes, string? culture = null) where T : class, IPublishedContent - => parentNodes.DescendantsOrSelf(VariationContextAccessor, PublishedContentCache, DocumentNavigationQueryService, culture); + => parentNodes.DescendantsOrSelf(VariationContextAccessor, GetPublishedCache(parentNodes.First()), GetNavigationQueryService(parentNodes.First()), culture); public static IEnumerable Descendants(this IPublishedContent content, string? culture = null) - => content.Descendants(VariationContextAccessor, PublishedContentCache, DocumentNavigationQueryService, culture); + => content.Descendants(VariationContextAccessor, GetPublishedCache(content), GetNavigationQueryService(content), culture); public static IEnumerable Descendants(this IPublishedContent content, int level, string? culture = null) - => content.Descendants(VariationContextAccessor, PublishedContentCache, DocumentNavigationQueryService, level, culture); + => content.Descendants(VariationContextAccessor, GetPublishedCache(content), GetNavigationQueryService(content), level, culture); public static IEnumerable DescendantsOfType(this IPublishedContent content, string contentTypeAlias, string? culture = null) - => content.DescendantsOfType(VariationContextAccessor, PublishedContentCache, DocumentNavigationQueryService, contentTypeAlias, culture); + => content.DescendantsOfType(VariationContextAccessor, GetPublishedCache(content), GetNavigationQueryService(content), contentTypeAlias, culture); public static IEnumerable Descendants(this IPublishedContent content, string? culture = null) where T : class, IPublishedContent - => content.Descendants(VariationContextAccessor, PublishedContentCache, DocumentNavigationQueryService, culture); + => content.Descendants(VariationContextAccessor, GetPublishedCache(content), GetNavigationQueryService(content), culture); public static IEnumerable Descendants(this IPublishedContent content, int level, string? culture = null) where T : class, IPublishedContent - => content.Descendants(VariationContextAccessor, PublishedContentCache, DocumentNavigationQueryService, level, culture); + => content.Descendants(VariationContextAccessor, GetPublishedCache(content), GetNavigationQueryService(content), level, culture); public static IEnumerable DescendantsOrSelf( this IPublishedContent content, string? culture = null) - => content.DescendantsOrSelf(VariationContextAccessor, PublishedContentCache, DocumentNavigationQueryService, culture); + => content.DescendantsOrSelf(VariationContextAccessor, GetPublishedCache(content), GetNavigationQueryService(content), culture); public static IEnumerable DescendantsOrSelf(this IPublishedContent content, int level, string? culture = null) - => content.DescendantsOrSelf(VariationContextAccessor, PublishedContentCache, DocumentNavigationQueryService, level, culture); + => content.DescendantsOrSelf(VariationContextAccessor, GetPublishedCache(content), GetNavigationQueryService(content), level, culture); public static IEnumerable DescendantsOrSelfOfType(this IPublishedContent content, string contentTypeAlias, string? culture = null) - => content.DescendantsOrSelfOfType(VariationContextAccessor, PublishedContentCache, DocumentNavigationQueryService, contentTypeAlias, culture); + => content.DescendantsOrSelfOfType(VariationContextAccessor, GetPublishedCache(content), GetNavigationQueryService(content), contentTypeAlias, culture); public static IEnumerable DescendantsOrSelf(this IPublishedContent content, string? culture = null) where T : class, IPublishedContent - => content.DescendantsOrSelf(VariationContextAccessor, PublishedContentCache, DocumentNavigationQueryService, culture); + => content.DescendantsOrSelf(VariationContextAccessor, GetPublishedCache(content), GetNavigationQueryService(content), culture); public static IEnumerable DescendantsOrSelf(this IPublishedContent content, int level, string? culture = null) where T : class, IPublishedContent - => content.DescendantsOrSelf(VariationContextAccessor, PublishedContentCache, DocumentNavigationQueryService, level, culture); + => content.DescendantsOrSelf(VariationContextAccessor, GetPublishedCache(content), GetNavigationQueryService(content), level, culture); public static IPublishedContent? Descendant(this IPublishedContent content, string? culture = null) - => content.Descendant(VariationContextAccessor, PublishedContentCache, DocumentNavigationQueryService, culture); + => content.Descendant(VariationContextAccessor, GetPublishedCache(content), GetNavigationQueryService(content), culture); public static IPublishedContent? Descendant(this IPublishedContent content, int level, string? culture = null) - => content.Descendant(VariationContextAccessor, PublishedContentCache, DocumentNavigationQueryService, level, culture); + => content.Descendant(VariationContextAccessor, GetPublishedCache(content), GetNavigationQueryService(content), level, culture); public static IPublishedContent? DescendantOfType(this IPublishedContent content, string contentTypeAlias, string? culture = null) - => content.DescendantOfType(VariationContextAccessor, PublishedContentCache, DocumentNavigationQueryService, contentTypeAlias, culture); + => content.DescendantOfType(VariationContextAccessor, GetPublishedCache(content), GetNavigationQueryService(content), contentTypeAlias, culture); public static T? Descendant(this IPublishedContent content, string? culture = null) where T : class, IPublishedContent - => content.Descendant(VariationContextAccessor, PublishedContentCache, DocumentNavigationQueryService, culture); + => content.Descendant(VariationContextAccessor, GetPublishedCache(content), GetNavigationQueryService(content), culture); public static T? Descendant(this IPublishedContent content, int level, string? culture = null) where T : class, IPublishedContent - => content.Descendant(VariationContextAccessor, PublishedContentCache, DocumentNavigationQueryService, level, culture); + => content.Descendant(VariationContextAccessor, GetPublishedCache(content), GetNavigationQueryService(content), level, culture); public static IPublishedContent DescendantOrSelf(this IPublishedContent content, string? culture = null) => content.DescendantOrSelf(VariationContextAccessor, culture); public static IPublishedContent? DescendantOrSelf(this IPublishedContent content, int level, string? culture = null) - => content.DescendantOrSelf(VariationContextAccessor, PublishedContentCache, DocumentNavigationQueryService, level, culture); + => content.DescendantOrSelf(VariationContextAccessor, GetPublishedCache(content), GetNavigationQueryService(content), level, culture); public static IPublishedContent? DescendantOrSelfOfType(this IPublishedContent content, string contentTypeAlias, string? culture = null) - => content.DescendantOrSelfOfType(VariationContextAccessor, PublishedContentCache, DocumentNavigationQueryService, contentTypeAlias, culture); + => content.DescendantOrSelfOfType(VariationContextAccessor, GetPublishedCache(content), GetNavigationQueryService(content), contentTypeAlias, culture); public static T? DescendantOrSelf(this IPublishedContent content, string? culture = null) where T : class, IPublishedContent - => content.DescendantOrSelf(VariationContextAccessor, PublishedContentCache, DocumentNavigationQueryService, culture); + => content.DescendantOrSelf(VariationContextAccessor, GetPublishedCache(content), GetNavigationQueryService(content), culture); public static T? DescendantOrSelf(this IPublishedContent content, int level, string? culture = null) where T : class, IPublishedContent - => content.DescendantOrSelf(VariationContextAccessor, PublishedContentCache, DocumentNavigationQueryService, level, culture); + => content.DescendantOrSelf(VariationContextAccessor, GetPublishedCache(content), GetNavigationQueryService(content), level, culture); /// /// Gets the children of the content item. @@ -427,7 +460,7 @@ public static IPublishedContent DescendantOrSelf(this IPublishedContent content, /// /// public static IEnumerable Children(this IPublishedContent content, string? culture = null) - => content.Children(VariationContextAccessor, PublishedContentCache, DocumentNavigationQueryService, culture); + => content.Children(VariationContextAccessor, GetPublishedCache(content), GetNavigationQueryService(content), culture); /// /// Gets the children of the content, filtered by a predicate. @@ -446,7 +479,7 @@ public static IEnumerable Children(this IPublishedContent con this IPublishedContent content, Func predicate, string? culture = null) - => content.Children(VariationContextAccessor, PublishedContentCache, DocumentNavigationQueryService, predicate, culture); + => content.Children(VariationContextAccessor, GetPublishedCache(content), GetNavigationQueryService(content), predicate, culture); /// /// Gets the children of the content, of any of the specified types. @@ -459,7 +492,7 @@ public static IEnumerable Children(this IPublishedContent con /// The content type alias. /// The children of the content, of any of the specified types. public static IEnumerable? ChildrenOfType(this IPublishedContent content, string contentTypeAlias, string? culture = null) - => content.ChildrenOfType(VariationContextAccessor, PublishedContentCache, DocumentNavigationQueryService, contentTypeAlias, culture); + => content.ChildrenOfType(VariationContextAccessor, GetPublishedCache(content), GetNavigationQueryService(content), contentTypeAlias, culture); /// /// Gets the children of the content, of a given content type. @@ -476,30 +509,30 @@ public static IEnumerable Children(this IPublishedContent con /// public static IEnumerable? Children(this IPublishedContent content, string? culture = null) where T : class, IPublishedContent - => content.Children(VariationContextAccessor, PublishedContentCache, DocumentNavigationQueryService, culture); + => content.Children(VariationContextAccessor, GetPublishedCache(content), GetNavigationQueryService(content), culture); public static IPublishedContent? FirstChild(this IPublishedContent content, string? culture = null) - => content.FirstChild(VariationContextAccessor, PublishedContentCache, DocumentNavigationQueryService, culture); + => content.FirstChild(VariationContextAccessor, GetPublishedCache(content), GetNavigationQueryService(content), culture); /// /// Gets the first child of the content, of a given content type. /// public static IPublishedContent? FirstChildOfType(this IPublishedContent content, string contentTypeAlias, string? culture = null) - => content.FirstChildOfType(VariationContextAccessor, PublishedContentCache, DocumentNavigationQueryService, contentTypeAlias, culture); + => content.FirstChildOfType(VariationContextAccessor, GetPublishedCache(content), GetNavigationQueryService(content), contentTypeAlias, culture); public static IPublishedContent? FirstChild(this IPublishedContent content, Func predicate, string? culture = null) - => content.FirstChild(VariationContextAccessor, PublishedContentCache, DocumentNavigationQueryService, predicate, culture); + => content.FirstChild(VariationContextAccessor, GetPublishedCache(content), GetNavigationQueryService(content), predicate, culture); public static IPublishedContent? FirstChild(this IPublishedContent content, Guid uniqueId, string? culture = null) - => content.FirstChild(VariationContextAccessor, PublishedContentCache, DocumentNavigationQueryService, uniqueId, culture); + => content.FirstChild(VariationContextAccessor, GetPublishedCache(content), GetNavigationQueryService(content), uniqueId, culture); public static T? FirstChild(this IPublishedContent content, string? culture = null) where T : class, IPublishedContent - => content.FirstChild(VariationContextAccessor, PublishedContentCache, DocumentNavigationQueryService, culture); + => content.FirstChild(VariationContextAccessor, GetPublishedCache(content), GetNavigationQueryService(content), culture); public static T? FirstChild(this IPublishedContent content, Func predicate, string? culture = null) where T : class, IPublishedContent - => content.FirstChild(VariationContextAccessor, PublishedContentCache, DocumentNavigationQueryService, predicate, culture); + => content.FirstChild(VariationContextAccessor, GetPublishedCache(content), GetNavigationQueryService(content), predicate, culture); /// /// Gets the siblings of the content. @@ -514,7 +547,7 @@ public static IEnumerable Children(this IPublishedContent con /// Note that in V7 this method also return the content node self. /// public static IEnumerable? Siblings(this IPublishedContent content, string? culture = null) - => content.Siblings(PublishedContentCache, DocumentNavigationQueryService, VariationContextAccessor, culture); + => content.Siblings(GetPublishedCache(content), GetNavigationQueryService(content), VariationContextAccessor, culture); /// /// Gets the siblings of the content, of a given content type. @@ -530,7 +563,7 @@ public static IEnumerable Children(this IPublishedContent con /// Note that in V7 this method also return the content node self. /// public static IEnumerable? SiblingsOfType(this IPublishedContent content, string contentTypeAlias, string? culture = null) - => content.SiblingsOfType(VariationContextAccessor, PublishedContentCache, DocumentNavigationQueryService, contentTypeAlias, culture); + => content.SiblingsOfType(VariationContextAccessor, GetPublishedCache(content), GetNavigationQueryService(content), contentTypeAlias, culture); /// /// Gets the siblings of the content, of a given content type. @@ -547,7 +580,7 @@ public static IEnumerable Children(this IPublishedContent con /// public static IEnumerable? Siblings(this IPublishedContent content, string? culture = null) where T : class, IPublishedContent - => content.Siblings(VariationContextAccessor, PublishedContentCache, DocumentNavigationQueryService, culture); + => content.Siblings(VariationContextAccessor, GetPublishedCache(content), GetNavigationQueryService(content), culture); /// /// Gets the siblings of the content including the node itself to indicate the position. @@ -561,7 +594,7 @@ public static IEnumerable Children(this IPublishedContent con public static IEnumerable? SiblingsAndSelf( this IPublishedContent content, string? culture = null) - => content.SiblingsAndSelf(PublishedContentCache, DocumentNavigationQueryService, VariationContextAccessor, culture); + => content.SiblingsAndSelf(GetPublishedCache(content), GetNavigationQueryService(content), VariationContextAccessor, culture); /// /// Gets the siblings of the content including the node itself to indicate the position, of a given content type. @@ -577,7 +610,7 @@ public static IEnumerable Children(this IPublishedContent con this IPublishedContent content, string contentTypeAlias, string? culture = null) - => content.SiblingsAndSelfOfType(VariationContextAccessor, PublishedContentCache, DocumentNavigationQueryService, contentTypeAlias, culture); + => content.SiblingsAndSelfOfType(VariationContextAccessor, GetPublishedCache(content), GetNavigationQueryService(content), contentTypeAlias, culture); /// /// Gets the siblings of the content including the node itself to indicate the position, of a given content type. @@ -591,7 +624,7 @@ public static IEnumerable Children(this IPublishedContent con /// The siblings of the content including the node itself, of the given content type. public static IEnumerable? SiblingsAndSelf(this IPublishedContent content, string? culture = null) where T : class, IPublishedContent - => content.SiblingsAndSelf(VariationContextAccessor, PublishedContentCache, DocumentNavigationQueryService, culture); + => content.SiblingsAndSelf(VariationContextAccessor, GetPublishedCache(content), GetNavigationQueryService(content), culture); /// /// Gets the url of the content item. @@ -626,8 +659,8 @@ public static DataTable ChildrenAsTable(this IPublishedContent content, string c => content.ChildrenAsTable( VariationContextAccessor, - PublishedContentCache, - DocumentNavigationQueryService, + GetPublishedCache(content), + GetNavigationQueryService(content), ContentTypeService, MediaTypeService, MemberTypeService, @@ -700,4 +733,5 @@ public static IEnumerable SearchChildren( string term, string? indexName = null) => content.SearchChildren(ExamineManager, UmbracoContextAccessor, term, indexName); + }