b8146ae485
Add minimum quotas for users to earn the ability to create custom forums. The entry requirements that could earn the first forum include: 1. Having a Certified account status for at least 45 days. 2. Having written 10 posts or replies in the forums. Additional quota is granted in increasing difficulty based on the count of forum posts created. Other changes: * Admin view of Manage Forums can filter for official/community. * "Certified Since" now shown on profile pages. * Update FAQ page for Forums feature.
113 lines
3.1 KiB
Go
113 lines
3.1 KiB
Go
package models
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"time"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// CertificationPhoto table.
|
|
type CertificationPhoto struct {
|
|
ID uint64 `gorm:"primaryKey"`
|
|
UserID uint64 `gorm:"uniqueIndex"`
|
|
Filename string
|
|
Filesize int64
|
|
Status CertificationPhotoStatus
|
|
AdminComment string
|
|
SecondaryNeeded bool // a secondary form of ID has been requested
|
|
SecondaryFilename string // photo ID upload
|
|
SecondaryVerified bool // mark true when ID checked so original can be deleted
|
|
IPAddress string // the IP they uploaded the photo from
|
|
CreatedAt time.Time
|
|
UpdatedAt time.Time
|
|
}
|
|
|
|
type CertificationPhotoStatus string
|
|
|
|
const (
|
|
CertificationPhotoNeeded CertificationPhotoStatus = "needed"
|
|
CertificationPhotoPending CertificationPhotoStatus = "pending"
|
|
CertificationPhotoApproved CertificationPhotoStatus = "approved"
|
|
CertificationPhotoRejected CertificationPhotoStatus = "rejected"
|
|
|
|
// If a photo is pending approval but the admin wants to engage the
|
|
// secondary check (prompt user for a photo ID upload)
|
|
CertificationPhotoSecondary CertificationPhotoStatus = "secondary"
|
|
)
|
|
|
|
// GetCertificationPhoto retrieves the user's record from the DB or upserts their initial record.
|
|
func GetCertificationPhoto(userID uint64) (*CertificationPhoto, error) {
|
|
p := &CertificationPhoto{}
|
|
result := DB.Where("user_id = ?", userID).First(&p)
|
|
if result.Error == gorm.ErrRecordNotFound {
|
|
p = &CertificationPhoto{
|
|
UserID: userID,
|
|
Status: CertificationPhotoNeeded,
|
|
}
|
|
result = DB.Create(p)
|
|
return p, result.Error
|
|
}
|
|
return p, result.Error
|
|
}
|
|
|
|
// CertifiedSince retrieve's the last updated date of the user's certification photo, if approved.
|
|
//
|
|
// This incurs a DB query for their cert photo.
|
|
func (u *User) CertifiedSince() (time.Time, error) {
|
|
if !u.Certified {
|
|
return time.Time{}, errors.New("user is not certified")
|
|
}
|
|
|
|
cert, err := GetCertificationPhoto(u.ID)
|
|
if err != nil {
|
|
return time.Time{}, err
|
|
}
|
|
|
|
if cert.Status != CertificationPhotoApproved {
|
|
return time.Time{}, fmt.Errorf("cert photo status is: %s (expected 'approved')", cert.Status)
|
|
}
|
|
|
|
return cert.UpdatedAt, nil
|
|
}
|
|
|
|
// CertificationPhotosNeedingApproval returns a pager of the pictures that require admin approval.
|
|
func CertificationPhotosNeedingApproval(status CertificationPhotoStatus, pager *Pagination) ([]*CertificationPhoto, error) {
|
|
var p = []*CertificationPhoto{}
|
|
|
|
query := DB.Where(
|
|
"status = ?",
|
|
status,
|
|
).Order(
|
|
pager.Sort,
|
|
)
|
|
|
|
// Get the total count.
|
|
query.Model(&CertificationPhoto{}).Count(&pager.Total)
|
|
|
|
result := query.Offset(
|
|
pager.GetOffset(),
|
|
).Limit(pager.PerPage).Find(&p)
|
|
|
|
return p, result.Error
|
|
}
|
|
|
|
// CountCertificationPhotosNeedingApproval gets the count of pending photos for admin alert.
|
|
func CountCertificationPhotosNeedingApproval() int64 {
|
|
var count int64
|
|
DB.Where("status = ?", CertificationPhotoPending).Model(&CertificationPhoto{}).Count(&count)
|
|
return count
|
|
}
|
|
|
|
// Save photo.
|
|
func (p *CertificationPhoto) Save() error {
|
|
result := DB.Save(p)
|
|
return result.Error
|
|
}
|
|
|
|
// Delete the DB entry.
|
|
func (p *CertificationPhoto) Delete() error {
|
|
return DB.Delete(p).Error
|
|
}
|