SiteIdentityFormTrait
Site identity form: name, tagline, author and four images (logo, dark logo, favicon, default OG image).
Images are stored as regular assets (cms_system_images) through
ImageManager; only their ids go into the
settings. The setting value is varchar(255), so more than an id would not fit, and the
image stays discoverable in the admin images list.
The color variant (skin) is not edited here: ThemeSettingPresenter picks it together
with the template as one pair, so a skin can never be left over from a previous template.
Site name and tagline are language dependent: fields projectName_<langId> and
tagline_<langId> in language tabs. The default language (the main localization) is
stored under the base key (site.name, site.tagline), other languages under
<key>.<alias> (LocalizedSettingKey). An empty language value makes the front end
use the default language. Everything is saved in one saveBatch call. A new language gets
its tab automatically (fields are generated from languages); a language row that
saveBatch creates inherits is_public from the base key
(SettingManager::upsertSettingValue()).
IMPORTANT: replacing an image keeps the same id: the same asset is edited and the Api
regenerates its variants. Creating a new asset would leave orphan rows in
cms_system_images after every logo change.
Table of Contents
Constants
- IDENTITY_IMAGE_KEYS : mixed = ['logo' => 'site.logo.assetId', 'logoDark' => '...
- Form field => setting key holding the asset id.
- IDENTITY_LOCALIZED_TEXT_KEYS : mixed = ['projectName' => 'site.name', 'tagline' => 'si...
- Language dependent text fields => base setting key. The form field is `<field>_<langId>`, the key of a non-default language is `<key>.<alias>`.
- IDENTITY_MODULE : mixed = 1
- Identity settings belong to the System module.
- IDENTITY_TEXT_KEYS : mixed = ['author' => 'site.author']
- Text fields shared by all languages => setting key (author = person name).
Properties
- $imagePlanMissing : bool
- Set when the last failed image save ended because the usage has no variant plan in the DB.
Methods
- createComponentEditForm() : Form
- getIdentityDefaultLanguageId() : int
- Id of the default language (main localization); its values go to the base keys.
- getIdentityLanguages() : array<int, object>
- Form languages (objects with `getId()`/`getAlias()`), default language first; supplied by the presenter.
- addIdentityImageFields() : void
- The four image fields. `allowVector: true` for all: logos and favicon are often SVG and only an administrator uploads them (the Api sanitizes on save).
- addIdentityTextFields() : void
- Site name and tagline under the logo (per language) and the author for the meta tag.
- identityLanguageAliases() : array<int, string|null>
- Form languages: `langId => alias` for the language variant of a key, `null` = default language (base key). The default language is first.
- identityLocalizedFieldKeys() : array<string, string>
- Form field `<field>_<langId>` => setting key (default language = base key).
- identityUsageKey() : string
- Image usage key per field (`cms_system_asset_usages`): favicon and share image have their own plan, the other image fields (logo, dark logo) share `system-identity-logo`.
- resolveIdentityAssetId() : array{id: ?int, failed: bool, release?: ?int, created?: int}
- Returns the asset id to write into the settings for the field.
- saveIdentityAsset() : int|null
- Saves the uploaded file as an asset and returns its id (null when the save failed).
- saveSiteIdentityForm() : bool
- setSiteIdentityFormDefaults() : void
Constants
IDENTITY_IMAGE_KEYS
Form field => setting key holding the asset id.
private
mixed
IDENTITY_IMAGE_KEYS
= ['logo' => 'site.logo.assetId', 'logoDark' => 'site.logo.dark.assetId', 'favicon' => 'site.favicon.assetId', 'ogImage' => 'site.og.assetId']
Order = order of the fields in the form and in the template.
IDENTITY_LOCALIZED_TEXT_KEYS
Language dependent text fields => base setting key. The form field is `<field>_<langId>`, the key of a non-default language is `<key>.<alias>`.
private
mixed
IDENTITY_LOCALIZED_TEXT_KEYS
= ['projectName' => 'site.name', 'tagline' => 'site.tagline']
IDENTITY_MODULE
Identity settings belong to the System module.
private
mixed
IDENTITY_MODULE
= 1
IDENTITY_TEXT_KEYS
Text fields shared by all languages => setting key (author = person name).
private
mixed
IDENTITY_TEXT_KEYS
= ['author' => 'site.author']
Properties
$imagePlanMissing
Set when the last failed image save ended because the usage has no variant plan in the DB.
private
bool
$imagePlanMissing
= false
Methods
createComponentEditForm()
protected
createComponentEditForm() : Form
Return values
FormgetIdentityDefaultLanguageId()
Id of the default language (main localization); its values go to the base keys.
protected
abstract getIdentityDefaultLanguageId() : int
Return values
intgetIdentityLanguages()
Form languages (objects with `getId()`/`getAlias()`), default language first; supplied by the presenter.
protected
abstract getIdentityLanguages() : array<int, object>
Return values
array<int, object>addIdentityImageFields()
The four image fields. `allowVector: true` for all: logos and favicon are often SVG and only an administrator uploads them (the Api sanitizes on save).
private
addIdentityImageFields(Form $form) : void
Parameters
- $form : Form
addIdentityTextFields()
Site name and tagline under the logo (per language) and the author for the meta tag.
private
addIdentityTextFields(Form $form) : void
Parameters
- $form : Form
identityLanguageAliases()
Form languages: `langId => alias` for the language variant of a key, `null` = default language (base key). The default language is first.
private
identityLanguageAliases() : array<int, string|null>
A language whose alias cannot form a key (empty, invalid) is skipped; otherwise LocalizedSettingKey::forLanguage() would return the base key and that language would overwrite the default language value.
Return values
array<int, string|null>identityLocalizedFieldKeys()
Form field `<field>_<langId>` => setting key (default language = base key).
private
identityLocalizedFieldKeys() : array<string, string>
Return values
array<string, string>identityUsageKey()
Image usage key per field (`cms_system_asset_usages`): favicon and share image have their own plan, the other image fields (logo, dark logo) share `system-identity-logo`.
private
identityUsageKey(string $field) : string
Sizes and variant folders live in the usage tables, not in the form.
Parameters
- $field : string
Return values
stringresolveIdentityAssetId()
Returns the asset id to write into the settings for the field.
private
resolveIdentityAssetId(string $field, ArrayHash<string|int, mixed> $values) : array{id: ?int, failed: bool, release?: ?int, created?: int}
Three paths: "Remove" (deletes the asset and the value), a new file (saved into the
existing asset, or a new asset is created) and no change (keeps <field>CurrentId).
IMPORTANT: returns a tri-state, not ?int. null would mean both "admin asked to
remove" and "save failed", so a failed upload would empty site.logo.assetId and detach
the current image. On failure the original id is returned and the caller cancels the
whole save.
Parameters
- $field : string
- $values : ArrayHash<string|int, mixed>
Return values
array{id: ?int, failed: bool, release?: ?int, created?: int}saveIdentityAsset()
Saves the uploaded file as an asset and returns its id (null when the save failed).
private
saveIdentityAsset(string $field, int|null $currentId, FileUpload $upload) : int|null
null is handled by self::resolveIdentityAssetId(): it returns the original id
and failed=true, so the texts are not saved either and the admin gets an error. The
current image stays attached.
Parameters
- $field : string
- $currentId : int|null
- $upload : FileUpload
Return values
int|nullsaveSiteIdentityForm()
private
saveSiteIdentityForm(ArrayHash<string|int, mixed> $values) : bool
Parameters
- $values : ArrayHash<string|int, mixed>
Return values
boolsetSiteIdentityFormDefaults()
private
setSiteIdentityFormDefaults(Form $form) : void
Parameters
- $form : Form