V15: Fix previews (#17181)

* default to preview value from cookie instead of draft.

* Fix tests

---------

Co-authored-by: Zeegaan <skrivdetud@gmail.com>
This commit is contained in:
Bjarke Berg
2024-10-03 15:35:17 +02:00
committed by GitHub
parent 04d71fa354
commit 537a657de3
7 changed files with 43 additions and 19 deletions

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

@@ -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);

View File

@@ -21,19 +21,19 @@ public sealed class DocumentCache : IPublishedContentCache
_publishedContentTypeCache = publishedContentTypeCache;
}
public async Task<IPublishedContent?> GetByIdAsync(int id, bool preview = false) => await _documentCacheService.GetByIdAsync(id, preview);
public async Task<IPublishedContent?> GetByIdAsync(int id, bool? preview = null) => await _documentCacheService.GetByIdAsync(id, preview);
public async Task<IPublishedContent?> GetByIdAsync(Guid key, bool preview = false) => await _documentCacheService.GetByKeyAsync(key, preview);
public async Task<IPublishedContent?> GetByIdAsync(Guid key, bool? preview = null) => await _documentCacheService.GetByKeyAsync(key, preview);
public IPublishedContent? GetById(bool preview, int contentId) => GetByIdAsync(contentId, preview).GetAwaiter().GetResult();
public IPublishedContent? GetById(bool preview, Guid contentId) => GetByIdAsync(contentId, preview).GetAwaiter().GetResult();
public IPublishedContent? GetById(int contentId) => GetByIdAsync(contentId, false).GetAwaiter().GetResult();
public IPublishedContent? GetById(int contentId) => GetByIdAsync(contentId).GetAwaiter().GetResult();
public IPublishedContent? GetById(Guid contentId) => GetByIdAsync(contentId, false).GetAwaiter().GetResult();
public IPublishedContent? GetById(Guid contentId) => GetByIdAsync(contentId).GetAwaiter().GetResult();
public IPublishedContentType? GetContentType(int id) => _publishedContentTypeCache.Get(PublishedItemType.Content, id);

View File

@@ -22,6 +22,7 @@ internal sealed class DocumentCacheService : IDocumentCacheService
private readonly ICacheNodeFactory _cacheNodeFactory;
private readonly IEnumerable<IDocumentSeedKeyProvider> _seedKeyProviders;
private readonly IPublishedModelFactory _publishedModelFactory;
private readonly IPreviewService _previewService;
private readonly CacheSettings _cacheSettings;
private HashSet<Guid>? _seedKeys;
@@ -54,7 +55,8 @@ internal sealed class DocumentCacheService : IDocumentCacheService
ICacheNodeFactory cacheNodeFactory,
IEnumerable<IDocumentSeedKeyProvider> seedKeyProviders,
IOptions<CacheSettings> cacheSettings,
IPublishedModelFactory publishedModelFactory)
IPublishedModelFactory publishedModelFactory,
IPreviewService previewService)
{
_databaseCacheRepository = databaseCacheRepository;
_idKeyMap = idKeyMap;
@@ -64,22 +66,30 @@ internal sealed class DocumentCacheService : IDocumentCacheService
_cacheNodeFactory = cacheNodeFactory;
_seedKeyProviders = seedKeyProviders;
_publishedModelFactory = publishedModelFactory;
_previewService = previewService;
_cacheSettings = cacheSettings.Value;
}
public async Task<IPublishedContent?> GetByKeyAsync(Guid key, bool preview = false)
public async Task<IPublishedContent?> GetByKeyAsync(Guid key, bool? preview = null)
{
using ICoreScope scope = _scopeProvider.CreateCoreScope();
bool calculatedPreview = preview ?? GetPreview();
ContentCacheNode? contentCacheNode = await _hybridCache.GetOrCreateAsync(
GetCacheKey(key, preview), // Unique key to the cache entry
async cancel => await _databaseCacheRepository.GetContentSourceAsync(key, preview));
GetCacheKey(key, calculatedPreview), // Unique key to the cache entry
async cancel => await _databaseCacheRepository.GetContentSourceAsync(key, calculatedPreview));
scope.Complete();
return contentCacheNode is null ? null : _publishedContentFactory.ToIPublishedContent(contentCacheNode, preview).CreateModel(_publishedModelFactory);
return contentCacheNode is null ? null : _publishedContentFactory.ToIPublishedContent(contentCacheNode, calculatedPreview).CreateModel(_publishedModelFactory);
}
public async Task<IPublishedContent?> GetByIdAsync(int id, bool preview = false)
private bool GetPreview()
{
return _previewService.IsInPreview();
}
public async Task<IPublishedContent?> GetByIdAsync(int id, bool? preview = null)
{
Attempt<Guid> keyAttempt = _idKeyMap.GetKeyForId(id, UmbracoObjectTypes.Document);
if (keyAttempt.Success is false)
@@ -87,12 +97,14 @@ internal sealed class DocumentCacheService : IDocumentCacheService
return null;
}
bool calculatedPreview = preview ?? GetPreview();
using ICoreScope scope = _scopeProvider.CreateCoreScope();
ContentCacheNode? contentCacheNode = await _hybridCache.GetOrCreateAsync(
GetCacheKey(keyAttempt.Result, preview), // Unique key to the cache entry
async cancel => await _databaseCacheRepository.GetContentSourceAsync(id, preview));
GetCacheKey(keyAttempt.Result, calculatedPreview), // Unique key to the cache entry
async cancel => await _databaseCacheRepository.GetContentSourceAsync(id, calculatedPreview));
scope.Complete();
return contentCacheNode is null ? null : _publishedContentFactory.ToIPublishedContent(contentCacheNode, preview).CreateModel(_publishedModelFactory);;
return contentCacheNode is null ? null : _publishedContentFactory.ToIPublishedContent(contentCacheNode, calculatedPreview).CreateModel(_publishedModelFactory);;
}
public IEnumerable<IPublishedContent> GetByContentType(IPublishedContentType contentType)

View File

@@ -5,9 +5,9 @@ namespace Umbraco.Cms.Infrastructure.HybridCache.Services;
public interface IDocumentCacheService
{
Task<IPublishedContent?> GetByKeyAsync(Guid key, bool preview = false);
Task<IPublishedContent?> GetByKeyAsync(Guid key, bool? preview = null);
Task<IPublishedContent?> GetByIdAsync(int id, bool preview = false);
Task<IPublishedContent?> GetByIdAsync(int id, bool? preview = null);
Task SeedAsync(CancellationToken cancellationToken);

View File

@@ -104,7 +104,8 @@ public class DocumentHybridCacheMockTests : UmbracoIntegrationTestWithContent
GetRequiredService<ICacheNodeFactory>(),
GetSeedProviders(),
Options.Create(new CacheSettings()),
GetRequiredService<IPublishedModelFactory>());
GetRequiredService<IPublishedModelFactory>(),
GetRequiredService<IPreviewService>());
_mockedCache = new DocumentCache(_mockDocumentCacheService, GetRequiredService<IPublishedContentTypeCache>());
}