Example #1
0
        public virtual object AddComment(Area areaInput, PostBase postBaseInput, Comment commentInput, UserBase userBaseInput, UserBase currentUser, bool?remember, bool?subscribe)
        {
            if (site.CommentingDisabled)
            {
                return(null);
            }

            Area area = areaService.GetArea(areaInput.Name);

            if (area == null || area.CommentingDisabled)
            {
                return(null);
            }

            Post post = postService.GetPost(area, postBaseInput.Slug);

            if (post == null || post.CommentingDisabled)
            {
                return(null);
            }

            ValidationStateDictionary validationState;
            Comment newComment;

            postService.AddComment(area, post, commentInput, currentUser ?? userBaseInput, subscribe.HasValue && subscribe.Value, out validationState, out newComment);

            if (!validationState.IsValid)
            {
                ModelState.AddModelErrors(validationState);

                return(Item(areaInput, postBaseInput));
            }

            //todo: (nheskew) move into an action filter?
            if (remember != null && (bool)remember)
            {
                Response.Cookies.SetAnonymousUser(userBaseInput);
            }
            else if (currentUser == null && Request.Cookies.GetAnonymousUser() != null)
            {
                Response.Cookies.ClearAnonymousUser();
            }

            return(new RedirectResult(newComment.State != EntityState.PendingApproval ? Url.Comment(post, newComment) : Url.CommentPending(post, newComment)));
        }
Example #2
0
        public static void PostSave(PostBase post)
        {
            using (var client = CreateClient())
            {
                var indexClient = client.Indexes.GetClient("content");
                var body        = new StringBuilder();

                foreach (var block in post.Blocks)
                {
                    if (block is HtmlBlock htmlBlock)
                    {
                        body.AppendLine(htmlBlock.Body.Value);
                    }
                    else if (block is HtmlColumnBlock columnBlock)
                    {
                        body.AppendLine(columnBlock.Column1.Value);
                        body.AppendLine(columnBlock.Column2.Value);
                    }
                }

                var cleanHtml   = new Regex("<[^>]*(>|$)");
                var cleanSpaces = new Regex("[\\s\\r\\n]+");

                var cleaned = cleanSpaces.Replace(cleanHtml.Replace(body.ToString(), " "), " ").Trim();

                var actions = new IndexAction <Content>[]
                {
                    IndexAction.MergeOrUpload(
                        new Content
                    {
                        Slug        = post.Slug,
                        ContentId   = post.Id.ToString(),
                        ContentType = "post",
                        Title       = post.Title,
                        Category    = post.Category.Title,
                        Tags        = post.Tags.Select(t => t.Title).ToList(),
                        Body        = cleaned
                    }
                        )
                };
                var batch = IndexBatch.New(actions);

                indexClient.Documents.Index(batch);
            }
        }
Example #3
0
        public virtual object SaveEdit(Area areaInput, PostBase postBaseInput, Post postInput)
        {
            Area area = areaService.GetArea(areaInput.Name);

            Post post = postService.GetPost(area, postBaseInput.Slug);

            ValidationStateDictionary validationState;

            postService.EditPost(area, post, postInput, out validationState);

            //todo: (nheskew) need to do more than just return another action method because it's likely different actions will need different filters applied to it
            if (!validationState.IsValid)
            {
                ModelState.AddModelErrors(validationState);
                return(Edit(areaInput, postBaseInput));
            }

            return(Redirect(Url.Post(postInput)));
        }
Example #4
0
 private string GetState(PostBase post, bool isDraft)
 {
     if (post.Created != DateTime.MinValue)
     {
         if (post.Published.HasValue)
         {
             if (isDraft)
             {
                 return(ContentState.Draft);
             }
             return(ContentState.Published);
         }
         else
         {
             return(ContentState.Unpublished);
         }
     }
     return(ContentState.New);
 }
        /// <summary>
        /// Gets the post model with the specified id.
        /// </summary>
        /// <typeparam name="T">The model type</typeparam>
        /// <param name="id">The unique id</param>
        /// <param name="blogPages">The blog pages</param>
        /// <returns>The post model</returns>
        private async Task <T> GetByIdAsync <T>(Guid id, IList <PageInfo> blogPages) where T : PostBase
        {
            PostBase model = null;

            if (typeof(T) == typeof(PostInfo))
            {
                model = _cache?.Get <PostInfo>($"PostInfo_{id.ToString()}");
            }
            else if (!typeof(DynamicPost).IsAssignableFrom(typeof(T)))
            {
                model = _cache?.Get <PostBase>(id.ToString());

                if (model != null)
                {
                    await _factory.InitAsync(model, App.PostTypes.GetById(model.TypeId));
                }
            }

            if (model == null)
            {
                model = await _repo.GetById <T>(id).ConfigureAwait(false);

                if (model != null)
                {
                    var blog = blogPages.FirstOrDefault(p => p.Id == model.BlogId);

                    if (blog == null)
                    {
                        blog = await _pageService.GetByIdAsync <PageInfo>(model.BlogId).ConfigureAwait(false);

                        blogPages.Add(blog);
                    }

                    await OnLoadAsync(model, blog).ConfigureAwait(false);
                }
            }

            if (model != null && model is T)
            {
                return((T)model);
            }
            return(null);
        }
Example #6
0
        /// <summary>
        /// Creates or updates the searchable content for the
        /// given post.
        /// </summary>
        /// <param name="post">The post</param>
        public async Task SavePostAsync(PostBase post)
        {
            using (var client = CreateClient())
            {
                var indexClient = client.Indexes.GetClient("content");
                var body        = new StringBuilder();

                foreach (var block in post.Blocks)
                {
                    if (block is ISearchable searchableBlock)
                    {
                        body.AppendLine(searchableBlock.GetIndexedContent());
                    }
                }

                var cleanHtml   = new Regex("<[^>]*(>|$)");
                var cleanSpaces = new Regex("[\\s\\r\\n]+");

                var cleaned = cleanSpaces.Replace(cleanHtml.Replace(body.ToString(), " "), " ").Trim();

                var actions = new IndexAction <Content>[]
                {
                    IndexAction.MergeOrUpload(
                        new Content
                    {
                        Slug        = post.Slug,
                        ContentId   = post.Id.ToString(),
                        ContentType = "post",
                        Title       = post.Title,
                        Category    = post.Category.Title,
                        Tags        = post.Tags.Select(t => t.Title).ToList(),
                        Body        = cleaned
                    }
                        )
                };
                var batch = IndexBatch.New(actions);

                await indexClient.Documents.IndexAsync(batch);
            }
        }
Example #7
0
        public virtual OxiteModelItem <Post> Item(Area areaInput, PostBase postInput)
        {
            Area area = areaService.GetArea(areaInput.Name);

            if (area == null)
            {
                return(null);
            }

            Post post = postService.GetPost(area, postInput.Slug);

            if (post == null)
            {
                return(null);
            }

            return(new OxiteModelItem <Post>
            {
                Container = area,
                Item = post
            });
        }
        /// <summary>
        /// Gets the post model with the specified slug.
        /// </summary>
        /// <typeparam name="T">The model type</typeparam>
        /// <param name="blogId">The unique blog slug</param>
        /// <param name="slug">The unique slug</param>
        /// <returns>The post model</returns>
        public async Task <T> GetBySlugAsync <T>(Guid blogId, string slug) where T : PostBase
        {
            PostBase model = null;

            // Lets see if we can resolve the slug from cache
            var postId = _cache?.Get <Guid?>($"PostId_{blogId}_{slug}");

            if (postId.HasValue)
            {
                if (typeof(T) == typeof(PostInfo))
                {
                    model = _cache?.Get <PostInfo>($"PostInfo_{postId.ToString()}");
                }
                else if (!typeof(DynamicPost).IsAssignableFrom(typeof(T)))
                {
                    model = _cache?.Get <PostBase>(postId.ToString());
                }
            }

            if (model == null)
            {
                model = await _repo.GetBySlug <T>(blogId, slug).ConfigureAwait(false);

                if (model != null)
                {
                    var blog = await _pageService.GetByIdAsync <PageInfo>(model.BlogId).ConfigureAwait(false);

                    await OnLoadAsync(model, blog).ConfigureAwait(false);
                }
            }

            if (model != null && model is T)
            {
                return((T)model);
            }
            return(null);
        }
Example #9
0
        public virtual ActionResult Remove(Area areaInput, PostBase postBaseInput, Comment commentInput, string returnUri)
        {
            Area area = areaService.GetArea(areaInput.Name);

            if (area == null)
            {
                return(null);
            }

            Post post = postService.GetPost(area, postBaseInput.Slug);

            if (post == null)
            {
                return(null);
            }

            try
            {
                postService.RemoveComment(post, commentInput.ID);
            }
            catch
            {
                return(new JsonResult {
                    Data = false
                });
            }

            if (!string.IsNullOrEmpty(returnUri))
            {
                return(new RedirectResult(returnUri));
            }

            return(new JsonResult {
                Data = true
            });
        }
Example #10
0
 public abstract Task <Post> AddPost([FromBody] PostBase value);
Example #11
0
 /// <summary>
 /// Generates an absolute url for the given post.
 /// </summary>
 /// <param name="app">The application service</param>
 /// <param name="post">The post</param>
 /// <returns>The url</returns>
 public static string AbsoluteUrl(this IApplicationService app, PostBase post)
 {
     return($"{ AbsoluteUrlStart(app) }{ Url(app, post) }");
 }
Example #12
0
 /// <summary>Register service method with a service binder with or without implementation. Useful when customizing the  service binding logic.
 /// Note: this method is part of an experimental API that can change or be removed without any prior notice.</summary>
 /// <param name="serviceBinder">Service methods will be bound by calling <c>AddMethod</c> on this object.</param>
 /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
 public static void BindService(grpc::ServiceBinderBase serviceBinder, PostBase serviceImpl)
 {
     serviceBinder.AddMethod(__Method_CreateNewPostFun, serviceImpl == null ? null : new grpc::UnaryServerMethod <global::PostProto.NewPostInfo, global::PostProto.CreateNewPostResult>(serviceImpl.CreateNewPostFun));
     serviceBinder.AddMethod(__Method_UpdatePostShowListFun, serviceImpl == null ? null : new grpc::UnaryServerMethod <global::PostProto.UpdateMemberPostShowList, global::PostProto.UpdateShowListResult>(serviceImpl.UpdatePostShowListFun));
 }
Example #13
0
 /// <summary>Creates service definition that can be registered with a server</summary>
 /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
 public static grpc::ServerServiceDefinition BindService(PostBase serviceImpl)
 {
     return(grpc::ServerServiceDefinition.CreateBuilder()
            .AddMethod(__Method_CreateNewPostFun, serviceImpl.CreateNewPostFun)
            .AddMethod(__Method_UpdatePostShowListFun, serviceImpl.UpdatePostShowListFun).Build());
 }
Example #14
0
        public async Task <IActionResult> UpdatePost(Post post)
        {
            if (!ModelState.IsValid)
            {
                return(View("Edit", post));
            }

            Post existing = await _blog.GetPostById(post.Id) ?? post;

            string categories = Request.Form["categories"];

            existing.Categories = categories.Split(",", StringSplitOptions.RemoveEmptyEntries)
                                  .Select(c => c.Trim()
                                          .ToLowerInvariant())
                                  .ToList();
            existing.Title       = post.Title.Trim();
            existing.Slug        = !string.IsNullOrWhiteSpace(post.Slug) ? post.Slug.Trim() : PostBase.CreateSlug(post.Title);
            existing.IsPublished = post.IsPublished;
            existing.Content     = post.Content.Trim();
            existing.Excerpt     = post.Excerpt.Trim();

            await SaveFilesToDisk(existing);

            await _blog.SavePost(existing);

            return(Redirect(post.GetEncodedLink()));
        }
Example #15
0
 public static void PostDelete(PostBase post)
 {
 }
 /// <summary>
 /// Checks if the given post is published
 /// </summary>
 /// <param name="model">The posts model</param>
 /// <returns>If the post is published</returns>
 private bool IsPublished(PostBase model)
 {
     return(model != null && model.Published.HasValue && model.Published.Value <= DateTime.Now);
 }
Example #17
0
        /// <summary>
        ///     The AddPost
        /// </summary>
        /// <param name="blogId">The blogId<see cref="string" /></param>
        /// <param name="userId">The userId<see cref="string" /></param>
        /// <param name="password">The password<see cref="string" /></param>
        /// <param name="post">The post<see cref="Post" /></param>
        /// <param name="publish">The publish<see cref="bool" /></param>
        /// <returns>The <see cref="string" /></returns>
        public string AddPost(
            string blogId,
            string userId,
            string password,
            Post post,
            bool publish)
        {
            ValidateUser(userId, password);

            var newPost = new Models.Post
            {
                Title       = post.title,
                Slug        = !string.IsNullOrWhiteSpace(post.wp_slug) ? post.wp_slug : PostBase.CreateSlug(post.title),
                Content     = post.description,
                IsPublished = publish,
                Categories  = post.categories
            };

            if (post.dateCreated != DateTime.MinValue)
            {
                newPost.PubDate = post.dateCreated;
            }

            _blog.SavePost(newPost)
            .GetAwaiter()
            .GetResult();

            return(newPost.Id);
        }
        /// <summary>
        /// Invokes the middleware.
        /// </summary>
        /// <param name="context">The current http context</param>
        /// <param name="api">The current api</param>
        /// <returns>An async task</returns>
        public override async Task Invoke(HttpContext context, IApi api, IApplicationService service)
        {
            if (!IsHandled(context) && !context.Request.Path.Value.StartsWith("/manager/assets/"))
            {
                var url      = context.Request.Path.HasValue ? context.Request.Path.Value : "";
                var segments = url.Substring(1).Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
                int pos      = 0;

                //
                // 1: Store raw url
                //
                service.Url = context.Request.Path.Value;

                //
                // 2: Get the current site
                //
                Site site = null;

                // Try to get the requested site by hostname & prefix
                if (segments.Length > 0)
                {
                    site = await api.Sites.GetByHostnameAsync($"{context.Request.Host.Host}/{segments[0]}")
                           .ConfigureAwait(false);

                    if (site != null)
                    {
                        context.Request.Path = "/" + string.Join("/", segments.Skip(1));
                        pos = 1;
                    }
                }

                // Try to get the requested site by hostname
                if (site == null)
                {
                    site = await api.Sites.GetByHostnameAsync(context.Request.Host.Host)
                           .ConfigureAwait(false);
                }

                // If we didn't find the site, get the default site
                if (site == null)
                {
                    site = await api.Sites.GetDefaultAsync()
                           .ConfigureAwait(false);
                }

                if (site != null)
                {
                    // Update application service
                    service.Site.Id      = site.Id;
                    service.Site.Culture = site.Culture;
                    service.Site.Sitemap = await api.Sites.GetSitemapAsync(site.Id);

                    // Set current culture if specified in site
                    if (!string.IsNullOrEmpty(site.Culture))
                    {
                        var cultureInfo = new CultureInfo(service.Site.Culture);
                        CultureInfo.CurrentCulture = CultureInfo.CurrentUICulture = cultureInfo;
                    }
                }

                //
                // 3: Get the current page
                //
                PageBase page     = null;
                PageType pageType = null;

                if (segments != null && segments.Length > pos)
                {
                    // Scan for the most unique slug
                    for (var n = segments.Length; n > pos; n--)
                    {
                        var slug = string.Join("/", segments.Subset(pos, n));
                        page = await api.Pages.GetBySlugAsync <PageBase>(slug, site.Id)
                               .ConfigureAwait(false);

                        if (page != null)
                        {
                            pos = pos + n;
                            break;
                        }
                    }
                }
                else
                {
                    page = await api.Pages.GetStartpageAsync <PageBase>(site.Id)
                           .ConfigureAwait(false);
                }

                if (page != null)
                {
                    pageType            = App.PageTypes.GetById(page.TypeId);
                    service.PageId      = page.Id;
                    service.CurrentPage = page;
                }

                //
                // 4: Get the current post
                //
                PostBase post     = null;
                PostType postType = null;

                if (page != null && pageType.IsArchive && segments.Length > pos)
                {
                    post = await api.Posts.GetBySlugAsync <PostBase>(page.Id, segments[pos])
                           .ConfigureAwait(false);

                    if (post != null)
                    {
                        pos++;
                    }
                }

                if (post != null)
                {
                    postType            = App.PostTypes.GetById(post.TypeId);
                    service.CurrentPost = post;
                }

#if DEBUG
                _logger?.LogDebug($"FOUND SITE: [{ site.Id }]");
                if (page != null)
                {
                    _logger?.LogDebug($"FOUND PAGE: [{ page.Id }]");
                }

                if (post != null)
                {
                    _logger?.LogDebug($"FOUND POST: [{ post.Id }]");
                }
#endif

                //
                // 5: Route request
                //
                var route = new StringBuilder();
                var query = new StringBuilder();

                if (post != null)
                {
                    route.Append(post.Route ?? "/post");
                    for (var n = pos; n < segments.Length; n++)
                    {
                        route.Append("/");
                        route.Append(segments[n]);
                    }

                    query.Append("?id=");
                    query.Append(post.Id);
                }
                else if (page != null)
                {
                    route.Append(page.Route ?? (pageType.IsArchive ? "/archive" : "/page"));
                    for (var n = pos; n < segments.Length; n++)
                    {
                        route.Append("/");
                        route.Append(segments[n]);
                    }

                    query.Append("?id=");
                    query.Append(page.Id);

                    if (!page.ParentId.HasValue && page.SortOrder == 0)
                    {
                        query.Append("&startpage=true");
                    }
                }

                if (route.Length > 0)
                {
                    var strRoute = route.ToString();
                    var strQuery = query.ToString();

#if DEBUG
                    _logger?.LogDebug($"SETTING ROUTE: [{ strRoute }]");
                    _logger?.LogDebug($"SETTING QUERY: [{ strQuery }]");
#endif

                    context.Request.Path        = new PathString(strRoute);
                    context.Request.QueryString = new QueryString(strQuery);
                }
            }
            await _next.Invoke(context);
        }
Example #19
0
        public async Task <IActionResult> Edit(int id, [Bind("PostId,Title,Description,Slug,Content,Published")] PostBase post)
        {
            if (id != post.PostId)
            {
                return(NotFound());
            }

            // Phát sinh Slug theo Title
            if (ModelState["Slug"].ValidationState == ModelValidationState.Invalid)
            {
                post.Slug = Utils.GenerateSlug(post.Title);
                ModelState.SetModelValue("Slug", new ValueProviderResult(post.Slug));
                // Thiết lập và kiểm tra lại Model
                ModelState.Clear();
                TryValidateModel(post);
            }

            if (selectedCategories.Length == 0)
            {
                ModelState.AddModelError(String.Empty, "Phải ít nhất một chuyên mục");
            }

            bool SlugExisted = await _context.Posts.Where(p => p.Slug == post.Slug && p.PostId != post.PostId).AnyAsync();

            if (SlugExisted)
            {
                ModelState.AddModelError(nameof(post.Slug), "Slug đã có trong Database");
            }

            if (ModelState.IsValid)
            {
                // Lấy nội dung từ DB
                var postUpdate = await _context.Posts.Where(p => p.PostId == id)
                                 .Include(p => p.PostCategories)
                                 .ThenInclude(c => c.Category).FirstOrDefaultAsync();

                if (postUpdate == null)
                {
                    return(NotFound());
                }

                // Cập nhật nội dung mới
                postUpdate.Title       = post.Title;
                postUpdate.Description = post.Description;
                postUpdate.Content     = post.Content;
                postUpdate.Slug        = post.Slug;
                postUpdate.DateUpdated = DateTime.Now;
                postUpdate.Published   = post.Published;

                // Các danh mục không có trong selectedCategories
                var listcateremove = postUpdate.PostCategories
                                     .Where(p => !selectedCategories.Contains(p.CategoryID))
                                     .ToList();
                listcateremove.ForEach(c => postUpdate.PostCategories.Remove(c));

                // Các ID category chưa có trong postUpdate.PostCategories
                var listCateAdd = selectedCategories
                                  .Where(
                    id => !postUpdate.PostCategories.Where(c => c.CategoryID == id).Any()
                    ).ToList();

                listCateAdd.ForEach(id => {
                    postUpdate.PostCategories.Add(new PostCategory()
                    {
                        PostID     = postUpdate.PostId,
                        CategoryID = id
                    });
                });

                try {
                    _context.Update(postUpdate);

                    await _context.SaveChangesAsync();
                } catch (DbUpdateConcurrencyException) {
                    if (!PostExists(post.PostId))
                    {
                        return(NotFound());
                    }
                    else
                    {
                        throw;
                    }
                }
                return(RedirectToAction(nameof(Index)));
            }

            var categories = await _context.Categories.ToListAsync();

            ViewData["categories"] = new MultiSelectList(categories, "Id", "Title", selectedCategories);
            return(View(post));
        }
Example #20
0
        public async Task <IActionResult> Create([Bind("PostId,Title,Description,Slug,Content,Published")] PostBase post)
        {
            var user = await _usermanager.GetUserAsync(User);

            ViewData["userpost"] = $"{user.UserName} {user.FullName}";

            // Phát sinh Slug theo Title
            if (ModelState["Slug"].ValidationState == ModelValidationState.Invalid)
            {
                post.Slug = Utils.GenerateSlug(post.Title);
                ModelState.SetModelValue("Slug", new ValueProviderResult(post.Slug));
                // Thiết lập và kiểm tra lại Model
                ModelState.Clear();
                TryValidateModel(post);
            }

            if (selectedCategories.Length == 0)
            {
                ModelState.AddModelError(String.Empty, "Phải ít nhất một chuyên mục");
            }

            bool SlugExisted = await _context.Posts.Where(p => p.Slug == post.Slug).AnyAsync();

            if (SlugExisted)
            {
                ModelState.AddModelError(nameof(post.Slug), "Slug đã có trong Database");
            }

            if (ModelState.IsValid)
            {
                //Tạo Post
                var newpost = new Post()
                {
                    AuthorId    = user.Id,
                    Title       = post.Title,
                    Slug        = post.Slug,
                    Content     = post.Content,
                    Description = post.Description,
                    Published   = post.Published,
                    DateCreated = DateTime.Now,
                    DateUpdated = DateTime.Now
                };
                _context.Add(newpost);
                await _context.SaveChangesAsync();

                // Chèn thông tin về PostCategory của bài Post
                foreach (var selectedCategory in selectedCategories)
                {
                    _context.Add(new PostCategory()
                    {
                        PostID = newpost.PostId, CategoryID = selectedCategory
                    });
                }
                await _context.SaveChangesAsync();

                return(RedirectToAction(nameof(Index)));
            }

            var categories = await _context.Categories.ToListAsync();

            ViewData["categories"] = new MultiSelectList(categories, "Id", "Title", selectedCategories);
            return(View(post));
        }
Example #21
0
 public abstract Task <Post> AddPostMin(PostBase value);
Example #22
0
 public async Task <IViewComponentResult> InvokeAsync(PostBase post)
 {
     // ReSharper disable once Mvc.ViewComponentViewNotResolved
     return(View(post));
 }
        /// <summary>
        /// Invokes the middleware.
        /// </summary>
        /// <param name="context">The current http context</param>
        /// <param name="api">The current api</param>
        /// <param name="service">The application service</param>
        /// <returns>An async task</returns>
        public override async Task Invoke(HttpContext context, IApi api, IApplicationService service)
        {
            var appConfig = new Config(api);

            if (!IsHandled(context) && !context.Request.Path.Value.StartsWith("/manager/assets/"))
            {
                var url      = context.Request.Path.HasValue ? context.Request.Path.Value : "";
                var segments = url.Substring(1).Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
                int pos      = 0;

                //
                // 1: Store raw url
                //
                service.Url = context.Request.Path.Value;

                //
                // 2: Get the current site
                //
                Site site = null;

                var hostname = context.Request.Host.Host;

                if (_config.UseSiteRouting)
                {
                    // Try to get the requested site by hostname & prefix
                    if (segments.Length > 0)
                    {
                        var prefixedHostname = $"{hostname}/{segments[0]}";
                        site = await api.Sites.GetByHostnameAsync(prefixedHostname)
                               .ConfigureAwait(false);

                        if (site != null)
                        {
                            context.Request.Path = "/" + string.Join("/", segments.Skip(1));
                            hostname             = prefixedHostname;
                            pos = 1;
                        }
                    }

                    // Try to get the requested site by hostname
                    if (site == null)
                    {
                        site = await api.Sites.GetByHostnameAsync(context.Request.Host.Host)
                               .ConfigureAwait(false);
                    }
                }

                // If we didn't find the site, get the default site
                if (site == null)
                {
                    site = await api.Sites.GetDefaultAsync()
                           .ConfigureAwait(false);
                }

                if (site != null)
                {
                    // Update application service
                    service.Site.Id      = site.Id;
                    service.Site.Culture = site.Culture;
                    service.Site.Sitemap = await api.Sites.GetSitemapAsync(site.Id);

                    // Set current culture if specified in site
                    if (!string.IsNullOrEmpty(site.Culture))
                    {
                        var cultureInfo = new CultureInfo(service.Site.Culture);
                        CultureInfo.CurrentCulture = CultureInfo.CurrentUICulture = cultureInfo;
                    }
                }
                else
                {
                    // There's no sites available, let the application finish
                    await _next.Invoke(context);

                    return;
                }

                // Store hostname
                service.Hostname = hostname;

                //
                // Check if we shouldn't handle empty requests for start page
                //
                if (segments.Length == 0 && !_config.UseStartpageRouting)
                {
                    await _next.Invoke(context);

                    return;
                }

                //
                // 3: Check for alias
                //
                if (_config.UseAliasRouting && segments.Length > pos)
                {
                    var alias = await api.Aliases.GetByAliasUrlAsync($"/{ string.Join("/", segments.Subset(pos)) }", service.Site.Id);

                    if (alias != null)
                    {
                        context.Response.Redirect(alias.RedirectUrl, alias.Type == RedirectType.Permanent);
                        return;
                    }
                }

                //
                // 4: Get the current page
                //
                PageBase page     = null;
                PageType pageType = null;

                if (segments.Length > pos)
                {
                    // Scan for the most unique slug
                    for (var n = segments.Length; n > pos; n--)
                    {
                        var slug = string.Join("/", segments.Subset(pos, n));
                        page = await api.Pages.GetBySlugAsync <PageBase>(slug, site.Id)
                               .ConfigureAwait(false);

                        if (page != null)
                        {
                            pos = pos + n;
                            break;
                        }
                    }
                }
                else
                {
                    page = await api.Pages.GetStartpageAsync <PageBase>(site.Id)
                           .ConfigureAwait(false);
                }

                if (page != null)
                {
                    pageType       = App.PageTypes.GetById(page.TypeId);
                    service.PageId = page.Id;

                    // Only cache published pages
                    if (page.IsPublished)
                    {
                        service.CurrentPage = page;
                    }
                }

                //
                // 5: Get the current post
                //
                PostBase post = null;

                if (_config.UsePostRouting)
                {
                    if (page != null && pageType.IsArchive && segments.Length > pos)
                    {
                        post = await api.Posts.GetBySlugAsync <PostBase>(page.Id, segments[pos])
                               .ConfigureAwait(false);

                        if (post != null)
                        {
                            pos++;
                        }
                    }

                    if (post != null)
                    {
                        App.PostTypes.GetById(post.TypeId);

                        // Onlyc cache published posts
                        if (post.IsPublished)
                        {
                            service.CurrentPost = post;
                        }
                    }
                }

                _logger?.LogDebug($"Found Site: [{ site.Id }]");
                if (page != null)
                {
                    _logger?.LogDebug($"Found Page: [{ page.Id }]");
                }

                if (post != null)
                {
                    _logger?.LogDebug($"Found Post: [{ post.Id }]");
                }

                //
                // 6: Route request
                //
                var route = new StringBuilder();
                var query = new StringBuilder();

                if (post != null)
                {
                    if (string.IsNullOrWhiteSpace(post.RedirectUrl))
                    {
                        // Handle HTTP caching
                        if (HandleCache(context, site, post, appConfig.CacheExpiresPosts))
                        {
                            // Client has latest version
                            return;
                        }

                        route.Append(post.Route ?? "/post");
                        for (var n = pos; n < segments.Length; n++)
                        {
                            route.Append("/");
                            route.Append(segments[n]);
                        }

                        query.Append("id=");
                        query.Append(post.Id);
                    }
                    else
                    {
                        _logger?.LogDebug($"Setting redirect: [{ post.RedirectUrl }]");

                        context.Response.Redirect(post.RedirectUrl, post.RedirectType == RedirectType.Permanent);
                        return;
                    }
                }
                else if (page != null && _config.UsePageRouting)
                {
                    if (string.IsNullOrWhiteSpace(page.RedirectUrl))
                    {
                        route.Append(page.Route ?? (pageType.IsArchive ? "/archive" : "/page"));

                        // Set the basic query
                        query.Append("id=");
                        query.Append(page.Id);

                        if (!page.ParentId.HasValue && page.SortOrder == 0)
                        {
                            query.Append("&startpage=true");
                        }

                        if (!pageType.IsArchive)
                        {
                            if (HandleCache(context, site, page, appConfig.CacheExpiresPages))
                            {
                                // Client has latest version.
                                return;
                            }

                            // This is a regular page, append trailing segments
                            for (var n = pos; n < segments.Length; n++)
                            {
                                route.Append("/");
                                route.Append(segments[n]);
                            }
                        }
                        else if (post == null)
                        {
                            // This is an archive, check for archive params
                            int? year          = null;
                            bool foundCategory = false;
                            bool foundTag      = false;
                            bool foundPage     = false;

                            for (var n = pos; n < segments.Length; n++)
                            {
                                if (segments[n] == "category" && !foundPage)
                                {
                                    foundCategory = true;
                                    continue;
                                }

                                if (segments[n] == "tag" && !foundPage && !foundCategory)
                                {
                                    foundTag = true;
                                    continue;
                                }

                                if (segments[n] == "page")
                                {
                                    foundPage = true;
                                    continue;
                                }

                                if (foundCategory)
                                {
                                    try
                                    {
                                        var categoryId = (await api.Posts.GetCategoryBySlugAsync(page.Id, segments[n]).ConfigureAwait(false))?.Id;

                                        if (categoryId.HasValue)
                                        {
                                            query.Append("&category=");
                                            query.Append(categoryId);
                                        }
                                    }
                                    finally
                                    {
                                        foundCategory = false;
                                    }
                                }

                                if (foundTag)
                                {
                                    try
                                    {
                                        var tagId = (await api.Posts.GetTagBySlugAsync(page.Id, segments[n]).ConfigureAwait(false))?.Id;

                                        if (tagId.HasValue)
                                        {
                                            query.Append("&tag=");
                                            query.Append(tagId);
                                        }
                                    }
                                    finally
                                    {
                                        foundTag = false;
                                    }
                                }

                                if (foundPage)
                                {
                                    try
                                    {
                                        var pageNum = Convert.ToInt32(segments[n]);
                                        query.Append("&page=");
                                        query.Append(pageNum);
                                        query.Append("&pagenum=");
                                        query.Append(pageNum);
                                    }
                                    catch
                                    {
                                        // We don't care about the exception, we just
                                        // discard malformed input
                                    }
                                    // Page number should always be last, break the loop
                                    break;
                                }

                                if (!year.HasValue)
                                {
                                    try
                                    {
                                        year = Convert.ToInt32(segments[n]);

                                        if (year.Value > DateTime.Now.Year)
                                        {
                                            year = DateTime.Now.Year;
                                        }
                                        query.Append("&year=");
                                        query.Append(year);
                                    }
                                    catch
                                    {
                                        // We don't care about the exception, we just
                                        // discard malformed input
                                    }
                                }
                                else
                                {
                                    try
                                    {
                                        var month = Math.Max(Math.Min(Convert.ToInt32(segments[n]), 12), 1);
                                        query.Append("&month=");
                                        query.Append(month);
                                    }
                                    catch
                                    {
                                        // We don't care about the exception, we just
                                        // discard malformed input
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        _logger?.LogDebug($"Setting redirect: [{ page.RedirectUrl }]");

                        context.Response.Redirect(page.RedirectUrl, page.RedirectType == RedirectType.Permanent);
                        return;
                    }
                }

                if (route.Length > 0)
                {
                    var strRoute = route.ToString();
                    var strQuery = query.ToString();

                    _logger?.LogDebug($"Setting Route: [{ strRoute }]");
                    _logger?.LogDebug($"Setting Query: [{ strQuery }]");

                    context.Request.Path = new PathString(strRoute);
                    if (context.Request.QueryString.HasValue)
                    {
                        context.Request.QueryString =
                            new QueryString(context.Request.QueryString.Value + "&" + strQuery);
                    }
                    else
                    {
                        context.Request.QueryString =
                            new QueryString("?" + strQuery);
                    }
                }
            }
            await _next.Invoke(context);
        }
Example #24
0
 public static string GetBodyShort(this PostBase postBase)
 {
     return(!string.IsNullOrEmpty(postBase.BodyShort)
                ? postBase.BodyShort
                : postBase.GetBodyShort(100));
 }