1+ using Microsoft . Extensions . Logging ;
2+ using Umbraco . Cms . Api . Management . Routing ;
13using Umbraco . Cms . Api . Management . ViewModels . Document ;
24using Umbraco . Cms . Core . Models ;
5+ using Umbraco . Cms . Core . Models . Membership ;
36using Umbraco . Cms . Core . Routing ;
7+ using Umbraco . Cms . Core . Security ;
8+ using Umbraco . Cms . Core . Services ;
9+ using Umbraco . Extensions ;
410
511namespace Umbraco . Cms . Api . Management . Factories ;
612
713public class DocumentUrlFactory : IDocumentUrlFactory
814{
915 private readonly IPublishedUrlInfoProvider _publishedUrlInfoProvider ;
1016 private readonly UrlProviderCollection _urlProviders ;
17+ private readonly IPreviewService _previewService ;
18+ private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor ;
19+ private readonly IAbsoluteUrlBuilder _absoluteUrlBuilder ;
20+ private readonly ILogger < DocumentUrlFactory > _logger ;
1121
12- public DocumentUrlFactory ( IPublishedUrlInfoProvider publishedUrlInfoProvider , UrlProviderCollection urlProviders )
22+ public DocumentUrlFactory (
23+ IPublishedUrlInfoProvider publishedUrlInfoProvider ,
24+ UrlProviderCollection urlProviders ,
25+ IPreviewService previewService ,
26+ IBackOfficeSecurityAccessor backOfficeSecurityAccessor ,
27+ IAbsoluteUrlBuilder absoluteUrlBuilder ,
28+ ILogger < DocumentUrlFactory > logger )
1329 {
1430 _publishedUrlInfoProvider = publishedUrlInfoProvider ;
1531 _urlProviders = urlProviders ;
32+ _previewService = previewService ;
33+ _backOfficeSecurityAccessor = backOfficeSecurityAccessor ;
34+ _absoluteUrlBuilder = absoluteUrlBuilder ;
35+ _logger = logger ;
1636 }
1737
1838 public async Task < IEnumerable < DocumentUrlInfo > > CreateUrlsAsync ( IContent content )
1939 {
2040 ISet < UrlInfo > urlInfos = await _publishedUrlInfoProvider . GetAllAsync ( content ) ;
21- return CreateDocumentUrlInfos ( urlInfos ) ;
41+ return urlInfos
42+ . Select ( urlInfo => CreateDocumentUrlInfo ( urlInfo , false ) )
43+ . ToArray ( ) ;
2244 }
2345
2446 public async Task < IEnumerable < DocumentUrlInfoResponseModel > > CreateUrlSetsAsync ( IEnumerable < IContent > contentItems )
@@ -34,28 +56,53 @@ public async Task<IEnumerable<DocumentUrlInfoResponseModel>> CreateUrlSetsAsync(
3456 return documentUrlInfoResourceSets ;
3557 }
3658
37- public Task < IEnumerable < DocumentUrlInfoResponseModel > > CreatePreviewUrlSetsAsync ( IEnumerable < IContent > contentItems )
59+ public async Task < DocumentUrlInfo ? > GetPreviewUrlAsync ( IContent content , string providerAlias , string ? culture , string ? segment )
3860 {
39- DocumentUrlInfoResponseModel [ ] documentUrlInfoResourceSets = contentItems . Select ( content =>
61+ IUrlProvider ? provider = _urlProviders . FirstOrDefault ( provider => provider . Alias . InvariantEquals ( providerAlias ) ) ;
62+ if ( provider is null )
63+ {
64+ _logger . LogError ( "Could not resolve the URL provider requested for preview: {providerAlias}" , providerAlias ) ;
65+ return null ;
66+ }
67+
68+ UrlInfo ? previewUrlInfo = await provider . GetPreviewUrlAsync ( content , culture , segment ) ;
69+ if ( previewUrlInfo is null )
70+ {
71+ _logger . LogError ( "The URL provider: {providerAlias} could not generate a preview URL for content with key: {contentKey}" , providerAlias , content . Key ) ;
72+ return null ;
73+ }
74+
75+ // must initiate preview state for internal preview URLs
76+ if ( previewUrlInfo . Url is not null && previewUrlInfo . IsExternal is false )
77+ {
78+ IUser ? currentUser = _backOfficeSecurityAccessor . BackOfficeSecurity ? . CurrentUser ;
79+ if ( currentUser is null )
4080 {
41- IEnumerable < UrlInfo > previewUrls = _urlProviders . SelectMany ( provider => provider . GetPreviewUrls ( content ) ) ;
42- return new DocumentUrlInfoResponseModel ( content . Key , CreateDocumentUrlInfos ( previewUrls ) ) ;
43- } )
44- . ToArray ( ) ;
81+ _logger . LogError ( "Could not access the current backoffice user while attempting to authenticate for preview." ) ;
82+ return null ;
83+ }
4584
46- return Task . FromResult < IEnumerable < DocumentUrlInfoResponseModel > > ( documentUrlInfoResourceSets ) ;
85+ if ( await _previewService . TryEnterPreviewAsync ( currentUser ) is false )
86+ {
87+ _logger . LogError ( "A server error occured, could not initiate an authenticated preview state for the current user." ) ;
88+ return null ;
89+ }
90+ }
91+
92+ return CreateDocumentUrlInfo ( previewUrlInfo , previewUrlInfo . IsExternal is false ) ;
4793 }
4894
49- private IEnumerable < DocumentUrlInfo > CreateDocumentUrlInfos ( IEnumerable < UrlInfo > urlInfos )
50- => urlInfos
51- . Where ( urlInfo => urlInfo . Url is not null )
52- . Select ( urlInfo => new DocumentUrlInfo
53- {
54- Culture = urlInfo . Culture ,
55- Url = urlInfo . Url ! . ToString ( ) ,
56- Message = urlInfo . Message ,
57- IsExternal = urlInfo . IsExternal ,
58- Provider = urlInfo . Provider ,
59- } )
60- . ToArray ( ) ;
95+ private DocumentUrlInfo CreateDocumentUrlInfo ( UrlInfo urlInfo , bool ensureAbsoluteUrl )
96+ {
97+ var url = urlInfo . Url ? . ToString ( ) ;
98+ return new DocumentUrlInfo
99+ {
100+ Culture = urlInfo . Culture ,
101+ Url = ensureAbsoluteUrl && url is not null
102+ ? _absoluteUrlBuilder . ToAbsoluteUrl ( url ) . ToString ( )
103+ : url ,
104+ Message = urlInfo . Message ,
105+ Provider = urlInfo . Provider ,
106+ } ;
107+ }
61108}
0 commit comments