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; }
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); }
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); } } }
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)); }
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)); } }
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); }
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; } }
public ActionResult Create() { var model = new BlogPostViewModel(); ViewBag.BlogId = new SelectList(blogService.FindAll(), "Id", "Title"); return View(model); }
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); }
/// <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); }