blog.go 13 KB

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