- every write that records history (admin, MCP, batch, import, undo, automatic) queues the framework's site-cache purge (kind seo, slug the address or * for settings and robots.txt) after its commit, once per transaction; a rolled-back write never purges - the record-deleted cleanup and the address tracking of saves outside the admin run in lagoon transactions, so their history purges as well
75 lines
2.2 KiB
Go
75 lines
2.2 KiB
Go
package seo
|
|
|
|
import (
|
|
"context"
|
|
|
|
"git.golem15.com/golem15/sm-seo-plugin/classes"
|
|
"git.golem15.com/golem15/summercms/modules/backpack"
|
|
"git.golem15.com/golem15/summercms/modules/lagoon"
|
|
"git.golem15.com/golem15/summercms/modules/pact"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// listen subscribes to the framework's record events (D-92): a deleted
|
|
// record of a content type loses its SEO entries (kept in history), a
|
|
// created one gets its address snapshot, and an updated one whose address
|
|
// changed gets its 301 after commit (D-18), whoever wrote it: Journal's
|
|
// API, MCP, an import, or an admin form whose SEO tab the administrator
|
|
// does not see. Listener errors are logged by the bus and never fail the
|
|
// write that fired them.
|
|
func (p *Plugin) listen(app *backpack.App) {
|
|
if app == nil || app.Events == nil {
|
|
return
|
|
}
|
|
app.Events.Listen("golem15.seo", func(ctx context.Context, ev *pact.RecordDeleted) error {
|
|
svc := p.Service()
|
|
if svc == nil {
|
|
return nil
|
|
}
|
|
return svc.RecordDeleted(ctx, ev)
|
|
})
|
|
app.Events.Listen("golem15.seo", func(ctx context.Context, ev *pact.RecordSaved) error {
|
|
svc := p.Service()
|
|
if svc == nil || ev == nil {
|
|
return nil
|
|
}
|
|
if ev.Created {
|
|
return svc.RecordCreated(ctx, ev)
|
|
}
|
|
return p.addressesAfterSave(ctx, svc, ev.Model, ev.ID)
|
|
})
|
|
}
|
|
|
|
// addressesAfterSave re-describes a saved record of a content type in a
|
|
// transaction of its own and applies AddressChanged to every locale whose
|
|
// address differs from its entry's URL. After an admin save whose SEO tab
|
|
// already did this, nothing differs and nothing happens.
|
|
func (p *Plugin) addressesAfterSave(ctx context.Context, svc *classes.Service, model, id string) error {
|
|
reg := svc.Registry()
|
|
if reg == nil {
|
|
return nil
|
|
}
|
|
typ, ok := reg.ContentTypeForModel(model)
|
|
if !ok || typ.Content == nil {
|
|
return nil
|
|
}
|
|
db, err := svc.DB(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
// A lagoon transaction, so the history the 301 records purges the site
|
|
// cache after the commit.
|
|
return lagoon.Transaction(ctx, db, func(ctx context.Context, tx *gorm.DB) error {
|
|
changes, err := svc.AddressChanges(ctx, tx, typ, id)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, change := range changes {
|
|
if _, err := svc.AddressChanged(ctx, tx, change); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
})
|
|
}
|