module_index.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  1. package modules
  2. import (
  3. "database/sql"
  4. _ "github.com/go-sql-driver/mysql"
  5. "fmt"
  6. "html"
  7. "os"
  8. "strconv"
  9. "golang-fave/assets"
  10. "golang-fave/consts"
  11. "golang-fave/engine/builder"
  12. "golang-fave/engine/wrapper"
  13. "golang-fave/utils"
  14. )
  15. func (this *Modules) RegisterModule_Index() *Module {
  16. return this.newModule(MInfo{
  17. WantDB: true,
  18. Mount: "index",
  19. Name: "Pages",
  20. Order: 0,
  21. Icon: assets.SysSvgIconPage,
  22. Sub: &[]MISub{
  23. {Mount: "default", Name: "List of Pages", Show: true, Icon: assets.SysSvgIconList},
  24. {Mount: "add", Name: "Add New Page", Show: true, Icon: assets.SysSvgIconPlus},
  25. {Mount: "modify", Name: "Modify Page", Show: false},
  26. },
  27. }, func(wrap *wrapper.Wrapper) {
  28. // Front-end
  29. wrap.RenderFrontEnd("index", consts.TmplDataModIndex{
  30. MetaTitle: "Meta Title",
  31. MetaKeywords: "Meta Keywords",
  32. MetaDescription: "Meta Description",
  33. MainMenuItems: []consts.TmplDataMainMenuItem{
  34. {Name: "Home", Link: "/", Active: true},
  35. {Name: "Item 1", Link: "/#1", Active: false},
  36. {Name: "Item 2", Link: "/#2", Active: false},
  37. {Name: "Item 3", Link: "/#3", Active: false},
  38. },
  39. })
  40. }, func(wrap *wrapper.Wrapper) (string, string, string) {
  41. content := ""
  42. sidebar := ""
  43. if wrap.CurrSubModule == "" || wrap.CurrSubModule == "default" {
  44. content += this.getBreadCrumbs(wrap, &[]consts.BreadCrumb{
  45. {Name: "List of Pages"},
  46. })
  47. content += builder.DataTable(wrap, "pages", "id", "DESC", []builder.DataTableRow{
  48. {
  49. DBField: "id",
  50. },
  51. {
  52. DBField: "name",
  53. NameInTable: "Page / Alias",
  54. CallBack: func(values *[]string) string {
  55. name := `<a href="/cp/` + wrap.CurrModule + `/modify/` + (*values)[0] + `/">` + html.EscapeString((*values)[1]) + `</a>`
  56. alias := html.EscapeString((*values)[2])
  57. return `<div>` + name + `</div><div><small>` + alias + `</small></div>`
  58. },
  59. },
  60. {
  61. DBField: "alias",
  62. },
  63. {
  64. DBField: "datetime",
  65. NameInTable: "Date / Time",
  66. },
  67. {
  68. DBField: "active",
  69. NameInTable: "Active",
  70. },
  71. }, func(values *[]string) string {
  72. return `<a class="ico" href="/cp/` + wrap.CurrModule + `/modify/` + (*values)[0] + `/">` +
  73. assets.SysSvgIconEdit + `</a>` +
  74. `<a class="ico" href="#">` + assets.SysSvgIconRemove + `</a>`
  75. }, "/cp/"+wrap.CurrModule+"/")
  76. } else if wrap.CurrSubModule == "add" || wrap.CurrSubModule == "modify" {
  77. if wrap.CurrSubModule == "add" {
  78. content += this.getBreadCrumbs(wrap, &[]consts.BreadCrumb{
  79. {Name: "Add New Page"},
  80. })
  81. } else {
  82. content += this.getBreadCrumbs(wrap, &[]consts.BreadCrumb{
  83. {Name: "Modify Page"},
  84. })
  85. }
  86. data := utils.MySql_page{
  87. A_id: 0,
  88. A_user: 0,
  89. A_name: "",
  90. A_alias: "",
  91. A_content: "",
  92. A_meta_title: "",
  93. A_meta_keywords: "",
  94. A_meta_description: "",
  95. A_datetime: 0,
  96. A_active: 0,
  97. }
  98. if wrap.CurrSubModule == "modify" {
  99. if len(wrap.UrlArgs) != 3 {
  100. return "", "", ""
  101. }
  102. if !utils.IsNumeric(wrap.UrlArgs[2]) {
  103. return "", "", ""
  104. }
  105. err := wrap.DB.QueryRow(`
  106. SELECT
  107. id,
  108. user,
  109. name,
  110. alias,
  111. content,
  112. meta_title,
  113. meta_keywords,
  114. meta_description,
  115. active
  116. FROM
  117. pages
  118. WHERE
  119. id = ?
  120. LIMIT 1;`,
  121. utils.StrToInt(wrap.UrlArgs[2]),
  122. ).Scan(
  123. &data.A_id,
  124. &data.A_user,
  125. &data.A_name,
  126. &data.A_alias,
  127. &data.A_content,
  128. &data.A_meta_title,
  129. &data.A_meta_keywords,
  130. &data.A_meta_description,
  131. &data.A_active,
  132. )
  133. if err != nil {
  134. return "", "", ""
  135. }
  136. }
  137. content += builder.DataForm(wrap, []builder.DataFormField{
  138. {
  139. Kind: builder.DFKHidden,
  140. Name: "action",
  141. Value: "index-modify",
  142. },
  143. {
  144. Kind: builder.DFKHidden,
  145. Name: "id",
  146. Value: utils.IntToStr(data.A_id),
  147. },
  148. {
  149. Kind: builder.DFKText,
  150. Caption: "Page Name",
  151. Name: "name",
  152. Value: data.A_name,
  153. },
  154. {
  155. Kind: builder.DFKText,
  156. Caption: "Page Alias",
  157. Name: "alias",
  158. Value: data.A_alias,
  159. Hint: "Example: /about-us/ or /about-us.html or /about/team.html",
  160. },
  161. {
  162. Kind: builder.DFKTextArea,
  163. Caption: "Page Content",
  164. Name: "content",
  165. Value: data.A_content,
  166. },
  167. {
  168. Kind: builder.DFKText,
  169. Caption: "Meta Title",
  170. Name: "meta_title",
  171. Value: data.A_meta_title,
  172. },
  173. {
  174. Kind: builder.DFKText,
  175. Caption: "Meta Keywords",
  176. Name: "meta_keywords",
  177. Value: data.A_meta_keywords,
  178. },
  179. {
  180. Kind: builder.DFKTextArea,
  181. Caption: "Meta Description",
  182. Name: "meta_description",
  183. Value: data.A_meta_description,
  184. },
  185. {
  186. Kind: builder.DFKCheckBox,
  187. Caption: "Active",
  188. Name: "active",
  189. Value: utils.IntToStr(data.A_active),
  190. },
  191. {
  192. Kind: builder.DFKMessage,
  193. },
  194. {
  195. Kind: builder.DFKSubmit,
  196. Value: "Add",
  197. Target: "add-edit-button",
  198. },
  199. })
  200. if wrap.CurrSubModule == "add" {
  201. sidebar += `<button class="btn btn-primary btn-sidebar" id="add-edit-button">Add</button>`
  202. } else {
  203. sidebar += `<button class="btn btn-primary btn-sidebar" id="add-edit-button">Save</button>`
  204. }
  205. }
  206. return this.getSidebarModules(wrap), content, sidebar
  207. })
  208. }
  209. func (this *Modules) RegisterAction_IndexMysqlSetup() *Action {
  210. return this.newAction(AInfo{
  211. WantDB: false,
  212. Mount: "index-mysql-setup",
  213. }, func(wrap *wrapper.Wrapper) {
  214. pf_host := wrap.R.FormValue("host")
  215. pf_port := wrap.R.FormValue("port")
  216. pf_name := wrap.R.FormValue("name")
  217. pf_user := wrap.R.FormValue("user")
  218. pf_password := wrap.R.FormValue("password")
  219. if pf_host == "" {
  220. wrap.MsgError(`Please specify host for MySQL connection`)
  221. return
  222. }
  223. if pf_port == "" {
  224. wrap.MsgError(`Please specify host port for MySQL connection`)
  225. return
  226. }
  227. if _, err := strconv.Atoi(pf_port); err != nil {
  228. wrap.MsgError(`MySQL host port must be integer number`)
  229. return
  230. }
  231. if pf_name == "" {
  232. wrap.MsgError(`Please specify MySQL database name`)
  233. return
  234. }
  235. if pf_user == "" {
  236. wrap.MsgError(`Please specify MySQL user`)
  237. return
  238. }
  239. // Try connect to mysql
  240. db, err := sql.Open("mysql", pf_user+":"+pf_password+"@tcp("+pf_host+":"+pf_port+")/"+pf_name)
  241. if err != nil {
  242. wrap.MsgError(err.Error())
  243. return
  244. }
  245. defer db.Close()
  246. err = db.Ping()
  247. if err != nil {
  248. wrap.MsgError(err.Error())
  249. return
  250. }
  251. // Try to install all tables
  252. _, err = db.Query(fmt.Sprintf(
  253. `CREATE TABLE %s.users (
  254. id int(11) NOT NULL AUTO_INCREMENT COMMENT 'AI',
  255. first_name VARCHAR(64) NOT NULL DEFAULT '' COMMENT 'User first name',
  256. last_name VARCHAR(64) NOT NULL DEFAULT '' COMMENT 'User last name',
  257. email VARCHAR(64) NOT NULL COMMENT 'User email',
  258. password VARCHAR(32) NOT NULL COMMENT 'User password (MD5)',
  259. admin int(1) NOT NULL COMMENT 'Is admin user or not',
  260. active int(1) NOT NULL COMMENT 'Is active user or not',
  261. PRIMARY KEY (id)
  262. ) ENGINE = InnoDB;`,
  263. pf_name))
  264. if err != nil {
  265. wrap.MsgError(err.Error())
  266. return
  267. }
  268. _, err = db.Query(fmt.Sprintf(
  269. `CREATE TABLE %s.pages (
  270. id int(11) NOT NULL AUTO_INCREMENT COMMENT 'AI',
  271. user int(11) NOT NULL COMMENT 'User id',
  272. name varchar(255) NOT NULL COMMENT 'Page name',
  273. alias varchar(255) NOT NULL COMMENT 'Page url part',
  274. content text NOT NULL COMMENT 'Page content',
  275. meta_title varchar(255) NOT NULL DEFAULT '' COMMENT 'Page meta title',
  276. meta_keywords varchar(255) NOT NULL DEFAULT '' COMMENT 'Page meta keywords',
  277. meta_description varchar(510) NOT NULL DEFAULT '' COMMENT 'Page meta description',
  278. datetime datetime NOT NULL COMMENT 'Creation date/time',
  279. active int(1) NOT NULL COMMENT 'Is active page or not',
  280. PRIMARY KEY (id)
  281. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;`,
  282. pf_name))
  283. if err != nil {
  284. wrap.MsgError(err.Error())
  285. return
  286. }
  287. // Save mysql config file
  288. err = utils.MySqlConfigWrite(wrap.DConfig+string(os.PathSeparator)+"mysql.json", pf_host, pf_port, pf_name, pf_user, pf_password)
  289. if err != nil {
  290. wrap.MsgError(err.Error())
  291. return
  292. }
  293. // Reload current page
  294. wrap.Write(`window.location.reload(false);`)
  295. })
  296. }
  297. func (this *Modules) RegisterAction_IndexFirstUser() *Action {
  298. return this.newAction(AInfo{
  299. WantDB: true,
  300. Mount: "index-first-user",
  301. }, func(wrap *wrapper.Wrapper) {
  302. pf_first_name := wrap.R.FormValue("first_name")
  303. pf_last_name := wrap.R.FormValue("last_name")
  304. pf_email := wrap.R.FormValue("email")
  305. pf_password := wrap.R.FormValue("password")
  306. if pf_email == "" {
  307. wrap.MsgError(`Please specify user email`)
  308. return
  309. }
  310. if !utils.IsValidEmail(pf_email) {
  311. wrap.MsgError(`Please specify correct user email`)
  312. return
  313. }
  314. if pf_password == "" {
  315. wrap.MsgError(`Please specify user password`)
  316. return
  317. }
  318. _, err := wrap.DB.Query(
  319. `INSERT INTO users SET
  320. first_name = ?,
  321. last_name = ?,
  322. email = ?,
  323. password = MD5(?),
  324. admin = 1,
  325. active = 1
  326. ;`,
  327. pf_first_name,
  328. pf_last_name,
  329. pf_email,
  330. pf_password,
  331. )
  332. if err != nil {
  333. wrap.MsgError(err.Error())
  334. return
  335. }
  336. // Reload current page
  337. wrap.Write(`window.location.reload(false);`)
  338. })
  339. }
  340. func (this *Modules) RegisterAction_IndexUserSignIn() *Action {
  341. return this.newAction(AInfo{
  342. WantDB: true,
  343. Mount: "index-user-sign-in",
  344. }, func(wrap *wrapper.Wrapper) {
  345. pf_email := wrap.R.FormValue("email")
  346. pf_password := wrap.R.FormValue("password")
  347. if pf_email == "" {
  348. wrap.MsgError(`Please specify user email`)
  349. return
  350. }
  351. if !utils.IsValidEmail(pf_email) {
  352. wrap.MsgError(`Please specify correct user email`)
  353. return
  354. }
  355. if pf_password == "" {
  356. wrap.MsgError(`Please specify user password`)
  357. return
  358. }
  359. if wrap.S.GetInt("UserId", 0) > 0 {
  360. wrap.MsgError(`You already logined`)
  361. return
  362. }
  363. var user_id int
  364. err := wrap.DB.QueryRow(
  365. `SELECT
  366. id
  367. FROM
  368. users
  369. WHERE
  370. email = ? and
  371. password = MD5(?) and
  372. admin = 1 and
  373. active = 1
  374. LIMIT 1;`,
  375. pf_email,
  376. pf_password,
  377. ).Scan(
  378. &user_id,
  379. )
  380. if err != nil && err != sql.ErrNoRows {
  381. wrap.MsgError(err.Error())
  382. return
  383. }
  384. if err == sql.ErrNoRows {
  385. wrap.MsgError(`Incorrect email or password`)
  386. return
  387. }
  388. // Save to current session
  389. wrap.S.SetInt("UserId", user_id)
  390. // Reload current page
  391. wrap.Write(`window.location.reload(false);`)
  392. })
  393. }
  394. func (this *Modules) RegisterAction_IndexUserLogout() *Action {
  395. return this.newAction(AInfo{
  396. WantDB: true,
  397. Mount: "index-user-logout",
  398. WantUser: true,
  399. }, func(wrap *wrapper.Wrapper) {
  400. // Reset session var
  401. wrap.S.SetInt("UserId", 0)
  402. // Reload current page
  403. wrap.Write(`window.location.reload(false);`)
  404. })
  405. }
  406. func (this *Modules) RegisterAction_IndexUserUpdateProfile() *Action {
  407. return this.newAction(AInfo{
  408. WantDB: true,
  409. Mount: "index-user-update-profile",
  410. WantUser: true,
  411. }, func(wrap *wrapper.Wrapper) {
  412. pf_first_name := wrap.R.FormValue("first_name")
  413. pf_last_name := wrap.R.FormValue("last_name")
  414. pf_email := wrap.R.FormValue("email")
  415. pf_password := wrap.R.FormValue("password")
  416. if pf_email == "" {
  417. wrap.MsgError(`Please specify user email`)
  418. return
  419. }
  420. if !utils.IsValidEmail(pf_email) {
  421. wrap.MsgError(`Please specify correct user email`)
  422. return
  423. }
  424. if pf_password != "" {
  425. // Update with password if set
  426. _, err := wrap.DB.Query(
  427. `UPDATE users SET
  428. first_name = ?,
  429. last_name = ?,
  430. email = ?,
  431. password = MD5(?)
  432. WHERE
  433. id = ?
  434. ;`,
  435. pf_first_name,
  436. pf_last_name,
  437. pf_email,
  438. pf_password,
  439. wrap.User.A_id,
  440. )
  441. if err != nil {
  442. wrap.MsgError(err.Error())
  443. return
  444. }
  445. } else {
  446. // Update without password if not set
  447. _, err := wrap.DB.Query(
  448. `UPDATE users SET
  449. first_name = ?,
  450. last_name = ?,
  451. email = ?
  452. WHERE
  453. id = ?
  454. ;`,
  455. pf_first_name,
  456. pf_last_name,
  457. pf_email,
  458. wrap.User.A_id,
  459. )
  460. if err != nil {
  461. wrap.MsgError(err.Error())
  462. return
  463. }
  464. }
  465. // Reload current page
  466. wrap.Write(`window.location.reload(false);`)
  467. })
  468. }