/// <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 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); }
/// <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="entityBlocks">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> /// <param name="executionContext"> /// The execution context from the caller which can be used in /// any child queries to ensure any elevated permissions are /// passed down the chain of execution. /// </param> /// <returns> /// Dictionary of mapped display models, with a key (block version id) that can be /// used to identify them. /// </returns> public virtual async Task <IReadOnlyDictionary <int, IPageBlockTypeDisplayModel> > MapDisplayModelAsync( string typeName, IEnumerable <IEntityVersionPageBlock> entityBlocks, PublishStatusQuery publishStatus, IExecutionContext executionContext ) { // 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 Dictionary <int, IPageBlockTypeDisplayModel>(); foreach (var pageBlock in entityBlocks) { var displayModel = (IPageBlockTypeDisplayModel)_dbUnstructuredDataSerializer.Deserialize(pageBlock.SerializedData, modelType); var versionBlockId = pageBlock.GetVersionBlockId(); if (displayModels.ContainsKey(versionBlockId)) { throw new Exception($"A block with a version id of {versionBlockId} has already been added to the mapping collection."); } displayModels.Add(versionBlockId, displayModel); } return(displayModels); } else { var blockWorkflowStatus = publishStatus.ToRelatedEntityQueryStatus(); // We have to use a mapping class to do some custom mapping var displayModels = (Task <IReadOnlyDictionary <int, IPageBlockTypeDisplayModel> >)_mapGenericMethod .MakeGenericMethod(modelType) .Invoke(this, new object[] { entityBlocks, blockWorkflowStatus, executionContext }); return(await displayModels); } }
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); }