Exemplo n.º 1
0
        public async Task <PostEntity> UpdateAsync(EditPostRequest request)
        {
            var post = await _postRepository.GetAsync(request.Id);

            if (null == post)
            {
                throw new InvalidOperationException($"Post {request.Id} is not found.");
            }

            post.CommentEnabled  = request.EnableComment;
            post.PostContent     = request.EditorContent;
            post.ContentAbstract = GetPostAbstract(
                request.EditorContent,
                AppSettings.PostAbstractWords,
                AppSettings.Editor == EditorChoice.Markdown);

            // Address #221: Do not allow published posts back to draft status
            // postModel.IsPublished = request.IsPublished;
            // Edit draft -> save and publish, ignore false case because #221
            bool isNewPublish = false;

            if (request.IsPublished && !post.IsPublished)
            {
                post.IsPublished = true;
                post.PubDateUtc  = DateTime.UtcNow;

                isNewPublish = true;
            }

            // #325: Allow changing publish date for published posts
            if (request.PublishDate != null && post.PubDateUtc.HasValue)
            {
                var tod          = post.PubDateUtc.Value.TimeOfDay;
                var adjustedDate = _dateTimeResolver.ToUtc(request.PublishDate.Value);
                post.PubDateUtc = adjustedDate.AddTicks(tod.Ticks);
            }

            post.Slug                = request.Slug;
            post.Title               = request.Title;
            post.ExposedToSiteMap    = request.ExposedToSiteMap;
            post.LastModifiedUtc     = DateTime.UtcNow;
            post.IsFeedIncluded      = request.IsFeedIncluded;
            post.ContentLanguageCode = request.ContentLanguageCode;

            // 1. Add new tags to tag lib
            foreach (var item in request.Tags.Where(item => !_tagRepository.Any(p => p.DisplayName == item)))
            {
                await _tagRepository.AddAsync(new TagEntity
                {
                    DisplayName    = item,
                    NormalizedName = TagService.NormalizeTagName(item)
                });

                await _blogAudit.AddAuditEntry(EventType.Content, AuditEventId.TagCreated,
                                               $"Tag '{item}' created.");
            }

            // 2. update tags
            post.PostTag.Clear();
            if (request.Tags.Any())
            {
                foreach (var tagName in request.Tags)
                {
                    if (!TagService.ValidateTagName(tagName))
                    {
                        continue;
                    }

                    var tag = await _tagRepository.GetAsync(t => t.DisplayName == tagName);

                    if (tag != null)
                    {
                        post.PostTag.Add(new PostTagEntity
                        {
                            PostId = post.Id,
                            TagId  = tag.Id
                        });
                    }
                }
            }

            // 3. update categories
            post.PostCategory.Clear();
            if (null != request.CategoryIds && request.CategoryIds.Length > 0)
            {
                foreach (var cid in request.CategoryIds)
                {
                    if (_categoryRepository.Any(c => c.Id == cid))
                    {
                        post.PostCategory.Add(new PostCategoryEntity
                        {
                            PostId     = post.Id,
                            CategoryId = cid
                        });
                    }
                }
            }

            await _postRepository.UpdateAsync(post);

            await _blogAudit.AddAuditEntry(
                EventType.Content,
                isNewPublish?AuditEventId.PostPublished : AuditEventId.PostUpdated,
                $"Post updated, id: {post.Id}");

            _cache.Remove(CacheDivision.Post, request.Id.ToString());
            return(post);
        }
Exemplo n.º 2
0
        public async Task <PostEntity> CreateAsync(CreatePostRequest request)
        {
            var abs = GetPostAbstract(
                request.EditorContent, AppSettings.PostAbstractWords,
                AppSettings.Editor == EditorChoice.Markdown);

            var post = new PostEntity
            {
                CommentEnabled      = request.EnableComment,
                Id                  = Guid.NewGuid(),
                PostContent         = request.EditorContent,
                ContentAbstract     = abs,
                CreateOnUtc         = DateTime.UtcNow,
                Slug                = request.Slug.ToLower().Trim(),
                Title               = request.Title.Trim(),
                ContentLanguageCode = request.ContentLanguageCode,
                ExposedToSiteMap    = request.ExposedToSiteMap,
                IsFeedIncluded      = request.IsFeedIncluded,
                PubDateUtc          = request.IsPublished ? DateTime.UtcNow : (DateTime?)null,
                IsDeleted           = false,
                IsPublished         = request.IsPublished,
                PostExtension       = new PostExtensionEntity
                {
                    Hits  = 0,
                    Likes = 0
                }
            };

            // check if exist same slug under the same day
            // linq to sql fix:
            // cannot write "p.PubDateUtc.GetValueOrDefault().Date == DateTime.UtcNow.Date"
            // it will not blow up, but can result in select ENTIRE posts and evaluated in memory!!!
            // - The LINQ expression 'where (Convert([p]?.PubDateUtc?.GetValueOrDefault(), DateTime).Date == DateTime.UtcNow.Date)' could not be translated and will be evaluated locally
            // Why EF Core this diao yang?
            if (_postRepository.Any(p =>
                                    p.Slug == post.Slug &&
                                    p.PubDateUtc != null &&
                                    p.PubDateUtc.Value.Year == DateTime.UtcNow.Date.Year &&
                                    p.PubDateUtc.Value.Month == DateTime.UtcNow.Date.Month &&
                                    p.PubDateUtc.Value.Day == DateTime.UtcNow.Date.Day))
            {
                var uid = Guid.NewGuid();
                post.Slug += $"-{uid.ToString().ToLower().Substring(0, 8)}";
                Logger.LogInformation($"Found conflict for post slug, generated new slug: {post.Slug}");
            }

            // add categories
            if (null != request.CategoryIds && request.CategoryIds.Length > 0)
            {
                foreach (var cid in request.CategoryIds)
                {
                    if (_categoryRepository.Any(c => c.Id == cid))
                    {
                        post.PostCategory.Add(new PostCategoryEntity
                        {
                            CategoryId = cid,
                            PostId     = post.Id
                        });
                    }
                }
            }

            // add tags
            if (null != request.Tags && request.Tags.Length > 0)
            {
                foreach (var item in request.Tags)
                {
                    if (!TagService.ValidateTagName(item))
                    {
                        continue;
                    }

                    var tag = await _tagRepository.GetAsync(q => q.DisplayName == item);

                    if (null == tag)
                    {
                        var newTag = new TagEntity
                        {
                            DisplayName    = item,
                            NormalizedName = TagService.NormalizeTagName(item)
                        };

                        tag = await _tagRepository.AddAsync(newTag);

                        await _blogAudit.AddAuditEntry(EventType.Content, AuditEventId.TagCreated,
                                                       $"Tag '{tag.NormalizedName}' created.");
                    }

                    post.PostTag.Add(new PostTagEntity
                    {
                        TagId  = tag.Id,
                        PostId = post.Id
                    });
                }
            }

            await _postRepository.AddAsync(post);

            await _blogAudit.AddAuditEntry(EventType.Content, AuditEventId.PostCreated, $"Post created, id: {post.Id}");

            return(post);
        }