Example #1
0
        /// <summary>
        /// Executes the specified request.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <returns>Execution result.</returns>
        public bool Execute(SitemapViewModel request)
        {
            var sitemap = Repository
                          .AsQueryable <Models.Sitemap>()
                          .Where(map => map.Id == request.Id)
                          .FetchMany(map => map.AccessRules)
                          .Distinct()
                          .ToList()
                          .First();

            var roles = new[] { RootModuleConstants.UserRoles.EditContent };

            if (CmsConfiguration.Security.AccessControlEnabled)
            {
                AccessControlService.DemandAccess(sitemap, Context.Principal, AccessLevel.ReadWrite, roles);
            }

            UnitOfWork.BeginTransaction();

            if (sitemap.AccessRules != null)
            {
                var rules = sitemap.AccessRules.ToList();
                rules.ForEach(sitemap.RemoveRule);
            }

            sitemap = Repository.Delete <Models.Sitemap>(request.Id, request.Version);

            UnitOfWork.Commit();

            Events.SitemapEvents.Instance.OnSitemapDeleted(sitemap);

            return(true);
        }
        /// <summary>
        /// Executes the specified request.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <returns></returns>
        public ClonePageWithLanguageViewModel Execute(GetPageForCloningWithLanguageCommandRequest request)
        {
            var pageFutureQuery = Repository
                                  .AsQueryable <PageProperties>()
                                  .Where(p => p.Id == request.PageId && !p.IsDeleted)
                                  .Select(p =>
                                          new
            {
                Model = new ClonePageWithLanguageViewModel
                {
                    PageId       = p.Id,
                    IsMasterPage = p.IsMasterPage
                },
                LanguageGroupIdentifier = p.LanguageGroupIdentifier,
                LanguageId = p.Language != null ? p.Language.Id : (System.Guid?)null
            })
                                  .ToFuture();

            var languagesFuture = languageService.GetLanguagesLookupValues();
            var result          = pageFutureQuery.FirstOne();
            var model           = result.Model;

            model.Languages = languagesFuture.ToList();
            model.ShowWarningAboutNoCultures = !model.Languages.Any();

            if (model.IsMasterPage)
            {
                AccessControlService.DemandAccess(Context.Principal, RootModuleConstants.UserRoles.Administration);
            }
            else
            {
                AccessControlService.DemandAccess(Context.Principal, RootModuleConstants.UserRoles.EditContent);
            }

            IList <UserAccessViewModel> accessRules;

            if (cmsConfiguration.Security.AccessControlEnabled)
            {
                accessRules = Repository
                              .AsQueryable <Root.Models.Page>()
                              .Where(x => x.Id == request.PageId && !x.IsDeleted)
                              .SelectMany(x => x.AccessRules)
                              .OrderBy(x => x.Identity)
                              .ToFuture()
                              .ToList()
                              .Select(x => new UserAccessViewModel(x))
                              .ToList();
            }
            else
            {
                accessRules = null;
            }

            model.AccessControlEnabled = cmsConfiguration.Security.AccessControlEnabled;
            model.UserAccessList       = accessRules;

            AddRemoveLanguages(model.Languages, result.LanguageGroupIdentifier, result.LanguageId);

            return(model);
        }
        /// <summary>
        /// Executes the specified request.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <returns><c>true</c> if succeeded, otherwise <c>false</c></returns>
        /// <exception cref="System.ComponentModel.DataAnnotations.ValidationException">If page status is not correct.</exception>
        public bool Execute(SavePagePublishStatusRequest request)
        {
            AccessControlService.DemandAccess(Context.Principal, RootModuleConstants.UserRoles.PublishContent);     // This would rise security exception if user has no access.

            var page = UnitOfWork.Session
                       .QueryOver <PageProperties>().Where(p => p.Id == request.PageId && !p.IsDeleted)
                       .SingleOrDefault <PageProperties>();

            if (page != null)
            {
                if (page.IsMasterPage)
                {
                    return(false);
                }

                var initialStatus = page.Status;

                if (page.Status == PageStatus.Draft || page.Status == PageStatus.Preview)
                {
                    var message    = string.Format(PagesGlobalization.SavePageStatus_PageIsInInappropriateStatus_Message);
                    var logMessage = string.Format("Draft/Preview page id={0} can not be published.", page.Id);
                    throw new ValidationException(() => message, logMessage);
                }

                if (request.IsPublished)
                {
                    page.Status      = PageStatus.Published;
                    page.PublishedOn = DateTime.Now;
                }
                else
                {
                    page.Status = PageStatus.Unpublished;
                }

                // NOTE: When transaction is enabled exception is raised from DefaultEntityTrackingService.DemandReadWriteRule() saying that DB timeouted...
                // UnitOfWork.BeginTransaction();

                Repository.Save(page);

                if (request.IsPublished)
                {
                    contentService.PublishDraftContent(page.Id);
                }

                UnitOfWork.Commit();

                if (page.Status != initialStatus)
                {
                    Events.PageEvents.Instance.OnPagePublishStatusChanged(page);
                }
            }

            return(true);
        }
        /// <summary>
        /// Executes the specified request.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <returns>
        /// <c>true</c>, if successfully restored.
        /// </returns>
        public bool Execute(RestorePageContentViewModel request)
        {
            var content = Repository
                          .AsQueryable <Root.Models.Content>(p => p.Id == request.PageContentId)
                          .Fetch(f => f.Original)
                          .First();

            var contentType = content.GetType();

            if (contentType == typeof(HtmlContentWidget) || contentType == typeof(ServerControlWidget))
            {
                AccessControlService.DemandAccess(Context.Principal, RootModuleConstants.UserRoles.Administration);
            }
            else
            {
                AccessControlService.DemandAccess(Context.Principal, RootModuleConstants.UserRoles.PublishContent);
                if (content.Original != null)
                {
                    var pageContent = Repository.AsQueryable <Root.Models.PageContent>()
                                      .Where(x => x.Content.Id == content.Original.Id && !x.IsDeleted)
                                      .Fetch(x => x.Page)
                                      .ThenFetchMany(x => x.AccessRules)
                                      .ToList()
                                      .FirstOrDefault();

                    if (pageContent != null)
                    {
                        AccessControlService.DemandAccess(pageContent.Page, Context.Principal, AccessLevel.ReadWrite);

                        // Check if user has confirmed the deletion of regions in content.
                        if (!request.IsUserConfirmed && pageContent.Page.IsMasterPage)
                        {
                            var hasAnyChildren = contentService.CheckIfContentHasDeletingChildren(pageContent.Page.Id, content.Original.Id, ((HtmlContent)content).Html);
                            if (hasAnyChildren)
                            {
                                var message    = PagesGlobalization.RestoreContent_ContentHasChildrenContents_RegionDeleteConfirmationMessage;
                                var logMessage = string.Format("User is trying to restore content with regions which has children contents. Confirmation is required. PageContentId: {0}, ContentId: {1}, PageId: {2}",
                                                               pageContent.Id, content.Id, pageContent.Page.Id);
                                throw new ConfirmationRequestException(() => message, logMessage);
                            }
                        }
                    }
                }
            }

            var restoredContent = contentService.RestoreContentFromArchive(content);

            UnitOfWork.Commit();

            Events.RootEvents.Instance.OnContentRestored(restoredContent);

            return(true);
        }
Example #5
0
        /// <summary>
        /// Executes this command.
        /// </summary>
        /// <param name="fileId">The file id.</param>
        /// <returns>The view model.</returns>
        public virtual FileViewModel Execute(Guid fileId)
        {
            var fileQuery = Repository.AsQueryable <MediaFile>().Where(f => f.Id == fileId && !f.IsDeleted);

            if (configuration.Security.AccessControlEnabled)
            {
                fileQuery = fileQuery.FetchMany(f => f.AccessRules);
            }

            var file = fileQuery.ToList().FirstOne();

            var model = new FileViewModel
            {
                Id            = file.Id.ToString(),
                Title         = file.Title,
                Description   = file.Description,
                Url           = fileUrlResolver.EnsureFullPathUrl(file.PublicUrl),
                Version       = file.Version.ToString(CultureInfo.InvariantCulture),
                FileName      = file.OriginalFileName,
                FileExtension = file.OriginalFileExtension,
                FileSize      = file.SizeAsText(),
                Tags          = tagService.GetMediaTagNames(fileId),
                Image         = file.Image == null || file.Image.IsDeleted ? null :
                                new ImageSelectorViewModel
                {
                    ImageId      = file.Image.Id,
                    ImageVersion = file.Image.Version,
                    ImageUrl     = fileUrlResolver.EnsureFullPathUrl(file.Image.PublicUrl),
                    ThumbnailUrl = fileUrlResolver.EnsureFullPathUrl(file.Image.PublicThumbnailUrl),
                    ImageTooltip = file.Image.Caption,
                    FolderId     = file.Image.Folder != null ? file.Image.Folder.Id : (Guid?)null
                },
                AccessControlEnabled = configuration.Security.AccessControlEnabled
            };

            model.Categories = categoryService.GetSelectedCategories <Media, MediaCategory>(fileId);

            if (configuration.Security.AccessControlEnabled)
            {
                AccessControlService.DemandAccess(file, Context.Principal, AccessLevel.Read);

                model.UserAccessList = file.AccessRules.Select(f => new UserAccessViewModel(f)).ToList();
                model.Url            = fileService.GetDownloadFileUrl(MediaType.File, model.Id.ToGuidOrDefault(), model.Url);

                SetIsReadOnly(model, ((IAccessSecuredObject)file).AccessRules);
            }

            model.CategoriesFilterKey  = file.GetCategorizableItemKey();
            model.CategoriesLookupList = categoryService.GetCategoriesLookupList(model.CategoriesFilterKey);

            return(model);
        }
        /// <summary>
        /// Executes the specified request.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <returns>The view model with list of history view models.</returns>
        public SitemapHistoryViewModel Execute(GetSitemapHistoryRequest request)
        {
            var currentVersionQuery = Repository.AsQueryable <Models.Sitemap>()
                                      .Where(map => map.Id == request.SitemapId);

            if (cmsConfiguration.Security.AccessControlEnabled)
            {
                currentVersionQuery = currentVersionQuery.FetchMany(f => f.AccessRules);
            }

            var currentVersion = currentVersionQuery.Distinct().ToList().First();

            if (cmsConfiguration.Security.AccessControlEnabled)
            {
                AccessControlService.DemandAccess(currentVersion, Context.Principal, AccessLevel.Read);
            }

            var history = new List <SitemapHistoryItem>
            {
                new SitemapHistoryItem
                {
                    Id                      = currentVersion.Id,
                    Version                 = currentVersion.Version,
                    SitemapTitle            = currentVersion.Title,
                    StatusName              = NavigationGlobalization.SitemapStatus_Active,
                    ArchivedOn              = null,
                    ArchivedByUser          = null,
                    CanCurrentUserRestoreIt = false
                }
            };

            var historyEntities = sitemapService.GetSitemapHistory(request.SitemapId);

            history.AddRange(
                historyEntities.Select(
                    archive =>
                    new SitemapHistoryItem
            {
                Id                      = archive.Id,
                Version                 = archive.Version,
                SitemapTitle            = archive.Title,
                StatusName              = NavigationGlobalization.SitemapStatus_Archived,
                ArchivedOn              = archive.CreatedOn,
                ArchivedByUser          = archive.CreatedByUser,
                CanCurrentUserRestoreIt = true
            }).ToList());

            history = AddSortAndPaging(history, request);

            return(new SitemapHistoryViewModel(history, request, history.Count, request.SitemapId));
        }
Example #7
0
        /// <summary>
        /// Executes the specified request.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <returns>Execution result.</returns>
        public SitemapNodeViewModel Execute(SitemapNodeViewModel request)
        {
            var sitemap =
                Repository.AsQueryable <Models.Sitemap>()
                .Where(map => map.Id == request.SitemapId)
                .FetchMany(f => f.AccessRules)
                .FetchMany(map => map.Nodes)
                .ThenFetch(mapNode => mapNode.Page)
                .FetchMany(map => map.Nodes)
                .ThenFetch(mapNode => mapNode.Translations)
                .Distinct()
                .ToList()
                .First();

            if (CmsConfiguration.Security.AccessControlEnabled)
            {
                AccessControlService.DemandAccess(sitemap, Context.Principal, AccessLevel.ReadWrite);
            }

            UnitOfWork.BeginTransaction();

            if (!request.SitemapId.HasDefaultValue())
            {
                SitemapService.ArchiveSitemap(sitemap);
            }

            bool updatedInDB;
            var  node = SitemapService.SaveNode(out updatedInDB, sitemap, request.Id, request.Version, request.Url, request.Title, request.Macro, request.PageId, request.UsePageTitleAsNodeTitle, request.DisplayOrder, request.ParentId);

            UnitOfWork.Commit();

            if (updatedInDB)
            {
                if (request.Id.HasDefaultValue())
                {
                    Events.SitemapEvents.Instance.OnSitemapNodeCreated(node);
                }
                else
                {
                    Events.SitemapEvents.Instance.OnSitemapNodeUpdated(node);
                }

                Events.SitemapEvents.Instance.OnSitemapUpdated(node.Sitemap);
            }

            return(new SitemapNodeViewModel
            {
                Id = node.Id,
                Version = node.Version
            });
        }
        /// <summary>
        /// Executes the specified request.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <returns>
        ///   <c>true</c>, if successfully restored.
        /// </returns>
        public SiteSettingSitemapViewModel Execute(SitemapRestoreViewModel request)
        {
            var archive =
                Repository.AsQueryable <SitemapArchive>()
                .Where(sitemapArchive => sitemapArchive.Id == request.SitemapVersionId)
                .Fetch(sitemapArchive => sitemapArchive.Sitemap)
                .ThenFetchMany(f => f.AccessRules)
                .Fetch(sitemapArchive => sitemapArchive.Sitemap)
                .ThenFetchMany(map => map.Nodes)
                .ThenFetch(node => node.Page)
                .Fetch(sitemapArchive => sitemapArchive.Sitemap)
                .ThenFetchMany(map => map.Nodes)
                .ThenFetchMany(node => node.Translations)
                .Distinct()
                .ToList()
                .First();

            if (CmsConfiguration.Security.AccessControlEnabled)
            {
                AccessControlService.DemandAccess(archive.Sitemap, Context.Principal, AccessLevel.ReadWrite);
            }

// TODO: do we need a such confirmation?
//            // Check if user has confirmed restoration if exist nodes linked to deleted pages.
//            if (!request.IsUserConfirmed)
//            {
//                var hasDeletedPages = SitemapService.CheckIfArchiveHasDeletedPages(archive);
//                if (hasDeletedPages)
//                {
//                    var message = NavigationGlobalization.RestoreSitemap_ArchiveHasDeletedPages_RestoreConfirmationMessage;
//                    var logMessage = string.Format("User is trying to restore sitemap which has deleted pages. Confirmation is required. archiveId: {0}, sitemapId: {1}", archive.Id, archive.Sitemap.Id);
//                    throw new ConfirmationRequestException(() => message, logMessage);
//                }
//            }

            UnitOfWork.BeginTransaction();

            SitemapService.ArchiveSitemap(archive.Sitemap);
            var restoredSitemap = SitemapService.RestoreSitemapFromArchive(archive);

            UnitOfWork.Commit();

            Events.SitemapEvents.Instance.OnSitemapRestored(restoredSitemap);

            return(new SiteSettingSitemapViewModel
            {
                Id = restoredSitemap.Id,
                Title = restoredSitemap.Title,
                Version = restoredSitemap.Version
            });
        }
Example #9
0
        public MultiFileUploadViewModel Execute(GetMultiFileUploadRequest request)
        {
            var model = new MultiFileUploadViewModel();

            model.RootFolderId     = request.FolderId;
            model.RootFolderType   = request.Type;
            model.ReuploadMediaId  = request.ReuploadMediaId;
            model.SelectedFolderId = Guid.Empty;
            model.UploadedFiles    = null;

            var foldersQuery = Repository.AsQueryable <MediaFolder>().Where(f => f.Type == request.Type);

            if (request.FolderId == Guid.Empty)
            {
                foldersQuery = foldersQuery.Where(f => f.Folder == null);
            }
            else
            {
                foldersQuery = foldersQuery.Where(f => f.Folder.Id == request.FolderId);
            }

            model.Folders = foldersQuery
                            .OrderBy(f => f.Title)
                            .Select(f => new Tuple <Guid, string>(f.Id, f.Title))
                            .ToList();

            model.Folders.Insert(0, new Tuple <Guid, string>(Guid.Empty, ".."));

            if (request.Type != MediaType.Image && cmsConfiguration.Security.AccessControlEnabled)
            {
                if (!request.ReuploadMediaId.HasDefaultValue())
                {
                    var media = Repository.AsQueryable <Media>(m => m.Id == request.ReuploadMediaId).FirstOne();
                    var file  = media as MediaFile;
                    if (file != null)
                    {
                        AccessControlService.DemandAccess(file, Context.Principal, AccessLevel.ReadWrite);
                    }
                }
                else
                {
                    var principal = SecurityService.GetCurrentPrincipal();
                    model.UserAccessList       = AccessControlService.GetDefaultAccessList(principal).Cast <UserAccessViewModel>().ToList();
                    model.AccessControlEnabled = cmsConfiguration.Security.AccessControlEnabled;
                }
            }
            return(model);
        }
Example #10
0
        /// <summary>
        /// Executes the specified request.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <returns></returns>
        /// <exception cref="System.NotImplementedException"></exception>
        public ClonePageViewModel Execute(Guid request)
        {
            var pageQuery = Repository
                            .AsQueryable <PageProperties>()
                            .Where(p => p.Id == request && !p.IsDeleted)
                            .Select(p => new ClonePageViewModel
            {
                PageId       = p.Id,
                IsMasterPage = p.IsMasterPage
            })
                            .ToFuture();

            ClonePageViewModel          model;
            IList <UserAccessViewModel> accessRules;

            if (cmsConfiguration.Security.AccessControlEnabled)
            {
                accessRules = Repository
                              .AsQueryable <Root.Models.Page>()
                              .Where(x => x.Id == request && !x.IsDeleted)
                              .SelectMany(x => x.AccessRules)
                              .OrderBy(x => x.Identity)
                              .ToFuture()
                              .ToList()
                              .Select(x => new UserAccessViewModel(x))
                              .ToList();
            }
            else
            {
                accessRules = null;
            }

            model = pageQuery.FirstOne();
            model.AccessControlEnabled = cmsConfiguration.Security.AccessControlEnabled;
            model.UserAccessList       = accessRules;

            if (model.IsMasterPage)
            {
                AccessControlService.DemandAccess(Context.Principal, RootModuleConstants.UserRoles.Administration);
            }
            else
            {
                AccessControlService.DemandAccess(Context.Principal, RootModuleConstants.UserRoles.EditContent);
            }

            return(model);
        }
Example #11
0
        /// <summary>
        /// Executes the specified request.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <returns>Media preview.</returns>
        public MediaPreviewViewModel Execute(Guid request)
        {
            var response = new MediaPreviewViewModel();

            var media = Repository
                        .AsQueryable <Media>(m => m.Id == request)
                        .Fetch(m => m.Original)
                        .FirstOne();

            var image = media as MediaImage;

            if (image != null)
            {
                response.AddProperty(MediaGlobalization.MediaHistory_Preview_Properties_Caption, image.Caption);
                response.AddProperty(MediaGlobalization.MediaHistory_Preview_Properties_ImageDimensions, string.Format("{0} x {1}", image.Width, image.Height));
                response.AddProperty(MediaGlobalization.MediaHistory_Preview_Properties_PublicThumbnailUrl, fileUrlResolver.EnsureFullPathUrl(image.PublicThumbnailUrl), true);

                response.AddProperty(image.Caption, fileUrlResolver.EnsureFullPathUrl(image.PublicUrl), isImageUrl: true);
            }

            var file = media as MediaFile;

            if (file != null)
            {
                if (cmsConfiguration.Security.AccessControlEnabled)
                {
                    AccessControlService.DemandAccess(file.Original as MediaFile ?? file, Context.Principal, AccessLevel.Read);
                }

                var publicUrl = fileService.GetDownloadFileUrl(MediaType.File, file.Id, fileUrlResolver.EnsureFullPathUrl(file.PublicUrl));

                response.AddProperty(MediaGlobalization.MediaHistory_Preview_Properties_Title, file.Title);
                response.AddProperty(MediaGlobalization.MediaHistory_Preview_Properties_Description, file.Description);
                response.AddProperty(MediaGlobalization.MediaHistory_Preview_Properties_FileSize, file.SizeAsText());
                response.AddProperty(MediaGlobalization.MediaHistory_Preview_Properties_PublicUrl, publicUrl, true);

                if (media.Image != null)
                {
                    response.AddProperty(media.Image.Caption, fileUrlResolver.EnsureFullPathUrl(media.Image.PublicUrl), isImageUrl: true);
                }
            }

            response.Properties = response.Properties.OrderByDescending(o => o.Title).ToList();

            return(response);
        }
Example #12
0
        /// <summary>
        /// Executes the specified id.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <returns>
        /// Response type of <see cref="DownloadFileCommandResponse" />
        /// </returns>
        /// <exception cref="System.Web.HttpException">403;Access Forbidden</exception>
        public DownloadFileCommandResponse Execute(Guid id)
        {
            // Load file
            var fileQuery = Repository.AsQueryable <MediaFile>(f => f.Id == id && !f.IsDeleted);

            if (cmsConfiguration.Security.AccessControlEnabled)
            {
                fileQuery = fileQuery.FetchMany(f => f.AccessRules);
            }

            var file = fileQuery.ToList().FirstOne();

            // Access control is ALWAYS disabled for images
            var accesControlEnabled = cmsConfiguration.Security.AccessControlEnabled && file.Type != MediaType.Image;

            if (!accesControlEnabled || !storageService.SecuredUrlsEnabled)
            {
                return(new DownloadFileCommandResponse {
                    RedirectUrl = fileUrlResolver.EnsureFullPathUrl(file.PublicUrl)
                });
            }

            // Get download URL with security token
            try
            {
                AccessControlService.DemandAccess(file, Context.Principal, AccessLevel.Read);
            }
            catch (SecurityException)
            {
                return(new DownloadFileCommandResponse {
                    HasNoAccess = true
                });
            }

            var url = storageService.GetSecuredUrl(file.FileUri);

            return(new DownloadFileCommandResponse {
                RedirectUrl = url
            });
        }
        /// <summary>
        /// Executes the specified request.
        /// </summary>
        /// <param name="pageContentId">The id of the archived page content version.</param>
        /// <returns>True, if restore is successfull</returns>
        public bool Execute(Guid pageContentId)
        {
            var content = Repository
                          .AsQueryable <Root.Models.Content>(p => p.Id == pageContentId)
                          .Fetch(f => f.Original)
                          .First();

            var contentType = content.GetType();

            if (contentType == typeof(HtmlContentWidget) || contentType == typeof(ServerControlWidget))
            {
                AccessControlService.DemandAccess(Context.Principal, RootModuleConstants.UserRoles.Administration);
            }
            else
            {
                AccessControlService.DemandAccess(Context.Principal, RootModuleConstants.UserRoles.PublishContent);
                if (content.Original != null)
                {
                    var pageContent = Repository.AsQueryable <Root.Models.PageContent>()
                                      .Where(x => x.Content.Id == content.Original.Id && !x.IsDeleted)
                                      .Fetch(x => x.Page)
                                      .ThenFetchMany(x => x.AccessRules)
                                      .ToList()
                                      .FirstOrDefault();

                    if (pageContent != null)
                    {
                        AccessControlService.DemandAccess(pageContent.Page, Context.Principal, AccessLevel.ReadWrite);
                    }
                }
            }

            contentService.RestoreContentFromArchive(content);

            UnitOfWork.Commit();

            return(true);
        }
Example #14
0
        /// <summary>
        /// Executes the specified request.
        /// </summary>
        /// <param name="request">The request.</param>
        public SitemapViewModel Execute(SitemapViewModel request)
        {
            createdNodes.Clear();
            updatedNodes.Clear();
            deletedNodes.Clear();

            var createNew = request.Id.HasDefaultValue();

            Models.Sitemap sitemap;

            if (!createNew)
            {
                var sitemapQuery = Repository.AsQueryable <Models.Sitemap>().Where(s => s.Id == request.Id);

                if (CmsConfiguration.Security.AccessControlEnabled)
                {
                    sitemapQuery = sitemapQuery.FetchMany(f => f.AccessRules);
                }

                sitemap = sitemapQuery.ToList().First();

                if (CmsConfiguration.Security.AccessControlEnabled)
                {
                    AccessControlService.DemandAccess(sitemap, Context.Principal, AccessLevel.ReadWrite);
                }
            }
            else
            {
                sitemap = new Models.Sitemap()
                {
                    AccessRules = new List <AccessRule>()
                };
            }

            var nodeList = !createNew?Repository.AsQueryable <SitemapNode>()
                           .Where(node => node.Sitemap.Id == sitemap.Id)
                           .ToFuture()
                               : new List <SitemapNode>();

            var translationList = !createNew
                                      ? Repository.AsQueryable <SitemapNodeTranslation>()
                                  .Where(t => t.Node.Sitemap.Id == sitemap.Id)
                                  .Fetch(t => t.Node)
                                  .ToFuture()
                                      : new List <SitemapNodeTranslation>();

            UnitOfWork.BeginTransaction();

            if (!createNew)
            {
                SitemapService.ArchiveSitemap(request.Id);
            }

            if (CmsConfiguration.Security.AccessControlEnabled)
            {
                sitemap.AccessRules.RemoveDuplicateEntities();

                var accessRules = request.UserAccessList != null?request.UserAccessList.Cast <IAccessRule>().ToList() : null;

                AccessControlService.UpdateAccessControl(sitemap, accessRules);
            }

            sitemap.Title   = request.Title;
            sitemap.Version = request.Version;
            Repository.Save(sitemap);

            SaveNodeList(sitemap, request.RootNodes, null, nodeList.ToList(), translationList.ToList());

            IList <Tag> newTags;

            TagService.SaveTags(sitemap, request.Tags, out newTags);


            UnitOfWork.Commit();

            foreach (var node in createdNodes)
            {
                Events.SitemapEvents.Instance.OnSitemapNodeCreated(node);
            }

            foreach (var node in updatedNodes)
            {
                Events.SitemapEvents.Instance.OnSitemapNodeUpdated(node);
            }

            foreach (var node in deletedNodes)
            {
                Events.SitemapEvents.Instance.OnSitemapNodeDeleted(node);
            }

            if (createNew)
            {
                Events.SitemapEvents.Instance.OnSitemapCreated(sitemap);
            }
            else
            {
                Events.SitemapEvents.Instance.OnSitemapUpdated(sitemap);
            }

            Events.RootEvents.Instance.OnTagCreated(newTags);

            return(GetModelMainData(sitemap));
        }
Example #15
0
        /// <summary>
        /// Executes the specified request.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <returns></returns>
        /// <exception cref="ConcurrentDataException"></exception>
        /// <exception cref="System.ComponentModel.DataAnnotations.ValidationException">
        /// </exception>
        public virtual bool Execute(DeletePageViewModel request)
        {
            var page = Repository.First <PageProperties>(request.PageId);

            if (page.Version != request.Version)
            {
                throw new ConcurrentDataException(page);
            }

            if (page.IsMasterPage && Repository.AsQueryable <MasterPage>(mp => mp.Master == page).Any())
            {
                var message    = PagesGlobalization.DeletePageCommand_MasterPageHasChildren_Message;
                var logMessage = string.Format("Failed to delete page. Page is selected as master page. Id: {0} Url: {1}", page.Id, page.PageUrl);
                throw new ValidationException(() => message, logMessage);
            }

            request.RedirectUrl = urlService.FixUrl(request.RedirectUrl);

            if (request.UpdateSitemap)
            {
                AccessControlService.DemandAccess(Context.Principal, RootModuleConstants.UserRoles.EditContent);
            }

            var sitemaps     = new Dictionary <Models.Sitemap, bool>();
            var sitemapNodes = sitemapService.GetNodesByPage(page);

            if (request.UpdateSitemap)
            {
                sitemapNodes.Select(node => node.Sitemap)
                .Distinct()
                .ToList()
                .ForEach(
                    sitemap =>
                    sitemaps.Add(
                        sitemap,
                        !cmsConfiguration.Security.AccessControlEnabled || AccessControlService.GetAccessLevel(sitemap, Context.Principal) == AccessLevel.ReadWrite));

                foreach (var node in sitemapNodes)
                {
                    if (sitemaps[node.Sitemap] && node.ChildNodes.Count > 0)
                    {
                        var logMessage = string.Format("In {0} sitemap node {1} has {2} child nodes.", node.Sitemap.Id, node.Id, node.ChildNodes.Count);
                        throw new ValidationException(() => PagesGlobalization.DeletePageCommand_SitemapNodeHasChildNodes_Message, logMessage);
                    }
                }
            }

            UnitOfWork.BeginTransaction();

            IList <SitemapNode> updatedNodes = new List <SitemapNode>();
            IList <SitemapNode> deletedNodes = new List <SitemapNode>();

            if (sitemapNodes != null)
            {
                // Archive sitemaps before update.
                sitemaps.Select(pair => pair.Key).ToList().ForEach(sitemap => sitemapService.ArchiveSitemap(sitemap.Id));
                foreach (var node in sitemapNodes)
                {
                    if (!node.IsDeleted)
                    {
                        if (request.UpdateSitemap && sitemaps[node.Sitemap])
                        {
                            // Delete sitemap node.
                            sitemapService.DeleteNode(node, ref deletedNodes);
                        }
                        else
                        {
                            // Unlink sitemap node.
                            if (node.Page != null && node.Page.Id == page.Id)
                            {
                                node.Page    = null;
                                node.Url     = page.PageUrl;
                                node.UrlHash = page.PageUrlHash;
                                Repository.Save(node);
                                updatedNodes.Add(node);
                            }
                        }
                    }
                }
            }

            if (!string.IsNullOrWhiteSpace(request.RedirectUrl))
            {
                if (string.Equals(page.PageUrl, request.RedirectUrl, StringComparison.OrdinalIgnoreCase))
                {
                    var logMessage = string.Format("Circular redirect loop from url {0} to url {0}.", request.RedirectUrl);
                    throw new ValidationException(() => PagesGlobalization.ValidatePageUrlCommand_SameUrlPath_Message, logMessage);
                }

                // Validate url
                if (!urlService.ValidateUrl(request.RedirectUrl))
                {
                    var logMessage = string.Format("Invalid redirect url {0}.", request.RedirectUrl);
                    throw new ValidationException(() => PagesGlobalization.ValidatePageUrlCommand_InvalidUrlPath_Message, logMessage);
                }

                string patternsValidationMessage;
                if (!urlService.ValidateUrlPatterns(request.RedirectUrl, out patternsValidationMessage, PagesGlobalization.DeletePage_RedirectUrl_Name))
                {
                    var logMessage = string.Format("{0}. URL: {1}.", patternsValidationMessage, request.RedirectUrl);
                    throw new ValidationException(() => patternsValidationMessage, logMessage);
                }

                var redirect = redirectService.GetPageRedirect(page.PageUrl);
                if (redirect != null)
                {
                    redirect.RedirectUrl = request.RedirectUrl;
                }
                else
                {
                    redirect = redirectService.CreateRedirectEntity(page.PageUrl, request.RedirectUrl);
                }

                if (redirect != null)
                {
                    Repository.Save(redirect);
                }
            }

            // Delete child entities.
            if (page.PageTags != null)
            {
                foreach (var pageTag in page.PageTags)
                {
                    Repository.Delete(pageTag);
                }
            }

            if (page.PageContents != null)
            {
                foreach (var pageContent in page.PageContents)
                {
                    Repository.Delete(pageContent);
                }
            }

            if (page.Options != null)
            {
                foreach (var option in page.Options)
                {
                    Repository.Delete(option);
                }
            }

            if (page.AccessRules != null)
            {
                var rules = page.AccessRules.ToList();
                rules.ForEach(page.RemoveRule);
            }

            if (page.MasterPages != null)
            {
                foreach (var master in page.MasterPages)
                {
                    Repository.Delete(master);
                }
            }

            // Delete page
            Repository.Delete <Root.Models.Page>(request.PageId, request.Version);

            // Commit
            UnitOfWork.Commit();

            var updatedSitemaps = new List <Models.Sitemap>();

            foreach (var node in updatedNodes)
            {
                Events.SitemapEvents.Instance.OnSitemapNodeUpdated(node);
                if (!updatedSitemaps.Contains(node.Sitemap))
                {
                    updatedSitemaps.Add(node.Sitemap);
                }
            }

            foreach (var node in deletedNodes)
            {
                Events.SitemapEvents.Instance.OnSitemapNodeDeleted(node);
                if (!updatedSitemaps.Contains(node.Sitemap))
                {
                    updatedSitemaps.Add(node.Sitemap);
                }
            }

            foreach (var updatedSitemap in updatedSitemaps)
            {
                Events.SitemapEvents.Instance.OnSitemapUpdated(updatedSitemap);
            }

            // Notifying, that page is deleted.
            Events.PageEvents.Instance.OnPageDeleted(page);

            if (sitemaps.Any(tuple => !tuple.Value))
            {
                // Some sitemaps where skipped, because user has no permission to edit.
                Context.Messages.AddSuccess(PagesGlobalization.DeletePage_SitemapSkipped_Message);
            }

            return(true);
        }
Example #16
0
        /// <summary>
        /// Executes the specified request.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <returns>Save response.</returns>
        /// <exception cref="CmsException">Failed to save page properties.</exception>
        public SavePageResponse Execute(EditPagePropertiesViewModel request)
        {
            UnitOfWork.BeginTransaction();

            var pageQuery = Repository
                            .AsQueryable <PageProperties>(p => p.Id == request.Id)
                            .FetchMany(p => p.Options)
                            .Fetch(p => p.Layout).ThenFetchMany(l => l.LayoutOptions)
                            .AsQueryable();

            if (cmsConfiguration.Security.AccessControlEnabled)
            {
                pageQuery = pageQuery.FetchMany(f => f.AccessRules);
            }

            var page = pageQuery.ToList().FirstOne();

            if (cmsConfiguration.Security.AccessControlEnabled)
            {
                AccessControlService.DemandAccess(page, Context.Principal, AccessLevel.ReadWrite, RootModuleConstants.UserRoles.EditContent, RootModuleConstants.UserRoles.PublishContent);
            }
            else
            {
                AccessControlService.DemandAccess(Context.Principal, RootModuleConstants.UserRoles.EditContent, RootModuleConstants.UserRoles.PublishContent);
            }

            Models.Redirect redirectCreated  = null;
            bool            initialSeoStatus = page.HasSEO;

            request.PageUrl = urlService.FixUrl(request.PageUrl);

            if (!string.Equals(page.PageUrl, request.PageUrl))
            {
                pageService.ValidatePageUrl(request.PageUrl, request.Id);
                if (request.RedirectFromOldUrl)
                {
                    var redirect = redirectService.CreateRedirectEntity(page.PageUrl, request.PageUrl);
                    if (redirect != null)
                    {
                        Repository.Save(redirect);
                        redirectCreated = redirect;
                    }
                }

                page.NodeCountInSitemap = request.UpdateSitemap
                    ? sitemapService.ChangeUrl(page.PageUrl, request.PageUrl)
                    : sitemapService.NodesWithUrl(request.PageUrl);

                page.PageUrl = request.PageUrl;
            }

            page.PageUrlHash = page.PageUrl.UrlHash();
            page.Layout      = Repository.AsProxy <Root.Models.Layout>(request.TemplateId);
            page.Category    = request.CategoryId.HasValue ? Repository.AsProxy <CategoryEntity>(request.CategoryId.Value) : null;
            page.Title       = request.PageName;
            page.CustomCss   = request.PageCSS;
            page.CustomJS    = request.PageJavascript;

            var publishDraftContent = false;

            if (request.CanPublishPage)
            {
                AccessControlService.DemandAccess(Context.Principal, RootModuleConstants.UserRoles.PublishContent);

                if (request.IsPagePublished)
                {
                    if (page.Status != PageStatus.Published)
                    {
                        page.Status         = PageStatus.Published;
                        page.PublishedOn    = DateTime.Now;
                        publishDraftContent = true;
                    }
                }
                else
                {
                    page.Status = PageStatus.Unpublished;
                }
            }

            page.UseNoFollow     = request.UseNoFollow;
            page.UseNoIndex      = request.UseNoIndex;
            page.UseCanonicalUrl = request.UseCanonicalUrl;
            page.IsArchived      = request.IsArchived;
            page.Version         = request.Version;

            page.Image          = request.Image != null && request.Image.ImageId.HasValue ? Repository.AsProxy <MediaImage>(request.Image.ImageId.Value) : null;
            page.SecondaryImage = request.SecondaryImage != null && request.SecondaryImage.ImageId.HasValue ? Repository.AsProxy <MediaImage>(request.SecondaryImage.ImageId.Value) : null;
            page.FeaturedImage  = request.FeaturedImage != null && request.FeaturedImage.ImageId.HasValue ? Repository.AsProxy <MediaImage>(request.FeaturedImage.ImageId.Value) : null;

            var optionValues  = page.Options.Distinct();
            var parentOptions = page.Layout.LayoutOptions.Distinct();

            optionService.SaveOptionValues(request.OptionValues, optionValues, parentOptions, () => new PageOption {
                Page = page
            });

            if (cmsConfiguration.Security.AccessControlEnabled)
            {
                page.AccessRules.RemoveDuplicateEntities();

                var accessRules = request.UserAccessList != null?request.UserAccessList.Cast <IAccessRule>().ToList() : null;

                accessControlService.UpdateAccessControl(page, accessRules);
            }

            Repository.Save(page);

            // Save tags
            IList <Tag> newTags;

            tagService.SavePageTags(page, request.Tags, out newTags);

            if (publishDraftContent)
            {
                contentService.PublishDraftContent(page.Id);
            }

            UnitOfWork.Commit();

            // Notify about page properties change.
            Events.PageEvents.Instance.OnPagePropertiesChanged(page);

            // Notify about redirect creation.
            if (redirectCreated != null)
            {
                Events.PageEvents.Instance.OnRedirectCreated(redirectCreated);
            }

            // Notify about SEO status change.
            if (initialSeoStatus != page.HasSEO)
            {
                Events.PageEvents.Instance.OnPageSeoStatusChanged(page);
            }

            // Notify about new tags.
            Events.RootEvents.Instance.OnTagCreated(newTags);

            return(new SavePageResponse(page));
        }
Example #17
0
        public SavePageHtmlContentResponse Execute(PageContentViewModel request)
        {
            if (request.DesirableStatus == ContentStatus.Published)
            {
                AccessControlService.DemandAccess(Context.Principal, RootModuleConstants.UserRoles.PublishContent);
            }

            if (request.Id == default(Guid) || request.DesirableStatus != ContentStatus.Published)
            {
                AccessControlService.DemandAccess(Context.Principal, RootModuleConstants.UserRoles.EditContent);
            }

            PageContent pageContent;
            var         isNew = request.Id.HasDefaultValue();

            if (!isNew)
            {
                var query = Repository
                            .AsQueryable <PageContent>()
                            .Where(f => f.Id == request.Id && !f.IsDeleted)
                            .AsQueryable();

                if (!request.IsUserConfirmed)
                {
                    query = query.Fetch(f => f.Page);
                }

                if (configuration.Security.AccessControlEnabled)
                {
                    query = query.Fetch(f => f.Page).ThenFetchMany(f => f.AccessRules);
                }

                pageContent = query.ToList().FirstOne();

                // Check if user has confirmed the deletion of content
                if (!request.IsUserConfirmed && pageContent.Page.IsMasterPage)
                {
                    var hasAnyChildren = contentService.CheckIfContentHasDeletingChildren(request.PageId, request.ContentId, request.PageContent);
                    if (hasAnyChildren)
                    {
                        var message    = PagesGlobalization.SaveContent_ContentHasChildrenContents_RegionDeleteConfirmationMessage;
                        var logMessage = string.Format("User is trying to delete content regions which has children contents. Confirmation is required. PageContentId: {0}, ContentId: {1}, PageId: {2}",
                                                       request.Id, request.ContentId, request.PageId);
                        throw new ConfirmationRequestException(() => message, logMessage);
                    }
                }
            }
            else
            {
                pageContent       = new PageContent();
                pageContent.Order = contentService.GetPageContentNextOrderNumber(request.PageId);

                if (configuration.Security.AccessControlEnabled)
                {
                    pageContent.Page = Repository
                                       .AsQueryable <Root.Models.Page>(p => p.Id == request.PageId)
                                       .FetchMany(p => p.AccessRules)
                                       .ToList()
                                       .FirstOne();
                }
            }

            // Deman access
            if (configuration.Security.AccessControlEnabled)
            {
                AccessControlService.DemandAccess(pageContent.Page, Context.Principal, AccessLevel.ReadWrite);
            }

            // Get page as proxy, if page is not retrieved yet
            if (!configuration.Security.AccessControlEnabled)
            {
                pageContent.Page = Repository.AsProxy <Root.Models.Page>(request.PageId);
            }
            pageContent.Region = Repository.AsProxy <Region>(request.RegionId);

            var contentToSave = new HtmlContent
            {
                Id               = request.ContentId,
                ActivationDate   = request.LiveFrom,
                ExpirationDate   = TimeHelper.FormatEndDate(request.LiveTo),
                Name             = request.ContentName,
                Html             = request.PageContent ?? string.Empty,
                UseCustomCss     = request.EnabledCustomCss,
                CustomCss        = request.CustomCss,
                UseCustomJs      = request.EanbledCustomJs,
                CustomJs         = request.CustomJs,
                EditInSourceMode = request.EditInSourceMode
            };

            // Preserve content if user is not authorized to change it.
            if (!SecurityService.IsAuthorized(RootModuleConstants.UserRoles.EditContent) && request.Id != default(Guid))
            {
                var originalContent  = Repository.First <HtmlContent>(request.ContentId);
                var contentToPublish = (HtmlContent)(originalContent.History != null
                    ? originalContent.History.FirstOrDefault(c => c.Status == ContentStatus.Draft) ?? originalContent
                    : originalContent);

                contentToSave.Name             = contentToPublish.Name;
                contentToSave.Html             = contentToPublish.Html;
                contentToSave.UseCustomCss     = contentToPublish.UseCustomCss;
                contentToSave.CustomCss        = contentToPublish.CustomCss;
                contentToSave.UseCustomJs      = contentToPublish.UseCustomJs;
                contentToSave.CustomJs         = contentToPublish.CustomJs;
                contentToSave.EditInSourceMode = contentToPublish.EditInSourceMode;
            }

            UnitOfWork.BeginTransaction();
            pageContent.Content = contentService.SaveContentWithStatusUpdate(
                contentToSave,
                request.DesirableStatus);

            if (pageContent.Content.ContentRegions != null &&
                pageContent.Content.ContentRegions.Count > 0)
            {
                if (!pageContent.Page.IsMasterPage)
                {
                    var logMessage = string.Format("Dynamic regions are not allowed. Page: {0}, Content: {1}", pageContent.Page, pageContent.Id);
                    throw new ValidationException(() => PagesGlobalization.SaveContent_DynamicRegionsAreNotAllowed_Message, logMessage);
                }
            }

            Repository.Save(pageContent);
            UnitOfWork.Commit();

            // Notify.
            if (request.DesirableStatus != ContentStatus.Preview)
            {
                if (isNew)
                {
                    Events.PageEvents.Instance.OnPageContentInserted(pageContent);
                    Events.PageEvents.Instance.OnHtmlContentCreated((HtmlContent)pageContent.Content);
                }
                else
                {
                    Events.PageEvents.Instance.OnHtmlContentUpdated((HtmlContent)pageContent.Content);
                }
            }

            return(new SavePageHtmlContentResponse {
                PageContentId = pageContent.Id,
                ContentId = pageContent.Content.Id,
                RegionId = pageContent.Region.Id,
                PageId = pageContent.Page.Id
            });
        }
Example #18
0
        /// <summary>
        /// Executes the specified request.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <returns>Blog post view model</returns>
        public SaveBlogPostCommandResponse Execute(BlogPostViewModel request)
        {
            if (request.DesirableStatus == ContentStatus.Published)
            {
                AccessControlService.DemandAccess(Context.Principal, RootModuleConstants.UserRoles.PublishContent);
            }

            var layout      = LoadLayout();
            var region      = LoadRegion();
            var isNew       = request.Id.HasDefaultValue();
            var userCanEdit = false;

            if (isNew || request.DesirableStatus != ContentStatus.Published)
            {
                AccessControlService.DemandAccess(Context.Principal, RootModuleConstants.UserRoles.EditContent);
                userCanEdit = true;
            }
            else
            {
                userCanEdit = SecurityService.IsAuthorized(RootModuleConstants.UserRoles.EditContent);
            }

            // UnitOfWork.BeginTransaction(); // NOTE: this causes concurrent data exception.

            BlogPost        blogPost;
            BlogPostContent content     = null;
            PageContent     pageContent = null;

            Pages.Models.Redirect redirectCreated = null;

            // Loading blog post and it's content, or creating new, if such not exists
            if (!isNew)
            {
                blogPost = Repository.First <BlogPost>(request.Id);
                content  = Repository.FirstOrDefault <BlogPostContent>(c => c.PageContents.Any(x => x.Page == blogPost && x.Region == region && !x.IsDeleted));
                if (content != null)
                {
                    pageContent = Repository.FirstOrDefault <PageContent>(c => c.Page == blogPost && c.Region == region && !c.IsDeleted && c.Content == content);
                }

                if (userCanEdit && !string.Equals(blogPost.PageUrl, request.BlogUrl) && request.BlogUrl != null)
                {
                    request.BlogUrl = urlService.FixUrl(request.BlogUrl);
                    pageService.ValidatePageUrl(request.BlogUrl, request.Id);
                    if (request.RedirectFromOldUrl)
                    {
                        var redirect = redirectService.CreateRedirectEntity(blogPost.PageUrl, request.BlogUrl);
                        if (redirect != null)
                        {
                            Repository.Save(redirect);
                            redirectCreated = redirect;
                        }
                    }

                    blogPost.PageUrl = urlService.FixUrl(request.BlogUrl);
                }
            }
            else
            {
                blogPost = new BlogPost();

                AddDefaultAccessRules(blogPost);
            }

            if (pageContent == null)
            {
                pageContent = new PageContent {
                    Region = region, Page = blogPost
                };
            }

            // Push to change modified data each time.
            blogPost.ModifiedOn = DateTime.Now;
            blogPost.Version    = request.Version;

            if (userCanEdit)
            {
                blogPost.Title       = request.Title;
                blogPost.Description = request.IntroText;
                blogPost.Author      = request.AuthorId.HasValue ? Repository.AsProxy <Author>(request.AuthorId.Value) : null;
                blogPost.Category    = request.CategoryId.HasValue ? Repository.AsProxy <Category>(request.CategoryId.Value) : null;
                blogPost.Image       = (request.Image != null && request.Image.ImageId.HasValue) ? Repository.AsProxy <MediaImage>(request.Image.ImageId.Value) : null;
                if (isNew || request.DesirableStatus == ContentStatus.Published)
                {
                    blogPost.ActivationDate = request.LiveFromDate;
                    blogPost.ExpirationDate = TimeHelper.FormatEndDate(request.LiveToDate);
                }
            }

            if (isNew)
            {
                if (!string.IsNullOrWhiteSpace(request.BlogUrl))
                {
                    blogPost.PageUrl = urlService.FixUrl(request.BlogUrl);
                    pageService.ValidatePageUrl(blogPost.PageUrl);
                }
                else
                {
                    blogPost.PageUrl = blogService.CreateBlogPermalink(request.Title);
                }

                blogPost.MetaTitle = request.Title;
                blogPost.Layout    = layout;
                UpdateStatus(blogPost, request.DesirableStatus);
            }
            else if (request.DesirableStatus == ContentStatus.Published)
            {
                UpdateStatus(blogPost, request.DesirableStatus);
            }

            // Create content.
            var newContent = new BlogPostContent
            {
                Id               = content != null ? content.Id : Guid.Empty,
                Name             = request.Title,
                Html             = request.Content ?? string.Empty,
                EditInSourceMode = request.EditInSourceMode,
                ActivationDate   = request.LiveFromDate,
                ExpirationDate   = TimeHelper.FormatEndDate(request.LiveToDate)
            };

            // Preserve content if user is not authorized to change it.
            if (!userCanEdit)
            {
                if (content == null)
                {
                    throw new SecurityException("Forbidden: Access is denied."); // User has no rights to create new content.
                }

                var contentToPublish = (BlogPostContent)(content.History != null
                    ? content.History.FirstOrDefault(c => c.Status == ContentStatus.Draft) ?? content
                    : content);

                newContent.Name = contentToPublish.Name;
                newContent.Html = contentToPublish.Html;
            }

            content             = (BlogPostContent)contentService.SaveContentWithStatusUpdate(newContent, request.DesirableStatus);
            pageContent.Content = content;

            blogPost.PageUrlHash     = blogPost.PageUrl.UrlHash();
            blogPost.UseCanonicalUrl = request.UseCanonicalUrl;
            Repository.Save(blogPost);
            Repository.Save(content);
            Repository.Save(pageContent);

            // Save tags if user has edit right.
            IList <Tag> newTags = null;

            if (userCanEdit)
            {
                tagService.SavePageTags(blogPost, request.Tags, out newTags);
            }

            // Commit
            UnitOfWork.Commit();

            // Notify about new or updated blog post.
            if (isNew)
            {
                Events.BlogEvents.Instance.OnBlogCreated(blogPost);
            }
            else
            {
                Events.BlogEvents.Instance.OnBlogUpdated(blogPost);
            }

            // Notify about new created tags.
            Events.RootEvents.Instance.OnTagCreated(newTags);

            // Notify about redirect creation.
            if (redirectCreated != null)
            {
                Events.PageEvents.Instance.OnRedirectCreated(redirectCreated);
            }

            return(new SaveBlogPostCommandResponse
            {
                Id = blogPost.Id,
                Version = blogPost.Version,
                Title = blogPost.Title,
                PageUrl = blogPost.PageUrl,
                ModifiedByUser = blogPost.ModifiedByUser,
                ModifiedOn = blogPost.ModifiedOn.ToFormattedDateString(),
                CreatedOn = blogPost.CreatedOn.ToFormattedDateString(),
                PageStatus = blogPost.Status,
                DesirableStatus = request.DesirableStatus,
                PageContentId = pageContent.Id
            });
        }
        /// <summary>
        /// Executes the specified request.
        /// </summary>
        /// <param name="id">The page id.</param>
        /// <returns></returns>
        public EditPagePropertiesViewModel Execute(Guid id)
        {
            var modelQuery = Repository
                             .AsQueryable <PageProperties>()
                             .Where(p => p.Id == id)
                             .Select(page =>
                                     new
            {
                Model = new EditPagePropertiesViewModel
                {
                    Id                   = page.Id,
                    Version              = page.Version,
                    PageName             = page.Title,
                    PageUrl              = page.PageUrl,
                    ForceAccessProtocol  = page.ForceAccessProtocol,
                    PageCSS              = page.CustomCss,
                    PageJavascript       = page.CustomJS,
                    UseNoFollow          = page.UseNoFollow,
                    UseNoIndex           = page.UseNoIndex,
                    UseCanonicalUrl      = page.UseCanonicalUrl,
                    IsPagePublished      = page.Status == PageStatus.Published,
                    IsArchived           = page.IsArchived,
                    IsMasterPage         = page.IsMasterPage,
                    TemplateId           = page.Layout.Id,
                    MasterPageId         = page.MasterPage.Id,
                    CategoryId           = page.Category.Id,
                    LanguageId           = page.Language.Id,
                    AccessControlEnabled = cmsConfiguration.Security.AccessControlEnabled,
                    IsInSitemap          = page.PagesView.IsInSitemap,
                    Image                = page.Image == null || page.Image.IsDeleted ? null :
                                           new ImageSelectorViewModel
                    {
                        ImageId      = page.Image.Id,
                        ImageVersion = page.Image.Version,
                        ImageUrl     = fileUrlResolver.EnsureFullPathUrl(page.Image.PublicUrl),
                        ThumbnailUrl = fileUrlResolver.EnsureFullPathUrl(page.Image.PublicThumbnailUrl),
                        ImageTooltip = page.Image.Caption,
                        FolderId     = page.Image.Folder != null ? page.Image.Folder.Id : (Guid?)null
                    },
                    SecondaryImage = page.SecondaryImage == null || page.SecondaryImage.IsDeleted ? null :
                                     new ImageSelectorViewModel
                    {
                        ImageId      = page.SecondaryImage.Id,
                        ImageVersion = page.SecondaryImage.Version,
                        ImageUrl     = fileUrlResolver.EnsureFullPathUrl(page.SecondaryImage.PublicUrl),
                        ThumbnailUrl = fileUrlResolver.EnsureFullPathUrl(page.SecondaryImage.PublicThumbnailUrl),
                        ImageTooltip = page.SecondaryImage.Caption,
                        FolderId     = page.SecondaryImage.Folder != null ? page.SecondaryImage.Folder.Id : (Guid?)null
                    },
                    FeaturedImage = page.FeaturedImage == null || page.FeaturedImage.IsDeleted ? null :
                                    new ImageSelectorViewModel
                    {
                        ImageId      = page.FeaturedImage.Id,
                        ImageVersion = page.FeaturedImage.Version,
                        ImageUrl     = fileUrlResolver.EnsureFullPathUrl(page.FeaturedImage.PublicUrl),
                        ThumbnailUrl = fileUrlResolver.EnsureFullPathUrl(page.FeaturedImage.PublicThumbnailUrl),
                        ImageTooltip = page.FeaturedImage.Caption,
                        FolderId     = page.FeaturedImage.Folder != null ? page.FeaturedImage.Folder.Id : (Guid?)null
                    }
                },
                LanguageGroupIdentifier = page.LanguageGroupIdentifier
            })
                             .ToFuture();

            var tagsFuture      = tagService.GetPageTagNames(id);
            var categories      = categoryService.GetCategories();
            var languagesFuture = (cmsConfiguration.EnableMultilanguage) ? languageService.GetLanguages() : null;

            IEnumerable <AccessRule> userAccessFuture;

            if (cmsConfiguration.Security.AccessControlEnabled)
            {
                userAccessFuture = Repository
                                   .AsQueryable <Root.Models.Page>()
                                   .Where(x => x.Id == id && !x.IsDeleted)
                                   .SelectMany(x => x.AccessRules)
                                   .OrderBy(x => x.IsForRole)
                                   .ThenBy(x => x.Identity)
                                   .ToFuture();
            }
            else
            {
                userAccessFuture = null;
            }

            var model = modelQuery.ToList().FirstOrDefault();

            if (model != null && model.Model != null)
            {
                if (model.Model.IsMasterPage)
                {
                    AccessControlService.DemandAccess(Context.Principal, RootModuleConstants.UserRoles.Administration);
                }
                else
                {
                    AccessControlService.DemandAccess(Context.Principal, RootModuleConstants.UserRoles.MultipleRoles(RootModuleConstants.UserRoles.EditContent, RootModuleConstants.UserRoles.PublishContent));
                }

                model.Model.Tags = tagsFuture.ToList();
                model.Model.RedirectFromOldUrl  = true;
                model.Model.Categories          = categories;
                model.Model.PageAccessProtocols = this.GetProtocolForcingTypes();
                model.Model.UpdateSitemap       = true;
                model.Model.CustomOptions       = optionService.GetCustomOptions();
                model.Model.ShowTranslationsTab = cmsConfiguration.EnableMultilanguage && !model.Model.IsMasterPage;
                if (model.Model.ShowTranslationsTab)
                {
                    model.Model.Languages = languagesFuture.ToList();
                    if (!model.Model.Languages.Any())
                    {
                        model.Model.TranslationMessages = new UserMessages();
                        model.Model.TranslationMessages.AddInfo(PagesGlobalization.EditPageProperties_TranslationsTab_NoLanguagesCreated_Message);
                    }
                    if (model.LanguageGroupIdentifier.HasValue)
                    {
                        model.Model.Translations = pageService.GetPageTranslations(model.LanguageGroupIdentifier.Value).ToList();
                    }
                }

                // Get layout options, page options and merge them
                model.Model.OptionValues = optionService.GetMergedMasterPagesOptionValues(model.Model.Id, model.Model.MasterPageId, model.Model.TemplateId);

                if (userAccessFuture != null)
                {
                    model.Model.UserAccessList = userAccessFuture.Select(x => new UserAccessViewModel(x)).ToList();

                    var rules = model.Model.UserAccessList.Cast <IAccessRule>().ToList();

                    SetIsReadOnly(model.Model, rules);
                }

                model.Model.CanPublishPage = SecurityService.IsAuthorized(Context.Principal, RootModuleConstants.UserRoles.PublishContent);

                // Get templates
                model.Model.Templates = layoutService.GetAvailableLayouts(id, model.Model.MasterPageId).ToList();
                model.Model.Templates
                .Where(x => x.TemplateId == model.Model.TemplateId || x.TemplateId == model.Model.MasterPageId)
                .Take(1).ToList()
                .ForEach(x => x.IsActive = true);
            }

            return(model != null ? model.Model : null);
        }
Example #20
0
        /// <summary>
        /// Executes this command.
        /// </summary>
        public ConfirmUploadResponse Execute(MultiFileUploadViewModel request)
        {
            ConfirmUploadResponse response = new ConfirmUploadResponse {
                SelectedFolderId = request.SelectedFolderId ?? Guid.Empty, ReuploadMediaId = request.ReuploadMediaId
            };

            if (request.UploadedFiles != null && request.UploadedFiles.Count > 0)
            {
                MediaFolder folder = null;

                if (request.SelectedFolderId != null && request.SelectedFolderId.Value != Guid.Empty)
                {
                    folder = Repository.AsProxy <MediaFolder>(request.SelectedFolderId.Value);
                    if (folder.IsDeleted)
                    {
                        response.FolderIsDeleted = true;
                        return(response);
                    }
                }

                UnitOfWork.BeginTransaction();

                List <MediaFile> files  = new List <MediaFile>();
                var updateAccessControl = true;

                if (request.ReuploadMediaId.HasDefaultValue())
                {
                    UpdateMedia(request, folder, files);
                }
                else
                {
                    // Re-upload performed.
                    var fileId = request.UploadedFiles.FirstOrDefault();
                    var file   = Repository.FirstOrDefault <MediaFile>(fileId);

                    if (!fileId.HasDefaultValue())
                    {
                        var originalMedia = Repository.First <MediaFile>(request.ReuploadMediaId);
                        if (cmsConfiguration.Security.AccessControlEnabled && !(originalMedia is IAccessControlDisabled))
                        {
                            AccessControlService.DemandAccess(originalMedia, Context.Principal, AccessLevel.ReadWrite);
                        }

                        file.Original = originalMedia;

                        // Do not update access control, if re-uploading
                        updateAccessControl = false;

                        file.Title       = originalMedia.Title;
                        file.Description = originalMedia.Description;
                        file.IsArchived  = originalMedia.IsArchived;
                        file.Folder      = originalMedia.Folder;
                        file.Image       = originalMedia.Image;
                        if (file is MediaImage && originalMedia is MediaImage)
                        {
                            ((MediaImage)file).Caption    = ((MediaImage)originalMedia).Caption;
                            ((MediaImage)file).ImageAlign = ((MediaImage)originalMedia).ImageAlign;
                        }

                        file.IsTemporary = false;
                        file.PublishedOn = DateTime.Now;

                        var temp = (MediaFile)file.Clone();
                        originalMedia.CopyDataTo(file);
                        temp.CopyDataTo(originalMedia);
                        files.Add(originalMedia);
                    }
                }

                if (updateAccessControl && cmsConfiguration.Security.AccessControlEnabled)
                {
                    foreach (var file in files)
                    {
                        if (!(file is MediaImage))
                        {
                            var currentFile = file;
                            var fileEntity  = Repository.AsQueryable <MediaFile>().Where(f => f.Id == currentFile.Id).FetchMany(f => f.AccessRules).ToList().FirstOne();

                            accessControlService.UpdateAccessControl(
                                fileEntity, request.UserAccessList != null ? request.UserAccessList.Cast <IAccessRule>().ToList() : new List <IAccessRule>());
                        }
                    }
                }

                UnitOfWork.Commit();

                if (request.ReuploadMediaId.HasDefaultValue())
                {
                    foreach (var file in files)
                    {
                        if (file is MediaImage)
                        {
                            file.PublicUrl += string.Format("?{0}", DateTime.Now.ToString(MediaManagerModuleDescriptor.HardLoadImageDateTimeFormat));
                            ((MediaImage)file).PublicThumbnailUrl += string.Format("?{0}", DateTime.Now.ToString(MediaManagerModuleDescriptor.HardLoadImageDateTimeFormat));
                        }
                    }
                }

                response.Medias = files.Select(Convert).ToList();

                // Notify.
                foreach (var mediaFile in files)
                {
                    Events.MediaManagerEvents.Instance.OnMediaFileUpdated(mediaFile);
                }
            }

            return(response);
        }
        /// <summary>
        /// Executes the specified request.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <returns></returns>
        public SortPageContentCommandResponse Execute(PageContentSortViewModel request)
        {
            UnitOfWork.BeginTransaction();

            var sortedPageContents   = new List <PageContent>();
            var regionIds            = request.PageContents.Select(r => r.RegionId).Distinct().ToArray();
            var parentPageContentIds = request.PageContents.Where(r => r.ParentPageContentId.HasValue).Select(r => r.ParentPageContentId.Value);
            var pageContentIds       = request.PageContents.Select(r => r.PageContentId).Concat(parentPageContentIds).Distinct().ToArray();
            var response             = new SortPageContentCommandResponse {
                PageContents = request.PageContents
            };

            // Load all page contents from all regions from request
            var contentsFuture = Repository
                                 .AsQueryable <PageContent>()
                                 .Where(f => f.Page.Id == request.PageId && (regionIds.Contains(f.Region.Id) || pageContentIds.Contains(f.Id)))
                                 .ToFuture();

            // Demand access
            if (cmsConfiguration.Security.AccessControlEnabled)
            {
                var page = Repository
                           .AsQueryable <Root.Models.Page>()
                           .Where(p => p.Id == request.PageId)
                           .FetchMany(p => p.AccessRules)
                           .ToFuture()
                           .ToList()
                           .FirstOne();

                AccessControlService.DemandAccess(page, Context.Principal, AccessLevel.ReadWrite, RootModuleConstants.UserRoles.EditContent);
            }
            else
            {
                AccessControlService.DemandAccess(Context.Principal, RootModuleConstants.UserRoles.EditContent);
            }

            var pageContents = contentsFuture.ToList();

            request.PageContents
            .GroupBy(group => new System.Tuple <Guid, Guid?>(group.RegionId, group.ParentPageContentId))
            .ForEach(group =>
            {
                var regionId            = group.Key.Item1;
                var parentPageContentId = group.Key.Item2;
                var region = Repository.AsProxy <Region>(regionId);
                var index  = 0;

                foreach (var viewModel in group)
                {
                    var pageContent = pageContents.FirstOrDefault(f => f.Id == viewModel.PageContentId);

                    PageContent parentPageContent = null;
                    if (parentPageContentId.HasValue && !parentPageContentId.Value.HasDefaultValue())
                    {
                        parentPageContent = pageContents.Where(f => f.Id == parentPageContentId).FirstOne();
                    }

                    if (pageContent == null)
                    {
                        throw new EntityNotFoundException(typeof(PageContent), Guid.Empty);
                    }

                    if (pageContent.Order != index ||
                        pageContent.Region.Id != regionId ||
                        pageContent.Parent == null && parentPageContent != null ||
                        pageContent.Parent != null && parentPageContent == null ||
                        (pageContent.Parent != null && parentPageContent != null && parentPageContent.Id != pageContent.Parent.Id))
                    {
                        if (pageContent.Version != viewModel.Version)
                        {
                            throw new ConcurrentDataException(pageContent);
                        }

                        pageContent.Order  = index;
                        pageContent.Region = region;
                        pageContent.Parent = parentPageContent;

                        sortedPageContents.Add(pageContent);
                        Repository.Save(pageContent);
                    }
                    index++;
                }
            });

            UnitOfWork.Commit();

            // Notify
            foreach (var pageContent in sortedPageContents)
            {
                // Notify.
                Events.PageEvents.Instance.OnPageContentSorted(pageContent);
            }

            // Update versions
            foreach (var pageContent in pageContents)
            {
                var responseContent = response.PageContents.FirstOrDefault(pc => pc.PageContentId == pageContent.Id);
                if (responseContent != null)
                {
                    responseContent.Version = pageContent.Version;
                }
            }

            return(response);
        }
Example #22
0
        /// <summary>
        /// Executes the specified request.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <returns>Media preview.</returns>
        public MediaPreviewViewModel Execute(Guid request)
        {
            var response = new MediaPreviewViewModel();

            var media = Repository.AsQueryable <Media>(m => m.Id == request).Fetch(m => m.Original).FirstOne();
            var file  = media as MediaFile;

            if (file != null)
            {
                var image = media as MediaImage;

                if (cmsConfiguration.Security.AccessControlEnabled)
                {
                    AccessControlService.DemandAccess(file.Original as MediaFile ?? file, Context.Principal, AccessLevel.Read);
                }

                response.AddProperty(MediaGlobalization.MediaHistory_Preview_Properties_Title, file.Title);

                if (image != null)
                {
                    response.AddProperty(MediaGlobalization.MediaHistory_Preview_Properties_Caption, image.Caption);
                }

                var publicUrl = fileService.GetDownloadFileUrl(MediaType.File, file.Id, fileUrlResolver.EnsureFullPathUrl(file.PublicUrl));
                response.AddUrl(MediaGlobalization.MediaHistory_Preview_Properties_PublicUrl, publicUrl);

                if (image != null)
                {
                    response.AddUrl(
                        MediaGlobalization.MediaHistory_Preview_Properties_PublicThumbnailUrl,
                        fileUrlResolver.EnsureFullPathUrl(
                            image.PublicThumbnailUrl + string.Format("?{0}", DateTime.Now.ToString(MediaManagerModuleDescriptor.HardLoadImageDateTimeFormat))));
                }

                response.AddProperty(MediaGlobalization.MediaHistory_Preview_Properties_FileSize, file.SizeAsText());

                if (image != null)
                {
                    var dimensionCalculator = new ImageDimensionsCalculator(image);

                    if (dimensionCalculator.Height != dimensionCalculator.ResizedCroppedHeight || dimensionCalculator.Width != dimensionCalculator.ResizedCroppedWidth)
                    {
                        response.AddProperty(MediaGlobalization.MediaHistory_Preview_Properties_CroppedImageDimensions,
                                             string.Format("{0} x {1}", dimensionCalculator.ResizedCroppedWidth, dimensionCalculator.ResizedCroppedHeight));
                    }
                    response.AddProperty(MediaGlobalization.MediaHistory_Preview_Properties_ImageDimensions,
                                         string.Format("{0} x {1}", dimensionCalculator.Width, dimensionCalculator.Height));
                }

                if (!string.IsNullOrWhiteSpace(file.Description))
                {
                    response.AddProperty(MediaGlobalization.MediaHistory_Preview_Properties_Description, file.Description);
                }

                if (media.Image != null)
                {
                    response.AddImage(
                        media.Image.Caption,
                        fileUrlResolver.EnsureFullPathUrl(
                            media.Image.PublicUrl + string.Format("?{0}", DateTime.Now.ToString(MediaManagerModuleDescriptor.HardLoadImageDateTimeFormat))));
                }

                if (image != null)
                {
                    response.AddImage(
                        image.Caption,
                        fileUrlResolver.EnsureFullPathUrl(
                            image.PublicUrl + string.Format("?{0}", DateTime.Now.ToString(MediaManagerModuleDescriptor.HardLoadImageDateTimeFormat))));
                }
            }

            return(response);
        }
Example #23
0
        /// <summary>
        /// Saves SEO information.
        /// </summary>
        /// <param name="model">The SEO information model.</param>
        /// <returns>
        /// true if SEO information saved successfully; false otherwise.
        /// </returns>
        public virtual EditSeoViewModel Execute(EditSeoViewModel model)
        {
            var pageQuery =
                Repository.AsQueryable <PageProperties>(p => p.Id == model.PageId)
                .FetchMany(p => p.Options)
                .Fetch(p => p.Layout)
                .ThenFetchMany(l => l.LayoutOptions)
                .FetchMany(p => p.MasterPages)
                .AsQueryable();

            if (cmsConfiguration.Security.AccessControlEnabled)
            {
                pageQuery = pageQuery.FetchMany(f => f.AccessRules);
            }

            var page         = pageQuery.ToList().FirstOne();
            var beforeChange = new UpdatingPagePropertiesModel(page);

            var roles = new[] { RootModuleConstants.UserRoles.EditContent };

            if (cmsConfiguration.Security.AccessControlEnabled)
            {
                AccessControlService.DemandAccess(page, Context.Principal, AccessLevel.ReadWrite, roles);
            }
            else
            {
                AccessControlService.DemandAccess(Context.Principal, roles);
            }

            bool initialHasSeo = page.HasSEO;

            Models.Redirect newRedirect = null;

            page.Version = model.Version;
            page.Title   = model.PageTitle;

            model.ChangedUrlPath = urlService.FixUrl(model.ChangedUrlPath);

            IList <SitemapNode> updatedNodes = null;

            if (!string.Equals(model.PageUrlPath, model.ChangedUrlPath))
            {
                pageService.ValidatePageUrl(model.ChangedUrlPath, model.PageId);

                if (model.CreatePermanentRedirect)
                {
                    var redirect = redirectService.CreateRedirectEntity(model.PageUrlPath, model.ChangedUrlPath);
                    if (redirect != null)
                    {
                        Repository.Save(redirect);
                        newRedirect = redirect;
                    }
                }

                if (model.UpdateSitemap)
                {
                    updatedNodes = sitemapService.ChangeUrlsInAllSitemapsNodes(page.PageUrl, model.ChangedUrlPath);
                }

                page.PageUrl = model.ChangedUrlPath;
            }

            page.PageUrlHash     = page.PageUrl.UrlHash();
            page.MetaTitle       = model.MetaTitle;
            page.MetaKeywords    = model.MetaKeywords;
            page.MetaDescription = model.MetaDescription;
            page.UseCanonicalUrl = model.UseCanonicalUrl;

            // Notify about page properties changing.
            var cancelEventArgs = Events.PageEvents.Instance.OnPagePropertiesChanging(beforeChange, new UpdatingPagePropertiesModel(page));

            if (cancelEventArgs.Cancel)
            {
                Context.Messages.AddError(cancelEventArgs.CancellationErrorMessages.ToArray());
                return(null);
            }

            Repository.Save(page);
            UnitOfWork.Commit();

            Events.PageEvents.Instance.OnPagePropertiesChanged(page);

            // Notify about SEO change.
            if (page.HasSEO != initialHasSeo)
            {
                Events.PageEvents.Instance.OnPageSeoStatusChanged(page);
            }

            // Notify about new redirect creation.
            if (newRedirect != null)
            {
                Events.PageEvents.Instance.OnRedirectCreated(newRedirect);
            }

            // Notify about updated sitemap nodes.
            if (updatedNodes != null)
            {
                var updatedSitemaps = new List <Models.Sitemap>();
                foreach (var node in updatedNodes)
                {
                    Events.SitemapEvents.Instance.OnSitemapNodeUpdated(node);
                    if (!updatedSitemaps.Contains(node.Sitemap))
                    {
                        updatedSitemaps.Add(node.Sitemap);
                    }
                }

                foreach (var updatedSitemap in updatedSitemaps)
                {
                    Events.SitemapEvents.Instance.OnSitemapUpdated(updatedSitemap);
                }
            }

            return(new EditSeoViewModel {
                PageUrlPath = page.PageUrl
            });
        }
Example #24
0
        /// <summary>
        /// Executes the specified request.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <returns>AddNewPage view model</returns>
        public AddNewPageViewModel Execute(AddNewPageCommandRequest request)
        {
            if (request.CreateMasterPage)
            {
                AccessControlService.DemandAccess(Context.Principal, RootModuleConstants.UserRoles.Administration);
            }
            else
            {
                AccessControlService.DemandAccess(Context.Principal, RootModuleConstants.UserRoles.EditContent);
            }

            var showLanguages   = cmsConfiguration.EnableMultilanguage && !request.CreateMasterPage;
            var languagesFuture = (showLanguages) ? languageService.GetLanguagesLookupValues() : null;

            var principal = securityService.GetCurrentPrincipal();
            var model     = new AddNewPageViewModel
            {
                ParentPageUrl        = request.ParentPageUrl,
                Templates            = layoutService.GetAvailableLayouts().ToList(),
                AccessControlEnabled = cmsConfiguration.Security.AccessControlEnabled,
                CreateMasterPage     = request.CreateMasterPage,
                ShowLanguages        = showLanguages
            };

            if (showLanguages)
            {
                model.Languages     = languagesFuture.ToList();
                model.ShowLanguages = model.Languages.Any();
            }

            if (model.Templates.Count > 0)
            {
                model.Templates.ToList().ForEach(x => x.IsActive = false);

                // Select current page as master
                var urlHash = request.ParentPageUrl.UrlHash();
                model.Templates.Where(t => t.IsMasterPage && t.MasterUrlHash == urlHash).ToList().ForEach(x => x.IsActive = true);

                // Select current page's layout
                if (model.Templates.Count(t => t.IsActive) != 1)
                {
                    // Try to get layout of the current page
                    var currentPageLayout = repository
                                            .AsQueryable <Root.Models.Page>(p => p.PageUrlHash == request.ParentPageUrl.UrlHash())
                                            .Select(p => new
                    {
                        MasterPageId = p.MasterPage != null ? p.MasterPage.Id : (System.Guid?)null,
                        LayoutId     = p.Layout != null ? p.Layout.Id : (System.Guid?)null
                    })
                                            .FirstOrDefault();
                    if (currentPageLayout != null)
                    {
                        if (currentPageLayout.MasterPageId.HasValue)
                        {
                            model.Templates
                            .Where(t => t.IsMasterPage && t.TemplateId == currentPageLayout.MasterPageId.Value)
                            .Take(1)
                            .ToList().ForEach(x => x.IsActive = true);
                        }
                        else if (currentPageLayout.LayoutId.HasValue)
                        {
                            model.Templates
                            .Where(t => !t.IsMasterPage && t.TemplateId == currentPageLayout.LayoutId.Value)
                            .Take(1)
                            .ToList().ForEach(x => x.IsActive = true);
                        }
                    }
                }

                // Select first layout as active
                if (model.Templates.Count(t => t.IsActive) != 1)
                {
                    model.Templates.First().IsActive = true;
                }

                var active = model.Templates.First(t => t.IsActive);
                if (active != null)
                {
                    if (active.IsMasterPage)
                    {
                        model.MasterPageId   = active.TemplateId;
                        model.UserAccessList = Repository
                                               .AsQueryable <Root.Models.Page>()
                                               .Where(x => x.Id == model.MasterPageId && !x.IsDeleted)
                                               .SelectMany(x => x.AccessRules)
                                               .OrderBy(x => x.Identity)
                                               .Select(x => new UserAccessViewModel(x)).ToList();
                    }
                    else
                    {
                        model.TemplateId     = active.TemplateId;
                        model.UserAccessList = AccessControlService.GetDefaultAccessList(principal).Select(f => new UserAccessViewModel(f)).ToList();
                    }
                }

                if (model.TemplateId.HasValue)
                {
                    model.OptionValues = layoutService.GetLayoutOptionValues(model.TemplateId.Value);
                }

                if (model.MasterPageId.HasValue)
                {
                    model.OptionValues = masterPageService.GetMasterPageOptionValues(model.MasterPageId.Value);
                }

                model.CustomOptions = optionService.GetCustomOptions();
            }

            return(model);
        }
        /// <summary>
        /// Executes the specified request.
        /// </summary>
        /// <param name="request">The request.</param>
        public void Execute(List <SitemapViewModel> requests)
        {
            createdNodes.Clear();
            updatedNodes.Clear();
            deletedNodes.Clear();

            var sitemapsToSave = new List <SaveModel>();

            foreach (var request in requests)
            {
                var createNew = request.Id.HasDefaultValue();

                Models.Sitemap sitemap;

                if (!createNew)
                {
                    var sitemapQuery = Repository.AsQueryable <Models.Sitemap>()
                                       .Where(s => s.Id == request.Id);

                    if (CmsConfiguration.Security.AccessControlEnabled)
                    {
                        sitemapQuery = sitemapQuery.FetchMany(f => f.AccessRules);
                    }

                    sitemapQuery = sitemapQuery.FetchMany(s => s.Nodes);

                    sitemap = sitemapQuery.ToList().First(); // NOTE: bottleneck. TODO: remake with ToFuture to get all the sitemaps at once.

                    if (CmsConfiguration.Security.AccessControlEnabled)
                    {
                        AccessControlService.DemandAccess(sitemap, Context.Principal, AccessLevel.ReadWrite);
                    }
                }
                else
                {
                    sitemap = new Models.Sitemap()
                    {
                        AccessRules = new List <AccessRule>(), Nodes = new List <SitemapNode>()
                    };
                }

                sitemapsToSave.Add(new SaveModel()
                {
                    Model = request, Entity = sitemap, IsNew = createNew
                });
            }


            UnitOfWork.BeginTransaction();

            var createdTags = new List <Tag>();

            foreach (var item in sitemapsToSave)
            {
                // Save/update only sitemap nodes.
                SaveNodeList(item.Entity, item.Model.RootNodes, null, item.Entity.Nodes.ToList());
            }

            UnitOfWork.Commit();

            foreach (var node in createdNodes)
            {
                Events.SitemapEvents.Instance.OnSitemapNodeCreated(node);
            }

            foreach (var node in updatedNodes)
            {
                Events.SitemapEvents.Instance.OnSitemapNodeUpdated(node);
            }

            foreach (var node in deletedNodes)
            {
                Events.SitemapEvents.Instance.OnSitemapNodeDeleted(node);
            }

            foreach (var item in sitemapsToSave)
            {
                if (item.IsNew)
                {
                    Events.SitemapEvents.Instance.OnSitemapCreated(item.Entity);
                }
                else
                {
                    Events.SitemapEvents.Instance.OnSitemapUpdated(item.Entity);
                }
            }

            Events.RootEvents.Instance.OnTagCreated(createdTags);
        }
Example #26
0
        /// <summary>
        /// Executes the specified request.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <returns></returns>
        /// <exception cref="ConcurrentDataException"></exception>
        /// <exception cref="CmsException"></exception>
        public DestroyContentDraftCommandResponse Execute(DestroyContentDraftCommandRequest request)
        {
            var contentQuery = Repository
                               .AsQueryable <Root.Models.Content>(p => p.Id == request.Id)
                               .Fetch(f => f.Original).AsQueryable();

            if (cmsConfiguration.Security.AccessControlEnabled)
            {
                contentQuery = contentQuery.FetchMany(f => f.PageContents).ThenFetch(f => f.Page).ThenFetchMany(f => f.AccessRules).AsQueryable();
            }

            var content = contentQuery.ToList().FirstOrDefault();

            // Throw concurrent data exception (user needs to reload page):
            // - content may be null, if looking for already deleted draft
            // - content may be changed, if looking for
            if (content == null || request.Version != content.Version)
            {
                throw new ConcurrentDataException(content ?? new Root.Models.Content());
            }

            var pageContents = content.PageContents;

            // If content is published, try to get it's active draft
            if (content.Status == ContentStatus.Published)
            {
                content = Repository
                          .AsQueryable <Root.Models.Content>(p => p.Original == content)
                          .Where(c => c.Status == ContentStatus.Draft && !c.IsDeleted)
                          .Fetch(f => f.Original)
                          .FirstOrDefault();

                if (content == null)
                {
                    // Throw concurrent data exception (user needs to reload page):
                    // - content may be null, if looking for already deleted draft
                    throw new ConcurrentDataException(new Root.Models.Content());
                }
            }

            if (content.Status != ContentStatus.Draft)
            {
                throw new CmsException(string.Format("Only draft version can be destroyed. Id: {0}, Status: {1}", content.Id, content.Status));
            }

            if (content.Original == null)
            {
                throw new CmsException(string.Format("Draft version cannot be destroyed - it has no published original version. Id: {0}, Status: {1}", content.Id, content.Status));
            }

            var contentType = content.GetType();

            if (contentType == typeof(HtmlContentWidget) || contentType == typeof(ServerControlWidget))
            {
                AccessControlService.DemandAccess(Context.Principal, RootModuleConstants.UserRoles.Administration);
            }
            else
            {
                bool checkedAccess = false;
                if (content is HtmlContent)
                {
                    var pageContent = pageContents.FirstOrDefault();
                    if (pageContent != null && pageContent.Page != null)
                    {
                        checkedAccess = true;
                        AccessControlService.DemandAccess(pageContent.Page, Context.Principal, AccessLevel.ReadWrite, RootModuleConstants.UserRoles.EditContent);
                    }
                }

                if (!checkedAccess)
                {
                    AccessControlService.DemandAccess(Context.Principal, RootModuleConstants.UserRoles.EditContent);
                }
            }

            Repository.Delete(content);
            UnitOfWork.Commit();

            var response = new DestroyContentDraftCommandResponse
            {
                PublishedId     = content.Original.Id,
                Id              = content.Original.Id,
                OriginalId      = content.Original.Id,
                Version         = content.Original.Version,
                OriginalVersion = content.Original.Version,
                WidgetName      = content.Original.Name,
                IsPublished     = true,
                HasDraft        = false,
                DesirableStatus = ContentStatus.Published
            };

            // Try to cast to widget
            var widget = content.Original as HtmlContentWidget;

            if (widget != null && widget.Category != null && !widget.Category.IsDeleted)
            {
                response.CategoryName = widget.Category.Name;
            }

            return(response);
        }
Example #27
0
        public ChangedContentResultViewModel Execute(SavePageHtmlContentCommandRequest request)
        {
            var model = request.Content;

            if (model.DesirableStatus == ContentStatus.Published)
            {
                AccessControlService.DemandAccess(Context.Principal, RootModuleConstants.UserRoles.PublishContent);
            }

            if (model.Id == default(Guid) || model.DesirableStatus != ContentStatus.Published)
            {
                AccessControlService.DemandAccess(Context.Principal, RootModuleConstants.UserRoles.EditContent);
            }

            PageContent pageContent;
            var         isNew = model.Id.HasDefaultValue();

            if (!isNew)
            {
                var query = Repository
                            .AsQueryable <PageContent>()
                            .Where(f => f.Id == model.Id && !f.IsDeleted)
                            .AsQueryable();

                if (!model.IsUserConfirmed)
                {
                    query = query.Fetch(f => f.Page);
                }

                if (configuration.Security.AccessControlEnabled)
                {
                    query = query.Fetch(f => f.Page).ThenFetchMany(f => f.AccessRules);
                }

                pageContent = query.ToList().FirstOne();

                // Check if user has confirmed the deletion of content
                if (!model.IsUserConfirmed && pageContent.Page.IsMasterPage)
                {
                    contentService.CheckIfContentHasDeletingChildrenWithException(model.PageId, model.ContentId, model.PageContent);
                }
            }
            else
            {
                pageContent       = new PageContent();
                pageContent.Order = contentService.GetPageContentNextOrderNumber(model.PageId, model.ParentPageContentId);

                if (configuration.Security.AccessControlEnabled)
                {
                    pageContent.Page = Repository
                                       .AsQueryable <Root.Models.Page>(p => p.Id == model.PageId)
                                       .FetchMany(p => p.AccessRules)
                                       .ToList()
                                       .FirstOne();
                }
            }

            // Demand access
            if (configuration.Security.AccessControlEnabled)
            {
                AccessControlService.DemandAccess(pageContent.Page, Context.Principal, AccessLevel.ReadWrite);
            }

            // Get page as proxy, if page is not retrieved yet
            if (!configuration.Security.AccessControlEnabled)
            {
                pageContent.Page = Repository.AsProxy <Root.Models.Page>(model.PageId);
            }
            pageContent.Region = Repository.AsProxy <Region>(model.RegionId);
            if (!model.ParentPageContentId.HasDefaultValue())
            {
                pageContent.Parent = Repository.AsProxy <PageContent>(model.ParentPageContentId);
            }
            else
            {
                pageContent.Parent = null;
            }

            var contentToSave = new HtmlContent
            {
                Id               = model.ContentId,
                ActivationDate   = model.LiveFrom,
                ExpirationDate   = TimeHelper.FormatEndDate(model.LiveTo),
                Name             = model.ContentName,
                Html             = model.PageContent ?? string.Empty,
                UseCustomCss     = model.EnabledCustomCss,
                CustomCss        = model.CustomCss,
                UseCustomJs      = model.EanbledCustomJs,
                CustomJs         = model.CustomJs,
                EditInSourceMode = model.EditInSourceMode
            };

            // Preserve content if user is not authorized to change it.
            if (!SecurityService.IsAuthorized(RootModuleConstants.UserRoles.EditContent) && model.Id != default(Guid))
            {
                var originalContent  = Repository.First <HtmlContent>(model.ContentId);
                var contentToPublish = (HtmlContent)(originalContent.History != null
                    ? originalContent.History.FirstOrDefault(c => c.Status == ContentStatus.Draft) ?? originalContent
                    : originalContent);

                contentToSave.Name             = contentToPublish.Name;
                contentToSave.Html             = contentToPublish.Html;
                contentToSave.UseCustomCss     = contentToPublish.UseCustomCss;
                contentToSave.CustomCss        = contentToPublish.CustomCss;
                contentToSave.UseCustomJs      = contentToPublish.UseCustomJs;
                contentToSave.CustomJs         = contentToPublish.CustomJs;
                contentToSave.EditInSourceMode = contentToPublish.EditInSourceMode;
            }

            UnitOfWork.BeginTransaction();
            pageContent.Content = contentService.SaveContentWithStatusUpdate(
                contentToSave,
                model.DesirableStatus);
            optionsService.SaveChildContentOptions(pageContent.Content, request.ChildContentOptionValues, model.DesirableStatus);

            if (pageContent.Content.ContentRegions != null &&
                pageContent.Content.ContentRegions.Count > 0)
            {
                if (!pageContent.Page.IsMasterPage)
                {
                    var logMessage = string.Format("Dynamic regions are not allowed. Page: {0}, Content: {1}", pageContent.Page, pageContent.Id);
                    throw new ValidationException(() => PagesGlobalization.SaveContent_DynamicRegionsAreNotAllowed_Message, logMessage);
                }
            }

            Repository.Save(pageContent);
            UnitOfWork.Commit();

            // Notify.
            if (model.DesirableStatus != ContentStatus.Preview)
            {
                if (isNew)
                {
                    Events.PageEvents.Instance.OnHtmlContentCreated((HtmlContent)pageContent.Content);
                    Events.PageEvents.Instance.OnPageContentInserted(pageContent);
                }
                else
                {
                    Events.PageEvents.Instance.OnHtmlContentUpdated((HtmlContent)pageContent.Content);
                }
            }

            var contentData = (pageContent.Content.History != null
                    ? pageContent.Content.History.FirstOrDefault(c => c.Status == ContentStatus.Draft) ?? pageContent.Content
                    : pageContent.Content);

            var response = new ChangedContentResultViewModel
            {
                PageContentId      = pageContent.Id,
                ContentId          = contentData.Id,
                RegionId           = pageContent.Region.Id,
                PageId             = pageContent.Page.Id,
                DesirableStatus    = request.Content.DesirableStatus,
                Title              = contentData.Name,
                ContentVersion     = contentData.Version,
                PageContentVersion = pageContent.Version,
                ContentType        = HtmlContentAccessor.ContentWrapperType
            };

            if (request.Content.IncludeChildRegions)
            {
                response.Regions = widgetService.GetWidgetChildRegionViewModels(contentData);
            }

            return(response);
        }
        /// <summary>
        /// Executes the specified request.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <returns>Save response.</returns>
        /// <exception cref="CmsException">Failed to save page properties.</exception>
        public SavePageResponse Execute(EditPagePropertiesViewModel request)
        {
            var isMultilanguageEnabled = cmsConfiguration.EnableMultilanguage;

            ValidateRequest(request, isMultilanguageEnabled);

            var pageQuery =
                Repository.AsQueryable <PageProperties>(p => p.Id == request.Id)
                .FetchMany(p => p.Options)
                .Fetch(p => p.Layout)
                .ThenFetchMany(l => l.LayoutOptions)
                .FetchMany(p => p.MasterPages)
                .AsQueryable();

            if (cmsConfiguration.Security.AccessControlEnabled)
            {
                pageQuery = pageQuery.FetchMany(f => f.AccessRules);
            }

            var page         = pageQuery.ToList().FirstOne();
            var beforeChange = new UpdatingPagePropertiesModel(page);

            var roles = page.IsMasterPage
                            ? new[]
            {
                RootModuleConstants.UserRoles.EditContent, RootModuleConstants.UserRoles.PublishContent, RootModuleConstants.UserRoles.Administration
            }
                            : new[] { RootModuleConstants.UserRoles.EditContent, RootModuleConstants.UserRoles.PublishContent };

            if (cmsConfiguration.Security.AccessControlEnabled)
            {
                AccessControlService.DemandAccess(page, Context.Principal, AccessLevel.ReadWrite, roles);
            }
            else
            {
                AccessControlService.DemandAccess(Context.Principal, roles);
            }

            var canEdit = page.IsMasterPage
                              ? SecurityService.IsAuthorized(
                Context.Principal,
                RootModuleConstants.UserRoles.MultipleRoles(RootModuleConstants.UserRoles.EditContent, RootModuleConstants.UserRoles.Administration))
                              : SecurityService.IsAuthorized(Context.Principal, RootModuleConstants.UserRoles.EditContent);

            IList <PageProperties> translations = null;

            if (canEdit && isMultilanguageEnabled && !page.IsMasterPage)
            {
                translations = LoadAndValidateTranslations(page, request);
            }

            // Load master pages for updating page's master path and page's children master path
            IList <Guid>       newMasterIds;
            IList <Guid>       oldMasterIds;
            IList <Guid>       childrenPageIds;
            IList <MasterPage> existingChildrenMasterPages;

            masterPageService.PrepareForUpdateChildrenMasterPages(page, request.MasterPageId, out newMasterIds, out oldMasterIds, out childrenPageIds, out existingChildrenMasterPages);

            IList <SitemapNode> updatedNodes = null;

            // Start transaction, only when everything is already loaded
            UnitOfWork.BeginTransaction();

            Models.Redirect redirectCreated  = null;
            var             initialSeoStatus = page.HasSEO;

            request.PageUrl = urlService.FixUrl(request.PageUrl);

            if (canEdit && !string.Equals(page.PageUrl, request.PageUrl))
            {
                pageService.ValidatePageUrl(request.PageUrl, request.Id);
                if (request.RedirectFromOldUrl)
                {
                    var redirect = redirectService.CreateRedirectEntity(page.PageUrl, request.PageUrl);
                    if (redirect != null)
                    {
                        Repository.Save(redirect);
                        redirectCreated = redirect;
                    }
                }

                if (request.UpdateSitemap)
                {
                    updatedNodes = sitemapService.ChangeUrlsInAllSitemapsNodes(page.PageUrl, request.PageUrl);
                }

                page.PageUrl = request.PageUrl;
            }

            List <PageProperties> updatePageTranslations = null;

            if (canEdit)
            {
                page.PageUrlHash         = page.PageUrl.UrlHash();
                page.ForceAccessProtocol = request.ForceAccessProtocol;

                categoryService.CombineEntityCategories <PageProperties, PageCategory>(page, request.Categories);

                page.Title     = request.PageName;
                page.CustomCss = request.PageCSS;
                page.CustomJS  = request.PageJavascript;

                masterPageService.SetMasterOrLayout(page, request.MasterPageId, request.TemplateId);

                if (isMultilanguageEnabled && !page.IsMasterPage)
                {
                    updatePageTranslations = UpdatePageTranslations(page, translations, request);
                }
            }

            var publishDraftContent = false;

            if (request.CanPublishPage && !page.IsMasterPage)
            {
                AccessControlService.DemandAccess(Context.Principal, RootModuleConstants.UserRoles.PublishContent);

                if (request.IsPagePublished)
                {
                    if (page.Status != PageStatus.Published)
                    {
                        page.Status         = PageStatus.Published;
                        page.PublishedOn    = DateTime.Now;
                        publishDraftContent = true;
                    }
                }
                else
                {
                    page.Status = PageStatus.Unpublished;
                }
            }

            IList <PageOption> pageOptions = page.Options.Distinct().ToList();

            if (canEdit)
            {
                if (!page.IsMasterPage)
                {
                    page.UseNoFollow = request.UseNoFollow;
                    page.UseNoIndex  = request.UseNoIndex;
                    page.IsArchived  = request.IsArchived;
                }

                page.UseCanonicalUrl = request.UseCanonicalUrl;
                page.Version         = request.Version;

                page.Image          = request.Image != null && request.Image.ImageId.HasValue ? Repository.AsProxy <MediaImage>(request.Image.ImageId.Value) : null;
                page.SecondaryImage = request.SecondaryImage != null && request.SecondaryImage.ImageId.HasValue
                                          ? Repository.AsProxy <MediaImage>(request.SecondaryImage.ImageId.Value)
                                          : null;
                page.FeaturedImage = request.FeaturedImage != null && request.FeaturedImage.ImageId.HasValue
                                         ? Repository.AsProxy <MediaImage>(request.FeaturedImage.ImageId.Value)
                                         : null;

                pageOptions = optionService.SaveOptionValues(request.OptionValues, pageOptions, () => new PageOption {
                    Page = page
                });

                if (cmsConfiguration.Security.AccessControlEnabled)
                {
                    page.AccessRules.RemoveDuplicateEntities();

                    var accessRules = request.UserAccessList != null?request.UserAccessList.Cast <IAccessRule>().ToList() : null;

                    accessControlService.UpdateAccessControl(page, accessRules);
                }
            }

            // Notify about page properties changing.
            var cancelEventArgs = Events.PageEvents.Instance.OnPagePropertiesChanging(beforeChange, new UpdatingPagePropertiesModel(page));

            if (cancelEventArgs.Cancel)
            {
                Context.Messages.AddError(cancelEventArgs.CancellationErrorMessages.ToArray());
                return(null);
            }

            Repository.Save(page);

            IList <Tag> newTags = null;

            if (canEdit)
            {
                masterPageService.UpdateChildrenMasterPages(existingChildrenMasterPages, oldMasterIds, newMasterIds, childrenPageIds);
                tagService.SavePageTags(page, request.Tags, out newTags);
            }

            if (publishDraftContent)
            {
                contentService.PublishDraftContent(page.Id);
            }

            UnitOfWork.Commit();

            // Notify about page properties change.
            page.Options = pageOptions;
            Events.PageEvents.Instance.OnPagePropertiesChanged(page);

            // Notify about translation properties changed
            if (updatePageTranslations != null)
            {
                updatePageTranslations.ForEach(Events.PageEvents.Instance.OnPagePropertiesChanged);
            }

            // Notify about redirect creation.
            if (redirectCreated != null)
            {
                Events.PageEvents.Instance.OnRedirectCreated(redirectCreated);
            }

            // Notify about SEO status change.
            if (initialSeoStatus != page.HasSEO)
            {
                Events.PageEvents.Instance.OnPageSeoStatusChanged(page);
            }

            // Notify about new tags.
            Events.RootEvents.Instance.OnTagCreated(newTags);

            // Notify about updated sitemap nodes.
            if (updatedNodes != null)
            {
                var updatedSitemaps = new List <Models.Sitemap>();
                foreach (var node in updatedNodes)
                {
                    Events.SitemapEvents.Instance.OnSitemapNodeUpdated(node);
                    if (!updatedSitemaps.Contains(node.Sitemap))
                    {
                        updatedSitemaps.Add(node.Sitemap);
                    }
                }

                foreach (var updatedSitemap in updatedSitemaps)
                {
                    Events.SitemapEvents.Instance.OnSitemapUpdated(updatedSitemap);
                }
            }

            return(new SavePageResponse(page));
        }
Example #29
0
        /// <summary>
        /// Executes the specified request.
        /// </summary>
        /// <param name="request">The page view model.</param>
        /// <returns>Created page</returns>
        public virtual SavePageResponse Execute(AddNewPageViewModel request)
        {
            if (request.CreateMasterPage)
            {
                AccessControlService.DemandAccess(Context.Principal, RootModuleConstants.UserRoles.Administration);
            }
            else
            {
                AccessControlService.DemandAccess(Context.Principal, RootModuleConstants.UserRoles.EditContent);
            }

            if (!request.MasterPageId.HasValue && !request.TemplateId.HasValue)
            {
                var message = RootGlobalization.MasterPage_Or_Layout_ShouldBeSelected_ValidationMessage;
                throw new ValidationException(() => message, message);
            }
            if (request.MasterPageId.HasValue && request.TemplateId.HasValue)
            {
                var logMessage = string.Format("Only one of master page and layout can be selected. LayoutId: {0}, MasterPageId: {1}", request.MasterPageId, request.TemplateId);
                var message    = RootGlobalization.MasterPage_Or_Layout_OnlyOne_ShouldBeSelected_ValidationMessage;
                throw new ValidationException(() => message, logMessage);
            }

            // Create / fix page url.
            var pageUrl       = request.PageUrl;
            var createPageUrl = pageUrl == null;

            if (createPageUrl && !string.IsNullOrWhiteSpace(request.PageTitle))
            {
                pageUrl = pageService.CreatePagePermalink(request.PageTitle, request.ParentPageUrl, null, request.LanguageId);
            }
            else
            {
                pageUrl = urlService.FixUrl(pageUrl);

                // Validate Url
                pageService.ValidatePageUrl(pageUrl);
            }

            var page = new PageProperties
            {
                PageUrl      = pageUrl,
                PageUrlHash  = pageUrl.UrlHash(),
                Title        = request.PageTitle,
                MetaTitle    = request.PageTitle,
                Status       = request.CreateMasterPage ? PageStatus.Published : PageStatus.Unpublished,
                IsMasterPage = request.CreateMasterPage
            };

            if (request.MasterPageId.HasValue)
            {
                page.MasterPage = Repository.AsProxy <Root.Models.Page>(request.MasterPageId.Value);

                masterPageService.SetPageMasterPages(page, request.MasterPageId.Value);
            }
            else
            {
                page.Layout = Repository.AsProxy <Root.Models.Layout>(request.TemplateId.Value);
            }

            if (cmsConfiguration.EnableMultilanguage)
            {
                if (request.LanguageId.HasValue && !request.LanguageId.Value.HasDefaultValue())
                {
                    page.Language = Repository.AsProxy <Language>(request.LanguageId.Value);
                }
            }

            page.Options = optionService.SaveOptionValues(request.OptionValues, null, () => new PageOption {
                Page = page
            });

            Repository.Save(page);

            // Update access control if enabled:
            if (cmsConfiguration.Security.AccessControlEnabled)
            {
                AccessControlService.UpdateAccessControl(page, request.UserAccessList != null ? request.UserAccessList.Cast <IAccessRule>().ToList() : null);
            }

            UnitOfWork.Commit();

            // Notifying, that page is created
            Events.PageEvents.Instance.OnPageCreated(page);

            var response = new SavePageResponse(page)
            {
                IsSitemapActionEnabled = ConfigurationHelper.IsSitemapActionEnabledAfterAddingNewPage(cmsConfiguration)
            };

            return(response);
        }
Example #30
0
        /// <summary>
        /// Executes the specified request.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <returns></returns>
        public SortPageContentResponse Execute(PageContentSortViewModel request)
        {
            var response = new SortPageContentResponse();

            UnitOfWork.BeginTransaction();

            #region Updated page content Order if needed.

            var pageQuery = Repository.AsQueryable <PageContent>().Where(f => f.Page.Id == request.PageId && f.Region.Id == request.RegionId);
            if (cmsConfiguration.Security.AccessControlEnabled)
            {
                pageQuery = pageQuery.Fetch(f => f.Page).ThenFetchMany(f => f.AccessRules);
            }
            var pageContents = pageQuery.ToList();

            // Demand access
            if (cmsConfiguration.Security.AccessControlEnabled)
            {
                if (pageContents.Count > 0)
                {
                    var page = pageContents[0].Page;

                    AccessControlService.DemandAccess(page, Context.Principal, AccessLevel.ReadWrite, RootModuleConstants.UserRoles.EditContent);
                }
            }
            else
            {
                AccessControlService.DemandAccess(Context.Principal, RootModuleConstants.UserRoles.EditContent);
            }

            var index = 0;
            foreach (var content in request.PageContents)
            {
                var pageContent = pageContents.FirstOrDefault(f => f.Id == content.Id);
                if (pageContent == null)
                {
                    throw new EntityNotFoundException(typeof(PageContent), Guid.Empty);
                }
                if (pageContent.Order != index)
                {
                    if (pageContent.Version != content.Version)
                    {
                        throw new ConcurrentDataException(pageContent);
                    }

                    pageContent.Order = index;
                    Repository.Save(pageContent);
                    response.UpdatedPageContents.Add(new ContentViewModel {
                        Id = pageContent.Id
                    });
                }
                index++;
            }
            #endregion

            #region Get page content updated versions.
            // NOTE: Maybe, it is logical to place this code after UnitOfWork.Commit(), but in this way, NHibernate generates less traffic to DB.
            pageContents = Repository.AsQueryable <PageContent>().Where(f => f.Page.Id == request.PageId && f.Region.Id == request.RegionId).ToList();
            foreach (var updatedPageContent in response.UpdatedPageContents)
            {
                var pageContent = pageContents.FirstOrDefault(f => f.Id == updatedPageContent.Id);
                if (pageContent == null)
                {
                    throw new CmsException(string.Format("Content was not found by id={0}.", updatedPageContent.Id));
                }
                updatedPageContent.Version = pageContent.Version;
            }
            #endregion

            UnitOfWork.Commit();

            return(response);
        }