- the RecordSaved listener re-describes an updated record of a content type after commit and applies AddressChanged per changed locale, so Journal's API, MCP and imports get the 301 too; an admin save that already applied it changes nothing more
72 lines
2.1 KiB
Go
72 lines
2.1 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/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
|
|
}
|
|
return db.Transaction(func(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
|
|
})
|
|
}
|