Merge remote-tracking branch 'origin/release/15.0' into v15/dev

# Conflicts:
#	src/Umbraco.PublishedCache.HybridCache/Services/MediaCacheService.cs
#	src/Umbraco.Web.UI.Client
#	tests/Umbraco.Tests.Common/Builders/MediaTypeEditingBuilder.cs
This commit is contained in:
Bjarke Berg
2024-10-10 11:11:08 +02:00
35 changed files with 833 additions and 126 deletions

View File

@@ -14,6 +14,7 @@ public sealed class ContentTypeCacheRefresher : PayloadCacheRefresherBase<Conten
{
private readonly IContentTypeCommonRepository _contentTypeCommonRepository;
private readonly IPublishedModelFactory _publishedModelFactory;
private readonly IPublishedContentTypeFactory _publishedContentTypeFactory;
private readonly IIdKeyMap _idKeyMap;
public ContentTypeCacheRefresher(
@@ -23,12 +24,14 @@ public sealed class ContentTypeCacheRefresher : PayloadCacheRefresherBase<Conten
IContentTypeCommonRepository contentTypeCommonRepository,
IEventAggregator eventAggregator,
ICacheRefresherNotificationFactory factory,
IPublishedModelFactory publishedModelFactory)
IPublishedModelFactory publishedModelFactory,
IPublishedContentTypeFactory publishedContentTypeFactory)
: base(appCaches, serializer, eventAggregator, factory)
{
_idKeyMap = idKeyMap;
_contentTypeCommonRepository = contentTypeCommonRepository;
_publishedModelFactory = publishedModelFactory;
_publishedContentTypeFactory = publishedContentTypeFactory;
}
#region Json
@@ -114,6 +117,8 @@ public sealed class ContentTypeCacheRefresher : PayloadCacheRefresherBase<Conten
// TODO: We need to clear the HybridCache of any content using the ContentType, but NOT the database cache here, and this should be done within the "WithSafeLiveFactoryReset" to ensure that the factory is locked in the meantime.
_publishedModelFactory.WithSafeLiveFactoryReset(() => { });
_publishedContentTypeFactory.NotifyDataTypeChanges();
// now we can trigger the event
base.Refresh(payloads);
}

View File

@@ -13,6 +13,7 @@ public sealed class DataTypeCacheRefresher : PayloadCacheRefresherBase<DataTypeC
{
private readonly IIdKeyMap _idKeyMap;
private readonly IPublishedModelFactory _publishedModelFactory;
private readonly IPublishedContentTypeFactory _publishedContentTypeFactory;
public DataTypeCacheRefresher(
AppCaches appCaches,
@@ -20,11 +21,13 @@ public sealed class DataTypeCacheRefresher : PayloadCacheRefresherBase<DataTypeC
IIdKeyMap idKeyMap,
IEventAggregator eventAggregator,
ICacheRefresherNotificationFactory factory,
IPublishedModelFactory publishedModelFactory)
IPublishedModelFactory publishedModelFactory,
IPublishedContentTypeFactory publishedContentTypeFactory)
: base(appCaches, serializer, eventAggregator, factory)
{
_idKeyMap = idKeyMap;
_publishedModelFactory = publishedModelFactory;
_publishedContentTypeFactory = publishedContentTypeFactory;
}
#region Json
@@ -86,6 +89,9 @@ public sealed class DataTypeCacheRefresher : PayloadCacheRefresherBase<DataTypeC
// TODO: We need to clear the HybridCache of any content using the ContentType, but NOT the database cache here, and this should be done within the "WithSafeLiveFactoryReset" to ensure that the factory is locked in the meantime.
_publishedModelFactory.WithSafeLiveFactoryReset(() => { });
var changedIds = payloads.Select(x => x.Id).ToArray();
_publishedContentTypeFactory.NotifyDataTypeChanges(changedIds);
base.Refresh(payloads);
}

View File

@@ -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;
@@ -1909,5 +1911,491 @@ public static class PublishedContentExtensions
private static Dictionary<string, string> GetAliasesAndNames(IContentTypeBase? contentType) =>
contentType?.PropertyTypes.ToDictionary(x => x.Alias, x => x.Name) ?? new Dictionary<string, string>();
#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<T>(this IPublishedContent content, int maxLevel)
where T : class, IPublishedContent
{
return Ancestor<T>(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<IPublishedContent> 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<IPublishedContent> 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<T> Ancestors<T>(this IPublishedContent content)
where T : class, IPublishedContent
{
return Ancestors<T>(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<T> Ancestors<T>(this IPublishedContent content, int maxLevel)
where T : class, IPublishedContent
{
return Ancestors<T>(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<T>(this IPublishedContent content, int maxLevel)
where T : class, IPublishedContent
{
return AncestorOrSelf<T>(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<IPublishedContent> 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<IPublishedContent> 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<T> AncestorsOrSelf<T>(this IPublishedContent content, int maxLevel)
where T : class, IPublishedContent
{
return AncestorsOrSelf<T>(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<IPublishedContent> AncestorsOrSelf(this IPublishedContent content, bool orSelf,
Func<IPublishedContent, bool>? 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<IPublishedContent> 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<IPublishedContent> 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<IPublishedContent> Breadcrumbs<T>(
this IPublishedContent content,
bool andSelf = true)
where T : class, IPublishedContent=>
content.Breadcrumbs<T>(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<IPublishedContent> 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<IPublishedContent> Children(
this IPublishedContent content,
IVariationContextAccessor variationContextAccessor,
Func<IPublishedContent, bool> 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<IPublishedContent> 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<T> Children<T>(
this IPublishedContent content,
IVariationContextAccessor variationContextAccessor,
string? culture = null)
where T : class, IPublishedContent =>
content.Children(variationContextAccessor, GetPublishedCache(content),
GetNavigationQueryService(content), culture).OfType<T>();
[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<IPublishedContent> DescendantsOrSelfOfType(
this IEnumerable<IPublishedContent> 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<T> DescendantsOrSelf<T>(
this IEnumerable<IPublishedContent> parentNodes,
IVariationContextAccessor variationContextAccessor,
string? culture = null)
where T : class, IPublishedContent =>
parentNodes.SelectMany(x => x.DescendantsOrSelf<T>(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<IPublishedContent> 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<IPublishedContent> 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<IPublishedContent> 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<T> Descendants<T>(
this IPublishedContent content,
IVariationContextAccessor variationContextAccessor,
string? culture = null)
where T : class, IPublishedContent =>
content.Descendants(variationContextAccessor, GetPublishedCache(content),
GetNavigationQueryService(content), culture).OfType<T>();
[Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")]
public static IEnumerable<T> Descendants<T>(
this IPublishedContent content,
IVariationContextAccessor variationContextAccessor,
int level,
string? culture = null)
where T : class, IPublishedContent =>
content.Descendants(variationContextAccessor, GetPublishedCache(content),
GetNavigationQueryService(content), level, culture).OfType<T>();
[Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")]
public static IEnumerable<IPublishedContent> 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<IPublishedContent> 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<IPublishedContent> 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<T> DescendantsOrSelf<T>(
this IPublishedContent content,
IVariationContextAccessor variationContextAccessor,
string? culture = null)
where T : class, IPublishedContent =>
content.DescendantsOrSelf(variationContextAccessor, GetPublishedCache(content),
GetNavigationQueryService(content), culture).OfType<T>();
[Obsolete("Please use IPublishedCache and IDocumentNavigationQueryService or IMediaNavigationQueryService directly. This will be removed in a future version of Umbraco")]
public static IEnumerable<T> DescendantsOrSelf<T>(
this IPublishedContent content,
IVariationContextAccessor variationContextAccessor,
int level,
string? culture = null)
where T : class, IPublishedContent =>
content.DescendantsOrSelf(variationContextAccessor, GetPublishedCache(content),
GetNavigationQueryService(content), level, culture).OfType<T>();
[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<T>(
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<T>(
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<T>(
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<T>(
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<IPublishedContent, bool> 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<T>(
this IPublishedContent content,
IVariationContextAccessor variationContextAccessor,
string? culture = null)
where T : class, IPublishedContent =>
content.Children<T>(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<T>(
this IPublishedContent content,
IVariationContextAccessor variationContextAccessor,
Func<T, bool> predicate,
string? culture = null)
where T : class, IPublishedContent =>
content.Children<T>(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<IPublishedContent> 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<IPublishedContent> 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<T> Siblings<T>(
this IPublishedContent content,
IVariationContextAccessor variationContextAccessor,
string? culture = null)
where T : class, IPublishedContent =>
Siblings<T>(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<IPublishedContent>? 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<IPublishedContent> 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<T> SiblingsAndSelf<T>(
this IPublishedContent content,
IVariationContextAccessor variationContextAccessor,
string? culture = null)
where T : class, IPublishedContent => SiblingsAndSelf<T>(content, variationContextAccessor, GetPublishedCache(content),
GetNavigationQueryService(content), culture);
private static INavigationQueryService GetNavigationQueryService(IPublishedContent content)
{
switch (content.ContentType.ItemType)
{
case PublishedItemType.Content:
return StaticServiceProvider.Instance.GetRequiredService<IDocumentNavigationQueryService>();
case PublishedItemType.Media:
return StaticServiceProvider.Instance.GetRequiredService<IMediaNavigationQueryService>();
default:
throw new NotSupportedException("Unsupported content type.");
}
}
private static IPublishedCache GetPublishedCache(IPublishedContent content)
{
switch (content.ContentType.ItemType)
{
case PublishedItemType.Content:
return StaticServiceProvider.Instance.GetRequiredService<IPublishedContentCache>();
case PublishedItemType.Media:
return StaticServiceProvider.Instance.GetRequiredService<IPublishedMediaCache>();
default:
throw new NotSupportedException("Unsupported content type.");
}
}
}

View File

@@ -11,7 +11,7 @@ public interface IPublishedContentCache : IPublishedCache
/// <param name="preview">A value indicating whether to consider unpublished content.</param>
/// <returns>The content, or null.</returns>
/// <remarks>Considers published or unpublished content depending on defaults.</remarks>
Task<IPublishedContent?> GetByIdAsync(int id, bool preview = false);
Task<IPublishedContent?> GetByIdAsync(int id, bool? preview = null);
/// <summary>
/// Gets a content identified by its unique identifier.
@@ -20,7 +20,7 @@ public interface IPublishedContentCache : IPublishedCache
/// <param name="preview">A value indicating whether to consider unpublished content.</param>
/// <returns>The content, or null.</returns>
/// <remarks>Considers published or unpublished content depending on defaults.</remarks>
Task<IPublishedContent?> GetByIdAsync(Guid key, bool preview = false);
Task<IPublishedContent?> GetByIdAsync(Guid key, bool? preview = null);
// FIXME: All these routing methods needs to be removed, as they are no longer part of the content cache
/// <summary>

View File

@@ -50,6 +50,22 @@ internal abstract class EntityTypeContainerService<TTreeEntity, TEntityContainer
return await Task.FromResult(_entityContainerRepository.Get(id));
}
/// <inheritdoc />
public async Task<IEnumerable<EntityContainer>> GetAsync(string name, int level)
{
using ICoreScope scope = ScopeProvider.CreateCoreScope(autoComplete: true);
ReadLock(scope);
return await Task.FromResult(_entityContainerRepository.Get(name, level));
}
/// <inheritdoc />
public async Task<IEnumerable<EntityContainer>> GetAllAsync()
{
using ICoreScope scope = ScopeProvider.CreateCoreScope(autoComplete: true);
ReadLock(scope);
return await Task.FromResult(_entityContainerRepository.GetMany());
}
/// <inheritdoc />
public async Task<EntityContainer?> GetParentAsync(EntityContainer container)
=> await Task.FromResult(GetParent(container));

View File

@@ -14,6 +14,20 @@ public interface IEntityTypeContainerService<TTreeEntity>
/// <returns></returns>
Task<EntityContainer?> GetAsync(Guid id);
/// <summary>
/// Gets containers by name and level
/// </summary>
/// <param name="name">The name of the containers to get.</param>
/// <param name="level">The level in the tree of the containers to get.</param>
/// <returns></returns>
Task<IEnumerable<EntityContainer>> GetAsync(string name, int level);
/// <summary>
/// Gets all containers
/// </summary>
/// <returns></returns>
Task<IEnumerable<EntityContainer>> GetAllAsync();
/// <summary>
/// Gets the parent container of a container
/// </summary>

View File

@@ -15,5 +15,7 @@ public interface IPreviewService
/// </summary>
Task EndPreviewAsync();
bool IsInPreview();
Task<Attempt<ClaimsIdentity>> TryGetPreviewClaimsIdentityAsync();
}

View File

@@ -1,5 +1,6 @@
using System.Security.Claims;
using Microsoft.Extensions.DependencyInjection;
using Umbraco.Cms.Core.Cache;
using Umbraco.Cms.Core.Models.Membership;
using Umbraco.Cms.Core.Preview;
using Umbraco.Cms.Core.Security;
@@ -13,15 +14,18 @@ public class PreviewService : IPreviewService
private readonly ICookieManager _cookieManager;
private readonly IPreviewTokenGenerator _previewTokenGenerator;
private readonly IServiceScopeFactory _serviceScopeFactory;
private readonly IRequestCache _requestCache;
public PreviewService(
ICookieManager cookieManager,
IPreviewTokenGenerator previewTokenGenerator,
IServiceScopeFactory serviceScopeFactory)
IServiceScopeFactory serviceScopeFactory,
IRequestCache requestCache)
{
_cookieManager = cookieManager;
_previewTokenGenerator = previewTokenGenerator;
_serviceScopeFactory = serviceScopeFactory;
_requestCache = requestCache;
}
public async Task<bool> TryEnterPreviewAsync(IUser user)
@@ -42,6 +46,11 @@ public class PreviewService : IPreviewService
return Task.CompletedTask;
}
public bool IsInPreview() =>
_requestCache.Get(
"IsInPreview",
() => TryGetPreviewClaimsIdentityAsync().GetAwaiter().GetResult().Success) as bool? ?? false;
public async Task<Attempt<ClaimsIdentity>> TryGetPreviewClaimsIdentityAsync()
{
var cookieValue = _cookieManager.GetCookieValue(Constants.Web.PreviewCookieName);