github.com/ngocphuongnb/tetua@v0.0.7-alpha/packages/entrepository/post.go (about)

     1  package entrepository
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  	"time"
     8  
     9  	"github.com/ngocphuongnb/tetua/app/entities"
    10  	e "github.com/ngocphuongnb/tetua/app/entities"
    11  	"github.com/ngocphuongnb/tetua/app/utils"
    12  	"github.com/ngocphuongnb/tetua/packages/entrepository/ent"
    13  	"github.com/ngocphuongnb/tetua/packages/entrepository/ent/post"
    14  	"github.com/ngocphuongnb/tetua/packages/entrepository/ent/topic"
    15  )
    16  
    17  type PostRepository struct {
    18  	*BaseRepository[e.Post, ent.Post, *ent.PostQuery, *e.PostFilter]
    19  }
    20  
    21  func (p *PostRepository) IncreaseViewCount(ctx context.Context, id int, views int64) (err error) {
    22  	_, err = p.Client.Post.UpdateOneID(id).AddViewCount(views).Save(ctx)
    23  	return
    24  }
    25  
    26  func (p *PostRepository) Approve(ctx context.Context, id int) (err error) {
    27  	_, err = p.Client.Post.UpdateOneID(id).SetApproved(true).Save(ctx)
    28  	return
    29  }
    30  
    31  func (p *PostRepository) PublishedPostByID(ctx context.Context, id int) (*entities.Post, error) {
    32  	post, err := p.Client.Post.
    33  		Query().
    34  		Where(post.DeletedAtIsNil()).
    35  		Where(post.IDEQ(id)).
    36  		Where(post.DraftEQ(false)).
    37  		Where(post.Approved(true)).
    38  		WithUser(func(uq *ent.UserQuery) {
    39  			uq.WithAvatarImage()
    40  		}).
    41  		WithTopics().
    42  		WithFeaturedImage().
    43  		Only(ctx)
    44  
    45  	if err != nil {
    46  		return nil, EntError(err, fmt.Sprintf("post not found with id: %d", id))
    47  	}
    48  
    49  	return entPostToPost(post), nil
    50  }
    51  
    52  func CreatePostRepository(client *ent.Client) *PostRepository {
    53  	return &PostRepository{
    54  		BaseRepository: &BaseRepository[e.Post, ent.Post, *ent.PostQuery, *e.PostFilter]{
    55  			Name:      "post",
    56  			Client:    client,
    57  			ConvertFn: entPostToPost,
    58  			ByIDFn: func(ctx context.Context, client *ent.Client, id int) (*ent.Post, error) {
    59  				return client.Post.Query().
    60  					Where(post.DeletedAtIsNil()).
    61  					Where(post.IDEQ(id)).
    62  					WithUser(func(uq *ent.UserQuery) {
    63  						uq.WithAvatarImage()
    64  					}).
    65  					WithTopics().
    66  					WithFeaturedImage().
    67  					Only(ctx)
    68  			},
    69  			DeleteByIDFn: func(ctx context.Context, client *ent.Client, id int) error {
    70  				return client.Post.UpdateOneID(id).SetDeletedAt(time.Now()).Exec(ctx)
    71  			},
    72  			CreateFn: func(ctx context.Context, client *ent.Client, data *e.Post) (*ent.Post, error) {
    73  				if data.UserID == 0 {
    74  					return nil, errors.New("user_id is required")
    75  				}
    76  				cq := client.Post.Create().
    77  					SetName(data.Name).
    78  					SetDescription(data.Description).
    79  					SetSlug(data.Slug).
    80  					SetContentHTML(data.ContentHTML).
    81  					SetContent(data.Content).
    82  					SetDraft(data.Draft).
    83  					SetApproved(data.Approved).
    84  					SetUserID(data.UserID).
    85  					AddTopicIDs(data.TopicIDs...)
    86  
    87  				if data.FeaturedImageID != 0 {
    88  					cq.SetFeaturedImageID(data.FeaturedImageID)
    89  				}
    90  
    91  				return cq.Save(ctx)
    92  			},
    93  			UpdateFn: func(ctx context.Context, client *ent.Client, data *e.Post) (*ent.Post, error) {
    94  				if data.ID == 0 {
    95  					return nil, errors.New("post id is required in order to update")
    96  				}
    97  				uq := client.Post.UpdateOneID(data.ID).
    98  					SetName(data.Name).
    99  					SetDescription(data.Description).
   100  					SetSlug(data.Slug).
   101  					SetContentHTML(data.ContentHTML).
   102  					SetContent(data.Content).
   103  					SetDraft(data.Draft).
   104  					SetApproved(data.Approved)
   105  
   106  				if len(data.TopicIDs) > 0 {
   107  					oldPostEnt, err := client.Post.Query().
   108  						WithTopics().
   109  						Where(post.DeletedAtIsNil()).
   110  						Where(post.IDEQ(data.ID)).Only(ctx)
   111  
   112  					if err != nil {
   113  						return nil, err
   114  					}
   115  
   116  					oldPost := entPostToPost(oldPostEnt)
   117  					oldTopicIDs := utils.SliceMap(oldPost.Topics, func(t *entities.Topic) int {
   118  						return t.ID
   119  					})
   120  					uq.RemoveTopicIDs(oldTopicIDs...).AddTopicIDs(data.TopicIDs...)
   121  				}
   122  
   123  				if data.FeaturedImageID != 0 {
   124  					uq.SetFeaturedImageID(data.FeaturedImageID)
   125  				}
   126  
   127  				return uq.Save(ctx)
   128  			},
   129  			QueryFilterFn: func(client *ent.Client, filters ...*e.PostFilter) *ent.PostQuery {
   130  				query := client.Post.Query().Where(post.DeletedAtIsNil())
   131  				publish := "published"
   132  				approved := "approved"
   133  
   134  				if len(filters) > 0 {
   135  					if filters[0].Publish != "" {
   136  						publish = filters[0].Publish
   137  					}
   138  					if filters[0].Approve != "" {
   139  						approved = filters[0].Approve
   140  					}
   141  
   142  					if len(filters[0].UserIDs) > 0 {
   143  						query = query.Where(post.UserIDIn(filters[0].UserIDs...))
   144  					}
   145  
   146  					if len(filters[0].TopicIDs) > 0 {
   147  						query = query.Where(post.HasTopicsWith(topic.IDIn(filters[0].TopicIDs...)))
   148  					}
   149  
   150  					if len(filters[0].ExcludeIDs) > 0 {
   151  						query = query.Where(post.IDNotIn(filters[0].ExcludeIDs...))
   152  					}
   153  				}
   154  
   155  				if publish != "all" {
   156  					if publish == "published" {
   157  						query = query.Where(post.DraftEQ(false))
   158  					}
   159  
   160  					if publish == "draft" {
   161  						query = query.Where(post.DraftEQ(true))
   162  					}
   163  				}
   164  
   165  				if approved != "all" {
   166  					if approved == "approved" {
   167  						query = query.Where(post.Approved(true))
   168  					}
   169  
   170  					if approved == "pending" {
   171  						query = query.Where(post.Approved(false))
   172  					}
   173  				}
   174  
   175  				return query
   176  			},
   177  			FindFn: func(ctx context.Context, query *ent.PostQuery, filters ...*e.PostFilter) ([]*ent.Post, error) {
   178  				page, limit, sorts := getPaginateParams(filters[0])
   179  				return query.
   180  					WithUser(func(uq *ent.UserQuery) {
   181  						uq.WithAvatarImage()
   182  					}).
   183  					WithTopics().
   184  					WithFeaturedImage().
   185  					Limit(limit).
   186  					Offset((page - 1) * limit).
   187  					Order(sorts...).
   188  					All(ctx)
   189  			},
   190  		},
   191  	}
   192  }