diff --git a/cmd/warehost-web/handler.go b/cmd/warehost-web/handler.go index 72885af..8e5a54d 100644 --- a/cmd/warehost-web/handler.go +++ b/cmd/warehost-web/handler.go @@ -7,7 +7,7 @@ import ( "os" "text/template" - //"github.com/microcosm-cc/bluemonday" + // "github.com/microcosm-cc/bluemonday" "github.com/russross/blackfriday" liblog "dev.sum7.eu/sum7/warehost/lib/log" @@ -62,7 +62,7 @@ func handlerfiles(w http.ResponseWriter, r *http.Request) { } func handlerfunc(w http.ResponseWriter, r *http.Request) { - url := r.URL.Path[1:] + url := web.FixPath(r.URL.Path[1:]) logger := liblog.NewModulLog(r.Host).GetLog(r, url) website, err := getWebsite(r.Host) if err != nil { @@ -73,43 +73,44 @@ func handlerfunc(w http.ResponseWriter, r *http.Request) { logger = logger.WithField("hID", website.ID) var menus []*web.Menu - dbconnection.Where("website = ?", website.ID).Preload("Menu").Order("position").Find(&menus) - var menu *web.Menu - for _, item := range menus { - if item.Shorturl == "" && menu == nil { - menu = item - } - if item.Shorturl == url { - menu = item - } - } - if menu.ID <= 0 { - logger.Warn("menu not found") - http.NotFound(w, r) - return - } - menus = web.BuildMenuTree(menus) - page := web.Page{WebsiteID: website.ID, MenuID: menu.ID} - dbconnection.Where(&page).Find(&page) - if page.ID <= 0 { - logger.Warn("page not found") - http.NotFound(w, r) - return - } - page.Menu = menu + dbconnection.Where("website = ?", website.ID).Preload("URL").Order("position").Find(&menus) + + var urls []*web.URL + dbconnection.Where("website = ?", website.ID).Find(&urls) + var urlObj *web.URL + for _, item := range urls { + if item.Path == "" && urlObj == nil { + urlObj = item + } + if item.Path == url { + urlObj = item + } + } + + menus = web.BuildMenuTree(menus) + + page := web.Page{ + WebsiteID: website.ID, + URLID: urlObj.ID, + } + dbconnection.Where(page).FirstOrInit(&page) + if page.ID > 0 { + unsafe := blackfriday.MarkdownCommon([]byte(page.Content)) + //page.Content = string(bluemonday.UGCPolicy().SanitizeBytes(unsafe)) + page.Content = string(unsafe) + page.URL = urlObj + } - unsafe := blackfriday.MarkdownCommon([]byte(page.Content)) - //page.Content = string(bluemonday.UGCPolicy().SanitizeBytes(unsafe)) - page.Content = string(unsafe) i := TemplateInfo{ Website: website, Host: r.Host, URL: url, - Page: &page, Menu: menus, + Page: &page, } t, err := template.ParseGlob(fmt.Sprintf("%s/%d/%s/%s", config.Webroot, website.ID, "tmpl", "*.tmpl")) logger.Info("done") + if err != nil { w.Write([]byte(fmt.Sprintf("

Error on rendering Template

\n%s", err))) } else { diff --git a/modul/web/apimenu.go b/modul/web/apimenu.go index e611eaa..5a1709a 100644 --- a/modul/web/apimenu.go +++ b/modul/web/apimenu.go @@ -14,7 +14,7 @@ func menuTree(w http.ResponseWriter, r *http.Request) { ctx := r.Context() logger := log.GetLog(r, "menutree") var menus []*Menu - dbconnection.Where("website = ?", ctx.Value("websiteid").(int64)).Order("position").Find(&menus) + dbconnection.Where("website = ?", ctx.Value("websiteid").(int64)).Preload("URL").Order("position").Find(&menus) logger.Info("done") libapi.JSONWrite(w, r, BuildMenuTree(menus), nil) } @@ -24,7 +24,7 @@ func menuList(w http.ResponseWriter, r *http.Request) { ctx := r.Context() logger := log.GetLog(r, "menulist") var menus []*Menu - dbconnection.Where("website = ?", ctx.Value("websiteid").(int64)).Order("position").Find(&menus) + dbconnection.Where("website = ?", ctx.Value("websiteid").(int64)).Preload("URL").Order("position").Find(&menus) logger.Info("done") libapi.JSONWrite(w, r, menus, nil) } @@ -41,9 +41,13 @@ func menuAdd(w http.ResponseWriter, r *http.Request) { } menuEntry.WebsiteID = ctx.Value("websiteid").(int64) + if menuEntry.URL != nil { + menuEntry.URLID = &menuEntry.URL.ID + menuEntry.URL = nil + } if err := dbconnection.Create(&menuEntry).Error; err != nil { - logger.Error("database: during create menu") + logger.Error("database: during create menu: ", err) libapi.JSONWrite(w, r, false, &libapi.ErrorResult{Message: "Internal Database Error"}) return } @@ -71,8 +75,13 @@ func menuEdit(w http.ResponseWriter, r *http.Request) { menuEntry.WebsiteID = ctx.Value("websiteid").(int64) menuEntry.ID = menuid + if menuEntry.URL != nil { + menuEntry.URLID = &menuEntry.URL.ID + menuEntry.URL = nil + } + if err := dbconnection.Save(menuEntry).Error; err != nil { - logger.Error("database: during edit website menu entry") + logger.Error("database: during edit website menu entry: ", err) libapi.JSONWrite(w, r, false, &libapi.ErrorResult{Message: "Internal Database Error"}) return } @@ -96,7 +105,7 @@ func menuDelete(w http.ResponseWriter, r *http.Request) { ID: menuid, } if err := dbconnection.Unscoped().Delete(menu).Error; err != nil { - logger.Error("database: during delete website menu entry") + logger.Error("database: during delete website menu entry: ", err) libapi.JSONWrite(w, r, false, &libapi.ErrorResult{Message: "Internal Database Error"}) return } diff --git a/modul/web/apipage.go b/modul/web/apipage.go index 071a095..261d98c 100644 --- a/modul/web/apipage.go +++ b/modul/web/apipage.go @@ -14,7 +14,7 @@ func pageList(w http.ResponseWriter, r *http.Request) { ctx := r.Context() logger := log.GetLog(r, "pagelist") var pages []*Page - dbconnection.Where("website = ?", ctx.Value("websiteid").(int64)).Preload("Menu").Find(&pages) + dbconnection.Where("website = ?", ctx.Value("websiteid").(int64)).Preload("URL").Find(&pages) logger.Info("done") libapi.JSONWrite(w, r, pages, nil) } @@ -31,13 +31,11 @@ func pageAdd(w http.ResponseWriter, r *http.Request) { } page.WebsiteID = ctx.Value("websiteid").(int64) - if menu := page.Menu; menu != nil { - page.MenuID = page.Menu.ID - page.Menu = nil - } + page.URL.WebsiteID = page.WebsiteID + page.URL.Path = FixPath(page.URL.Path) if err := dbconnection.Create(&page).Error; err != nil { - logger.Error("database: during create page") + logger.Error("database: during create page: ", err) libapi.JSONWrite(w, r, false, &libapi.ErrorResult{Message: "Internal Database Error"}) return } @@ -62,25 +60,35 @@ func pageEdit(w http.ResponseWriter, r *http.Request) { libapi.JSONWrite(w, r, false, returnerr) return } - page.WebsiteID = ctx.Value("websiteid").(int64) - page.ID = pageid - if menu := page.Menu; menu != nil { - page.MenuID = page.Menu.ID - page.Menu = nil - } - if err := dbconnection.Save(page).Error; err != nil { - logger.Error("database: during delete website page") + page.ID = pageid + page.WebsiteID = ctx.Value("websiteid").(int64) + page.URL.WebsiteID = page.WebsiteID + page.URL.Path = FixPath(page.URL.Path) + + tx := dbconnection.Begin() + if err := tx.Save(page.URL).Error; err != nil { + logger.Error("database: during save website url: ", err) libapi.JSONWrite(w, r, false, &libapi.ErrorResult{Message: "Internal Database Error"}) return } + + page.URLID = page.URL.ID + page.URL = nil + + if err := tx.Save(page).Error; err != nil { + logger.Error("database: during save website page: ", err) + libapi.JSONWrite(w, r, false, &libapi.ErrorResult{Message: "Internal Database Error"}) + return + } + tx.Commit() + logger.Info("done") libapi.JSONWrite(w, r, true, nil) } // PageDelete to delete page func pageDelete(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() logger := log.GetLog(r, "pagedelete") pageid, err := strconv.ParseInt(pat.Param(r, "pageid"), 10, 64) if err != nil { @@ -89,12 +97,11 @@ func pageDelete(w http.ResponseWriter, r *http.Request) { return } logger = logger.WithField("id", pageid) - page := &Page{ - WebsiteID: ctx.Value("websiteid").(int64), - ID: pageid, - } - if err := dbconnection.Unscoped().Delete(page).Error; err != nil { - logger.Error("database: during delete website page") + page := &Page{} + dbconnection.Where("id = ?", pageid).Preload("URL").First(page) + + if err := dbconnection.Unscoped().Delete(page.URL).Error; err != nil { + logger.Error("database: during delete website page: ", err) libapi.JSONWrite(w, r, false, &libapi.ErrorResult{Message: "Internal Database Error"}) return } diff --git a/modul/web/lib.go b/modul/web/lib.go index 53fbcdc..13a98fd 100644 --- a/modul/web/lib.go +++ b/modul/web/lib.go @@ -3,8 +3,10 @@ package web import ( "net/http" "strconv" + "strings" "context" + "goji.io/pat" libapi "dev.sum7.eu/sum7/warehost/lib/api" @@ -12,6 +14,10 @@ import ( libsystem "dev.sum7.eu/sum7/warehost/system" ) +func FixPath(path string) string { + return strings.ToLower(strings.Trim(path, "/ ")) +} + //InvolveWebsiteHandler for api function to Verifie User ist loggedin func InvolveWebsiteHandler(h libapi.Handle) libapi.Handle { return func(w http.ResponseWriter, r *http.Request) { diff --git a/modul/web/models.go b/modul/web/models.go index 52005c0..9df8a2c 100644 --- a/modul/web/models.go +++ b/modul/web/models.go @@ -38,8 +38,9 @@ func (Manager) TableName() string { return "web_manager" } // Media struct type Media struct { + ID int64 `gorm:"primary_key"` WebsiteID int64 `sql:"type:bigint REFERENCES web_website(id) ON UPDATE CASCADE ON DELETE CASCADE;column:website;primary_key" json:"-"` - Path string `gorm:"type:varchar(255);column:path;primary_key" json:"path"` + Path string `gorm:"type:varchar(255);column:path" json:"path"` } // TableName of struct @@ -50,8 +51,9 @@ type Menu struct { ID int64 `gorm:"primary_key"` WebsiteID int64 `sql:"type:bigint REFERENCES web_website(id) ON UPDATE CASCADE ON DELETE CASCADE;column:website" json:"-"` Name string `gorm:"type:varchar(255);column:name" json:"name"` - Shorturl string `gorm:"type:varchar(255);column:url" json:"url"` ParentID *int64 `sql:"type:bigint REFERENCES web_menu(id) ON UPDATE SET NULL ON DELETE SET NULL;column:menu" json:"parentid"` + URLID *int64 `sql:"type:bigint REFERENCES web_url(id) ON UPDATE CASCADE ON DELETE SET NULL;column:url" json:"-"` + URL *URL `gorm:"foreignkey:URL" json:"url"` Position int `sql:"type:int;column:position" json:"position"` Children []*Menu `json:"children"` } @@ -59,12 +61,22 @@ type Menu struct { // TableName of struct func (Menu) TableName() string { return "web_menu" } +// URL struct +type URL struct { + ID int64 `gorm:"primary_key"` + WebsiteID int64 `sql:"type:bigint REFERENCES web_website(id) ON UPDATE CASCADE ON DELETE CASCADE;column:website;unique_index:url_website_path" gorm:"unique_index:idx_url_website_path" json:"-"` + Path string `gorm:"type:varchar(255);column:path;unique_index:idx_url_website_path" json:"path"` +} + +// TableName of struct +func (URL) TableName() string { return "web_url" } + // Page struct type Page struct { ID int64 `gorm:"primary_key"` WebsiteID int64 `sql:"type:bigint REFERENCES web_website(id) ON UPDATE CASCADE ON DELETE CASCADE;column:website" json:"-"` - MenuID int64 `sql:"type:bigint unique REFERENCES web_menu(id) ON UPDATE CASCADE ON DELETE CASCADE;column:menu" json:"-"` - Menu *Menu `json:"menu"` + URLID int64 `sql:"type:bigint unique REFERENCES web_url(id) ON UPDATE CASCADE ON DELETE CASCADE;column:url" json:"-"` + URL *URL `gorm:"foreignkey:URL" json:"url"` Title string `gorm:"type:varchar(255);column:title" json:"title"` Content string `gorm:"type:text;column:content" json:"content"` } @@ -99,5 +111,5 @@ func BuildMenuTree(items []*Menu) []*Menu { // SyncModels to verify the database schema func SyncModels(dbconnection *gorm.DB) { - dbconnection.AutoMigrate(&Website{}, &Domain{}, &Manager{}, &Media{}, &Menu{}, &Page{}) + dbconnection.AutoMigrate(&Website{}, &Domain{}, &Manager{}, &URL{}, &Media{}, &Menu{}, &Page{}) }