# Conflicts: # build/NuSpecs/UmbracoCms.Web.nuspec # src/SolutionInfo.cs # src/Umbraco.Core/Cache/MediaCacheRefresher.cs # src/Umbraco.Core/Composing/ComponentCollection.cs # src/Umbraco.Core/Composing/Composers.cs # src/Umbraco.Core/Composing/TypeFinder.cs # src/Umbraco.Core/Composing/TypeLoader.cs # src/Umbraco.Core/Configuration/Grid/GridEditorsConfig.cs # src/Umbraco.Core/Constants-SvgSanitizer.cs # src/Umbraco.Core/ContentApps/ContentAppFactoryCollection.cs # src/Umbraco.Core/Extensions/PublishedContentExtensions.cs # src/Umbraco.Core/Extensions/PublishedPropertyExtension.cs # src/Umbraco.Core/Extensions/StringExtensions.cs # src/Umbraco.Core/HealthChecks/Checks/Security/ExcessiveHeadersCheck.cs # src/Umbraco.Core/HealthChecks/HealthCheckResults.cs # src/Umbraco.Core/IO/FileSystems.cs # src/Umbraco.Core/IO/IOHelper.cs # src/Umbraco.Core/IO/MediaFileSystem.cs # src/Umbraco.Core/IO/PhysicalFileSystem.cs # src/Umbraco.Core/Logging/DebugDiagnosticsLogger.cs # src/Umbraco.Core/Logging/DisposableTimer.cs # src/Umbraco.Core/Logging/ILogger.cs # src/Umbraco.Core/Logging/LogProfiler.cs # src/Umbraco.Core/Logging/OwinLogger.cs # src/Umbraco.Core/Manifest/ManifestWatcher.cs # src/Umbraco.Core/Mapping/UmbracoMapper.cs # src/Umbraco.Core/Media/UploadAutoFillProperties.cs # src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs # src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/PreValueMigratorCollection.cs # src/Umbraco.Core/Models/Mapping/ContentPropertyBasicMapper.cs # src/Umbraco.Core/Models/Mapping/DataTypeMapDefinition.cs # src/Umbraco.Core/Models/Mapping/MacroMapDefinition.cs # src/Umbraco.Core/Models/Member.cs # src/Umbraco.Core/Packaging/PackageActionRunner.cs # src/Umbraco.Core/PropertyEditors/DataValueEditor.cs # src/Umbraco.Core/PropertyEditors/Validators/EyeDropperColorPickerConfigurationEditor.cs # src/Umbraco.Core/PropertyEditors/Validators/EyeDropperColorPickerPropertyEditor.cs # src/Umbraco.Core/Routing/DefaultUrlProvider.cs # src/Umbraco.Core/Runtime/CoreRuntime.cs # src/Umbraco.Core/Runtime/MainDom.cs # src/Umbraco.Core/RuntimeState.cs # src/Umbraco.Core/Scoping/ScopeProvider.cs # src/Umbraco.Core/Sync/DatabaseServerMessenger.cs # src/Umbraco.Core/Templates/HtmlUrlParser.cs # src/Umbraco.Core/UriExtensions.cs # src/Umbraco.Examine.Lucene/UmbracoContentIndex.cs # src/Umbraco.Examine.Lucene/UmbracoExamineIndex.cs # src/Umbraco.Infrastructure/Examine/IndexRebuilder.cs # src/Umbraco.Infrastructure/Manifest/DataEditorConverter.cs # src/Umbraco.Infrastructure/Manifest/ManifestParser.cs # src/Umbraco.Infrastructure/Migrations/Install/DatabaseBuilder.cs # src/Umbraco.Infrastructure/Migrations/Install/DatabaseSchemaCreator.cs # src/Umbraco.Infrastructure/Migrations/MigrationPlan.cs # src/Umbraco.Infrastructure/Migrations/Upgrade/V_8_0_0/DataTypeMigration.cs # src/Umbraco.Infrastructure/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs # src/Umbraco.Infrastructure/Migrations/Upgrade/V_8_0_0/MergeDateAndDateTimePropertyEditor.cs # src/Umbraco.Infrastructure/Migrations/Upgrade/V_8_0_0/RadioAndCheckboxPropertyEditorsMigration.cs # src/Umbraco.Infrastructure/Packaging/PackageDataInstallation.cs # src/Umbraco.Infrastructure/Persistence/Repositories/Implement/ContentRepositoryBase.cs # src/Umbraco.Infrastructure/Persistence/Repositories/Implement/ContentTypeRepository.cs # src/Umbraco.Infrastructure/Persistence/Repositories/Implement/ContentTypeRepositoryBase.cs # src/Umbraco.Infrastructure/Persistence/Repositories/Implement/MediaRepository.cs # src/Umbraco.Infrastructure/Persistence/UmbracoDatabase.cs # src/Umbraco.Infrastructure/Persistence/UmbracoDatabaseFactory.cs # src/Umbraco.Infrastructure/PropertyEditors/BlockEditorPropertyEditor.cs # src/Umbraco.Infrastructure/PropertyEditors/ImageCropperPropertyEditor.cs # src/Umbraco.Infrastructure/PropertyEditors/MultiUrlPickerValueEditor.cs # src/Umbraco.Infrastructure/PropertyEditors/NestedContentPropertyEditor.cs # src/Umbraco.Infrastructure/PropertyEditors/RichTextEditorPastedImages.cs # src/Umbraco.Infrastructure/PropertyEditors/ValueConverters/GridValueConverter.cs # src/Umbraco.Infrastructure/PropertyEditors/ValueConverters/ImageCropperValueConverter.cs # src/Umbraco.Infrastructure/PropertyEditors/ValueConverters/JsonValueConverter.cs # src/Umbraco.Infrastructure/PublishedCache/PublishedContentTypeCache.cs # src/Umbraco.Infrastructure/Runtime/SqlMainDomLock.cs # src/Umbraco.Infrastructure/Scoping/Scope.cs # src/Umbraco.Infrastructure/Search/ExamineNotificationHandler.cs # src/Umbraco.Infrastructure/Services/Implement/ContentService.cs # src/Umbraco.Infrastructure/Services/Implement/LocalizedTextService.cs # src/Umbraco.Infrastructure/Services/Implement/LocalizedTextServiceFileSources.cs # src/Umbraco.Infrastructure/Services/Implement/MediaService.cs # src/Umbraco.Infrastructure/Services/Implement/NotificationService.cs # src/Umbraco.Infrastructure/Sync/ServerMessengerBase.cs # src/Umbraco.ModelsBuilder.Embedded/Compose/ModelsBuilderComposer.cs # src/Umbraco.ModelsBuilder.Embedded/LiveModelsProvider.cs # src/Umbraco.PublishedCache.NuCache/ContentStore.cs # src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentEventsTests.cs # src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Mapping/MappingTests.cs # src/Umbraco.Tests.UnitTests/Umbraco.ModelsBuilder.Embedded/BuilderTests.cs # src/Umbraco.Tests/Composing/TypeLoaderTests.cs # src/Umbraco.Tests/LegacyXmlPublishedCache/DictionaryPublishedContent.cs # src/Umbraco.Tests/LegacyXmlPublishedCache/LegacyBackgroundTask/BackgroundTaskRunner.cs # src/Umbraco.Tests/LegacyXmlPublishedCache/PreviewContent.cs # src/Umbraco.Tests/LegacyXmlPublishedCache/PublishedMediaCache.cs # src/Umbraco.Tests/LegacyXmlPublishedCache/XmlStore.cs # src/Umbraco.Tests/LegacyXmlPublishedCache/XmlStoreFilePersister.cs # src/Umbraco.Tests/Services/ContentServicePerformanceTest.cs # src/Umbraco.Tests/Services/PerformanceTests.cs # src/Umbraco.Tests/TestHelpers/ConsoleLogger.cs # src/Umbraco.Tests/Testing/TestingTests/MockTests.cs # src/Umbraco.Web.BackOffice/Controllers/BackOfficeServerVariables.cs # src/Umbraco.Web.BackOffice/Controllers/ContentController.cs # src/Umbraco.Web.BackOffice/Controllers/DashboardController.cs # src/Umbraco.Web.BackOffice/Controllers/ExamineManagementController.cs # src/Umbraco.Web.BackOffice/HealthChecks/HealthCheckController.cs # src/Umbraco.Web.BackOffice/PropertyEditors/RteEmbedController.cs # src/Umbraco.Web.BackOffice/Services/IconService.cs # src/Umbraco.Web.BackOffice/Trees/ContentTreeControllerBase.cs # src/Umbraco.Web.Common/Extensions/FormCollectionExtensions.cs # src/Umbraco.Web.Common/Install/InstallApiController.cs # src/Umbraco.Web.Common/Macros/MacroRenderer.cs # src/Umbraco.Web.Common/ModelsBuilder/PureLiveModelFactory.cs # src/Umbraco.Web.UI.Client/package-lock.json # src/Umbraco.Web.UI.Client/src/views/memberTypes/copy.controller.js # src/Umbraco.Web.UI.Client/src/views/memberTypes/copy.html # src/Umbraco.Web.UI.NetCore/umbraco/UmbracoBackOffice/Default.cshtml # src/Umbraco.Web.UI.NetCore/umbraco/config/lang/da.xml # src/Umbraco.Web.UI.NetCore/umbraco/config/lang/en.xml # src/Umbraco.Web.UI.NetCore/umbraco/config/lang/en_us.xml # src/Umbraco.Web.UI/config/splashes/noNodes.aspx # src/Umbraco.Web/AspNet/AspNetHttpContextAccessor.cs # src/Umbraco.Web/Cache/DistributedCacheBinder.cs # src/Umbraco.Web/Cache/DistributedCacheBinder_Handlers.cs # src/Umbraco.Web/Editors/AuthenticationController.cs # src/Umbraco.Web/Editors/BackOfficeController.cs # src/Umbraco.Web/Editors/Binders/ContentModelBinderHelper.cs # src/Umbraco.Web/Editors/ContentControllerBase.cs # src/Umbraco.Web/Editors/ContentTypeController.cs # src/Umbraco.Web/Editors/DictionaryController.cs # src/Umbraco.Web/Editors/MemberTypeController.cs # src/Umbraco.Web/Editors/PasswordChanger.cs # src/Umbraco.Web/Editors/RelationTypeController.cs # src/Umbraco.Web/Editors/TinyMceController.cs # src/Umbraco.Web/HealthCheck/Checks/Security/HttpsCheck.cs # src/Umbraco.Web/HtmlHelperRenderExtensions.cs # src/Umbraco.Web/HttpUrlHelperExtensions.cs # src/Umbraco.Web/HybridEventMessagesAccessor.cs # src/Umbraco.Web/ImageCropperTemplateExtensions.cs # src/Umbraco.Web/JavaScript/ClientDependencyConfiguration.cs # src/Umbraco.Web/Mvc/RenderMvcController.cs # src/Umbraco.Web/PublishedCache/NuCache/DataSource/DatabaseDataSource.cs # src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs # src/Umbraco.Web/Routing/ContentFinderByConfigured404.cs # src/Umbraco.Web/Routing/ContentFinderByIdPath.cs # src/Umbraco.Web/Routing/ContentFinderByRedirectUrl.cs # src/Umbraco.Web/Routing/ContentFinderByUrl.cs # src/Umbraco.Web/Routing/ContentFinderByUrlAlias.cs # src/Umbraco.Web/Routing/ContentFinderByUrlAndTemplate.cs # src/Umbraco.Web/Routing/NotFoundHandlerHelper.cs # src/Umbraco.Web/Routing/PublishedRouter.cs # src/Umbraco.Web/Runtime/WebInitialComposer.cs # src/Umbraco.Web/Scheduling/KeepAlive.cs # src/Umbraco.Web/Scheduling/ScheduledPublishing.cs # src/Umbraco.Web/Scheduling/TempFileCleanup.cs # src/Umbraco.Web/Security/MembershipHelper.cs # src/Umbraco.Web/Security/Providers/UmbracoMembershipProvider.cs # src/Umbraco.Web/Trees/MemberTreeController.cs # src/Umbraco.Web/Trees/MemberTypeAndGroupTreeControllerBase.cs # src/Umbraco.Web/Trees/MemberTypeTreeController.cs # src/Umbraco.Web/UmbracoApplicationBase.cs # src/Umbraco.Web/UmbracoInjectedModule.cs # src/Umbraco.Web/UmbracoModule.cs # src/Umbraco.Web/WebApi/AngularJsonMediaTypeFormatter.cs # src/Umbraco.Web/WebApi/Filters/FileUploadCleanupFilterAttribute.cs # src/Umbraco.Web/WebApi/UnhandledExceptionLogger.cs
361 lines
17 KiB
C#
361 lines
17 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Microsoft.Extensions.Logging;
|
|
using Umbraco.Cms.Core;
|
|
using Umbraco.Cms.Core.Cache;
|
|
using Umbraco.Cms.Core.Dictionary;
|
|
using Umbraco.Cms.Core.Mapping;
|
|
using Umbraco.Cms.Core.Models;
|
|
using Umbraco.Cms.Core.Models.ContentEditing;
|
|
using Umbraco.Cms.Core.Models.Mapping;
|
|
using Umbraco.Cms.Core.Models.Membership;
|
|
using Umbraco.Cms.Core.Models.PublishedContent;
|
|
using Umbraco.Cms.Core.Routing;
|
|
using Umbraco.Cms.Core.Security;
|
|
using Umbraco.Cms.Core.Services;
|
|
using Umbraco.Cms.Core.Web;
|
|
using Umbraco.Cms.Web.BackOffice.Trees;
|
|
using Umbraco.Extensions;
|
|
using Constants = Umbraco.Cms.Core.Constants;
|
|
|
|
namespace Umbraco.Cms.Web.BackOffice.Mapping
|
|
{
|
|
/// <summary>
|
|
/// Declares how model mappings for content
|
|
/// </summary>
|
|
internal class ContentMapDefinition : IMapDefinition
|
|
{
|
|
private readonly CommonMapper _commonMapper;
|
|
private readonly CommonTreeNodeMapper _commonTreeNodeMapper;
|
|
private readonly ICultureDictionary _cultureDictionary;
|
|
private readonly ILocalizedTextService _localizedTextService;
|
|
private readonly IContentService _contentService;
|
|
private readonly IContentTypeService _contentTypeService;
|
|
private readonly IFileService _fileService;
|
|
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
|
|
private readonly IPublishedRouter _publishedRouter;
|
|
private readonly ILocalizationService _localizationService;
|
|
private readonly ILoggerFactory _loggerFactory;
|
|
private readonly IUserService _userService;
|
|
private readonly IEntityService _entityService;
|
|
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
|
|
private readonly IVariationContextAccessor _variationContextAccessor;
|
|
private readonly IPublishedUrlProvider _publishedUrlProvider;
|
|
private readonly UriUtility _uriUtility;
|
|
private readonly AppCaches _appCaches;
|
|
private readonly TabsAndPropertiesMapper<IContent> _tabsAndPropertiesMapper;
|
|
private readonly ContentSavedStateMapper<ContentPropertyDisplay> _stateMapper;
|
|
private readonly ContentBasicSavedStateMapper<ContentPropertyBasic> _basicStateMapper;
|
|
private readonly ContentVariantMapper _contentVariantMapper;
|
|
|
|
|
|
public ContentMapDefinition(
|
|
CommonMapper commonMapper,
|
|
CommonTreeNodeMapper commonTreeNodeMapper,
|
|
ICultureDictionary cultureDictionary,
|
|
ILocalizedTextService localizedTextService,
|
|
IContentService contentService,
|
|
IContentTypeService contentTypeService,
|
|
IFileService fileService,
|
|
IUmbracoContextAccessor umbracoContextAccessor,
|
|
IPublishedRouter publishedRouter,
|
|
ILocalizationService localizationService,
|
|
ILoggerFactory loggerFactory,
|
|
IUserService userService,
|
|
IVariationContextAccessor variationContextAccessor,
|
|
IContentTypeBaseServiceProvider contentTypeBaseServiceProvider,
|
|
UriUtility uriUtility,
|
|
IPublishedUrlProvider publishedUrlProvider,
|
|
IEntityService entityService,
|
|
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
|
|
AppCaches appCaches)
|
|
{
|
|
_commonMapper = commonMapper;
|
|
_commonTreeNodeMapper = commonTreeNodeMapper;
|
|
_cultureDictionary = cultureDictionary;
|
|
_localizedTextService = localizedTextService;
|
|
_contentService = contentService;
|
|
_contentTypeService = contentTypeService;
|
|
_fileService = fileService;
|
|
_umbracoContextAccessor = umbracoContextAccessor;
|
|
_publishedRouter = publishedRouter;
|
|
_localizationService = localizationService;
|
|
_loggerFactory = loggerFactory;
|
|
_userService = userService;
|
|
_entityService = entityService;
|
|
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
|
|
_variationContextAccessor = variationContextAccessor;
|
|
_uriUtility = uriUtility;
|
|
_publishedUrlProvider = publishedUrlProvider;
|
|
_appCaches = appCaches;
|
|
|
|
_tabsAndPropertiesMapper = new TabsAndPropertiesMapper<IContent>(cultureDictionary, localizedTextService, contentTypeBaseServiceProvider);
|
|
_stateMapper = new ContentSavedStateMapper<ContentPropertyDisplay>();
|
|
_basicStateMapper = new ContentBasicSavedStateMapper<ContentPropertyBasic>();
|
|
_contentVariantMapper = new ContentVariantMapper(_localizationService, localizedTextService);
|
|
}
|
|
|
|
public void DefineMaps(IUmbracoMapper mapper)
|
|
{
|
|
mapper.Define<IContent, ContentPropertyCollectionDto>((source, context) => new ContentPropertyCollectionDto(), Map);
|
|
mapper.Define<IContent, ContentItemDisplay>((source, context) => new ContentItemDisplay(), Map);
|
|
mapper.Define<IContent, ContentVariantDisplay>((source, context) => new ContentVariantDisplay(), Map);
|
|
mapper.Define<IContent, ContentItemBasic<ContentPropertyBasic>>((source, context) => new ContentItemBasic<ContentPropertyBasic>(), Map);
|
|
}
|
|
|
|
// Umbraco.Code.MapAll
|
|
private static void Map(IContent source, ContentPropertyCollectionDto target, MapperContext context)
|
|
{
|
|
target.Properties = context.MapEnumerable<IProperty, ContentPropertyDto>(source.Properties);
|
|
}
|
|
|
|
// Umbraco.Code.MapAll -AllowPreview -Errors -PersistedContent
|
|
private void Map(IContent source, ContentItemDisplay target, MapperContext context)
|
|
{
|
|
target.AllowedActions = GetActions(source);
|
|
target.AllowedTemplates = GetAllowedTemplates(source);
|
|
target.ContentApps = _commonMapper.GetContentApps(source);
|
|
target.ContentTypeId = source.ContentType.Id;
|
|
target.ContentTypeKey = source.ContentType.Key;
|
|
target.ContentTypeAlias = source.ContentType.Alias;
|
|
target.ContentTypeName = _localizedTextService.UmbracoDictionaryTranslate(_cultureDictionary, source.ContentType.Name);
|
|
target.DocumentType = _commonMapper.GetContentType(source, context);
|
|
target.Icon = source.ContentType.Icon;
|
|
target.Id = source.Id;
|
|
target.IsBlueprint = source.Blueprint;
|
|
target.IsChildOfListView = DetermineIsChildOfListView(source, context);
|
|
target.IsContainer = source.ContentType.IsContainer;
|
|
target.IsElement = source.ContentType.IsElement;
|
|
target.Key = source.Key;
|
|
target.Owner = _commonMapper.GetOwner(source, context);
|
|
target.ParentId = source.ParentId;
|
|
target.Path = source.Path;
|
|
target.SortOrder = source.SortOrder;
|
|
target.TemplateAlias = GetDefaultTemplate(source);
|
|
target.TemplateId = source.TemplateId ?? default;
|
|
target.Trashed = source.Trashed;
|
|
target.TreeNodeUrl = _commonTreeNodeMapper.GetTreeNodeUrl<ContentTreeController>(source);
|
|
target.Udi = Udi.Create(source.Blueprint ? Constants.UdiEntityType.DocumentBlueprint : Constants.UdiEntityType.Document, source.Key);
|
|
target.UpdateDate = source.UpdateDate;
|
|
target.Updater = _commonMapper.GetCreator(source, context);
|
|
target.Urls = GetUrls(source);
|
|
target.Variants = _contentVariantMapper.Map(source, context);
|
|
|
|
target.ContentDto = new ContentPropertyCollectionDto();
|
|
target.ContentDto.Properties = context.MapEnumerable<IProperty, ContentPropertyDto>(source.Properties);
|
|
}
|
|
|
|
// Umbraco.Code.MapAll -Segment -Language -DisplayName
|
|
private void Map(IContent source, ContentVariantDisplay target, MapperContext context)
|
|
{
|
|
target.CreateDate = source.CreateDate;
|
|
target.ExpireDate = GetScheduledDate(source, ContentScheduleAction.Expire, context);
|
|
target.Name = source.Name;
|
|
target.PublishDate = source.PublishDate;
|
|
target.ReleaseDate = GetScheduledDate(source, ContentScheduleAction.Release, context);
|
|
target.State = _stateMapper.Map(source, context);
|
|
target.Tabs = _tabsAndPropertiesMapper.Map(source, context);
|
|
target.UpdateDate = source.UpdateDate;
|
|
}
|
|
|
|
// Umbraco.Code.MapAll -Alias
|
|
private void Map(IContent source, ContentItemBasic<ContentPropertyBasic> target, MapperContext context)
|
|
{
|
|
target.ContentTypeId = source.ContentType.Id;
|
|
target.ContentTypeAlias = source.ContentType.Alias;
|
|
target.CreateDate = source.CreateDate;
|
|
target.Edited = source.Edited;
|
|
target.Icon = source.ContentType.Icon;
|
|
target.Id = source.Id;
|
|
target.Key = source.Key;
|
|
target.Name = GetName(source, context);
|
|
target.Owner = _commonMapper.GetOwner(source, context);
|
|
target.ParentId = source.ParentId;
|
|
target.Path = source.Path;
|
|
target.Properties = context.MapEnumerable<IProperty, ContentPropertyBasic>(source.Properties);
|
|
target.SortOrder = source.SortOrder;
|
|
target.State = _basicStateMapper.Map(source, context);
|
|
target.Trashed = source.Trashed;
|
|
target.Udi = Udi.Create(source.Blueprint ? Constants.UdiEntityType.DocumentBlueprint : Constants.UdiEntityType.Document, source.Key);
|
|
target.UpdateDate = GetUpdateDate(source, context);
|
|
target.Updater = _commonMapper.GetCreator(source, context);
|
|
target.VariesByCulture = source.ContentType.VariesByCulture();
|
|
}
|
|
|
|
private IEnumerable<string> GetActions(IContent source)
|
|
{
|
|
var backOfficeSecurity = _backOfficeSecurityAccessor.BackOfficeSecurity;
|
|
|
|
//cannot check permissions without a context
|
|
if (backOfficeSecurity is null)
|
|
return Enumerable.Empty<string>();
|
|
|
|
string path;
|
|
if (source.HasIdentity)
|
|
path = source.Path;
|
|
else
|
|
{
|
|
var parent = _contentService.GetById(source.ParentId);
|
|
path = parent == null ? "-1" : parent.Path;
|
|
}
|
|
|
|
return _userService.GetPermissionsForPath(backOfficeSecurity.CurrentUser, path).GetAllPermissions();
|
|
}
|
|
|
|
private UrlInfo[] GetUrls(IContent source)
|
|
{
|
|
if (source.ContentType.IsElement)
|
|
{
|
|
return Array.Empty<UrlInfo>();
|
|
}
|
|
|
|
var umbracoContext = _umbracoContextAccessor.UmbracoContext;
|
|
|
|
if (umbracoContext == null)
|
|
{
|
|
return new[] { UrlInfo.Message("Cannot generate URLs without a current Umbraco Context") };
|
|
}
|
|
|
|
// NOTE: unfortunately we're not async, we'll use .Result and hope this won't cause a deadlock anywhere for now
|
|
var urls = source.GetContentUrlsAsync(_publishedRouter, umbracoContext, _localizationService, _localizedTextService, _contentService, _variationContextAccessor, _loggerFactory.CreateLogger<IContent>(), _uriUtility, _publishedUrlProvider)
|
|
.ConfigureAwait(false)
|
|
.GetAwaiter()
|
|
.GetResult()
|
|
.ToArray();
|
|
|
|
return urls;
|
|
}
|
|
|
|
private DateTime GetUpdateDate(IContent source, MapperContext context)
|
|
{
|
|
// invariant = global date
|
|
if (!source.ContentType.VariesByCulture()) return source.UpdateDate;
|
|
|
|
// variant = depends on culture
|
|
var culture = context.GetCulture();
|
|
|
|
// if there's no culture here, the issue is somewhere else (UI, whatever) - throw!
|
|
if (culture == null)
|
|
throw new InvalidOperationException("Missing culture in mapping options.");
|
|
|
|
// if we don't have a date for a culture, it means the culture is not available, and
|
|
// hey we should probably not be mapping it, but it's too late, return a fallback date
|
|
var date = source.GetUpdateDate(culture);
|
|
return date ?? source.UpdateDate;
|
|
}
|
|
|
|
private string GetName(IContent source, MapperContext context)
|
|
{
|
|
// invariant = only 1 name
|
|
if (!source.ContentType.VariesByCulture()) return source.Name;
|
|
|
|
// variant = depends on culture
|
|
var culture = context.GetCulture();
|
|
|
|
// if there's no culture here, the issue is somewhere else (UI, whatever) - throw!
|
|
if (culture == null)
|
|
throw new InvalidOperationException("Missing culture in mapping options.");
|
|
|
|
// if we don't have a name for a culture, it means the culture is not available, and
|
|
// hey we should probably not be mapping it, but it's too late, return a fallback name
|
|
return source.CultureInfos.TryGetValue(culture, out var name) && !name.Name.IsNullOrWhiteSpace() ? name.Name : $"({source.Name})";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Checks if the content item is a descendant of a list view
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="context"></param>
|
|
/// <returns>
|
|
/// Returns true if the content item is a descendant of a list view and where the content is
|
|
/// not a current user's start node.
|
|
/// </returns>
|
|
/// <remarks>
|
|
/// We must check if it's the current user's start node because in that case we will actually be
|
|
/// rendering the tree node underneath the list view to visually show context. In this case we return
|
|
/// false because the item is technically not being rendered as part of a list view but instead as a
|
|
/// real tree node. If we didn't perform this check then tree syncing wouldn't work correctly.
|
|
/// </remarks>
|
|
private bool DetermineIsChildOfListView(IContent source, MapperContext context)
|
|
{
|
|
var userStartNodes = Array.Empty<int>();
|
|
|
|
// In cases where a user's start node is below a list view, we will actually render
|
|
// out the tree to that start node and in that case for that start node, we want to return
|
|
// false here.
|
|
if (context.HasItems && context.Items.TryGetValue("CurrentUser", out var usr) && usr is IUser currentUser)
|
|
{
|
|
userStartNodes = currentUser.CalculateContentStartNodeIds(_entityService, _appCaches);
|
|
if (!userStartNodes.Contains(Constants.System.Root))
|
|
{
|
|
// return false if this is the user's actual start node, the node will be rendered in the tree
|
|
// regardless of if it's a list view or not
|
|
if (userStartNodes.Contains(source.Id))
|
|
return false;
|
|
}
|
|
}
|
|
|
|
var parent = _contentService.GetParent(source);
|
|
|
|
if (parent == null)
|
|
return false;
|
|
|
|
var pathParts = parent.Path.Split(Constants.CharArrays.Comma).Select(x => int.TryParse(x, out var i) ? i : 0).ToList();
|
|
|
|
// reduce the path parts so we exclude top level content items that
|
|
// are higher up than a user's start nodes
|
|
foreach (var n in userStartNodes)
|
|
{
|
|
var index = pathParts.IndexOf(n);
|
|
if (index != -1)
|
|
{
|
|
// now trim all top level start nodes to the found index
|
|
for (var i = 0; i < index; i++)
|
|
{
|
|
pathParts.RemoveAt(0);
|
|
}
|
|
}
|
|
}
|
|
|
|
return parent.ContentType.IsContainer || _contentTypeService.HasContainerInPath(pathParts.ToArray());
|
|
}
|
|
|
|
|
|
private DateTime? GetScheduledDate(IContent source, ContentScheduleAction action, MapperContext context)
|
|
{
|
|
var culture = context.GetCulture() ?? string.Empty;
|
|
var schedule = source.ContentSchedule.GetSchedule(culture, action);
|
|
return schedule.FirstOrDefault()?.Date; // take the first, it's ordered by date
|
|
}
|
|
|
|
private IDictionary<string, string> GetAllowedTemplates(IContent source)
|
|
{
|
|
var contentType = _contentTypeService.Get(source.ContentTypeId);
|
|
|
|
return contentType.AllowedTemplates
|
|
.Where(t => t.Alias.IsNullOrWhiteSpace() == false && t.Name.IsNullOrWhiteSpace() == false)
|
|
.ToDictionary(t => t.Alias, t => _localizedTextService.UmbracoDictionaryTranslate(_cultureDictionary, t.Name));
|
|
}
|
|
|
|
private string GetDefaultTemplate(IContent source)
|
|
{
|
|
if (source == null)
|
|
return null;
|
|
|
|
// If no template id was set...
|
|
if (!source.TemplateId.HasValue)
|
|
{
|
|
// ... and no default template is set, return null...
|
|
// ... otherwise return the content type default template alias.
|
|
return string.IsNullOrWhiteSpace(source.ContentType.DefaultTemplate?.Alias)
|
|
? null
|
|
: source.ContentType.DefaultTemplate?.Alias;
|
|
}
|
|
|
|
var template = _fileService.GetTemplate(source.TemplateId.Value);
|
|
return template.Alias;
|
|
}
|
|
}
|
|
}
|