public async Task <IEnumerable <PageBlockTypeDisplayModelMapperOutput> > MapAsync( IReadOnlyCollection <PageBlockTypeDisplayModelMapperInput <ContentSplitSectionDataModel> > inputCollection, PublishStatusQuery publishStatus ) { // Because mapping is done in batch, we have to map multiple images here // Fortunately Cofoundry gives us access to repositories that can fetch this data // for us var imageAssetIds = inputCollection.SelectDistinctModelValuesWithoutEmpty(i => i.ImageAssetId); var imageAssets = await _imageAssetRepository.GetImageAssetRenderDetailsByIdRangeAsync(imageAssetIds); var results = new List <PageBlockTypeDisplayModelMapperOutput>(); foreach (var input in inputCollection) { var output = new ContentSplitSectionDisplayModel(); output.HtmlText = new HtmlString(input.DataModel.HtmlText); output.Title = input.DataModel.Title; output.Image = imageAssets.GetOrDefault(input.DataModel.ImageAssetId); results.Add(input.CreateOutput(output)); } return(results); }
public async Task <IEnumerable <PageBlockTypeDisplayModelMapperOutput> > MapAsync( IReadOnlyCollection <PageBlockTypeDisplayModelMapperInput <PageListDataModel> > inputCollection, PublishStatusQuery publishStatus ) { var allPageIds = inputCollection.SelectManyDistinctModelValues(d => d.PageIds); // Page routes are cached and so are the quickest way to get simple page information. // If we needed more data we could use a different but slower query to get it. var query = new GetPageRenderDetailsByIdRangeQuery(allPageIds); var allPageRoutes = await _pageRepository.GetPageRenderDetailsByIdRangeAsync(query); var results = new List <PageBlockTypeDisplayModelMapperOutput>(inputCollection.Count); foreach (var input in inputCollection) { var output = new PageListDisplayModel(); // Here will get the relevant pages and order them correctly. // Additionally if we are viewing the published version of the page // then we make sure we only show published pages in the list. output.Pages = allPageRoutes .FilterAndOrderByKeys(input.DataModel.PageIds) .ToList(); // The CreateOutput() method wraps the mapped display // model with it's identifier so we can identify later on results.Add(input.CreateOutput(output)); } return(results); }
private async Task <AuthorDetails> MapAuthor( BlogPostDataModel dataModel, PublishStatusQuery publishStatusQuery ) { if (dataModel.AuthorId < 1) { return(null); } var authorQuery = new GetCustomEntityRenderSummaryByIdQuery(dataModel.AuthorId, publishStatusQuery.ToRelatedEntityQueryStatus()); var dbAuthor = await _customEntityRepository.GetCustomEntityRenderSummaryByIdAsync(authorQuery); var model = dbAuthor?.Model as AuthorDataModel; if (model == null) { return(null); } var author = new AuthorDetails() { Name = dbAuthor.Title, Biography = HtmlFormatter.ConvertToBasicHtml(model.Biography) }; if (model.ProfileImageAssetId < 1) { return(author); } author.ProfileImage = await _imageAssetRepository.GetImageAssetRenderDetailsByIdAsync(model.ProfileImageAssetId.Value); return(author); }
private async Task <List <PageBlockTypeDisplayModelMapperOutput> > MapGeneric <T>( IEnumerable <IEntityVersionPageBlock> pageBlocks, PublishStatusQuery publishStatusQuery ) where T : IPageBlockTypeDataModel { var mapperType = typeof(IPageBlockTypeDisplayModelMapper <T>); var mapper = (IPageBlockTypeDisplayModelMapper <T>)_serviceProvider.GetService(mapperType); if (mapper == null) { string msg = @"{0} does not implement IPageBlockDisplayModel and no custom mapper could be found. You must create a class that implements IPageBlockDisplayModelMapper<{0}> if you are using a custom display model. Full type name: {1}"; throw new Exception(string.Format(msg, typeof(T).Name, typeof(T).FullName)); } var dataModels = new List <PageBlockTypeDisplayModelMapperInput <T> >(); foreach (var pageBlock in pageBlocks) { var mapperModel = new PageBlockTypeDisplayModelMapperInput <T>(); mapperModel.DataModel = (T)_dbUnstructuredDataSerializer.Deserialize(pageBlock.SerializedData, typeof(T)); mapperModel.VersionBlockId = pageBlock.GetVersionBlockId(); dataModels.Add(mapperModel); } var results = await mapper.MapAsync(dataModels, publishStatusQuery); return(results.ToList()); }
private async Task <ICollection <MappedPageBlock> > ToBlockMappingDataAsync( IEnumerable <IEntityVersionPageBlock> entityBlocks, IEnumerable <PageBlockTypeSummary> blockTypes, PublishStatusQuery workflowStatus ) { var mappedBlocks = new List <MappedPageBlock>(); foreach (var group in entityBlocks.GroupBy(m => m.PageBlockTypeId)) { var blockType = blockTypes.SingleOrDefault(t => t.PageBlockTypeId == group.Key); var mapperOutput = await _pageVersionBlockModelMapper.MapDisplayModelAsync(blockType.FileName, group, workflowStatus); foreach (var block in group) { var mappedBlock = new MappedPageBlock() { PageBlock = block, BlockType = blockType, DisplayModel = mapperOutput.Single(o => o.VersionBlockId == block.GetVersionBlockId()).DisplayModel }; mappedBlocks.Add(mappedBlock); } } return(mappedBlocks); }
public async Task <IEnumerable <PageBlockTypeDisplayModelMapperOutput> > MapAsync( IReadOnlyCollection <PageBlockTypeDisplayModelMapperInput <DocumentDataModel> > inputCollection, PublishStatusQuery publishStatusQuery ) { var documentIds = inputCollection.SelectDistinctModelValuesWithoutEmpty(i => i.DocumentAssetId); var documentsQuery = new GetDocumentAssetRenderDetailsByIdRangeQuery(documentIds); var documents = await _queryExecutor.ExecuteAsync(documentsQuery); var results = new List <PageBlockTypeDisplayModelMapperOutput>(inputCollection.Count); foreach (var input in inputCollection) { var document = documents.GetOrDefault(input.DataModel.DocumentAssetId); var output = new DocumentDisplayModel(); if (document != null) { output.Description = document.Description; output.Title = document.Title; if (input.DataModel.DownloadMode == DocumentDownloadMode.ForceDownload) { output.Url = _documentAssetRouteLibrary.DocumentAssetDownload(document); } else { output.Url = _documentAssetRouteLibrary.DocumentAsset(document); } } results.Add(input.CreateOutput(output)); } return(results); }
/// <summary> /// Maps a batch of the same type of page block data to a collection /// of display models ready for rendering. /// </summary> /// <param name="typeName">The block type name e.g. 'PlainText', 'RawHtml'.</param> /// <param name="pageBlocks">The version data to get the serialized model from.</param> /// <param name="publishStatus"> /// The publish status of the parent page or custom entity /// being mapped. This is provided so dependent entities can use /// the same publish status. /// </param> /// <returns> /// Collection of mapped display models, wrapped in an output class that /// can be used to identify them. /// </returns> public async Task <ICollection <PageBlockTypeDisplayModelMapperOutput> > MapDisplayModelAsync( string typeName, IEnumerable <IEntityVersionPageBlock> pageBlocks, PublishStatusQuery publishStatus ) { // Find the data-provider class for this block type Type modelType = _pageBlockDataModelTypeFactory.CreateByPageBlockTypeFileName(typeName); if (typeof(IPageBlockTypeDisplayModel).IsAssignableFrom(modelType)) { // We can serialize directly to the display model var displayModels = new List <PageBlockTypeDisplayModelMapperOutput>(); foreach (var pageBlock in pageBlocks) { var mapperModel = new PageBlockTypeDisplayModelMapperOutput(); mapperModel.DisplayModel = (IPageBlockTypeDisplayModel)_dbUnstructuredDataSerializer.Deserialize(pageBlock.SerializedData, modelType); mapperModel.VersionBlockId = pageBlock.GetVersionBlockId(); displayModels.Add(mapperModel); } return(displayModels); } else { var blockWorkflowStatus = publishStatus.ToRelatedEntityQueryStatus(); // We have to use a mapping class to do some custom mapping var displayModels = (Task <List <PageBlockTypeDisplayModelMapperOutput> >)_mapGenericMethod .MakeGenericMethod(modelType) .Invoke(this, new object[] { pageBlocks, blockWorkflowStatus }); return(await displayModels); } }
public async Task <BlogPostDisplayModel> MapDisplayModelAsync( CustomEntityRenderDetails renderDetails, BlogPostDataModel dataModel, PublishStatusQuery publishStatusQuery ) { var vm = new BlogPostDisplayModel(); vm.MetaDescription = dataModel.ShortDescription; vm.PageTitle = renderDetails.Title; vm.Title = renderDetails.Title; vm.Date = renderDetails.CreateDate; vm.FullPath = renderDetails.PageUrls.FirstOrDefault(); if (!EnumerableHelper.IsNullOrEmpty(dataModel.CategoryIds)) { // We manually query and map relations which gives us maximum flexibility when mapping models // Fortunately the framework provides tools to make this fairly simple vm.Categories = await _contentRepository .CustomEntities() .GetByIdRange(dataModel.CategoryIds) .AsRenderSummaries(publishStatusQuery) .MapItem(MapCategory) .FilterAndOrderByKeys(dataModel.CategoryIds) .ExecuteAsync(); } return(vm); }
private async Task<PagedQueryResult<BlogPostSummary>> MapBlogPostsAsync( PagedQueryResult<CustomEntityRenderSummary> customEntityResult, PublishStatusQuery ambientEntityPublishStatusQuery) { var blogPosts = new List<BlogPostSummary>(); var imageAssetIds = customEntityResult .Items .Select(i => (BlogPostDataModel)i.Model) .Where(m => m.ThumbnailImageAssetId != null) .Select(m => m.ThumbnailImageAssetId.Value) .Distinct(); var imageLookup = await _contentRepository .ImageAssets() .GetByIdRange(imageAssetIds) .AsRenderDetails() .ExecuteAsync(); foreach (var customEntity in customEntityResult.Items) { var model = (BlogPostDataModel)customEntity.Model; var blogPost = new BlogPostSummary(); blogPost.Title = customEntity.Title; blogPost.ShortDescription = model.ShortDescription; blogPost.ThumbnailImageAsset = imageLookup.GetOrDefault(model.ThumbnailImageAssetId); blogPost.FullPath = customEntity.PageUrls.FirstOrDefault(); blogPost.PostDate = customEntity.PublishDate; blogPosts.Add(blogPost); } return customEntityResult.ChangeType(blogPosts); }
private async Task <CustomEntityVersionPageBlockRenderDetails> MapAsync( CustomEntityVersionPageBlock versionBlock, string blockTypeFileName, string customEntityDefinitionCode, PublishStatusQuery publishStatus, IExecutionContext executionContext ) { _permissionValidationService.EnforceCustomEntityPermission <CustomEntityReadPermission>(customEntityDefinitionCode, executionContext.UserContext); var blockTypeQuery = new GetPageBlockTypeSummaryByIdQuery(versionBlock.PageBlockTypeId); var blockType = await _queryExecutor.ExecuteAsync(blockTypeQuery, executionContext); EntityNotFoundException.ThrowIfNull(blockType, versionBlock.PageBlockTypeId); var result = new CustomEntityVersionPageBlockRenderDetails(); result.CustomEntityVersionPageBlockId = versionBlock.CustomEntityVersionPageBlockId; result.BlockType = blockType; result.DisplayModel = await _pageVersionBlockModelMapper.MapDisplayModelAsync( blockTypeFileName, versionBlock, publishStatus, executionContext ); return(result); }
public GetCustomEntitySummariesByIdRangeQuery( IEnumerable <int> customEntityIds, PublishStatusQuery publishStatusQuery = PublishStatusQuery.Published ) : this(customEntityIds?.ToList()) { }
private async Task <PageVersionBlockRenderDetails> MapAsync( PageVersionBlock pageVersionBlock, string blockTypeFileName, PublishStatusQuery publishStatus, IExecutionContext executionContext ) { var blockTypeQuery = new GetPageBlockTypeSummaryByIdQuery(pageVersionBlock.PageBlockTypeId); var blockType = await _queryExecutor.ExecuteAsync(blockTypeQuery, executionContext); EntityNotFoundException.ThrowIfNull(blockType, pageVersionBlock.PageBlockTypeId); var result = new PageVersionBlockRenderDetails(); result.PageVersionBlockId = pageVersionBlock.PageVersionBlockId; result.BlockType = blockType; result.DisplayModel = await _pageVersionBlockModelMapper.MapDisplayModelAsync( blockTypeFileName, pageVersionBlock, publishStatus, executionContext ); return(result); }
public async Task <IEnumerable <PageBlockTypeDisplayModelMapperOutput> > MapAsync( IReadOnlyCollection <PageBlockTypeDisplayModelMapperInput <ImageDataModel> > inputCollection, PublishStatusQuery publishStatusQuery ) { var imageAssetIds = inputCollection.SelectDistinctModelValuesWithoutEmpty(i => i.ImageId); var imagesQuery = new GetImageAssetRenderDetailsByIdRangeQuery(imageAssetIds); var images = await _queryExecutor.ExecuteAsync(imagesQuery); var results = new List <PageBlockTypeDisplayModelMapperOutput>(inputCollection.Count); foreach (var input in inputCollection) { var output = new ImageDisplayModel() { AltText = input.DataModel.AltText, LinkPath = input.DataModel.LinkPath, LinkTarget = input.DataModel.LinkTarget }; var image = images.GetOrDefault(input.DataModel.ImageId); output.Source = _imageAssetRouteLibrary.ImageAsset(image); results.Add(input.CreateOutput(output)); } return(results); }
public Task <IEnumerable <PageBlockTypeDisplayModelMapperOutput> > MapAsync( IReadOnlyCollection <PageBlockTypeDisplayModelMapperInput <SingleLineTextDataModel> > inputCollection, PublishStatusQuery publishStatusQuery ) { return(Task.FromResult(Map(inputCollection))); }
public async Task WhenQueriedWithPublishStatus_ReturnsCorrectWorkflowStatus( PublishStatusQuery publishStatus, WorkFlowStatus?draftOnlyWorkFlowStatus, WorkFlowStatus?publishOnlyWorkFlowStatus, WorkFlowStatus?publishAndDraftWorkFlowStatus ) { var uniqueData = UNIQUE_PREFIX + "QPubStatus_" + publishStatus; using var app = _appFactory.Create(); var directoryId = await app.TestData.PageDirectories().AddAsync(uniqueData); var pageWithDraftOnlyId = await app.TestData.Pages().AddAsync(uniqueData + "_D", directoryId); var pageWithPublishedOnlyId = await app.TestData.Pages().AddAsync(uniqueData + "_P", directoryId, c => c.Publish = true); var pageWithPublishedandDraftId = await app.TestData.Pages().AddAsync(uniqueData + "_DP", directoryId, c => c.Publish = true); await app.TestData.Pages().AddDraftAsync(pageWithPublishedandDraftId); var contentRepository = app.Services.GetContentRepositoryWithElevatedPermissions(); var pages = await contentRepository .Pages() .GetByIdRange(new int[] { pageWithDraftOnlyId, pageWithPublishedOnlyId, pageWithPublishedandDraftId }) .AsRenderSummaries(publishStatus) .ExecuteAsync(); AssertStatus(pages, pageWithDraftOnlyId, draftOnlyWorkFlowStatus); AssertStatus(pages, pageWithPublishedOnlyId, publishOnlyWorkFlowStatus); AssertStatus(pages, pageWithPublishedandDraftId, publishAndDraftWorkFlowStatus);
protected async Task <IReadOnlyDictionary <int, IPageBlockTypeDisplayModel> > MapGeneric <TDataModel>( IEnumerable <IEntityVersionPageBlock> pageBlocks, PublishStatusQuery publishStatusQuery, IExecutionContext executionContext ) where TDataModel : IPageBlockTypeDataModel { var mapperType = typeof(IPageBlockTypeDisplayModelMapper <TDataModel>); var mapper = (IPageBlockTypeDisplayModelMapper <TDataModel>)_serviceProvider.GetService(mapperType); if (mapper == null) { string msg = @"{0} does not implement IPageBlockDisplayModel and no custom mapper could be found. You must create a class that implements IPageBlockDisplayModelMapper<{0}> if you are using a custom display model. Full type name: {1}"; throw new Exception(string.Format(msg, typeof(TDataModel).Name, typeof(TDataModel).FullName)); } var dataModels = new List <PageBlockTypeDisplayModelMapperInput <TDataModel> >(); foreach (var pageBlock in pageBlocks) { var mapperModel = new PageBlockTypeDisplayModelMapperInput <TDataModel>(); mapperModel.DataModel = (TDataModel)_dbUnstructuredDataSerializer.Deserialize(pageBlock.SerializedData, typeof(TDataModel)); mapperModel.VersionBlockId = pageBlock.GetVersionBlockId(); dataModels.Add(mapperModel); } var context = new PageBlockTypeDisplayModelMapperContext <TDataModel>(dataModels, publishStatusQuery, executionContext); var result = new PageBlockTypeDisplayModelMapperResult <TDataModel>(dataModels.Count); await mapper.MapAsync(context, result); return(result.Items); }
public async Task <BlogPostDisplayModel> MapDisplayModelAsync( CustomEntityRenderDetails renderDetails, BlogPostDataModel dataModel, PublishStatusQuery publishStatusQuery ) { var vm = new BlogPostDisplayModel(); vm.MetaDescription = dataModel.ShortDescription; vm.PageTitle = renderDetails.Title; vm.Title = renderDetails.Title; vm.Date = renderDetails.CreateDate; vm.FullPath = renderDetails.PageUrls.FirstOrDefault(); if (!EnumerableHelper.IsNullOrEmpty(dataModel.CategoryIds)) { // We manually query and map relations which gives us maximum flexibility when mapping models // Fortunately the framework provides tools to make this fairly simple var relatedEntityPublishStatusQuery = publishStatusQuery.ToRelatedEntityQueryStatus(); var categoriesQuery = new GetCustomEntityRenderSummariesByIdRangeQuery(dataModel.CategoryIds, relatedEntityPublishStatusQuery); var customEntities = await _customEntityRepository.GetCustomEntityRenderSummariesByIdRangeAsync(categoriesQuery); vm.Categories = customEntities .FilterAndOrderByKeys(dataModel.CategoryIds) .Select(c => MapCategory(c)) .ToList(); } return(vm); }
public GetCustomEntityRenderSummariesByDefinitionCodeQuery( string customEntityDefinitionCode, PublishStatusQuery workflowStatus = PublishStatusQuery.Published ) { CustomEntityDefinitionCode = customEntityDefinitionCode; PublishStatus = workflowStatus; }
/// <summary> /// Query to retreive all custom entites of a specific type, projected as a /// CustomEntityRenderSummary, which is a general-purpose projection with version /// specific data, including a deserialized data model. The results are /// version-sensitive and defaults to returning published versions only, but /// this behavior can be controlled by the publishStatus query property. /// </summary> /// <param name="customEntityDefinitionCode">The definition code of the custom entity to filter on.</param> /// <param name="publicStatusQuery"> /// Used to determine which version of the custom entities to include data for. This /// defaults to Published, meaning that only published custom entities will be returned. /// </param> public GetCustomEntityRenderSummariesByDefinitionCodeQuery( string customEntityDefinitionCode, PublishStatusQuery publicStatusQuery = PublishStatusQuery.Published ) { CustomEntityDefinitionCode = customEntityDefinitionCode; PublishStatus = publicStatusQuery; }
/// <summary> /// Turns the PublishStatusQuery used to query an entity into a PublishStatusQuery /// that can be used to query dependent entities. E.g. PublishStatusQuery.SpecificVersion /// cannot be used to query a dependent entity and so PublishStatusQuery.Latest is /// used instead. /// </summary> /// <remarks> /// When working with child entities, the PublishStatusQuery we apply to /// them is not neccessarily the status used to query the parent. If we are /// loading a page using the Draft status, then we cannot expect that all /// dependencies should have a draft version, so we re-write it to Latest. /// The same applies if we're loading a specific version. /// </remarks> public static PublishStatusQuery ToRelatedEntityQueryStatus(this PublishStatusQuery publishStatusQuery) { if (publishStatusQuery == PublishStatusQuery.Draft || publishStatusQuery == PublishStatusQuery.SpecificVersion) { publishStatusQuery = PublishStatusQuery.Latest; } return(publishStatusQuery); }
/// <summary> /// Returns custom entities filtered on the url slug value. This query /// can return multiple custom entities because unique UrlSlugs is an /// optional setting on the custom entity definition. /// </summary> /// <param name="customEntityDefinitionCode">Required. The definition code of the custom entity to filter on.</param> /// <param name="urlSlug">Required. The url slug to find matching custom entities for.</param> /// <param name="publishStatusQuery"> /// Used to determine which version of the custom entities to include data for. This /// defaults to Published, meaning that only published custom entities will be returned. /// Note that PublishStatusQuery.SpecificVersion is not available /// because the query can potentially return multiple results. /// </param> public GetCustomEntityRenderSummariesByUrlSlugQuery( string customEntityDefinitionCode, string urlSlug, PublishStatusQuery publishStatusQuery = PublishStatusQuery.Published ) { CustomEntityDefinitionCode = customEntityDefinitionCode; UrlSlug = urlSlug; PublishStatus = publishStatusQuery; }
/// <summary> /// Maps a single page block data model to a concrete /// display model. /// </summary> /// <param name="typeName">The block type name e.g. 'PlainText', 'RawHtml'.</param> /// <param name="pageBlock">The version data to get the serialized model from.</param> /// <param name="publishStatus"> /// The publish status of the parent page or custom entity /// being mapped. This is provided so dependent entities can use /// the same publish status. /// </param> /// <returns>Mapped display model.</returns> public async Task <IPageBlockTypeDisplayModel> MapDisplayModelAsync( string typeName, IEntityVersionPageBlock pageBlock, PublishStatusQuery publishStatus ) { var mapped = await MapDisplayModelAsync(typeName, new IEntityVersionPageBlock[] { pageBlock }, publishStatus); return(mapped .Select(m => m.DisplayModel) .SingleOrDefault()); }
public GetCustomEntitySummariesByIdRangeQuery( IReadOnlyCollection <int> customEntityIds, PublishStatusQuery publishStatusQuery = PublishStatusQuery.Published ) { if (customEntityIds == null) { throw new ArgumentNullException(nameof(customEntityIds)); } CustomEntityIds = customEntityIds; PublishStatus = publishStatusQuery; }
/// <summary> /// Maps custom entity render data into a specific custom entity /// display model type, which can be used to render out view data. /// </summary> /// <typeparam name="TDisplayModel">Display model type to map to.</typeparam> /// <param name="renderDetails">The custom entity model to map, including the raw data model.</param> /// <param name="publishStatusQuery"> /// The query type that should be used to query dependent entities. E.g. if the custom /// entity was queried with the Published status query, then any dependent entities should /// also be queried as Published. /// </param> /// <returns>Mapped display model instance.</returns> public Task <TDisplayModel> MapDisplayModelAsync <TDisplayModel>( CustomEntityRenderDetails renderDetails, PublishStatusQuery publishStatusQuery ) where TDisplayModel : ICustomEntityDisplayModel { var mapperType = typeof(ICustomEntityDisplayModelMapper <,>).MakeGenericType(renderDetails.Model.GetType(), typeof(TDisplayModel)); var mapper = _serviceProvider.GetRequiredService(mapperType); var method = mapperType.GetMethod(mapDisplayModelMethodName); return((Task <TDisplayModel>)method.Invoke(mapper, new object[] { renderDetails, renderDetails.Model, publishStatusQuery })); }
public Task <TestCustomEntityPageDisplayModel> MapDisplayModelAsync( CustomEntityRenderDetails renderDetails, TestCustomEntityDataModel dataModel, PublishStatusQuery publishStatusQuery ) { var displayModel = new TestCustomEntityPageDisplayModel() { PageTitle = renderDetails.Title, MetaDescription = "Test Meta Description" }; return(Task.FromResult(displayModel)); }
/// <summary> /// Validates that a query model has a valid version id property /// for the provided PublishStatusQuery value. E.g. the version id /// should only be specified if the publish status is set to /// PublishStatusQuery.SpecificVersion. Any errors are returned as /// validation results, intended to be used in an IValidatableObject /// implementation. /// </summary> /// <param name="publishStatusQuery">PublishStatusQuery value to check.</param> /// <param name="pageVersionId">Version id property to check.</param> /// <param name="versionIdPropertyName">The name of the version id property to return in any error messages.</param> public static IEnumerable <ValidationResult> ValidateVersionId( PublishStatusQuery publishStatusQuery, int?pageVersionId, string versionIdPropertyName ) { if (publishStatusQuery == PublishStatusQuery.SpecificVersion && (!pageVersionId.HasValue || pageVersionId < 1)) { yield return(new ValidationResult($"Value cannot be null if {nameof(PublishStatusQuery)}.{nameof(PublishStatusQuery.SpecificVersion)} is specified", new string[] { versionIdPropertyName })); } else if (publishStatusQuery != PublishStatusQuery.SpecificVersion && pageVersionId.HasValue) { yield return(new ValidationResult($"Value should be null if {nameof(PublishStatusQuery)}.{nameof(PublishStatusQuery.SpecificVersion)} is not specified", new string[] { versionIdPropertyName })); } }
/// <summary> /// Gets version routing info for the specified PublishStatus query /// </summary> public static T GetVersionRouting <T>(this IEnumerable <T> versions, PublishStatusQuery status, int?versionId = null) where T : IVersionRoute { T result; switch (status) { case PublishStatusQuery.Draft: result = versions .SingleOrDefault(v => v.WorkFlowStatus == WorkFlowStatus.Draft); break; case PublishStatusQuery.Published: result = versions .Where(v => v.WorkFlowStatus == WorkFlowStatus.Published) .OrderByDescending(v => v.CreateDate) .FirstOrDefault(); break; case PublishStatusQuery.Latest: result = versions .Where(v => v.WorkFlowStatus == WorkFlowStatus.Draft || v.WorkFlowStatus == WorkFlowStatus.Published) .OrderByDescending(v => v.WorkFlowStatus == WorkFlowStatus.Draft) .FirstOrDefault(); break; case PublishStatusQuery.PreferPublished: result = versions .Where(v => v.WorkFlowStatus == WorkFlowStatus.Draft || v.WorkFlowStatus == WorkFlowStatus.Published) .OrderByDescending(v => v.WorkFlowStatus == WorkFlowStatus.Published) .FirstOrDefault(); break; case PublishStatusQuery.SpecificVersion: if (!versionId.HasValue) { throw new InvalidOperationException("PublishStatusQuery.SpecificVersion requires a specific VersionId"); } result = versions .SingleOrDefault(v => v.VersionId == versionId); break; default: throw new InvalidOperationException("Unrecognised PublishStatusQuery: " + status); } return(result); }
/// <summary> /// Here we map the raw custom entity data from Cofoundry into our /// own BlogPostSummary which will get sent to be rendered in the /// view. /// /// This code is repeated in HomepageBlogPostsViewComponent for /// simplicity, but typically you'd put the code into a shared /// mapper or break data access out into it's own shared layer. /// </summary> private async Task <PagedQueryResult <BlogPostSummary> > MapBlogPostsAsync( PagedQueryResult <CustomEntityRenderSummary> customEntityResult, PublishStatusQuery ambientEntityPublishStatusQuery ) { var blogPosts = new List <BlogPostSummary>(customEntityResult.Items.Count()); var imageAssetIds = customEntityResult .Items .Select(i => (BlogPostDataModel)i.Model) .Select(m => m.ThumbnailImageAssetId) .Distinct(); var authorIds = customEntityResult .Items .Select(i => (BlogPostDataModel)i.Model) .Select(m => m.AuthorId) .Distinct(); var imageLookup = await _imageAssetRepository.GetImageAssetRenderDetailsByIdRangeAsync(imageAssetIds); var authorQuery = new GetCustomEntityRenderSummariesByIdRangeQuery(authorIds, ambientEntityPublishStatusQuery); var authorLookup = await _customEntityRepository.GetCustomEntityRenderSummariesByIdRangeAsync(authorQuery); foreach (var customEntity in customEntityResult.Items) { var model = (BlogPostDataModel)customEntity.Model; var blogPost = new BlogPostSummary(); blogPost.Title = customEntity.Title; blogPost.ShortDescription = model.ShortDescription; blogPost.ThumbnailImageAsset = imageLookup.GetOrDefault(model.ThumbnailImageAssetId); blogPost.FullPath = customEntity.PageUrls.FirstOrDefault(); blogPost.PostDate = customEntity.PublishDate; var author = authorLookup.GetOrDefault(model.AuthorId); if (author != null) { blogPost.AuthorName = author.Title; } blogPosts.Add(blogPost); } return(customEntityResult.ChangeType(blogPosts)); }
private async Task <ICollection <MappedPageBlock> > ToBlockMappingDataAsync( IEnumerable <IEntityVersionPageBlock> entityBlocks, IEnumerable <PageBlockTypeSummary> blockTypes, PublishStatusQuery publishStatus, IExecutionContext executionContext ) { var mappedBlocks = new List <MappedPageBlock>(); foreach (var group in entityBlocks.GroupBy(m => m.PageBlockTypeId)) { var blockType = blockTypes.SingleOrDefault(t => t.PageBlockTypeId == group.Key); // If missing e.g. archived, skip if (blockType == null) { continue; } var mapperOutput = await _pageVersionBlockModelMapper.MapDisplayModelAsync( blockType.FileName, group, publishStatus, executionContext ); foreach (var block in group) { var versionBlockId = block.GetVersionBlockId(); if (mapperOutput.ContainsKey(versionBlockId) && mapperOutput[versionBlockId] != null) { var mappedBlock = new MappedPageBlock() { PageBlock = block, BlockType = blockType, DisplayModel = mapperOutput[versionBlockId] }; mappedBlocks.Add(mappedBlock); } } } return(mappedBlocks); }
public Task <IEnumerable <PageBlockTypeDisplayModelMapperOutput> > MapAsync( IReadOnlyCollection <PageBlockTypeDisplayModelMapperInput <RichTextWithMediaDataModel> > inputCollection, PublishStatusQuery publishStatusQuery ) { var results = new List <PageBlockTypeDisplayModelMapperOutput>(inputCollection.Count); foreach (var input in inputCollection) { var output = new RichTextWithMediaDisplayModel(); output.RawHtml = new HtmlString(input.DataModel.RawHtml); results.Add(input.CreateOutput(output)); } return(Task.FromResult(results.AsEnumerable())); }