- 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
91 lines
2.9 KiB
Go
91 lines
2.9 KiB
Go
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
|
|
}
|