package views import ( "reflect" "github.com/qor5/admin/activity" "github.com/qor5/admin/presets" "github.com/qor5/admin/presets/actions" "github.com/qor5/admin/publish" "github.com/qor5/web" "github.com/qor5/x/i18n" "github.com/sunfmin/reflectutils" "gorm.io/gorm" ) const ( PublishEvent = "publish_PublishEvent" RepublishEvent = "publish_RepublishEvent" UnpublishEvent = "publish_UnpublishEvent" switchVersionEvent = "publish_SwitchVersionEvent" SaveNewVersionEvent = "publish_SaveNewVersionEvent" DuplicateVersionEvent = "publish_DuplicateVersionEvent" renameVersionEvent = "publish_RenameVersionEvent" selectVersionsEvent = "publish_SelectVersionsEvent" afterDeleteVersionEvent = "publish_AfterDeleteVersionEvent" ActivityPublish = "Publish" ActivityRepublish = "Republish" ActivityUnPublish = "UnPublish" ParamScriptAfterPublish = "publish_param_script_after_publish" ) func registerEventFuncs(db *gorm.DB, mb *presets.ModelBuilder, publisher *publish.Builder, ab *activity.ActivityBuilder) { mb.RegisterEventFunc(PublishEvent, publishAction(db, mb, publisher, ab, ActivityPublish)) mb.RegisterEventFunc(RepublishEvent, publishAction(db, mb, publisher, ab, ActivityRepublish)) mb.RegisterEventFunc(UnpublishEvent, unpublishAction(db, mb, publisher, ab, ActivityUnPublish)) mb.RegisterEventFunc(switchVersionEvent, switchVersionAction(db, mb, publisher)) mb.RegisterEventFunc(SaveNewVersionEvent, saveNewVersionAction(db, mb, publisher)) mb.RegisterEventFunc(DuplicateVersionEvent, duplicateVersionAction(db, mb, publisher)) mb.RegisterEventFunc(renameVersionEvent, renameVersionAction(db, mb, publisher, ab, ActivityUnPublish)) mb.RegisterEventFunc(selectVersionsEvent, selectVersionsAction(db, mb, publisher, ab, ActivityUnPublish)) mb.RegisterEventFunc(afterDeleteVersionEvent, afterDeleteVersionAction(db, mb, publisher)) } func publishAction(db *gorm.DB, mb *presets.ModelBuilder, publisher *publish.Builder, ab *activity.ActivityBuilder, actionName string) web.EventFunc { return func(ctx *web.EventContext) (r web.EventResponse, err error) { paramID := ctx.R.FormValue(presets.ParamID) obj := mb.NewModel() obj, err = mb.Editing().Fetcher(obj, paramID, ctx) if err != nil { return } publisher.WithEventContext(ctx) err = publisher.Publish(obj) if err != nil { return } if ab != nil { if _, exist := ab.GetModelBuilder(obj); exist { ab.AddCustomizedRecord(actionName, false, ctx.R.Context(), obj) } } if script := ctx.R.FormValue(ParamScriptAfterPublish); script != "" { web.AppendVarsScripts(&r, script) } else { presets.ShowMessage(&r, "success", "") r.Reload = true } return } } func unpublishAction(db *gorm.DB, mb *presets.ModelBuilder, publisher *publish.Builder, ab *activity.ActivityBuilder, actionName string) web.EventFunc { return func(ctx *web.EventContext) (r web.EventResponse, err error) { paramID := ctx.R.FormValue(presets.ParamID) obj := mb.NewModel() obj, err = mb.Editing().Fetcher(obj, paramID, ctx) if err != nil { return } err = publisher.UnPublish(obj) if err != nil { return } if ab != nil { if _, exist := ab.GetModelBuilder(obj); exist { ab.AddCustomizedRecord(actionName, false, ctx.R.Context(), obj) } } presets.ShowMessage(&r, "success", "") r.Reload = true return } } func renameVersionAction(db *gorm.DB, mb *presets.ModelBuilder, publisher *publish.Builder, ab *activity.ActivityBuilder, actionName string) web.EventFunc { return func(ctx *web.EventContext) (r web.EventResponse, err error) { paramID := ctx.R.FormValue(presets.ParamID) obj := mb.NewModel() obj, err = mb.Editing().Fetcher(obj, paramID, ctx) if err != nil { return } name := ctx.R.FormValue("name") if err = reflectutils.Set(obj, "Version.VersionName", name); err != nil { return } if err = mb.Editing().Saver(obj, paramID, ctx); err != nil { return } msgr := i18n.MustGetModuleMessages(ctx.R, I18nPublishKey, Messages_en_US).(*Messages) presets.ShowMessage(&r, msgr.SuccessfullyRename, "") return } } func selectVersionsAction(db *gorm.DB, mb *presets.ModelBuilder, publisher *publish.Builder, ab *activity.ActivityBuilder, actionName string) web.EventFunc { return func(ctx *web.EventContext) (r web.EventResponse, err error) { var ( msgr = i18n.MustGetModuleMessages(ctx.R, I18nPublishKey, Messages_en_US).(*Messages) ) table, _, err := versionListTable(db, mb, msgr, ctx) if err != nil { return } r.UpdatePortals = append(r.UpdatePortals, &web.PortalUpdate{ Name: "versions-list", Body: table, }) return } } func afterDeleteVersionAction(db *gorm.DB, mb *presets.ModelBuilder, publisher *publish.Builder) web.EventFunc { return func(ctx *web.EventContext) (r web.EventResponse, err error) { qs := ctx.Queries() cs := mb.NewModel().(presets.SlugDecoder).PrimaryColumnValuesBySlug(ctx.R.FormValue("id")) deletedVersion := cs["version"] deletedID := qs.Get("id") currentSelectedID := qs.Get("current_selected_id") // switching version is one of the following in order that exists: // 1. current selected version // 2. next(older) version // 3. prev(newer) version switchingVersion := currentSelectedID if deletedID == currentSelectedID { versions, _ := findVersionItems(db, mb, ctx, deletedID) vO := reflect.ValueOf(versions).Elem() if vO.Len() == 0 { r.Reload = true return } version := vO.Index(0).Interface() if vO.Len() > 1 { hasOlderVersion := false for i := 0; i < vO.Len(); i++ { v := vO.Index(i).Interface() if v.(publish.VersionInterface).GetVersion() < deletedVersion { hasOlderVersion = true version = v break } } if !hasOlderVersion { version = vO.Index(vO.Len() - 1) } } switchingVersion = version.(presets.SlugEncoder).PrimarySlug() } web.AppendVarsScripts(&r, web.Plaid(). EventFunc(switchVersionEvent). Query(presets.ParamID, switchingVersion). Query("selected", qs.Get("selected")). Query("page", qs.Get("page")). Query("no_msg", true). Go(), web.Plaid(). EventFunc(actions.ReloadList). Go(), ) return } }