blog.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628
  1. package fetdata
  2. import (
  3. "math"
  4. "sort"
  5. "strings"
  6. "golang-fave/engine/utils"
  7. "golang-fave/engine/wrapper"
  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. fave_blog_posts
  38. WHERE
  39. active = 1
  40. ;
  41. `
  42. sql_rows := `
  43. SELECT
  44. fave_blog_posts.id,
  45. fave_blog_posts.user,
  46. fave_blog_posts.name,
  47. fave_blog_posts.alias,
  48. fave_blog_posts.category,
  49. fave_blog_posts.briefly,
  50. fave_blog_posts.content,
  51. UNIX_TIMESTAMP(fave_blog_posts.datetime) as datetime,
  52. fave_blog_posts.active,
  53. fave_users.id,
  54. fave_users.first_name,
  55. fave_users.last_name,
  56. fave_users.email,
  57. fave_users.admin,
  58. fave_users.active,
  59. cats.id,
  60. cats.user,
  61. cats.name,
  62. cats.alias,
  63. cats.lft,
  64. cats.rgt,
  65. cats.depth,
  66. cats.parent_id
  67. FROM
  68. fave_blog_posts
  69. LEFT JOIN fave_users ON fave_users.id = fave_blog_posts.user
  70. LEFT JOIN (
  71. SELECT
  72. main.id,
  73. main.user,
  74. main.name,
  75. main.alias,
  76. main.lft,
  77. main.rgt,
  78. main.depth,
  79. parent.id AS parent_id
  80. FROM
  81. (
  82. SELECT
  83. node.id,
  84. node.user,
  85. node.name,
  86. node.alias,
  87. node.lft,
  88. node.rgt,
  89. (COUNT(parent.id) - 1) AS depth
  90. FROM
  91. fave_blog_cats AS node,
  92. fave_blog_cats AS parent
  93. WHERE
  94. node.lft BETWEEN parent.lft AND parent.rgt
  95. GROUP BY
  96. node.id
  97. ORDER BY
  98. node.lft ASC
  99. ) AS main
  100. LEFT JOIN (
  101. SELECT
  102. node.id,
  103. node.user,
  104. node.name,
  105. node.alias,
  106. node.lft,
  107. node.rgt,
  108. (COUNT(parent.id) - 0) AS depth
  109. FROM
  110. fave_blog_cats AS node,
  111. fave_blog_cats AS parent
  112. WHERE
  113. node.lft BETWEEN parent.lft AND parent.rgt
  114. GROUP BY
  115. node.id
  116. ORDER BY
  117. node.lft ASC
  118. ) AS parent ON
  119. parent.depth = main.depth AND
  120. main.lft > parent.lft AND
  121. main.rgt < parent.rgt
  122. WHERE
  123. main.id > 1
  124. ORDER BY
  125. main.lft ASC
  126. ) AS cats ON cats.id = fave_blog_posts.category
  127. WHERE
  128. fave_blog_posts.active = 1
  129. ORDER BY
  130. fave_blog_posts.id DESC
  131. LIMIT ?, ?;
  132. `
  133. // Category selected
  134. if this.category != nil {
  135. var cat_ids []string
  136. if rows, err := this.wrap.DB.Query(
  137. this.wrap.R.Context(),
  138. `SELECT
  139. node.id
  140. FROM
  141. fave_blog_cats AS node,
  142. fave_blog_cats AS parent
  143. WHERE
  144. node.lft BETWEEN parent.lft AND parent.rgt AND
  145. node.id > 1 AND
  146. parent.id = ?
  147. GROUP BY
  148. node.id
  149. ORDER BY
  150. node.lft ASC
  151. ;`,
  152. this.category.Id(),
  153. ); err == nil {
  154. defer rows.Close()
  155. for rows.Next() {
  156. var cat_id string
  157. if err := rows.Scan(&cat_id); *this.wrap.LogCpError(&err) == nil {
  158. cat_ids = append(cat_ids, cat_id)
  159. }
  160. }
  161. }
  162. sql_nums = `
  163. SELECT
  164. COUNT(*)
  165. FROM
  166. (
  167. SELECT
  168. COUNT(*)
  169. FROM
  170. fave_blog_posts
  171. LEFT JOIN fave_blog_cat_post_rel ON fave_blog_cat_post_rel.post_id = fave_blog_posts.id
  172. WHERE
  173. fave_blog_posts.active = 1 AND
  174. fave_blog_cat_post_rel.category_id IN (` + strings.Join(cat_ids, ", ") + `)
  175. GROUP BY
  176. fave_blog_posts.id
  177. ) AS tbl
  178. ;
  179. `
  180. sql_rows = `
  181. SELECT
  182. fave_blog_posts.id,
  183. fave_blog_posts.user,
  184. fave_blog_posts.name,
  185. fave_blog_posts.alias,
  186. fave_blog_posts.category,
  187. fave_blog_posts.briefly,
  188. fave_blog_posts.content,
  189. UNIX_TIMESTAMP(fave_blog_posts.datetime) AS datetime,
  190. fave_blog_posts.active,
  191. fave_users.id,
  192. fave_users.first_name,
  193. fave_users.last_name,
  194. fave_users.email,
  195. fave_users.admin,
  196. fave_users.active,
  197. cats.id,
  198. cats.user,
  199. cats.name,
  200. cats.alias,
  201. cats.lft,
  202. cats.rgt,
  203. cats.depth,
  204. cats.parent_id
  205. FROM
  206. fave_blog_posts
  207. LEFT JOIN fave_blog_cat_post_rel ON fave_blog_cat_post_rel.post_id = fave_blog_posts.id
  208. LEFT JOIN fave_users ON fave_users.id = fave_blog_posts.user
  209. LEFT JOIN (
  210. SELECT
  211. main.id,
  212. main.user,
  213. main.name,
  214. main.alias,
  215. main.lft,
  216. main.rgt,
  217. main.depth,
  218. parent.id AS parent_id
  219. FROM
  220. (
  221. SELECT
  222. node.id,
  223. node.user,
  224. node.name,
  225. node.alias,
  226. node.lft,
  227. node.rgt,
  228. (COUNT(parent.id) - 1) AS depth
  229. FROM
  230. fave_blog_cats AS node,
  231. fave_blog_cats AS parent
  232. WHERE
  233. node.lft BETWEEN parent.lft AND parent.rgt
  234. GROUP BY
  235. node.id
  236. ORDER BY
  237. node.lft ASC
  238. ) AS main
  239. LEFT JOIN (
  240. SELECT
  241. node.id,
  242. node.user,
  243. node.name,
  244. node.alias,
  245. node.lft,
  246. node.rgt,
  247. (COUNT(parent.id) - 0) AS depth
  248. FROM
  249. fave_blog_cats AS node,
  250. fave_blog_cats AS parent
  251. WHERE
  252. node.lft BETWEEN parent.lft AND parent.rgt
  253. GROUP BY
  254. node.id
  255. ORDER BY
  256. node.lft ASC
  257. ) AS parent ON
  258. parent.depth = main.depth AND
  259. main.lft > parent.lft AND
  260. main.rgt < parent.rgt
  261. WHERE
  262. main.id > 1
  263. ORDER BY
  264. main.lft ASC
  265. ) AS cats ON cats.id = fave_blog_posts.category
  266. WHERE
  267. fave_blog_posts.active = 1 AND
  268. fave_blog_cat_post_rel.category_id IN (` + strings.Join(cat_ids, ", ") + `)
  269. GROUP BY
  270. fave_blog_posts.id,
  271. cats.parent_id
  272. ORDER BY
  273. fave_blog_posts.id DESC
  274. LIMIT ?, ?;
  275. `
  276. }
  277. if err := this.wrap.DB.QueryRow(this.wrap.R.Context(), sql_nums).Scan(&this.postsCount); *this.wrap.LogCpError(&err) == nil {
  278. if this.category == nil {
  279. this.postsPerPage = (*this.wrap.Config).Blog.Pagination.Index
  280. } else {
  281. this.postsPerPage = (*this.wrap.Config).Blog.Pagination.Category
  282. }
  283. this.postsMaxPage = int(math.Ceil(float64(this.postsCount) / float64(this.postsPerPage)))
  284. this.postsCurrPage = this.wrap.GetCurrentPage(this.postsMaxPage)
  285. offset := this.postsCurrPage*this.postsPerPage - this.postsPerPage
  286. if rows, err := this.wrap.DB.Query(this.wrap.R.Context(), sql_rows, offset, this.postsPerPage); err == nil {
  287. defer rows.Close()
  288. for rows.Next() {
  289. rp := utils.MySql_blog_post{}
  290. ru := utils.MySql_user{}
  291. ro := utils.MySql_blog_category{}
  292. if err := rows.Scan(
  293. &rp.A_id,
  294. &rp.A_user,
  295. &rp.A_name,
  296. &rp.A_alias,
  297. &rp.A_category,
  298. &rp.A_briefly,
  299. &rp.A_content,
  300. &rp.A_datetime,
  301. &rp.A_active,
  302. &ru.A_id,
  303. &ru.A_first_name,
  304. &ru.A_last_name,
  305. &ru.A_email,
  306. &ru.A_admin,
  307. &ru.A_active,
  308. &ro.A_id,
  309. &ro.A_user,
  310. &ro.A_name,
  311. &ro.A_alias,
  312. &ro.A_lft,
  313. &ro.A_rgt,
  314. &ro.A_depth,
  315. &ro.A_parent,
  316. ); *this.wrap.LogCpError(&err) == nil {
  317. this.posts = append(this.posts, &BlogPost{
  318. wrap: this.wrap,
  319. object: &rp,
  320. user: &User{wrap: this.wrap, object: &ru},
  321. category: &BlogCategory{wrap: this.wrap, object: &ro},
  322. })
  323. }
  324. }
  325. }
  326. }
  327. // Build pagination
  328. if true {
  329. for i := 1; i < this.postsCurrPage; i++ {
  330. if this.postsCurrPage >= 5 && i > 1 && i < this.postsCurrPage-1 {
  331. continue
  332. }
  333. if this.postsCurrPage >= 5 && i > 1 && i < this.postsCurrPage {
  334. this.pagination = append(this.pagination, &BlogPagination{
  335. Dots: true,
  336. })
  337. }
  338. link := this.wrap.R.URL.Path
  339. if i > 1 {
  340. link = link + "?p=" + utils.IntToStr(i)
  341. }
  342. this.pagination = append(this.pagination, &BlogPagination{
  343. Num: utils.IntToStr(i),
  344. Link: link,
  345. Current: false,
  346. })
  347. }
  348. // Current page
  349. link := this.wrap.R.URL.Path
  350. if this.postsCurrPage > 1 {
  351. link = link + "?p=" + utils.IntToStr(this.postsCurrPage)
  352. }
  353. this.pagination = append(this.pagination, &BlogPagination{
  354. Num: utils.IntToStr(this.postsCurrPage),
  355. Link: link,
  356. Current: true,
  357. })
  358. for i := this.postsCurrPage + 1; i <= this.postsMaxPage; i++ {
  359. if this.postsCurrPage < this.postsMaxPage-3 && i == this.postsCurrPage+3 {
  360. this.pagination = append(this.pagination, &BlogPagination{
  361. Dots: true,
  362. })
  363. }
  364. if this.postsCurrPage < this.postsMaxPage-3 && i > this.postsCurrPage+1 && i <= this.postsMaxPage-1 {
  365. continue
  366. }
  367. link := this.wrap.R.URL.Path
  368. if i > 1 {
  369. link = link + "?p=" + utils.IntToStr(i)
  370. }
  371. this.pagination = append(this.pagination, &BlogPagination{
  372. Num: utils.IntToStr(i),
  373. Link: link,
  374. Current: false,
  375. })
  376. }
  377. } else {
  378. for i := 1; i <= this.postsMaxPage; i++ {
  379. link := this.wrap.R.URL.Path
  380. if i > 1 {
  381. link = link + "?p=" + utils.IntToStr(i)
  382. }
  383. this.pagination = append(this.pagination, &BlogPagination{
  384. Num: utils.IntToStr(i),
  385. Link: link,
  386. Current: i == this.postsCurrPage,
  387. })
  388. }
  389. }
  390. // Pagination prev/next
  391. if this.postsMaxPage > 1 {
  392. link := this.wrap.R.URL.Path
  393. if this.postsCurrPage-1 > 1 {
  394. link = this.wrap.R.URL.Path + "?p=" + utils.IntToStr(this.postsCurrPage-1)
  395. }
  396. this.paginationPrev = &BlogPagination{
  397. Num: utils.IntToStr(this.postsCurrPage - 1),
  398. Link: link,
  399. Current: this.postsCurrPage <= 1,
  400. }
  401. if this.postsCurrPage >= 1 && this.postsCurrPage < this.postsMaxPage {
  402. link = this.wrap.R.URL.Path + "?p=" + utils.IntToStr(this.postsCurrPage+1)
  403. } else {
  404. link = this.wrap.R.URL.Path + "?p=" + utils.IntToStr(this.postsMaxPage)
  405. }
  406. this.paginationNext = &BlogPagination{
  407. Num: utils.IntToStr(this.postsCurrPage + 1),
  408. Link: link,
  409. Current: this.postsCurrPage >= this.postsMaxPage,
  410. }
  411. }
  412. return this
  413. }
  414. func (this *Blog) preload_cats() {
  415. if this.bufferCats == nil {
  416. this.bufferCats = map[int]*utils.MySql_blog_category{}
  417. if rows, err := this.wrap.DB.Query(
  418. this.wrap.R.Context(),
  419. `SELECT
  420. main.id,
  421. main.user,
  422. main.name,
  423. main.alias,
  424. main.lft,
  425. main.rgt,
  426. main.depth,
  427. parent.id AS parent_id
  428. FROM
  429. (
  430. SELECT
  431. node.id,
  432. node.user,
  433. node.name,
  434. node.alias,
  435. node.lft,
  436. node.rgt,
  437. (COUNT(parent.id) - 1) AS depth
  438. FROM
  439. fave_blog_cats AS node,
  440. fave_blog_cats AS parent
  441. WHERE
  442. node.lft BETWEEN parent.lft AND parent.rgt
  443. GROUP BY
  444. node.id
  445. ORDER BY
  446. node.lft ASC
  447. ) AS main
  448. LEFT JOIN (
  449. SELECT
  450. node.id,
  451. node.user,
  452. node.name,
  453. node.alias,
  454. node.lft,
  455. node.rgt,
  456. (COUNT(parent.id) - 0) AS depth
  457. FROM
  458. fave_blog_cats AS node,
  459. fave_blog_cats AS parent
  460. WHERE
  461. node.lft BETWEEN parent.lft AND parent.rgt
  462. GROUP BY
  463. node.id
  464. ORDER BY
  465. node.lft ASC
  466. ) AS parent ON
  467. parent.depth = main.depth AND
  468. main.lft > parent.lft AND
  469. main.rgt < parent.rgt
  470. WHERE
  471. main.id > 1
  472. ORDER BY
  473. main.lft ASC
  474. ;
  475. `); err == nil {
  476. defer rows.Close()
  477. for rows.Next() {
  478. row := utils.MySql_blog_category{}
  479. if err := rows.Scan(
  480. &row.A_id,
  481. &row.A_user,
  482. &row.A_name,
  483. &row.A_alias,
  484. &row.A_lft,
  485. &row.A_rgt,
  486. &row.A_depth,
  487. &row.A_parent,
  488. ); *this.wrap.LogCpError(&err) == nil {
  489. this.bufferCats[row.A_id] = &row
  490. if _, ok := this.bufferCats[row.A_parent]; ok {
  491. this.bufferCats[row.A_parent].A_childs = true
  492. }
  493. }
  494. }
  495. }
  496. }
  497. }
  498. func (this *Blog) Category() *BlogCategory {
  499. if this == nil {
  500. return nil
  501. }
  502. return this.category
  503. }
  504. func (this *Blog) Post() *BlogPost {
  505. if this == nil {
  506. return nil
  507. }
  508. return this.post
  509. }
  510. func (this *Blog) HavePosts() bool {
  511. if this == nil {
  512. return false
  513. }
  514. if len(this.posts) <= 0 {
  515. return false
  516. }
  517. return true
  518. }
  519. func (this *Blog) Posts() []*BlogPost {
  520. if this == nil {
  521. return []*BlogPost{}
  522. }
  523. return this.posts
  524. }
  525. func (this *Blog) PostsCount() int {
  526. if this == nil {
  527. return 0
  528. }
  529. return this.postsCount
  530. }
  531. func (this *Blog) PostsPerPage() int {
  532. if this == nil {
  533. return 0
  534. }
  535. return this.postsPerPage
  536. }
  537. func (this *Blog) PostsMaxPage() int {
  538. if this == nil {
  539. return 0
  540. }
  541. return this.postsMaxPage
  542. }
  543. func (this *Blog) PostsCurrPage() int {
  544. if this == nil {
  545. return 0
  546. }
  547. return this.postsCurrPage
  548. }
  549. func (this *Blog) Pagination() []*BlogPagination {
  550. if this == nil {
  551. return []*BlogPagination{}
  552. }
  553. return this.pagination
  554. }
  555. func (this *Blog) PaginationPrev() *BlogPagination {
  556. if this == nil {
  557. return nil
  558. }
  559. return this.paginationPrev
  560. }
  561. func (this *Blog) PaginationNext() *BlogPagination {
  562. if this == nil {
  563. return nil
  564. }
  565. return this.paginationNext
  566. }
  567. func (this *Blog) Categories(parent, depth int) []*BlogCategory {
  568. this.preload_cats()
  569. depth_tmp := 0
  570. result := []*BlogCategory{}
  571. for _, cat := range this.bufferCats {
  572. if parent <= 1 {
  573. if depth <= 0 {
  574. result = append(result, (&BlogCategory{wrap: this.wrap, object: cat}).load(&this.bufferCats))
  575. } else {
  576. if cat.A_depth <= depth {
  577. result = append(result, (&BlogCategory{wrap: this.wrap, object: cat}).load(&this.bufferCats))
  578. }
  579. }
  580. } else {
  581. if cat.A_parent == parent {
  582. if depth_tmp == 0 {
  583. depth_tmp = cat.A_depth
  584. }
  585. if depth <= 0 {
  586. result = append(result, (&BlogCategory{wrap: this.wrap, object: cat}).load(&this.bufferCats))
  587. } else {
  588. if (cat.A_depth - depth_tmp + 1) <= depth {
  589. result = append(result, (&BlogCategory{wrap: this.wrap, object: cat}).load(&this.bufferCats))
  590. }
  591. }
  592. }
  593. }
  594. }
  595. sort.Slice(result, func(i, j int) bool { return result[i].Left() < result[j].Left() })
  596. return result
  597. }