Пример #1
0
        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 }));
            }
        }
Пример #4
0
        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));
            }
        }
Пример #5
0
        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));
        }
Пример #6
0
        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;
            }
        }
Пример #7
0
        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));
            }
        }
Пример #8
0
        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);
        }