Example #1
1
func (publish *Publish) ConfigureQorResource(res resource.Resourcer) {
	if res, ok := res.(*admin.Resource); ok {
		for _, gopath := range strings.Split(os.Getenv("GOPATH"), ":") {
			admin.RegisterViewPath(path.Join(gopath, "src/github.com/qor/qor/publish/views"))
		}
		res.UseTheme("publish")

		if event := res.GetAdmin().GetResource("PublishEvent"); event == nil {
			eventResource := res.GetAdmin().AddResource(&PublishEvent{}, &admin.Config{Invisible: true})
			eventResource.IndexAttrs("Name", "Description", "CreatedAt")
		}

		controller := publishController{publish}
		router := res.GetAdmin().GetRouter()
		router.Get(fmt.Sprintf("/%v/diff/:publish_unique_key", res.ToParam()), controller.Diff)
		router.Get(res.ToParam(), controller.Preview)
		router.Post(res.ToParam(), controller.PublishOrDiscard)

		res.GetAdmin().RegisterFuncMap("publish_unique_key", func(res *admin.Resource, record interface{}, context *admin.Context) string {
			return fmt.Sprintf("%s__%v", res.ToParam(), context.GetDB().NewScope(record).PrimaryKeyValue())
		})

		res.GetAdmin().RegisterFuncMap("is_publish_event_resource", func(res *admin.Resource) bool {
			return IsPublishEvent(res.Value)
		})
	}
}
Example #2
0
func (transition *Transition) ConfigureQorResource(res resource.Resourcer) {
	if res, ok := res.(*admin.Resource); ok {
		if res.GetMeta("State") == nil {
			res.Meta(&admin.Meta{Name: "State", Permission: roles.Allow(roles.Update, "nobody")})
		}
	}
}
Example #3
0
// ConfigureQorResourceBeforeInitialize configure qor resource when initialize qor admin
func (publish *Publish) ConfigureQorResourceBeforeInitialize(res resource.Resourcer) {
	if res, ok := res.(*admin.Resource); ok {
		res.GetAdmin().RegisterViewPath("github.com/qor/publish/views")
		res.UseTheme("publish")

		if event := res.GetAdmin().GetResource("PublishEvent"); event == nil {
			eventResource := res.GetAdmin().AddResource(&PublishEvent{}, &admin.Config{Invisible: true})
			eventResource.IndexAttrs("Name", "Description", "CreatedAt")
		}
	}
}
Example #4
0
func (MediaLibrary) ConfigureQorResource(res resource.Resourcer) {
	if res, ok := res.(*admin.Resource); ok {
		res.UseTheme("grid")
		res.UseTheme("media_library")
		res.IndexAttrs("File")
	}
}
Example #5
0
File: worker.go Project: qor/worker
// ConfigureQorResourceBeforeInitialize a method used to config Worker for qor admin
func (worker *Worker) ConfigureQorResourceBeforeInitialize(res resource.Resourcer) {
	if res, ok := res.(*admin.Resource); ok {
		res.GetAdmin().RegisterViewPath("github.com/qor/worker/views")
		res.UseTheme("worker")

		worker.Admin = res.GetAdmin()
		worker.JobResource = worker.Admin.NewResource(worker.Config.Job)
		worker.JobResource.UseTheme("worker")
		worker.JobResource.Meta(&admin.Meta{Name: "Name", Valuer: func(record interface{}, context *qor.Context) interface{} {
			return record.(QorJobInterface).GetJobName()
		}})
		worker.JobResource.IndexAttrs("ID", "Name", "Status", "CreatedAt")
		worker.JobResource.Name = res.Name

		for _, status := range []string{JobStatusScheduled, JobStatusNew, JobStatusRunning, JobStatusDone, JobStatusException} {
			var status = status
			worker.JobResource.Scope(&admin.Scope{Name: status, Handle: func(db *gorm.DB, ctx *qor.Context) *gorm.DB {
				return db.Where("status = ?", status)
			}})
		}

		// default scope
		worker.JobResource.Scope(&admin.Scope{
			Handle: func(db *gorm.DB, ctx *qor.Context) *gorm.DB {
				if jobName := ctx.Request.URL.Query().Get("job"); jobName != "" {
					return db.Where("kind = ?", jobName)
				}

				if groupName := ctx.Request.URL.Query().Get("group"); groupName != "" {
					var jobNames []string
					for _, job := range worker.Jobs {
						if groupName == job.Group {
							jobNames = append(jobNames, job.Name)
						}
					}
					if len(jobNames) > 0 {
						return db.Where("kind IN (?)", jobNames)
					}
					return db.Where("kind IS NULL")
				}

				return db
			},
			Default: true,
		})

		// Auto Migration
		worker.Admin.Config.DB.AutoMigrate(worker.Config.Job)

		// Configure jobs
		for _, job := range worker.Jobs {
			if job.Resource == nil {
				job.Resource = worker.Admin.NewResource(worker.JobResource.Value)
			}
		}
	}
}
Example #6
0
// ConfigureQorResource configure qor locale for Qor Admin
func (*AssetManager) ConfigureQorResource(res resource.Resourcer) {
	if res, ok := res.(*admin.Resource); ok {
		router := res.GetAdmin().GetRouter()
		router.Post(fmt.Sprintf("/%v/upload", res.ToParam()), func(context *admin.Context) {
			result := AssetManager{}
			result.File.Scan(context.Request.MultipartForm.File["file"])
			context.GetDB().Save(&result)
			bytes, _ := json.Marshal(map[string]string{"filelink": result.File.URL(), "filename": result.File.GetFileName()})
			context.Writer.Write(bytes)
		})

		assetURL := regexp.MustCompile(`^/system/assets/(\d+)/`)
		router.Post(fmt.Sprintf("/%v/crop", res.ToParam()), func(context *admin.Context) {
			defer context.Request.Body.Close()
			var (
				err error
				url struct{ URL string }
				buf bytes.Buffer
			)

			io.Copy(&buf, context.Request.Body)
			if err = json.Unmarshal(buf.Bytes(), &url); err == nil {
				if matches := assetURL.FindStringSubmatch(url.URL); len(matches) > 1 {
					result := &AssetManager{}
					if err = context.GetDB().Find(result, matches[1]).Error; err == nil {
						if err = result.File.Scan(buf.Bytes()); err == nil {
							if err = context.GetDB().Save(result).Error; err == nil {
								bytes, _ := json.Marshal(map[string]string{"url": result.File.URL(), "filename": result.File.GetFileName()})
								context.Writer.Write(bytes)
								return
							}
						}
					}
				}
			}

			bytes, _ := json.Marshal(map[string]string{"err": err.Error()})
			context.Writer.Write(bytes)
		})
	}
}
Example #7
0
File: i18n.go Project: qor/i18n
// ConfigureQorResource configure qor resource for qor admin
func (i18n *I18n) ConfigureQorResource(res resource.Resourcer) {
	if res, ok := res.(*admin.Resource); ok {
		i18n.Resource = res
		res.UseTheme("i18n")
		res.GetAdmin().I18n = i18n
		res.SearchAttrs("value") // generate search handler for i18n

		var getPrimaryLocale = func(context *admin.Context) string {
			if locale := context.Request.Form.Get("primary_locale"); locale != "" {
				return locale
			}
			if availableLocales := getAvailableLocales(context.Request, context.CurrentUser); len(availableLocales) > 0 {
				return availableLocales[0]
			}
			return ""
		}

		var getEditingLocale = func(context *admin.Context) string {
			if locale := context.Request.Form.Get("to_locale"); locale != "" {
				return locale
			}
			return getLocaleFromContext(context.Context)
		}

		type matchedTranslation struct {
			Key           string
			PrimaryLocale string
			PrimaryValue  string
			EditingLocale string
			EditingValue  string
		}

		res.GetAdmin().RegisterFuncMap("i18n_available_translations", func(context *admin.Context) (results []matchedTranslation) {
			var (
				translationsMap     = i18n.LoadTranslations()
				matchedTranslations = map[string]matchedTranslation{}
				keys                = []string{}
				keyword             = strings.ToLower(context.Request.URL.Query().Get("keyword"))
				primaryLocale       = getPrimaryLocale(context)
				editingLocale       = getEditingLocale(context)
			)

			var filterTranslations = func(translations map[string]*Translation, isPrimary bool) {
				if translations != nil {
					for key, translation := range translations {
						if (keyword == "") || (strings.Index(strings.ToLower(translation.Key), keyword) != -1 ||
							strings.Index(strings.ToLower(translation.Value), keyword) != -1) {
							if _, ok := matchedTranslations[key]; !ok {
								var t = matchedTranslation{
									Key:           key,
									PrimaryLocale: primaryLocale,
									EditingLocale: editingLocale,
									EditingValue:  translation.Value,
								}

								if localeTranslations, ok := translationsMap[primaryLocale]; ok {
									if v, ok := localeTranslations[key]; ok {
										t.PrimaryValue = v.Value
									}
								}

								matchedTranslations[key] = t
								keys = append(keys, key)
							}
						}
					}
				}
			}

			filterTranslations(translationsMap[getEditingLocale(context)], false)
			if primaryLocale != editingLocale {
				filterTranslations(translationsMap[getPrimaryLocale(context)], true)
			}

			sort.Strings(keys)

			pagination := context.Searcher.Pagination
			pagination.Total = len(keys)
			pagination.PerPage = 25
			pagination.CurrentPage, _ = strconv.Atoi(context.Request.URL.Query().Get("page"))
			if pagination.CurrentPage == 0 {
				pagination.CurrentPage = 1
			}
			if pagination.CurrentPage > 0 {
				pagination.Pages = pagination.Total / pagination.PerPage
			}
			context.Searcher.Pagination = pagination

			var paginationKeys []string
			if pagination.CurrentPage == -1 {
				paginationKeys = keys
			} else {
				lastIndex := pagination.CurrentPage * pagination.PerPage
				if pagination.Total < lastIndex {
					lastIndex = pagination.Total
				}

				startIndex := (pagination.CurrentPage - 1) * pagination.PerPage
				if lastIndex >= startIndex {
					paginationKeys = keys[startIndex:lastIndex]
				}
			}

			for _, key := range paginationKeys {
				results = append(results, matchedTranslations[key])
			}
			return results
		})

		res.GetAdmin().RegisterFuncMap("i18n_primary_locale", getPrimaryLocale)

		res.GetAdmin().RegisterFuncMap("i18n_editing_locale", getEditingLocale)

		res.GetAdmin().RegisterFuncMap("i18n_viewable_locales", func(context admin.Context) []string {
			return getAvailableLocales(context.Request, context.CurrentUser)
		})

		res.GetAdmin().RegisterFuncMap("i18n_editable_locales", func(context admin.Context) []string {
			return getEditableLocales(context.Request, context.CurrentUser)
		})

		controller := i18nController{i18n}
		router := res.GetAdmin().GetRouter()
		router.Get(res.ToParam(), controller.Index)
		router.Post(res.ToParam(), controller.Update)
		router.Put(res.ToParam(), controller.Update)

		res.GetAdmin().RegisterViewPath("github.com/qor/i18n/views")
	}
}
Example #8
0
// ConfigureQorResource used to configure transition for qor admin
func (transition *Transition) ConfigureQorResource(res resource.Resourcer) {
	if res, ok := res.(*admin.Resource); ok {
		if res.GetMeta("State") == nil {
			res.Meta(&admin.Meta{Name: "State", Permission: roles.Deny(roles.Update, roles.Anyone).Deny(roles.Create, roles.Anyone)})
		}

		res.IndexAttrs(res.IndexAttrs(), "-StateChangeLogs")
		res.ShowAttrs(res.ShowAttrs(), "-StateChangeLogs", false)
		res.NewAttrs(res.NewAttrs(), "-StateChangeLogs")
		res.EditAttrs(res.EditAttrs(), "-StateChangeLogs")
	}
}
Example #9
0
func (s Status) ConfigureQorResource(res resource.Resourcer) {
	if res, ok := res.(*admin.Resource); ok {
		if res.GetMeta("PublishStatus") == nil {
			res.IndexAttrs(res.IndexAttrs(), "-PublishStatus")
			res.NewAttrs(res.NewAttrs(), "-PublishStatus")
			res.EditAttrs(res.EditAttrs(), "-PublishStatus")
			res.ShowAttrs(res.ShowAttrs(), "-PublishStatus", false)
		}
	}
}
Example #10
0
func (i18n *I18n) ConfigureQorResource(res resource.Resourcer) {
	if res, ok := res.(*admin.Resource); ok {
		res.UseTheme("i18n")
		res.GetAdmin().I18n = i18n
		res.SearchAttrs("value") // generate search handler for i18n

		res.GetAdmin().RegisterFuncMap("lt", func(locale, key string, withDefault bool) string {
			if translations := i18n.Translations[locale]; translations != nil {
				if t := translations[key]; t != nil && t.Value != "" {
					return t.Value
				}
			}

			if withDefault {
				if translations := i18n.Translations[Default]; translations != nil {
					if t := translations[key]; t != nil {
						return t.Value
					}
				}
			}

			return ""
		})

		res.GetAdmin().RegisterFuncMap("i18n_available_keys", func(context *admin.Context) (keys []string) {
			translations := i18n.Translations[Default]
			if translations == nil {
				for _, values := range i18n.Translations {
					translations = values
					break
				}
			}

			keyword := context.Request.URL.Query().Get("keyword")

			for key, translation := range translations {
				if (keyword == "") || (strings.Index(strings.ToLower(translation.Key), strings.ToLower(keyword)) != -1 ||
					strings.Index(strings.ToLower(translation.Value), keyword) != -1) {
					keys = append(keys, key)
				}
			}

			sort.Strings(keys)

			pagination := context.Searcher.Pagination
			pagination.Total = len(keys)
			pagination.PrePage = 25
			pagination.CurrentPage, _ = strconv.Atoi(context.Request.URL.Query().Get("page"))
			if pagination.CurrentPage == 0 {
				pagination.CurrentPage = 1
			}
			if pagination.CurrentPage > 0 {
				pagination.Pages = pagination.Total / pagination.PrePage
			}
			context.Searcher.Pagination = pagination

			if pagination.CurrentPage == -1 {
				return keys
			}

			lastIndex := pagination.CurrentPage * pagination.PrePage
			if pagination.Total < lastIndex {
				lastIndex = pagination.Total
			}

			return keys[(pagination.CurrentPage-1)*pagination.PrePage : lastIndex]
		})

		res.GetAdmin().RegisterFuncMap("i18n_primary_locale", func(context admin.Context) string {
			if locale := context.Request.Form.Get("primary_locale"); locale != "" {
				return locale
			}
			if availableLocales := getAvailableLocales(context.Request, context.CurrentUser); len(availableLocales) > 0 {
				return availableLocales[0]
			}
			return ""
		})

		res.GetAdmin().RegisterFuncMap("i18n_editing_locale", func(context admin.Context) string {
			if locale := context.Request.Form.Get("to_locale"); locale != "" {
				return locale
			}
			return getLocaleFromContext(context.Context)
		})

		res.GetAdmin().RegisterFuncMap("i18n_viewable_locales", func(context admin.Context) []string {
			return getAvailableLocales(context.Request, context.CurrentUser)
		})

		res.GetAdmin().RegisterFuncMap("i18n_editable_locales", func(context admin.Context) []string {
			return getEditableLocales(context.Request, context.CurrentUser)
		})

		controller := i18nController{i18n}
		router := res.GetAdmin().GetRouter()
		router.Get(res.ToParam(), controller.Index)
		router.Post(res.ToParam(), controller.Update)
		router.Put(res.ToParam(), controller.Update)

		for _, gopath := range strings.Split(os.Getenv("GOPATH"), ":") {
			admin.RegisterViewPath(path.Join(gopath, "src/github.com/qor/qor/i18n/views"))
		}
	}
}
func (serialize *SerializableMeta) ConfigureQorResourceBeforeInitialize(res resource.Resourcer) {
	if res, ok := res.(*admin.Resource); ok {
		for _, gopath := range strings.Split(os.Getenv("GOPATH"), ":") {
			admin.RegisterViewPath(path.Join(gopath, "src/github.com/qor/serializable_meta/views"))
		}

		if _, ok := res.Value.(SerializableMetaInterface); ok {
			if res.GetMeta("Kind") == nil {
				res.Meta(&admin.Meta{
					Name: "Kind",
					Type: "hidden",
					Valuer: func(value interface{}, context *qor.Context) interface{} {
						if context.GetDB().NewScope(value).PrimaryKeyZero() {
							return nil
						} else {
							return value.(SerializableMetaInterface).GetSerializableArgumentKind()
						}
					},
				})
			}

			if res.GetMeta("SerializableMeta") == nil {
				res.Meta(&admin.Meta{
					Name: "SerializableMeta",
					Type: "serializable_meta",
					Valuer: func(value interface{}, context *qor.Context) interface{} {
						if serializeArgument, ok := value.(SerializableMetaInterface); ok {
							return struct {
								Value    interface{}
								Resource *admin.Resource
							}{
								Value:    serializeArgument.GetSerializableArgument(serializeArgument),
								Resource: serializeArgument.GetSerializableArgumentResource(),
							}
						}
						return nil
					},
					Setter: func(result interface{}, metaValue *resource.MetaValue, context *qor.Context) {
						if serializeArgument, ok := result.(SerializableMetaInterface); ok {
							serializeArgumentResource := serializeArgument.GetSerializableArgumentResource()
							value := serializeArgumentResource.NewStruct()

							for _, meta := range serializeArgumentResource.GetMetas([]string{}) {
								for _, metaValue := range metaValue.MetaValues.Values {
									if meta.GetName() == metaValue.Name {
										if setter := meta.GetSetter(); setter != nil {
											setter(value, metaValue, context)
										}
									}
								}
							}

							serializeArgument.SetSerializableArgumentValue(value)
						}
					},
				})
			}

			res.NewAttrs("Kind", "SerializableMeta")
			res.EditAttrs("ID", "Kind", "SerializableMeta")
		}
	}
}
Example #12
0
File: worker.go Project: qor/worker
// ConfigureQorResource a method used to config Worker for qor admin
func (worker *Worker) ConfigureQorResource(res resource.Resourcer) {
	if res, ok := res.(*admin.Resource); ok {
		// Parse job
		cmdLine := flag.NewFlagSet(os.Args[0], flag.ContinueOnError)
		qorJobID := cmdLine.String("qor-job", "", "Qor Job ID")
		runAnother := cmdLine.Bool("run-another", false, "Run another qor job")
		cmdLine.Parse(os.Args[1:])

		if *qorJobID != "" {
			if *runAnother == true {
				if newJob := worker.saveAnotherJob(*qorJobID); newJob != nil {
					newJobID := newJob.GetJobID()
					qorJobID = &newJobID
				} else {
					fmt.Println("failed to clone job " + *qorJobID)
					os.Exit(1)
				}
			}

			if err := worker.RunJob(*qorJobID); err == nil {
				os.Exit(0)
			} else {
				fmt.Println(err)
				os.Exit(1)
			}
		}

		// register view funcmaps
		worker.Admin.RegisterFuncMap("get_grouped_jobs", func(context *admin.Context) map[string][]*Job {
			var groupedJobs = map[string][]*Job{}
			var groupName = context.Request.URL.Query().Get("group")
			var jobName = context.Request.URL.Query().Get("job")
			for _, job := range worker.Jobs {
				if !(job.HasPermission(roles.Read, context.Context) && job.HasPermission(roles.Create, context.Context)) {
					continue
				}

				if (groupName == "" || groupName == job.Group) && (jobName == "" || jobName == job.Name) {
					groupedJobs[job.Group] = append(groupedJobs[job.Group], job)
				}
			}
			return groupedJobs
		})

		// configure routes
		router := worker.Admin.GetRouter()
		controller := workerController{Worker: worker}
		jobParamIDName := worker.JobResource.ParamIDName()
		router.Get(res.ToParam(), controller.Index)
		router.Get(res.ToParam()+"/new", controller.New)
		router.Get(fmt.Sprintf("%v/%v", res.ToParam(), jobParamIDName), controller.Show)
		router.Get(fmt.Sprintf("%v/%v/edit", res.ToParam(), jobParamIDName), controller.Show)
		router.Post(fmt.Sprintf("%v/%v/run", res.ToParam(), jobParamIDName), controller.RunJob)
		router.Post(res.ToParam(), controller.AddJob)
		router.Put(fmt.Sprintf("%v/%v", res.ToParam(), jobParamIDName), controller.Update)
		router.Delete(fmt.Sprintf("%v/%v", res.ToParam(), jobParamIDName), controller.KillJob)
	}
}
Example #13
0
// ConfigureQorResource configure sorting for qor admin
func (s *Sorting) ConfigureQorResource(res resource.Resourcer) {
	if res, ok := res.(*admin.Resource); ok {
		Admin := res.GetAdmin()
		res.UseTheme("sorting")

		if res.Config.Permission == nil {
			res.Config.Permission = roles.NewPermission()
		}

		for _, gopath := range strings.Split(os.Getenv("GOPATH"), ":") {
			admin.RegisterViewPath(path.Join(gopath, "src/github.com/qor/sorting/views"))
		}

		role := res.Config.Permission.Role
		if _, ok := role.Get("sorting_mode"); !ok {
			role.Register("sorting_mode", func(req *http.Request, currentUser interface{}) bool {
				return req.URL.Query().Get("sorting") != ""
			})
		}

		if res.GetMeta("Position") == nil {
			res.Meta(&admin.Meta{
				Name: "Position",
				Valuer: func(value interface{}, ctx *qor.Context) interface{} {
					db := ctx.GetDB()
					var count int
					var pos = value.(sortingInterface).GetPosition()

					if _, ok := modelValue(value).(sortingDescInterface); ok {
						if total, ok := db.Get("sorting_total_count"); ok {
							count = total.(int)
						} else {
							var result = res.NewStruct()
							db.New().Order("position DESC", true).First(result)
							count = result.(sortingInterface).GetPosition()
							db.InstantSet("sorting_total_count", count)
						}
						pos = count - pos + 1
					}

					primaryKey := ctx.GetDB().NewScope(value).PrimaryKeyValue()
					url := path.Join(ctx.Request.URL.Path, fmt.Sprintf("%v", primaryKey), "sorting/update_position")
					return template.HTML(fmt.Sprintf("<input type=\"number\" class=\"qor-sorting__position\" value=\"%v\" data-sorting-url=\"%v\" data-position=\"%v\">", pos, url, pos))
				},
				Permission: roles.Allow(roles.Read, "sorting_mode"),
			})
		}

		attrs := res.ConvertSectionToStrings(res.IndexAttrs())
		for _, attr := range attrs {
			if attr != "Position" {
				attrs = append(attrs, attr)
			}
		}
		res.IndexAttrs(res.IndexAttrs(), "Position")
		res.NewAttrs(res.NewAttrs(), "-Position")
		res.EditAttrs(res.EditAttrs(), "-Position")
		res.ShowAttrs(res.ShowAttrs(), "-Position", false)

		router := Admin.GetRouter()
		router.Post(fmt.Sprintf("/%v/%v/sorting/update_position", res.ToParam(), res.ParamIDName()), updatePosition)
	}
}
// ConfigureQorResourceBeforeInitialize configure qor resource for qor admin
func (serialize *SerializableMeta) ConfigureQorResourceBeforeInitialize(res resource.Resourcer) {
	if res, ok := res.(*admin.Resource); ok {
		res.GetAdmin().RegisterViewPath("github.com/qor/serializable_meta/views")

		if _, ok := res.Value.(SerializableMetaInterface); ok {
			if res.GetMeta("Kind") == nil {
				res.Meta(&admin.Meta{
					Name: "Kind",
					Type: "hidden",
					Valuer: func(value interface{}, context *qor.Context) interface{} {
						defer func() {
							if r := recover(); r != nil {
								utils.ExitWithMsg("SerializableMeta: Can't Get Kind")
							}
						}()

						return value.(SerializableMetaInterface).GetSerializableArgumentKind()
					},
					Setter: func(value interface{}, metaValue *resource.MetaValue, context *qor.Context) {
						value.(SerializableMetaInterface).SetSerializableArgumentKind(utils.ToString(metaValue.Value))
					},
				})
			}

			if res.GetMeta("SerializableMeta") == nil {
				res.Meta(&admin.Meta{
					Name: "SerializableMeta",
					Type: "serializable_meta",
					Valuer: func(value interface{}, context *qor.Context) interface{} {
						if serializeArgument, ok := value.(SerializableMetaInterface); ok {
							return struct {
								Value    interface{}
								Resource *admin.Resource
							}{
								Value:    serializeArgument.GetSerializableArgument(serializeArgument),
								Resource: serializeArgument.GetSerializableArgumentResource(),
							}
						}
						return nil
					},
					FormattedValuer: func(value interface{}, context *qor.Context) interface{} {
						if serializeArgument, ok := value.(SerializableMetaInterface); ok {
							return serializeArgument.GetSerializableArgument(serializeArgument)
						}
						return nil
					},
					Setter: func(result interface{}, metaValue *resource.MetaValue, context *qor.Context) {
						if serializeArgument, ok := result.(SerializableMetaInterface); ok {
							if serializeArgumentResource := serializeArgument.GetSerializableArgumentResource(); serializeArgumentResource != nil {
								var clearUpRecord, fillUpRecord func(record interface{}, metaors []resource.Metaor, metaValues []*resource.MetaValue)
								// Keep original value, so if user don't have permission to update some fields, we won't lost the data
								value := serializeArgument.GetSerializableArgument(serializeArgument)

								for _, fc := range serializeArgumentResource.Validators {
									context.AddError(fc(value, metaValue.MetaValues, context))
								}

								// Clear all nested slices if has related form data
								clearUpRecord = func(record interface{}, metaors []resource.Metaor, metaValues []*resource.MetaValue) {
									for _, meta := range metaors {
										for _, metaValue := range metaValues {
											if meta.GetName() == metaValue.Name {
												if metaResource, ok := meta.GetResource().(*admin.Resource); ok && metaResource != nil && metaValue.MetaValues != nil {
													nestedFieldValue := reflect.Indirect(reflect.ValueOf(record)).FieldByName(meta.GetFieldName())
													if nestedFieldValue.Kind() == reflect.Struct {
														clearUpRecord(nestedFieldValue.Addr().Interface(), metaResource.GetMetas([]string{}), metaValue.MetaValues.Values)
													} else if nestedFieldValue.Kind() == reflect.Slice {
														nestedFieldValue.Set(reflect.Zero(nestedFieldValue.Type()))
													}
												}
											}
										}
									}
								}
								clearUpRecord(value, serializeArgumentResource.GetMetas([]string{}), metaValue.MetaValues.Values)

								fillUpRecord = func(record interface{}, metaors []resource.Metaor, metaValues []*resource.MetaValue) {
									for _, meta := range metaors {
										for _, metaValue := range metaValues {
											if meta.GetName() == metaValue.Name {
												if metaResource, ok := meta.GetResource().(*admin.Resource); ok && metaResource != nil && metaValue.MetaValues != nil {
													nestedFieldValue := reflect.Indirect(reflect.ValueOf(record)).FieldByName(meta.GetFieldName())

													if nestedFieldValue.Kind() == reflect.Struct {
														nestedValue := nestedFieldValue.Addr().Interface()
														for _, fc := range metaResource.Validators {
															context.AddError(fc(nestedValue, metaValue.MetaValues, context))
														}

														fillUpRecord(nestedValue, metaResource.GetMetas([]string{}), metaValue.MetaValues.Values)

														for _, fc := range metaResource.Processors {
															context.AddError(fc(nestedValue, metaValue.MetaValues, context))
														}
													}

													if nestedFieldValue.Kind() == reflect.Slice {
														nestedValue := reflect.New(nestedFieldValue.Type().Elem())

														for _, fc := range metaResource.Validators {
															context.AddError(fc(nestedValue, metaValue.MetaValues, context))
														}

														if destroy := metaValue.MetaValues.Get("_destroy"); destroy == nil || fmt.Sprint(destroy.Value) == "0" {
															fillUpRecord(nestedValue.Interface(), metaResource.GetMetas([]string{}), metaValue.MetaValues.Values)
															if !reflect.DeepEqual(reflect.Zero(nestedFieldValue.Type().Elem()).Interface(), nestedValue.Elem().Interface()) {
																nestedFieldValue.Set(reflect.Append(nestedFieldValue, nestedValue.Elem()))

																for _, fc := range metaResource.Processors {
																	context.AddError(fc(nestedValue, metaValue.MetaValues, context))
																}
															}
														}
													}
													continue
												}

												if setter := meta.GetSetter(); setter != nil {
													setter(record, metaValue, context)
													continue
												}
											}
										}
									}
								}

								fillUpRecord(value, serializeArgumentResource.GetMetas([]string{}), metaValue.MetaValues.Values)

								for _, fc := range serializeArgumentResource.Processors {
									context.AddError(fc(value, metaValue.MetaValues, context))
								}
								serializeArgument.SetSerializableArgumentValue(value)
							}
						}
					},
				})
			}

			res.NewAttrs("Kind", "SerializableMeta")
			res.EditAttrs("ID", "Kind", "SerializableMeta")
		}
	}
}
Example #15
0
// ConfigureQorResource configure qor resource for qor admin
func (publish *Publish) ConfigureQorResource(res resource.Resourcer) {
	if res, ok := res.(*admin.Resource); ok {
		controller := publishController{publish}
		router := res.GetAdmin().GetRouter()
		router.Get(fmt.Sprintf("/%v/diff/:publish_unique_key", res.ToParam()), controller.Diff)
		router.Get(res.ToParam(), controller.Preview)
		router.Post(res.ToParam(), controller.PublishOrDiscard)

		res.GetAdmin().RegisterFuncMap("publish_unique_key", func(res *admin.Resource, record interface{}, context *admin.Context) string {
			var publishKeys = []string{res.ToParam()}
			var scope = publish.DB.NewScope(record)
			for _, primaryField := range scope.PrimaryFields() {
				publishKeys = append(publishKeys, fmt.Sprint(primaryField.Field.Interface()))
			}
			return strings.Join(publishKeys, "__")
		})

		res.GetAdmin().RegisterFuncMap("is_publish_event_resource", func(res *admin.Resource) bool {
			return IsPublishEvent(res.Value)
		})
	}
}