public async Task PublishReadyDrafts(CancellationToken cancellationToken = default(CancellationToken))
        {
            var settings = await _projectService.GetCurrentProjectSettings().ConfigureAwait(false);

            var drafts = await _pageQueries.GetPagesReadyForPublish(settings.Id, cancellationToken);

            foreach (var page in drafts)
            {
                page.Content         = page.DraftContent;
                page.Author          = page.DraftAuthor;
                page.PubDate         = page.DraftPubDate.Value;
                page.SerializedModel = page.DraftSerializedModel;
                page.IsPublished     = true;

                page.DraftAuthor          = null;
                page.DraftContent         = null;
                page.DraftSerializedModel = null;
                page.DraftPubDate         = null;

                await Update(page, settings);

                await _eventHandlers.HandlePublished(page.ProjectId, page).ConfigureAwait(false);

                await _historyCommands.DeleteDraftHistory(page.ProjectId, page.Id).ConfigureAwait(false);

                await _navigationCache.ClearTreeCache();

                _log.LogDebug($"auto published draft for page {page.Title}");
            }
        }
        public async Task ClearTreeCache()
        {
            foreach (var builder in _builders)
            {
                var cacheKey = await _cacheKeyResolver.GetCacheKey(builder);

                await _treeCache.ClearTreeCache(cacheKey);
            }
        }
        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));
            }
        }
Beispiel #4
0
        public async Task Update(ISiteSettings site, string oldFolderName = null)
        {
            await _eventHandlers.HandleSitePreUpdate(site.Id).ConfigureAwait(false);

            _dataProtector.Protect(site);
            if (site.Id == Guid.Empty)
            {
                site.Id = Guid.NewGuid();
                await _commands.Update(site, CancellationToken.None);
            }
            else
            {
                await _commands.Update(site, CancellationToken.None);
            }

            await _cacheHelper.SetDistributedCacheTimestamp(site.Id, site.LastModifiedUtc).ConfigureAwait(false);

            if (_multiTenantOptions.Mode == MultiTenantMode.FolderName)
            {
                if (!string.IsNullOrEmpty(oldFolderName))
                {
                    _cacheHelper.ClearLocalCache(oldFolderName);
                    await _cacheHelper.ClearSiteFolderListCache();

                    await _navigationCache.ClearTreeCache();
                }

                if (string.IsNullOrEmpty(site.SiteFolderName))
                {
                    _cacheHelper.ClearLocalCache("root");
                }
                else
                {
                    _cacheHelper.ClearLocalCache(site.SiteFolderName);
                }
            }
            else
            {
                if (_context != null && !string.IsNullOrEmpty(_context.Request.Host.Value))
                {
                    _cacheHelper.ClearLocalCache(_context.Request.Host.Value);
                }


                if (!string.IsNullOrWhiteSpace(site.PreferredHostName))
                {
                    _cacheHelper.ClearLocalCache(site.PreferredHostName);
                }

                var siteHosts = await GetSiteHosts(site.Id);

                if (siteHosts != null && siteHosts.Count > 0)
                {
                    foreach (ISiteHost siteHostName in siteHosts)
                    {
                        _cacheHelper.ClearLocalCache(siteHostName.HostName);
                    }
                }
            }
            _cacheHelper.ClearLocalCache("site-" + site.Id.ToString());

            await _eventHandlers.HandleSiteUpdated(site).ConfigureAwait(false);
        }
        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.GetCurrentProjectSettings();

                var            page    = request.Page;
                ContentHistory history = null;
                if (page == null)
                {
                    isNew = true;
                    page  = new Page()
                    {
                        ProjectId     = request.ProjectId,
                        ParentId      = "0",
                        CreatedByUser = request.UserName,
                        ContentType   = request.ViewModel.ContentType
                    };
                }
                else
                {
                    history = page.CreateHistory(request.UserName);
                }


                if (!string.IsNullOrEmpty(request.ViewModel.Slug))
                {
                    // remove any bad characters
                    var slug = ContentUtils.CreateSlug(request.ViewModel.Slug);
                    if (slug != page.Slug)
                    {
                        var slugIsAvailable = await _pageService.SlugIsAvailable(slug);

                        while (!slugIsAvailable)
                        {
                            slug           += "-";
                            slugIsAvailable = await _pageService.SlugIsAvailable(slug);
                        }
                        if (slugIsAvailable)
                        {
                            page.Slug = slug;
                        }
                    }
                }

                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.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 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;
                                page.PubDate = newPubDate;
                            }
                        }
                    }

                    switch (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)
                        {
                            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;
                        if (!page.PubDate.HasValue)
                        {
                            page.PubDate = DateTime.UtcNow;
                        }
                        page.IsPublished       = true;
                        shouldFirePublishEvent = true;

                        page.DraftAuthor  = null;
                        page.DraftContent = null;
                        page.DraftPubDate = null;

                        break;

                    case SaveMode.DeleteCurrentDraft:

                        shouldFirePublishEvent = false;

                        page.DraftAuthor          = null;
                        page.DraftContent         = null;
                        page.DraftPubDate         = null;
                        page.DraftSerializedModel = 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);
                    //}

                    await _navigationCache.ClearTreeCache();
                }

                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));
            }
        }
Beispiel #6
0
        public async Task <CommandResult <IPage> > Handle(InitTemplatedPageRequest request, CancellationToken cancellationToken = default(CancellationToken))
        {
            // initialize an unpublished page based on the template

            var errors = new List <string>();

            try
            {
                var serializer = GetSerializer(request.Template.SerializerName);
                var type       = Type.GetType(request.Template.ModelType);
                var model      = Activator.CreateInstance(type);

                var page = new Page
                {
                    ProjectId          = request.ProjectId,
                    CreatedByUser      = request.CreatedByUserName,
                    DraftAuthor        = request.Author,
                    LastModifiedByUser = request.CreatedByUserName,
                    TemplateKey        = request.Template.Key,
                    Title                = request.ViewModel.Title,
                    Serializer           = serializer.Name,
                    DraftSerializedModel = serializer.Serialize(request.Template.ModelType, model),
                    ParentSlug           = request.ViewModel.ParentSlug,
                    PageOrder            = request.ViewModel.PageOrder,
                    Content              = await _viewRenderer.RenderViewAsString(request.Template.RenderView, model).ConfigureAwait(false),
                    IsPublished          = false
                };

                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";
                }

                await _pageService.Create(page);

                await _navigationCache.ClearTreeCache();

                var result = new CommandResult <IPage>(page, true, errors);

                return(result);
            }
            catch (Exception ex)
            {
                _log.LogError($"{ex.Message}:{ex.StackTrace}");

                errors.Add(_localizer["Initializing a new page from a content template failed. An error has been logged."]);

                return(new CommandResult <IPage>(null, false, errors));
            }
        }
        public async Task <string> NewPage(
            string blogId,
            string userName,
            string password,
            PageStruct newPage,
            bool publish)
        {
            var permission = await _security.ValidatePermissions(
                blogId,
                userName,
                password,
                CancellationToken.None
                ).ConfigureAwait(false);

            if (!permission.CanEditPages)
            {
                _log.LogWarning($"user {userName} cannot edit pages");
                return(null);
            }

            var page = _mapper.GetPageFromStruct(newPage);

            page.ProjectId          = blogId;
            page.Id                 = Guid.NewGuid().ToString();
            page.CreatedByUser      = permission.DisplayName;
            page.LastModifiedByUser = permission.DisplayName;
            if (!string.IsNullOrWhiteSpace(page.ParentId))
            {
                var parent = await _pageService.GetPage(page.ParentId).ConfigureAwait(false);

                if (parent != null)
                {
                    page.ParentSlug = parent.Slug;
                }
            }
            else
            {
                page.ParentSlug = null;
            }
            if (string.IsNullOrWhiteSpace(newPage.pageOrder))
            {
                page.PageOrder = await _pageService.GetNextChildPageOrder(page.ParentSlug).ConfigureAwait(false);
            }

            var utcPubDate = _timeZoneHelper.ConvertToUtc(newPage.pageDate, permission.TimeZoneId);

            if (publish)
            {
                if (utcPubDate.Year == 1)
                {
                    //invalid because not supplied
                    utcPubDate = DateTime.UtcNow;
                }

                if (utcPubDate < DateTime.UtcNow)
                {
                    page.IsPublished = true;
                    page.PubDate     = utcPubDate;
                }
                else
                {
                    //future date needs to be draft, it will auto publish after pub date
                    page.DraftAuthor  = page.Author;
                    page.DraftContent = page.Content;
                    page.DraftPubDate = utcPubDate;
                    page.IsPublished  = false;
                    page.PubDate      = null;
                    page.Content      = null;
                }
            }
            else
            {
                page.DraftAuthor  = page.Author;
                page.DraftContent = page.Content;
                if (utcPubDate > DateTime.UtcNow)
                {
                    page.DraftPubDate = utcPubDate;
                }
                page.Content     = null;
                page.IsPublished = false;
                page.PubDate     = null;
            }

            await _pageUrlResolver.ConvertMediaToRelativeUrls(page).ConfigureAwait(false);

            await _pageService.Create(page).ConfigureAwait(false);

            await _navigationCache.ClearTreeCache();

            if (publish)
            {
                await _pageService.FirePublishEvent(page).ConfigureAwait(false);
            }

            return(page.Id);
        }