feat: organisation logo (attachOne logo) and payload helpers
- Organisation gains the public attachOne logo (OrganisationLogoField), editable as an image upload on the Organisations form; avatar unchanged - OrganisationLogoURL and OrganisationLogoFields give applications the has_logo, logo and logo_url keys for their organisation payloads - no migration: attachments live in system_files
This commit is contained in:
90
classes/organisation_logo.go
Normal file
90
classes/organisation_logo.go
Normal file
@@ -0,0 +1,90 @@
|
||||
package classes
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"strconv"
|
||||
|
||||
"git.golem15.com/golem15/sm-user-plugin/models"
|
||||
"git.golem15.com/golem15/summercms/modules/backpack"
|
||||
"git.golem15.com/golem15/summercms/modules/lagoon/attach"
|
||||
"gocloud.dev/blob"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// OrganisationLogoSize is the edge in pixels of the logo thumbnail
|
||||
// OrganisationLogoFields answers.
|
||||
const OrganisationLogoSize = 256
|
||||
|
||||
// organisationLogo loads the organisation's logo attachment, or nil.
|
||||
func organisationLogo(ctx context.Context, app *backpack.App, org *models.Organisation) (*attach.File, error) {
|
||||
if app == nil || org == nil || org.ID == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
gdb, ok := app.Lookup[*gorm.DB]()
|
||||
if !ok || gdb == nil {
|
||||
return nil, nil
|
||||
}
|
||||
var f attach.File
|
||||
err := gdb.WithContext(ctx).
|
||||
Where("attachment_type = ? AND attachment_id = ? AND field = ?", org.MorphName(), strconv.FormatUint(uint64(org.ID), 10), models.OrganisationLogoField).
|
||||
Take(&f).Error
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, nil
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &f, nil
|
||||
}
|
||||
|
||||
// OrganisationLogoURL returns the URL of the organisation's logo at size
|
||||
// pixels, the way AvatarURL serves a user's picture: the thumbnail (size by
|
||||
// size, mode auto) of the logo attachment, or the attachment's file path
|
||||
// when the thumbnail fails (logged). It answers false when the organisation
|
||||
// has no logo or no file bucket is published. The URL may be relative; a
|
||||
// caller that needs an absolute URL resolves it. Only a failing database
|
||||
// lookup is an error.
|
||||
func OrganisationLogoURL(ctx context.Context, app *backpack.App, org *models.Organisation, size int) (string, bool, error) {
|
||||
f, err := organisationLogo(ctx, app, org)
|
||||
if err != nil || f == nil {
|
||||
return "", false, err
|
||||
}
|
||||
bucket, ok := app.Lookup[*blob.Bucket]()
|
||||
if !ok || bucket == nil {
|
||||
return "", false, nil
|
||||
}
|
||||
url, err := f.Thumb(ctx, bucket, size, size, "auto")
|
||||
if err != nil {
|
||||
pluginLog.Error("golem15.user: organisation logo thumb", "err", err)
|
||||
return "/" + attach.BlobKey(f.DiskName), true, nil
|
||||
}
|
||||
return url, true, nil
|
||||
}
|
||||
|
||||
// OrganisationLogoFields answers the logo keys an application adds to its
|
||||
// own organisation payloads, named like the user payload's avatar keys:
|
||||
// has_logo (bool), logo (the attachment's disk name, or nil) and logo_url
|
||||
// (the OrganisationLogoSize thumbnail URL, or nil). An organisation without
|
||||
// a logo answers false, nil and nil. Only a failing database lookup is an
|
||||
// error.
|
||||
func OrganisationLogoFields(ctx context.Context, app *backpack.App, org *models.Organisation) (map[string]any, error) {
|
||||
out := map[string]any{"has_logo": false, "logo": nil, "logo_url": nil}
|
||||
f, err := organisationLogo(ctx, app, org)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if f == nil {
|
||||
return out, nil
|
||||
}
|
||||
out["has_logo"] = true
|
||||
out["logo"] = f.DiskName
|
||||
url, ok, err := OrganisationLogoURL(ctx, app, org, OrganisationLogoSize)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if ok && url != "" {
|
||||
out["logo_url"] = url
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
Reference in New Issue
Block a user