2018-06-06 00:21:22 +00:00
package common
import (
2022-02-21 03:53:13 +00:00
"database/sql"
"strconv"
"strings"
2018-06-06 00:21:22 +00:00
2022-02-21 03:53:13 +00:00
qgen "git.tuxpa.in/a/gosora/query_gen"
2018-06-06 00:21:22 +00:00
)
type CustomPageStmts struct {
2022-02-21 03:32:53 +00:00
update * sql . Stmt
create * sql . Stmt
2018-06-06 00:21:22 +00:00
}
var customPageStmts CustomPageStmts
func init ( ) {
2022-02-21 03:32:53 +00:00
DbInits . Add ( func ( acc * qgen . Accumulator ) error {
customPageStmts = CustomPageStmts {
update : acc . Update ( "pages" ) . Set ( "name=?,title=?,body=?,allowedGroups=?,menuID=?" ) . Where ( "pid=?" ) . Prepare ( ) ,
create : acc . Insert ( "pages" ) . Columns ( "name,title,body,allowedGroups,menuID" ) . Fields ( "?,?,?,?,?" ) . Prepare ( ) ,
}
return acc . FirstError ( )
} )
2018-06-06 00:21:22 +00:00
}
type CustomPage struct {
2022-02-21 03:32:53 +00:00
ID int
Name string // TODO: Let admins put pages in "virtual subdirectories"
Title string
Body string
AllowedGroups [ ] int
MenuID int
2018-06-06 00:21:22 +00:00
}
func BlankCustomPage ( ) * CustomPage {
2022-02-21 03:32:53 +00:00
return new ( CustomPage )
2018-06-06 00:21:22 +00:00
}
2019-11-08 21:46:50 +00:00
func ( p * CustomPage ) AddAllowedGroup ( gid int ) {
2022-02-21 03:32:53 +00:00
p . AllowedGroups = append ( p . AllowedGroups , gid )
2018-06-06 00:21:22 +00:00
}
2019-11-08 21:46:50 +00:00
func ( p * CustomPage ) getRawAllowedGroups ( ) ( rawAllowedGroups string ) {
2022-02-21 03:32:53 +00:00
for _ , group := range p . AllowedGroups {
rawAllowedGroups += strconv . Itoa ( group ) + ","
}
if len ( rawAllowedGroups ) > 0 {
rawAllowedGroups = rawAllowedGroups [ : len ( rawAllowedGroups ) - 1 ]
}
return rawAllowedGroups
2018-06-06 00:21:22 +00:00
}
2019-11-08 21:46:50 +00:00
func ( p * CustomPage ) Commit ( ) error {
2022-02-21 03:32:53 +00:00
_ , err := customPageStmts . update . Exec ( p . Name , p . Title , p . Body , p . getRawAllowedGroups ( ) , p . MenuID , p . ID )
Pages . Reload ( p . ID )
return err
2018-06-06 00:21:22 +00:00
}
2019-11-08 21:46:50 +00:00
func ( p * CustomPage ) Create ( ) ( int , error ) {
2022-02-21 03:32:53 +00:00
res , err := customPageStmts . create . Exec ( p . Name , p . Title , p . Body , p . getRawAllowedGroups ( ) , p . MenuID )
if err != nil {
return 0 , err
}
pid64 , err := res . LastInsertId ( )
return int ( pid64 ) , err
2018-06-06 00:21:22 +00:00
}
var Pages PageStore
// Holds the custom pages, but doesn't include the template pages in /pages/ which are a lot more flexible yet harder to use and which are too risky security-wise to make editable in the Control Panel
type PageStore interface {
2022-02-21 03:32:53 +00:00
Count ( ) ( count int )
Get ( id int ) ( * CustomPage , error )
GetByName ( name string ) ( * CustomPage , error )
GetOffset ( offset , perPage int ) ( pages [ ] * CustomPage , err error )
Reload ( id int ) error
Delete ( id int ) error
2018-06-06 00:21:22 +00:00
}
// TODO: Add a cache to this to save on the queries
type DefaultPageStore struct {
2022-02-21 03:32:53 +00:00
get * sql . Stmt
getByName * sql . Stmt
getOffset * sql . Stmt
count * sql . Stmt
delete * sql . Stmt
2018-06-06 00:21:22 +00:00
}
func NewDefaultPageStore ( acc * qgen . Accumulator ) ( * DefaultPageStore , error ) {
2022-02-21 03:32:53 +00:00
pa := "pages"
allCols := "pid, name, title, body, allowedGroups, menuID"
return & DefaultPageStore {
get : acc . Select ( pa ) . Columns ( "name, title, body, allowedGroups, menuID" ) . Where ( "pid=?" ) . Prepare ( ) ,
getByName : acc . Select ( pa ) . Columns ( allCols ) . Where ( "name=?" ) . Prepare ( ) ,
getOffset : acc . Select ( pa ) . Columns ( allCols ) . Orderby ( "pid DESC" ) . Limit ( "?,?" ) . Prepare ( ) ,
count : acc . Count ( pa ) . Prepare ( ) ,
delete : acc . Delete ( pa ) . Where ( "pid=?" ) . Prepare ( ) ,
} , acc . FirstError ( )
2018-06-06 00:21:22 +00:00
}
2019-06-01 12:31:48 +00:00
func ( s * DefaultPageStore ) Count ( ) ( count int ) {
2022-02-21 03:32:53 +00:00
err := s . count . QueryRow ( ) . Scan ( & count )
if err != nil {
LogError ( err )
}
return count
2018-06-06 00:21:22 +00:00
}
2019-06-01 12:31:48 +00:00
func ( s * DefaultPageStore ) parseAllowedGroups ( raw string , page * CustomPage ) error {
2022-02-21 03:32:53 +00:00
if raw == "" {
return nil
}
for _ , sgroup := range strings . Split ( raw , "," ) {
group , err := strconv . Atoi ( sgroup )
if err != nil {
return err
}
page . AddAllowedGroup ( group )
}
return nil
2018-06-06 00:21:22 +00:00
}
2019-07-26 22:26:52 +00:00
func ( s * DefaultPageStore ) Get ( id int ) ( * CustomPage , error ) {
2022-02-21 03:32:53 +00:00
p := & CustomPage { ID : id }
rawAllowedGroups := ""
err := s . get . QueryRow ( id ) . Scan ( & p . Name , & p . Title , & p . Body , & rawAllowedGroups , & p . MenuID )
if err != nil {
return nil , err
}
return p , s . parseAllowedGroups ( rawAllowedGroups , p )
2018-06-06 00:21:22 +00:00
}
2019-07-26 22:26:52 +00:00
func ( s * DefaultPageStore ) GetByName ( name string ) ( * CustomPage , error ) {
2022-02-21 03:32:53 +00:00
p := BlankCustomPage ( )
rawAllowedGroups := ""
err := s . getByName . QueryRow ( name ) . Scan ( & p . ID , & p . Name , & p . Title , & p . Body , & rawAllowedGroups , & p . MenuID )
if err != nil {
return nil , err
}
return p , s . parseAllowedGroups ( rawAllowedGroups , p )
2018-06-06 00:21:22 +00:00
}
2020-01-14 05:07:00 +00:00
func ( s * DefaultPageStore ) GetOffset ( offset , perPage int ) ( pages [ ] * CustomPage , err error ) {
2022-02-21 03:32:53 +00:00
rows , err := s . getOffset . Query ( offset , perPage )
if err != nil {
return pages , err
}
defer rows . Close ( )
for rows . Next ( ) {
p := & CustomPage { ID : 0 }
rawAllowedGroups := ""
err := rows . Scan ( & p . ID , & p . Name , & p . Title , & p . Body , & rawAllowedGroups , & p . MenuID )
if err != nil {
return pages , err
}
err = s . parseAllowedGroups ( rawAllowedGroups , p )
if err != nil {
return pages , err
}
pages = append ( pages , p )
}
return pages , rows . Err ( )
2018-06-06 00:21:22 +00:00
}
// Always returns nil as there's currently no cache
2019-07-26 22:26:52 +00:00
func ( s * DefaultPageStore ) Reload ( id int ) error {
2022-02-21 03:32:53 +00:00
return nil
2018-06-06 00:21:22 +00:00
}
2019-07-26 22:26:52 +00:00
func ( s * DefaultPageStore ) Delete ( id int ) error {
2022-02-21 03:32:53 +00:00
_ , err := s . delete . Exec ( id )
return err
2018-06-06 00:21:22 +00:00
}