blog.go 14 KB

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