1
0
Fork 0
mirror of https://github.com/documize/community.git synced 2025-08-02 03:55:24 +02:00

saving and inserting reusable content blocks

This commit is contained in:
Harvey Kandola 2017-01-20 14:24:38 -08:00
parent fdbf03b25c
commit b7fa3b9006
32 changed files with 1334 additions and 768 deletions

View file

@ -80,10 +80,19 @@ func AddDocumentPage(w http.ResponseWriter, r *http.Request) {
model.Meta.PageID = pageID
model.Page.SetDefaults()
model.Meta.SetDefaults()
model.Meta.OrgID = p.Context.OrgID
model.Meta.UserID = p.Context.UserID
// page.Title = template.HTMLEscapeString(page.Title)
// laod previous meta if page is being created from published template
if model.Page.PresetID != "" {
em, err2 := p.GetPageMeta(model.Page.PresetID)
if err2 != nil {
writeGeneralSQLError(w, method, err2)
return
}
model.Meta = em
model.Meta.PageID = pageID
}
tx, err := request.Db.Beginx()
if err != nil {
@ -111,7 +120,7 @@ func AddDocumentPage(w http.ResponseWriter, r *http.Request) {
log.IfErr(tx.Commit())
newPage, err := p.GetPage(pageID)
newPage, _ := p.GetPage(pageID)
json, err := json.Marshal(newPage)
@ -669,7 +678,7 @@ func GetDocumentRevisions(w http.ResponseWriter, r *http.Request) {
return
}
revisions, err := p.GetDocumentRevisions(documentID)
revisions, _ := p.GetDocumentRevisions(documentID)
payload, err := json.Marshal(revisions)
@ -706,7 +715,7 @@ func GetDocumentPageRevisions(w http.ResponseWriter, r *http.Request) {
return
}
revisions, err := p.GetPageRevisions(pageID)
revisions, _ := p.GetPageRevisions(pageID)
payload, err := json.Marshal(revisions)
@ -757,7 +766,7 @@ func GetDocumentPageDiff(w http.ResponseWriter, r *http.Request) {
return
}
revision, err := p.GetPageRevision(revisionID)
revision, _ := p.GetPageRevision(revisionID)
latestHTML := page.Body
previousHTML := revision.Body
@ -875,3 +884,145 @@ func RollbackDocumentPage(w http.ResponseWriter, r *http.Request) {
writeSuccessBytes(w, payload)
}
/********************
* Page Templates
********************/
type sectionTemplate struct {
DocumentID string `json:"documentId"`
PageID string `json:"pageId"`
Title string `json:"title"`
}
// SavePageAsTemplate inserts new section into document.
func SavePageAsTemplate(w http.ResponseWriter, r *http.Request) {
method := "SavePageAsTemplate"
p := request.GetPersister(r)
defer utility.Close(r.Body)
body, err := ioutil.ReadAll(r.Body)
if err != nil {
writeBadRequestError(w, method, "Bad payload")
return
}
payload := new(sectionTemplate)
err = json.Unmarshal(body, &payload)
if err != nil {
writePayloadError(w, method, err)
return
}
// Data checks
if len(payload.DocumentID) == 0 {
writeMissingDataError(w, method, "documentID")
return
}
if len(payload.PageID) == 0 {
writeMissingDataError(w, method, "pageID")
return
}
if len(payload.Title) == 0 {
writeMissingDataError(w, method, "title")
return
}
if !p.CanChangeDocument(payload.DocumentID) {
writeForbiddenError(w)
return
}
// if strings.HasPrefix(newTitle, "\"") {
// newTitle = newTitle[1:]
// }
// if strings.HasSuffix(newTitle, "\"") {
// newTitle = newTitle[:len(newTitle)-1]
// }
// get previous page
prevPage, err := p.GetPage(payload.PageID)
if err != nil {
writeServerError(w, method, err)
return
}
prevMeta, err := p.GetPageMeta(payload.PageID)
if err != nil {
writeServerError(w, method, err)
return
}
// safety check
if prevPage.DocumentID != payload.DocumentID || prevMeta.DocumentID != payload.DocumentID {
writeUnauthorizedError(w)
return
}
newID := util.UniqueID()
prevPage.RefID = newID
prevPage.Preset = true
prevPage.Title = payload.Title
prevMeta.PageID = newID
tx, err := request.Db.Beginx()
if err != nil {
writeTransactionError(w, method, err)
return
}
p.Context.Transaction = tx
model := new(models.PageModel)
model.Page = prevPage
model.Meta = prevMeta
err = p.AddPage(*model)
if err != nil {
log.IfErr(tx.Rollback())
writeGeneralSQLError(w, method, err)
return
}
log.IfErr(tx.Commit())
writeSuccessEmptyJSON(w)
}
// GetSpaceSectionTemplates gets published section templates
func GetSpaceSectionTemplates(w http.ResponseWriter, r *http.Request) {
method := "GetSpaceSectionTemplates"
p := request.GetPersister(r)
params := mux.Vars(r)
folderID := params["folderID"]
if len(folderID) == 0 {
writeMissingDataError(w, method, "folderID")
return
}
var pages []entity.PageTemplate
var err error
pages, err = p.GetSpaceSectionTemplates(folderID)
if len(pages) == 0 {
pages = []entity.PageTemplate{}
}
if err != nil {
writeGeneralSQLError(w, method, err)
return
}
json, err := json.Marshal(pages)
if err != nil {
writeJSONMarshalError(w, method, "page", err)
return
}
writeSuccessBytes(w, json)
}

View file

@ -216,6 +216,8 @@ func init() {
log.IfErr(Add(RoutePrefixPrivate, "sections", []string{"GET", "OPTIONS"}, nil, GetSections))
log.IfErr(Add(RoutePrefixPrivate, "sections", []string{"POST", "OPTIONS"}, nil, RunSectionCommand))
log.IfErr(Add(RoutePrefixPrivate, "sections/refresh", []string{"GET", "OPTIONS"}, nil, RefreshSections))
log.IfErr(Add(RoutePrefixPrivate, "sections/templates/{folderID}", []string{"GET", "OPTIONS"}, nil, GetSpaceSectionTemplates))
log.IfErr(Add(RoutePrefixPrivate, "sections/templates", []string{"POST", "OPTIONS"}, nil, SavePageAsTemplate))
// Links
log.IfErr(Add(RoutePrefixPrivate, "links/{folderID}/{documentID}/{pageID}", []string{"GET", "OPTIONS"}, nil, GetLinkCandidates))

View file

@ -186,6 +186,8 @@ type Page struct {
UserID string `json:"userId"`
ContentType string `json:"contentType"`
PageType string `json:"pageType"`
Preset bool `json:"preset"`
PresetID string `json:"presetId"`
Level uint64 `json:"level"`
Sequence float64 `json:"sequence"`
Title string `json:"title"`
@ -259,6 +261,14 @@ type Revision struct {
Revisions int `json:"revisions"`
}
// PageTemplate represents a section that has been published as a template.
// We have to create this struct to hold user name.
type PageTemplate struct {
Page
Firstname string `json:"firstname"`
Lastname string `json:"lastname"`
}
// DocumentMeta details who viewed the document.
type DocumentMeta struct {
Viewers []DocumentMetaViewer `json:"viewers"`

View file

@ -26,7 +26,6 @@ import (
// AddPage inserts the given page into the page table, adds that page to the queue of pages to index and audits that the page has been added.
func (p *Persister) AddPage(model models.PageModel) (err error) {
err = nil
model.Page.OrgID = p.Context.OrgID
model.Page.UserID = p.Context.UserID
model.Page.Created = time.Now().UTC()
@ -51,7 +50,7 @@ func (p *Persister) AddPage(model models.PageModel) (err error) {
model.Page.Sequence = maxSeq * 2
}
stmt, err := p.Context.Transaction.Preparex("INSERT INTO page (refid, orgid, documentid, userid, contenttype, pagetype, level, title, body, revisions, sequence, created, revised) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
stmt, err := p.Context.Transaction.Preparex("INSERT INTO page (refid, orgid, documentid, userid, contenttype, pagetype, level, title, body, revisions, sequence, preset, presetid, created, revised) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
defer utility.Close(stmt)
if err != nil {
@ -59,14 +58,14 @@ func (p *Persister) AddPage(model models.PageModel) (err error) {
return
}
_, err = stmt.Exec(model.Page.RefID, model.Page.OrgID, model.Page.DocumentID, model.Page.UserID, model.Page.ContentType, model.Page.PageType, model.Page.Level, model.Page.Title, model.Page.Body, model.Page.Revisions, model.Page.Sequence, model.Page.Created, model.Page.Revised)
_, err = stmt.Exec(model.Page.RefID, model.Page.OrgID, model.Page.DocumentID, model.Page.UserID, model.Page.ContentType, model.Page.PageType, model.Page.Level, model.Page.Title, model.Page.Body, model.Page.Revisions, model.Page.Sequence, model.Page.Preset, model.Page.PresetID, model.Page.Created, model.Page.Revised)
if err != nil {
log.Error("Unable to execute insert for page", err)
return
}
err = searches.Add(&databaseRequest{OrgID: p.Context.OrgID}, model.Page, model.Page.RefID)
_ = searches.Add(&databaseRequest{OrgID: p.Context.OrgID}, model.Page, model.Page.RefID)
stmt2, err := p.Context.Transaction.Preparex("INSERT INTO pagemeta (pageid, orgid, userid, documentid, rawbody, config, externalsource, created, revised) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)")
defer utility.Close(stmt2)
@ -92,7 +91,7 @@ func (p *Persister) AddPage(model models.PageModel) (err error) {
func (p *Persister) GetPage(pageID string) (page entity.Page, err error) {
err = nil
stmt, err := Db.Preparex("SELECT a.id, a.refid, a.orgid, a.documentid, a.userid, a.contenttype, a.pagetype, a.level, a.sequence, a.title, a.body, a.revisions, a.created, a.revised FROM page a WHERE a.orgid=? AND a.refid=?")
stmt, err := Db.Preparex("SELECT a.id, a.refid, a.orgid, a.documentid, a.userid, a.contenttype, a.pagetype, a.level, a.sequence, a.title, a.body, a.revisions, a.preset, a.presetid, a.created, a.revised FROM page a WHERE a.orgid=? AND a.refid=?")
defer utility.Close(stmt)
if err != nil {
@ -114,7 +113,7 @@ func (p *Persister) GetPage(pageID string) (page entity.Page, err error) {
func (p *Persister) GetPages(documentID string) (pages []entity.Page, err error) {
err = nil
err = Db.Select(&pages, "SELECT a.id, a.refid, a.orgid, a.documentid, a.userid, a.contenttype, a.pagetype, a.level, a.sequence, a.title, a.body, a.revisions, a.created, a.revised FROM page a WHERE a.orgid=? AND a.documentid=? ORDER BY a.sequence", p.Context.OrgID, documentID)
err = Db.Select(&pages, "SELECT a.id, a.refid, a.orgid, a.documentid, a.userid, a.contenttype, a.pagetype, a.level, a.sequence, a.title, a.body, a.revisions, a.preset, a.presetid, a.created, a.revised FROM page a WHERE a.orgid=? AND a.documentid=? ORDER BY a.sequence", p.Context.OrgID, documentID)
if err != nil {
log.Error(fmt.Sprintf("Unable to execute select pages for org %s and document %s", p.Context.OrgID, documentID), err)
@ -131,7 +130,7 @@ func (p *Persister) GetPagesWhereIn(documentID, inPages string) (pages []entity.
args := []interface{}{p.Context.OrgID, documentID}
tempValues := strings.Split(inPages, ",")
sql := "SELECT a.id, a.refid, a.orgid, a.documentid, a.userid, a.contenttype, a.pagetype, a.level, a.sequence, a.title, a.body, a.revisions, a.created, a.revised FROM page a WHERE a.orgid=? AND a.documentid=? AND a.refid IN (?" + strings.Repeat(",?", len(tempValues)-1) + ") ORDER BY sequence"
sql := "SELECT a.id, a.refid, a.orgid, a.documentid, a.userid, a.contenttype, a.pagetype, a.level, a.sequence, a.title, a.body, a.preset, a.presetid, a.revisions, a.created, a.revised FROM page a WHERE a.orgid=? AND a.documentid=? AND a.refid IN (?" + strings.Repeat(",?", len(tempValues)-1) + ") ORDER BY sequence"
inValues := make([]interface{}, len(tempValues))
@ -181,7 +180,7 @@ func (p *Persister) GetPagesWhereIn(documentID, inPages string) (pages []entity.
// GetPagesWithoutContent returns a slice containing all the page records for a given documentID, in presentation sequence,
// but without the body field (which holds the HTML content).
func (p *Persister) GetPagesWithoutContent(documentID string) (pages []entity.Page, err error) {
err = Db.Select(&pages, "SELECT id, refid, orgid, documentid, userid, contenttype, pagetype, sequence, level, title, revisions, created, revised FROM page WHERE orgid=? AND documentid=? ORDER BY sequence", p.Context.OrgID, documentID)
err = Db.Select(&pages, "SELECT id, refid, orgid, documentid, userid, contenttype, pagetype, sequence, level, title, revisions, preset, presetid, created, revised FROM page WHERE orgid=? AND documentid=? ORDER BY sequence", p.Context.OrgID, documentID)
if err != nil {
log.Error(fmt.Sprintf("Unable to execute select pages for org %s and document %s", p.Context.OrgID, documentID), err)
@ -386,17 +385,17 @@ func (p *Persister) DeletePage(documentID, pageID string) (rows int64, err error
rows, err = p.Base.DeleteConstrained(p.Context.Transaction, "page", p.Context.OrgID, pageID)
if err == nil {
_, err = p.Base.DeleteWhere(p.Context.Transaction, fmt.Sprintf("DELETE FROM pagemeta WHERE orgid='%s' AND pageid='%s'", p.Context.OrgID, pageID))
_, err = searches.Delete(&databaseRequest{OrgID: p.Context.OrgID}, documentID, pageID)
_, _ = p.Base.DeleteWhere(p.Context.Transaction, fmt.Sprintf("DELETE FROM pagemeta WHERE orgid='%s' AND pageid='%s'", p.Context.OrgID, pageID))
_, _ = searches.Delete(&databaseRequest{OrgID: p.Context.OrgID}, documentID, pageID)
// delete content links from this page
_, err = p.DeleteSourcePageLinks(pageID)
_, _ = p.DeleteSourcePageLinks(pageID)
// mark as orphan links to this page
err = p.MarkOrphanPageLink(pageID)
_ = p.MarkOrphanPageLink(pageID)
// nuke revisions
_, err = p.DeletePageRevisions(pageID)
_, _ = p.DeletePageRevisions(pageID)
p.Base.Audit(p.Context, "remove-page", documentID, pageID)
}
@ -508,3 +507,24 @@ func (p *Persister) DeletePageRevisions(pageID string) (rows int64, err error) {
return
}
/********************
* Section templates
********************/
// GetSpaceSectionTemplates returns a slice all saved section templates.
func (p *Persister) GetSpaceSectionTemplates(folderID string) (pages []entity.PageTemplate, err error) {
err = Db.Select(&pages, `SELECT a.id, a.refid, a.orgid, a.documentid, a.userid, a.contenttype, a.pagetype, a.level, a.sequence, a.title, a.body, a.revisions, a.preset, a.presetid, a.created, a.revised, u.firstname, u.lastname
FROM page a
LEFT JOIN document b ON a.documentid = b.refid
LEFT JOIN user u ON a.userid = u.refid
WHERE a.orgid=? AND b.labelid=? AND a.preset=1
ORDER BY a.title`, p.Context.OrgID, folderID)
if err != nil {
log.Error(fmt.Sprintf("Unable to execute GetSpaceSectionTemplates for org %s and space %s", p.Context.OrgID, folderID), err)
return
}
return
}