module_blog_categories.go 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. package modules
  2. import (
  3. "html"
  4. "strings"
  5. "golang-fave/engine/wrapper"
  6. "golang-fave/utils"
  7. )
  8. func (this *Modules) blog_GetCategorySelectOptions(wrap *wrapper.Wrapper, id int, parentId int, selids []int) string {
  9. result := ``
  10. rows, err := wrap.DB.Query(
  11. `SELECT
  12. node.id,
  13. node.user,
  14. node.name,
  15. node.alias,
  16. (COUNT(parent.id) - 1) AS depth
  17. FROM
  18. blog_cats AS node,
  19. blog_cats AS parent
  20. WHERE
  21. node.lft BETWEEN parent.lft AND parent.rgt AND
  22. node.id > 1
  23. GROUP BY
  24. node.id
  25. ORDER BY
  26. node.lft ASC
  27. ;`,
  28. )
  29. if err == nil {
  30. defer rows.Close()
  31. values := make([]string, 5)
  32. scan := make([]interface{}, len(values))
  33. for i := range values {
  34. scan[i] = &values[i]
  35. }
  36. idStr := utils.IntToStr(id)
  37. parentIdStr := utils.IntToStr(parentId)
  38. for rows.Next() {
  39. err = rows.Scan(scan...)
  40. if err == nil {
  41. disabled := ""
  42. if string(values[0]) == idStr {
  43. disabled = " disabled"
  44. }
  45. selected := ""
  46. if string(values[0]) == parentIdStr {
  47. selected = " selected"
  48. }
  49. if len(selids) > 0 && utils.InArrayInt(selids, utils.StrToInt(string(values[0]))) {
  50. selected = " selected"
  51. }
  52. depth := utils.StrToInt(string(values[4])) - 1
  53. if depth < 0 {
  54. depth = 0
  55. }
  56. sub := strings.Repeat("&mdash; ", depth)
  57. result += `<option value="` + html.EscapeString(string(values[0])) + `"` + disabled + selected + `>` + sub + html.EscapeString(string(values[2])) + `</option>`
  58. }
  59. }
  60. }
  61. return result
  62. }
  63. func (this *Modules) blog_GetCategoryParentId(wrap *wrapper.Wrapper, id int) int {
  64. var parentId int
  65. err := wrap.DB.QueryRow(`
  66. SELECT
  67. parent.id
  68. FROM
  69. blog_cats AS node,
  70. blog_cats AS parent
  71. WHERE
  72. node.lft BETWEEN parent.lft AND parent.rgt AND
  73. node.id = ? AND
  74. parent.id <> ?
  75. ORDER BY
  76. parent.lft DESC
  77. LIMIT 1;`,
  78. id,
  79. id,
  80. ).Scan(
  81. &parentId,
  82. )
  83. if err != nil {
  84. return 0
  85. }
  86. return parentId
  87. }
  88. func (this *Modules) blog_ActionCategoryAdd(wrap *wrapper.Wrapper, pf_id, pf_name, pf_alias, pf_parent string) error {
  89. // Start transaction with table lock
  90. _, err := wrap.DB.Exec("LOCK TABLE blog_cats WRITE;")
  91. if err != nil {
  92. return err
  93. }
  94. tx, err := wrap.DB.Begin()
  95. if err != nil {
  96. return err
  97. }
  98. // Update and insert new category
  99. if _, err = tx.Exec("SELECT @mr := rgt FROM blog_cats WHERE id = ?;", pf_parent); err != nil {
  100. tx.Rollback()
  101. return err
  102. }
  103. if _, err = tx.Exec("UPDATE blog_cats SET rgt = rgt + 2 WHERE rgt > @mr;"); err != nil {
  104. tx.Rollback()
  105. return err
  106. }
  107. if _, err = tx.Exec("UPDATE blog_cats SET lft = lft + 2 WHERE lft > @mr;"); err != nil {
  108. tx.Rollback()
  109. return err
  110. }
  111. if _, err = tx.Exec("UPDATE blog_cats SET rgt = rgt + 2 WHERE id = ?;", pf_parent); err != nil {
  112. tx.Rollback()
  113. return err
  114. }
  115. if _, err = tx.Exec("INSERT INTO blog_cats (id, user, name, alias, lft, rgt) VALUES (NULL, ?, ?, ?, @mr, @mr + 1);", wrap.User.A_id, pf_name, pf_alias); err != nil {
  116. tx.Rollback()
  117. return err
  118. }
  119. // Commit all changes and unlock table
  120. err = tx.Commit()
  121. if err != nil {
  122. return err
  123. }
  124. _, err = wrap.DB.Exec("UNLOCK TABLES;")
  125. if err != nil {
  126. return err
  127. }
  128. return nil
  129. }
  130. func (this *Modules) blog_ActionCategoryUpdate(wrap *wrapper.Wrapper, pf_id, pf_name, pf_alias, pf_parent string) error {
  131. parentId := this.blog_GetCategoryParentId(wrap, utils.StrToInt(pf_id))
  132. if utils.StrToInt(pf_parent) == parentId {
  133. // If parent not changed, just update category data
  134. _, err := wrap.DB.Exec(`
  135. UPDATE blog_cats SET
  136. name = ?,
  137. alias = ?
  138. WHERE
  139. id > 1 AND
  140. id = ?
  141. ;`,
  142. pf_name,
  143. pf_alias,
  144. pf_id,
  145. )
  146. return err
  147. } else {
  148. // Parent is changed, move category to new parent
  149. // Start transaction with table lock
  150. _, err := wrap.DB.Exec("LOCK TABLE blog_cats WRITE;")
  151. if err != nil {
  152. return err
  153. }
  154. tx, err := wrap.DB.Begin()
  155. if err != nil {
  156. return err
  157. }
  158. // Shift
  159. if _, err = tx.Exec("SELECT @ml := lft, @mr := rgt FROM blog_cats WHERE id = ?;", pf_id); err != nil {
  160. tx.Rollback()
  161. return err
  162. }
  163. if _, err = tx.Exec("UPDATE blog_cats SET lft = 0, rgt = 0 WHERE id = ?;", pf_id); err != nil {
  164. tx.Rollback()
  165. return err
  166. }
  167. if _, err = tx.Exec("UPDATE blog_cats SET lft = lft - 1, rgt = rgt - 1 WHERE lft > @ml AND rgt < @mr;"); err != nil {
  168. tx.Rollback()
  169. return err
  170. }
  171. if _, err = tx.Exec("UPDATE blog_cats SET lft = lft - 2 WHERE lft > @mr;"); err != nil {
  172. tx.Rollback()
  173. return err
  174. }
  175. if _, err = tx.Exec("UPDATE blog_cats SET rgt = rgt - 2 WHERE rgt > @mr;"); err != nil {
  176. tx.Rollback()
  177. return err
  178. }
  179. // Update
  180. if _, err = tx.Exec("SELECT @mr := rgt FROM blog_cats WHERE id = ?;", pf_parent); err != nil {
  181. tx.Rollback()
  182. return err
  183. }
  184. if _, err = tx.Exec("UPDATE blog_cats SET rgt = rgt + 2 WHERE rgt > @mr;"); err != nil {
  185. tx.Rollback()
  186. return err
  187. }
  188. if _, err = tx.Exec("UPDATE blog_cats SET lft = lft + 2 WHERE lft > @mr;"); err != nil {
  189. tx.Rollback()
  190. return err
  191. }
  192. if _, err = tx.Exec("UPDATE blog_cats SET rgt = rgt + 2 WHERE id = ?;", pf_parent); err != nil {
  193. tx.Rollback()
  194. return err
  195. }
  196. if _, err = tx.Exec("UPDATE blog_cats SET name = ?, alias = ?, lft = @mr, rgt = @mr + 1 WHERE id = ?;", pf_name, pf_alias, pf_id); err != nil {
  197. tx.Rollback()
  198. return err
  199. }
  200. // Commit all changes and unlock table
  201. err = tx.Commit()
  202. if err != nil {
  203. return err
  204. }
  205. _, err = wrap.DB.Exec("UNLOCK TABLES;")
  206. if err != nil {
  207. return err
  208. }
  209. }
  210. return nil
  211. }
  212. func (this *Modules) RegisterAction_BlogCategoriesModify() *Action {
  213. return this.newAction(AInfo{
  214. WantDB: true,
  215. Mount: "blog-categories-modify",
  216. WantAdmin: true,
  217. }, func(wrap *wrapper.Wrapper) {
  218. pf_id := wrap.R.FormValue("id")
  219. pf_name := wrap.R.FormValue("name")
  220. pf_alias := wrap.R.FormValue("alias")
  221. pf_parent := wrap.R.FormValue("parent")
  222. if !utils.IsNumeric(pf_id) || !utils.IsNumeric(pf_parent) {
  223. wrap.MsgError(`Inner system error`)
  224. return
  225. }
  226. if pf_name == "" {
  227. wrap.MsgError(`Please specify category name`)
  228. return
  229. }
  230. if pf_alias == "" {
  231. pf_alias = utils.GenerateSingleAlias(pf_name)
  232. }
  233. if !utils.IsValidSingleAlias(pf_alias) {
  234. wrap.MsgError(`Please specify correct category alias`)
  235. return
  236. }
  237. // Set root category as default
  238. if pf_parent == "0" {
  239. pf_parent = "1"
  240. } else {
  241. // Check if parent category exists
  242. var parentId int
  243. err := wrap.DB.QueryRow(`
  244. SELECT
  245. id
  246. FROM
  247. blog_cats
  248. WHERE
  249. id > 1 AND
  250. id = ?
  251. LIMIT 1;`,
  252. pf_parent,
  253. ).Scan(&parentId)
  254. if err != nil {
  255. wrap.MsgError(err.Error())
  256. return
  257. }
  258. }
  259. if pf_id == "0" {
  260. if err := this.blog_ActionCategoryAdd(wrap, pf_id, pf_name, pf_alias, pf_parent); err != nil {
  261. wrap.MsgError(err.Error())
  262. return
  263. }
  264. wrap.Write(`window.location='/cp/blog/categories/';`)
  265. } else {
  266. if err := this.blog_ActionCategoryUpdate(wrap, pf_id, pf_name, pf_alias, pf_parent); err != nil {
  267. wrap.MsgError(err.Error())
  268. return
  269. }
  270. wrap.Write(`window.location='/cp/blog/categories-modify/` + pf_id + `/';`)
  271. }
  272. })
  273. }
  274. func (this *Modules) RegisterAction_BlogCategoriesDelete() *Action {
  275. return this.newAction(AInfo{
  276. WantDB: true,
  277. Mount: "blog-categories-delete",
  278. WantAdmin: true,
  279. }, func(wrap *wrapper.Wrapper) {
  280. pf_id := wrap.R.FormValue("id")
  281. if !utils.IsNumeric(pf_id) || utils.StrToInt(pf_id) <= 1 {
  282. wrap.MsgError(`Inner system error`)
  283. return
  284. }
  285. // Start transaction with table lock
  286. _, err := wrap.DB.Exec("LOCK TABLES blog_cats WRITE, blog_cat_post_rel WRITE;")
  287. if err != nil {
  288. wrap.MsgError(err.Error())
  289. return
  290. }
  291. tx, err := wrap.DB.Begin()
  292. if err != nil {
  293. wrap.MsgError(err.Error())
  294. return
  295. }
  296. // Update and delete target category
  297. if _, err = tx.Exec("SELECT @ml := lft, @mr := rgt FROM blog_cats WHERE id = ?;", pf_id); err != nil {
  298. tx.Rollback()
  299. wrap.MsgError(err.Error())
  300. return
  301. }
  302. if _, err = tx.Exec("DELETE FROM blog_cats WHERE id = ?;", pf_id); err != nil {
  303. tx.Rollback()
  304. wrap.MsgError(err.Error())
  305. return
  306. }
  307. if _, err = tx.Exec("UPDATE blog_cats SET lft = lft - 1, rgt = rgt - 1 WHERE lft > @ml AND rgt < @mr;"); err != nil {
  308. tx.Rollback()
  309. wrap.MsgError(err.Error())
  310. return
  311. }
  312. if _, err = tx.Exec("UPDATE blog_cats SET lft = lft - 2 WHERE lft > @mr;"); err != nil {
  313. tx.Rollback()
  314. wrap.MsgError(err.Error())
  315. return
  316. }
  317. if _, err = tx.Exec("UPDATE blog_cats SET rgt = rgt - 2 WHERE rgt > @mr;"); err != nil {
  318. tx.Rollback()
  319. wrap.MsgError(err.Error())
  320. return
  321. }
  322. if _, err = tx.Exec("DELETE FROM blog_cat_post_rel WHERE category_id = ?;", pf_id); err != nil {
  323. tx.Rollback()
  324. wrap.MsgError(err.Error())
  325. return
  326. }
  327. // Commit all changes and unlock table
  328. err = tx.Commit()
  329. if err != nil {
  330. wrap.MsgError(err.Error())
  331. return
  332. }
  333. _, err = wrap.DB.Exec("UNLOCK TABLES;")
  334. if err != nil {
  335. wrap.MsgError(err.Error())
  336. return
  337. }
  338. // Reload current page
  339. wrap.Write(`window.location.reload(false);`)
  340. })
  341. }