wp-go/app/theme/wp/index.go
2023-12-03 22:42:44 +08:00

180 lines
4.4 KiB
Go

package wp
import (
"database/sql"
"errors"
"fmt"
"github.com/fthvgb1/wp-go/app/pkg/cache"
"github.com/fthvgb1/wp-go/app/pkg/constraints"
"github.com/fthvgb1/wp-go/app/pkg/models"
"github.com/fthvgb1/wp-go/app/plugins"
"github.com/fthvgb1/wp-go/cache/reload"
"github.com/fthvgb1/wp-go/helper/number"
"github.com/fthvgb1/wp-go/helper/slice"
"github.com/fthvgb1/wp-go/model"
"github.com/fthvgb1/wp-go/plugin/pagination"
"strings"
)
type IndexHandle struct {
*Handle
Param *IndexParams
Posts []models.Posts
pageEle pagination.Elements
TotalRows int
postsPlugin PostsPlugin
}
func (i *IndexHandle) ListPlugin() func(*Handle, *models.Posts) {
return i.postsPlugin
}
func (i *IndexHandle) SetListPlugin(listPlugin func(*Handle, *models.Posts)) {
i.postsPlugin = listPlugin
}
func (i *IndexHandle) PageEle() pagination.Elements {
return i.pageEle
}
func (i *IndexHandle) SetPageEle(pageEle pagination.Elements) {
i.pageEle = pageEle
}
func NewIndexHandle(handle *Handle) *IndexHandle {
return &IndexHandle{Handle: handle}
}
func PushIndexHandler(pipeScene string, h *Handle, call HandleCall) {
h.PushHandlers(pipeScene, call, constraints.Home,
constraints.Category, constraints.Search, constraints.Tag,
constraints.Archive, constraints.Author,
)
}
func (i *IndexHandle) ParseIndex(parm *IndexParams) (err error) {
i.Param = parm
switch i.scene {
case constraints.Search:
i.Param.ParseSearch()
case constraints.Category:
err = i.Param.ParseCategory()
case constraints.Tag:
err = i.Param.ParseTag()
case constraints.Archive:
err = i.Param.ParseArchive()
case constraints.Author:
err = i.Param.ParseAuthor()
}
if err != nil {
i.Stats = constraints.ParamError
return
}
i.Param.ParseParams()
i.Param.CacheKey = i.Param.getSearchKey()
i.ginH["title"] = i.Param.getTitle()
i.ginH["search"] = i.Param.Search
i.ginH["header"] = i.Param.Header
return
}
func (i *IndexHandle) GetIndexData() (posts []models.Posts, totalRaw int, err error) {
q := &model.QueryCondition{
Where: i.Param.Where,
Order: model.SqlBuilder{{i.Param.OrderBy, i.Param.Order}},
Join: i.Param.Join,
In: [][]any{i.Param.PostType, i.Param.PostStatus},
}
switch i.scene {
case constraints.Home, constraints.Category, constraints.Tag, constraints.Author:
posts, totalRaw, err = cache.PostLists(i.C, i.Param.CacheKey, q, i.Param.Page, i.Param.PageSize)
if i.scene == constraints.Home && i.Param.Page == 1 {
i.MarkSticky(&posts)
}
case constraints.Search:
posts, totalRaw, err = cache.SearchPost(i.C, i.Param.CacheKey, q, i.Param.Page, i.Param.PageSize)
case constraints.Archive:
i.ginH["archiveYear"] = i.Param.Year
i.ginH["archiveMonth"] = strings.TrimLeft(i.Param.Month, "0")
posts, totalRaw, err = cache.GetMonthPostIds(i.C, i.Param.Year, i.Param.Month, i.Param.Page, i.Param.PageSize, i.Param.Order)
}
return
}
func (i *IndexHandle) Pagination() {
if i.pageEle == nil {
i.pageEle = plugins.TwentyFifteenPagination()
}
q := i.C.Request.URL.Query().Encode()
if q != "" {
q = fmt.Sprintf("?%s", q)
}
paginations := pagination.NewParsePagination(i.TotalRows, i.Param.PageSize, i.Param.Page, i.Param.PaginationStep, q, i.C.Request.URL.Path)
i.ginH["pagination"] = pagination.Paginate(i.pageEle, paginations)
}
func (i *IndexHandle) BuildIndexData(parm *IndexParams) (err error) {
err = i.ParseIndex(parm)
if err != nil {
i.Stats = constraints.ParamError
return
}
posts, totalRows, err := i.GetIndexData()
if err != nil && !errors.Is(err, sql.ErrNoRows) {
i.Stats = constraints.Error404
return
}
i.Posts = posts
i.TotalRows = totalRows
i.ginH["totalPage"] = number.DivideCeil(totalRows, i.Param.PageSize)
return
}
func (i *IndexHandle) ExecPostsPlugin() {
fn := i.postsPlugin
if fn == nil {
fn = reload.GetAnyValBys("postPlugins", i, func(a *IndexHandle) (PostsPlugin, bool) {
return UsePostsPlugins(), true
})
}
for j := range i.Posts {
fn(i.Handle, &i.Posts[j])
}
}
func IndexRender(h *Handle) {
i := h.Index
i.ExecPostsPlugin()
i.Pagination()
i.ginH["posts"] = i.Posts
}
func Index(h *Handle) {
i := h.Index
err := i.BuildIndexData(NewIndexParams(i.C))
if err != nil {
i.SetErr(err)
}
h.SetData("scene", h.Scene())
}
func (i *IndexHandle) MarkSticky(posts *[]models.Posts) {
a := i.StickPosts()
if len(a) < 1 {
return
}
m := i.StickMapPosts()
*posts = append(a, slice.Filter(*posts, func(post models.Posts, _ int) bool {
_, ok := m[post.Id]
return !ok
})...)
}