Example #1
0
 public BlogPostViewModel Update(BlogPostViewModel model)
 {
     IsAuthenticated();
     // todo sanitize tags
     _blogService.UpdatePost(new Post { Id = model.Id, Body = HtmlUtilities.Sanitize(model.Body), Title = HtmlUtilities.Sanitize(model.Title), Tags = model.Tags, CommentsEnabled = model.CommentsEnabled, Draft = model.IsDraft, EntryUpdateDate = DateTime.Now, EntryAddedDate = model.EntryAddedDate});
     return model;
 }
Example #2
0
 public BlogPostViewModel Create(BlogPostViewModel model)
 {
     IsAuthenticated();
     if (string.IsNullOrEmpty(model.Title))
     {
         throw new ItsaException("All posts must have a title");
     }
     var post = _blogService.CreatePost(new Post { Body = model.Body, Title = model.Title, Tags = model.Tags, EntryAddedDate = DateTime.Now, CommentsEnabled = model.CommentsEnabled, Draft = model.IsDraft });
     model.Id = post.Id;
     return model;
 }
        public ActionResult Create(BlogPostViewModel model)
        {
            if (ModelState.IsValid)
            {
                blogPostService.AddOrUpdate(model);

                var action = RedirectToAction("Index");
                return action.WithSuccess(string.Format("The blog post \"{0}\" has been added".TA(), model.Title));
            }
            ViewBag.BlogId = new SelectList(blogService.FindAll(), "Id", "Title");
            return View(model);
        }
Example #4
0
        protected override void MapExtraProperties(bool isNew, BlogPost entity, BlogPostContent content, PageContent pageContent, BlogPostViewModel model, IPrincipal principal)
        {
            var currentVersion = entity.Version;

            base.MapExtraProperties(isNew, entity, content, pageContent, model, principal);

            var modelExt = model as BlogPostViewModelExtender;

            if (modelExt != null)
            {
                // Restore version if not set from the extended model
                if (model.Version <= 0)
                {
                    entity.Version = currentVersion;
                }

                entity.SecondaryImage  = modelExt.SecondaryImageId.HasValue ? repository.AsProxy <MediaImage>(modelExt.SecondaryImageId.Value) : null;
                entity.FeaturedImage   = modelExt.FeaturedImageId.HasValue ? repository.AsProxy <MediaImage>(modelExt.FeaturedImageId.Value) : null;
                entity.IsArchived      = modelExt.IsArchived;
                entity.UseNoFollow     = modelExt.UseNoFollow;
                entity.UseNoIndex      = modelExt.UseNoIndex;
                entity.MetaKeywords    = modelExt.MetaKeywords;
                entity.MetaDescription = modelExt.MetaDescription;

                if (modelExt.UpdateLanguage)
                {
                    entity.Language = modelExt.LanguageId.HasValue ? repository.AsProxy <Language>(modelExt.LanguageId.Value) : null;
                    entity.LanguageGroupIdentifier = modelExt.LanguageGroupIdentifier;
                }

                // If creating new and content / page content / region ids are set, enforce them to be set explicitly
                if (isNew && !model.ContentId.HasDefaultValue() && modelExt.PageContentId.HasValue && modelExt.RegionId.HasValue)
                {
                    pageContent.Id     = modelExt.PageContentId.Value;
                    pageContent.Region = repository.AsProxy <Region>(modelExt.RegionId.Value);
                }

                // Set blog post Id, if it's set
                if (isNew && !model.Id.HasDefaultValue())
                {
                    entity.Id = model.Id;
                }

                // PublishedOn
                if (isNew && entity.Status == PageStatus.Published && modelExt.PublishedOn.HasValue)
                {
                    entity.PublishedOn = modelExt.PublishedOn.Value;
                }

                // Set layout / master page
                if (modelExt.MasterPageId.HasValue)
                {
                    entity.Layout = null;
                    if (isNew)
                    {
                        entity.MasterPage = repository
                                            .AsQueryable <Page>(p => p.Id == modelExt.MasterPageId.Value)
                                            .FetchMany(p => p.AccessRules)
                                            .ToList()
                                            .FirstOne();

                        if (modelExt.AccessRules == null)
                        {
                            AddDefaultAccessRules(entity, principal, entity.MasterPage);
                        }
                        masterPageService.SetPageMasterPages(entity, entity.MasterPage.Id);
                    }
                    else
                    {
                        entity.MasterPage = repository.AsProxy <Page>(modelExt.MasterPageId.Value);
                    }
                }
                else if (modelExt.LayoutId.HasValue)
                {
                    entity.Layout     = repository.AsProxy <Layout>(modelExt.LayoutId.Value);
                    entity.MasterPage = null;
                    if (isNew && modelExt.AccessRules == null)
                    {
                        AddDefaultAccessRules(entity, principal, null);
                    }
                }

                // Add access rules from the request
                if (modelExt.AccessRules != null)
                {
                    if (entity.AccessRules == null)
                    {
                        entity.AccessRules = new List <AccessRule>();
                    }
                    else
                    {
                        entity.AccessRules.RemoveDuplicateEntities();
                    }
                    var accessRules = modelExt.AccessRules
                                      .Select(r => (IAccessRule) new AccessRule
                    {
                        AccessLevel = (AccessLevel)(int)r.AccessLevel,
                        Identity    = r.Identity,
                        IsForRole   = r.IsForRole
                    }).ToList();

                    accessControlService.UpdateAccessControl(entity, accessRules);
                }
            }
        }
Example #5
0
        protected override BlogPostContent SaveContentWithStatusUpdate(bool isNew, BlogPostContent newContent, BlogPostViewModel model, IPrincipal principal)
        {
            var modelExt = model as BlogPostViewModelExtender;

            if (isNew && modelExt != null && !modelExt.ContentId.HasDefaultValue())
            {
                contentService.UpdateDynamicContainer(newContent);
                if (model.DesirableStatus == ContentStatus.Published)
                {
                    newContent.PublishedOn     = modelExt.PublishedOn ?? DateTime.Now;
                    newContent.PublishedByUser = principal.Identity.Name;
                    // TODO: pass published by user newContent.PublishedByUser = !string.IsNullOrEmpty(request.Data.PublishedByUser) ? request.Data.PublishedByUser : securityService.CurrentPrincipalName;
                }

                newContent.Status = model.DesirableStatus;
                newContent.Id     = modelExt.ContentId;
                repository.Save(newContent);

                return(newContent);
            }

            return(base.SaveContentWithStatusUpdate(isNew, newContent, model, principal));
        }
 protected virtual void ValidateData(bool isNew, BlogPostViewModel model)
 {
     // Do nothing
 }
 protected virtual void MapExtraProperties(bool isNew, BlogPost entity, BlogPostContent content, PageContent pageContent, BlogPostViewModel model, IPrincipal principal)
 {
     entity.Version = model.Version;
 }
 protected virtual void PrepareForUpdateChildrenMasterPages(bool isNew, BlogPost entity, BlogPostViewModel model, out IList <Guid> newMasterIds,
                                                            out IList <Guid> oldMasterIds, out IList <Guid> childrenPageIds, out IList <MasterPage> existingChildrenMasterPages)
 {
     newMasterIds                = null;
     oldMasterIds                = null;
     childrenPageIds             = null;
     existingChildrenMasterPages = null;
 }
 protected virtual BlogPostContent SaveContentWithStatusUpdate(bool isNew, BlogPostContent newContent, BlogPostViewModel request, IPrincipal principal)
 {
     return((BlogPostContent)contentService.SaveContentWithStatusUpdate(newContent, request.DesirableStatus));
 }
Example #10
0
        public ActionResult Edit(BlogPostViewModel viewModel, string submit)
        {
            if (ModelState.IsValid)
            {
                var repo = TechTruffleRepositoryFactory.Create();

                //handles the hashtags
                string[] hashTag = viewModel.StringHashtags.Split(' ');

                var hashTagRepo = repo.GetAllHashTags();

                foreach (var hash in hashTag)
                {
                    if (!hashTagRepo.Any(h => h.HashtagName == hash))
                    {
                        var newHash = new Hashtag();
                        newHash.HashtagName = hash;
                        repo.AddHashTag(newHash);
                    }

                    var hashToAdd = repo.GetAllHashTags().SingleOrDefault(h => h.HashtagName == hash);

                    if (viewModel.BlogPost.Hashtags == null)
                    {
                        viewModel.BlogPost.Hashtags = new List <Hashtag>();
                        viewModel.BlogPost.Hashtags.Add(hashToAdd);
                    }
                    else
                    {
                        viewModel.BlogPost.Hashtags.Add(hashToAdd);
                    }
                }

                //handles the blogcategory
                viewModel.BlogPost.BlogCategory = repo.GetBlogCategory(viewModel.BlogPost.BlogCategory.BlogCategoryId);

                //handles the Blog Status
                switch (submit)
                {
                case "Save":
                    viewModel.BlogPost.BlogStatus = repo.GetBlogStatus("Draft");
                    break;

                case "Post":
                    viewModel.BlogPost.BlogStatus = repo.GetBlogStatus("Pending");
                    break;

                case "Publish":
                    viewModel.BlogPost.BlogStatus = repo.GetBlogStatus("Published");
                    break;

                default:
                    break;
                }

                repo.EditBlogPost(viewModel.BlogPost);

                return(RedirectToAction("Blogs"));
            }
            else
            {
                viewModel.SetCategoryItems(TechTruffleRepositoryFactory.Create().GetAllBlogCategories());
                return(View(viewModel));
            }
        }
Example #11
0
        private List <BlogPostImportResult> ImportBlogPosts(IPrincipal principal, IDictionary <string, Guid> authors, IDictionary <string, Guid> categories,
                                                            List <BlogMLPost> blogs, List <BlogPostImportResult> modifications, bool createRedirects = false)
        {
            var createdBlogPosts = new List <BlogPostImportResult>();

            if (blogs != null)
            {
                foreach (var blogML in blogs)
                {
                    BlogPostViewModel blogPostModel = null;

                    try
                    {
                        blogPostModel = MapViewModel(blogML, modifications.First(m => m.Id == blogML.ID));

                        BlogPostImportResult blogPostResult = null;
                        if (!ValidateModel(blogPostModel, blogML, out blogPostResult))
                        {
                            createdBlogPosts.Add(blogPostResult);
                            continue;
                        }

                        if (blogML.Authors != null && blogML.Authors.Count > 0)
                        {
                            blogPostModel.AuthorId = authors[blogML.Authors[0].Ref];
                        }
                        if (blogML.Categories != null && blogML.Categories.Count > 0 && categories != null && categories.Count > 0)
                        {
                            for (var i = 0; i < blogML.Categories.Count; i++)
                            {
                                var category = blogML.Categories[i];

                                if (blogPostModel.Categories == null)
                                {
                                    blogPostModel.Categories = new List <LookupKeyValue>();
                                }

                                if (categories.ContainsKey(category.Ref))
                                {
                                    blogPostModel.Categories.Add(new LookupKeyValue()
                                    {
                                        Key = categories[category.Ref].ToLowerInvariantString()
                                    });
                                }
                            }
                        }

                        string[] error;
                        var      blogPost = blogService.SaveBlogPost(blogPostModel, null, principal, out error);
                        if (blogPost == null)
                        {
                            blogPostResult = new BlogPostImportResult
                            {
                                Title        = blogML.PostName ?? blogML.Title,
                                Success      = false,
                                ErrorMessage = error.Length > 0 ? error[0] : string.Empty
                            };
                            createdBlogPosts.Add(blogPostResult);

                            continue;
                        }

                        blogPostResult = new BlogPostImportResult
                        {
                            Title   = blogML.PostName ?? blogML.Title,
                            PageUrl = blogPost.PageUrl,
                            Id      = blogPost.Id.ToString(),
                            Success = true
                        };
                        createdBlogPosts.Add(blogPostResult);

                        if (createRedirects)
                        {
                            var oldUrl = TryValidateOldUrl(blogML.PostUrl);
                            if (oldUrl != null && oldUrl != blogPostModel.BlogUrl)
                            {
                                var redirect = redirectService.GetPageRedirect(oldUrl);
                                if (redirect == null)
                                {
                                    redirect = redirectService.CreateRedirectEntity(oldUrl, blogPostModel.BlogUrl);
                                    repository.Save(redirect);
                                    unitOfWork.Commit();
                                    Events.PageEvents.Instance.OnRedirectCreated(redirect);
                                }
                                else
                                {
                                    blogPostResult.WarnMessage = string.Format(BlogGlobalization.ImportBlogPosts_RedirectWasAlreadyCreatedFor_Message, blogML.PostUrl);
                                }
                            }
                            else if (oldUrl == null)
                            {
                                blogPostResult.WarnMessage = string.Format(BlogGlobalization.ImportBlogPosts_FailedToCreateRedirectFor_Message, blogML.PostUrl);
                            }
                        }
                    }
                    catch (Exception exc)
                    {
                        var failedBlogPost = new BlogPostImportResult
                        {
                            Title        = blogML.PostName ?? blogML.Title,
                            PageUrl      = blogPostModel != null && blogPostModel.BlogUrl != null ? blogPostModel.BlogUrl : blogML.PostUrl,
                            Success      = false,
                            ErrorMessage = exc.Message,
                            Id           = blogML.ID
                        };
                        createdBlogPosts.Add(failedBlogPost);

                        Log.Error("Failed to import blog post.", exc);
                    }
                }
            }

            return(createdBlogPosts);
        }
Example #12
0
        public ActionResult BlogPosts(string categoria, string blog, int p = 1)
        {
            if (categoria == null || blog == null)
            {
                return(new HttpStatusCodeResult(HttpStatusCode.NotFound));
            }

            var objBlog = Db.Blogs.FirstOrDefault(b => b.Url == blog);

            if (objBlog == null)
            {
                return(new HttpStatusCodeResult(HttpStatusCode.NotFound));
            }

            if (objBlog.Categoria.Url != categoria)
            {
                return(new RedirectResult($"/blogs/{objBlog.Categoria.Url}/{objBlog.Url}/posts/", true));
            }

            ViewBag.TotalRegistros = objBlog.Noticias.Count;

            //Get the list of blog autors
            var lstAutors = Autor.GetAllByBlogId(objBlog.Id).ToList();

            //Set the path in the images
            lstAutors.ForEach(a => a.Avatar = $"{Constants.UrlDominioEstaticoUploads}/{"autores"}/{a.Avatar}");

            var model = new BlogPostViewModel
            {
                Blog   = objBlog,
                Autors = lstAutors
            };

            model.Blog.Noticias = objBlog.Noticias.Where(post => post.StatusId == Status.Publicada.Id)
                                  .OrderByDescending(b => b.DataPublicacao)
                                  .Skip((p - 1) * Constants.TakeNoticias)
                                  .Take(Constants.TakeNoticias)
                                  .ToList();

            //Paginação
            ViewBag.PaginaAtual = p;

            var totalPaginas = Math.Ceiling(((double)ViewBag.TotalRegistros / Constants.TakeNoticias));

            if (Convert.ToInt32(totalPaginas) > 1)
            {
                ViewBag.Paginacao = Pagination.AddPagination(ViewBag.PaginaAtual, Convert.ToInt32(totalPaginas), 5, true);
            }

            //base model defaults
            model.Title        = $"Blog {objBlog.Titulo} - Massa News";
            model.Description  = $"{objBlog.Descricao} Confira o Blog {objBlog.Titulo}!";
            model.Robots       = "index, follow";
            model.Canonical    = $"{Constants.UrlWeb}/blogs/{categoria}/{blog}/posts";
            model.ImgOpenGraph = $"{Constants.UrlWeb}/content/images/avatar/blogs/{blog}.jpg";

            ViewBag.ActiveNav = objBlog.Titulo;

            // Página
            ViewBag.Pagina = "blog";

            // Editoria
            ViewBag.EditoriaUrl = "blogs";

            // Categoria
            ViewBag.Categoria = model.Blog.Categoria.Url;

            // Blog
            ViewBag.Blog = model.Blog.Url;

            return(View(model));
        }
        protected override void GetBlogPostAndContentEntities(BlogPostViewModel model, IPrincipal principal, string[] roles,
                                                              ref bool isNew, out BlogPostContent content, out PageContent pageContent, out BlogPost blogPost)
        {
            var modelExt = model as BlogPostViewModelExtender;

            if (!isNew && modelExt != null)
            {
                content     = null;
                pageContent = null;

                blogPost = repository
                           .AsQueryable <BlogPost>(bp => bp.Id == model.Id)
                           .FetchMany(bp => bp.AccessRules)
                           .FetchMany(bp => bp.PageTags)
                           .ThenFetch(pt => pt.Tag)
                           .ToList()
                           .FirstOrDefault();

                if (blogPost != null)
                {
                    if (configuration.Security.AccessControlEnabled)
                    {
                        accessControlService.DemandAccess(blogPost, principal, AccessLevel.ReadWrite, roles);
                    }

                    if (modelExt.PageContentId.HasValue)
                    {
                        content = repository
                                  .AsQueryable <BlogPostContent>(c => c.PageContents.Any(x => x.Page.Id == model.Id &&
                                                                                         !x.IsDeleted && x.Id == modelExt.PageContentId.Value &&
                                                                                         !x.IsDeleted && c.Id == model.ContentId))
                                  .ToFuture()
                                  .FirstOrDefault();

                        if (content == null)
                        {
                            const string message    = "Cannot find a blog post content by specified blog post content and Id and page content Id.";
                            var          logMessage = string.Format("{0} BlogId: {1}, BlogPostContentId: {2}, PageContentId: {3}",
                                                                    message, model.Id, model.ContentId, modelExt.PageContentId);
                            throw new ValidationException(() => message, logMessage);
                        }

                        pageContent = repository.First <PageContent>(pc => pc.Id == modelExt.PageContentId.Value);
                    }
                    else
                    {
                        content = repository
                                  .AsQueryable <BlogPostContent>(c => c.PageContents.Any(x => x.Page.Id == model.Id && !x.IsDeleted) && !c.IsDeleted)
                                  .ToFuture()
                                  .FirstOrDefault();

                        if (content != null)
                        {
                            var contentRef = content;
                            pageContent = repository.FirstOrDefault <PageContent>(c => c.Page.Id == model.Id && !c.IsDeleted && c.Content == contentRef);
                        }
                    }
                }

                isNew = blogPost == null;
                if (isNew)
                {
                    blogPost    = new BlogPost();
                    pageContent = new PageContent {
                        Page = blogPost
                    };
                }
            }
            else
            {
                base.GetBlogPostAndContentEntities(model, principal, roles, ref isNew, out content, out pageContent, out blogPost);
            }
        }
        protected override void PrepareForUpdateChildrenMasterPages(bool isNew, BlogPost entity, BlogPostViewModel model, out IList <Guid> newMasterIds,
                                                                    out IList <Guid> oldMasterIds, out IList <Guid> childrenPageIds, out IList <MasterPage> existingChildrenMasterPages)
        {
            var modelExt = model as BlogPostViewModelExtender;

            if (!isNew && modelExt != null)
            {
                masterPageService.PrepareForUpdateChildrenMasterPages(entity, modelExt.MasterPageId,
                                                                      out newMasterIds, out oldMasterIds, out childrenPageIds, out existingChildrenMasterPages);
            }
            else
            {
                newMasterIds                = null;
                oldMasterIds                = null;
                childrenPageIds             = null;
                existingChildrenMasterPages = null;
            }
        }
Example #15
0
 public ActionResult Create()
 {
     var model = new BlogPostViewModel();
     ViewBag.BlogId = new SelectList(blogService.FindAll(), "Id", "Title");
     return View(model);
 }
Example #16
0
        public ActionResult CreateBlog(BlogPostViewModel viewModel, string submit)
        {
            if (ModelState.IsValid)
            {
                var repo = TechTruffleRepositoryFactory.Create();

                //handles users
                var authUserName = User.Identity.GetUserName();
                viewModel.BlogPost.User          = new ApplicationUser();
                viewModel.BlogPost.User.UserName = authUserName;

                //handles the hashtags
                string[] hashTag = viewModel.StringHashtags.Split(' ');

                var hashTagEntity = repo.GetAllHashTags();

                viewModel.BlogPost.Hashtags = new List <Hashtag>();

                foreach (var hash in hashTag)
                {
                    var ht = hashTagEntity.FirstOrDefault(i => i.HashtagName == hash);

                    if (ht == null)
                    {
                        var newHash = new Hashtag();
                        newHash.HashtagName = hash;
                        viewModel.BlogPost.Hashtags.Add(newHash);
                    }
                    else
                    {
                        viewModel.BlogPost.Hashtags.Add(ht);
                    }
                }

                //handles the blogcategory
                viewModel.BlogPost.BlogCategory = repo.GetBlogCategory(viewModel.BlogPost.BlogCategory.BlogCategoryId);

                //handles date

                //handles the Blog Status
                switch (submit)
                {
                case "Save":
                    viewModel.BlogPost.BlogStatus = repo.GetBlogStatus("Draft");
                    break;

                case "Post":
                    viewModel.BlogPost.BlogStatus = repo.GetBlogStatus("Pending");
                    break;

                case "Publish":
                    viewModel.BlogPost.BlogStatus = repo.GetBlogStatus("Published");
                    break;

                default:
                    break;
                }

                repo.CreateNewBlogPost(viewModel.BlogPost);

                return(RedirectToAction("Blogs"));
            }
            else
            {
                viewModel.SetCategoryItems(TechTruffleRepositoryFactory.Create().GetAllBlogCategories());
                return(View(viewModel));
            }
        }
        /// <summary>
        /// Saves the blog post.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <param name="childContentOptionValues">The child content option values.</param>
        /// <param name="principal">The principal.</param>
        /// <param name="errorMessages">The error messages.</param>
        /// <param name="updateActivationIfNotChanged">if set to <c>true</c> update activation time even if it was not changed.</param>
        /// <returns>
        /// Saved blog post entity
        /// </returns>
        /// <exception cref="System.ComponentModel.DataAnnotations.ValidationException"></exception>
        /// <exception cref="SecurityException">Forbidden: Access is denied.</exception>
        public BlogPost SaveBlogPost(BlogPostViewModel request, IList <ContentOptionValuesViewModel> childContentOptionValues, IPrincipal principal, out string[] errorMessages, bool updateActivationIfNotChanged = true)
        {
            errorMessages = new string[0];
            string[] roles;
            if (request.DesirableStatus == ContentStatus.Published)
            {
                accessControlService.DemandAccess(principal, RootModuleConstants.UserRoles.PublishContent);
                roles = new[] { RootModuleConstants.UserRoles.PublishContent };
            }
            else
            {
                accessControlService.DemandAccess(principal, RootModuleConstants.UserRoles.EditContent);
                roles = new[] { RootModuleConstants.UserRoles.EditContent };
            }

            var isNew       = request.Id.HasDefaultValue();
            var userCanEdit = securityService.IsAuthorized(RootModuleConstants.UserRoles.EditContent);

            ValidateData(isNew, request);

            BlogPost        blogPost;
            BlogPostContent content;
            PageContent     pageContent;

            GetBlogPostAndContentEntities(request, principal, roles, ref isNew, out content, out pageContent, out blogPost);
            var beforeChange = new UpdatingBlogModel(blogPost);

            // Master page / layout
            Layout layout;
            Page   masterPage;
            Region region;

            LoadDefaultLayoutAndRegion(out layout, out masterPage, out region);

            if (masterPage != null)
            {
                var level = accessControlService.GetAccessLevel(masterPage, principal);
                if (level < AccessLevel.Read)
                {
                    var          message    = BlogGlobalization.SaveBlogPost_FailedToSave_InaccessibleMasterPage;
                    const string logMessage = "Failed to save blog post. Selected master page for page layout is inaccessible.";
                    throw new ValidationException(() => message, logMessage);
                }
            }

            if (pageContent.Region == null)
            {
                pageContent.Region = region;
            }

            // 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;

            PrepareForUpdateChildrenMasterPages(isNew, blogPost, request, out newMasterIds, out oldMasterIds, out childrenPageIds, out existingChildrenMasterPages);

            // TODO: TEST AND TRY TO FIX IT: TRANSACTION HERE IS REQUIRED!
            // UnitOfWork.BeginTransaction(); // NOTE: this causes concurrent data exception.

            Redirect redirectCreated = null;

            if (!isNew && userCanEdit && !string.Equals(blogPost.PageUrl, request.BlogUrl) && !string.IsNullOrWhiteSpace(request.BlogUrl))
            {
                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);
            }

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

            if (userCanEdit)
            {
                blogPost.Title       = request.Title;
                blogPost.Description = request.IntroText;
                blogPost.Author      = request.AuthorId.HasValue ? repository.AsProxy <Author>(request.AuthorId.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)
                {
                    if (updateActivationIfNotChanged)
                    {
                        blogPost.ActivationDate = request.LiveFromDate;
                        blogPost.ExpirationDate = TimeHelper.FormatEndDate(request.LiveToDate);
                    }
                    else
                    {
                        blogPost.ActivationDate = TimeHelper.GetFirstIfTheSameDay(blogPost.ActivationDate, request.LiveFromDate);
                        blogPost.ExpirationDate = TimeHelper.GetFirstIfTheSameDay(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 = CreateBlogPermalink(request.Title, null, request.Categories != null ? request.Categories.Select(c => Guid.Parse(c.Key)) : null);
                }

                blogPost.MetaTitle = request.MetaTitle ?? request.Title;
                if (masterPage != null)
                {
                    blogPost.MasterPage = masterPage;
                    masterPageService.SetPageMasterPages(blogPost, masterPage.Id);
                }
                else
                {
                    blogPost.Layout = layout;
                }
                UpdateStatus(blogPost, request.DesirableStatus);
                AddDefaultAccessRules(blogPost, principal, masterPage);
            }
            else if (request.DesirableStatus == ContentStatus.Published ||
                     blogPost.Status == PageStatus.Preview)
            {
                // Update only if publishing or current status is preview.
                // Else do not change, because it may change from published to draft status
                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,
                OriginalText     = request.OriginalText,
                EditInSourceMode = request.EditInSourceMode,
                ActivationDate   = request.LiveFromDate,
                ExpirationDate   = TimeHelper.FormatEndDate(request.LiveToDate),
                ContentTextMode  = request.ContentTextMode,
            };

            if (!updateActivationIfNotChanged && content != null)
            {
                newContent.ActivationDate = TimeHelper.GetFirstIfTheSameDay(content.ActivationDate, newContent.ActivationDate);
                newContent.ExpirationDate = TimeHelper.GetFirstIfTheSameDay(content.ExpirationDate, newContent.ExpirationDate);
            }

            if (request.ContentTextMode == ContentTextMode.Markdown &&
                request.Content == null &&
                request.OriginalText != null)
            {
                newContent.Html = MarkdownConverter.ToHtml(request.OriginalText);
            }

            // 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;
                newContent.ContentTextMode = contentToPublish.ContentTextMode;
                newContent.OriginalText    = contentToPublish.OriginalText;
            }

            content             = SaveContentWithStatusUpdate(isNew, newContent, request, principal);
            pageContent.Content = content;
            optionService.SaveChildContentOptions(content, childContentOptionValues, request.DesirableStatus);

            blogPost.PageUrlHash     = blogPost.PageUrl.UrlHash();
            blogPost.UseCanonicalUrl = request.UseCanonicalUrl;

            MapExtraProperties(isNew, blogPost, content, pageContent, request, principal);

            // Notify about page properties changing.
            var cancelEventArgs = Events.BlogEvents.Instance.OnBlogChanging(beforeChange, new UpdatingBlogModel(blogPost));

            if (cancelEventArgs.Cancel)
            {
                errorMessages = cancelEventArgs.CancellationErrorMessages.ToArray();
                return(null);
            }

            if (isNew || userCanEdit)
            {
                categoryService.CombineEntityCategories <BlogPost, PageCategory>(blogPost, request.Categories);
            }

            repository.Save(blogPost);
            repository.Save(content);
            repository.Save(pageContent);

            masterPageService.UpdateChildrenMasterPages(existingChildrenMasterPages, oldMasterIds, newMasterIds, childrenPageIds);

            pageContent.Content   = content;
            blogPost.PageContents = new [] { pageContent };

            IList <Tag> newTags = null;

            if (userCanEdit)
            {
                newTags = SaveTags(blogPost, request);
            }

            // Commit
            unitOfWork.Commit();

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

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

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

            return(blogPost);
        }
Example #18
0
        /// <summary>
        /// Saves the blog post.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <param name="principal">The principal.</param>
        /// <returns>
        /// Saved blog post entity
        /// </returns>
        public BlogPost SaveBlogPost(BlogPostViewModel request, IPrincipal principal)
        {
            string[] roles;
            if (request.DesirableStatus == ContentStatus.Published)
            {
                accessControlService.DemandAccess(principal, RootModuleConstants.UserRoles.PublishContent);
                roles = new[] { RootModuleConstants.UserRoles.PublishContent };
            }
            else
            {
                accessControlService.DemandAccess(principal, RootModuleConstants.UserRoles.EditContent);
                roles = new[] { RootModuleConstants.UserRoles.EditContent };
            }

            Layout layout;
            Page   masterPage;

            LoadLayout(out layout, out masterPage);

            if (masterPage != null)
            {
                var level = accessControlService.GetAccessLevel(masterPage, principal);
                if (level < AccessLevel.Read)
                {
                    var          message    = BlogGlobalization.SaveBlogPost_FailedToSave_InaccessibleMasterPage;
                    const string logMessage = "Failed to save blog post. Selected master page for page layout is inaccessible.";
                    throw new ValidationException(() => message, logMessage);
                }
            }

            var region      = LoadRegion(layout, masterPage);
            var isNew       = request.Id.HasDefaultValue();
            var 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)
            {
                var blogPostFuture = repository
                                     .AsQueryable <BlogPost>(b => b.Id == request.Id)
                                     .ToFuture();

                content = repository
                          .AsQueryable <BlogPostContent>(c => c.PageContents.Any(x => x.Page.Id == request.Id && !x.IsDeleted))
                          .ToFuture()
                          .FirstOrDefault();

                blogPost = blogPostFuture.FirstOne();

                if (cmsConfiguration.Security.AccessControlEnabled)
                {
                    accessControlService.DemandAccess(blogPost, principal, AccessLevel.ReadWrite, roles);
                }

                if (content != null)
                {
                    // Check if user has confirmed the deletion of content
                    if (!request.IsUserConfirmed && blogPost.IsMasterPage)
                    {
                        var hasAnyChildren = contentService.CheckIfContentHasDeletingChildren(blogPost.Id, content.Id, request.Content);
                        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. ContentId: {0}, PageId: {1}",
                                                           content.Id, blogPost.Id);
                            throw new ConfirmationRequestException(() => message, logMessage);
                        }
                    }

                    pageContent = repository.FirstOrDefault <PageContent>(c => c.Page == blogPost && !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();
            }

            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 = CreateBlogPermalink(request.Title);
                }

                blogPost.MetaTitle = request.MetaTitle ?? request.Title;
                if (masterPage != null)
                {
                    blogPost.MasterPage = masterPage;
                    masterPageService.SetPageMasterPages(blogPost, masterPage.Id);
                }
                else
                {
                    blogPost.Layout = layout;
                }
                UpdateStatus(blogPost, request.DesirableStatus);
                AddDefaultAccessRules(blogPost, principal, masterPage);
            }
            else if (request.DesirableStatus == ContentStatus.Published ||
                     blogPost.Status == PageStatus.Preview)
            {
                // Update only if publishing or current status is preview.
                // Else do not change, because it may change from published to draft status
                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);

            pageContent.Content   = content;
            blogPost.PageContents = new [] { pageContent };

            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(blogPost);
        }