diff --git a/src/Umbraco.Core/Extensions/PublishedContentExtensions.cs b/src/Umbraco.Core/Extensions/PublishedContentExtensions.cs index 848bf62208..fdf47a2c82 100644 --- a/src/Umbraco.Core/Extensions/PublishedContentExtensions.cs +++ b/src/Umbraco.Core/Extensions/PublishedContentExtensions.cs @@ -2759,6 +2759,7 @@ public static class PublishedContentExtensions /// The content. /// The navigation service /// Variation context accessor. + /// /// /// The specific culture to filter for. If null is used the current culture is used. (Default is /// null) @@ -2773,10 +2774,69 @@ public static class PublishedContentExtensions IPublishedCache publishedCache, INavigationQueryService navigationQueryService, IVariationContextAccessor variationContextAccessor, + IPublishStatusQueryService publishStatusQueryService, string? culture = null) => - SiblingsAndSelf(content, publishedCache, navigationQueryService, variationContextAccessor, culture) + SiblingsAndSelf(content, publishedCache, navigationQueryService, variationContextAccessor, publishStatusQueryService, culture) ?.Where(x => x.Id != content.Id) ?? Enumerable.Empty(); + /// + /// Gets the siblings of the content. + /// + /// The content. + /// The navigation service + /// Variation context accessor. + /// + /// The specific culture to filter for. If null is used the current culture is used. (Default is + /// null) + /// + /// The content cache instance. + /// The siblings of the content. + /// + /// Note that in V7 this method also return the content node self. + /// + [Obsolete("Use the overload with IPublishStatusQueryService, scheduled for removal in v17")] + public static IEnumerable Siblings( + this IPublishedContent content, + IPublishedCache publishedCache, + INavigationQueryService navigationQueryService, + IVariationContextAccessor variationContextAccessor, + string? culture = null) => + Siblings( + content, + publishedCache, + navigationQueryService, + variationContextAccessor, + StaticServiceProvider.Instance.GetRequiredService(), + culture); + + /// + /// Gets the siblings of the content, of a given content type. + /// + /// The content. + /// Variation context accessor. + /// + /// The specific culture to filter for. If null is used the current culture is used. (Default is + /// null) + /// + /// + /// + /// + /// The content type alias. + /// The siblings of the content, of the given content type. + /// + /// Note that in V7 this method also return the content node self. + /// + public static IEnumerable SiblingsOfType( + this IPublishedContent content, + IVariationContextAccessor variationContextAccessor, + IPublishedCache publishedCache, + INavigationQueryService navigationQueryService, + IPublishStatusQueryService publishStatusQueryService, + string contentTypeAlias, + string? culture = null) => + SiblingsAndSelfOfType(content, variationContextAccessor, publishedCache, navigationQueryService, publishStatusQueryService, contentTypeAlias, culture) + .Where(x => x.Id != content.Id); + /// /// Gets the siblings of the content, of a given content type. /// @@ -2793,6 +2853,7 @@ public static class PublishedContentExtensions /// /// Note that in V7 this method also return the content node self. /// + [Obsolete("Use the overload with IPublishStatusQueryService, scheduled for removal in v17")] public static IEnumerable SiblingsOfType( this IPublishedContent content, IVariationContextAccessor variationContextAccessor, @@ -2800,8 +2861,42 @@ public static class PublishedContentExtensions INavigationQueryService navigationQueryService, string contentTypeAlias, string? culture = null) => - SiblingsAndSelfOfType(content, variationContextAccessor, publishedCache, navigationQueryService, contentTypeAlias, culture) - .Where(x => x.Id != content.Id); + SiblingsOfType( + content, + variationContextAccessor, + publishedCache, + navigationQueryService, + StaticServiceProvider.Instance.GetRequiredService(), + contentTypeAlias, + culture); + + /// + /// Gets the siblings of the content, of a given content type. + /// + /// The content type. + /// The content. + /// Variation context accessor. + /// + /// + /// + /// + /// The specific culture to filter for. If null is used the current culture is used. (Default is + /// null) + /// + /// The siblings of the content, of the given content type. + /// + /// Note that in V7 this method also return the content node self. + /// + public static IEnumerable Siblings( + this IPublishedContent content, + IVariationContextAccessor variationContextAccessor, + IPublishedCache publishedCache, + INavigationQueryService navigationQueryService, + IPublishStatusQueryService publishStatusQueryService, + string? culture = null) + where T : class, IPublishedContent => + SiblingsAndSelf(content, variationContextAccessor, publishedCache, navigationQueryService, publishStatusQueryService, culture) + ?.Where(x => x.Id != content.Id) ?? Enumerable.Empty(); /// /// Gets the siblings of the content, of a given content type. @@ -2819,6 +2914,7 @@ public static class PublishedContentExtensions /// /// Note that in V7 this method also return the content node self. /// + [Obsolete("Use the overload with IPublishStatusQueryService, scheduled for removal in v17")] public static IEnumerable Siblings( this IPublishedContent content, IVariationContextAccessor variationContextAccessor, @@ -2826,8 +2922,56 @@ public static class PublishedContentExtensions INavigationQueryService navigationQueryService, string? culture = null) where T : class, IPublishedContent => - SiblingsAndSelf(content, variationContextAccessor, publishedCache, navigationQueryService, culture) - ?.Where(x => x.Id != content.Id) ?? Enumerable.Empty(); + Siblings( + content, + variationContextAccessor, + publishedCache, + navigationQueryService, + StaticServiceProvider.Instance.GetRequiredService(), + culture); + + /// + /// Gets the siblings of the content including the node itself to indicate the position. + /// + /// The content. + /// Cache instance. + /// The navigation service. + /// Variation context accessor. + /// + /// + /// The specific culture to filter for. If null is used the current culture is used. (Default is + /// null) + /// + /// The siblings of the content including the node itself. + public static IEnumerable? SiblingsAndSelf( + this IPublishedContent content, + IPublishedCache publishedCache, + INavigationQueryService navigationQueryService, + IVariationContextAccessor variationContextAccessor, + IPublishStatusQueryService publishStatusQueryService, + string? culture = null) + { + var success = navigationQueryService.TryGetParentKey(content.Key, out Guid? parentKey); + + if (success is false || parentKey is null) + { + if (navigationQueryService.TryGetRootKeys(out IEnumerable childrenKeys) is false) + { + return null; + } + + culture ??= variationContextAccessor.VariationContext?.Culture ?? string.Empty; + return childrenKeys + .Where(x => publishStatusQueryService.IsDocumentPublished(x , culture)) + .Select(publishedCache.GetById) + .WhereNotNull() + .WhereIsInvariantOrHasCulture(variationContextAccessor, culture); + } + + return navigationQueryService.TryGetChildrenKeys(parentKey.Value, out IEnumerable siblingKeys) is false + ? null + : siblingKeys.Select(publishedCache.GetById).WhereNotNull(); + } /// /// Gets the siblings of the content including the node itself to indicate the position. @@ -2841,31 +2985,66 @@ public static class PublishedContentExtensions /// null) /// /// The siblings of the content including the node itself. + [Obsolete("Use the overload with IPublishStatusQueryService, scheduled for removal in v17")] public static IEnumerable? SiblingsAndSelf( this IPublishedContent content, IPublishedCache publishedCache, INavigationQueryService navigationQueryService, IVariationContextAccessor variationContextAccessor, + string? culture = null) => + SiblingsAndSelf( + content, + publishedCache, + navigationQueryService, + variationContextAccessor, + StaticServiceProvider.Instance.GetRequiredService(), + culture); + + /// + /// Gets the siblings of the content including the node itself to indicate the position, of a given content type. + /// + /// The content. + /// Variation context accessor. + /// + /// The specific culture to filter for. If null is used the current culture is used. (Default is + /// null) + /// + /// + /// + /// The content type alias. + /// + /// The siblings of the content including the node itself, of the given content type. + public static IEnumerable SiblingsAndSelfOfType( + this IPublishedContent content, + IVariationContextAccessor variationContextAccessor, + IPublishedCache publishedCache, + INavigationQueryService navigationQueryService, + IPublishStatusQueryService publishStatusQueryService, + string contentTypeAlias, string? culture = null) { - var success = navigationQueryService.TryGetParentKey(content.Key, out Guid? parentKey); + var parentExists = navigationQueryService.TryGetParentKey(content.Key, out Guid? parentKey); - if (success is false || parentKey is null) + IPublishedContent? parent = parentKey is null + ? null + : publishedCache.GetById(parentKey.Value); + + if (parentExists && parent is not null) { - if (navigationQueryService.TryGetRootKeys(out IEnumerable childrenKeys) is false) - { - return null; - } - - return childrenKeys - .Select(publishedCache.GetById) - .WhereNotNull() - .WhereIsInvariantOrHasCulture(variationContextAccessor, culture); + return parent.ChildrenOfType(variationContextAccessor, publishedCache, navigationQueryService, publishStatusQueryService, contentTypeAlias, culture); } - return navigationQueryService.TryGetChildrenKeys(parentKey.Value, out IEnumerable siblingKeys) is false - ? null - : siblingKeys.Select(publishedCache.GetById).WhereNotNull(); + if (navigationQueryService.TryGetRootKeysOfType(contentTypeAlias, out IEnumerable rootKeysOfType) is false) + { + return []; + } + + culture ??= variationContextAccessor.VariationContext?.Culture ?? string.Empty; + return rootKeysOfType + .Where(x => publishStatusQueryService.IsDocumentPublished(x, culture)) + .Select(publishedCache.GetById) + .WhereNotNull() + .WhereIsInvariantOrHasCulture(variationContextAccessor, culture); } /// @@ -2881,35 +3060,22 @@ public static class PublishedContentExtensions /// The content type alias. /// /// The siblings of the content including the node itself, of the given content type. + [Obsolete("Use the overload with IPublishStatusQueryService, scheduled for removal in v17")] public static IEnumerable SiblingsAndSelfOfType( this IPublishedContent content, IVariationContextAccessor variationContextAccessor, IPublishedCache publishedCache, INavigationQueryService navigationQueryService, string contentTypeAlias, - string? culture = null) - { - var parentExists = navigationQueryService.TryGetParentKey(content.Key, out Guid? parentKey); - - IPublishedContent? parent = parentKey is null - ? null - : publishedCache.GetById(parentKey.Value); - - if (parentExists && parent is not null) - { - return parent.ChildrenOfType(variationContextAccessor, publishedCache, navigationQueryService, contentTypeAlias, culture); - } - - if (navigationQueryService.TryGetRootKeysOfType(contentTypeAlias, out IEnumerable rootKeysOfType) is false) - { - return []; - } - - return rootKeysOfType - .Select(publishedCache.GetById) - .WhereNotNull() - .WhereIsInvariantOrHasCulture(variationContextAccessor, culture); - } + string? culture = null) => + SiblingsAndSelfOfType( + content, + variationContextAccessor, + publishedCache, + navigationQueryService, + StaticServiceProvider.Instance.GetRequiredService(), + contentTypeAlias, + culture); /// /// Gets the siblings of the content including the node itself to indicate the position, of a given content type. @@ -2945,7 +3111,9 @@ public static class PublishedContentExtensions return []; } + culture ??= variationContextAccessor.VariationContext?.Culture ?? string.Empty; return rootKeys + .Where(x => publishStatusQueryService.IsDocumentPublished(x, culture)) .Select(publishedCache.GetById) .WhereNotNull() .WhereIsInvariantOrHasCulture(variationContextAccessor, culture) @@ -2975,14 +3143,13 @@ public static class PublishedContentExtensions IPublishedCache publishedCache, INavigationQueryService navigationQueryService, string? culture = null) - where T : class, IPublishedContent => - SiblingsAndSelf( - content, - variationContextAccessor, - publishedCache, - navigationQueryService, - StaticServiceProvider.Instance.GetRequiredService(), - culture); + where T : class, IPublishedContent => SiblingsAndSelf( + content, + variationContextAccessor, + publishedCache, + navigationQueryService, + StaticServiceProvider.Instance.GetRequiredService(), + culture); #endregion @@ -4147,9 +4314,27 @@ public static class PublishedContentExtensions public static IEnumerable SiblingsAndSelf( this IPublishedContent content, IVariationContextAccessor variationContextAccessor, + IPublishStatusQueryService publishStatusQueryService, string? culture = null) - where T : class, IPublishedContent => SiblingsAndSelf(content, variationContextAccessor, GetPublishedCache(content), - GetNavigationQueryService(content), culture); + where T : class, IPublishedContent => + SiblingsAndSelf( + content, + variationContextAccessor, + GetPublishedCache(content), + GetNavigationQueryService(content), + publishStatusQueryService, + culture); + + [Obsolete("Use the overload with IPublishStatusQueryService, scheduled for removal in v17")] + public static IEnumerable SiblingsAndSelf( + this IPublishedContent content, + IVariationContextAccessor variationContextAccessor, + string? culture = null) + where T : class, IPublishedContent => SiblingsAndSelf( + content, + variationContextAccessor, + StaticServiceProvider.Instance.GetRequiredService(), + culture); private static INavigationQueryService GetNavigationQueryService(IPublishedContent content) diff --git a/src/Umbraco.Web.Common/Extensions/FriendlyPublishedContentExtensions.cs b/src/Umbraco.Web.Common/Extensions/FriendlyPublishedContentExtensions.cs index 94294f1330..d2bb93ac5d 100644 --- a/src/Umbraco.Web.Common/Extensions/FriendlyPublishedContentExtensions.cs +++ b/src/Umbraco.Web.Common/Extensions/FriendlyPublishedContentExtensions.cs @@ -558,7 +558,7 @@ public static class FriendlyPublishedContentExtensions /// Note that in V7 this method also return the content node self. /// public static IEnumerable? Siblings(this IPublishedContent content, string? culture = null) - => content.Siblings(GetPublishedCache(content), GetNavigationQueryService(content), VariationContextAccessor, culture); + => content.Siblings(GetPublishedCache(content), GetNavigationQueryService(content), VariationContextAccessor, PublishStatusQueryService, culture); /// /// Gets the siblings of the content, of a given content type. @@ -574,7 +574,7 @@ public static class FriendlyPublishedContentExtensions /// 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, GetPublishedCache(content), GetNavigationQueryService(content), contentTypeAlias, culture); + => content.SiblingsOfType(VariationContextAccessor, GetPublishedCache(content), GetNavigationQueryService(content), PublishStatusQueryService, contentTypeAlias, culture); /// /// Gets the siblings of the content, of a given content type. @@ -591,7 +591,7 @@ public static class FriendlyPublishedContentExtensions /// public static IEnumerable? Siblings(this IPublishedContent content, string? culture = null) where T : class, IPublishedContent - => content.Siblings(VariationContextAccessor, GetPublishedCache(content), GetNavigationQueryService(content), culture); + => content.Siblings(VariationContextAccessor, GetPublishedCache(content), GetNavigationQueryService(content), PublishStatusQueryService, culture); /// /// Gets the siblings of the content including the node itself to indicate the position. @@ -605,7 +605,7 @@ public static class FriendlyPublishedContentExtensions public static IEnumerable? SiblingsAndSelf( this IPublishedContent content, string? culture = null) - => content.SiblingsAndSelf(GetPublishedCache(content), GetNavigationQueryService(content), VariationContextAccessor, culture); + => content.SiblingsAndSelf(GetPublishedCache(content), GetNavigationQueryService(content), VariationContextAccessor, PublishStatusQueryService, culture); /// /// Gets the siblings of the content including the node itself to indicate the position, of a given content type. @@ -621,7 +621,7 @@ public static class FriendlyPublishedContentExtensions this IPublishedContent content, string contentTypeAlias, string? culture = null) - => content.SiblingsAndSelfOfType(VariationContextAccessor, GetPublishedCache(content), GetNavigationQueryService(content), contentTypeAlias, culture); + => content.SiblingsAndSelfOfType(VariationContextAccessor, GetPublishedCache(content), GetNavigationQueryService(content), PublishStatusQueryService, contentTypeAlias, culture); /// /// Gets the siblings of the content including the node itself to indicate the position, of a given content type. @@ -635,7 +635,7 @@ public static class FriendlyPublishedContentExtensions /// 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, GetPublishedCache(content), GetNavigationQueryService(content), culture); + => content.SiblingsAndSelf(VariationContextAccessor, GetPublishedCache(content), GetNavigationQueryService(content), PublishStatusQueryService, culture); /// /// Gets the url of the content item.