public async Task <IActionResult> Edit(PageEditViewModel model) { if (!ModelState.IsValid) { if (string.IsNullOrEmpty(model.Id)) { ViewData["Title"] = sr["New Page"]; } else { ViewData["Title"] = string.Format(CultureInfo.CurrentUICulture, sr["Edit - {0}"], model.Title); } return(View(model)); } var project = await projectService.GetCurrentProjectSettings(); if (project == null) { log.LogInformation("redirecting to index because project settings not found"); return(RedirectToRoute(pageRoutes.PageRouteName)); } var canEdit = await User.CanEditPages(project.Id, authorizationService); if (!canEdit) { log.LogInformation("redirecting to index because user is not allowed to edit"); return(RedirectToRoute(pageRoutes.PageRouteName)); } IPage page = null; if (!string.IsNullOrEmpty(model.Id)) { page = await pageService.GetPage(model.Id); } var needToClearCache = false; var isNew = false; string slug = string.Empty;; bool slugIsAvailable = false; if (page != null) { if ((!string.IsNullOrEmpty(page.ViewRoles))) { if (!User.IsInRoles(page.ViewRoles)) { log.LogWarning($"page {page.Title} is protected by roles that user is not in so redirecting"); return(RedirectToRoute(pageRoutes.PageRouteName)); } } if (page.Title != model.Title) { needToClearCache = true; } page.Title = model.Title; page.MetaDescription = model.MetaDescription; page.Content = model.Content; if (page.IsPublished != model.IsPublished) { needToClearCache = true; } if (page.PageOrder != model.PageOrder) { needToClearCache = true; } if (!string.IsNullOrEmpty(model.Slug)) { // remove any bad characters model.Slug = ContentUtils.CreateSlug(model.Slug); if (model.Slug != page.Slug) { slugIsAvailable = await pageService.SlugIsAvailable(model.Slug); if (slugIsAvailable) { page.Slug = model.Slug; needToClearCache = true; } else { this.AlertDanger(sr["The page slug was not changed because the requested slug is already in use."], true); } } } } else { isNew = true; needToClearCache = true; if (!string.IsNullOrEmpty(model.Slug)) { // remove any bad chars model.Slug = ContentUtils.CreateSlug(model.Slug); slugIsAvailable = await pageService.SlugIsAvailable(model.Slug); if (slugIsAvailable) { slug = model.Slug; } } if (string.IsNullOrEmpty(slug)) { slug = ContentUtils.CreateSlug(model.Title); } slugIsAvailable = await pageService.SlugIsAvailable(slug); if (!slugIsAvailable) { model.DisqusShortname = project.DisqusShortName; //log.LogInformation("returning 409 because slug already in use"); ModelState.AddModelError("pageediterror", sr["slug is already in use."]); return(View(model)); } page = new Page() { ProjectId = project.Id, Author = await authorNameResolver.GetAuthorName(User), Title = model.Title, MetaDescription = model.MetaDescription, Content = model.Content, Slug = slug, ParentId = "0" //,Categories = categories.ToList() }; } if (!string.IsNullOrEmpty(model.ParentSlug)) { var parentPage = await pageService.GetPageBySlug(model.ParentSlug); if (parentPage != null) { if (parentPage.Id != page.ParentId) { page.ParentId = parentPage.Id; page.ParentSlug = parentPage.Slug; needToClearCache = true; } } } else { // empty means root level page.ParentSlug = string.Empty; page.ParentId = "0"; } if (page.ViewRoles != model.ViewRoles) { needToClearCache = true; } page.ViewRoles = model.ViewRoles; page.CorrelationKey = model.CorrelationKey; page.PageOrder = model.PageOrder; page.IsPublished = model.IsPublished; page.ShowHeading = model.ShowHeading; page.ShowMenu = model.ShowMenu; page.MenuOnly = model.MenuOnly; page.ShowComments = model.ShowComments; if (page.MenuFilters != model.MenuFilters) { needToClearCache = true; } page.MenuFilters = model.MenuFilters; if (page.ExternalUrl != model.ExternalUrl) { needToClearCache = true; } page.ExternalUrl = model.ExternalUrl; if (!string.IsNullOrEmpty(model.Author)) { page.Author = model.Author; } if (!string.IsNullOrEmpty(model.PubDate)) { var localTime = DateTime.Parse(model.PubDate); page.PubDate = timeZoneHelper.ConvertToUtc(localTime, project.TimeZoneId); } if (page.ProjectId != project.Id) { page.ProjectId = project.Id; } if (isNew) { await pageService.Create(page, model.IsPublished); this.AlertSuccess(sr["The page was created successfully."], true); } else { await pageService.Update(page, model.IsPublished); this.AlertSuccess(sr["The page was updated successfully."], true); } if (needToClearCache) { pageService.ClearNavigationCache(); } if (page.Slug == project.DefaultPageSlug) { return(RedirectToRoute(pageRoutes.PageRouteName, new { slug = "" })); } if (!string.IsNullOrEmpty(page.ExternalUrl)) { this.AlertWarning(sr["Note that since this page has an override url, the menu item will link to the url so the page is used only as a means to add a link in the menu, the content is not used."], true); return(RedirectToRoute(pageRoutes.PageEditRouteName, new { slug = page.Slug })); } //var url = Url.RouteUrl(pageRoutes.PageRouteName, new { slug = page.Slug }); return(RedirectToRoute(pageRoutes.PageRouteName, new { slug = page.Slug })); //return Content(url); }
public async Task <CommandResult <IPage> > Handle(UpdateTemplatedPageRequest request, CancellationToken cancellationToken = default(CancellationToken)) { var errors = new List <string>(); var customModelIsValid = true; try { var page = request.Page; var history = page.CreateHistory(request.UserName); var project = await _projectService.GetProjectSettings(request.ProjectId); var serializer = GetSerializer(request.Template.SerializerName); var parser = GetFormParser(request.Template.FormParserName); var validator = GetValidator(request.Template.ValidatorName); var type = Type.GetType(request.Template.ModelType); var model = parser.ParseModel(request.Template.ModelType, request.Form); if (model == null) { errors.Add(_localizer["Failed to parse custom template model from form."]); customModelIsValid = false; //failed to parse model from form // at least return the original model before changes string pageModelString; if (!string.IsNullOrWhiteSpace(page.DraftSerializedModel)) { pageModelString = page.DraftSerializedModel; } else { pageModelString = page.SerializedModel; } if (!string.IsNullOrWhiteSpace(pageModelString)) { request.ViewModel.TemplateModel = serializer.Deserialize(request.Template.ModelType, pageModelString); } } if (customModelIsValid) { // we are going to return the parsed model either way request.ViewModel.TemplateModel = model; var validationContext = new ValidationContext(model, serviceProvider: null, items: null); var validationResults = new List <ValidationResult>(); customModelIsValid = validator.IsValid(model, validationContext, validationResults); if (!customModelIsValid) { foreach (var item in validationResults) { foreach (var memberName in item.MemberNames) { request.ModelState.AddModelError(memberName, item.ErrorMessage); } } } } if (!string.IsNullOrEmpty(request.ViewModel.Slug)) { // remove any bad characters request.ViewModel.Slug = ContentUtils.CreateSlug(request.ViewModel.Slug); if (request.ViewModel.Slug != page.Slug) { var slugIsAvailable = await _pageService.SlugIsAvailable(request.ViewModel.Slug); if (!slugIsAvailable) { errors.Add(_localizer["The page slug was not changed because the requested slug is already in use."]); request.ModelState.AddModelError("Slug", _localizer["The page slug was not changed because the requested slug is already in use."]); } } } if (request.ModelState.IsValid) { var modelString = serializer.Serialize(request.Template.ModelType, model); var renderedModel = await _viewRenderer.RenderViewAsString(request.Template.RenderView, model).ConfigureAwait(false); page.Title = request.ViewModel.Title; page.CorrelationKey = request.ViewModel.CorrelationKey; page.LastModified = DateTime.UtcNow; page.LastModifiedByUser = request.UserName; page.MenuFilters = request.ViewModel.MenuFilters; page.MetaDescription = request.ViewModel.MetaDescription; page.PageOrder = request.ViewModel.PageOrder; page.ShowHeading = request.ViewModel.ShowHeading; page.ShowMenu = request.ViewModel.ShowMenu; page.ShowComments = request.ViewModel.ShowComments; page.MenuFilters = request.ViewModel.MenuFilters; page.ViewRoles = request.ViewModel.ViewRoles; if (!string.IsNullOrEmpty(request.ViewModel.Slug)) { page.Slug = request.ViewModel.Slug; } page.ViewRoles = request.ViewModel.ViewRoles; if (!string.IsNullOrEmpty(request.ViewModel.ParentSlug)) { var parentPage = await _pageService.GetPageBySlug(request.ViewModel.ParentSlug); if (parentPage != null) { if (parentPage.Id != page.ParentId) { page.ParentId = parentPage.Id; page.ParentSlug = parentPage.Slug; } } } else { // empty means root level page.ParentSlug = string.Empty; page.ParentId = "0"; } if (page.ParentSlug == project.DefaultPageSlug) { _log.LogWarning($"{request.UserName} tried to explicitely set the default page slug as the parent slug which is not allowed since all root pages are already children of the default page"); page.ParentSlug = string.Empty; page.ParentId = "0"; } var shouldFirePublishEvent = false; switch (request.ViewModel.SaveMode) { case SaveMode.SaveDraft: page.DraftSerializedModel = modelString; page.DraftContent = renderedModel; page.DraftAuthor = request.ViewModel.Author; if (!page.PubDate.HasValue) { page.IsPublished = false; } break; case SaveMode.PublishLater: page.DraftSerializedModel = modelString; page.DraftContent = renderedModel; page.DraftAuthor = request.ViewModel.Author; if (request.ViewModel.NewPubDate.HasValue) { var tzId = await _timeZoneIdResolver.GetUserTimeZoneId(CancellationToken.None); page.DraftPubDate = _timeZoneHelper.ConvertToUtc(request.ViewModel.NewPubDate.Value, tzId); } if (!page.PubDate.HasValue) { page.IsPublished = false; } break; case SaveMode.PublishNow: page.Author = request.ViewModel.Author; page.Content = renderedModel; page.SerializedModel = modelString; page.PubDate = DateTime.UtcNow; page.IsPublished = true; shouldFirePublishEvent = true; page.DraftAuthor = null; page.DraftContent = null; page.DraftPubDate = null; page.DraftSerializedModel = null; break; } await _historyCommands.Create(request.ProjectId, history).ConfigureAwait(false); await _pageService.Update(page); if (shouldFirePublishEvent) { await _pageService.FirePublishEvent(page).ConfigureAwait(false); await _historyCommands.DeleteDraftHistory(project.Id, page.Id).ConfigureAwait(false); } await _navigationCache.ClearTreeCache(); } return(new CommandResult <IPage>(page, customModelIsValid && request.ModelState.IsValid, errors)); } catch (Exception ex) { _log.LogError($"{ex.Message}:{ex.StackTrace}"); errors.Add(_localizer["Updating a page from a content template failed. An error has been logged."]); return(new CommandResult <IPage>(null, false, errors)); } }
public async Task <IActionResult> Edit(PostEditViewModel model) { if (!ModelState.IsValid) { if (string.IsNullOrEmpty(model.Id)) { ViewData["Title"] = sr["New Post"]; } else { ViewData["Title"] = string.Format(CultureInfo.CurrentUICulture, sr["Edit - {0}"], model.Title); } return(View(model)); } var project = await projectService.GetCurrentProjectSettings(); if (project == null) { log.LogInformation("redirecting to index because project settings not found"); return(RedirectToRoute(blogRoutes.BlogIndexRouteName)); } var canEdit = await User.CanEditPages(project.Id, authorizationService); if (!canEdit) { log.LogInformation("redirecting to index because user is not allowed to edit"); return(RedirectToRoute(blogRoutes.BlogIndexRouteName)); } var categories = new List <string>(); if (!string.IsNullOrEmpty(model.Categories)) { if (config.ForceLowerCaseCategories) { categories = model.Categories.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim().ToLower()) .Where(x => !string.IsNullOrWhiteSpace(x) && x != "," ) .Distinct() .ToList(); } else { categories = model.Categories.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()) .Where(x => !string.IsNullOrWhiteSpace(x) && x != "," ) .Distinct() .ToList(); } } IPost post = null; if (!string.IsNullOrEmpty(model.Id)) { post = await blogService.GetPost(model.Id); } var isNew = false; bool slugAvailable; string slug; if (post != null) { post.Title = model.Title; post.MetaDescription = model.MetaDescription; post.Content = model.Content; post.Categories = categories; if (model.Slug != post.Slug) { // remove any bad chars model.Slug = ContentUtils.CreateSlug(model.Slug); slugAvailable = await blogService.SlugIsAvailable(project.Id, model.Slug); if (slugAvailable) { post.Slug = model.Slug; } else { //log.LogWarning($"slug {model.Slug} was requested but not changed because it is already in use"); this.AlertDanger(sr["The post slug was not changed because the requested slug is already in use."], true); } } } else { isNew = true; if (!string.IsNullOrEmpty(model.Slug)) { // remove any bad chars model.Slug = ContentUtils.CreateSlug(model.Slug); slug = model.Slug; slugAvailable = await blogService.SlugIsAvailable(project.Id, slug); if (!slugAvailable) { slug = ContentUtils.CreateSlug(model.Title); } } else { slug = ContentUtils.CreateSlug(model.Title); } slugAvailable = await blogService.SlugIsAvailable(project.Id, slug); if (!slugAvailable) { //log.LogInformation("returning 409 because slug already in use"); ModelState.AddModelError("postediterror", sr["slug is already in use."]); return(View(model)); } post = new Post() { BlogId = project.Id, Author = await authorNameResolver.GetAuthorName(User), Title = model.Title, MetaDescription = model.MetaDescription, Content = model.Content, Slug = slug , Categories = categories.ToList() }; } if (!string.IsNullOrEmpty(model.Author)) { post.Author = model.Author; } post.IsPublished = model.IsPublished; post.CorrelationKey = model.CorrelationKey; post.ImageUrl = model.ImageUrl; post.ThumbnailUrl = model.ThumbnailUrl; post.IsFeatured = model.IsFeatured; if (!string.IsNullOrEmpty(model.PubDate)) { var localTime = DateTime.Parse(model.PubDate); post.PubDate = timeZoneHelper.ConvertToUtc(localTime, project.TimeZoneId); } if (isNew) { await blogService.Create(post); } else { await blogService.Update(post); } if (project.IncludePubDateInPostUrls) { return(RedirectToRoute(blogRoutes.PostWithDateRouteName, new { year = post.PubDate.Year, month = post.PubDate.Month.ToString("00"), day = post.PubDate.Day.ToString("00"), slug = post.Slug })); } else { return(RedirectToRoute(blogRoutes.PostWithoutDateRouteName, new { slug = post.Slug })); } }
public async Task <CommandResult <IPost> > Handle(CreateOrUpdatePostRequest request, CancellationToken cancellationToken = default(CancellationToken)) { var errors = new List <string>(); try { bool isNew = false; var project = await _projectService.GetProjectSettings(request.ProjectId); var post = request.Post; ContentHistory history = null; if (post == null) { isNew = true; post = new Post() { BlogId = request.ProjectId, Title = request.ViewModel.Title, MetaDescription = request.ViewModel.MetaDescription, Slug = ContentUtils.CreateSlug(request.ViewModel.Title), CreatedByUser = request.UserName }; } else { history = post.CreateHistory(request.UserName); } if (!string.IsNullOrEmpty(request.ViewModel.Slug)) { // remove any bad characters request.ViewModel.Slug = ContentUtils.CreateSlug(request.ViewModel.Slug); if (request.ViewModel.Slug != post.Slug) { var slugIsAvailable = await _blogService.SlugIsAvailable(request.ViewModel.Slug); if (!slugIsAvailable) { request.ModelState.AddModelError("Slug", _localizer["The page slug was not changed because the requested slug is already in use."]); } } } if (request.ModelState.IsValid) { post.Title = request.ViewModel.Title; post.CorrelationKey = request.ViewModel.CorrelationKey; post.ImageUrl = request.ViewModel.ImageUrl; post.ThumbnailUrl = request.ViewModel.ThumbnailUrl; post.IsFeatured = request.ViewModel.IsFeatured; post.ContentType = request.ViewModel.ContentType; post.TeaserOverride = request.ViewModel.TeaserOverride; post.SuppressTeaser = request.ViewModel.SuppressTeaser; post.LastModified = DateTime.UtcNow; post.LastModifiedByUser = request.UserName; if (!string.IsNullOrEmpty(request.ViewModel.Slug)) { post.Slug = request.ViewModel.Slug; } var categories = new List <string>(); if (!string.IsNullOrEmpty(request.ViewModel.Categories)) { if (_editOptions.ForceLowerCaseCategories) { categories = request.ViewModel.Categories.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim().ToLower()) .Where(x => !string.IsNullOrWhiteSpace(x) && x != "," ) .Distinct() .ToList(); } else { categories = request.ViewModel.Categories.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()) .Where(x => !string.IsNullOrWhiteSpace(x) && x != "," ) .Distinct() .ToList(); } } post.Categories = categories; var shouldFirePublishEvent = false; switch (request.ViewModel.SaveMode) { case SaveMode.SaveDraft: post.DraftContent = request.ViewModel.Content; post.DraftAuthor = request.ViewModel.Author; break; case SaveMode.PublishLater: post.DraftContent = request.ViewModel.Content; post.DraftAuthor = request.ViewModel.Author; if (request.ViewModel.NewPubDate.HasValue) { var tzId = await _timeZoneIdResolver.GetUserTimeZoneId(CancellationToken.None); post.DraftPubDate = _timeZoneHelper.ConvertToUtc(request.ViewModel.NewPubDate.Value, tzId); } if (!post.PubDate.HasValue) { post.IsPublished = false; } break; case SaveMode.PublishNow: post.Content = request.ViewModel.Content; post.Author = request.ViewModel.Author; if (!post.PubDate.HasValue) { post.PubDate = DateTime.UtcNow; } else if (post.PubDate > DateTime.UtcNow) { post.PubDate = DateTime.UtcNow; } post.IsPublished = true; shouldFirePublishEvent = true; post.DraftAuthor = null; post.DraftContent = null; post.DraftPubDate = null; break; } if (project.TeaserMode != TeaserMode.Off) { // need to generate the teaser on save string html = null; if (post.ContentType == "markdown") { var mdPipeline = new MarkdownPipelineBuilder().UseAdvancedExtensions().Build(); html = Markdown.ToHtml(post.Content, mdPipeline); } else { html = post.Content; } var teaserResult = _teaserService.GenerateTeaser( project.TeaserTruncationMode, project.TeaserTruncationLength, html, Guid.NewGuid().ToString(),//cache key post.Slug, project.LanguageCode, false //logWarnings ); post.AutoTeaser = teaserResult.Content; } if (history != null) { await _historyCommands.Create(request.ProjectId, history).ConfigureAwait(false); } if (isNew) { await _blogService.Create(post); } else { await _blogService.Update(post); } if (shouldFirePublishEvent) { await _blogService.FirePublishEvent(post); await _historyCommands.DeleteDraftHistory(request.ProjectId, post.Id).ConfigureAwait(false); } } return(new CommandResult <IPost>(post, request.ModelState.IsValid, errors)); } catch (Exception ex) { _log.LogError($"{ex.Message}:{ex.StackTrace}"); errors.Add(_localizer["Updating a page failed. An error has been logged."]); return(new CommandResult <IPost>(null, false, errors)); } }
public async Task <IActionResult> AjaxPost(PageEditViewModel model) { // disable status code page for ajax requests var statusCodePagesFeature = HttpContext.Features.Get <IStatusCodePagesFeature>(); if (statusCodePagesFeature != null) { statusCodePagesFeature.Enabled = false; } if (string.IsNullOrEmpty(model.Title)) { // if a page has been configured to not show the title // this may be null on edit, if it is a new page then it should be required // because it is used for generating the slug //if (string.IsNullOrEmpty(model.Slug)) //{ log.LogInformation("returning 500 because no title was posted"); return(StatusCode(500)); //} } var project = await projectService.GetCurrentProjectSettings(); if (project == null) { log.LogInformation("returning 500 blog not found"); return(StatusCode(500)); } var canEdit = await User.CanEditPages(project.Id, authorizationService); if (!canEdit) { log.LogInformation("returning 403 user is not allowed to edit"); return(StatusCode(403)); } //string[] categories = new string[0]; //if (!string.IsNullOrEmpty(model.Categories)) //{ // categories = model.Categories.Split(new char[] { ',' }, // StringSplitOptions.RemoveEmptyEntries); //} IPage page = null; if (!string.IsNullOrEmpty(model.Id)) { page = await pageService.GetPage(model.Id); } var needToClearCache = false; var isNew = false; if (page != null) { page.Title = model.Title; page.MetaDescription = model.MetaDescription; page.Content = model.Content; if (page.PageOrder != model.PageOrder) { needToClearCache = true; } } else { isNew = true; needToClearCache = true; var slug = ContentUtils.CreateSlug(model.Title); var available = await pageService.SlugIsAvailable(project.Id, slug); if (!available) { log.LogInformation("returning 409 because slug already in use"); return(StatusCode(409)); } page = new Page() { ProjectId = project.Id, Author = User.GetUserDisplayName(), Title = model.Title, MetaDescription = model.MetaDescription, Content = model.Content, Slug = slug, ParentId = "0" //,Categories = categories.ToList() }; } if (!string.IsNullOrEmpty(model.ParentSlug)) { var parentPage = await pageService.GetPageBySlug(project.Id, model.ParentSlug); if (parentPage != null) { if (parentPage.Id != page.ParentId) { page.ParentId = parentPage.Id; page.ParentSlug = parentPage.Slug; needToClearCache = true; } } } else { // empty means root level page.ParentSlug = string.Empty; page.ParentId = "0"; } if (page.ViewRoles != model.ViewRoles) { needToClearCache = true; } page.ViewRoles = model.ViewRoles; page.PageOrder = model.PageOrder; page.IsPublished = model.IsPublished; page.ShowHeading = model.ShowHeading; if (!string.IsNullOrEmpty(model.PubDate)) { var localTime = DateTime.Parse(model.PubDate); page.PubDate = timeZoneHelper.ConvertToUtc(localTime, project.TimeZoneId); } if (isNew) { await pageService.Create(page, model.IsPublished); } else { await pageService.Update(page, model.IsPublished); } if (needToClearCache) { pageService.ClearNavigationCache(); } var url = Url.Action("Index", "Page", new { slug = page.Slug }); return(Content(url)); }
public async Task AjaxPost(PostViewModel model) { // disable status code page for ajax requests var statusCodePagesFeature = HttpContext.Features.Get <IStatusCodePagesFeature>(); if (statusCodePagesFeature != null) { statusCodePagesFeature.Enabled = false; } if (string.IsNullOrEmpty(model.Title)) { log.LogInformation("returning 500 because no title was posted"); Response.StatusCode = 500; return; } var project = await projectService.GetCurrentProjectSettings(); if (project == null) { log.LogInformation("returning 500 blog not found"); Response.StatusCode = 500; return; } bool canEdit = await User.CanEditBlog(project.Id, authorizationService); if (!canEdit) { log.LogInformation("returning 403 user is not allowed to edit"); Response.StatusCode = 403; return; } var categories = new List <string>(); if (!string.IsNullOrEmpty(model.Categories)) { categories = model.Categories.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim().ToLower()) .Where(x => !string.IsNullOrWhiteSpace(x) && x != "," ) .Distinct() .ToList(); } IPost post = null; if (!string.IsNullOrEmpty(model.Id)) { post = await blogService.GetPost(model.Id); } var isNew = false; if (post != null) { post.Title = model.Title; post.MetaDescription = model.MetaDescription; post.Content = model.Content; post.Categories = categories; } else { isNew = true; var slug = blogService.CreateSlug(model.Title); var available = await blogService.SlugIsAvailable(slug); if (!available) { log.LogInformation("returning 409 because slug already in use"); Response.StatusCode = 409; return; } post = new Post() { Author = User.GetUserDisplayName(), Title = model.Title, MetaDescription = model.MetaDescription, Content = model.Content, Slug = slug, Categories = categories.ToList() }; } post.IsPublished = model.IsPublished; if (!string.IsNullOrEmpty(model.PubDate)) { var localTime = DateTime.Parse(model.PubDate); var pubDate = timeZoneHelper.ConvertToUtc(localTime, project.TimeZoneId); // TODO: this logic probably needs to also be implemented in the metaweblog service in case the pubdate is changed from there if (!isNew) { if (pubDate != post.PubDate) { await blogService.HandlePubDateAboutToChange(post, pubDate).ConfigureAwait(false); } } post.PubDate = pubDate; } try { if (isNew) { await blogService.Create(post); } else { await blogService.Update(post); } // TODO: clear cache string url; if (project.IncludePubDateInPostUrls) { url = Url.Link(blogRoutes.PostWithDateRouteName, new { year = post.PubDate.Year, month = post.PubDate.Month.ToString("00"), day = post.PubDate.Date.Day.ToString("00"), slug = post.Slug }); } else { url = Url.Link(blogRoutes.PostWithoutDateRouteName, new { slug = post.Slug }); } await Response.WriteAsync(url); } catch (Exception ex) { log.LogError("ajax post failed with exception " + ex.Message + " " + ex.StackTrace, ex); Response.StatusCode = 500; } }
public async Task <CommandResult <IPage> > Handle(CreateOrUpdatePageRequest request, CancellationToken cancellationToken = default(CancellationToken)) { var errors = new List <string>(); try { bool isNew = false; var project = await _projectService.GetProjectSettings(request.ProjectId); var page = request.Page; ContentHistory history = null; if (page == null) { isNew = true; page = new Page() { ProjectId = request.ProjectId, ParentId = "0", CreatedByUser = request.UserName, Slug = ContentUtils.CreateSlug(request.ViewModel.Title), ContentType = request.ViewModel.ContentType }; } else { history = page.CreateHistory(request.UserName); } if (!string.IsNullOrEmpty(request.ViewModel.Slug)) { // remove any bad characters request.ViewModel.Slug = ContentUtils.CreateSlug(request.ViewModel.Slug); if (request.ViewModel.Slug != page.Slug) { var slugIsAvailable = await _pageService.SlugIsAvailable(request.ViewModel.Slug); if (!slugIsAvailable) { errors.Add(_localizer["The page slug was invalid because the requested slug is already in use."]); request.ModelState.AddModelError("Slug", _localizer["The page slug was not changed because the requested slug is already in use."]); } } } if (request.ModelState.IsValid) { page.Title = request.ViewModel.Title; page.CorrelationKey = request.ViewModel.CorrelationKey; page.LastModified = DateTime.UtcNow; page.LastModifiedByUser = request.UserName; page.MenuFilters = request.ViewModel.MenuFilters; page.MetaDescription = request.ViewModel.MetaDescription; page.PageOrder = request.ViewModel.PageOrder; page.ShowHeading = request.ViewModel.ShowHeading; page.ShowMenu = request.ViewModel.ShowMenu; page.MenuOnly = request.ViewModel.MenuOnly; page.DisableEditor = request.ViewModel.DisableEditor; page.ShowComments = request.ViewModel.ShowComments; page.MenuFilters = request.ViewModel.MenuFilters; page.ExternalUrl = request.ViewModel.ExternalUrl; page.ViewRoles = request.ViewModel.ViewRoles; if (!string.IsNullOrEmpty(request.ViewModel.Slug)) { page.Slug = request.ViewModel.Slug; } if (!string.IsNullOrEmpty(request.ViewModel.ParentSlug)) { var parentPage = await _pageService.GetPageBySlug(request.ViewModel.ParentSlug); if (parentPage != null) { if (parentPage.Id != page.ParentId) { page.ParentId = parentPage.Id; page.ParentSlug = parentPage.Slug; } } } else { // empty means root level page.ParentSlug = string.Empty; page.ParentId = "0"; } if (page.ParentSlug == project.DefaultPageSlug) { _log.LogWarning($"{request.UserName} tried to explicitely set the default page slug as the parent slug which is not allowed since all root pages are already children of the default page"); page.ParentSlug = string.Empty; page.ParentId = "0"; } var shouldFirePublishEvent = false; //var shouldFireUnPublishEvent = false; switch (request.ViewModel.SaveMode) { //case SaveMode.UnPublish: // page.DraftContent = request.ViewModel.Content; // page.DraftAuthor = request.ViewModel.Author; // page.DraftPubDate = null; // page.IsPublished = false; // page.PubDate = null; // shouldFireUnPublishEvent = true; // break; case SaveMode.SaveDraft: page.DraftContent = request.ViewModel.Content; page.DraftAuthor = request.ViewModel.Author; // should we clear the draft pub date if save draft clicked? //page.DraftPubDate = null; if (!page.PubDate.HasValue) { page.IsPublished = false; } break; case SaveMode.PublishLater: page.DraftContent = request.ViewModel.Content; page.DraftAuthor = request.ViewModel.Author; if (request.ViewModel.NewPubDate.HasValue) { var tzId = await _timeZoneIdResolver.GetUserTimeZoneId(CancellationToken.None); page.DraftPubDate = _timeZoneHelper.ConvertToUtc(request.ViewModel.NewPubDate.Value, tzId); } if (!page.PubDate.HasValue) { page.IsPublished = false; } break; case SaveMode.PublishNow: page.Content = request.ViewModel.Content; page.Author = request.ViewModel.Author; page.PubDate = DateTime.UtcNow; page.IsPublished = true; shouldFirePublishEvent = true; page.DraftAuthor = null; page.DraftContent = null; page.DraftPubDate = null; break; } if (history != null) { await _historyCommands.Create(request.ProjectId, history).ConfigureAwait(false); } if (isNew) { await _pageService.Create(page); } else { await _pageService.Update(page); } if (shouldFirePublishEvent) { await _pageService.FirePublishEvent(page).ConfigureAwait(false); await _historyCommands.DeleteDraftHistory(project.Id, page.Id).ConfigureAwait(false); } //if (shouldFireUnPublishEvent) //{ // await _pageService.FireUnPublishEvent(page).ConfigureAwait(false); //} _pageService.ClearNavigationCache(); } return(new CommandResult <IPage>(page, request.ModelState.IsValid, errors)); } catch (Exception ex) { _log.LogError($"{ex.Message}:{ex.StackTrace}"); errors.Add(_localizer["Updating a page failed. An error has been logged."]); return(new CommandResult <IPage>(null, false, errors)); } }
public async Task <CommandResult <IPost> > Handle(UpdateTemplatedPostRequest request, CancellationToken cancellationToken = default(CancellationToken)) { var errors = new List <string>(); var customModelIsValid = true; try { var post = request.Post; var history = post.CreateHistory(request.UserName); var project = await _projectService.GetCurrentProjectSettings(); var serializer = GetSerializer(request.Template.SerializerName); var parser = GetFormParser(request.Template.FormParserName); var validator = GetValidator(request.Template.ValidatorName); var type = Type.GetType(request.Template.ModelType); var model = parser.ParseModel(request.Template.ModelType, request.Form); if (model == null) { errors.Add(_localizer["Failed to parse custom template model from form."]); customModelIsValid = false; //failed to parse model from form // at least return the original model before changes string pageModelString; if (!string.IsNullOrWhiteSpace(post.DraftSerializedModel)) { pageModelString = post.DraftSerializedModel; } else { pageModelString = post.SerializedModel; } if (!string.IsNullOrWhiteSpace(pageModelString)) { request.ViewModel.TemplateModel = serializer.Deserialize(request.Template.ModelType, pageModelString); } } if (customModelIsValid) { // we are going to return the parsed model either way request.ViewModel.TemplateModel = model; var validationContext = new ValidationContext(model, serviceProvider: null, items: null); var validationResults = new List <ValidationResult>(); customModelIsValid = validator.IsValid(model, validationContext, validationResults); if (!customModelIsValid) { foreach (var item in validationResults) { foreach (var memberName in item.MemberNames) { request.ModelState.AddModelError(memberName, item.ErrorMessage); } } } } if (!string.IsNullOrEmpty(request.ViewModel.Slug)) { // remove any bad characters request.ViewModel.Slug = ContentUtils.CreateSlug(request.ViewModel.Slug); if (request.ViewModel.Slug != post.Slug) { var slug = request.ViewModel.Slug; var slugIsAvailable = await _blogService.SlugIsAvailable(slug); while (!slugIsAvailable) { slug += "-"; slugIsAvailable = await _blogService.SlugIsAvailable(slug); } if (slugIsAvailable) { post.Slug = slug; } } } if (request.ModelState.IsValid) { var modelString = serializer.Serialize(request.Template.ModelType, model); var renderedModel = await _viewRenderer.RenderViewAsString(request.Template.RenderView, model).ConfigureAwait(false); post.Title = request.ViewModel.Title; post.CorrelationKey = request.ViewModel.CorrelationKey; post.ImageUrl = request.ViewModel.ImageUrl; post.ThumbnailUrl = request.ViewModel.ThumbnailUrl; post.IsFeatured = request.ViewModel.IsFeatured; post.TeaserOverride = request.ViewModel.TeaserOverride; post.SuppressTeaser = request.ViewModel.SuppressTeaser; post.ShowComments = request.ViewModel.ShowComments; post.LastModified = DateTime.UtcNow; post.LastModifiedByUser = request.UserName; post.MetaDescription = request.ViewModel.MetaDescription; var categories = new List <string>(); if (!string.IsNullOrEmpty(request.ViewModel.Categories)) { if (_editOptions.ForceLowerCaseCategories) { categories = request.ViewModel.Categories.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim().ToLower()) .Where(x => !string.IsNullOrWhiteSpace(x) && x != "," ) .Distinct() .ToList(); } else { categories = request.ViewModel.Categories.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()) .Where(x => !string.IsNullOrWhiteSpace(x) && x != "," ) .Distinct() .ToList(); } } post.Categories = categories; var tzId = await _timeZoneIdResolver.GetUserTimeZoneId(CancellationToken.None); var shouldFirePublishEvent = false; var saveMode = request.ViewModel.SaveMode; if (saveMode == SaveMode.PublishLater) { if (request.ViewModel.NewPubDate.HasValue) { var newPubDate = _timeZoneHelper.ConvertToUtc(request.ViewModel.NewPubDate.Value, tzId); if (newPubDate < DateTime.UtcNow) { saveMode = SaveMode.PublishNow; post.PubDate = newPubDate; } } } switch (saveMode) { case SaveMode.SaveDraft: post.DraftSerializedModel = modelString; post.DraftContent = renderedModel; post.DraftAuthor = request.ViewModel.Author; if (!post.PubDate.HasValue) { post.IsPublished = false; } break; case SaveMode.PublishLater: post.DraftSerializedModel = modelString; post.DraftContent = renderedModel; post.DraftAuthor = request.ViewModel.Author; if (request.ViewModel.NewPubDate.HasValue) { post.DraftPubDate = _timeZoneHelper.ConvertToUtc(request.ViewModel.NewPubDate.Value, tzId); } if (!post.PubDate.HasValue) { post.IsPublished = false; } break; case SaveMode.PublishNow: post.Author = request.ViewModel.Author; post.Content = renderedModel; post.SerializedModel = modelString; if (!post.PubDate.HasValue) { post.PubDate = DateTime.UtcNow; } post.IsPublished = true; shouldFirePublishEvent = true; post.DraftAuthor = null; post.DraftContent = null; post.DraftPubDate = null; post.DraftSerializedModel = null; break; } if (project.TeaserMode != TeaserMode.Off) { // need to generate the teaser on save var teaserResult = _teaserService.GenerateTeaser( project.TeaserTruncationMode, project.TeaserTruncationLength, post.Content, Guid.NewGuid().ToString(),//cache key post.Slug, project.LanguageCode, false //logWarnings ); post.AutoTeaser = teaserResult.Content; } await _historyCommands.Create(request.ProjectId, history).ConfigureAwait(false); await _blogService.Update(post); if (shouldFirePublishEvent) { await _blogService.FirePublishEvent(post).ConfigureAwait(false); await _historyCommands.DeleteDraftHistory(project.Id, post.Id).ConfigureAwait(false); } } return(new CommandResult <IPost>(post, customModelIsValid && request.ModelState.IsValid, errors)); } catch (Exception ex) { _log.LogError($"{ex.Message}:{ex.StackTrace}"); errors.Add(_localizer["Updating a post from a content template failed. An error has been logged."]); return(new CommandResult <IPost>(null, false, errors)); } }
public async Task <string> NewPost( string blogId, string userName, string password, PostStruct newPost, bool publish, string authorDisplayName ) { var permission = await _security.ValidatePermissions( blogId, userName, password, CancellationToken.None ).ConfigureAwait(false); if (!permission.CanEditPosts) { _log.LogWarning($"rejecting new post because user {userName} cannot edit posts"); return(null); } var post = _mapper.GetPostFromStruct(newPost); post.BlogId = blogId; post.Id = Guid.NewGuid().ToString(); post.Author = authorDisplayName; post.CreatedByUser = permission.DisplayName; var utcPubDate = _timeZoneHelper.ConvertToUtc(newPost.postDate, permission.TimeZoneId); if (publish) { if (utcPubDate.Year == 1) { //invalid because not supplied utcPubDate = DateTime.UtcNow; } if (utcPubDate <= DateTime.UtcNow) { post.IsPublished = true; post.PubDate = utcPubDate; } else { //future date needs to be draft, it will auto publish after pub date post.DraftAuthor = post.Author; post.DraftContent = post.Content; post.DraftPubDate = utcPubDate; post.IsPublished = false; post.PubDate = null; post.Content = null; } } else { post.DraftAuthor = post.Author; post.DraftContent = post.Content; if (utcPubDate > DateTime.UtcNow) { post.DraftPubDate = utcPubDate; } post.Content = null; post.PubDate = null; } await _blogUrlResolver.ConvertMediaToRelativeUrls(post).ConfigureAwait(false); await _blogService.Create(post).ConfigureAwait(false); if (publish) { await _blogService.FirePublishEvent(post).ConfigureAwait(false); } return(post.Id); }