105 lines
3.3 KiB
Go
105 lines
3.3 KiB
Go
// Code generated by summer make. DO NOT EDIT.
|
|
|
|
package models
|
|
|
|
import (
|
|
"strings"
|
|
"time"
|
|
"unicode"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// Quiz is a set of questions a signed-in user can attempt. Context is a
|
|
// free-form link to a record of another plugin, such as "acme.shop:course:12".
|
|
type Quiz struct {
|
|
ID uint `gorm:"column:id;primaryKey"`
|
|
Title string `gorm:"column:title"`
|
|
Slug string `gorm:"column:slug"`
|
|
Description *string `gorm:"column:description"`
|
|
Context *string `gorm:"column:context"`
|
|
IsPublished bool `gorm:"column:is_published"`
|
|
TimeLimitSeconds *int `gorm:"column:time_limit_seconds"`
|
|
PassingScore int `gorm:"column:passing_score"`
|
|
ShuffleQuestions bool `gorm:"column:shuffle_questions"`
|
|
RoundSize *int `gorm:"column:round_size"`
|
|
CreatedAt time.Time `gorm:"column:created_at"`
|
|
UpdatedAt time.Time `gorm:"column:updated_at"`
|
|
Questions []Question `gorm:"foreignKey:QuizID"`
|
|
}
|
|
|
|
// TableName is the plugin-prefixed table.
|
|
func (Quiz) TableName() string { return "golem15_quizzes_quizzes" }
|
|
|
|
// Fillable lists the columns mass assignment may set.
|
|
func (Quiz) Fillable() []string {
|
|
return []string{
|
|
"title", "slug", "description", "context", "is_published",
|
|
"time_limit_seconds", "passing_score", "shuffle_questions", "round_size",
|
|
}
|
|
}
|
|
|
|
// Rules are checked by the admin API on every save; unique ignores the quiz
|
|
// being updated.
|
|
func (Quiz) Rules() map[string]string {
|
|
return map[string]string{
|
|
"title": "required|max:255",
|
|
"slug": "required|max:255|unique:golem15_quizzes_quizzes",
|
|
"context": "nullable|max:255",
|
|
"passing_score": "required|integer|between:0,100",
|
|
"time_limit_seconds": "nullable|integer|min:1",
|
|
"round_size": "nullable|integer|min:1",
|
|
}
|
|
}
|
|
|
|
// BeforeValidate fills the slug from the title before the admin form
|
|
// validates, so the unique rule sees the final slug.
|
|
func (q *Quiz) BeforeValidate(*gorm.DB) error {
|
|
q.fillSlug()
|
|
return nil
|
|
}
|
|
|
|
// BeforeSave fills the slug from the title on every other write path.
|
|
func (q *Quiz) BeforeSave(*gorm.DB) error {
|
|
q.fillSlug()
|
|
return nil
|
|
}
|
|
|
|
func (q *Quiz) fillSlug() {
|
|
if strings.TrimSpace(q.Slug) == "" {
|
|
q.Slug = Slugify(q.Title)
|
|
} else {
|
|
q.Slug = Slugify(q.Slug)
|
|
}
|
|
}
|
|
|
|
var transliterations = map[rune]string{
|
|
'ą': "a", 'ć': "c", 'ę': "e", 'ł': "l", 'ń': "n", 'ó': "o", 'ś': "s", 'ź': "z", 'ż': "z",
|
|
'ä': "a", 'ö': "o", 'ü': "u", 'ß': "ss", 'á': "a", 'é': "e", 'í': "i", 'ú': "u",
|
|
'č': "c", 'ř': "r", 'š': "s", 'ž': "z", 'ě': "e", 'ý': "y", 'à': "a", 'è': "e",
|
|
}
|
|
|
|
// Slugify lowercases s, transliterates common Latin diacritics and joins the
|
|
// remaining letters and digits with single hyphens.
|
|
func Slugify(s string) string {
|
|
var b strings.Builder
|
|
dash := false
|
|
for _, r := range strings.ToLower(strings.TrimSpace(s)) {
|
|
if t, ok := transliterations[r]; ok {
|
|
b.WriteString(t)
|
|
dash = false
|
|
continue
|
|
}
|
|
if (r >= 'a' && r <= 'z') || (r >= '0' && r <= '9') {
|
|
b.WriteRune(r)
|
|
dash = false
|
|
continue
|
|
}
|
|
if (unicode.IsSpace(r) || unicode.IsPunct(r) || unicode.IsSymbol(r)) && b.Len() > 0 && !dash {
|
|
b.WriteByte('-')
|
|
dash = true
|
|
}
|
|
}
|
|
return strings.TrimSuffix(b.String(), "-")
|
|
}
|