blog.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  1. package fetdata
  2. import (
  3. "math"
  4. "sort"
  5. "strings"
  6. "golang-fave/engine/wrapper"
  7. "golang-fave/utils"
  8. )
  9. type BlogPagination struct {
  10. Num string
  11. Link string
  12. Current bool
  13. Dots bool
  14. }
  15. type Blog struct {
  16. wrap *wrapper.Wrapper
  17. category *BlogCategory
  18. post *BlogPost
  19. posts []*BlogPost
  20. postsCount int
  21. postsPerPage int
  22. postsMaxPage int
  23. postsCurrPage int
  24. pagination []*BlogPagination
  25. paginationPrev *BlogPagination
  26. paginationNext *BlogPagination
  27. bufferCats map[int]*utils.MySql_blog_category
  28. }
  29. func (this *Blog) load() *Blog {
  30. if this == nil {
  31. return this
  32. }
  33. sql_nums := `
  34. SELECT
  35. COUNT(*)
  36. FROM
  37. blog_posts
  38. WHERE
  39. active = 1
  40. ;
  41. `
  42. sql_rows := `
  43. SELECT
  44. blog_posts.id,
  45. blog_posts.user,
  46. blog_posts.name,
  47. blog_posts.alias,
  48. blog_posts.briefly,
  49. blog_posts.content,
  50. UNIX_TIMESTAMP(blog_posts.datetime) as datetime,
  51. blog_posts.active,
  52. users.id,
  53. users.first_name,
  54. users.last_name,
  55. users.email,
  56. users.admin,
  57. users.active
  58. FROM
  59. blog_posts
  60. LEFT JOIN users ON users.id = blog_posts.user
  61. WHERE
  62. blog_posts.active = 1
  63. ORDER BY
  64. blog_posts.id DESC
  65. LIMIT ?, ?;
  66. `
  67. // Category selected
  68. if this.category != nil {
  69. var cat_ids []string
  70. if rows, err := this.wrap.DB.Query(
  71. `SELECT
  72. node.id
  73. FROM
  74. blog_cats AS node,
  75. blog_cats AS parent
  76. WHERE
  77. node.lft BETWEEN parent.lft AND parent.rgt AND
  78. node.id > 1 AND
  79. parent.id = ?
  80. GROUP BY
  81. node.id
  82. ORDER BY
  83. node.lft ASC
  84. ;`,
  85. this.category.Id(),
  86. ); err == nil {
  87. defer rows.Close()
  88. for rows.Next() {
  89. var cat_id string
  90. if err := rows.Scan(&cat_id); err == nil {
  91. cat_ids = append(cat_ids, cat_id)
  92. }
  93. }
  94. }
  95. sql_nums = `
  96. SELECT
  97. COUNT(*)
  98. FROM
  99. (
  100. SELECT
  101. COUNT(*)
  102. FROM
  103. blog_posts
  104. LEFT JOIN blog_cat_post_rel ON blog_cat_post_rel.post_id = blog_posts.id
  105. WHERE
  106. blog_posts.active = 1 AND
  107. blog_cat_post_rel.category_id IN (` + strings.Join(cat_ids, ", ") + `)
  108. GROUP BY
  109. blog_posts.id
  110. ) AS tbl
  111. ;
  112. `
  113. sql_rows = `
  114. SELECT
  115. blog_posts.id,
  116. blog_posts.user,
  117. blog_posts.name,
  118. blog_posts.alias,
  119. blog_posts.briefly,
  120. blog_posts.content,
  121. UNIX_TIMESTAMP(blog_posts.datetime) AS datetime,
  122. blog_posts.active,
  123. users.id,
  124. users.first_name,
  125. users.last_name,
  126. users.email,
  127. users.admin,
  128. users.active
  129. FROM
  130. blog_posts
  131. LEFT JOIN blog_cat_post_rel ON blog_cat_post_rel.post_id = blog_posts.id
  132. LEFT JOIN users ON users.id = blog_posts.user
  133. WHERE
  134. blog_posts.active = 1 AND
  135. blog_cat_post_rel.category_id IN (` + strings.Join(cat_ids, ", ") + `)
  136. GROUP BY
  137. blog_posts.id
  138. ORDER BY
  139. blog_posts.id DESC
  140. LIMIT ?, ?;
  141. `
  142. }
  143. if err := this.wrap.DB.QueryRow(sql_nums).Scan(&this.postsCount); err == nil {
  144. if this.category == nil {
  145. this.postsPerPage = (*this.wrap.Config).Blog.Pagination.Index
  146. } else {
  147. this.postsPerPage = (*this.wrap.Config).Blog.Pagination.Category
  148. }
  149. this.postsMaxPage = int(math.Ceil(float64(this.postsCount) / float64(this.postsPerPage)))
  150. this.postsCurrPage = this.wrap.GetCurrentPage(this.postsMaxPage)
  151. offset := this.postsCurrPage*this.postsPerPage - this.postsPerPage
  152. if rows, err := this.wrap.DB.Query(sql_rows, offset, this.postsPerPage); err == nil {
  153. defer rows.Close()
  154. for rows.Next() {
  155. rp := utils.MySql_blog_post{}
  156. ru := utils.MySql_user{}
  157. if err := rows.Scan(
  158. &rp.A_id,
  159. &rp.A_user,
  160. &rp.A_name,
  161. &rp.A_alias,
  162. &rp.A_briefly,
  163. &rp.A_content,
  164. &rp.A_datetime,
  165. &rp.A_active,
  166. &ru.A_id,
  167. &ru.A_first_name,
  168. &ru.A_last_name,
  169. &ru.A_email,
  170. &ru.A_admin,
  171. &ru.A_active,
  172. ); err == nil {
  173. this.posts = append(this.posts, &BlogPost{
  174. wrap: this.wrap,
  175. object: &rp,
  176. user: &User{wrap: this.wrap, object: &ru},
  177. })
  178. }
  179. }
  180. }
  181. }
  182. // Build pagination
  183. if true {
  184. for i := 1; i < this.postsCurrPage; i++ {
  185. if this.postsCurrPage >= 5 && i > 1 && i < this.postsCurrPage-1 {
  186. continue
  187. }
  188. if this.postsCurrPage >= 5 && i > 1 && i < this.postsCurrPage {
  189. this.pagination = append(this.pagination, &BlogPagination{
  190. Dots: true,
  191. })
  192. }
  193. link := this.wrap.R.URL.Path
  194. if i > 1 {
  195. link = link + "?p=" + utils.IntToStr(i)
  196. }
  197. this.pagination = append(this.pagination, &BlogPagination{
  198. Num: utils.IntToStr(i),
  199. Link: link,
  200. Current: false,
  201. })
  202. }
  203. // Current page
  204. link := this.wrap.R.URL.Path
  205. if this.postsCurrPage > 1 {
  206. link = link + "?p=" + utils.IntToStr(this.postsCurrPage)
  207. }
  208. this.pagination = append(this.pagination, &BlogPagination{
  209. Num: utils.IntToStr(this.postsCurrPage),
  210. Link: link,
  211. Current: true,
  212. })
  213. for i := this.postsCurrPage + 1; i <= this.postsMaxPage; i++ {
  214. if this.postsCurrPage < this.postsMaxPage-3 && i == this.postsCurrPage+3 {
  215. this.pagination = append(this.pagination, &BlogPagination{
  216. Dots: true,
  217. })
  218. }
  219. if this.postsCurrPage < this.postsMaxPage-3 && i > this.postsCurrPage+1 && i <= this.postsMaxPage-1 {
  220. continue
  221. }
  222. link := this.wrap.R.URL.Path
  223. if i > 1 {
  224. link = link + "?p=" + utils.IntToStr(i)
  225. }
  226. this.pagination = append(this.pagination, &BlogPagination{
  227. Num: utils.IntToStr(i),
  228. Link: link,
  229. Current: false,
  230. })
  231. }
  232. } else {
  233. for i := 1; i <= this.postsMaxPage; i++ {
  234. link := this.wrap.R.URL.Path
  235. if i > 1 {
  236. link = link + "?p=" + utils.IntToStr(i)
  237. }
  238. this.pagination = append(this.pagination, &BlogPagination{
  239. Num: utils.IntToStr(i),
  240. Link: link,
  241. Current: i == this.postsCurrPage,
  242. })
  243. }
  244. }
  245. // Pagination prev/next
  246. if this.postsMaxPage > 1 {
  247. link := this.wrap.R.URL.Path
  248. if this.postsCurrPage-1 > 1 {
  249. link = this.wrap.R.URL.Path + "?p=" + utils.IntToStr(this.postsCurrPage-1)
  250. }
  251. this.paginationPrev = &BlogPagination{
  252. Num: utils.IntToStr(this.postsCurrPage - 1),
  253. Link: link,
  254. Current: this.postsCurrPage <= 1,
  255. }
  256. if this.postsCurrPage >= 1 && this.postsCurrPage < this.postsMaxPage {
  257. link = this.wrap.R.URL.Path + "?p=" + utils.IntToStr(this.postsCurrPage+1)
  258. } else {
  259. link = this.wrap.R.URL.Path + "?p=" + utils.IntToStr(this.postsMaxPage)
  260. }
  261. this.paginationNext = &BlogPagination{
  262. Num: utils.IntToStr(this.postsCurrPage + 1),
  263. Link: link,
  264. Current: this.postsCurrPage >= this.postsMaxPage,
  265. }
  266. }
  267. return this
  268. }
  269. func (this *Blog) preload_cats() {
  270. if this.bufferCats == nil {
  271. this.bufferCats = map[int]*utils.MySql_blog_category{}
  272. if rows, err := this.wrap.DB.Query(`
  273. SELECT
  274. main.id,
  275. main.user,
  276. main.name,
  277. main.alias,
  278. main.lft,
  279. main.rgt,
  280. main.depth,
  281. parent.id AS parent_id
  282. FROM
  283. (
  284. SELECT
  285. node.id,
  286. node.user,
  287. node.name,
  288. node.alias,
  289. node.lft,
  290. node.rgt,
  291. (COUNT(parent.id) - 1) AS depth
  292. FROM
  293. blog_cats AS node,
  294. blog_cats AS parent
  295. WHERE
  296. node.lft BETWEEN parent.lft AND parent.rgt
  297. GROUP BY
  298. node.id
  299. ORDER BY
  300. node.lft ASC
  301. ) AS main
  302. LEFT JOIN (
  303. SELECT
  304. node.id,
  305. node.user,
  306. node.name,
  307. node.alias,
  308. node.lft,
  309. node.rgt,
  310. (COUNT(parent.id) - 0) AS depth
  311. FROM
  312. blog_cats AS node,
  313. blog_cats AS parent
  314. WHERE
  315. node.lft BETWEEN parent.lft AND parent.rgt
  316. GROUP BY
  317. node.id
  318. ORDER BY
  319. node.lft ASC
  320. ) AS parent ON
  321. parent.depth = main.depth AND
  322. main.lft > parent.lft AND
  323. main.rgt < parent.rgt
  324. WHERE
  325. main.id > 1
  326. ORDER BY
  327. main.lft ASC
  328. ;
  329. `); err == nil {
  330. defer rows.Close()
  331. for rows.Next() {
  332. row := utils.MySql_blog_category{}
  333. if err := rows.Scan(
  334. &row.A_id,
  335. &row.A_user,
  336. &row.A_name,
  337. &row.A_alias,
  338. &row.A_lft,
  339. &row.A_rgt,
  340. &row.A_depth,
  341. &row.A_parent,
  342. ); err == nil {
  343. this.bufferCats[row.A_id] = &row
  344. if _, ok := this.bufferCats[row.A_parent]; ok {
  345. this.bufferCats[row.A_parent].A_childs = true
  346. }
  347. }
  348. }
  349. }
  350. }
  351. }
  352. func (this *Blog) Category() *BlogCategory {
  353. if this == nil {
  354. return nil
  355. }
  356. return this.category
  357. }
  358. func (this *Blog) Post() *BlogPost {
  359. if this == nil {
  360. return nil
  361. }
  362. return this.post
  363. }
  364. func (this *Blog) HavePosts() bool {
  365. if this == nil {
  366. return false
  367. }
  368. if len(this.posts) <= 0 {
  369. return false
  370. }
  371. return true
  372. }
  373. func (this *Blog) Posts() []*BlogPost {
  374. if this == nil {
  375. return []*BlogPost{}
  376. }
  377. return this.posts
  378. }
  379. func (this *Blog) PostsCount() int {
  380. if this == nil {
  381. return 0
  382. }
  383. return this.postsCount
  384. }
  385. func (this *Blog) PostsPerPage() int {
  386. if this == nil {
  387. return 0
  388. }
  389. return this.postsPerPage
  390. }
  391. func (this *Blog) PostsMaxPage() int {
  392. if this == nil {
  393. return 0
  394. }
  395. return this.postsMaxPage
  396. }
  397. func (this *Blog) PostsCurrPage() int {
  398. if this == nil {
  399. return 0
  400. }
  401. return this.postsCurrPage
  402. }
  403. func (this *Blog) Pagination() []*BlogPagination {
  404. if this == nil {
  405. return []*BlogPagination{}
  406. }
  407. return this.pagination
  408. }
  409. func (this *Blog) PaginationPrev() *BlogPagination {
  410. if this == nil {
  411. return nil
  412. }
  413. return this.paginationPrev
  414. }
  415. func (this *Blog) PaginationNext() *BlogPagination {
  416. if this == nil {
  417. return nil
  418. }
  419. return this.paginationNext
  420. }
  421. func (this *Blog) Categories(parent, depth int) []*BlogCategory {
  422. this.preload_cats()
  423. depth_tmp := 0
  424. result := []*BlogCategory{}
  425. for _, cat := range this.bufferCats {
  426. if parent <= 1 {
  427. if depth <= 0 {
  428. result = append(result, (&BlogCategory{wrap: this.wrap, object: cat}).load(&this.bufferCats))
  429. } else {
  430. if cat.A_depth <= depth {
  431. result = append(result, (&BlogCategory{wrap: this.wrap, object: cat}).load(&this.bufferCats))
  432. }
  433. }
  434. } else {
  435. if cat.A_parent == parent {
  436. if depth_tmp == 0 {
  437. depth_tmp = cat.A_depth
  438. }
  439. if depth <= 0 {
  440. result = append(result, (&BlogCategory{wrap: this.wrap, object: cat}).load(&this.bufferCats))
  441. } else {
  442. if (cat.A_depth - depth_tmp + 1) <= depth {
  443. result = append(result, (&BlogCategory{wrap: this.wrap, object: cat}).load(&this.bufferCats))
  444. }
  445. }
  446. }
  447. }
  448. }
  449. sort.Slice(result, func(i, j int) bool { return result[i].Left() < result[j].Left() })
  450. return result
  451. }