- FormAfterCreate/FormAfterUpdate run the locale check, then register a purge of kind faq through cooler.PurgeSiteCacheAfterCommit - new FormAfterDelete purges after the delete commits - purgeSiteCache helper takes the save transaction from cabana.TxFromContext and the purger from cooler.SiteCacheFromApp (site_cache.* keys) - TestFaqAdminPurgesSiteCache on Postgres
104 lines
3.5 KiB
Go
104 lines
3.5 KiB
Go
package controllers
|
|
|
|
import (
|
|
"context"
|
|
|
|
"git.golem15.com/golem15/sm-faq-plugin/models"
|
|
translate "git.golem15.com/golem15/sm-translate-plugin/models"
|
|
"git.golem15.com/golem15/summercms/modules/backpack"
|
|
"git.golem15.com/golem15/summercms/modules/cabana"
|
|
"git.golem15.com/golem15/summercms/modules/pact"
|
|
)
|
|
|
|
const (
|
|
// FAQsControllerID is the cabana controller id of the FAQs screen.
|
|
FAQsControllerID = "golem15.faq.faqs"
|
|
// PermissionFAQs is the PHP permission golem15.faq.faqs.
|
|
PermissionFAQs = "golem15.faq.faqs"
|
|
)
|
|
|
|
// faqsAdminController lists and edits FAQs: a name, a slug, the locale, the
|
|
// active switch, a rich text description and the question repeater.
|
|
type faqsAdminController struct {
|
|
app func() *backpack.App
|
|
}
|
|
|
|
func (faqsAdminController) ID() string { return FAQsControllerID }
|
|
|
|
func (faqsAdminController) ModelName() string { return `Golem15\FAQ\Models\FAQ` }
|
|
|
|
func (faqsAdminController) ConfigDir() string { return "controllers/faqs" }
|
|
|
|
func (faqsAdminController) RequiredPermissions() []string {
|
|
return []string{PermissionFAQs}
|
|
}
|
|
|
|
func (faqsAdminController) NewRecord() any { return &models.FAQ{} }
|
|
|
|
// AdminFieldRelations binds the locale field to the translate Locale through
|
|
// locale_id (PHP belongsTo locale).
|
|
func (faqsAdminController) AdminFieldRelations() []cabana.FieldRelationContract {
|
|
return []cabana.FieldRelationContract{{
|
|
Field: "locale",
|
|
Kind: "belongsTo",
|
|
NewRelated: func() any { return &translate.Locale{} },
|
|
ForeignKey: "locale_id",
|
|
}}
|
|
}
|
|
|
|
// errLocaleRequired is the field message of a FAQ saved without a locale.
|
|
const errLocaleRequired = "golem15.faq::lang.errors.locale_required"
|
|
|
|
// siteCacheKind is the kind a FAQ save's site-cache purge carries.
|
|
const siteCacheKind = "faq"
|
|
|
|
// FormAfterCreate refuses a FAQ without a locale. cabana writes locale_id
|
|
// from the relation field after the model rules ran, so the check runs here,
|
|
// inside the save's transaction: the refusal rolls the row back. A FAQ that
|
|
// passes purges the host site's page caches once the save commits.
|
|
func (c faqsAdminController) FormAfterCreate(ctx context.Context, model any) error {
|
|
return c.afterSave(ctx, model)
|
|
}
|
|
|
|
// FormAfterUpdate applies the same check and purge to an update.
|
|
func (c faqsAdminController) FormAfterUpdate(ctx context.Context, model any) error {
|
|
return c.afterSave(ctx, model)
|
|
}
|
|
|
|
// FormAfterDelete purges the host site's page caches once the delete
|
|
// commits.
|
|
func (c faqsAdminController) FormAfterDelete(ctx context.Context, model any) error {
|
|
if faq, ok := model.(*models.FAQ); ok && faq != nil {
|
|
purgeSiteCache(ctx, c.app, siteCacheKind, faq.Slug)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (c faqsAdminController) afterSave(ctx context.Context, model any) error {
|
|
if err := requireLocale(model); err != nil {
|
|
return err
|
|
}
|
|
if faq, ok := model.(*models.FAQ); ok && faq != nil {
|
|
purgeSiteCache(ctx, c.app, siteCacheKind, faq.Slug)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func requireLocale(model any) error {
|
|
faq, ok := model.(*models.FAQ)
|
|
if !ok || faq == nil || faq.LocaleID != 0 {
|
|
return nil
|
|
}
|
|
return &cabana.ValidationError{Details: map[string]any{"locale": []string{errLocaleRequired}}}
|
|
}
|
|
|
|
var (
|
|
_ pact.FormAfterCreate = faqsAdminController{}
|
|
_ pact.FormAfterUpdate = faqsAdminController{}
|
|
_ pact.FormAfterDelete = faqsAdminController{}
|
|
_ pact.AdminController = faqsAdminController{}
|
|
_ pact.AdminPermissioned = faqsAdminController{}
|
|
_ pact.AdminRecordSource = faqsAdminController{}
|
|
_ cabana.FieldRelationProvider = faqsAdminController{}
|
|
)
|