Browse Source

Cats for blog module like in shop

Vova Tkach 5 years ago
parent
commit
dde318017c

+ 12 - 4
assets/template/sidebar_right_html_file.go

@@ -4,10 +4,18 @@ var VarSidebarRightHtmlFile = []byte(`<div class="card mb-4">
 	<h5 class="card-header">Blog categories</h5>
 	<div class="card-body">
 		<ul class="m-0 p-0 pl-4">
-			{{range $.Data.Blog.Categories 0}}
-				<li class="{{if and $.Data.Blog.Category (eq $.Data.Blog.Category.Id .Id)}}active{{end}}">
-					<a href="{{.Permalink}}">{{.Name}}</a>
-				</li>
+			{{if $.Data.Blog.Category}}
+				{{range $.Data.Blog.Categories $.Data.Blog.Category.Id 1}}
+					<li class="{{if and $.Data.Blog.Category (eq $.Data.Blog.Category.Id .Id)}}active{{end}}">
+						<a href="{{.Permalink}}">{{.Name}}</a>
+					</li>
+				{{end}}
+			{{else}}
+				{{range $.Data.Blog.Categories 0 1}}
+					<li class="{{if and $.Data.Blog.Category (eq $.Data.Blog.Category.Id .Id)}}active{{end}}">
+						<a href="{{.Permalink}}">{{.Name}}</a>
+					</li>
+				{{end}}
 			{{end}}
 		</ul>
 	</div>

+ 75 - 23
engine/fetdata/blog.go

@@ -2,6 +2,7 @@ package fetdata
 
 import (
 	"math"
+	"sort"
 	"strings"
 
 	"golang-fave/engine/wrapper"
@@ -29,7 +30,7 @@ type Blog struct {
 	paginationPrev *BlogPagination
 	paginationNext *BlogPagination
 
-	bufferCats map[string][]*BlogCategory
+	bufferCats map[int]*utils.MySql_blog_category
 }
 
 func (this *Blog) load() *Blog {
@@ -360,23 +361,19 @@ func (this *Blog) PaginationNext() *BlogPagination {
 	return this.paginationNext
 }
 
-func (this *Blog) Categories(mlvl int) []*BlogCategory {
-	if this == nil {
-		return []*BlogCategory{}
-	}
+func (this *Blog) Categories(parent, depth int) []*BlogCategory {
 	if this.bufferCats == nil {
-		this.bufferCats = map[string][]*BlogCategory{}
-	}
-	key := ""
-	where := ``
-	if mlvl > 0 {
-		where += `AND tbl.depth <= ` + utils.IntToStr(mlvl)
-	}
-	if _, ok := this.bufferCats[key]; !ok {
-		var cats []*BlogCategory
+		this.bufferCats = map[int]*utils.MySql_blog_category{}
 		if rows, err := this.wrap.DB.Query(`
 			SELECT
-				tbl.*
+				main.id,
+				main.user,
+				main.name,
+				main.alias,
+				main.lft,
+				main.rgt,
+				depth.depth,
+				MAX(main.parent_id) AS parent_id
 			FROM
 				(
 					SELECT
@@ -386,6 +383,19 @@ func (this *Blog) Categories(mlvl int) []*BlogCategory {
 						node.alias,
 						node.lft,
 						node.rgt,
+						parent.id AS parent_id
+					FROM
+						blog_cats AS node,
+						blog_cats AS parent
+					WHERE
+						node.lft BETWEEN parent.lft AND parent.rgt AND
+						node.id > 1
+					ORDER BY
+						node.lft ASC
+				) AS main
+				LEFT JOIN (
+					SELECT
+						node.id,
 						(COUNT(parent.id) - 1) AS depth
 					FROM
 						blog_cats AS node,
@@ -396,22 +406,64 @@ func (this *Blog) Categories(mlvl int) []*BlogCategory {
 						node.id
 					ORDER BY
 						node.lft ASC
-				) AS tbl
+				) AS depth ON depth.id = main.id
 			WHERE
-				tbl.id > 1
-				` + where + `
+				main.id > 1 AND
+				main.id <> main.parent_id
+			GROUP BY
+				main.id
+			ORDER BY
+				main.lft ASC
 			;
 		`); err == nil {
 			defer rows.Close()
 			for rows.Next() {
 				row := utils.MySql_blog_category{}
-				var Depth int
-				if err := rows.Scan(&row.A_id, &row.A_user, &row.A_name, &row.A_alias, &row.A_lft, &row.A_rgt, &Depth); err == nil {
-					cats = append(cats, &BlogCategory{object: &row, depth: Depth})
+				if err := rows.Scan(
+					&row.A_id,
+					&row.A_user,
+					&row.A_name,
+					&row.A_alias,
+					&row.A_lft,
+					&row.A_rgt,
+					&row.A_depth,
+					&row.A_parent,
+				); err == nil {
+					this.bufferCats[row.A_id] = &row
+				}
+			}
+		}
+	}
+
+	depth_tmp := 0
+	result := []*BlogCategory{}
+
+	for _, cat := range this.bufferCats {
+		if parent <= 1 {
+			if depth <= 0 {
+				result = append(result, (&BlogCategory{wrap: this.wrap, object: cat}).load(&this.bufferCats))
+			} else {
+				if cat.A_depth <= depth {
+					result = append(result, (&BlogCategory{wrap: this.wrap, object: cat}).load(&this.bufferCats))
+				}
+			}
+		} else {
+			if cat.A_parent == parent {
+				if depth_tmp == 0 {
+					depth_tmp = cat.A_depth
+				}
+				if depth <= 0 {
+					result = append(result, (&BlogCategory{wrap: this.wrap, object: cat}).load(&this.bufferCats))
+				} else {
+					if (cat.A_depth - depth_tmp + 1) <= depth {
+						result = append(result, (&BlogCategory{wrap: this.wrap, object: cat}).load(&this.bufferCats))
+					}
 				}
 			}
 		}
-		this.bufferCats[key] = cats
 	}
-	return this.bufferCats[key]
+
+	sort.Slice(result, func(i, j int) bool { return result[i].Left() < result[j].Left() })
+
+	return result
 }

+ 178 - 3
engine/fetdata/blog_category.go

@@ -8,15 +8,168 @@ import (
 type BlogCategory struct {
 	wrap   *wrapper.Wrapper
 	object *utils.MySql_blog_category
-	depth  int
 
 	user *User
+
+	bufferCats map[int]*utils.MySql_blog_category
 }
 
-func (this *BlogCategory) load() *BlogCategory {
+func (this *BlogCategory) load(cache *map[int]*utils.MySql_blog_category) *BlogCategory {
+	if this == nil {
+		return this
+	}
+	if cache != nil {
+		this.bufferCats = (*cache)
+		return this
+	}
+	if this.bufferCats == nil {
+		this.bufferCats = map[int]*utils.MySql_blog_category{}
+	}
+	if rows, err := this.wrap.DB.Query(`
+		SELECT
+			main.id,
+			main.user,
+			main.name,
+			main.alias,
+			main.lft,
+			main.rgt,
+			depth.depth,
+			MAX(main.parent_id) AS parent_id
+		FROM
+			(
+				SELECT
+					node.id,
+					node.user,
+					node.name,
+					node.alias,
+					node.lft,
+					node.rgt,
+					parent.id AS parent_id
+				FROM
+					blog_cats AS node,
+					blog_cats AS parent
+				WHERE
+					node.lft BETWEEN parent.lft AND parent.rgt AND
+					node.id > 1
+				ORDER BY
+					node.lft ASC
+			) AS main
+			LEFT JOIN (
+				SELECT
+					node.id,
+					(COUNT(parent.id) - 1) AS depth
+				FROM
+					blog_cats AS node,
+					blog_cats AS parent
+				WHERE
+					node.lft BETWEEN parent.lft AND parent.rgt
+				GROUP BY
+					node.id
+				ORDER BY
+					node.lft ASC
+			) AS depth ON depth.id = main.id
+		WHERE
+			main.id > 1 AND
+			main.id <> main.parent_id
+		GROUP BY
+			main.id
+		ORDER BY
+			main.lft ASC
+		;
+	`); err == nil {
+		defer rows.Close()
+		for rows.Next() {
+			row := utils.MySql_blog_category{}
+			if err := rows.Scan(
+				&row.A_id,
+				&row.A_user,
+				&row.A_name,
+				&row.A_alias,
+				&row.A_lft,
+				&row.A_rgt,
+				&row.A_depth,
+				&row.A_parent,
+			); err == nil {
+				this.bufferCats[row.A_id] = &row
+			}
+		}
+	}
 	return this
 }
 
+func (this *BlogCategory) loadById(id int) {
+	if this == nil {
+		return
+	}
+	if this.object != nil {
+		return
+	}
+	this.object = &utils.MySql_blog_category{}
+	if err := this.wrap.DB.QueryRow(`
+		SELECT
+			main.id,
+			main.user,
+			main.name,
+			main.alias,
+			main.lft,
+			main.rgt,
+			depth.depth,
+			MAX(main.parent_id) AS parent_id
+		FROM
+			(
+				SELECT
+					node.id,
+					node.user,
+					node.name,
+					node.alias,
+					node.lft,
+					node.rgt,
+					parent.id AS parent_id
+				FROM
+					blog_cats AS node,
+					blog_cats AS parent
+				WHERE
+					node.lft BETWEEN parent.lft AND parent.rgt AND
+					node.id > 1
+				ORDER BY
+					node.lft ASC
+			) AS main
+			LEFT JOIN (
+				SELECT
+					node.id,
+					(COUNT(parent.id) - 1) AS depth
+				FROM
+					blog_cats AS node,
+					blog_cats AS parent
+				WHERE
+					node.lft BETWEEN parent.lft AND parent.rgt
+				GROUP BY
+					node.id
+				ORDER BY
+					node.lft ASC
+			) AS depth ON depth.id = main.id
+		WHERE
+			main.id > 1 AND
+			main.id <> main.parent_id AND
+			main.id = ?
+		GROUP BY
+			main.id
+		;`,
+		id,
+	).Scan(
+		&this.object.A_id,
+		&this.object.A_user,
+		&this.object.A_name,
+		&this.object.A_alias,
+		&this.object.A_lft,
+		&this.object.A_rgt,
+		&this.object.A_depth,
+		&this.object.A_parent,
+	); err != nil {
+		return
+	}
+}
+
 func (this *BlogCategory) Id() int {
 	if this == nil {
 		return 0
@@ -75,5 +228,27 @@ func (this *BlogCategory) Level() int {
 	if this == nil {
 		return 0
 	}
-	return this.depth
+	return this.object.A_depth
+}
+
+func (this *BlogCategory) Parent() *BlogCategory {
+	if this == nil {
+		return nil
+	}
+	if this.bufferCats == nil {
+		return nil
+	}
+	if _, ok := this.bufferCats[this.object.A_parent]; !ok {
+		return nil
+	}
+	cat := &BlogCategory{wrap: this.wrap, object: this.bufferCats[this.object.A_parent]}
+	return cat.load(&this.bufferCats)
+}
+
+func (this *BlogCategory) HaveChilds() bool {
+	// TODO: Add ability
+	if this == nil {
+		return false
+	}
+	return false
 }

+ 1 - 1
engine/fetdata/fetdata.go

@@ -29,7 +29,7 @@ func New(wrap *wrapper.Wrapper, drow interface{}, is404 bool) *FERData {
 	} else if wrap.CurrModule == "blog" {
 		if len(wrap.UrlArgs) == 3 && wrap.UrlArgs[0] == "blog" && wrap.UrlArgs[1] == "category" && wrap.UrlArgs[2] != "" {
 			if o, ok := drow.(*utils.MySql_blog_category); ok {
-				d_Blog = &Blog{wrap: wrap, category: (&BlogCategory{wrap: wrap, object: o}).load()}
+				d_Blog = &Blog{wrap: wrap, category: (&BlogCategory{wrap: wrap, object: o}).load(nil)}
 				d_Blog.load()
 			}
 		} else if len(wrap.UrlArgs) == 2 && wrap.UrlArgs[0] == "blog" && wrap.UrlArgs[1] != "" {

+ 28 - 20
hosts/localhost/template/sidebar-right.html

@@ -1,21 +1,29 @@
-<div class="card mb-4">
-	<h5 class="card-header">Blog categories</h5>
-	<div class="card-body">
-		<ul class="m-0 p-0 pl-4">
-			{{range $.Data.Blog.Categories 0}}
-				<li class="{{if and $.Data.Blog.Category (eq $.Data.Blog.Category.Id .Id)}}active{{end}}">
-					<a href="{{.Permalink}}">{{.Name}}</a>
-				</li>
-			{{end}}
-		</ul>
-	</div>
-</div>
-<div class="card mb-4">
-	<h5 class="card-header">Useful links</h5>
-	<div class="card-body">
-		<ul class="m-0 p-0 pl-4">
-			<li><a href="https://github.com/vladimirok5959/golang-fave" target="_blank">Project on GitHub</a></li>
-			<li><a href="https://github.com/vladimirok5959/golang-fave/wiki" target="_blank">Wiki on GitHub</a></li>
-		</ul>
-	</div>
+<div class="card mb-4">
+	<h5 class="card-header">Blog categories</h5>
+	<div class="card-body">
+		<ul class="m-0 p-0 pl-4">
+			{{if $.Data.Blog.Category}}
+				{{range $.Data.Blog.Categories $.Data.Blog.Category.Id 1}}
+					<li class="{{if and $.Data.Blog.Category (eq $.Data.Blog.Category.Id .Id)}}active{{end}}">
+						<a href="{{.Permalink}}">{{.Name}}</a>
+					</li>
+				{{end}}
+			{{else}}
+				{{range $.Data.Blog.Categories 0 1}}
+					<li class="{{if and $.Data.Blog.Category (eq $.Data.Blog.Category.Id .Id)}}active{{end}}">
+						<a href="{{.Permalink}}">{{.Name}}</a>
+					</li>
+				{{end}}
+			{{end}}
+		</ul>
+	</div>
+</div>
+<div class="card mb-4">
+	<h5 class="card-header">Useful links</h5>
+	<div class="card-body">
+		<ul class="m-0 p-0 pl-4">
+			<li><a href="https://github.com/vladimirok5959/golang-fave" target="_blank">Project on GitHub</a></li>
+			<li><a href="https://github.com/vladimirok5959/golang-fave/wiki" target="_blank">Wiki on GitHub</a></li>
+		</ul>
+	</div>
 </div>

+ 48 - 10
modules/module_blog.go

@@ -37,18 +37,54 @@ func (this *Modules) RegisterModule_Blog() *Module {
 			row := &utils.MySql_blog_category{}
 			err := wrap.DB.QueryRow(`
 				SELECT
-					id,
-					user,
-					name,
-					alias,
-					lft,
-					rgt
+					main.id,
+					main.user,
+					main.name,
+					main.alias,
+					main.lft,
+					main.rgt,
+					depth.depth,
+					MAX(main.parent_id) AS parent_id
 				FROM
-					blog_cats
+					(
+						SELECT
+							node.id,
+							node.user,
+							node.name,
+							node.alias,
+							node.lft,
+							node.rgt,
+							parent.id AS parent_id
+						FROM
+							blog_cats AS node,
+							blog_cats AS parent
+						WHERE
+							node.lft BETWEEN parent.lft AND parent.rgt AND
+							node.id > 1
+						ORDER BY
+							node.lft ASC
+					) AS main
+					LEFT JOIN (
+						SELECT
+							node.id,
+							(COUNT(parent.id) - 1) AS depth
+						FROM
+							blog_cats AS node,
+							blog_cats AS parent
+						WHERE
+							node.lft BETWEEN parent.lft AND parent.rgt
+						GROUP BY
+							node.id
+						ORDER BY
+							node.lft ASC
+					) AS depth ON depth.id = main.id
 				WHERE
-					alias = ? AND
-					id > 1
-				LIMIT 1;`,
+					main.id > 1 AND
+					main.id <> main.parent_id AND
+					main.alias = ?
+				GROUP BY
+					main.id
+				;`,
 				wrap.UrlArgs[2],
 			).Scan(
 				&row.A_id,
@@ -57,6 +93,8 @@ func (this *Modules) RegisterModule_Blog() *Module {
 				&row.A_alias,
 				&row.A_lft,
 				&row.A_rgt,
+				&row.A_depth,
+				&row.A_parent,
 			)
 
 			if err != nil && err != wrapper.ErrNoRows {

+ 8 - 6
utils/mysql_struct_blog_category.go

@@ -1,10 +1,12 @@
 package utils
 
 type MySql_blog_category struct {
-	A_id    int
-	A_user  int
-	A_name  string
-	A_alias string
-	A_lft   int
-	A_rgt   int
+	A_id     int
+	A_user   int
+	A_name   string
+	A_alias  string
+	A_lft    int
+	A_rgt    int
+	A_depth  int
+	A_parent int
 }