/// <summary> /// Gets page from database manager result. /// </summary> /// <param name="dbm">Database manager.</param> /// <param name="loadZonesAndElements">Indicates depth of data load.</param> /// <param name="loadTags">Indicates whether tags should be loaded.</param> /// <returns>Page (or null if page not found).</returns> private Page GetPage(IDatabaseManager dbm, bool loadZonesAndElements, bool loadTags) { // Get layout if (loadZonesAndElements && !dbm.Read()) { return(null); } Page page = GetPageFromDatabaseManager(dbm); // Move data reader on? if (loadZonesAndElements || loadTags) { dbm.Read(); } // Get page zones? if (loadZonesAndElements) { Dictionary <long, PageZone> pageZonesById = new Dictionary <long, PageZone>(); while (dbm.Read()) { PageZone pageZone = GetPageZoneFromDatabaseManager(dbm); page.PageZones.Add(pageZone); pageZonesById.Add(pageZone.PageZoneId, pageZone); } // Get page zone elements while (dbm.Read()) { PageZoneElement pageZoneElement = GetPageZoneElementFromDatabaseManager(dbm); pageZonesById[pageZoneElement.PageZoneId].PageZoneElements.Add(pageZoneElement); } } // Get tags?? if (loadTags) { while (dbm.Read()) { page.Tags.Add(GetTagFromDatabaseManager(dbm)); } } // Return the result return(page); }
/// <summary> /// Updates a configurable page zone. Creates new elements and removes old elements. Re-orders existing elements. /// </summary> /// <param name="tenantId">Website that page belongs to.</param> /// <param name="pageId">Page identifier.</param> /// <param name="pageZoneId">Page zone identifier.</param> /// <param name="pageZoneElements">New page zone contents.</param> /// <param name="unitOfWork">Unit of work.</param> public void UpdateZone(long tenantId, long pageId, long pageZoneId, List <PageZoneElementInfo> pageZoneElements, IUnitOfWork unitOfWork = null) { // If we don't have a unit of work in place, create one now so that we can rollback all changes in case of failure IUnitOfWork localUnitOfWork = unitOfWork == null?_unitOfWorkFactory.CreateUnitOfWork() : null; // Do the page update try { // Get page, master page and page zone that we administering Page page = Read(tenantId, pageId, unitOfWork ?? localUnitOfWork); MasterPage masterPage = _masterPageService.Read(tenantId, page.MasterPageId, unitOfWork ?? localUnitOfWork); PageZone pageZone = page.PageZones.Where(z => z.PageZoneId == pageZoneId).FirstOrDefault(); // Perform validation _pageValidator.ValidateUpdateZone(masterPage, page, pageZoneId, pageZoneElements); // Construct new list of page zone elements List <PageZoneElement> newPageZoneElements = new List <PageZoneElement>(); foreach (PageZoneElementInfo info in pageZoneElements) { // Create new page zone element? if (info.PageZoneElementId == 0) { IElementSettings element = _elementService.New(tenantId, info.ElementTypeId); element.Name = info.Name; long elementId = _elementService.Create(element, unitOfWork ?? localUnitOfWork); newPageZoneElements.Add(new PageZoneElement { TenantId = tenantId, PageId = pageId, PageZoneId = pageZoneId, PageZoneElementId = 0, SortOrder = info.SortOrder, ElementTypeId = info.ElementTypeId, ElementId = elementId, Element = element }); } // Update existing page zone element? if (info.PageZoneElementId != 0) { IElementSettings element = _elementService.New(tenantId, info.ElementTypeId); element.Name = info.Name; PageZoneElement pageZoneElement = pageZone.PageZoneElements.Where(e => e.PageZoneElementId == info.PageZoneElementId).First(); pageZoneElement.SortOrder = info.SortOrder; pageZoneElement.Element = element; newPageZoneElements.Add(pageZoneElement); } } // Do the page zone element update _pageRepository.UpdatePageZoneElements(tenantId, pageId, pageZoneId, newPageZoneElements, unitOfWork ?? localUnitOfWork); // Get elements that might be removed List <ElementKeyValue> elementsToDelete = new List <ElementKeyValue>(); foreach (PageZoneElement pageZoneElement in pageZone.PageZoneElements) { PageZoneElementInfo pageZoneElementInfo = pageZoneElements.Where(e => e.PageZoneElementId == pageZoneElement.PageZoneElementId).FirstOrDefault(); if (pageZoneElementInfo == null) { elementsToDelete.Add(new ElementKeyValue { ElementId = pageZoneElement.ElementId, ElementTypeId = pageZoneElement.ElementTypeId }); } } // Delete elements if no longer in use foreach (ElementKeyValue elementKeyValue in elementsToDelete) { if (!ElementInUse(tenantId, elementKeyValue.ElementId, unitOfWork ?? localUnitOfWork)) { _elementService.Delete(tenantId, elementKeyValue.ElementTypeId, elementKeyValue.ElementId, unitOfWork ?? localUnitOfWork); } } // Commit work if local unit of work in place if (localUnitOfWork != null) { localUnitOfWork.Commit(); } } catch (ValidationErrorException) { if (localUnitOfWork != null) { localUnitOfWork.Rollback(); } throw; } catch (Exception ex) { if (localUnitOfWork != null) { localUnitOfWork.Rollback(); } throw new ValidationErrorException(new ValidationError(null, ApplicationResource.UnexpectedErrorMessage), ex); } }
/// <summary> /// Creates a new page. /// </summary> /// <param name="tenantId">The website that created page will belong to.</param> /// <param name="parentPageId">Parent page (can be null if page has no parent - i.e. is home page, or if can be determined).</param> /// <param name="masterpageId">The master page that newly created page is based on.</param> /// <param name="pageInfo">If specified, used to override master page settings.</param> /// <param name="unitOfWork">Unit of work.</param> /// <returns>Newly allocated page identifier.</returns> public long Create(long tenantId, long?parentPageId, long masterPageId, PageInfo pageInfo, IUnitOfWork unitOfWork = null) { // Multiple actions are performed during page creation, so we need a unit of work to perform rollback if any failures occur IUnitOfWork localUnitOfWork = unitOfWork == null?_unitOfWorkFactory.CreateUnitOfWork() : null; try { // Get master page that will determine how new page is created MasterPage masterPage = _masterPageRepository.Read(tenantId, masterPageId, unitOfWork ?? localUnitOfWork); // Get valid parent pages List <Page> parentPages = null; if (masterPage.AncestorPageId.HasValue && masterPage.AncestorPageLevel.HasValue) { parentPages = ListMasterPageParentPages(masterPage, unitOfWork ?? localUnitOfWork); } // Validate the page create request (including checking that all or none of the image upload properties are specified) _pageValidator.ValidateCreate(tenantId, parentPageId, pageInfo, parentPages); // Set parent page identifier? if (parentPageId == null && masterPage.AncestorPageId.HasValue && masterPage.AncestorPageLevel.HasValue) { parentPageId = parentPages[0].PageId; } // Construct new page based on master page definition DateTime now = DateTime.UtcNow; Page page = new Page { Created = now, Description = pageInfo == null ? masterPage.PageDescription : pageInfo.Description, MasterPageId = masterPageId, Name = pageInfo == null ? masterPage.PageName : pageInfo.Name, Occurred = masterPage.HasOccurred ? DateTime.UtcNow.Date : (DateTime?)null, ParentPageId = parentPageId, Updated = now, TenantId = tenantId, PageZones = new List <PageZone>(), Tags = pageInfo == null ? new List <Tag>() : pageInfo.Tags, ImageTenantId = pageInfo == null ? null : pageInfo.ImageTenantId, ThumbnailImageUploadId = pageInfo == null ? null : pageInfo.ThumbnailImageUploadId, PreviewImageUploadId = pageInfo == null ? null : pageInfo.PreviewImageUploadId, ImageUploadId = pageInfo == null ? null : pageInfo.ImageUploadId }; // Construct page zones foreach (MasterPageZone masterPageZone in masterPage.MasterPageZones) { if (masterPageZone.AdminType != MasterPageZoneAdminType.Static) { PageZone pageZone = new PageZone { TenantId = tenantId, MasterPageId = masterPageId, MasterPageZoneId = masterPageZone.MasterPageZoneId, PageZoneElements = new List <PageZoneElement>() }; foreach (MasterPageZoneElement masterPageZoneElement in masterPageZone.MasterPageZoneElements) { long elementId = _elementService.Copy(tenantId, masterPageZoneElement.ElementId, tenantId, masterPageZoneElement.Element.ElementTypeId, unitOfWork ?? localUnitOfWork); PageZoneElement pageZoneElement = new PageZoneElement { TenantId = tenantId, ElementTypeId = masterPageZoneElement.Element.ElementTypeId, ElementId = elementId, Parent = pageZone }; if (masterPageZone.AdminType == MasterPageZoneAdminType.Configurable) { pageZoneElement.SortOrder = masterPageZoneElement.SortOrder; } if (masterPageZone.AdminType == MasterPageZoneAdminType.Editable) { pageZoneElement.MasterPageId = masterPageId; pageZoneElement.MasterPageZoneId = masterPageZone.MasterPageZoneId; pageZoneElement.MasterPageZoneElementId = masterPageZoneElement.MasterPageZoneElementId; } pageZone.PageZoneElements.Add(pageZoneElement); } page.PageZones.Add(pageZone); } } // Commit page images? if (page.ImageUploadId.HasValue) { _uploadService.Commit(page.ImageTenantId.Value, page.ThumbnailImageUploadId.Value, GetPageImageStorageHierarchy(), unitOfWork ?? localUnitOfWork); _uploadService.Commit(page.ImageTenantId.Value, page.PreviewImageUploadId.Value, GetPageImageStorageHierarchy(), unitOfWork ?? localUnitOfWork); _uploadService.Commit(page.ImageTenantId.Value, page.ImageUploadId.Value, GetPageImageStorageHierarchy(), unitOfWork ?? localUnitOfWork); } // Create page and return newly allocated page identifier page.PageId = _pageRepository.Create(page, unitOfWork ?? localUnitOfWork); // Update page tags? if (masterPage.Taggable) { _pageRepository.UpdateTags(page, unitOfWork ?? localUnitOfWork); } // Commit work if local unit of work in place, then return newly allocated page identifier if (localUnitOfWork != null) { localUnitOfWork.Commit(); } return(page.PageId); } catch (ValidationErrorException) { if (localUnitOfWork != null) { localUnitOfWork.Rollback(); } throw; } catch (Exception ex) { if (localUnitOfWork != null) { localUnitOfWork.Rollback(); } throw new ValidationErrorException(new ValidationError(null, ApplicationResource.UnexpectedErrorMessage), ex); } finally { if (localUnitOfWork != null) { localUnitOfWork.Dispose(); } } }
/// <summary> /// Validates update of page zone. /// </summary> /// <param name="masterPage">Master page associated with page whose zone is being updated.</param> /// <param name="page">Page whose zone is being updated.</param> /// <param name="pageZoneId">Identifier of page zone being updated.</param> /// <param name="pageZoneElements">Determines the content in a page zone.</param> /// <param name="keyPrefix">Validation key prefix.</param> public void ValidateUpdateZone(MasterPage masterPage, Page page, long pageZoneId, List <PageZoneElementInfo> pageZoneElements, string keyPrefix = null) { // Check that at least one item of content is specified if (pageZoneElements == null || pageZoneElements.Count == 0) { throw new ValidationErrorException(new ValidationError(null, PageResource.PageZoneElementsRequiredMessage)); } // Check page zone exists PageZone pageZone = page.PageZones.Where(z => z.PageZoneId == pageZoneId).FirstOrDefault(); if (pageZone == null) { throw new ValidationErrorException(new ValidationError(null, PageResource.PageZoneInvalidMessage)); } // Check master page zone exists MasterPageZone masterPageZone = masterPage.MasterPageZones.Where(z => z.MasterPageZoneId == pageZone.MasterPageZoneId).FirstOrDefault(); if (masterPageZone == null) { throw new ValidationErrorException(new ValidationError(null, PageResource.PageZoneInvalidMessage)); } // Check that master page zone is configurable if (masterPageZone.AdminType != MasterPageZoneAdminType.Configurable) { throw new ValidationErrorException(new ValidationError(null, PageResource.PageZoneInvalidMessage)); } // Check that element types in update request match allowed element types in zone configuration Dictionary <Guid, MasterPageZoneElementType> elementTypesById = masterPageZone.MasterPageZoneElementTypes.GroupBy(t => t.ElementTypeId).ToDictionary(t => t.Key, t => t.First()); foreach (PageZoneElementInfo pageZoneElementInfo in pageZoneElements) { if (!elementTypesById.ContainsKey(pageZoneElementInfo.ElementTypeId)) { throw new ValidationErrorException(new ValidationError(null, PageResource.PageZoneInvalidMessage)); } } // Check that element names are all specified foreach (PageZoneElementInfo pageZoneElementInfo in pageZoneElements) { if (string.IsNullOrWhiteSpace(pageZoneElementInfo.Name)) { throw new ValidationErrorException(new ValidationError(null, PageResource.PageZoneElementNameRequiredMessage)); } if (pageZoneElementInfo.Name.Trim().Length > ElementLengths.NameMaxLength) { throw new ValidationErrorException(new ValidationError(null, string.Format(PageResource.PageZoneElementNameMaxLengthMessage, "name", ElementLengths.NameMaxLength))); } pageZoneElementInfo.Name = pageZoneElementInfo.Name.Trim(); } // Check that all page zone elements specified are found in page zone foreach (PageZoneElementInfo pageZoneElementInfo in pageZoneElements) { if (pageZoneElementInfo.PageZoneElementId != 0) { PageZoneElement pageZoneElement = pageZone.PageZoneElements.Where(e => e.PageZoneElementId == pageZoneElementInfo.PageZoneElementId).FirstOrDefault(); if (pageZoneElement == null) { throw new ValidationErrorException(new ValidationError(null, PageResource.PageZoneElementInvalidMessage)); } } } }