Aller au contenu

omnisense/omnibase Référence de l’API

Étage
Cœur
Version
5.x
Vérifié en réel
Son README ne le dit pas
Licence
MIT
composer require omnisense/omnibase:5.x-dev

Lue dans les fichiers PHP du paquet au commit de146f9813b4 : ses espaces de noms, classes, interfaces et énumérations, leurs constantes, propriétés et méthodes publiques avec leur PHPDoc, et les options que prennent ses fabriques. Rien n’en est exécuté.

App\Controller

  • DemoController class

    A deliberately flat, style-free tour of a few base-bundle features.

    1 method

Base

  • Discovery class

    What a host discovers among the core's services, as data (plan "omnibase agnostic", step F5e slice 4c; §2.5: the declaration is the core's, a bridge compiles it): the registries of src/Resources/discovery.php - what the 21 compiler passes of omnibridge/symfony looked for until then, each in its own class. omnibridge/symfony compiles them in one generic pass, omnibridge/laravel applies those it needs to what it binds (the collections, the fallbacks, the entity listeners' events, the repositories), and Omnibridge\Container builds with the generic kinds (`autoconfigure`, `collect`, `fallbacks`: omnisense/omnibridge's Container\Discovery format).

    3 methods · 1 constant

  • Options class

    The core's options as data (plan "omnibase agnostic", step F5e slice 4b): the schema of `base:` - each option's type, default, what it is for, its deprecation, its nesting - and the environment variables a service reads that need a value where the environment has none. One declaration, read by every host, so that no option is declared twice:

    6 methods · 1 constant

  • Services class

    The core's services as data (plan "omnibase agnostic", steps F5a and F5e slice 4; Marco's answer 3: the services stay available everywhere): one declaration that Symfony's container, Laravel's and omnisense/omnibridge's plain-PHP Omnibridge\Container read alike, so that no service is wired three times. Every service of the core is here - what omnibridge/symfony's config/omnibase/services/*.php registered until slice 4 - with its tags and its decoration.

    7 methods · 1 constant

Base\ApiPlatform\Metadata\Resource\Factory

Base\Attributes

Base\Attributes\Attribute

  • Iconize class

    Class Iconize package Base\Attributes\Attribute\Iconize

    3 methods

  • IsGranted class

    13 methods

  • Route class

    Attribute class for @Route().

    1 method · 1 constant

  • Sitemap class

    Class Sitemap package Base\Attributes\Attribute\Sitemap

    7 methods

Base\Attributes\Traits

Base\Auth

  • DemoPasswords class

    The passwords in a demonstration (the `demo` environment, plan "omniauth" AU7): Base\Subscriber\DemoBackOfficeSubscriber's rule where omniauth checks the password - the super-administrator signs in with base.demo.superadmin_password, an account that opens the back office with base.demo.admin_password, never with the password the database holds (a copy of the production's); while a tier's secret is not set, its accounts have no password at all. Every other account's is its own (the store this decorates). A secret is never written in place of a password.

    3 methods

  • EnrolmentPrompt class

    When a signed-in visitor is sent to the second factor's enrolment page (user_settings_enrolment), framework-free (step R29 of the audit "lesringostars face au master plan"): what Base\Subscriber\ SecurityEnrolmentSubscriber asks under Symfony and omnibridge/laravel's enrolment middleware asks under Laravel, each with its own request and session.

    5 methods · 1 constant

  • NotifierSender class

    omniauth's Sender on omnibase's e-mails (plan "omniauth", §1.9): a sign-in link (Notifier::loginLink(), the e-mail of the former loginToken()) and the second factor's code (Notifier::emailCode()), by e-mail alone - what the page tells the visitor is the same whether an account goes with the address or not.

    2 methods

  • Policy class

    omnibase's rule around omniauth's (plan "omniauth", §1.6, step AU4 - the former P4 of the study): Base\Service\SecurityPolicy, asked of the account signing in, decorating the second-factor rule omniauth is given (EnrolledSecondFactors: a second factor after a password, a link or an identity provider, for an account that set one up).

    6 methods · 2 constants

  • PolicyLinking class

    omniauth's rule for a link by a verified address, on omnibase's Policy (QA3): never for an account with a second factor or an administration role, nor a demonstration account; $also adds another rule (omniauth's NoSecondFactorLinking, which reads the methods mounted).

    2 methods

  • Registration class

    A sign-up once its form holds, the same on every host (plan "omnibase agnostic", step F5c): the account approved or left to an administrator (base.user.register.autoapprove), its password, a name when its class has a username the form left empty, verified at once when a verified account signs up (a social connection), the administrators told (base.user.register.notify_admins), then kept. Symfony's SecurityController::Register() signs the account in afterwards; another host does it its own way.

    3 methods

  • UserAccounts class

    omniauth's accounts: omnibase's users (the `user` table, and the application's own beside it - lesringostars' userProfile, joined).

    7 methods · 5 constants

  • UserBackupCodes class

    The backup codes: user.backupCodes, a JSON list of password_hash()'s, as User::setBackupCodes() writes it.

    2 methods

  • UserEmailCodes class

    The code by e-mail: user.emailAuthEnabled, and user.emailAuthCode holding, by Marco's decision QA5, the code's keyed hash (omniauth's EmailCodeMethod computes it) instead of the code scheb/2fa kept in clear; null once used or turned off. A code scheb sent before the switch matches no hash: its owner asks for another (it lived minutes).

    6 methods

  • UserIdentities class

    omniauth's identities at providers: the userIdentity table (Base\Entity\User\Identity), by Marco's decision QA3 - an account is found by the provider's subject, never by user.identityProvider (which keeps its own meaning: where the account came from) nor by the address alone. The table's two unique keys refuse what omniauth's OAuthMethod refuses before them: a subject linked to two accounts, two identities of one provider on one account.

    6 methods

  • UserLinkTokens class

    The sign-in links: the userToken rows named "login-token", logginable, as SecurityController::LoginTokenRequest made them - now, by Marco's decision QA4, holding the link's SHA-256 (64 hexadecimal characters) in `value`, never the link, until the moment omniauth gives (15 minutes), and used up at the first sign-in: claimed by marking it revoked (one UPDATE: of two requests with the same link, one only gets the account), then removed.

    3 methods · 1 constant

  • UserPasskeys class

    omniauth/webauthn's passkeys: the userPasskey table through Base\Entity\User\Passkey, which the core describes since AU1. The record holds the credential id and the public key as base64 - the text of the columns -, the entity their bytes (the passkey_base64 type turns one into the other); the other eleven fields are the same values. A passkey added here is a row web-auth/webauthn-symfony-bundle reads, and one it wrote is a record here (omniauth/webauthn's tests prove both ways on those very columns).

    6 methods

  • UserPasswords class

    The password hashes: user.password, as Symfony's "auto" hasher wrote them (bcrypt, cost 13 on lesringostars); omniauth's PasswordMethod checks them with symfony/password-hasher under any host and hands back a rehash.

    2 methods

  • UserStore class

    What omniauth's stores over omnibase's tables share (plan "omniauth", §2.2, step AU4): the unit of work (plan "omnibase agnostic", step F2d: omnisense/omnibridge's contract - Doctrine's under Symfony, or over the entity manager a Laravel host builds by hand on the same mapping -), the repositories through it, the accounts as omnibase's users, and a write kept at once (a method that returns has written: a link issued is in the table before its e-mail leaves).

    1 method

  • UserTotpSecrets class

    The authenticator applications' secrets: user.secret, as the column holds it. Sealed at rest when the site sets omniauth's totp.secret_key (QA5): the hosts' bridges then wrap this store in omniauth/otp's SealedTotpSecrets, so the column holds "otp:v1:..." and its readers the base32 secret; a secret kept in clear before (scheb/2fa's) is read as it is until the site's migration rewrites it.

    3 methods

  • UserTrustedVersion class

    The trusted devices' version: user.trustedTokenVersion, the "vsn" claim of the trusted_device cookie scheb/2fa wrote and omniauth writes alike.

    2 methods

Base\Auth\Account

  • AlreadySignedIn class

    The pages for visitors only - the sign-up, the forgotten password and its link -, written once for every host (plan "omnibase agnostic", step F5e, slice 5; formerly SecurityController::Register() and ResetPasswordRequest()/Response(), and the twin's AccountPages::register() again): an account signed in (and kept) is told so and sent to its profile.

    2 methods · 1 constant

  • Closing class

    An account closed by its owner, and opened again by the link it is sent, written once for every host (plan "omnibase agnostic", step F5e, slice 5; formerly SecurityController::DisableAccountRequest() and EnableAccountRequest()). A demonstration account is everyone's: it does not close itself.

    3 methods · 1 constant

  • Devices class

    The account's sessions and passkeys on its settings page, written once for every host (plan "omnibase agnostic", step F5e, slice 5b; formerly UserSettingsController::Settings(), RenamePasskey(), DeletePasskey() and LogoutSession()): the twenty sessions last used (the list is there to spot one that should not be, the oldest of six hundred tell nobody anything), a passkey renamed or removed and a session signed out - each by its token, and only the account's own (another's: no such page) -, then back to the settings.

    6 methods · 3 constants

  • MemberSearch class

    The members' search, written once for every host (plan "omnibase agnostic", step F5e, slice 5b; formerly UserSearchController::Main()): members are looked for by their username, where the application's account has one - never by their e-mail address, which the page would show to anyone -, fifty at most, the banned and the ghosts left out; no term, no one.

    2 methods · 2 constants

  • Outcome class

    Where an account's page sends the visitor once its rule has decided (plan "omnibase agnostic", step F5e, slice 5): one of omnibase's routes, an address, the site's index - its route, or its address -, the page the visitor was going to (else the index's address), a page to show (a Template), or a refusal (403) or no such page (404); first signing an account in, remembered or not, where the rule says so. The rule decides and sends its notifications; each host turns the Outcome into its answer (omnibridge/symfony's Omnibase\Response\Outcomes, omnibridge/laravel's Http\Outcomes): which router, which referrer, which authenticator are the host's.

    11 methods · 9 constants

  • Passwords class

    A forgotten password reset by a link, and a password the owner did not choose changed at the first sign-in, written once for every host (plan "omnibase agnostic", step F5e, slice 5; formerly SecurityController:: ResetPasswordRequest(), ResetPasswordResponse() and ChangePassword()). The forms stay the host's; each method is one of their moments. A demonstration account keeps its password, and says so.

    6 methods · 3 constants

  • ProfileAccess class

    Whose profile a page shows or edits, written once for every host (plan "omnibase agnostic", step F5e, slice 5; formerly UserProfileController::Show() and Edit(), and the twin's AccountPages::profileEdit() again): an id, that account (no such account: no such page); none (-1), the account signed in, kept - else the members' search; another's profile is edited by an administrator only.

    3 methods · 1 constant

  • RescuePage class

    The back office's sign-in page ("rescue"), written once for every host (plan "omnibase agnostic", step F5e, slice 5; formerly RescueController::LoginRescue()): an account signed in fully goes where it was going (else the back office's home); the page shows the back office's logo (else the site's) and sends the visitor, once signed in, to the page it asked for when it is one of this site's - as a path, which the sign-in matches against the routes -, else to the back office's home. Which template and the back office's address are the host's.

    4 methods · 3 constants

  • SecondFactor class

    The account's authenticator application, written once for every host (plan "omnibase agnostic", step F5e, slice 5b; formerly UserSettingsController's TwoFactorAuthentication*() and displayTotpQrCode()): - a demonstration account changes nothing of its second factor (refused aloud, back to the settings); - turning it on: refused where the administrator switched the feature off, nothing to do where it is on; a secret kept in the session until a code of the visitor's application confirms it, checked on a copy of the account (the account itself never carries an unconfirmed secret: another request's flush would keep it); confirmed, the secret kept (through omniauth's store, sealed at rest where the site says so), eight backup codes shown once; - turning it off: the token, then the administrator's rule (a second factor required stays), then the password; - the QR codes: the secret as the application scans it (opened by omniauth's store), or the pending one.

    12 methods · 6 constants

  • SignIn class

    The sign-in page's rules and the sign-in link's, written once for every host (plan "omnibase agnostic", step F5e, slice 5; formerly SecurityController::Login() and LoginTokenRequest()). The forms, the captcha and omniauth's link (where omniauth signs in, it issues the links: the host asks it) stay the host's.

    5 methods · 5 constants

  • SignOutPage class

    The sign-out page's rules, written once for every host (plan "omnibase agnostic", step F5e, slice 5; formerly SecurityController::Logout(), whose confirmation omnibridge/laravel's SignIn::logoutPage() wrote again). Signed in: where the host's sign-out asks a CSRF token, a request without the session's is asked to confirm by a link that carries one - a link from another site, an <img>, a page kept from an ended session signs nobody out -; with it, on to the host's sign-out. Signed out: the account that just left is told goodbye (or that it was put out), and the visitor goes back where it was, the index from a secured page.

    4 methods · 1 constant

  • Verification class

    An account's e-mail address verified, then its approval asked of the administrators, written once for every host (plan "omnibase agnostic", step F5e, slice 5; formerly SecurityController::VerifyEmailRequest(), VerifyEmailResponse() and AdminApprovalRequest()). The link's account is signed in by the host between tokenOwner() and confirm(). Each step ends on the account's profile.

    5 methods · 4 constants

  • WaitingPages class

    The pages a visitor waits on - the maintenance, the launch, a page not open yet, an account waiting for its approval -, written once for every host (plan "omnibase agnostic", step F5e, slice 5; formerly SecurityController::Maintenance(), Launch(), Pending() and PendingForApproval()): their templates and data.

    5 methods

Base\Auth\Listener

  • GuardSignIn class

    Base\Security\SignInCaptcha on omniauth's events: each failed sign-in from an address counts (SignInFailed), a success forgets them (SignedIn), and from base.guard.sign_in_after failures on, a password sign-in from that address must pass the captcha before its password is checked (Verifying, refused `captcha`: SignInCaptcha::MESSAGE is what the page says).

    5 methods · 1 constant

  • TrackConnections class

    The browsers an account signs in from (userConnection rows, through Base\Security\UserTracker), on omniauth's events: what Base\EntitySubscriber\ConnectionSubscriber does on Symfony's - a success marks the browser's connection succeeded (made if it is new), a failure on a known account marks it failed - the account the attempt had, or the one of the identifier typed (a wrong password: Symfony's passport loaded it too). Runs before WarnNewDevice, which looks for the connection a sign-in made.

    4 methods

  • UpdateAccount class

    The account brought up to date at its sign-in, what Base\Security\LoginFormAuthenticator::onAuthenticationSuccess() does under Symfony: a role the application's UserRole enum no longer knows dropped from the account's own roles (never those of its groups), its time zone and its language kept (the visitor's when it had none), its kick lifted.

    3 methods

  • WarnNewDevice class

    A sign-in from a browser the account had not used (a connection this sign-in made, TrackConnections running first): the e-mail "a new device" when the administrator turned it on, and - on an account with no second factor that has not declined it - the flag of the session that makes the next page offer, once, to set up a code. Base\Subscriber\NewDeviceSubscriber's rule on omniauth's SignedIn event: never at the account's very first sign-in (nothing to compare with), nothing that blocks the sign-in.

    3 methods · 1 constant

  • WelcomeBack class

    A disabled account that proved who it is: the "welcome back" e-mail, with a token good an hour - its next sign-in within that hour enables the account again (UserAccounts::check()). Base\Security\UserChecker's checkPostAuth() under Symfony, on omniauth's AccountRefused event.

    3 methods · 1 constant

Base\Auth\Policy

  • Access class

    Who may open the site while its access is restricted (plan "omnibase agnostic", step F5e, slice 1): the rule omnibridge/symfony's AccessVoter held, on the core's services, for every host.

    4 methods · 5 constants

  • Admin class

    BACKEND (plan "omnibase agnostic", step F5e, slice 1): the back office and the debugging tools are an administrator's. Asked only on their pages (the host says whether the current route is one).

    2 methods · 1 constant

  • Complaint class

    Who reads and answers a complaint (plan "omnibase agnostic", step F5e, slice 1; Base\Entity\User\Complaint): COMPLAINT_READ / COMPLAINT_HANDLE, the complaint as subject, or none (may this user read complaints at all).

    3 methods · 2 constants

  • Launch class

    LAUNCH_ACCESS (plan "omnibase agnostic", step F5e, slice 1): the site is launched, or the address is one of the restriction's exceptions (Access::exception()).

    2 methods · 1 constant

  • Maintenance class

    MAINTENANCE_ACCESS (plan "omnibase agnostic", step F5e, slice 1): the site is not under maintenance, or the address is one of the restriction's exceptions (Access::exception()).

    2 methods · 1 constant

  • Page interface

    The page a request opens, as the restriction asks it (plan "omnibase agnostic", step F5e, slice 1): what only the host knows - its router, its firewalls -, asked lazily, only once the access is restricted.

    5 methods

  • Permission class

    The permission tags (plan "omnibase agnostic", step F5e, slice 1): custom fine-grained names, backed by Base\Entity\User\Permission and granted on the user or through a group's membership ("ARTICLE.PUBLISH"; "ARTICLE.*" grants every "ARTICLE." one). Only that name space: never a ROLE_ or IS_ attribute (the role hierarchy's) nor an EA_ one (omnibase/admin's), only upper-case names of letters, digits, _ . and :.

    2 methods

  • Restriction class

    What a request meets while the site's access is restricted (plan "omnibase agnostic", step F5e, slice 1): the decision omnibridge/symfony's SecuritySubscriber::onAccessRequest() took, for every host.

    2 methods

  • RestrictionDecision class

    Restriction's answer (plan "omnibase agnostic", step F5e, slice 1): the request goes on (a notice for the visitor, perhaps), is answered "not found", or is sent to the first of the routes the denied are sent to (the sign-in when there is none). `profiler` says whether the visitor keeps the profiler (a special grant): the host turns it off otherwise, outside debugging.

    3 methods · 3 constants

  • Welcome class

    The word of welcome a sign-in leaves (plan "omnibase agnostic", step F5e, slice 1): the key omnibridge/symfony's SecuritySubscriber::onLoginSuccess() and omnibridge/laravel's WelcomeFlash each chose, in @notifications, the account its {0}, a "success".

    1 method · 1 constant

Base\Bridge\Composer\Stub

  • AbstractBaseStub class

    The App\ stubs of one folder of the core: for each plain class Base\<Name>\X that the application does not define in src/<Name>/, a stub of App\<Name>\X - the alias Base\Bundle\AbstractBaseBundle declares at run time - for an IDE and static analysis.

    1 method

  • EntityStub class

    The stubs of App\Entity\ (see AbstractBaseStub).

  • EnumStub class

    The stubs of App\Enum\ (see AbstractBaseStub).

  • FormStub class

    The stubs of App\Form\ (see AbstractBaseStub): the core's folder, and the form types, extensions and services omnibridge/symfony holds since the plan "omnibase agnostic"'s step F5b (Omnibridge\Symfony\Omnibase\Form\X), which extend them by their former names, Base\Form\X (src/Resources/former-names.php).

    1 method

  • NotifierStub class

    The stubs of App\Notifier\ (see AbstractBaseStub).

  • RepositoryStub class

    The stubs of App\Repository\ (see AbstractBaseStub). The core's repositories are omnibridge/doctrine's since the plan "omnibase agnostic"'s step F3 (Omnibridge\Doctrine\Omnibase\Repository\X): their stubs extend them by their former names, Base\Repository\X, which the core aliases (src/Resources/former-names.php) and the application's App\Repository\X stands for at run time, as before.

Base\Bridge\PHPStan

  • EntityAccessorReflection class

    One accessor of EntityAccessorsExtension: public, with the signature of the method it ends in (an alias: AliasTrait hands the arguments on), any arguments and that method's return type when $anyArguments (a translation's: TranslatableTrait reads a property and leaves them), any arguments and mixed without one.

    15 methods

  • EntityAccessorsExtension class

    The accessors an omnibase entity answers through __call() for PHPStan (audit "lesringostars face au master plan", R21b), as FinderMethodsExtension does for the repositories' finders:

    3 methods · 1 constant

  • FinderMethodReflection class

    One method of the finder language (FinderMethodsExtension): public, any arguments, mixed.

    15 methods

  • FinderMethodsExtension class

    The finder language of omnibase's repositories for PHPStan: a repository extending Base\Database\Repository\ServiceEntityRepository answers, through __call() and ServiceEntityParser, every method its name describes - findOneBySlug(), cacheByParentAndState(), countByDomainAndUpdatedAtYoungerThan(), distinctCountBy...(), lengthOf...() - which no declaration can list. Each is known to PHPStan as a public method taking any arguments and returning mixed, as ServiceEntityRepository::__call() declares; any other unknown name is still an undefined method.

    2 methods · 1 constant

Base\Bridge\Symfony

  • AccountScreens class

    The account's screens under Symfony (plan "omnibase agnostique", C5): what the framework-free builder (Base\Screen\Builder\Accounts) cannot know, asked where the templates of before asked it - the viewer and their roles (the Access contract: `app.user`, `is_granted`), an avatar's thumbnail (`|thumbnail`), the providers one may link (`oauth_available()`), web push and the back-office address of a notification (`push_available()`, `push_vapid_key()`, `notification_admin_url()`), Twig's time zone (the days of the notifications' groups) -, handed to the builder. What the account's controllers and the Twig function `account_profile()` (a host page's) call; a Twig runtime, so that it may read Twig's functions and filters without a circular service. It asks them by their names, as a template does, not by the classes of omnibase's Twig extensions (plan "omnibase agnostic", F4: nothing outside src/Twig names Base\Twig\); a function no extension registered answers as it did when its extension was missing.

    4 methods · 1 constant

  • NotificationMessages class

    The Symfony half of Base\Entity\User\Notification (plan "omnibase agnostique", step C3f): what the entity made with the framework, moved here as it was. The entity keeps what a notification is - its subject, content, importance, channels, recipients, context, templates - and its sending through the notifier; it hands this class what needs Symfony:

    4 methods · 1 constant

  • PasskeyRecords interface

    Base\Contract\PasskeyRecords under Symfony (plan "omniauth", AU1): WebauthnBundle's CredentialRecordRepositoryInterface and CanSaveCredentialRecord, which Base\Repository\User\PasskeyRepository implemented itself up to AU1 and which the contract is an alias of when the bundle is installed. Not to be named by a class: implement Base\Contract\PasskeyRecords.

  • PasskeyUsers interface

    Base\Contract\PasskeyUsers under Symfony (plan "omniauth", AU1): WebauthnBundle's PublicKeyCredentialUserEntityRepositoryInterface, which Base\Security\WebauthnUserEntityRepository implemented itself up to AU1 and which the contract is an alias of when the bundle is installed. Not to be named by a class: implement Base\Contract\PasskeyUsers.

  • SecurityUser interface

    Base\Contract\SecurityUser under Symfony (plan "omnibase agnostique", C7b): the interfaces Base\Entity\User implemented itself up to 4.0 - Security's UserInterface and PasswordAuthenticatedUserInterface -, which the contract is an alias of when symfony/security-core is installed. Not to be named by a class: implement Base\Contract\SecurityUser.

  • SecurityUserLoader interface

    Base\Contract\SecurityUserLoader under Symfony (audit "lesringostars face au master plan", R2): doctrine-bridge's UserLoaderInterface - the repository an entity user provider loads a user by its identifier from -, which Base\Repository\UserRepository implemented itself up to 4.0 and which the contract is an alias of when symfony/doctrine-bridge is installed. Apart from Base\Bridge\Symfony\SecurityUserProvider: an interface cannot extend both (loadUserByIdentifier() answers ?UserInterface here, UserInterface there), a class implements both. Not to be named by a class: implement Base\Contract\SecurityUserLoader.

  • SecurityUserProvider interface

    Base\Contract\SecurityUserProvider under Symfony (audit "lesringostars face au master plan", R2): Security's UserProviderInterface and PasswordUpgraderInterface, which Base\Repository\UserRepository implemented itself up to 4.0 and which the contract is an alias of when symfony/security-core is installed. Not to be named by a class: implement Base\Contract\SecurityUserProvider.

  • TwoFactorUser interface

    Base\Contract\TwoFactorUser with scheb/2fa (plan "omnibase agnostique", C7b): the interfaces Base\Entity\User implemented itself up to 4.0 - TOTP and e-mail codes, backup codes, trusted devices -, which the contract is an alias of when scheb/2fa is installed. Not to be named by a class: implement Base\Contract\TwoFactorUser.

Base\Cache

Base\Cache\Abstract

  • AbstractLocalCache class

  • AbstractLocalCacheInterface interface

    A service's own cache, warmed by omnibase's cache warmers (Base\Cache\Warmer\*, which call warmUp()). warmUp() is declared here, with the signature of HttpKernel's WarmableInterface, which this interface no longer extends (plan "omnibase agnostique", C6): the AttributeReader and the ClassMetadataManipulator - what an entity manager built by hand reads its mapping through - load nothing of the framework. Symfony asks WarmableInterface of the kernel, its router and its translator only, none of which is one of these.

    7 methods

  • AbstractLocalCacheWarmerInterface interface

    1 method

Base\Cache\Pool

  • MemoryItem class

    An item of Base\Cache\Pool\MemoryPool (PSR-6). The parameters are left untyped so that it implements psr/cache 1, 2 and 3 alike.

    7 methods

  • MemoryPool class

    A PSR-6 pool held in memory, for the core's local caches (Base\Cache\Abstract\AbstractLocalCache: the obfuscator's map, the icons...) where no pool is given and symfony/cache is not installed (since 5.0, plan "omnibase agnostic", step F6: the core requires psr/cache, not symfony/cache).

    9 methods

Base\Console

  • Commands interface

    The host's other console commands, for a task that runs some (plan "omnibase agnostic", step F5e, slice 3: demo:reset runs the fixtures, uploader:entities, the cache pools). Each host answers the names it has; a name it has not got answers null. Their output goes where the host prints, not to the task's Report.

    1 method

  • ConsoleInterface interface

    1 method

  • Report class

    What a console task said and how it ended (plan "omnibase agnostic", step F5e, slice 3: Base\Console\Task\*), for every host to print: omnibridge/symfony's commands and omnibridge/laravel's artisan commands print the same Report, neither writes anything of its own.

    11 methods · 12 constants

Base\Console\Task

  • AutocompleteEntities class

    autocomplete:entities (plan "omnibase agnostic", step F5e, slice 3): the entities a picker searches (AutocompleteInterface), or an entity's rows and what each one answers a picker (its text and its data).

    1 method

  • BaseMapping class

    base:mapping (plan "omnibase agnostic", step F5e, slice 3): the core's enumerations, forms, entities and repositories, each aliased to the App\ class of the same name where the application has none (the App\ convention), and the application's classes that take their place.

    1 method · 1 constant

  • BaseMappingInput class

    base:mapping's options (plan "omnibase agnostic", step F5e, slice 3).

    1 method · 1 property

  • CacheClear class

    cache:clear's part that is omnibase's (plan "omnibase agnostic", step F5e, slice 3; formerly Base\Traits\ CacheClearTrait and the command's lock), around the host's own clear, given as a closure:

    2 methods · 1 constant

  • CacheClearInput class

    cache:clear's options and what the host knows of itself (plan "omnibase agnostic", step F5e, slice 3).

    2 methods · 8 properties

  • CacheClearSessions class

    cache:clear:sessions (plan "omnibase agnostic", step F5e, slice 3): every session file of the host's folder removed, so that every visitor is signed out.

    1 method

  • CacheClearSessionsInput class

    cache:clear:sessions' input (plan "omnibase agnostic", step F5e, slice 3): where the host keeps its session files.

    1 method · 2 properties

  • CacheClears class

    How many times the cache was cleared since it was made, kept in a file beside it (<cache dir>.txt): the first clear of an application that has not started yet, the second one that cache:clear runs by itself (base.autoclear). omnibridge/symfony's CacheClearCommand answers its static questions from it (plan "omnibase agnostic", step F5e, slice 3).

    6 methods · 1 property

  • DemoReset class

    demo:reset (plan "omnibase agnostic", step F5e, slice 3): the demonstration back to what the fixtures say - what the `cron` container runs every night in the `demo` environment, and nowhere else.

    2 methods · 4 constants

  • DemoResetInput class

    demo:reset's options and the base.demo.reset.* parameters (plan "omnibase agnostic", step F5e, slice 3).

    1 method · 4 properties

  • EntitiesInput class

    icon:entities' and autocomplete:entities' options (plan "omnibase agnostic", step F5e, slice 3).

    1 method · 3 properties

  • EntitiesTask class

    A console task on the entities of a class (plan "omnibase agnostic", step F5e, slice 3): icon:entities, autocomplete:entities, entity:discriminator. Whether a class is an entity is the unit of work's shapes' answer (Doctrine's ClassMetadataManipulator::isEntity() before), its rows its repository's.

    1 method

  • EntityDiscriminator class

    entity:discriminator (plan "omnibase agnostic", step F5e, slice 3): a class that is no entity refused aloud.

    1 method

  • EntityDiscriminatorInput class

    entity:discriminator's argument (plan "omnibase agnostic", step F5e, slice 3).

    1 method · 1 property

  • Folders class

    Where the console tasks look for classes (plan "omnibase agnostic", step F5e, slice 3): the core's src/ folder (it was BaseBundle::getBundleDir().'/src'), and the classes of a folder in the order the filesystem lists them.

    2 methods

  • IconEntities class

    icon:entities (plan "omnibase agnostic", step F5e, slice 3): the entities that have icons (IconizeInterface) and their class's icons, or an entity's rows and each one's icons.

    1 method

  • IconEnums class

    icon:enums (plan "omnibase agnostic", step F5e, slice 3): the core's enumerations, then the application's, and each value's icons (#[Iconize]); the native PHP enums and the groups without values of their own left out.

    1 method

  • IconEnumsInput class

    icon:enums' options (plan "omnibase agnostic", step F5e, slice 3).

    1 method · 2 properties

  • MailerTrap class

    base:mailer:trap (plan "omnibase agnostic", step F5e, slice 3): outgoing mail held during an incident (the trap sits at send time, so mail already queued is caught too), what was held looked at, the wrong ones thrown away and the rest let go - released through the host's transport ($send), around the trap. Held mail outlives the trap on purpose: disarming restores delivery without deciding, silently, what happens to what was caught.

    2 methods

  • MailerTrapInput class

    base:mailer:trap's arguments and options (plan "omnibase agnostic", step F5e, slice 3).

    1 method · 4 properties

  • NotifierMailTest class

    notifier:mail:test (plan "omnibase agnostic", step F5e, slice 3): a test e-mail sent to an account (by its id, e-mail address or username), else to the technical recipient's account, else to an account made up for the technical recipient's address (not stored), else to the first account.

    2 methods

  • NotifierMailTestInput class

    notifier:mail:test's options (plan "omnibase agnostic", step F5e, slice 3).

    1 method · 1 property

  • NotifierOverview class

    app:notifier (plan "omnibase agnostic", step F5e, slice 3): the templated notifications the application's notifier offers - its methods and its parents', BaseNotifier's own left out.

    1 method

  • NotifierOverviewInput class

    app:notifier's options (plan "omnibase agnostic", step F5e, slice 3).

    1 method · 1 property

  • ThreadPublishable class

    thread:publishable (plan "omnibase agnostic", step F5e, slice 3): the scheduled threads (ThreadState::FUTURE), those whose time has come, and - asked - those published, each under its row's lock and read again, so that two runs at once (the cron, an administrator's edit) publish it once.

    3 methods

  • ThreadPublishableInput class

    thread:publishable's options (plan "omnibase agnostic", step F5e, slice 3).

    1 method · 1 property

  • TimeMachineSnapshot class

    timemachine:snapshot (plan "omnibase agnostic", step F5e, slice 3): the database connections, the storages and the snapshots each storage holds; backup() and restore() list them first, then back up or restore - each step confirmed by the host's question ($confirm: the question, its default answer).

    4 methods

  • TimeMachineSnapshotBackupInput class

    timemachine:snapshot:backup's options (plan "omnibase agnostic", step F5e, slice 3).

    1 method · 2 properties

  • TimeMachineSnapshotInput class

    timemachine:snapshot's arguments and options, and those of its backup and restore (plan "omnibase agnostic", step F5e, slice 3).

    1 method · 4 properties

  • TimeMachineSnapshotRestoreInput class

    timemachine:snapshot:restore's options (plan "omnibase agnostic", step F5e, slice 3).

    1 method · 1 property

  • TimeMachineStorage class

    timemachine:storage (plan "omnibase agnostic", step F5e, slice 3): the storages a snapshot can be written to.

    2 methods

  • TranslationControllers class

    translation:controllers (plan "omnibase agnostic", step F5e, slice 3): the routes served by an App\ or a Base\ controller and, for each language, the key of their page's title, "@controllers.<route>.<suffix>", with its translation or "no translation found". The host gives its routes.

    1 method

  • TranslationControllersInput class

    translation:controllers' options (plan "omnibase agnostic", step F5e, slice 3).

    1 method · 4 properties

  • TranslationCrud class

    translation:crud (plan "omnibase agnostic", step F5e, slice 3): the back office's CRUD controllers - the core's, then the application's - and, for each language, the key of their page's title, "@admin.crud.<the class's path>.<action>.<suffix>", with its translation or "no translation found".

    1 method

  • TranslationCrudInput class

    translation:crud's options (plan "omnibase agnostic", step F5e, slice 3).

    1 method · 5 properties

  • TranslationEntities class

    translation:entities (plan "omnibase agnostic", step F5e, slice 3): the application's entities, then the core's - their namespaces first, then their classes, the translations' tables (…Intl) left out - and, for each language, the key of their noun, "@entities.<the path>.<suffix>", with its translation or "no translation found".

    1 method

  • TranslationEntitiesInput class

    translation:entities' options (plan "omnibase agnostic", step F5e, slice 3).

    1 method · 4 properties

  • TranslationEnums class

    translation:enums (plan "omnibase agnostic", step F5e, slice 3): the application's enumerations, then the core's (the native PHP enums and the groups without values of their own left out) and, for each language, the key of their noun, "@enums.<the path>.<suffix>", then of each value's, "@enums.<the path>.<value>.<suffix>", with their translations or "no translation found".

    1 method

  • TranslationEnumsInput class

    translation:enums' options (plan "omnibase agnostic", step F5e, slice 3).

    1 method · 4 properties

  • TranslationSettings class

    translation:settings (plan "omnibase agnostic", step F5e, slice 3): the settings under a path and their value in each language (a setting of a single language marked so), or, raw, each one's label and help per language.

    2 methods

  • TranslationSettingsInput class

    translation:settings' options (plan "omnibase agnostic", step F5e, slice 3).

    1 method · 3 properties

  • TranslationTask class

    What the translation keys' tasks share (plan "omnibase agnostic", step F5e, slice 3): the languages listed (the site's, or the one asked, refused when the site has not got it), a key's line - found, or "no translation found" - and where the core's and the application's classes are.

    1 method

  • TrashPurge class

    trash:purge (plan "omnibase agnostic", step F5e, slice 3): the trash emptied of everything past its grace period (base.extension.empty_trash, "+7 days" by default). A dry run unless forced: nothing else in the stack destroys content beyond recovery.

    2 methods

  • TrashPurgeInput class

    trash:purge's options (plan "omnibase agnostic", step F5e, slice 3).

    1 method · 2 properties

  • UploaderEntities class

    uploader:entities (plan "omnibase agnostic", step F5e, slice 3): the properties holding uploaded files (#[Uploader]) of the application's entities and the core's, the files each one's folder holds, and - asked - the orphans: the files no row names, and the names no file answers; deleted if asked (demo:reset's nightly step).

    2 methods

  • UploaderEntitiesInput class

    uploader:entities' options (plan "omnibase agnostic", step F5e, slice 3).

    2 methods · 6 properties

  • UploaderImages class

    uploader:images (plan "omnibase agnostic", step F5e, slice 3): uploader:entities, and - asked - each image and its thumbnails (the formats of its #[Uploader] and of base.uploader.formats) made in the cache, original and WebP, at most a batch per run.

    3 methods

  • UploaderImagesCrop class

    uploader:images:crop (plan "omnibase agnostic", step F5e, slice 3): uploader:images on the images (Base\Entity\ Layout\Image and its App\ classes), each image's crops made in the cache too; and - asked, confirmed - the crops' coordinates renormalised against a resolution (Base\Imagine\Filter\Basic\Definition\*).

    4 methods

  • UploaderImagesCropInput class

    uploader:images:crop's options (plan "omnibase agnostic", step F5e, slice 3).

    1 method · 2 properties

  • UploaderImagesInput class

    uploader:images' options (plan "omnibase agnostic", step F5e, slice 3).

    1 method · 3 properties

  • UserCreate class

    user:create (plan "omnibase agnostic", step F5e, slice 3): an account made from the command line, verified and approved, with a password it did not choose - generated and shown once, or given -, to be changed at its first sign-in (a PASSWORD_CHANGE token, which omnibridge/symfony's PasswordChangeSubscriber asks) unless kept; e-mailed its username and password (Notifier::accountCreated) unless not.

    2 methods · 2 constants

  • UserCreateInput class

    user:create's arguments and options (plan "omnibase agnostic", step F5e, slice 3).

    1 method · 6 properties

  • UserNotification class

    user:notifications (plan "omnibase agnostic", step F5e, slice 3): the notifications kept in the database counted (an account's, or everyone's), listed, and the read ones erased when older than base.user.notifications.expiry (or the expiry given), or whatever their age. An unread notification is never erased.

    2 methods

  • UserNotificationInput class

    user:notifications' options (plan "omnibase agnostic", step F5e, slice 3).

    1 method · 5 properties

Base\Contract

  • Framework class

    Whether omnibase's classes declare a framework's interfaces where they would (plan "omnibase agnostique", C7b, C7c): Base\Entity\User implements Security's UserInterface and PasswordAuthenticatedUserInterface and scheb/2fa's models through Base\Contract\SecurityUser and Base\Contract\TwoFactorUser, which are those interfaces when they are installed and empty otherwise.

    1 method

  • Link class

    A route's address by a router's reference type, through the Urls contract (plan "omnibase agnostique", C3e): what an entity's __toLink() made with BaseTrait's router, `$this->getRouter()->generate($name, $parameters, $referenceType)`, made where there is no framework too.

    1 method · 4 constants

  • Media interface

    The image route as an entity builds its addresses (plan "omnibase agnostique", C4b): a stored image is served by omnibase's route ux_image (or ux_imageExtension) with its path and how to serve it - a crop, a thumbnail, the filters, a salt - obfuscated in one `data` parameter, and the extension it is served with. Image::__toLink() and ImageCrop::__toLink() ask it instead of BaseTrait's MediaService.

    3 methods

  • MediaRouter interface

    The router as omnibase's media rule asks it (audit "lesringostars face au master plan", R6): FileService and MediaService - the image route's obfuscated addresses, their resolution, the files they serve - and Base\Service\ImageRoute, the route's answers, need only these five questions of a router: an address of a named route, the route and the parameters an address matches, the route's name of an address, the public address of a file, an address by name or as it is.

    5 methods

  • Nouns interface

    What an entity is called: its noun, singular or plural, at a level of politeness, for a gender - "Article", "Articles", "Commande" - and the label of one of its properties, from the "entities" catalogues (plan "omnibase agnostique", C4b): what an entity's __toString() falls back on when it has no title, what a list or a message names it by.

    2 methods

  • Pictures interface

    An image's address at the size a page shows it (plan "omnibase agnostique", C5): what omnibase's `|picture` filter answers - a thumbnail of a stored image, an address or a public path as it is, an asset of the build. Null for no image.

    1 method

  • Runtime class

    The registry through which omnibase's framework-free code reaches its contracts (plan "omnibase agnostique", C4): an entity's getter, an attribute, a value object asks Runtime::urls(), ::access(), ::nouns()... instead of the services Base\Traits\BaseTrait hands out.

    9 methods

  • Texts interface

    A stored text as a page shows it (plan "omnibase agnostique", C5): an Editor.js document or the HTML of an older editor, rendered - mentions, links, media, headings anchored - and its table of contents. What omnibase's `|wysiwyg` and `|wysiwyg_toc` filters answer.

    3 methods

  • Tickets interface

    Short-lived signed tickets to a service that checks them by itself (a WebSocket relay, a game server): a browser or a client asks the application for one, presents it to the service, and the service verifies the signature with the secret they share, never calling the application back. What it says (who, what room, what rights) is each factory's own, so `mint` is not part of the contract; how it is signed is Base\Service\Ticket\TicketSigner's, the one format the services read.

    3 methods

Base\Controller

  • SignatureController class

    A signing provider's callback (omnisense/omnisign: Yousign, DocuSign, DocuSeal...): its signature checked by the gateway, the envelope it names asked again and kept (Base\Service\Signatures::notify()). Without omnisense/omnisign there is nothing to update: 404.

    2 methods

Base\Controller\Action\Notification

  • Delete class

    The bell's removals, written once for every host (step R29 of the audit "lesringostars face au master plan"; formerly NotificationController:: Delete()). Body: {token, id?} - one notification of the account, or every read one when id is absent. The token is checked as Read checks it; 403 without it or for a visitor.

    2 methods

  • Latest class

    The bell's payload, written once for every host (step R27 of the audit "lesringostars face au master plan"; formerly NotificationController:: Latest(), and the closure of lesringostars-laravel's routes/web.php): the signed-in account's unread count and latest entries (?limit=, 1 to 20, 8 by default), for a tab open a while - the page's own dropdown is only as fresh as the page; 401 for a visitor. Private to the account.

    3 methods

  • Read class

    The bell's read marks, written once for every host (step R29 of the audit "lesringostars face au master plan"; formerly NotificationController:: MarkRead()). Body: {token, id?, read?} - one notification of the account, or every unread one when id is absent; read defaults to true, false puts one back to unread. The "notifications" token in the body (the toolbar's data-csrf) is checked through the host's Tokens; without it, or for a visitor, 403. JSON rather than a redirect: the bell updates in place.

    3 methods · 1 constant

Base\Controller\Action\Settings

  • EmailCodeToggle class

    The e-mailed code as a second factor, turned on or off, written once for every host (step R29 of the audit "lesringostars face au master plan"; formerly UserSettingsController::TwoFactorAuthentication_ToggleEmail()): the method the enrolment page (Enrolment) and the settings offer with a button. A demonstration account changes nothing; its form's token (intent "2fa_email", the field _token) is checked through the host's Tokens, 403 without it; turned on only where the administrator allows a second factor, off only when it is not the last one a required second factor leaves. The account told (Notice), then the settings.

    2 methods · 1 constant

  • Enrolment class

    The one-off "your account needs a second factor" page, written once for every host (step R29 of the audit "lesringostars face au master plan"; formerly UserSettingsController::Enrolment()).

    2 methods

  • EnrolmentSkip class

    The enrolment page's "not now", written once for every host (step R29 of the audit "lesringostars face au master plan"; formerly UserSettingsController::EnrolmentSkip()). Its form's token (intent "2fa_enrolment_skip", the field _token) is checked through the host's Tokens: without it, 403. Where the application allows no "later", back to the enrolment page (a hand-made POST gets the same answer as the missing button). Otherwise the session says so (SESSION_ENROLMENT_SKIPPED) and the offer's flag goes; after the offer, the profile and, for a year, a cookie of this browser (SecurityPolicy::COOKIE_NEW_DEVICE_PROMPT_DISMISSED: the only memory there is without a column of the account); after the mandatory enrolment, the settings. The account is told ("@notifications.settings.enrolmentSkipped", info: Notice).

    2 methods · 2 constants

  • Notice class

    How an account action written once for every host tells the account what it did (step R29): the host's own notice where it gives one (omnibridge/laravel: its flash, in the visitor's language), else omnibase's Notifier (Notification::send(), a flash under Symfony).

    1 method

Base\Controller\Action\Widget

  • Page class

    A page of the site's widgets (/page/{slug}: the legal notice, the privacy policy...), written once for every host (step R27 of the audit "lesringostars face au master plan"; formerly WidgetController::Page()): widget/page.html.twig with the page, none of that slug not found.

    2 methods

Base\Database

  • Events class

    4 constants

  • FormerNames class

    The former names of the core's classes that moved to omnibridge/doctrine and omnibridge/symfony (plan "omnibase agnostic", steps F3 and F5b), as data: former => new, read from src/Resources/former-names.{doctrine,symfony}.php, whose lists src/Resources/former-names.php aliases. For what names a moved class the way it was named before - MetadataSnapshot, which compares the mapping and not where a class lives, and the tests.

    3 methods

  • UnitOfWorks class

    omnisense/omnibridge's UnitOfWork for what a service of the core was given (plan "omnibase agnostic", step F2d): the unit of work itself, or a persistence's own manager - Doctrine's entity manager, which the hosts and the applications still hand to the core's services (omnibridge/laravel, the tests, a bundle's own wiring) - adapted once.

    4 methods · 1 constant

Base\Database\Attribute

  • Alias class

    8 methods · 3 properties

  • Associate class

    7 methods · 1 property

  • Blameable class

    Class Blameable package Base\AttributeReader\Abstract\Blameable

    6 methods

  • Cache class

    Caching to an entity or a collection.

    7 methods · 3 properties · 15 constants

  • Cascade class

    3 methods

  • Countify class

    7 methods · 5 constants

  • DiscriminatorEntry class

    4 methods

  • GenerateUuid class

    Class GenerateUuid package Base\Database\Attribute\GenerateUuid

    5 methods · 10 constants

  • Hashify class

    Class Hashify package Base\Database\Attribute\Hashify

    10 methods · 14 properties

  • Hierarchify class

    Class Hierarchify package Base\Database\Attribute\Hierarchify.

    5 methods · 2 properties

  • OrderColumn class

    5 methods · 2 properties · 2 constants

  • OrphanRemoval class

    3 methods

  • Randomize class

    Class Randomize package Base\Database\Attribute\Randomize

    3 methods

  • Slugify class

    Class Slugify package Base\Database\Attribute\Slugify

    7 methods

  • Timestamp class

    Class Timestamp package Base\Database\Attribute\Timestamp

    8 methods

  • Timezone class

    Class Timezone package Base\Database\Attribute\Timezone

    6 methods · 1 constant

  • Trasheable class

    Marks an entity as soft-deletable: `$em->remove()` stamps the deletion field instead of issuing a DELETE, and TrashFilter hides the row from every read.

    4 methods · 3 properties

  • Uploader class

    Class Uploader package Base\Database\Attribute\Uploader

    25 methods · 1 constant

  • Vault class

    16 methods · 3 properties

  • Versionable class

    Marks a property as worth remembering: every flush that changes it appends the old value to the entity's revision history (see VersionableSubscriber, which writes one Revision per entity per flush - not one per field).

    6 methods · 2 properties

Base\Database\Attribute\Backend

  • Backends class

    The persistence's part of each behaviour, by unit of work (plan "omnibase agnostic", step F2b).

    3 methods

  • CacheBackend interface

    #[Cache]'s part of the persistence (plan "omnibase agnostic", step F2b): the cache that keeps entities and their associations between requests (Doctrine's second-level cache). A persistence without such a cache implements it as nothing to do.

    1 method

  • OrderColumnBackend interface

    #[OrderColumn]'s part of the persistence (plan "omnibase agnostic", step F2c): a to-many association the persistence loads lazily keeps its stored positions until it is first read, instead of being loaded at every entity loaded to be sorted. Doctrine: the PersistentCollection's inner collection swapped for an OrderedArrayCollection. A persistence without lazy collections answers false, and the association is sorted at once.

    1 method

  • SlugifyBackend interface

    #[Slugify]'s part of the persistence (plan "omnibase agnostic", step F2b): what the running flush is about to write, so that two new entities of the same flush do not get the same slug, and whether the database still holds a unique index on the slug's column alone (per-type slugs wait for its migration).

    2 methods

  • VaultBackend interface

    #[Vault]'s part of the persistence (plan "omnibase agnostic", step F2b): an entity whose secured field was given a new plain value is written again, though the persistence sees no change in it (the field still holds the value it read, the new one is sealed at the update). Doctrine: the unit of work's scheduleForUpdate().

    1 method

Base\Database\Attribute\Extension

Base\Database\Backend

  • BulkDeletes interface

    Rows deleted by criteria in one statement, their entities never read (plan "omnibase agnostic", step F2e): what is recorded about an entity destroyed for good (its revisions, its trash entry's siblings). Doctrine's is a DQL DELETE; registered per unit of work in Base\Database\Attribute\Backend\Backends.

    1 method

  • ColumnTypes interface

    What a persistence knows of its column types that the core's code asks (plan "omnibase agnostic", step F5c, item 3): whether a field of a type holds a PHP array, which EntityHydrator gives an empty one by default.

    1 method

  • ConditionalUpdates interface

    One field of an entity's row written only if it still holds a value, in a single statement (plan "omnibase agnostic", step F2d): of two requests claiming the same sign-in link at once, one wins. Doctrine's is a DQL UPDATE ... WHERE id = :id AND field = :from; registered per unit of work in Base\Database\Attribute\Backend\Backends.

    1 method

  • EntityCache interface

    The cache a persistence keeps of entities between requests (plan "omnibase agnostic", step F2d): what is evicted when a row is written behind it.

    3 methods

  • RowLocks interface

    An entity's row locked for writing while some work runs, in a transaction (plan "omnibase agnostic", step F2d): the work sees no concurrent write of that row - a double click on "like" makes one Like, not two. Doctrine's is a pessimistic write lock (SELECT ... FOR UPDATE); registered per unit of work in Base\Database\Attribute\Backend\Backends.

    1 method

Base\Database\Common\Collections

Base\Database\Entity

  • EntityExtension class

    2 methods · 6 constants

  • EntityExtensionInterface interface

  • EntityHydrator class

    An entity filled from data, or turned into data, and an entity rebuilt as it was read (plan "omnibase agnostic", step F5c, item 3: on omnisense/omnibridge's UnitOfWork and the entities' shapes, no ORM's metadata). What it reads of the mapping is the entity's EntityShape (fields, their types and nullability, associations, their kind, side, target and mappedBy, the identifier) and its aliases (EntityFields); what it asks of the persistence goes through the unit of work (references), its repositories (UnitOfWorks::repositories(): an association by id, uuid or slug), its Snapshots (the original values) and its ColumnTypes where it registers one (which types hold an array).

    12 methods · 14 constants

  • EntityHydratorInterface interface

    3 methods

  • EntityValues class

    An entity's values as the behaviours read and write them, on the shapes of the unit of work's persistence (plan "omnibase agnostic", step F7c): what omnibridge/doctrine's ClassMetadataManipulator does with Doctrine's metadata (getFieldValue(), setFieldValue(), getPropertyValue(), setPropertyValue()), with omnibase's EntityShapes in its place, so that the same calls give the same values whichever persistence keeps the entity.

    13 methods

Base\Database\Entity\AggregateHydrator

Base\Database\Entity\Extension

Base\Database\Entity\Extension\Type

Base\Database\Lifecycle

  • RevisionRecorder class

    What a revision records, whatever persistence writes it (plan "omnibase agnostic", step F2b): the diff of an entity's #[Versionable] properties, their values in a comparable form, and the revision entry - not twice for the same diff in a row.

    4 methods

  • SettingsInvalidation class

    The SettingBag's snapshot emptied at every Setting or SettingIntl written, whatever writes it (the admin CRUD's plain flush included), on omnisense/omnibridge's neutral lifecycle events (plan "omnibase agnostic", step F2b). Base\EntitySubscriber\SettingSubscriber relays Doctrine's to it.

    4 methods

  • ThreadParticipants class

    Who takes part in a thread besides its owners, on omnisense/omnibridge's neutral lifecycle events (plan "omnibase agnostic"): the followers of a reply and the users its text mentions.

    5 methods

  • TrashRecorder class

    What a soft delete is, whatever persistence cancels the deletion (plan "omnibase agnostic", step F2b): which removal becomes a trashing, and the trash entry the trash listing and the purge read.

    4 methods

Base\Database\Mapping

  • Completor class

    What omnibase's attributes add to an entity class's mapping, as plain data (plan "omnibase agnostic", step E3): #[Alias]'s names (`aliasNames`, alias => property), #[Hierarchify]'s hierarchy (`entityHierarchy`, `entityHierarchySeparator`)... Completors::of() fills it from the class's attributes (their complete() hook), on no ORM. omnibridge/doctrine's ClassMetadataCompletor is this class under its former name.

    6 methods

  • Completors class

    Each entity class's completor - what omnibase's attributes add to its mapping (#[Alias]'s names, #[Hierarchify]'s hierarchy) - read from the class itself, on no ORM (plan "omnibase agnostic", step E3). It was written by the attributes' loadClassMetadata() into Doctrine's metadata as Doctrine loaded it, then cached by omnibridge/doctrine's ClassMetadataManipulator: a manipulator made again over an empty cache (a second kernel in the same process, in eloquent mode) answered without the aliases until the cache was cleared. Here it is the attributes' complete() hook, run over the class's attributes as omnibase's AttributeReader gives them to the mapping - the class's own, its methods' and its properties' (its own and the inherited ones that are not private) -, once per class and process: the same answer whichever persistence maps the class, and Doctrine's manipulator answers from here too.

    2 methods

  • DescriptionShapes class

    The entities' shapes read from a Description (plan "omnibase agnostic", step F2c): Base\Database\Schema\ Describer's (built from the entities' folders without any ORM), or a JSON file's. Mapped superclasses and embeddables have a shape, and are no entities for has().

    4 methods

  • EntityFields class

    An entity's properties by the names the core's code gives them, on no ORM (plan "omnibase agnostic", step F5c, item 3): its fields and associations from its shape, and its aliases - a property bound to another by #[Alias] (Gallery's "galleries" to "children") -, read from the attributes. What ClassMetadataManipulator's getFieldNames(), getFieldName(), resolveFieldPath() and fetchEntityName() answered from Doctrine's metadata and its completor (the aliases Alias::loadClassMetadata() wrote there), for EntityHydrator.

    9 methods

  • EntityShape class

    What the core's code reads of an entity's mapping, on no ORM (plan "omnibase agnostic", step F2c): its class, root, identifier, fields and their types, associations and their kind, side and target, and its discriminator - one Omnibridge\Schema\Entity of the application's Description.

    23 methods · 1 property

  • EntityShapes interface

    The entities' shapes (plan "omnibase agnostic", step F2c): from a Description (DescriptionShapes), or from the installed persistence (Base\Bridge\Doctrine\DoctrineShapes on Doctrine).

    2 methods

  • MetadataManipulator class

    What omnibase's AttributeReader and the attributes ask of the entities' mapping, read from the entities' shapes - the Description (Omnibridge\Schema) a persistence maps them with - and their completors, on no ORM (plan "omnibase agnostic", step E3). omnibridge/doctrine's ClassMetadataManipulator answered them from Doctrine's ClassMetadataFactory, so the reader, the behaviours on writes and the aliases (#[Alias]) needed doctrine/orm installed whatever the persistence; it extends this class now and keeps Doctrine's own (the mappings, the entity manager, the forms').

    45 methods · 1 constant

Base\Database\Repository

  • BackendOnly class

    A repository method that only the persistences named run (plan "omnibase agnostic", step E2): its query is no finder (Base\Database\Repository\Finder) but the backend's own language - native SQL with an upsert or a DATE() grouping, a bulk UPDATE -, so no persistence compiles it from the core: each one named writes the method in its own terms, any other refuses it aloud with refuse(), never answers it silently wrong.

    5 methods · 2 properties

  • Entities interface

    The entities of one class, whatever keeps them: what an application asks every repository of omnibase, with nothing of the ORM in what it takes or gives back - arrays of criteria and of order (field => ASC|DESC), the entities themselves, lists of them, integers.

    8 methods

  • Repositories interface

    The entities of any class, by its name (audit "lesringostars face au master plan", step R28): what code that is handed a class at run time - a form field's choices, a command over every uploading entity, the search's sort by hierarchy - asks, where it called the entity manager's getRepository() before. Nothing of the ORM in or out.

    3 methods

  • UnsupportedQueryException class

    A repository method the persistence installed does not run: declared #[BackendOnly] for another one (plan "omnibase agnostic", step E2), refused aloud rather than answered wrong.

Base\Database\Repository\Finder

  • Criterion class

    One criterion of a finder: a field (a path, "image.source"), the value it is compared with, and the words of the language that say how (EqualTo, YoungerThan, Partial, Insensitive, ClosestTo, InstanceOf...). $index numbers the criteria a name declares on the same field (findByIdGreaterThanAndIdLowerThan: id 0, id 1); null for a criterion given in the criteria array, compared for equality (or IN for a list).

    5 methods · 4 properties

  • Group class

    A parenthesised part of a finder: a name of the language and its arguments, given as one entry of the criteria array (plan "omnibase agnostic", step E2).

    6 methods

  • Key class

    A to-one association compared by its key, without a join (plan "omnibase agnostic", step E2b): the value of a criterion, given in the criteria array or to a name of the language.

    3 methods · 1 constant

  • Parser class

    The finder language of omnibase - findByEmailAndUsername(), findOneBySlug(), cacheOneByStateAndSlugStartingWith(), countByStateAndPublishedAtYoungerThan(), findPreviousOneByClassOfAndState(), lengthOfTagsBy()... - read from a method's name and its arguments into a Query: the request, the internal method it leads to, its arguments, the criteria the name declares with their options (EqualTo, NotEqualTo, GreaterThan, LowerThan, GreaterEqualTo, LowerEqualTo, YoungerThan, OlderThan, Within, IsOver, StartingWith, EndingWith, Null, Empty, True, False and their Not..., Insensitive, Partial, ClosestTo, FarestTo, InstanceOf, ClassOf, MemberOf, But, WithRoute, Model), the separator (And, Or), the column (countFor...By, lengthOf...By), the specials (One, All, Randomly, AtMost<N>, Last<N>, LastOne, Previous<N>, PreviousOne, Next<N>, NextOne), cache and Eagerly; since step E2, the aggregates sumOf<Column>By, minOf<Column>By and maxOf<Column>By, and the groups (Group::by('AOrB', ...) as an entry of the criteria array: a parenthesised part of the finder, read by this parser; since step B1b also Group::of() from its members, read already); since step E2b, a to-one association compared by its key without a join (Key::of($x), a criterion's value, EqualTo or NotEqualTo only).

    6 methods · 64 constants

  • Query class

    A finder call read by the Parser: the neutral form of the finder language, which a persistence compiles into its own queries.

    3 methods · 10 properties

  • Subject interface

    What the finder language asks of the entity a finder is called on, whatever keeps it: Doctrine's metadata (ServiceEntityParser), Eloquent's tables from Omnibridge\Schema (omnibridge/eloquent), or anything that knows its fields.

    4 methods

Base\Database\Schema

  • DiscriminatorRule class

    omnibase's discriminators, as Base\Bridge\Doctrine\MappingDriver and #[DiscriminatorEntry] give them to Doctrine (plan "omnibase agnostique", C6), on the description built without it:

    4 methods

  • EntitySchema class

    The schema of omnibase's entities and an application's, with no persistence installed (plan "omnibase agnostic", answer 11 and step F7a): their description (Omnibridge\Schema\Description) built from the entities' folders - their declarations read by reflection, omnibase's naming and its rules in the order Doctrine's listeners run them -, and what omnibase's own column types are (Omnibridge\Schema\Database\ColumnTypes): its enumerations' and sets' values, the serialized arrays and the passkeys' columns as the portable types they are written as.

    6 methods · 1 constant

  • ExtensionRule class

    The extensions' index, as Base\EntitySubscriber\ExtensionSubscriber gives it to Doctrine: on AbstractExtension's table, <table>_entity over entityClass and entityId (an index, not a unique constraint: a Revision is one row per flush).

    3 methods

  • OrderColumnRule class

    #[OrderColumn(orderBy: ...)]'s column, as the attribute gives it to Doctrine: on a to-many relation or a set column, the field named by orderBy is mapped if nothing maps it - a nullable json column, where the positions are kept; a property that is an #[Alias] of a relation counts as that relation. The set types by name, to know a set column (omnibase's enumerations: Base\Bridge\Doctrine\Types::enumerations()).

    4 methods

  • TargetRule class

    The targets resolved, as Doctrine's ResolveTargetEntityListener resolves them (DoctrineBundle's resolve_target_entities, Mapping::register()'s option): a relation toward an interface points to the class the application gave for it, the rest of the relation as it was.

    4 methods

  • TranslationRule class

    The translations' mapping, as Base\DatabaseSubscriber\IntlSubscriber gives it to Doctrine, on the description built without it:

    3 methods · 4 constants

  • VaultRule class

    #[Vault]'s constraints, as the attribute gives them to Doctrine: the unique constraint <table>_unique over the columns it names, and on the root of a translation hierarchy its vault column added to <table>_unique_translation (before translatable_id and locale: TranslationRule comes after).

    3 methods

Base\Database\Scope

  • TrashScope class

    The trashed rows left out of every read (plan "omnibase agnostic", step F2e): an entity whose class, or a parent's, is #[Trasheable] is read only while its deletion field is null. Base\Service\TrashManager::withTrash() disables it to look at the trash. Doctrine compiles it as its SQL filter "trash_filter" (Base\Database\Filter\TrashFilter).

    3 methods · 1 constant

  • VaultScope class

    The rows of another environment's vault left out of every read (plan "omnibase agnostic", step F2e): an entity whose class is #[Vault] is read when its vault field is null or names the environment the scope was enabled with ("environment"). Doctrine compiles it as its SQL filter "vault_filter" (Base\Database\Filter\VaultFilter).

    4 methods · 1 constant

Base\Database\Type

  • EnumType class

    An enumeration of omnibase: its values are its constants (UserRole::ADMIN = "ROLE_ADMIN"), with their icons, colours and texts, grouped by the "_" of their values. A plain PHP class, no type of an ORM (plan "omnibase agnostic", step F2a): a persistence maps a column named by getStaticName() to it - on Doctrine Base\Bridge\Doctrine\EnumTypeAdapter, registered under that name for each enumeration (Base\Bridge\Doctrine\Types), with the values converted by toDatabaseValue() and toPHPValue(). Base\Database\Type\Enumerations knows them by name. Until F2a it was Doctrine's Type itself.

    16 methods

  • Enumerations class

    omnibase's enumerations by the name a column's type gives them (user_role => Base\Enum\UserRole, or the application's App\Enum\UserRole): what code that holds a column's type asks to reach its enumeration, whatever persistence maps it (plan "omnibase agnostic", step F2a). Filled by the persistence when it registers them (Base\Bridge\Doctrine\Types on Doctrine).

    3 methods

  • SetType class

    An enumeration whose field holds a set of its values (UserRole: an account's roles), kept as those values joined by commas (a MySQL SET). A plain PHP class (plan "omnibase agnostic", step F2a): Base\Bridge\Doctrine\EnumTypeAdapter maps it on Doctrine.

    3 methods

  • Utc class

    Moments in UTC, for the code around a `utc_datetime_immutable` column: the present, and any date as the same moment in UTC - what a query parameter compared with such a column must be when it is bound without its type.

    3 methods

Base\Demo

  • DemoAccount class

    A demonstration account, as a bundle or the application declares it (DemoAccountProviderInterface): who signs in, as what, and what that role sees. The fixtures create the accounts from these declarations (DemoAccountFactory); in the `demo` environment the sign-in page offers one button for each (docs/20-architecture/demo.md).

    4 methods · 9 properties

  • DemoAccountFactory class

    The declared demonstration accounts as rows: what the fixtures call instead of writing each account by hand, and what `demo:reset` calls after them so that every declared account exists.

    5 methods

  • DemoAccountLock class

    A demonstration account stays what its declaration says (plan "omnibase agnostic", step F5a: the logic of Base\DatabaseSubscriber\DemoAccountLockSubscriber, on no persistence nor host): its identifier, its address, its password, its second factor are put back as the database had them, it is not disabled. The persistence's listener gives each account's original row and how to read and write its columns; the host says the message.

    4 methods · 1 constant

  • DemoAccountProviderInterface interface

    Declares demonstration accounts: implemented by a bundle for the roles of its trade (a practitioner, a secretary, a patient) and by the application for its own. Autoconfigured (tag base.demo_account_provider); the application's declaration replaces a bundle's for the same identifier.

    1 method

  • DemoAccountRegistry class

    Every demonstration account declared by the bundles and the application (DemoAccountProviderInterface), by identifier. The application's declarations come last and replace a bundle's; base.demo.exclude drops the ones a site has no use for.

    11 methods · 1 constant

  • DemoGuard class

    What the `demo` environment refuses to start on (BaseBundle::boot() asks, for a page as for a command):

    3 methods

  • DemoMode class

    Whether the kernel runs the demonstration: the `demo` environment, and no other. There is no switch to turn it on elsewhere - what it lifts (the staff's second factor) and what it offers (signing in as anyone declared) has no place on a production site.

    2 methods · 1 constant

  • DemoSignIn class

    Signing in as a demonstration account in one click, written once for every host (plan "omnibase agnostic", step F5e, slice 5; formerly DemoController::Login()): the `demo` environment only, a POST with its token (never a link a prefetch would follow), a declared account only, and never one that opens the back office (base.demo.admin_roles) or reaches ROLE_SUPERADMIN - declared so or promoted since: those sign in with their secret. A refusal is said and leads back to the sign-in page.

    3 methods · 2 constants

Base\Entity

Base\EntityDispatcher

  • AbstractEvent class

    NB: Flushing object manager from within listener should be avoided, this is done already in event dispatcher if needed.

    9 methods

  • AbstractEventDispatcher class

    An entity dispatcher notes events before a write (persisting(), updating(), removing(): addEvent()) and dispatches them once the write is done, through any PSR-14 dispatcher (user.register, thread.published...).

    27 methods · 2 constants

  • EventDispatcherInterface interface

    An entity dispatcher (AbstractEventDispatcher). The methods typed on doctrine/persistence's LifecycleEventArgs are deprecated since omnisense/omnibase 5.x and leave at 6.0: AbstractEventDispatcher's neutral hooks (persisting(), updating(), removing()) and its entry lifecycle() need no Doctrine package (plan "omnibase agnostic", step B leftover (a)).

    6 methods

  • EventInterface interface

    3 methods

Base\EntityDispatcher\Event

  • ThreadEvent class

    1 method · 3 constants

  • ThreadEventDispatcher class

    3 methods

  • UserEvent class

    The user.* events: UserEventDispatcher dispatches user.register when an account is persisted, and each other one when an update puts the account in that state (approved, verified, enabled, disabled, kicked out, locked, newcomer, banned; user.ghost when it stops being a ghost).

    1 method · 10 constants

  • UserEventDispatcher class

    3 methods

Base\EntitySubscriber

  • ConnectionSubscriber class

    6 methods

  • ThreadSubscriber class

    The threads' kernel events (thread.scheduled, thread.publishable: the state, the authors' and the mentionees' mails) and the Doctrine wiring of their followers and mentions (prePersist, onFlush), whose logic is Base\Database\Lifecycle\ThreadParticipants, on the neutral lifecycle events.

    6 methods

  • UserSubscriber class

    What an account's owner is told when the account changes (UserEventDispatcher raises the events): a registration asks to verify the address, an approval is confirmed, an account its owner closes is said goodbye to, one reopened welcomed back. Each notification goes out with its importance, through the site's channel policy (framework.notifier.channel_policy).

    9 methods · 2 constants

Base\Entity\Analytics

  • PageView class

    One row per (path, HOUR, source) - an hourly rolling aggregate, not a per-request event log. $views is incremented atomically (see PageViewRepository, which buckets any timestamp down to the top of its hour before writing) on every trackable request; time windows ("24h", "7 days", "all time") are just a SUM over however many of these rows fall in range, and a calendar-day figure (dailyBreakdown()) is itself a SUM over that day's up-to-24 hourly rows rather than its own storage grain - this is what lets "today" plot an hour-by-hour curve instead of the single flat point a pure daily rollup could ever produce.

    9 methods · 3 constants

  • PageVisit class

    An HOURLY PRESENCE record per page: at most one row per (hour, path, subjectType, subjectId), inserted on first sight and ignored afterwards - the same mechanism as Visit, with the path added.

    9 methods

  • Visit class

    An HOURLY PRESENCE record, not a per-request event log: at most one row per (hour, subjectType, subjectId) - see VisitRepository, which buckets any timestamp down to the top of its hour before writing - inserted on first sight that hour and ignored on every later request the same hour.

    7 methods · 2 constants

Base\Entity\Extension

  • Revision class

    One entry of an entity's modification history: what changed in a single flush, as `entityData = {"<field>": [old, new]}`.

    8 methods

  • TrashBall class

    4 methods

Base\Entity\Extension\Abstract

Base\Entity\Hours

  • ScopedWeek class

    The usual week of one place, when a site has several: a shop among the shops, a practice among the practices. The place is a scope key - any string its owner chooses ("store:12"), or an entity (Base\Service\OpeningHours::scopeOf()).

    5 methods

  • SpecialDay class

    A day (or a run of days) off the usual week: closed (holidays, a bank holiday), or open at other hours ([["10:00","14:00"]]). Read by Base\Service\OpeningHours everywhere (the day an order is for, the time slots, the footer, a banner, the JSON-LD's specialOpeningHoursSpecification).

    15 methods

  • WeekDayHours class

    The usual hours of one day of the week: [["09:00","13:00"],["16:30","19:00"]], or none (closed). No row at all: the week the site was configured with (base.opening_hours.week), read by Base\Service\OpeningHours. Special days (SpecialDay) override a date.

    5 methods

Base\Entity\Layout

  • Attribute class

    5 methods

  • AttributeIntl class

    6 methods

  • Image class

    23 methods

  • ImageCrop class

    40 methods

  • ImageCropInterface interface

    16 methods

  • ImageInterface interface

    5 methods

  • Redirection class

    An address the site no longer answers, and where it leads now: the pages of a site taken over (/produit/enseigne-lumineuse/ -> /savoir-faire/enseigne), a page renamed. Asked only when a request ends in "not found" (Base\Subscriber\RedirectionSubscriber): a page that exists is never shadowed, and a page that is found costs nothing.

    17 methods · 3 constants

  • Semantic class

    15 methods

  • SemanticIntl class

    4 methods

  • Setting class

    14 methods

  • SettingIntl class

    11 methods

  • ShortLink class

    8 methods

  • ShortLinkIntl class

    4 methods

  • TextOverride class

    A text of the site, as the team rewrote it from the back office: it replaces the one in translations/ for that key, domain and language (Base\Translation\OverridingTranslator), on every page and in every e-mail. Deleting it brings the original back. Same syntax as the original: {placeholders}, ICU plurals. Moved here from the apps' App\Entity\TextOverride (table textOverride there; this one is layoutTextOverride, so an app not moved yet keeps its own).

    12 methods

  • Tooltip class

    14 methods

  • TooltipIntl class

    4 methods

  • Widget class

    17 methods

  • WidgetIntl class

    8 methods

Base\Entity\Layout\Attribute

Base\Entity\Layout\Attribute\Adapter

Base\Entity\Layout\Attribute\Adapter\Common

Base\Entity\Layout\Attribute\Common

Base\Entity\Layout\Widget

Base\Entity\Layout\Widget\Set

Base\Entity\Signature

  • AbstractEnvelope class

    What an envelope keeps (Base\Entity\Signature\Envelope): what it is about - any entity, by its class and id -, the omnisense/omnisign gateway it went through and that gateway's reference, where it stands, its signers, and the signed document and its evidence once kept in the private storage. A mapped superclass: no table of its own; Envelope is an entity only when omnisense/omnisign is installed.

    19 methods · 6 constants

Base\Entity\Thread

  • Comment class

    What a visitor leaves under a thread (a blog post, a sequence, a video) - or, with no thread, in the site's visitors' book: a name, an e-mail (never shown), a site, a text, and for a reply the comment it answers. Signed in, the author is kept too. Moved here from omnibase/blog.

    39 methods · 1 property

  • Like class

    10 methods

  • Mention class

    11 methods

  • Tag class

    17 methods

  • TagIntl class

    6 methods

  • Taxon class

    23 methods

  • TaxonIntl class

    6 methods

Base\Entity\User

  • Address class

    28 methods

  • Complaint class

    A user's complaint about another one (or about something), for the staff to answer.

    35 methods · 4 constants

  • Connection class

    35 methods

  • Group class

    Open to extension the way User is: JOINED inheritance on a `class` discriminator, so an application can add its own group (a leader, a motto, a join mode...) as a subclass in its own table, while roles, permissions, rules, scopes and actions keep working on the base row. An application without a subclass sees no change but the discriminator column.

    36 methods · 1 constant

  • Identity class

    An account's identity at a provider (Google...): the provider's own identifier of the person ("sub"), which is what links the account - never the address alone (plan "omniauth", Marco's decision QA3). omniauth's Contract\Identities over this table is Base\Auth\UserIdentities.

    10 methods

  • Invitation class

    An e-mail that opens something: whoever follows its link before it runs out gets an account (or signs in with theirs), attached to what it was made for. Only the token's hash is kept; the token itself is sent, never stored (Base\Service\Invitations).

    13 methods

  • Notification class

    A notification: its subject, content, importance, channels, recipients, context and templates, and its sending through omnibase's notifier. Cut in two (plan "omnibase agnostique", step C3f): what needs Symfony - an ExceptionEvent or a FlattenException made content, render()'s Response, the e-mail built on Twig's TemplatedEmail and HttpFoundation's uploaded files - is Base\Bridge\Symfony\NotificationMessages'; this class names nothing of the framework (Symfony's Notifier is a standalone component).

    60 methods · 5 constants

  • Passkey class

    A passkey of an account (WebAuthn's credential record), described by the core (plan "omniauth", AU1; decision O6): its 13 fields are its own attributes, no longer inherited from web-auth's Webauthn\CredentialRecord and mapped by WebauthnBundle's XML, so the table is described once, read the same by any host (the Laravel twin maps it as Symfony does) and the entity loads nothing of webauthn-lib. The columns are those the bundle made (userPasskey, Version20260726133116 on lesringostars): the same names, and the types passkey_base64, passkey_aaguid and passkey_trust_path (omnibridge/doctrine's Passkey\{Base64, Aaguid, TrustPath}; named by their names, so the attributes read with no persistence installed) declare the same SQL and write the same text as the bundle's `base64`, `aaguid` and `trust_path` - no migration, a row written by either read by the other.

    9 methods · 13 properties

  • Penalty class

    A penalty an administrator has defined, NOT one somebody has received.

    21 methods

  • Permission class

    19 methods

  • PushSubscription class

    One browser's Web Push endpoint for one user. A person has one of these per browser they enabled notifications in (phone, laptop, ...), and each one dies on its own when the browser revokes it - the push service then answers 404/410 and WebPushService prunes the row.

    17 methods

  • Sanction class

    One penalty, given to one user, once.

    19 methods

  • Token class

    38 methods · 3 constants

Base\Entity\User\Attribute

  • GroupAction class

    What a group DOES for somebody who qualifies for it.

    5 methods

  • GroupRule class

    A condition a user must satisfy for a group to be open to them.

    5 methods

  • GroupScope class

    Who a group's rules are about in the first place.

    5 methods

Base\Entity\User\Attribute\Action

Base\Entity\User\Attribute\Scope

  • GroupAdapter class

    Narrows something to the members of another group.

    6 methods

  • UserAdapter class

    Narrows something to named people.

    6 methods

Base\Enum

  • Allergen enum

    The fourteen allergens a food business must declare in the European Union (Regulation (EU) No 1169/2011, Annex II), in the Annex's order. A plain string enum: stored as is (a JSON list of values on a dish, a varchar), labelled through the "enums" translation domain (allergen.<value>).

    4 methods · 14 cases

  • CommentState enum

    Where a comment is: waiting for the moderator, online, filed as spam, or taken down. A string enum (not omnibase's EnumType) so the column reads plainly in the database and in the admin's filters.

    1 method · 4 cases

  • ConnectionState class

    2 methods · 4 constants

  • EntityAction class

    2 methods · 3 constants

  • LogLevel class

    2 methods · 4 constants

  • Operation class

    2 methods · 6 constants

  • SpamApi class

    2 methods · 1 constant

  • SpamScore class

    3 methods · 4 constants

  • ThreadState class

    4 methods · 7 constants

  • UploadState class

    2 methods · 3 constants

  • UserGender class

    2 methods · 4 constants

  • UserRole class

    3 methods · 4 constants

  • UserState class

    2 methods · 8 constants

  • WorkflowState class

    2 methods · 6 constants

Base\Enum\Quadrant

Base\Enum\SystemOfUnits

Base\Event

  • SignatureEvent class

    An envelope moved (Base\Service\Signatures): completed, declined, expired, canceled - or a signer signed. The application answers on what it is about: a quote accepted once signed, a lease in force.

    4 methods · 5 constants

  • SitemapEvent class

    Dispatched while /sitemap.xml is being built, once the routes carrying a Sitemap attribute have been registered.

    3 methods · 1 constant

Base\Exception

Base\Field

Base\Field\Behaviour

  • AbstractBehaviour class

    A behaviour's plain parts: its defaults under the given options, no vars, the value as it is both ways, no front end, no route. The generic binder (Base\Form\Definition\FormBinder) completes a value a behaviour leaves as a string by its kind's rule (a date, a number).

    6 methods

  • Association class

    A related record's form embedded in its owner's (Kind::ASSOCIATION; plan "omnibase agnostic", step F5d, slice 7), as omnibase's AssociationType builds it, on every host: one record, its fields; or several (a to-many association), a collection (Collection) whose every entry is one record's form - an article's comments, a comment's replies. What AssociationType decides itself is here, and it asks it:

    9 methods · 3 constants

  • AssociationFile class

    Records made from uploads (Kind::ASSOCIATION_FILE, plan "omnibase agnostic", step F5d): a gallery's photos, a photo's image - what omnibase's AssociationFileType decided, on every host. The field is a compound holding one upload field (Upload: file, image or avatar) named by the first part of `entity_file`, the path from the related record to its file ("image.source": a photo's image's source). What the type decided itself is here, and it asks it:

    13 methods · 2 constants

  • Attribute class

    A record's attributes (Kind::ATTRIBUTE; plan "omnibase agnostic", step F5d, slice 7) - an account's hyperlinks -, as omnibase's AttributeType builds them, on every host: a select of the adapters offered (searched remotely, the field's `filter` narrowing them to its adapters' classes), then, for each attribute held, its value drawn by its adapter's field (a hyperlink's pattern, a number...). What AttributeType decides itself is here, and it asks it:

    8 methods · 1 constant

  • Behaviours class

    The behaviour of each kind, as every host asks it (plan "omnibase agnostic", step F5d): kind => an Omnibridge\Form\FieldBehaviour. The Symfony form types read their options and vars from it, the neutral FormView and FormBinder (Laravel's, React's props) too. A kind without a behaviour is a plain value its kind's generic rule reads (Kind::INPUT_TYPES, FormBinder).

    6 methods

  • ChoiceList class

    Kind::LOCALE: a plain select of the locales Intl names (Symfony's LocaleType), its choices given when the field names none.

    1 method

  • Choices class

    The choices a choosing kind offers when the field names none: an enum's (a PHP enum's cases, or one of omnibase's EnumType or SetType values: the role, the state, the gender), the countries, the locales - what Symfony's types guess or load themselves (FormGuessTrait::guessChoices(), CountryType, LocaleType).

    3 methods

  • Collection class

    A list of entries drawn one under the other (Kind::COLLECTION, Kind::ARRAY; plan "omnibase agnostic", step F5d, slice 7), as omnibase's CollectionType and ArrayType decide it, on every host. They ask it:

    7 methods · 2 constants

  • ColorPickr class

    Kind::COLOR_PICKER: a colour picked in Pickr (its settings in `pickr`, the swatches and the buttons' words included), shown as #RRGGBBAA: a short colour completed with an opaque alpha, anything else as the transparent black, which is no colour when the field may be empty (`is_nullable`).

    3 methods · 2 constants

  • CountrySelect class

    Kind::COUNTRY: a select2 of the countries (Base\Field\Choice\Countries), with their flags (use_html).

    1 method

  • DateTimePicker class

    Kind::DATETIME_PICKER: a date (and time) typed or picked in flatpickr. Its value is shown and read in the field's ICU `format` (yyyy-MM-dd HH:mm by default; a date-only picker gives yyyy-MM-dd), the picker's settings in `datetimepicker`, merged over the defaults key by key: a caller that turns the time off keeps the page's language.

    5 methods · 1 constant

  • Editor class

    Kind::EDITOR: an Editor.js document (forms/form-type-editor.js) kept as JSON in a hidden input - what omnibridge/symfony's EditorType decided, which it now asks.

    3 methods

  • Guess class

    What a field's options leave out and the record's mapping says, as omnibase's Symfony types guess it from Doctrine (FormGuessTrait, SlugType): read from the entity's shape on any host (the unit of work's EntityShapes) - the class a select chooses among (an association's target, an enumeration column's class) and whether it holds several (a to-many association, a set enumeration), and whether a slug may be empty (its column nullable).

    1 method

  • Icon class

    Kind::ICON: a select2 of the icon provider's icons, always searched remotely (ux_autocomplete_icons, 200 a page, the provider's adapter: the parameter base.icon_provider.default_adapter, Font Awesome's by default).

    2 methods

  • JsColor class

    Kind::COLOR: a colour typed or picked in jscolor, shown as #RRGGBBAA (an empty one as #00000000), kept as short as it can be written (#F00); the transparent black is no colour when the field may be empty (`is_nullable`).

    3 methods · 1 constant

  • Number class

    Kind::NUMBER: a number shown in the page's language (48,857 in French, as Symfony's NumberType writes it: its scale, else three decimals at most; grouping off by default), divided by `divisor` when shown and multiplied back when read, its prefix and suffix stripped; the steppers' settings (step, throttle, min, max, the keys) for the number script.

    3 methods

  • Password class

    Kind::PASSWORD: omnibase's password, typed twice by default (`plain`, then `plain_repeater`, as PasswordType names its two inputs), its strength shown (hint, the strength bounds) and checked; the value is what was typed, untrimmed, refused when the two inputs differ.

    4 methods

  • RecordFields class

    A record's fields as a form embedding it lists them (plan "omnibase agnostic", step F5d): what ClassMetadataManipulator::getFields() answers omnibase's TranslationType and AssociationType from Doctrine's metadata, read here from the entity's shape (the unit of work's EntityShapes) on any host.

    3 methods · 1 constant

  • Select class

    Kind::CHOICE and the kinds that choose among a list (role, state, gender, country, currency, locale, icon, an association picked rather than embedded): a select2 select, its entries given or searched remotely.

    8 methods

  • Slug class

    Kind::SLUG: an address's word, made from another field as it is typed (its `target`, a path in the form: "translations.title" is the default language's title) and locked once written by hand. Its settings are the slug script's: the separator, the characters kept, upper case, whether anything else is dropped (strict, by default when nothing is kept), the lock.

    2 methods

  • Toggle class

    Kind::BOOLEAN: a switch, asking for a confirmation when it is ticked or unticked (both by default), possibly saved at once through a toggle route (`toogle_url`, the option's historical spelling).

    1 method

  • Translation class

    A translations field (Kind::TRANSLATION, plan "omnibase agnostic", step F5d), as omnibase's TranslationType builds it, on every host: one part per language, each the translation entity's fields (RecordFields, the entity's shape). What TranslationType decides itself is here, and it asks it:

    11 methods

  • Upload class

    A file sent with its form (plan "omnibase agnostic", step F5d): what omnibase's FileType and its children (ImageType, AvatarType, AudioType, VideoType) decided, which they now ask - their options, and what their blocks read of the record's files: the stored files' public addresses, thumbnails, previews, download links, the largest size and the types accepted (the record's #[Uploader] and #[File]), the dropzone's settings and its address (Base\Field\Upload\Dropzone), the cropper's. The same on every host: the Symfony types read it, the neutral FormView gives it to omnibridge/laravel's renderer.

    8 methods · 1 property · 8 constants

  • Wysiwyg class

    Kind::WYSIWYG: an HTML text written in Quill (forms/form-type-wysiwyg.js), kept in a hidden input - what omnibridge/symfony's WysiwygType decided, which it now asks. Its settings are Quill's: the theme, the toolbar's modules, the placeholder, the height; no route. The widget's id has its dashes made underscores (a translation's fr-FR part: Quill's script reads the id as a name).

    1 method · 1 constant

Base\Field\Choice

  • Countries class

    The countries a country field offers, neutral (symfony/intl only): their names by code, the codes added by an application, those left out for want of a flag. Base\Field\CountryField reads its choices here, so describing a country field loads no form library; CountryType (Symfony) delegates here.

    6 methods

Base\Field\Conformance

  • Host interface

    A host as the field conformance suite drives it (Suite): its name (the one Base\Field\Kinds knows its coverage by), a definition drawn as the host draws it for a page, a submission bound and validated as the host processes it.

    3 methods

  • Outcome class

    A submission's outcome on a host: the data as bound, the errors by field name ("" for the form's own).

    1 method · 2 properties

  • Sample class

    One kind as the conformance suite tries it: a field of that kind named `value`, the data it starts from, what the page shows of it, what a visitor sends (under the field's name, as that host's markup sends it), the value the data then holds, and a value the field refuses.

    3 methods · 11 properties · 2 constants

  • Samples class

    A sample of every kind the core names (Kind::all()), as Symfony draws and reads it: the reference every other host conforms to. The page's language is French (fr-FR), the host's test sets it.

    2 methods

  • Suite class

    The field conformance suite (plan "omnibase agnostic", step F5d), the same on every host: a host's coverage declares every kind (Kinds::faults()), and each kind it implements draws its field, shows the data's value, binds what is sent to the same value, refuses what it cannot read. A kind it declares unsupported is refused aloud when drawn (a host's exception), never a plain input.

    5 methods · 2 constants

Base\Field\Editor

  • EditorJs class

    An Editor.js field's routes, answered for any host (plan "omnibase agnostic", step F5d): what omnibase's EditorController answered under Symfony, moved here as it was, so that every host serves an editor at the same addresses (ROUTES) with the same answers.

    17 methods · 6 constants

Base\Field\Option

Base\Field\Search

  • Answer class

    What a remote search answers (RemoteSearch): its status and its JSON body - the page of entries ({pagination, results}) or the reason it refused, a string, as omnibase's AutocompleteController answered them. Each host sends it as its JSON response.

    3 methods · 2 properties

  • ExchangeRate class

    A money field's exchange rate (/ux/autocomplete/currency/{source}/{target}/{data}), written once for every host (plan "omnibase agnostic", step F5e, slice 5b; formerly AutocompleteController::Forex()): the payload the field hands (obfuscated, short form) names the token and its intent, checked first; then the stored rate only - a visitor's request never spends the provider's quota, whether the application's Trading is live or not.

    2 methods · 1 constant

  • RemoteSearch class

    A select's remote search, answered for any host (plan "omnibase agnostic", step F5d): what omnibase's AutocompleteController answered under Symfony, moved here as it was, so that every host searches a select's records and an icon picker's icons from the same addresses (ROUTES) with the same answers.

    6 methods · 2 constants

Base\Field\Upload

  • Dropzone class

    A file field's uploads before its form is sent, answered for any host (plan "omnibase agnostic", step F5d): what omnibase's DropzoneController answered under Symfony, moved here as it was, so that every host takes a dropzone's files at the same addresses (ROUTES) with the same answers.

    7 methods · 5 constants

Base\Field\Validation

  • Autovalidate class

    A field's validation asked while the form is filled (/ux/validation/{hashid}), written once for every host (plan "omnibase agnostic", step F5e, slice 5b; formerly AutovalidateController): the payload - the token, the value, the form's type - serialised and hidden by Hashids on the site's secret; answered "Fine" when its "validation" token is the visitor's and the method the environment expects (GET in debug, POST otherwise), "Invalid request" (500) otherwise. No check of the value is made yet.

    4 methods · 1 constant

Base\Form\Common

  • AbstractModel class

    1 method

  • FormModelInterface interface

    1 method

  • NativeEnum class

    A PHP enum as a list of choices: what a select holds for a case (its value, or its name when the enum is not backed), the case back from it, and the words that name it.

    6 methods

Base\Form\Definition

  • AccountForms class

    The account's forms, neutral (plan "omnibase agnostic", step F5b): what omnibridge/symfony's types build, what a generic host renders and processes. A site adds its own fields to them.

    4 methods · 1 constant

  • Binding class

    What FormBinder::bind() gives: the data with the submitted values written, the values the form shows again, and the violations of the fields whose value could not be read.

    1 method · 3 properties

  • FormBinder class

    Data binding, neutral: what a form sends (an array of strings, files, lists) into the data it edits (an array, an entity, a DTO), and that data back into the values a form shows. The kind of each field says how (Kind): a trimmed string, an integer, a date, a choice among the field's choices, an association by its id (through the UnitOfWork's references), a file as the host gives it.

    8 methods · 5 constants

  • FormDefinition class

    A form, neutral: its fields (FieldDescriptors, each naming a kind), their groups, its actions (the buttons that submit it), the intent its token is made for, how it is sent. No host's form library: Symfony builds its form from a definition (omnibridge/symfony), a Twig, Blade or React renderer prints its FormView, FormProcessor binds, validates and keeps what is sent.

    41 methods · 3 constants

  • FormProcessor class

    A form's processing, neutral: bind what was sent (FormBinder), check the token (Omnibridge\Contract\Tokens), validate (Omnibridge\Contract\Validation: the data against what its class declares, each field's value against the field's constraints), then keep the data (Omnibridge\Persistence\UnitOfWork) when asked and valid. Each piece is optional: without Validation nothing is validated but what the binder could not read, without Tokens no token is made nor checked, without a unit of work nothing is kept. A form that asks for it (FormDefinition::setGuard()) goes through Base\Service\FormGuard when one is given: its trap and stamp are added to the view, what they say comes first; $translations says the guard's and the token's refusals.

    4 methods · 1 constant

  • FormSubmission class

    A form handled by FormProcessor: whether it was submitted, the data with what was sent written into it, the violations (the binder's, the validator's, the token's), the button clicked, whether the data was kept.

    8 methods · 8 properties

  • FormView class

    A form as a renderer reads it, neutral: a plain tree of views, each with its vars - name, full_name, id, kind, type (the input's HTML type), value, label and help (translatable keys), errors, attr, required, disabled, choices, multiple, checked - and its children by name. The root carries the method, the action and the token (a hidden child under FormDefinition::TOKEN_FIELD).

    13 methods · 4 properties

  • Properties class

    Reads and writes a property of the data a form edits, the way Symfony's PropertyAccess does for a form's paths - getX()/x()/isX()/hasX() and setX(), a public property, an array's key, "." paths - without its property-info and type-info, which the core does not keep (bare --strict).

    3 methods

  • RecordRules class

    A record a valid form has just written into, held to its class's rules before it is kept - its uniqueness above all: a profile's new name that another account has (plan "omnibase agnostic", step F5c: the profile's editor answered 500 on the database's refusal, and signed the session out). The host's Validation says what it reads (Symfony's validator reads omnibase's UniqueEntity itself); a class-level uniqueness it said nothing about is asked as omnisense/ omnibridge's Unique, the record itself not counted as taken.

    1 method

  • UniqueLookup class

    The lookup of Omnibridge\Validation\Constraint\Unique through the entities' repositories: whether another record than the one checked holds those values. What a host's Validation is given as $exists (omnibridge/symfony's, omnibridge/laravel's).

    2 methods

Base\Form\Model

  • CommentModel class

    What the comment form (Base\Form\Type\CommentType) edits - not the entity (omnibase's FormFactory refuses an entity as form data): the name, the e-mail, the site, the text. It implements SpamProtectionInterface so omnibase's FormTypeSpamExtension sends it to Akismet; the score lands here, and toComment() carries it onto the Comment to save.

    6 methods · 6 properties

  • ContactModel class

    What the contact form (Base\Form\Type\ContactType) sends: a name, an e-mail, a message, and as the form is set up a phone, a subject, attachments. `website` is the trap: left empty by people, filled by the robots that fill every field (isRobot()).

    3 methods · 7 properties

  • SecurityLoginModel class

    2 properties

  • SecurityLoginTokenModel class

    1 property

  • SecurityRegistrationModel class

    3 properties

  • SettingModel class

    1 property

  • ThreadSearchModel class

    5 properties

  • UserEditModel class

    3 properties

  • UserProfileModel class

    3 properties

  • UserSearchModel class

    1 property

Base\Http

  • RequestsOf class

    The request contract (Omnibridge\Contract\Requests) out of what a constructor was given: the contract itself, or - deprecated until 6.0 - Symfony's RequestStack, wrapped in omnibridge/symfony's StackRequests (named as a string: the core never loads the bridge itself). Null stays null: a service built outside any host reads no request.

    1 method · 1 constant

Base\Imagine

Base\Imagine\Filter

Base\Imagine\Filter\Advanced

Base\Imagine\Filter\Basic

Base\Imagine\Filter\Basic\Definition

Base\Imagine\Filter\Format

Base\Imagine\Svg

Base\Mailer

  • MailTrap class

    A hold-everything switch for outgoing mail, meant for the minutes after a hotfix when you are not yet sure the site is sending the right things to the right people.

    12 methods

Base\Notifier

  • ContactMessage class

    The contact page's message, written once for every host (plan "omnibase agnostic", step F5e, slice 5b; formerly ContactController::Contact()'s submission): sent to the site's contact address (base.settings.mail.contact, else the technical recipient), its confirmation to the sender, then the page that says so.

    2 methods · 2 constants

  • NotificationCenter class

    The notification center's page and the push subscriptions, written once for every host (plan "omnibase agnostic", step F5e, slice 5b; formerly NotificationController::Index(), PushConfig(), PushSubscribe(), PushUnsubscribe() and ServiceWorker()'s file; the bell's payload, read marks and removals are Base\Controller\Action\Notification's): - the page: a visitor signs in first; ?unread=1 narrows it in the query (the list stops at a hundred: hiding the read rows in the page showed an empty page to anyone whose last hundred were read while older ones waited); - push: the VAPID public key and whether a member may subscribe; a subscription kept or forgotten by the "notifications" token of the body (JSON, same origin), answered in JSON because the bell updates in place; - the service worker's source, served from the site's root (a worker's scope cannot exceed its own path).

    7 methods · 5 constants

  • NotificationLinkerInterface interface

    Turns a notification's target (class + id, see Notification::setTarget()) into a back-office URL. base-bundle ships a null implementation; the admin bundle replaces it with one that knows its CRUD routes, so a notification opened from the back-office lands on the record's edit page while the same notification on the front-end keeps its public URL.

    1 method

  • Notifier class

    13 methods

  • NotifierInterface interface

    1 method

  • NullNotificationLinker class

    No back-office installed: there is no admin page to link to.

    1 method

  • TestRecipient class

    Who the profiler's test e-mail is written to, written once for every host (plan "omnibase agnostic", step F5e, slice 5b; formerly ProfilerController::Email() and SendEmail()): the account signed in, else the technical recipient's account, found by its address, else an account made for the e-mail only (never kept), its address the technical recipient's, its username - where the application's account has one - the recipient's name.

    2 methods

Base\Notifier\Abstract

Base\Notifier\Channel

  • BrowserPlusChannel class

    A notification shown once on the visitor's next page: a flash message of its importance, through the request contract (plan "omnibase agnostic", F5c: Symfony's flash bag, Laravel's session). Nothing outside a request; the same message twice under one type is shown once.

    3 methods

  • EmailPlusChannel class

  • InAppChannel class

    The "inapp" channel: keeps a copy of the notification in the recipient's notification list (userNotification), which is what the bell in the toolbar and the back-office reads. Nothing else in the notifier persists a Notification - it is built, sent over its channels and dropped - so this channel is the one place a notification becomes a row.

    4 methods

  • PushChannel class

    The "push" channel: a Web Push message to every browser the recipient enabled notifications in. Silent when VAPID keys are not configured or the recipient is not a user, so a policy can list it unconditionally.

    3 methods

Base\Notifier\Mail

  • EmailComposer class

    omnibase's e-mails, written the same way under every host (plan "omniauth", step AU8b; R26 of the master plan's gaps): a notification's template rendered by Twig in the e-mail frame, its subject the page's <title>, its embedded pictures as inline parts. Framework-free: the views through omnibridge's Views (plan "omnibase agnostic", step F5a: Twig's environment through omnibridge/twig's TwigViews, or any engine that has omnibase's templates) and symfony/mime, which every host has (Laravel's mail is Symfony's Mailer). The text part is written here, in PHP.

    9 methods · 4 constants

  • InlineImages class

    The `email` an e-mail's template is given where Symfony's Twig bridge is not (EmailComposer::compose()): a picture of the template's paths embedded as an inline part, its cid: address returned - what Symfony\Bridge\Twig\Mime\WrappedTemplatedEmail::image() does, which omnibase's embed() asks for. The picture is found by the views' engine (omnibridge's ViewSources: Twig's loader through TwigViews), since step F5a.

    3 methods

  • MailVariables class

    What omnibase's e-mail templates read of `app` (the site's email.html.twig: app.site.domain, app.site.logo, app.email.title, app.email.age...), for a host whose Twig has no omnibase AppVariable (omnibridge/laravel): the same settings read the same way as SiteVariable and EmailVariable read them under Symfony - the site's logo, the e-mails' title, slogan and logo (each the site's when the e-mails have none of their own), the contact address, the years since the launch (Launcher::since()), the request's domain. EmailComposer gives it to the template as `app`, where the host has no such global.

    1 method · 2 properties

  • SignInMails class

    The e-mails of signing in - the sign-in link, the second factor's code, "welcome back" to a disabled account, a sign-in from a new device - with the words and templates omnibase's Notifier gives them (plan "omniauth", step AU8b; R26 of the master plan's gaps).

    9 methods · 4 constants

Base\Notifier\Recipient

Base\Repository

  • Aliases class

    The core's repositories by their interfaces (audit "lesringostars face au master plan", steps R15 and R27): what the code of a site and of the core type-hints, Doctrine's repository behind - one list, which Symfony's container aliases (config/services/database.php) and omnibridge/laravel binds, as a site's own repositories declare theirs by #[AsAlias]. The users' is the application's (App\Repository\UserRepository: the site's own, else omnibase's under that name).

    1 constant

  • ThreadTranslations interface

    The threads' translations, as the site-wide search reads them (audit "lesringostars face au master plan", step R28; see Base\Database\Repository\Entities): ThreadIntlRepository's query, which the core's ThreadSearchController and an application's search (lesringostars' App\Action\Search\Results) wrote by hand on a query builder before.

    1 method

  • Threads interface

    What a site asks of its threads (a destination, an article, a gallery, a calendar...): the one of a slug, of a parent, of a state, the ones under a parent, the previous and the next by publication. The interface the code of an application and of the core is given (audit "lesringostars face au master plan", step R15; see Base\Database\Repository\Entities); Doctrine's ThreadRepository answers it, and every site repository extending it.

    15 methods

  • Users interface

    The accounts (audit "lesringostars face au master plan", step R15; see Base\Database\Repository\Entities). UserRepository answers it - an application's App\Repository\UserRepository with it -, besides what it declares to Security (Base\Contract\SecurityUserLoader and SecurityUserProvider, R2).

    8 methods

Base\Repository\Analytics

  • PageViews interface

    The pages' views, by day and hour (audit "lesringostars face au master plan", step R28; see Base\Database\Repository\Entities): PageViewRepository answers it with the queries its callers ran by name before.

    7 methods

  • PageVisits interface

    The presence on each page, by day and hour (audit "lesringostars face au master plan", step R28; see Base\Database\Repository\Entities): PageVisitRepository answers it with the queries its callers ran by name before.

    4 methods

  • Visits interface

    The visitors' and members' presence, by day and hour (audit "lesringostars face au master plan", step R28; see Base\Database\Repository\Entities): VisitRepository answers it with the queries its callers ran by name before.

    5 methods

Base\Repository\Extension

  • Revisions interface

    The entities' revisions (audit "lesringostars face au master plan", step R28; see Base\Database\Repository\Entities): an entity's history, as VersionManager reads it - RevisionRepository's query.

    1 method

  • TrashBalls interface

    The trash (audit "lesringostars face au master plan", step R28; see Base\Database\Repository\Entities): what TrashManager and the purge ask of it, TrashBallRepository's queries.

    3 methods

Base\Repository\Hours

  • ScopedWeeks interface

    The opening weeks of the places that have their own (audit "lesringostars face au master plan", step R28; see Base\Database\Repository\Entities): ScopedWeekRepository answers it with the queries its callers ran by name before.

    4 methods

  • SpecialDays interface

    The special days (closures, other hours) (audit "lesringostars face au master plan", step R28; see Base\Database\Repository\Entities): SpecialDayRepository answers it with the queries its callers ran by name before.

    1 method

  • WeekDays interface

    The site's opening week, day by day (audit "lesringostars face au master plan", step R28; see Base\Database\Repository\Entities): WeekDayHoursRepository answers it with the queries its callers ran by name before.

    2 methods

Base\Repository\Layout

  • ImageCrops interface

    The crops of the stored images (audit "lesringostars face au master plan", step R28; see Base\Database\Repository\Entities): ImageCropRepository answers it with the queries its callers ran by name before.

    3 methods

  • Redirections interface

    The redirections (audit "lesringostars face au master plan", step R28; see Base\Database\Repository\Entities): RedirectionRepository answers it with the queries its callers ran by name before.

    2 methods

  • Semantics interface

    The semantic links of the texts (audit "lesringostars face au master plan", step R28; see Base\Database\Repository\Entities): SemanticRepository answers it with the queries its callers ran by name before.

    1 method

  • Settings interface

    The settings stored in the database (audit "lesringostars face au master plan", step R15; see Base\Database\Repository\Entities), with what SettingBag reads through the finder (step R28).

    2 methods

  • Widgets interface

    The widgets by their paths (audit "lesringostars face au master plan", step R28; see Base\Database\Repository\Entities): what WidgetProvider asks, through the finder's result cache unless told otherwise.

    2 methods

Base\Repository\Layout\Widget

  • Slots interface

    The widgets' slots by their paths (audit "lesringostars face au master plan", step R28; see Base\Database\Repository\Entities): what WidgetProvider asks, through the finder's result cache unless told otherwise.

    2 methods

Base\Repository\Thread

  • Comments interface

    The comments of the threads (audit "lesringostars face au master plan", step R28; see Base\Database\Repository\Entities): CommentRepository answers it with the queries its callers ran by name before. Since the plan "omnibase agnostic"'s step E2', what omnibase/blog and omnibase/video ask of it too (the comments online and waiting).

    5 methods

  • Likes interface

    The likes of the threads (audit "lesringostars face au master plan", step R28; see Base\Database\Repository\Entities): LikeRepository answers it with the queries its callers ran by name before.

    1 method

  • Mentions interface

    The mentions of members in the threads (audit "lesringostars face au master plan", step R28; see Base\Database\Repository\Entities): MentionRepository answers it with the queries its callers ran by name before.

    1 method

  • Tags interface

    A site's tags by their slugs (audit "lesringostars face au master plan", step R15; see Base\Database\Repository\Entities): TagRepository answers it through its finder, with the queries its callers ran by name before.

    2 methods

Base\Repository\User

  • Complaints interface

    The complaints (reports) of the members (plan "omnibase agnostic", step E2'; see Base\Database\Repository\Entities): what omnibase/admin's dashboard tile asks, ComplaintRepository's answer.

    1 method

  • Connections interface

    The accounts' connections (browsers, sessions) (audit "lesringostars face au master plan", step R28; see Base\Database\Repository\Entities): ConnectionRepository answers it with the queries its callers ran by name before.

    2 methods

  • Identities interface

    The accounts' identities at providers (plan "omnibase agnostic", step F2d; see Base\Database\Repository\Entities): IdentityRepository answers it with the queries Base\Auth\UserIdentities ran on it by name before.

    2 methods

  • Notifications interface

    A user's notifications, those with something to show (audit "lesringostars face au master plan", step R15; see Base\Database\Repository\Entities).

    2 methods

  • Passkeys interface

    The accounts' passkeys (audit "lesringostars face au master plan", step R28; see Base\Database\Repository\Entities): PasskeyRepository answers it with the queries its callers ran by name before.

    1 method

  • PushSubscriptions interface

    The browsers subscribed to Web Push (audit "lesringostars face au master plan", step R28; see Base\Database\Repository\Entities): PushSubscriptionRepository answers it with the queries its callers ran by name before.

    1 method

  • Tokens interface

    The accounts' tokens (sign-in links, address checks, password resets, API keys) (audit "lesringostars face au master plan", step R28; see Base\Database\Repository\Entities): TokenRepository answers it with the queries its callers ran by name before.

    4 methods

Base\Request

  • AttachmentDownload class

    A widget's attachment downloaded (/attachment/{slug}), written once for every host (plan "omnibase agnostic", step F5e, slice 5b; formerly WidgetController::Attachment()): its stored file, typed by its content (text/plain where PHP's fileinfo is missing), downloaded under its slug; no such attachment, no such page (null).

    3 methods

  • Decision class

    What a request rule decided (plan "omnibase agnostic", step F5e, slice 2: Base\Request\Rule\*), for every host to apply: the request goes on, is sent elsewhere (a route of the site's, or an address), or is refused with a status - and, with any of them, notices for the visitor, cookies for the answer, the account signed out, the address to come back to after a sign-in, the profiler turned off. omnibridge/symfony's subscribers and omnibridge/laravel's middleware apply it; neither decides anything itself.

    13 methods · 3 constants

  • ErrorPage class

    Which page answers an error, written once for every host (plan "omnibase agnostic", step F5e, slice 5b; formerly ErrorController::Main() and renderException()): for the site's developers, the debug page (RESCUE), unless the error page itself is previewed (_preview_error); otherwise the site's error page - under /admin the back office's own first (matched by the path, not the route: an address that matches nothing has no route, and a mistyped /admin/... is the most common error there), then the site's.

    2 methods · 4 constants

  • LocaleSwitch class

    The language menu's choice (/locale/{_locale}), written once for every host (plan "omnibase agnostic", step F5e, slice 5; formerly LocalizerController::Locale(), which omnibridge/laravel's SwitchLocale wrote again): a language the site speaks, remembered in the LANG cookie (Rule\Locale reads it) and as a member's own - not while impersonating -, then the page the visitor came from on this site, at its address in that language when it has one; a language the site does not speak, the index; none given, the choice forgotten.

    5 methods · 3 constants

  • Page interface

    The page a request opens, as the request rules ask it (plan "omnibase agnostic", step F5e, slice 2): the restriction's questions (Base\Auth\Policy\Page) and a few more, which only the host answers - its router names the route, its request the address.

    3 methods

  • RouterPage class

    A Page answered by omnibase's router (omnibridge/symfony's AdvancedRouter, or any router with its questions: getRouteName(), isAdmin(), isProfiler(), isUX(), isSecured()), plus what a router does not know - the sign-in's own pages, the restriction's routes, the address asked.

    9 methods

  • ShortLinkRedirect class

    A short link followed (s.<host>/{slug}), written once for every host (plan "omnibase agnostic", step F5e, slice 5b; formerly ShortLinkController::Main()): to the address it stands for, no such link no such page.

    2 methods

  • SitemapPage class

    The sitemap (/sitemap.xml, /sitemap.txt), written once for every host (plan "omnibase agnostic", step F5e, slice 5b; formerly SitemapController::Main()): the pages the routes' #[Sitemap] declare, on the request's origin, then those the application enumerates itself (its entities' addresses), asked through SitemapEvent::BUILD; the host serves the template of the extension asked.

    3 methods · 1 constant

  • TimezoneSwitch class

    The visitor's time zone chosen (/timezone/{_timezone}), written once for every host (plan "omnibase agnostic", step F5e, slice 5b; formerly LocalizerController::Timezone(), which read a `_locale` its path never carried: it only ever went to the index, after a deprecated setcookie(null) and a match of an empty referrer). A zone PHP knows ("Europe/Paris", "UTC") is remembered in LOCATION/TIMEZONE - the cookie the page's script writes and UserInfoTrait reads - and as a member's own (not while impersonating), then the visitor goes back to the page they came from on this site; a zone it does not know, the index, nothing changed; none given, the choice forgotten.

    4 methods · 2 constants

Base\Request\Rule

  • AccessControl class

    The pages an application keeps for some accounts, by their path (plan "omnibase agnostic", step F5e, slice 2): the `access_control` of Symfony's security configuration as data - its first entry whose path matches decides: PUBLIC_ACCESS opens the page; else one of its roles or attributes granted opens it; else the visitor meets the entry point (EntryPoint: the sign-in, or 403 once signed in). No entry matching, the page is open. Symfony's firewall applies its own configuration; a host without one (omnibridge/laravel) asks this rule with the same entries.

    2 methods · 1 constant

  • Accounts class

    The account rules of a request, in the order omnibridge/symfony's SecuritySubscriber::onKernelRequest() asked them (plan "omnibase agnostic", step F5e, slice 2), for an omnibase account signed in: the impersonation's reminder, the kick (which ends there), the presence (on a main request), the verification, the approval. Each host's adapter asks request() before the page and response() on its answer.

    3 methods

  • Analytics class

    The back office's figures (plan "omnibase agnostic", step F5e, slice 2; formerly omnibridge/symfony's AnalyticsSubscriber): on its main requests (not the profiler's), the accounts online - active within the online delay, the visitor aside - and those of them active now, as the views' globals `user_analytics` (labels) and `user_manager` (the accounts); and Google Analytics' basics, where the host has them, as `user_analytics.google`. The host gives its globals and puts back the ones answered.

    4 methods · 1 constant

  • Approval class

    An account not approved yet (plan "omnibase agnostic", step F5e, slice 2; formerly omnibridge/symfony's SecuritySubscriber::onKernelRequest()): approved and written at its first request when it is an administrator's, or when the site approves every sign-up (`base.user.register.autoapprove`); left as it is otherwise, the page going on.

    2 methods

  • EntryPoint class

    A page refused to the visitor (plan "omnibase agnostic", step F5e, slice 2): who is not signed in is sent to the sign-in - the rescue sign-in where the access restriction makes an exception of the page (EXCEPTION_ACCESS) -, the address kept for after it: what Symfony's firewall does through its entry point (omnibridge/symfony's LoginFormAuthenticator::start(), which asks this rule); who is signed in is refused (403).

    1 method · 2 constants

  • Impersonation class

    The account seen through another's eyes (plan "omnibase agnostic", step F5e, slice 2; formerly omnibridge/symfony's SecuritySubscriber::onKernelRequest()): while an administrator impersonates an account, every page reminds them, naming the account and the query parameter that ends it.

    1 method · 1 constant

  • Integrity class

    The session's integrity (plan "omnibase agnostic", step F5e, slice 2; formerly omnibridge/symfony's IntegritySubscriber, which no configuration registers): the session keeps the application's secret sealed by the vault and a checksum of the database's connection; a session whose secret or connection no longer matches, or whose account the host finds damaged, is signed out (told so), its remember-me cookie cleared, and sent to the rescue sign-in, which itself is never checked.

    6 methods · 4 constants

  • Kicked class

    An account an administrator kicked out (plan "omnibase agnostic", step F5e, slice 2; formerly omnibridge/symfony's SecuritySubscriber::onKernelRequest()): told so, sent to the sign-out with the token the sign-out asks (Base\Security\SignOut: the server signs it out itself), the address it was asking kept for after its next sign-in. Nothing is written: the next sign-in lifts the kick.

    2 methods · 1 constant

  • LaunchPage class

    The launch page (plan "omnibase agnostic", step F5e, slice 2; formerly Launcher::redirectOnDeny(), which asks it now, under omnibridge/symfony's SecuritySubscriber). Where the site waits for its launch date and sends the visitors to it (`base.settings.launchdate.redirect_on_deny`), outside the widgets', the profiler's, the back office's and the account's pages: before the date, an editor is told when and goes on; the launch page itself and a visitor granted LAUNCH_ACCESS (Base\Auth\Policy\Launch) go on; anyone else is signed out and sent to the launch page, the profiler off. Once launched, the launch page sends to the site's index.

    2 methods · 1 constant

  • Locale class

    The language of a page (plan "omnibase agnostic", step F5e, slice 2; formerly omnibridge/symfony's LocalizerSubscriber and omnibridge/laravel's Http\Localize, each its copy), and the one the next page remembers.

    7 methods · 1 property · 2 constants

  • MaintenancePage class

    The maintenance page (plan "omnibase agnostic", step F5e, slice 2; formerly MaintenanceProvider:: redirectOnDeny(), which asks it now, under omnibridge/symfony's SecuritySubscriber). While the site is under maintenance: an editor is told so and goes on; the maintenance page itself is served as it is, nothing else asked; a visitor granted MAINTENANCE_ACCESS (Base\Auth\Policy\Maintenance) goes on; anyone else is signed out and sent to the maintenance page (`base.site.maintenance.redirect_on_deny`, `security_maintenance` by default), the profiler off. Once it is over, the maintenance page sends to the site's index.

    2 methods · 1 constant

  • Presence class

    The presence of the account signed in (plan "omnibase agnostic", step F5e, slice 2; formerly omnibridge/symfony's SecuritySubscriber and omnibridge/laravel's Middleware\Presence, each its copy): an omnibase account not active lately (User::isActive()) is poked - its activeAt now - and written.

    2 methods

  • Redirection class

    A page not found, looked up in the site's redirections (plan "omnibase agnostic", step F5e, slice 2; formerly Base\Service\Redirections::responseFor(), which asks it now): the old addresses of a site taken over lead to its new pages, with the redirection's status (301 or 302), its use counted.

    2 methods

  • Verification class

    An account whose address is not verified yet (plan "omnibase agnostic", step F5e, slice 2; formerly omnibridge/symfony's SecuritySubscriber::onKernelRequest()): told so on every page but the account's own ("security_*") - that the e-mail was just sent (the verification's token still under its delay), or where to ask for it. A tester's account is left alone.

    2 methods · 1 constant

Base\Routing

  • AdminRouteNames class

    How omnibase/admin names a CRUD controller's routes, framework-free: the controller's namespace after Crud\ (or its short name), each segment kebab-cased and pluralised, a repeated segment collapsed, joined with "/" (Crud\Article\ArticleCrudController: "articles"; Crud\Article\ CommentReplyCrudController: "articles/comment-replies"), and the route "admin_crud_" + that slug with "-" and "/" made "_" + "_" + the action (admin_crud_articles_comments_edit).

    4 methods · 1 constant

  • AdminUrlGeneratorInterface interface

    Contract for building back-office URLs.

    7 methods

  • CookieDomain class

    The domain a cookie of the whole site is written for, framework-free (step R29 of the audit "lesringostars face au master plan"): omnibase's rule, AdvancedRouter::getDomain()'s - the request's domain when it is one of the configured domains (base.router.host_fallbacks), else the first of them; "localhost" when the router uses no fallbacks. Its subdomains share the cookie (a cookie with a Domain attribute). Symfony's router and omnibridge/laravel's sign-in effects (the browser's PHPUSERID) write it the same way.

    2 methods

  • NullAdminUrlGenerator class

    Stand-in used when omnibase/admin is not installed.

    7 methods

Base\Screen

  • Answer class

    An action's answer as Negotiation gives it, before any framework (step R10 of the audit "lesringostars face au master plan"): its status, body and headers, how it may be kept, whether the body is JSON (Symfony's JsonResponse, Laravel's), or the file it is (sent as it is stored). Each host's adapter makes its response of it, nothing more.

    1 method · 6 properties

  • Author class

    Who wrote a story, a comment, a reply (lesringostars' authors): a name, the address of their page (a profile, a comment's website), an avatar's address; `staff` where a screen marks the site's own people (the blog's "author" pill), left out of the props where it does not.

    3 methods · 4 properties

  • Cache class

    How an answer may be kept (step R10 of the audit "lesringostars face au master plan"): by any cache (public) or by the visitor's browser alone (private) - null leaves it to the host -, how long, whether it is to be asked again once stale, by no cache at all (no-store), and the request headers it varies on. Each host's adapter sets them on its response.

    4 methods · 5 properties

  • Card class

    A story on a list (lesringostars' BlogPage::card()): its slug, title, excerpt, date, reading time, authors and tags, its address. `likes`, `likeUrl` and `comments` are null where the screen counts none (never 0: "none counted" and "zero" stay apart). Added for omnibase's blog: the line under the title (`headline`), the cover's address at the width the screen shows it, the taxa, and `recent` - published lately, by the screen's clock (a template compares no moment: it reads this).

    3 methods · 16 properties

  • Comment class

    A comment (lesringostars' comments): its id or uuid (at least one: a front end keys and anchors on the uuid, else the id), slug, date, authors, text (as written: a template breaks its lines), the address to follow it, its replies, and whether it is recent by the screen's clock.

    3 methods · 9 properties

  • Confidential interface

    A screen carrying secrets of its viewer's session (plan "omnibase agnostique", C5): the tokens of its forms (Base\Screen\Account\Action), the token of its requests. Whoever answers it keeps it out of every cache - under Symfony, ScreenResponder gives `Cache-Control: private, no-store` and `Vary: Cookie`, the HTML as the JSON.

  • ContextProvider interface

    What a screen needs of the request it answers (plan "omnibase agnostique", C5): the frame around the page, the visitor signed in, the messages left for the page. Under Symfony Base\Bridge\Symfony\SymfonyScreenContext; a site decorates it to add its own frame fields; another framework fills it the same.

    3 methods

  • Discussion class

    The comments of a page and whether one may write (lesringostars' page `comments` and `hasMoreComments`, here `comments` and `hasMore`): one model, because the block is shown on pages that are no story too (a visitors' book, a host's home). `open`: a comment may be written here (the site's settings, the story's, the visitor); `canReply`: an answer to one may; `signIn`: the address of the sign-in page, for whoever may not; `flashes`: the messages left for this page, already read.

    3 methods · 6 properties

  • File class

    A stored file answered as it is (step R10 of the audit "lesringostars face au master plan"): its path, its type (null: the host guesses it from the file), how it may be kept.

    1 method · 3 properties

  • Fragments class

    Templates rendered one after the other into one string, a value of a JSON answer (step R10 of the audit "lesringostars face au master plan"): a batch of comments, the HTML a page's script inserts.

    1 method · 1 property

  • Frame class

    What every page shows around its screen (lesringostars' App\Screen\Frame): the page's language, the site, the addresses of the menus, the visitor signed in and the colour scheme, and what a site adds of its own (`extra`: lesringostars' destination, destinations, last article, tags, map), merged in its props between `site` and `links`. Given per request by a ContextProvider.

    4 methods · 7 properties · 1 constant

  • Json class

    Data answered in JSON, what an action a page's script asks hands back (step R10 of the audit "lesringostars face au master plan"): a feed, a batch of comments, a token. A Template among the data (at any depth) is rendered by the host into its markup, Fragments into theirs joined, before the data are encoded - as Symfony's JsonResponse encodes them, under either host.

    1 method · 3 properties

  • Link class

    Another story, as a page points to it (the one before, after, to read as well; a member's latest on their profile): its title, address and state; `publishedAt` where a page shows the date, left out of the props where it shows none.

    3 methods · 4 properties

  • Negotiation class

    How an action's result is answered, whichever framework hosts it (step R10 of the audit "lesringostars face au master plan"; formerly the body of Base\Bridge\Symfony\ScreenResponder, which is now Symfony's adapter of it, as omnibridge/laravel's Screen\Responder is Laravel's). Framework-free: the host gives what the client asked (a Visit) and a way to render a template, and makes its response of the Answer.

    6 methods · 4 constants

  • Redirect class

    What an action hands back to send the client elsewhere (step R27 of the audit "lesringostars face au master plan": a newsletter's tracking link counts the click, then leads to its subject): the address, the status (302 by default), stored by no cache by default; more headers when it carries some (a cookie).

    1 method · 4 properties

  • Reply class

    An answer to a comment (lesringostars' replies): its id or uuid (at least one: a front end keys and anchors on the uuid, else the id), date, authors, text, whether it was deleted, and whether it is recent by the screen's clock.

    3 methods · 7 properties

  • Screen interface

    A view model (plan 0, rule 13; plan "omnibase agnostique", C5): what a screen shows, as plain data a view bridge renders - Twig reads the object's public properties, a front end (React) reads toArray() as its props. No entity, no service, no class of a framework inside: scalars, ISO 8601 moments, lists and other screens.

    1 method

  • Shell class

    A page a front end renders (omnibridge/react's protocol), what an action of a React page hands back (step R10 of the audit "lesringostars face au master plan"): the component, its props, the front end's version, and the shell of the first visit - a template given `root` (the element holding the page), `page` and its own data. A visit within the front end gets the page in JSON, a front end of another version 409 and the address to reload, the first visit the shell, its markup alone.

    1 method · 5 properties

  • Site class

    The site around every page: its name, its slogan, its logo's address, the year, its description (lesringostars' frame `site`).

    3 methods · 5 properties

  • Story class

    A story on its own page (lesringostars' StoryPage `article`): what its card says, with its id, its text (StoryText's html, editor and toc, flattened as there), its sounds' addresses, whether it takes comments, and its state.

    7 methods · 20 properties

  • StoryText class

    A story's text as its page shows it (lesringostars' StoryText::render()): the HTML rendered, whether it was an Editor.js document, and its table of contents (each heading's tag, anchor and title, in the text's order).

    3 methods · 3 properties

  • Tag class

    A tag, a taxon (lesringostars' tags): its slug, label, colour, icon and the address that lists what carries it; `count` in a cloud of tags, `current` in a navigation by tag (the one shown), each left out of the props where a screen has none.

    3 methods · 7 properties

  • Template class

    A template and its data, what an action of a page hands back (step R10 of the audit "lesringostars face au master plan"): the host renders it - Twig under either framework -, with the status and the caching the action gives.

    2 methods · 6 properties

  • View class

    What a controller hands back (plan 0, rule 13): the template that draws the screen, the screen itself, the name of the component a front end draws it with (omnibridge/react's Page), and the status of the answer. The view bridge renders it: Twig with `frame` and `screen`, React with the frame's and the screen's props together.

    1 method · 4 properties

  • Viewer class

    The visitor signed in, as a page may show them: an id, a name, an avatar's address. Nothing else (no roles: what a screen needs of the visitor, its builder decides - may they reply, is the form open).

    3 methods · 3 properties

  • Visit class

    What a client asked of an action, as far as its answer depends on it (step R10 of the audit "lesringostars face au master plan"): the address, the types it accepts, and omnibridge/react's headers (X-Omnibridge: a visit within a front end; X-Omnibridge-Version: the front end's version).

    4 methods · 4 properties

  • Welcome class

    The page a new site shows at its root until it has one of its own, written once for every host (plan "omnibase agnostic", step F5e, slice 5b; formerly MainController::Index()'s): templates/welcome.html.php, plain PHP (no view engine), told the host framework's version, the project's folder and omnibase's version; answered 404, as a page the site has not written.

    1 method · 2 constants

Base\Screen\Account

  • AccountSummary class

    An account's security at a glance, on its profile, for its owner or an administrator: whether it has a second factor (null where two-factor is not available on the site), how many passkeys (null where passkeys are not - never 0 for "not counted"), the provider it signs in with (`google`), its language and time zone.

    3 methods · 5 properties

  • Action class

    A POST a page sends (plan "omnibase agnostique", C5): the address it goes to and the token of its intent (Omnibridge\Contract\Tokens), which the action checks. Only on a confidential screen (Base\Screen\Confidential): its answers are stored by no cache.

    3 methods · 2 properties

  • Member class

    A member as their profile shows them, to anyone who opens it: their number and name, their avatar - the stored one's address at 128 px, or the application's own rendering (`avatarHtml`: its User's getFormattedAvatar(), HTML) -, their roles (the names, which a template translates), whether they are online or were active lately (the account's own answers, by base.user.online_delay and active_delay), when they registered and were last seen, how many threads they own and likes they gave (counted).

    3 methods · 11 properties

  • Notification class

    A notification in the member's list: the bell's item (NotificationController::serialize(): id, title - else the subject -, text without its tags - null when it has none -, address, back-office address, importance, read or not, when it was sent) and its `group` - `today`, `yesterday`, `week` or `earlier`, by the screen's clock in the page's time zone, so that no template compares a moment.

    3 methods · 9 properties · 1 constant

  • NotificationsPage class

    The member's notifications (/notifications): the latest with something to show (newest first; the unread ones alone when asked), how many are unread (counted), whether the page shows the unread ones alone and the address of all of them, the token every request of the page carries and the addresses of those requests (read, latest, delete, push subscribe and unsubscribe), whether push can be offered and its public key. Its token: confidential.

    3 methods · 12 properties

  • Passkey class

    A passkey of the account: its number, its label (null for none), when it was added and last used, the actions renaming and removing it.

    3 methods · 6 properties

  • ProfilePage class

    A member's profile (/profile/{id}): the member, whether the viewer is that member, their five latest published threads (newest first, each dated by its publication, else its creation), the account's summary - only for its owner or an administrator, null for anyone else -, and the addresses its owner (or an administrator, for the edit) follows from there.

    3 methods · 7 properties

  • Provider class

    A provider one may sign in with (`google`, "Google"): whether the account signs in with it, the address linking it (while it does not).

    3 methods · 4 properties

  • Session class

    One of the account's sessions (a connection): its number, the browser's own string and a readable label ("Safari - macOS"), the addresses it came from, when it was last seen, whether it is still open, and the action signing it out (while it is).

    3 methods · 7 properties

  • SettingsPage class

    The account's settings (/settings): its name (null for nobody signed in: the page shows its title alone), whether it is a demonstration account (changing nothing of its credentials), its second factor (null where two-factor is not available), its passkeys (null where passkeys are not) and the identifier a new one registers, the sign-in providers shown (those available, and the account's own), its latest sessions, its language (its locale, `language`: the frame owns `locale`) and time zone. Its actions carry their tokens: confidential.

    3 methods · 9 properties

  • TwoFactor class

    An account's second factor on its settings page, as the security policy lets its owner change it: whether the administrator requires one (and the account still lacks it), the authenticator app - on or off, the address to switch it on (when it may be), the action switching it off (when it may be: on without it is locked by the administrator) -, the code by e-mail - on or off, locked (on, the only factor left, and required), the action toggling it (when not locked and the account may change its credentials) -, the backup codes left (null while the app is off).

    3 methods · 9 properties

Base\Screen\Builder

  • Accounts class

    The account's pages as view models (plan "omnibase agnostique", C5): a member's profile, the account's settings, the member's notifications, from omnibase's entities (a User, its threads and passkeys, its connections, its notifications) and the site's security policy. Framework-free: the addresses through the Urls contract, the forms' tokens through Tokens (the ones given, else Runtime's), "now" from a PSR-20 clock; what only the framework knows (an avatar's thumbnail, the providers available, web push) the caller passes in.

    9 methods · 2 constants

  • Stories class

    omnibase's threads as view models (plan "omnibase agnostique", C5): a thread on a list (Card), on its own page (Story), pointed to (Link), its text (StoryText), its tags, taxa and owners, the comments left on it.

    9 methods

Base\Security

  • ConnectionTracker class

    The browsers an account signs in from: a userConnection row per browser (its PHPUSERID) and account, with the addresses, agent, hosts, locale and time zones it came with. Framework-free (plan "omniauth", step AU8b): the host says who the browser is ($uniqid: the PHPUSERID its session or its cookie holds, a new one kept in both otherwise) and which host it reached ($host). Base\Security\UserTracker is the Symfony one (its RequestStack and omnibase's router); omnibridge/laravel builds this class on Laravel's session, cookies and request - the same rows, whichever host signed in.

    5 methods · 1 constant

  • CookieAnswer class

    The visitor's answer about cookies, read on the server: the page's script (@glitchr/flowjs/cookie, which omnibase/consent configures) keeps it in the cookie "cookie-consent" - {"c": {"USER": 1, "LOCATION": 0}, ...}, one yes or no per category. For the few cookies the server writes itself: the script lets nothing be written under a refused category, and neither does the server.

    2 methods · 1 constant

  • LoginRestrictionInterface interface

  • SignInCaptcha class

    The sign-in's captcha after a few failures, framework-free (plan "omniauth", step AU8b): the failures from an address are counted - whatever identifiers they tried - and from base.guard.sign_in_after of them on, a sign-in from that address must pass the captcha; a success forgets the count. Counted in a PSR-6 pool: one both hosts reach (lesringostars' Redis) makes a captcha one host asks for asked by the other as well.

    8 methods · 2 constants

  • SignOut class

    The sign-out's address, its token in it, for any host.

    2 methods · 4 constants

  • UserTracker class

    Base\Security\ConnectionTracker under Symfony: the browser's PHPUSERID from the request's session or cookie (a new one kept in both), the host from omnibase's router.

    2 methods

  • WebauthnUserEntityRepository class

    The accounts as passkeys know them (WebauthnBundle's user repository): an account's username is the key's name, its id (as text) the user handle.

    3 methods

Base\Serializer

  • Aco class

    7 methods · 9 constants

  • Excel class

    5 methods · 5 constants

Base\Serializer\Encoder

Base\Service

  • Analytics class

    Single entry point for this app's traffic counters: page views (a raw hit count per path) plus two independent unique-subject counters - anonymous "visitors" (cookie-identified, see the consent note on trackVisitor()) and authenticated "users" (Base\Entity\User ids) - both sliceable by the same time windows (today/24h, 7 days, 30 days, all time) because they're built on the exact same underlying mechanism (Base\Entity\Analytics\Visit's daily presence rows), just keyed differently. Storage/aggregation strategy lives in the two repositories; this class is the only thing application code (a request subscriber, an admin sidebar widget, ...) needs to know about.

    13 methods

  • ArrayParameterBag class

    The application's parameters given as an array, by their full names ("base.attributes.use_custom" => true), read by a dotted path as Base\Service\ParameterBag reads the container's (both are Base\Service\DottedParameterBag): omnibase's ParameterBagInterface where there is no container (an entity manager built by hand, Base\Bridge\Doctrine\Mapping; another framework). A path names a value or the values under it ("base.attributes" is ['use_custom' => true, ...]).

    2 methods

  • BaseService class

    The facade of omnibase's services for an application's code (plan "omnibase agnostique", C9): kept, not deprecated, with BaseTrait. Framework-neutral since the plan "omnibase agnostic", step F5c, item 3: its constructor takes nothing of a framework, every host builds it from the core's list (Base\Services), and each method asks omnisense/omnibridge's contracts through Base\Contract\Runtime - the settings, the request's session and route (Requests), the addresses and assets (Urls), the environment (Environment), the visitor (Access), the forms' tokens (Tokens), the unit of work (UnitOfWork), the entity hydrator.

    34 methods

  • Breadgrinder class

    3 methods

  • BreadgrinderInterface interface

    1 method

  • ColorExtractor class

    2 methods

  • CommentGuard class

    The comment forms' face of Base\Service\FormGuard, kept for the bundles that ask it (omnibase/blog, omnibase/video): the trap filled, a form sent faster than a person types, a second comment from the same address within the flood interval (base.comments.min_delay, base.comments.flood_interval).

    2 methods · 3 constants

  • DottedParameterBag class

    The application's parameters by their full names ("base.attributes.use_custom" => true), read by a dotted path (plan "omnibase agnostique", C9): the framework-free source both Base\Service\ArrayParameterBag (an array) and Base\Service\ParameterBag (the Symfony container's parameters) read through.

    3 methods

  • DownloadLinks class

    Signed download links: a route's absolute URL, signed by Symfony's UriSigner and valid for a while (base.download_links.ttl seconds unless told otherwise). Whoever holds one within that time gets the file - who may was checked when it was handed out (a licence, an entitlement, a voter). The one place for it: omnibase/forge's artifacts and omnibase/classroom's resources sign theirs here.

    4 methods

  • EditorEnhancer class

    8 methods

  • EditorEnhancerInterface interface

  • Embeds class

    An address (a video, a song, a board, a slideshow) turned into what a page can frame - the Twig function embed_url():

    3 methods · 1 constant

  • FileService class

    20 methods · 1 constant

  • FileServiceInterface interface

    7 methods

  • Flysystem class

    omnibase's storages, by name ("local.cache", "local.uploads", "s3.private"...), read and written through omnisense/omnidrive (plan "omnidrive", 2026-10-23): each storage is an Omnidrive\Drive of the Omnidrive\Drives the host gives - under Symfony the storages of flysystem-bundle's configuration (the services tagged flysystem.storage), or omnibase's local ones without the bundle (FlysystemStoragesPass); under Laravel its disks (omnibridge/laravel). A PSR-11 container of Flysystem operators is still accepted, read as Omnidrive\Flysystem\OperatorDrives.

    25 methods

  • FlysystemInterface interface

    omnibase's storages over Flysystem's types.

    20 methods

  • FormGuard class

    What stands between a form and a robot, in the order it is asked (docs/20-architecture/guard.md):

    23 methods · 17 constants

  • GroupManager class

    The one service that turns a score into an actual capability.

    4 methods

  • HotParameterBagInterface interface

    The parameters with the settings stored in the database laid over them: Base\Service\HotParameters (plan "omnibase agnostique", C9), which `parameter_bag` is under Symfony (omnibridge/symfony's HotParameterBag, also DependencyInjection's ParameterBagInterface) and the parameters under omnibridge/laravel. Since step F5c of plan "omnibase agnostic" it extends omnibase's ParameterBagInterface, no longer DependencyInjection's.

    5 methods

  • HotParameters class

    The settings stored in the database laid over any parameters (plan "omnibase agnostique", C9): the "hot" overlay of HotParameterBag, framework-free. A setting linked to a parameter ("bag" in the back office) is given by add() (under Symfony HotParameterBagSubscriber, on the first request or command, from the SettingBag) and read in place of the configuration's value.

    10 methods · 1 constant

  • IconProvider class

    9 methods

  • Icons class

    omnibase's `|iconify`: an icon's name, a list of them, an enumeration's or an IconizeInterface's icons, or a route's (the icons its controller declares, #[Iconize]) as HTML, by the first adapter that knows the name (Font Awesome, Bootstrap's icons...), a question mark for none.

    4 methods

  • ImageRoute class

    omnibase's image route, answered for any host (audit "lesringostars face au master plan", R6): what Base\Controller\UX\MediaController answered under Symfony, moved here as it was, so that a host without the framework serves the same images and thumbnails from the same addresses - an obfuscated `data` resolved by MediaService, its file filtered by Imagine (a format, a thumbnail, a crop) and kept in the local.cache storage, a redirection to the address with the right extension, the placeholder when nothing resolves.

    9 methods · 1 constant

  • Invitations class

    Invitation by token: nobody signs up, someone is invited. The token is random, sent once and never stored - only its SHA-256 is kept, so a leaked table opens nothing. Following the link creates the account (the link proved the address) or attaches the one that exists.

    9 methods · 1 constant

  • Launcher class

    7 methods

  • LauncherInterface interface

    4 methods

  • Links class

    A route's address by a router's reference type, made on the Urls contract (plan "omnibase agnostic", step E1): what an entity's __toLink() asks (Widget\Page, Widget\Attachment, ShortLink, Image, Semantic, Widget\Route), through Base\Contract\Link::to(), its static door.

    2 methods

  • LocalBusiness class

    schema.org's LocalBusiness for the page's JSON-LD: who the business is, where, how to reach it, when it is open. Search engines read the address, the phone and the hours (the days off too) from there.

    3 methods · 1 constant

  • Localizer class

    41 methods · 3 constants

  • LocalizerInterface interface

    28 methods

  • Locator class

    Where BaseTrait's static accessors keep what they resolved (audit "lesringostars face au master plan", step R28): the runtime locator BaseBundle::boot() seeds, the project's folder, the environment, each service once asked. Framework-free - a class of the Foundation -, so an entity's or an attribute's accessor no longer loads BaseService, the Symfony facade (a kernel, a form factory, a profiler in its constructor), which held them before. BaseService extends it: the same statics, its set*() calls and BaseService::getX() as before.

  • MaintenanceProvider class

    7 methods

  • MaintenanceProviderInterface interface

    6 methods

  • MediaService class

    26 methods

  • MediaServiceInterface interface

    8 methods

  • NullTrading class

    The currency rates where florianv/swap is not installed: Base\Service\Trading is declared only with it (and symfony/http-client's PSR-18 adapter, which it hands Swap), and `trading_market` / TradingInterface are then this one (Base\Discovery's `fallbacks`), so the Twig filters, the money field and the facade still have their service.

    13 methods

  • Obfuscator class

    9 methods

  • ObfuscatorInterface interface

    2 methods · 2 constants

  • OpeningHours class

    When the place is open - one service for the footer, a banner, the time slots a customer may wish for, the day an order is for and the page's JSON-LD.

    20 methods

  • Paginator class

    2 methods

  • PaginatorInterface interface

    1 method

  • ParameterBagInterface interface

    The parameters of the application, read by a dotted path ("base.uploader.storage"), as omnibase's code asks for them: the core's contract, with no class of the framework (plan "omnibase agnostique", step C3c).

    4 methods

  • ReadSettings class

    The settings the administrator stored (layoutSetting), read through a host's own reader where omnibase's SettingBag (its entity manager, cache, localizer and Symfony parameters) is not built - omnibridge/laravel's DatabaseSettings (plan "omniauth", step AU8b: SecurityPolicy under Laravel). Read only: a setting is changed in the back office, which is the Symfony site's.

    7 methods

  • Redirections class

    Where an address that is not found leads now (Base\Entity\Layout\Redirection).

    3 methods

  • Referrer class

    Where to go back to: the target path posted or kept in the session, the firewall's, the referer. The request and its session through Omnibridge\Contract\Requests (plan "omnibase agnostic", F5c).

    8 methods

  • ReferrerInterface interface

    4 methods

  • SecurityPolicy class

    The site-wide account-security policy an administrator sets, and the single place that decides what a *user* is then allowed to change about their own account.

    17 methods · 9 constants

  • SettingBag class

    The settings stored in the database (the back office's), compiled into one snapshot kept in a PSR-6 cache pool (plan "omnibase agnostique", C9: on psr/cache, no longer on Symfony's CacheInterface; its cache warmer is Base\Bridge\Symfony\SettingBagWarmer, which calls warmUp()).

    31 methods

  • SettingBagInterface interface

    6 methods

  • SettingSnapshotValue class

    Opaque per-locale value holder used inside a compiled SettingBag snapshot tree, standing in for the live Setting entity that same tree position holds in SettingBag::normalize()'s entity-tree shape. Kept as an object (not a plain array) so array_map_recursive() treats it as a leaf and does not recurse into the per-locale map itself.

    1 method · 1 property

  • Sharing class

    5 methods

  • SharingInterface interface

    1 method

  • Signatures class

    Documents signed through omnisense/omnisign, for any entity of the application: an envelope sent (send()), signed by e-mail or in the site's page (signingUrl()), followed (refresh(), or the provider's webhook: notify()), and once completed its signed document and evidence kept in the private storage (base.signatures.storage: the uploads', out of public/). Each move is a SignatureEvent; the application answers on what the envelope is about.

    13 methods

  • Sitemapper class

    10 methods

  • SitemapperInterface interface

    6 methods

  • SpamChecker class

    Is what a visitor wrote spam? The classifier of omnisense/omnishield behind omnibase's SpamCheckerInterface (check, score), which the forms (spam_protection), the comments and omnibase/faq's questions ask:

    9 methods

  • SpamCheckerInterface interface

    2 methods

  • SpeculativeRequest class

    Tells a speculative request - one a client made ahead of any user action, hoping to have the answer ready - from a real one.

    1 method

  • Storages interface

    omnibase's named storages over omnisense/omnidrive (audit "lesringostars face au master plan", step R28): what the core asks of them - a drive by its name (getDrive(), omnidrive's Drive: read, write, list, public address, local path...), and omnibase's rule of the public paths (getPublic(), prefixPath(), stripPrefix(): a stored file's address under public/, by the storage's prefix) with the checks it makes before a read or a write. Nothing of Flysystem in or out: a storage is named by a string.

    18 methods

  • SystemOfUnits class

    1 method

  • Themizer class

    16 methods

  • ThemizerInterface interface

    12 methods

  • TimeMachine class

    32 methods

  • TimeMachineInterface interface

    The backups (docs/30-operations/backups.md). Its implementation, Base\Service\TimeMachine, extends glitchr/backup-manager's Manager, a suggestion since 4.0: this interface loads without it, so the configuration reads DEFAULT_EXCLUDES here.

    7 methods · 1 constant

  • TimelineEventProviderInterface interface

    A source of "worth marking on a timeline" events (a deploy, a campaign launch, ...), collected by base-bundle-admin's TimelineEventRegistry and rendered as annotations on the analytics dashboard chart. Lives here (not base-bundle-admin) for the same reason Analytics does: it's a domain concept, not an admin-UI-specific one - a future non-admin consumer (a public changelog widget, a CLI report) could reuse it without depending on the admin package.

    1 method

  • Trading class

    20 methods

  • TradingInterface interface

    13 methods

  • Translator class

    omnibase's translator, and the Translations contract of the Foundation (trans(), exists()) where it runs: an entity's noun is asked of an EntityNouns over it (getEntityNouns(), plan "omnibase agnostique", C4b), the rule a host without the framework runs over its own Translations.

    24 methods · 21 constants

  • TranslatorInterface interface

    12 methods · 3 constants

  • TrashManager class

    Reads and empties what TrasheableSubscriber put aside.

    9 methods · 1 constant

  • VersionManager class

    Reads back what VersionableSubscriber wrote.

    4 methods

  • WidgetProvider class

    The widgets and their slots by path. Through their interfaces (audit "lesringostars face au master plan", step R28), where it asked the entity manager for their repositories: the same finders, the result cache unless $useCache is false.

    7 methods

  • WidgetProviderInterface interface

    4 methods

  • WysiwygEnhancer class

    9 methods

  • WysiwygEnhancerInterface interface

    8 methods

Base\Service\Analytics

  • UserAgentClassifier class

    Buckets a request's User-Agent into one of three Base\Entity\Analytics\ PageView::SOURCE_* values. AI checks run first and take priority over the generic crawler-detect pass: several AI crawlers (GPTBot, ClaudeBot, ...) also match generic bot heuristics, but they deserve their own bucket (SOURCE_AI) rather than falling into the catch-all SOURCE_BOT one - that split is the whole point of this class over just jaybizzle/crawler-detect's plain isCrawler() boolean.

    2 methods

Base\Service\Calendar

  • CalendarEntry class

    One date as a calendar sees it, whatever it was in the site: a concert (omnibase/agenda's Event), an appointment, a class, a pick-up. What Ics and GoogleCalendarLink write from - a bundle maps its own entity to one (see omnibase/agenda's Event::toCalendarEntry()).

    3 methods · 13 properties · 1 constant

  • GoogleCalendarLink class

    The "add to Google Calendar" link of a date: Google's own template page, filled in. Hours go in UTC with the date's timezone beside them (ctz), whole days as dates, the last one excluded as Google wants it.

    1 method · 1 constant

  • Ics class

    Dates as an iCalendar file (RFC 5545), written by hand: a calendar a phone subscribes to, or one date to add. Lines end with CRLF and are folded at 75 octets, texts are escaped, an hour is given in the date's timezone (with the VTIMEZONE that defines it) or in UTC, a date of whole days as dates. Moved here from omnibase/agenda, on CalendarEntry.

    5 methods · 1 constant

Base\Service\Collab

  • CollabRoomResolver class

    This class supplies room-key logic and version-hash logic for the real-time collaboration feature. EditorType uses this class.

    5 methods

  • CollabTicketFactory class

    This class creates a short-lived, signed ticket. A browser presents this ticket to the collab relay (relay/src/server.js in editorjs-yjs), to join a room's WebSocket connection. The relay checks the signature by itself.

    5 methods

Base\Service\Model

  • Autocomplete class

    3 methods

  • AutocompleteInterface interface

    2 methods

  • Autovalidate class

    2 methods

  • AutovalidateInterface interface

  • Breadcrumb class

    38 methods

  • BreadcrumbInterface interface

  • CacheableInterface interface

    3 methods

  • ClassAliases class

    omnibase's class convention, without the bundle: App\Entity\X is Base\Entity\X when the application declares no App\Entity\X of its own - and so for App\Repository, App\Enum, App\Tests, App\Notifier, App\Form. Under Symfony, BaseBundle::warmUp() declares these aliases from its pool and AbstractBaseBundle's last-resort autoloader answers by the same convention (it asks base()); an entity manager built by hand (Base\Bridge\Doctrine\ Mapping) registers the convention as an autoloader of its own - an association names its target App\Entity\User\Notification.

    2 methods · 1 constant

  • ClassFinder class

    The classes a folder of PHP files declares, read from the files: each file's namespace and its name, the interfaces (*Interface.php) and the empty files left out - what Base\Bundle\AbstractBaseBundle::getAllClasses() answers, without loading the bundle (and with it the framework) to ask.

    3 methods

  • ColorizeInterface interface

    2 methods

  • DevelopmentEnvironment class

    Whether the application runs for its developers (plan "omnibase agnostique", C9): BaseService::isDevelopment()'s rule, moved here so that a class that needs it asks the Environment contract instead of BaseService - debug on, or an environment named "dev", "local", or starting with "dev_" or "local_".

    2 methods

  • Duration class

    A number of seconds in words - "2 jours 3 heures 5 minutes" - from the application's texts (base.years, base.months, base.days, base.hours, base.minutes, base.seconds: ICU plurals on {0}), as Base\Service\Translator:: transTime() said it: the time left before a token expires, before a thread is published, an order abandoned (plan "omnibase agnostique", C4b).

    1 method

  • EntityNouns class

    The Nouns contract's rule (plan "omnibase agnostique", C4b): an entity's noun read from the "entities" catalogues through the Translations contract, by the key of its class and the variants its options ask for (Base\Service\Model\NounVariants), the first one the catalogues hold.

    6 methods · 2 constants

  • EnumNouns class

    The words of an enumeration's values (omnibase's `|trans_enum`): a value of an Base\Database\Type\EnumType - by its class or by the name of its DBAL type ("thread_state") - read from the "enums" catalogues through the Translations contract, under the key of the class that declares the value and its parents down to the type (Base\Enum\ThreadState: "thread_state"), the value lower-cased, the noun's variant its options ask for (Base\Service\Model\NounVariants), the first one the catalogues hold.

    4 methods · 1 constant

  • GraphInterface interface

    3 methods

  • HtmlizeInterface interface

    1 method

  • IconizeInterface interface

    2 methods

  • IntlDateTime class

    3 methods

  • LinkableInterface interface

    A thing with an address. $referenceType is one of Symfony's UrlGeneratorInterface reference types, by their values (Base\Contract\Link's constants, so that the interface names nothing of the routing component); Link::to() makes the address through the Urls contract.

    2 methods

  • LocaleNormalizer class

    omnibase's locale form, xx-XX, without the framework (plan "omnibase agnostique", C3e): the rule Base\Service\Localizer::normalizeLocale() and __toLocaleLang() apply, taken out of the Localizer (a Symfony service, its statics filled at its warm-up), which now asks it with its own default and fallback locales - the same strings, by construction.

    4 methods · 1 constant

  • NounVariants class

    The keys tried for a noun - an entity's (Base\Service\Model\EntityNouns), an enumeration's value (Base\Service\Translator::transEnum()) - after its base key, for the options a call gives: a level of politeness (Translator::POLITENESS_*), a gender (Translator::GENDERNESS_*), singular or plural (TranslatorInterface::NOUN_*).

    1 method

  • Pages interface

    Rows to page through, counted and sliced by whatever runs the query (plan "omnibase agnostic", step F2e): what Base\Service\Model\Pagination asks in place of Doctrine's Query and Paginator. Doctrine's is Base\Bridge\Doctrine\QueryPages (a DQL query, with omnibase's walkers); a plain array is paged by Pagination itself.

    2 methods

  • Pagination class

    28 methods · 1 constant

  • PaginationInterface interface

    8 methods

  • SaltInterface interface

    1 method

  • SelectInterface interface

    4 methods

  • SitemapEntry class

    15 methods

  • SpamProtectionInterface interface

    4 methods

  • WorkflowInterface interface

    4 methods

Base\Service\Model\Color

Base\Service\Model\Color\Intl

  • Colors class

    Colour names: the CSS named colours (CSS Color Module Level 4) with their sRGB hex codes, one name per code (aqua for cyan, fuchsia for magenta, the -gray spellings for -grey).

    8 methods · 1 constant

Base\Service\Model\Currency

Base\Service\Model\Currency\Api

Base\Service\Model\IconProvider

Base\Service\Model\IconProvider\Adapter

Base\Service\Model\Obfuscator

Base\Service\Model\Obfuscator\Compression

Base\Service\Model\Sharing

Base\Service\Model\Sharing\Adapter

Base\Service\Model\Wysiwyg

Base\Service\Push

  • WebPushService class

    Web Push delivery (RFC 8030 + VAPID) to the browsers a user enabled notifications in. The service is a no-op until VAPID keys are configured (VAPID_PUBLIC_KEY / VAPID_PRIVATE_KEY / VAPID_SUBJECT), so the rest of the notification center works without it - the in-app list, the badge - and push simply switches on the day the keys land in .env.local.

    9 methods

Base\Service\Qr

  • QrCode class

    A QR code for an address (or any text), drawn by endroid/qr-code: as SVG - sharp at any print size, the default - or PNG. Used by QrSheet for its pages, and directly for a poster or a ticket:

    2 methods

  • QrSheet class

    QR codes laid out on A4 pages to print: one big code per page (a poster for a counter, a door, a table), or a sheet of Avery labels - each label a code and a caption, at the label's place on the sheet, in millimetres.

    4 methods · 1 constant

Base\Service\Ticket

  • TicketSigner class

    The tickets' one format: base64url(json payload) . "." . hex(hmac_sha256(that base64url, secret)). Every service that checks tickets by itself reads exactly this, so it is written once, here, rather than in each factory - two copies checking a signature two slightly different ways is the bug nobody finds. The payload always names its room and when it expires (`room`, `exp`, a Unix time); the rest is the factory's.

    2 methods

Base\Thread

  • ThreadActions class

    The threads' API (/api/thread/{slug}/...), written once for every host (plan "omnibase agnostic", step F5e, slice 5b; formerly Api\ThreadController): a thread published or hidden by an administrator, followed or no longer followed by a member, liked or no longer liked - each by the "api_thread" token (the body's _token or an X-CSRF-Token header: as plain GET routes, a link or a picture elsewhere published a thread for a signed-in administrator, and made anyone like it). Each answers the JSON the controller answered, statuses included (a visitor's "Unauthorized" carries 401 in its body under a 200, as it did); null is no such thread (404).

    8 methods · 1 constant

  • ThreadSearch class

    The threads' search, written once for every host (plan "omnibase agnostic", step F5e, slice 5b; formerly ThreadSearchController::Main()): the generic term stands for the title, the excerpt and the content where they are not given apart; the published threads only, every state for an administrator; under the parent asked; the threads of the class highest in the hierarchy first. The model keeps the raw terms: the page highlights them.

    2 methods · 1 constant

Base\Traits

  • BagTrait trait

    2 methods

  • BaseCommonTrait trait

    25 methods

  • BaseTrait trait

    Static service accessors usable from anywhere (entities, attributes, subscribers, ...): the tool for writing an application quickly (plan "omnibase agnostique", C9 - Marco: "BaseTrait était un outil qui me permettait de développer rapidement"). It stays, and is not deprecated.

    32 methods

  • CacheClearTrait trait

  • CacheableTrait trait

    3 methods

  • FrameworkAccessorsTrait trait

    BaseTrait's accessors of the framework's services, from before BaseTrait named contracts only (plan "omnibase agnostic", step F2f). BaseTrait still uses this trait, so that the bundles and the applications that call them keep working; each call is deprecated (E_USER_DEPRECATED) and answers as before - the service, or null where the host has none.

    12 methods

  • ProxyTrait trait

    4 methods

  • SimpleCacheTrait trait

    9 methods

  • SingletonTrait trait

    6 methods

  • UserInfoTrait trait

    7 methods · 2 constants

Base\Translation

  • ApplicationTexts class

    Which texts the application wrote itself (its own translations folder), for the level of politeness (base.translator.politeness, docs/20-architecture/politeness.md).

    1 method

  • OverridingTranslator class

    The site's texts as the team rewrote them in the back office (Base\Entity\Layout\TextOverride, omnibase/admin's "Textes du site"): a rewritten key, in that language, wins over translations/. Between omnibase's translator (which resolves "@messages.key" and falls back between languages) and Symfony's: it sees a plain key and domain, and only answers when it has something.

    11 methods · 1 constant

  • TextOverrideCacheListener class

    A rewritten text saved or deleted: the next page reads them all again.

    5 methods

Base\Twig

  • AppVariable class

    7 methods · 10 properties

  • AssetPackage class

    This defines a Symfony Asset named package that groups all the assets provided by EasyAdmin. This is needed because EasyAdmin uses asset versioning, so the full absolute URLs of assets isn't known (the URL contain changing hashes).

    5 methods · 1 constant

  • Environment class

    omnibase's Twig environment: Twig's, with the page's globals as parameters, the tag renderers (TagRendererPass) and an asset's path as the page links it (Base\View\AssetPaths, through the HTML renderer).

    11 methods

  • Globals class

    2 methods

Base\Twig\Extension

  • AccountTwigExtension class

    account_profile(user): a member's profile as its view model (Base\Screen\Account\ProfilePage), as the visitor asking sees it - what a host page gives the core's profile template when it renders it with the user alone (lesringostars' /profile/of/{username}: `@Base/client/user/profile_show.html.twig` with `{user}`), so that the template reads its screen whoever renders it (plan "omnibase agnostique", C5). Answered by the AccountScreens runtime.

    1 method

  • AnalyticsTwigExtension class

    Thin Twig-side wrapper around Base\Service\Analytics - lets any template (the admin sidebar widget, a future public "N readers this week" badge, ...) reach the counters directly, without every consumer needing its own controller/Twig-global plumbing just to display a number.

    8 methods

  • BreadgrinderTwigExtension class

    4 methods

  • ClassTwigExtension class

    3 methods

  • ClipboardTwigExtension class

    4 methods

  • CommonsTwigExtension class

    The shared bricks, in a template (docs/40-commons):

    5 methods

  • DemoTwigExtension class

    The demonstration in a template (docs/20-architecture/demo.md): {% if demo_mode() %}...{% endif %} the `demo` environment, and no other {% for account in demo_accounts() %} the declared accounts a visitor may sign in as @Base/demo/_banner.html.twig and @Base/demo/_accounts.html.twig are what a layout and a sign-in page include; both print nothing outside `demo`. The banner names the first of these accounts to a visitor who is not signed in. Framework-free: a host that runs no demonstration (Laravel: no `demo` kernel environment) gives the mode alone - never active, no account.

    3 methods

  • DeployVersionExtension class

    A value that changes on every real deploy and stays stable otherwise - meant to be fed into a client-side cache key (e.g.

    3 methods

  • EnumTwigExtension class

    omnibase's enumerations in a template: `enum()` (an enumeration by its class or by the name of its DBAL type, "thread_state"), `|colorify` (the colours a ColorizeInterface gives, an enumeration's by value) and `|trans_enum` / `|trans_enumExists` (a value's words, EnumNouns over the Translations contract).

    7 methods

  • FormTwigExtension class

    6 methods

  • FunctionTwigExtension class

    omnibase's Twig functions and filters. html_attributes, mb_ucfirst, second, join_if_exists, less_than, at and emoji_only are omnibridge/twig's HelperExtension's (registered beside this one, the same results); str_shorten, highlight and datetime stay here, they do more than its copies (str_shorten's SHORTEN_BACK_SHRINK/EXTEND, highlight's excerpt, datetime's patterns lists, intervals and formats), and win over them.

    40 methods

  • HtmlTwigExtension class

    10 methods

  • IconTwigExtension class

    `|iconify` in a template: omnibase's Icons (an icon's name, a list, an enumeration's or a route's icons, as HTML).

    2 methods

  • LinkTwigExtension class

    Links in a template: `|urlify` (a link to an address or to a linkable record, its label the one given, else the address; marked "highlight" when it is the page's own) and `|linkify` (a linkable record's address).

    4 methods

  • LocalBusinessTwigExtension class

    schema.org's LocalBusiness in a template (docs/40-commons/local-business.md):

    2 methods

  • LocalizerTwigExtension class

    omnibase's locale filters and its timezone, country and currency menus, on its Localizer. The language menu, render_locale(), is MenuTwigExtension's (on the host's Locales contract, the same under Laravel).

    7 methods

  • MailTwigExtension class

    What omnibase's e-mail templates ask of Twig beyond Twig's own extras (inky_to_html, inline_css): embed() - a picture of the site's public folder (or of a Twig path) as the e-mail being written embeds it, its cid: address through the template's `email` (Symfony's WrappedTemplatedEmail, or InlineImages where omnibase writes the e-mail itself: Base\Notifier\Mail\EmailComposer), else its public path -, |url (an address made whole) and |inline_css_email (the styles inlined in an e-mail). MediaTwigExtension gives them under Symfony (its embed() and inline_css_email() are these lines); this extension gives them to a host whose Twig has no MediaTwigExtension (omnibridge/laravel), for omnibase's e-mails. Its templates find the public folder as @Public.

    7 methods

  • MathTwigExtension class

    4 methods

  • MediaTwigExtension class

    9 methods

  • MenuTwigExtension class

    The visitor's menus of a page: its language, `render_locale()` (the host's Locales contract: the site's languages and the request's), and its theme, `render_theme_modes()`, `render_theme_filters()`, `render_theme_widths()` (omnibase's ThemizerInterface: the modes, filters and widths the site offers and the visitor chose) - each a template rendered with the choices, the visitor's marked.

    6 methods

  • NotificationTwigExtension class

    What a toolbar needs to draw the bell: the unread count (the red dot), the latest entries (the dropdown), and the two things its script needs - the CSRF token every mutation carries and whether push can be offered at all.

    8 methods

  • OAuthTwigExtension class

    oauth_available('google'): whether a "continue with ..." button can lead anywhere - the provider is declared in hwi_oauth.resource_owners of some firewall AND has a client id. A site that leaves the id empty (a sandbox, a provider not set up yet) keeps the declaration without showing a button that ends on the provider's error page.

    3 methods

  • PaginatorTwigExtension class

    17 methods

  • PictureTwigExtension class

    What a template shows of a stored file through omnibase's media rule (MediaService, Base\Service\FileService): `image()` and `|thumbnail` (the image route's obfuscated address of a picture, at a size, in the format the browser takes), `|crop`, `|soundify` and `|vidify` (an audio or video player over the files' addresses), `|imagify`, `imageset()`, `|mimetype`, `|extensions`, `|filesize`, `|public`, `|downloadable`, `|embed_base64`, `|obfuscate_image`, `|obfuscate_file`, `|lightbox`.

    10 methods

  • SecurityPolicyTwigExtension class

    Exposes the administrator's account-security policy to every template as `security_policy`.

    2 methods

  • SemanticTwigExtension class

    3 methods

  • SharingFilter class

    5 methods

  • TextsTwigExtension class

    A stored text in a template: `|wysiwyg` (an Editor.js document or the HTML of an older editor, rendered - mentions, links, media, headings anchored; printed with |raw) and `|wysiwyg_toc` (its headings), on the Texts contract.

    4 methods

  • ThemizerTwigExtension class

    omnibase's theme filters on its Themizer. The theme menus, render_theme_modes(), _filters() and _widths(), are MenuTwigExtension's (framework-free, the same under Laravel).

    4 methods

  • TradingTwigExtension class

    5 methods

  • TranslatorTwigExtension class

    3 methods

  • WebpackTwigExtension class

    1 method

  • WidgetTwigExtension class

    4 methods

Base\Twig\Loader

Base\Twig\Renderer

Base\Twig\Renderer\Adapter

  • HtmlTagRenderer class

    Collects the HTML a page's templates add to its locations (html_entry_*), to print them where the layout asks. Reset between two requests (ResetInterface, kernel.reset): in a process that answers several - FrankenPHP's worker, a static export - one page's content (timeline.css...) was printed on every page after it.

    9 methods

  • WebpackTagRenderer class

    37 methods

Base\Twig\Variable

  • AdminLinks class

    `app.admin` where omnibase/admin's generator is not at hand (a host other than Symfony, whose back office stays the Symfony site's): crudify() is a record's back-office edit page, named by omnibase/admin's rule (AdminRouteNames::forEntity()), with the record's id - its address by the host's Urls contract, null when the host's Routes know no such route.

    2 methods

  • AdminVariable class

    5 methods

  • EmailVariable class

    The site as an e-mail names it: the e-mail's own title, slogan and logo set in the back office, else the site's. Read from the settings and the router themselves, where it asked BaseService (plan "omnibase agnostique", C9).

    7 methods

  • RandomVariable class

    2 methods

  • SiteVariable class

    21 methods

Base\Validator

Base\Validator\Constraints

  • Alphanumeric class

    1 property

  • AlphanumericPlus class

    1 property

  • AlphanumericPlusValidator class

    1 method

  • AlphanumericValidator class

    1 method

  • File class

    3 methods · 4 properties

  • FileValidator class

    1 method

  • Hexcode class

    1 property

  • HexcodeValidator class

    1 method

  • NotBlank class

    Constraint for the NotBlank validator.

    2 methods · 3 properties

  • NotBlankValidator class

    1 method

  • Password class

    9 methods · 7 properties · 3 constants

  • PasswordValidator class

    1 method

  • StringCaseEntity class

    Constraint for the StringCase Entity validator.

    1 property

  • StringCaseEntityValidator class

    1 method

  • Unique class

    No other record of the class has the same values for these fields (plan "omnibase agnostic", step E1): Symfony's UniqueEntity (symfony/doctrine-bridge) without Doctrine, the lookup asked of the persistence's Repositories (Base\Database\Repository\Repositories, whichever backend answers the unit of work). The same arguments, message, code and violation as UniqueEntity, so an entity that named it says the same; the neutral form layer reads it as omnisense/omnibridge's Unique.

    4 methods · 6 properties · 1 constant

  • UniqueEntity class

    Constraint for UniqueEntity validation.

    1 method · 7 properties · 1 constant

  • UniqueEntityValidator class

    2 methods

  • UniqueValidator class

    Unique's check (plan "omnibase agnostic", step E1): UniqueEntityValidator's steps, the record looked up through the persistence's Repositories instead of Doctrine's registry. The fields are read from the record's properties (Doctrine's reflection fields read the same values), the lookup is `repositoryMethod($criteria)` - findBy asked for two at most -, and the violation is the one UniqueEntity built: at errorPath (the first field by default), its value formatted the same way, the code NOT_UNIQUE_ERROR, the records found as its cause.

    2 methods

Base\View

  • AssetPaths interface

    An asset's path as the page links it (plan "omnibase agnostic", step F4): an address as it is, a path under the request's base folder. Under Twig, omnibase's environment answers it (Base\Twig\Environment, through its HTML renderer); a form type that shows a thumbnail asks it without naming the view engine.

    1 method

  • Bell class

    What a toolbar needs to draw the bell (plan "omnibase agnostic", step F4): the unread count (the red dot), the latest entries (the dropdown), the CSRF token every mutation carries, whether push can be offered and its public key, the back-office page of a notification. All of it for the user signed in (the host's Access contract); anonymous visitors get zeros, so a view needs no guard of its own. NotificationTwigExtension's notifications_*() and push_*() under Twig, the same code for Blade and a React page's props; push is offered where WebPushService is configured (none given: never).

    7 methods

  • Captions class

    Words a page shows that its translations give (plan "omnibase agnostic", step F4): a controller's title and excerpt (title(), excerpt()) and a value as text (|stringify) - FunctionTwigExtension's under Twig, the same code for Blade and a React page's props.

    4 methods

  • Commons class

    The shared bricks in a page (plan "omnibase agnostic", step F4; docs/40-commons): what a page can frame of an address (Embeds), a QR code as an SVG data: URI, the opening hours (of the site or of one place), and a stored picture to its URL - CommonsTwigExtension's embed_url(), qr_code(), opening_hours() and |picture under Twig, the same code for Blade and a React page's props. The Pictures contract of the screens (Base\Bridge\Symfony\MediaPictures) is its picture().

    5 methods

  • Dates class

    A moment as a pattern says it (plan "omnibase agnostic", step F4): the logic of the |datetime filter, formatted by PHP's intl as Twig's format_datetime() formats it (twig/intl-extra), without Twig - FunctionTwigExtension calls it with Twig's time zone, Blade and a React page's props with the application's.

    4 methods

  • Demo class

    The demonstration in a page (plan "omnibase agnostic", step F4; docs/20-architecture/demo.md): whether it runs (the `demo` environment, and no other) and the declared accounts a visitor may sign in as - DemoTwigExtension's demo_mode() and demo_accounts() under Twig, the same code for Blade and a React page's props. A host that runs no demonstration gives the mode alone - never active, no account.

    3 methods

  • DeployVersion class

    A value that changes on every real deploy and stays stable otherwise (plan "omnibase agnostic", step F4: DeployVersionExtension's deploy_version(), the same for Blade and a React page) - meant to be fed into a client-side cache key (@glitchr/transparent's Transparent.ready({cache_version: deploy_version()})) so a browser tab that cached a page before a deploy does not keep replaying it.

    2 methods

  • Enums class

    omnibase's enumerations in a page (plan "omnibase agnostic", step F4): an enumeration by its class or by its column type's name ("thread_state"), the colours a ColorizeInterface gives, a value's words (EnumNouns over the Translations contract) - EnumTwigExtension's enum(), |colorify and |trans_enum under Twig, the same code for Blade and a React page's props.

    5 methods

  • Formats class

    omnibase's formatting and value helpers, with no view engine (plan "omnibase agnostic", step F4): what the Twig functions and filters of FunctionTwigExtension and ClassTwigExtension compute - |highlight, mailto(), mailparse_email(), |pickup, |color_name, get_short_class()... -, the same code for Twig (the extensions call it), Blade (omnibridge/laravel) and a React page's props.

    19 methods

  • Links class

    Links (plan "omnibase agnostic", step F4): a link to an address or to a linkable record (|urlify) and a linkable record's address (|linkify) - LinkTwigExtension's under Twig, the same code for Blade and a React page's props. Whether an address is the page's own is the host's answer, a closure (omnibase's router under Symfony, omnibridge/laravel's under Laravel).

    3 methods

  • Menus class

    The visitor's menus of a page as data (plan "omnibase agnostic", step F4): the choices a menu offers and the one the visitor made - its language (the host's Locales contract), its theme's modes, filters and widths (omnibase's Themizer), its time zone and country (omnibase's Localizer). Twig renders them with omnibase's dropdown templates (render_locale(), render_theme_modes()..., MenuTwigExtension and LocalizerTwigExtension); Blade renders the same data, a React page takes it as props.

    7 methods

  • Money class

    An amount in the currency the visitor reads (plan "omnibase agnostic", step F4): the logic of the |format_currency and |apply_currency_rate filters, on the Trading service's rates, formatted by PHP's intl as Twig's format_currency() formats it (twig/intl-extra), without Twig - TradingTwigExtension calls it, Blade and a React page's props the same.

    4 methods

  • Pagination class

    A pagination's controls (plan "omnibase agnostic", step F4): the links of the paginator_*() functions and what the sliding control's template is given (paginator()), the same for Twig (PaginatorTwigExtension calls it), Blade and a React page's props.

    15 methods

  • Pictures class

    What a page shows of a stored picture through omnibase's media rule (plan "omnibase agnostic", step F4): image(), |crop and the |thumbnail filters of PictureTwigExtension, which call it with the template's context; Blade and a React page's props give theirs. In an e-mail being written (a context's `email` being Symfony's WrappedTemplatedEmail) a picture is made at once and never as WebP; a context's `warmup` is handed on.

    5 methods

  • ViewsAdapter class

    omnibridge's Views from what a constructor was given (plan "omnibase agnostic", step F5a): the core's services render through Views, and still accept Twig's environment, deprecated until 6.0, wrapped in omnibridge/twig's TwigViews. Naming Twig's class in a type loads nothing of Twig.

    2 methods

  • Widgets class

    A widget slot of a page as data (plan "omnibase agnostic", step F4): the template of the widget a slot holds and what it is rendered with (its row and widget classes, its label) - WidgetTwigExtension's render_slot() renders it under Twig; Blade renders the same, a React page takes it as props.

    2 methods

  • Wysiwyg class

    A stored text rendered (plan "omnibase agnostic", step F4): an Editor.js document or the HTML of the older editor, its mentions and links enhanced, its semantics if asked, its media, its headings anchored - the pipeline of |wysiwyg and |wysiwyg_toc (HtmlTwigExtension::renderWysiwyg() under Twig, the Texts contract of the screens: Base\Bridge\Symfony\WysiwygTexts), the same code for Blade and a React page's props.

    3 methods

App\Controller

DemoController class

class DemoController extends AbstractController DemoController.php:18

A deliberately flat, style-free tour of a few base-bundle features.

Every section runs in isolation so a failing feature reports its error instead of breaking the whole page.

DemoController::index()

public function index(SettingBagInterface $settings, ObfuscatorInterface $obfuscator, TranslatorInterface $translator, EntityManagerInterface $em): Response

Base

Discovery class

final class Discovery Discovery.php:18

What a host discovers among the core's services, as data (plan "omnibase agnostic", step F5e slice 4c; §2.5: the declaration is the core's, a bridge compiles it): the registries of src/Resources/discovery.php - what the 21 compiler passes of omnibridge/symfony looked for until then, each in its own class. omnibridge/symfony compiles them in one generic pass, omnibridge/laravel applies those it needs to what it binds (the collections, the fallbacks, the entity listeners' events, the repositories), and Omnibridge\Container builds with the generic kinds (autoconfigure, collect, fallbacks: omnisense/omnibridge's Container\Discovery format).

Kinds (KINDS): autoconfigure, collect, fallbacks, preferred, contracts, arguments, texts, storages, enumerations, repositories. docs/20-architecture/services.md.

const KINDS = ['autoconfigure', 'collect', 'fallbacks', 'preferred', 'contracts', 'arguments', 'texts', 'storages', 'enumerations', 'repositories']

Discovery::registries()

public static function registries(): array

Every registry, by kind.

Discovery::registry()

public static function registry(string $kind): array

One registry.

Discovery::enumerations()

public static function enumerations(string $projectDir, ?string $packageDir = null): array

The enumerations of the core and of an application, by their names: the non-abstract classes extending the registry's base class in its folders, each folder in the order the filesystem lists it (as the Symfony bundle has always listed them), an application's over the core's of the same name.

$packageDir

the core's folder (this package's by default)

Options class

final class Options Options.php:23

The core's options as data (plan "omnibase agnostic", step F5e slice 4b): the schema of base: - each option's type, default, what it is for, its deprecation, its nesting - and the environment variables a service reads that need a value where the environment has none. One declaration, read by every host, so that no option is declared twice:

  • omnibridge/symfony compiles the schema into BaseConfiguration's TreeBuilder (config:dump-reference base, debug:config base, the container's base.* parameters) and sets each env(NAME) parameter;
  • omnibridge/laravel validates the application's config/base.php with process() and takes the defaults it leaves out from it, its placeholders resolved by the application (%kernel.project_dir%: its base path);
  • a plain-PHP host gives Omnibridge\Container parameters(): every base.* parameter, as Symfony's extension sets them, and environment()'s defaults.

The schema is src/Resources/options.php, in Omnibridge\Options\Processor's node format; Processor and the Symfony tree answer alike (the same values, the same refusals: tests/Options/OptionsHostsTest).

const ROOT = 'base'

The root of the options: base:, the parameters base.*.

Options::schema()

public static function schema(): array

The options' schema: the root's children, in Omnibridge\Options\Processor's node format.

Options::environment()

public static function environment(?string $group = null): array

The environment variables the services read through %env()% that need a value where the environment has none (Symfony's env(NAME) parameters), by name; a group's only (Base\Services::GROUPS) when one is given.

Options::process()

public static function process(?array ...$configs): array

Configurations of base: merged in their order, checked against the schema and completed with its defaults, the placeholders of the defaults left for the host ('%kernel.project_dir%', '%env(APP_ENV)%').

Throws

Omnibridge\Options\InvalidOption an option the schema refuses

Options::defaults()

public static function defaults(): array

What a configuration that says nothing gives.

Options::parameters()

public static function parameters(?array ...$configs): array

The base.* parameters, as Symfony's extension sets them from the processed configuration: each option by its full name ('base.user.identifier'), an array also whole ('base.user') and item by item ('base.demo.admin_roles.0').

Options::environmentParameters()

public static function environmentParameters(): array

environment()'s defaults as the parameters a container reads them by: 'env(NAME)' => default.

Services class

final class Services Services.php:47

The core's services as data (plan "omnibase agnostic", steps F5a and F5e slice 4; Marco's answer 3: the services stay available everywhere): one declaration that Symfony's container, Laravel's and omnisense/omnibridge's plain-PHP Omnibridge\Container read alike, so that no service is wired three times. Every service of the core is here - what omnibridge/symfony's config/omnibase/services/*.php registered until slice 4 - with its tags and its decoration.

The definitions are in src/Resources/services/<group>.php, one file per group (the core's former config/services/<group>.php), in the order of GROUPS. A host reads them all (definitions()) or a group at a time (group(): omnibridge/symfony compiles each group in its place among its own definitions, so that its container stays the one it was). Each definition:

  • class (the parent's when left out under a parent), id (the class by default), parent (another definition of the list, whose arguments it inherits);
  • requires: the classes or interfaces a host must have for it (Twig, omniauth, omnisense/omnisign, glitchr/backup-manager...), environment: the one environment it is registered in (applies());
  • arguments by position (0, 1, index_N over a parent's) or by name ($name), in Omnibridge\Container's syntax: '@id' a service, '@?id' a service or null where there is none ('@??id' and '@!id': Symfony's ignore-on-invalid and ignore-on-uninitialized), '%name%' a parameter, '@@' and '%%' escape them; ['!tagged_iterator' => tag] the services of a tag, ['!service_closure' => '@id'] a closure returning one, ['!closure' => [callable]] a callable as a Closure, ['!new' => ['class' => ..., 'arguments' => [...]]] an object built in place, ['!iterator' => [...]] a lazy list; '@.inner' the service a decoration wraps;
  • bind: values by parameter name for what the arguments leave out;
  • factory, calls (method, arguments), decorates (id, inner, priority, on_invalid), tags (a name, or ['name' => ..., attributes...]), and Symfony's public, shared, lazy, abstract, autowire, autoconfigure;
  • contracts: the aliases answering it - an interface or a former id, as a list item, or under its name with public and the alias it goes through (target);
  • symfony: what only Symfony's container gives it, by its own services' ids (the router, the request stack, the cache pools, Twig's environment...): its arguments and calls replace the ones above there, its parent, factory, bind and decorates are added. Laravel's container and Omnibridge\Container autowire what the arguments above leave out (their contracts, by type).

The ids a definition names that the list does not define are the host's: omnibridge's contracts (Urls, Views, Environment, Translations...), Base\Service\ParameterBagInterface, Base\Contract\MediaRouter, Base\Service\Storages, imagine.bitmap, imagine.svg, Symfony\Component\Translation\Translator (docs/20-architecture/services.md). tests/ServicesTest checks that Symfony's container answers the list.

const GROUPS = ['services', 'auth', 'collab', 'commons', 'core', 'database', 'demo', 'form', 'local-business', 'media', 'redirections', 'twig', 'view', 'decoration']

The groups, in the order a host reads them.

Services::definitions()

public static function definitions(): array

Every definition of the core, the groups in their order.

Services::group()

public static function group(string $group): array

The definitions of a group, in their order.

Services::applies()

public static function applies(array $definition, ?string $environment = null): bool

Whether a host registers a definition: the classes and interfaces it requires are installed and, where it names one, the host runs that environment (demo). omnisense/omnibridge's rule, which Omnibridge\Container and omnibridge/laravel read the list with.

Services::id()

public static function id(array $definition): string
$definition

its id, its class by default

Services::contracts()

public static function contracts(array $definition): array

A definition's contracts as alias => options (public, target): a list item is a private alias of the service.

Services::classOf()

public static function classOf(array $definition): ?string

A definition's class, followed through its parents where it gives none (null under a parent the list does not define).

Services::find()

public static function find(string $id): ?array
Returns

the definition of an id

Base\ApiPlatform\Metadata\Resource\Factory

OverriddenResourceNameCollectionFactory class

final class OverriddenResourceNameCollectionFactory implements ResourceNameCollectionFactoryInterface OverriddenResourceNameCollectionFactory.php:31

Keeps one API resource per class the application actually uses.

API Platform scans every bundle's Entity directory, so base-bundle's own resources (Base\Entity\User, Base\Entity\Thread) are collected next to the application's, and two things make the same resource show up twice:

  • An App\ override: App\Entity\User mirrors Base\Entity\User and extends it. Both declare the same operations under the same names.
  • A class alias: where the application has no override, App\Entity\X is an alias of Base\Entity\X. PHP lists an alias among the declared classes - lowercased ("app\entity\thread") - so the scan finds the same class under a second name.

API Platform used to let the second declaration silently replace the first; since 4.3.18 it refuses, and the router - so the whole kernel - fails.

So entries naming the same class collapse into one, under its real name, and a Base\ resource that an App\ class extends gives way to it: the override is the resource the application means. A Base\ resource only extended under another name (App\Entity\Article extends Base\Entity\Thread) stays, since their operations do not collide.

OverriddenResourceNameCollectionFactory::__construct()

public function __construct(readonly ResourceNameCollectionFactoryInterface $decorated)

OverriddenResourceNameCollectionFactory::create()

public function create(): ResourceNameCollection

Base\Attributes

AbstractAttribute class

abstract class AbstractAttribute implements AttributeInterface AbstractAttribute.php:43

AbstractAttribute::getAttributeReader()

public static function getAttributeReader(): ?AttributeReader

AbstractAttribute::getEnvironment()

public static function getEnvironment(): string

AbstractAttribute::getProjectDir()

public static function getProjectDir(): string

AbstractAttribute::getParameterBag()

public static function getParameterBag(): ParameterBagInterface

AbstractAttribute::getEntityManager()

public static function getEntityManager(): ?EntityManager

AbstractAttribute::getEntityHydrator()

public static function getEntityHydrator(): EntityHydratorInterface

AbstractAttribute::getTypeOfField()

public static function getTypeOfField($className, string $property)
Throws

Exception

AbstractAttribute::getClassMetadata()

public static function getClassMetadata($objectOrClass): ?ClassMetadata

AbstractAttribute::getClassMetadataManipulator()

public static function getClassMetadataManipulator(): null|MetadataManipulator|\Omnibridge\Doctrine\Omnibase\Database\Mapping\ClassMetadataManipulator

The reader's manipulator: omnisense/omnibase's MetadataManipulator on the persistence's shapes (plan "omnibase agnostic", step E3), omnibridge/doctrine's ClassMetadataManipulator where a reader was made with that one.

AbstractAttribute::getClassMetadataCompletor()

public static function getClassMetadataCompletor(mixed $entityOrClassOrMetadata): null|Completor|\Omnibridge\Doctrine\Omnibase\Database\Mapping\ClassMetadataCompletor

AbstractAttribute::getFlysystem()

public static function getFlysystem(): Storages

AbstractAttribute::getImpersonator()

public static function getImpersonator(): ?User

AbstractAttribute::getUser()

public static function getUser(): ?User

AbstractAttribute::getRepository()

public static function getRepository($className): EntityRepository|ObjectRepository

AbstractAttribute::getAsset()

public static function getAsset($url): string

AbstractAttribute::resolveAttributes()

public static function resolveAttributes($entityOrClassNameOrMetadataOrRefl, string $mappingPath, ?string $attributeClass = null): array

Resolve the attribute instances mapped at $mappingPath for an entity/class (optionally filtered to $attributeClass). Named resolveAttributes rather than getAttributes: several #[Attribute] subclasses (e.g. IsGranted) have their own unrelated instance-level getAttributes()/setAttributes() pair, which a same-named static method here would collide with (incompatible static/instance override).

Throws

Exception

AbstractAttribute::getAttribute()

public static function getAttribute($entityOrClassNameOrMetadataOrRefl, string $mapping, string $attributeClass): mixed

AbstractAttribute::hasAttribute()

public static function hasAttribute($entityOrClassNameOrMetadataOrRefl, string $mapping, string $attributeClass): bool

AbstractAttribute::getUnitOfWork()

public static function getUnitOfWork(): UnitOfWork

Minimize the use unit of work to very specific context.. (doctrine internal use only) Please use getNativeEntity() to get back the

AbstractAttribute::getEntityChangeSet()

public static function getEntityChangeSet($entity, ?NeutralUnitOfWork $unitOfWork = null): array|PersistentCollection

The entity's changes, computed again first. Given the unit of work of the hook's event (plan "omnibase agnostic", step F7c), omnisense/omnibridge's contract answers - recompute(), then changes() -, whichever persistence keeps the entity; without one, Doctrine's unit of work (deprecated until 6.0).

AbstractAttribute::getSerializer()

public static function getSerializer(): ?Serializer

AbstractAttribute::isSerializable()

public static function isSerializable(AbstractAttribute $attribute): bool

AbstractAttribute::getPropertyOwnerRepository()

public function getPropertyOwnerRepository($entity, string $property, ?NeutralUnitOfWork $unitOfWork = null): EntityRepository|\Base\Database\Repository\Entities
Returns

the repository of the class declaring $property (an omnibase repository, Base\Database\Repository\ServiceEntityRepository, or any other)

Throws

NotSupported

AbstractAttribute::getEntityFromData()

public static function getEntityFromData($classname, $data, ?NeutralUnitOfWork $unitOfWork = null): ?object

AbstractAttribute::getOriginalEntity()

public static function getOriginalEntity($entity, ?NeutralUnitOfWork $unitOfWork = null): ?object
Throws

MappingException

AbstractAttribute::getOriginalEntityData()

public static function getOriginalEntityData($entity, ?NeutralUnitOfWork $unitOfWork = null): ?array
Throws

MappingException

AbstractAttribute::getOldEntity()

public static function getOldEntity($entity, ?NeutralUnitOfWork $unitOfWork = null): ?object

AbstractAttribute::getOldEntityData()

public static function getOldEntityData($entity, ?NeutralUnitOfWork $unitOfWork = null): ?array

AbstractAttribute::hasField()

public static function hasField($entity, string $property): bool

AbstractAttribute::getFieldValue()

public static function getFieldValue($entity, string $property, ?NeutralUnitOfWork $unitOfWork = null)
Throws

Exception

AbstractAttribute::setFieldValue()

public static function setFieldValue($entity, string $property, $value, ?NeutralUnitOfWork $unitOfWork = null): false|MetadataManipulator|\Omnibridge\Doctrine\Omnibase\Database\Mapping\ClassMetadataManipulator|EntityValues

AbstractAttribute::hasProperty()

public static function hasProperty($entity, string $property): bool

AbstractAttribute::getPropertyValue()

public static function getPropertyValue($entity, string $property, ?NeutralUnitOfWork $unitOfWork = null)

AbstractAttribute::setPropertyValue()

public static function setPropertyValue($entity, string $property, $value, ?NeutralUnitOfWork $unitOfWork = null): MetadataManipulator|\Omnibridge\Doctrine\Omnibase\Database\Mapping\ClassMetadataManipulator|EntityValues

AbstractAttribute::loadClassMetadata()

public function loadClassMetadata(ClassMetadata $classMetadata, string $target, ?string $targetValue = null): void

AbstractAttribute::complete()

public function complete(Completor $completor, string $target, ?string $targetValue = null): void

What the attribute adds to its class's completor (plan "omnibase agnostic", step E3: #[Alias]'s names, #[Hierarchify]'s hierarchy), on no ORM: Base\Database\Mapping\Completors calls it for each attribute of the class, its methods and its properties - the target and the class, method or property it is on.

AbstractAttribute::resolveDiscriminator()

public function resolveDiscriminator(ResolveDiscriminatorEventArgs $args): void

AbstractAttribute::preQuery()

public function preQuery(DoctrineQueryEventArgs $args): void

AbstractAttribute::onQuery()

public function onQuery(DoctrineQueryEventArgs $args): void

AbstractAttribute::postQuery()

public function postQuery(DoctrineQueryEventArgs $args): void

AbstractAttribute::preFlush()

public function preFlush(PreFlushEventArgs $event, ClassMetadata $classMetadata, mixed $entity, ?string $property = null): void

AbstractAttribute::onFlush()

public function onFlush(OnFlushEventArgs $event, ClassMetadata $classMetadata, mixed $entity, ?string $property = null)

AbstractAttribute::postFlush()

public function postFlush(PostFlushEventArgs $event, ClassMetadata $classMetadata, mixed $entity, ?string $property = null)

AbstractAttribute::prePersist()

public function prePersist(BaseLifecycleEventArgs $event, ClassMetadata $classMetadata, mixed $entity, ?string $property = null)

AbstractAttribute::preUpdate()

public function preUpdate(BaseLifecycleEventArgs $event, ClassMetadata $classMetadata, mixed $entity, ?string $property = null)

AbstractAttribute::preRemove()

public function preRemove(BaseLifecycleEventArgs $event, ClassMetadata $classMetadata, mixed $entity, ?string $property = null)

AbstractAttribute::postLoad()

public function postLoad(BaseLifecycleEventArgs $event, ClassMetadata $classMetadata, mixed $entity, ?string $property = null)

AbstractAttribute::postPersist()

public function postPersist(BaseLifecycleEventArgs $event, ClassMetadata $classMetadata, mixed $entity, ?string $property = null)

AbstractAttribute::postUpdate()

public function postUpdate(BaseLifecycleEventArgs $event, ClassMetadata $classMetadata, mixed $entity, ?string $property = null)

AbstractAttribute::postRemove()

public function postRemove(BaseLifecycleEventArgs $event, ClassMetadata $classMetadata, mixed $entity, ?string $property = null)

AbstractAttribute::onPrePersist()

public function onPrePersist(Lifecycle\PrePersist $event, ?string $property = null): void

AbstractAttribute::onPreUpdate()

public function onPreUpdate(Lifecycle\PreUpdate $event, ?string $property = null): void

AbstractAttribute::onPreRemove()

public function onPreRemove(Lifecycle\PreRemove $event, ?string $property = null): void

AbstractAttribute::onPostLoad()

public function onPostLoad(Lifecycle\PostLoad $event, ?string $property = null): void

AbstractAttribute::onPostPersist()

public function onPostPersist(Lifecycle\PostPersist $event, ?string $property = null): void

AbstractAttribute::onPostUpdate()

public function onPostUpdate(Lifecycle\PostUpdate $event, ?string $property = null): void

AbstractAttribute::onPostRemove()

public function onPostRemove(Lifecycle\PostRemove $event, ?string $property = null): void

AbstractAttribute::onPreFlush()

public function onPreFlush(Lifecycle\PreFlush $event, object $entity, ?string $property = null): void

A flush's moments, for one entity it writes (insertions, updates, deletions).

AbstractAttribute::onOnFlush()

public function onOnFlush(Lifecycle\OnFlush $event, object $entity, ?string $property = null): void

AbstractAttribute::onPostFlush()

public function onPostFlush(Lifecycle\PostFlush $event, object $entity, ?string $property = null): void

AttributeInterface interface

interface AttributeInterface AttributeInterface.php:13

AttributeInterface::supports()

public function supports(string $target, ?string $targetValue = null, mixed $object = null): bool

AttributeInterface::loadClassMetadata()

public function loadClassMetadata(ClassMetadata $classMetadata, string $target, ?string $targetValue = null)

AttributeInterface::resolveDiscriminator()

public function resolveDiscriminator(ResolveDiscriminatorEventArgs $args): void

AttributeInterface::preQuery()

public function preQuery(DoctrineQueryEventArgs $args): void

AttributeInterface::onQuery()

public function onQuery(DoctrineQueryEventArgs $args): void

AttributeInterface::postQuery()

public function postQuery(DoctrineQueryEventArgs $args): void

AttributeInterface::preFlush()

public function preFlush(PreFlushEventArgs $event, ClassMetadata $classMetadata, mixed $entity, ?string $property = null)

AttributeInterface::onFlush()

public function onFlush(OnFlushEventArgs $event, ClassMetadata $classMetadata, mixed $entity, ?string $property = null)

AttributeInterface::postFlush()

public function postFlush(PostFlushEventArgs $event, ClassMetadata $classMetadata, mixed $entity, ?string $property = null)

AttributeInterface::prePersist()

public function prePersist(LifecycleEventArgs $event, ClassMetadata $classMetadata, mixed $entity, ?string $property = null)

AttributeInterface::preUpdate()

public function preUpdate(LifecycleEventArgs $event, ClassMetadata $classMetadata, mixed $entity, ?string $property = null)

AttributeInterface::preRemove()

public function preRemove(LifecycleEventArgs $event, ClassMetadata $classMetadata, mixed $entity, ?string $property = null)

AttributeInterface::postPersist()

public function postPersist(LifecycleEventArgs $event, ClassMetadata $classMetadata, mixed $entity, ?string $property = null)

AttributeInterface::postUpdate()

public function postUpdate(LifecycleEventArgs $event, ClassMetadata $classMetadata, mixed $entity, ?string $property = null)

AttributeInterface::postRemove()

public function postRemove(LifecycleEventArgs $event, ClassMetadata $classMetadata, mixed $entity, ?string $property = null)

AttributeReader class

class AttributeReader extends AbstractLocalCache AttributeReader.php:30

const TARGET_CLASS = "class"
const TARGET_METHOD = "method"
const TARGET_PROPERTY = "property"
const ALL_TARGETS = [self::TARGET_CLASS, self::TARGET_METHOD, self::TARGET_PROPERTY]

AttributeReader::addAttribute()

public function addAttribute($attributes): self

AttributeReader::getEntityManager()

public function getEntityManager()

AttributeReader::getRepository()

public function getRepository($entity)
Throws

NotSupported

AttributeReader::isEntity()

public function isEntity(mixed $entity): bool

AttributeReader::getEntityHydrator()

public function getEntityHydrator(): EntityHydratorInterface

AttributeReader::getClassMetadataManipulator()

public function getClassMetadataManipulator(): MetadataManipulator|\Omnibridge\Doctrine\Omnibase\Database\Mapping\ClassMetadataManipulator

AttributeReader::getFlysystem()

public function getFlysystem(): ?Storages

AttributeReader::getParameterBag()

public function getParameterBag(): ParameterBagInterface

AttributeReader::__construct()

public function __construct(?EventDispatcherInterface $eventDispatcher, ?AdvancedRouterInterface $router, ?EntityManager $entityManager, ParameterBagInterface $parameterBag, ?Storages $flysystem, ?RequestStack $requestStack, ?TokenStorageInterface $tokenStorage, EntityHydrator $entityHydrator, MetadataManipulator|\Omnibridge\Doctrine\Omnibase\Database\Mapping\ClassMetadataManipulator $classMetadataManipulator, string $projectDir, string $environment, string $cacheDir)

The event dispatcher, the router, the filesystem, the request stack and the token storage are the framework's, and may be null: an entity manager built by hand (Base\Bridge\Doctrine\Mapping) reads the attributes of its entities with none of them - what needs one (an asset's base path, the user signed in, the routes' attributes) answers without it. The entity manager too (plan "omnibase agnostic", step E3): the mapping is read through the manipulator, on the persistence's shapes, so a reader is made where doctrine/orm is not installed.

AttributeReader::getEnvironment()

public function getEnvironment()

AttributeReader::getProjectDir()

public function getProjectDir()

AttributeReader::getPaths()

public function getPaths(): array

AttributeReader::addPath()

public function addPath(string $path): self

AttributeReader::configuredPaths()

public static function configuredPaths(ParameterBagInterface $parameterBag): array

The folders base.attributes.paths names. The configuration's list is in the bag whole (base.attributes.paths) and item by item (base.attributes.paths.0, .1...: omnibase's flattened parameters, and what Base\Bridge\Doctrine\Mapping gives an entity manager built by hand); the pattern that read them wanted a dot after the number (paths.0.), which no key has, so none was ever read.

AttributeReader::getAsset()

public function getAsset(string $url): string

AttributeReader::getUser()

public function getUser(): ?UserInterface

AttributeReader::getImpersonator()

public function getImpersonator(): ?User

AttributeReader::getAttributeNames()

public function getAttributeNames(): array

AttributeReader::addAttributeName()

public function addAttributeName(string $attributeName)

AttributeReader::removeAttributeName()

public function removeAttributeName(string $attributeName)

AttributeReader::getAttributeTargets()

public function getAttributeTargets(object|string $className): array

AttributeReader::getParent()

public function getParent(string $className): ?string

Everything related to hierarchy

AttributeReader::getAncestor()

public function getAncestor($className): ?string

AttributeReader::getAncestorAttributes()

public function getAncestorAttributes($className, $attributeNames = null, $attributeTargets = [])
Throws

Exception

AttributeReader::getParentAttributes()

public function getParentAttributes($className, $attributeNames = null, $attributeTargets = [])
Throws

Exception

AttributeReader::getChildren()

public function getChildren($className)

AttributeReader::getChildrenAttributes()

public function getChildrenAttributes($className, $attributeNames = null, $attributeTargets = [])
Throws

Exception

AttributeReader::classAttributesOf()

public static function classAttributesOf(string $class, string $attribute): array

A class's own attributes of a type: the reader's (its cache) where one was made, else read from the class itself - in plain PHP, where the reader is not made (it is built on Doctrine's metadata), the persistence's scopes still read #[Trasheable] and #[Vault] (plan "omnibase agnostic", step F7d).

AttributeReader::getClassAttributes()

public function getClassAttributes(mixed $classNameOrMetadataOrRefl, mixed $attributeNames = null, array $attributeTargets = []): array

AttributeReader::getMethodAttributes()

public function getMethodAttributes(mixed $classNameOrMetadataOrRefl, mixed $attributeNames = null, array $attributeTargets = []): array

AttributeReader::getPropertyAttributes()

public function getPropertyAttributes(mixed $classNameOrMetadataOrRefl, mixed $attributeNames = null, array $attributeTargets = []): array

AttributeReader::getReflClass()

public function getReflClass($classNameOrMetadataOrRefl)

AttributeReader::normalizeNames()

public function normalizeNames(mixed $attributeNames, bool $fallbackAttributeNames = true): ?array

AttributeReader::normalizeTargets()

public function normalizeTargets($attributeTargets, $attributeNames)
Throws

Exception

AttributeReader::warmUp()

public function warmUp(string $cacheDir, ?string $buildDir = null): array

AttributeReader::precompute()

public function precompute(): void

Precompute attributes for every entity class and every routed controller. Iterating the ROUTE COLLECTION makes ApiPlatform load entity metadata, so this must NEVER run from a runtime constructor — only from the cache warmer (cache:clear / cache:warmup), where no Doctrine event dispatch is in flight. Idempotent per cache lifetime via executeOnce.

AttributeReader::getAttributes()

public function getAttributes($classNameOrMetadataOrRefl, $attributeNames = null, array $attributeTargets = []): array
Throws

Exception

Base\Attributes\Attribute

Iconize class

class Iconize extends AbstractAttribute Iconize.php:13

Class Iconize package Base\Attributes\Attribute\Iconize

Iconize::__construct()

public function __construct(array|string $icons = [])

Iconize::supports()

public function supports(string $target, ?string $targetValue = null, $object = null): bool

Iconize::getIcons()

public function getIcons()

IsGranted class

class IsGranted extends AbstractAttribute IsGranted.php:12

IsGranted::__construct()

public function __construct(array|string|Expression $attributes, array|string|Expression|null $subject = null, ?string $message = null, ?int $statusCode = null)

IsGranted::supports()

public function supports(string $target, ?string $targetValue = null, $object = null): bool

IsGranted::setAttributes()

public function setAttributes($attributes)

IsGranted::getAttributes()

public function getAttributes()

IsGranted::setSubject()

public function setSubject($subject)

IsGranted::getSubject()

public function getSubject()

IsGranted::getMessage()

public function getMessage()

IsGranted::setMessage()

public function setMessage($message)

IsGranted::getStatusCode()

public function getStatusCode()

IsGranted::setStatusCode()

public function setStatusCode($statusCode)

IsGranted::setValue()

public function setValue($value)

IsGranted::getAliasName()

public function getAliasName()

IsGranted::allowArray()

public function allowArray()

Route class

class Route extends Route Route.php:14

Attribute class for @Route().

const TRANSLATIONS_FILE = "/config/routes_paths.yaml"

Path relative to the project directory of the central route path dictionary consulted when $path is a bare key (see __construct()).

Route::__construct()

public function __construct(string|array|null $path = null, ?string $name = null, array $requirements = [], array $options = [], array $defaults = [], ?string $host = null, ?string $domain = null, ?string $subdomain = null, ?string $machine = null, ?int $port = null, array|string $methods = [], array|string $schemes = [], ?string $condition = null, ?int $priority = null, ?string $locale = null, ?string $format = null, ?bool $utf8 = null, ?bool $stateless = null, ?string $env = null)

Sitemap class

class Sitemap extends AbstractAttribute Sitemap.php:21

Class Sitemap package Base\Attributes\Attribute\Sitemap

Sitemap::__construct()

public function __construct(?string $group = null, float $priority = 0.5, string $changefreq = "daily", ?string $lastmod = null)

Sitemap::getUrls()

public static function getUrls()

Sitemap::getGroup()

public function getGroup()

Sitemap::getLastMod()

public function getLastMod()

Sitemap::getChangeFreq()

public function getChangeFreq()

Sitemap::getPriority()

public function getPriority()

Sitemap::supports()

public function supports(string $target, ?string $targetValue = null, $object = null): bool

Base\Attributes\Traits

HierarchifyTrait trait

trait HierarchifyTrait HierarchifyTrait.php:7

HierarchifyTrait::getHierarchy()

public function getHierarchy($id = -1, ?string $separator = null)
Throws

Exception

HierarchifyTrait::getHierarchyDepth()

public function getHierarchyDepth(?string $separator = null)
Throws

Exception

HierarchifyTrait::getHierarchyTree()

public function getHierarchyTree(?string $separator = null)
Throws

Exception

Base\Auth

DemoPasswords class

class DemoPasswords implements Passwords DemoPasswords.php:18

The passwords in a demonstration (the demo environment, plan "omniauth" AU7): Base\Subscriber\DemoBackOfficeSubscriber's rule where omniauth checks the password - the super-administrator signs in with base.demo.superadmin_password, an account that opens the back office with base.demo.admin_password, never with the password the database holds (a copy of the production's); while a tier's secret is not set, its accounts have no password at all. Every other account's is its own (the store this decorates). A secret is never written in place of a password.

DemoPasswords::__construct()

public function __construct(protected readonly Passwords $inner, protected readonly DemoAccountRegistry $accounts, protected readonly ?string $superAdminSecret = null, protected readonly ?string $adminSecret = null)

DemoPasswords::hash()

public function hash(object $account): ?string

DemoPasswords::update()

public function update(object $account, string $hash): void

EnrolmentPrompt class

final class EnrolmentPrompt EnrolmentPrompt.php:29

When a signed-in visitor is sent to the second factor's enrolment page (user_settings_enrolment), framework-free (step R29 of the audit "lesringostars face au master plan"): what Base\Subscriber\ SecurityEnrolmentSubscriber asks under Symfony and omnibridge/laravel's enrolment middleware asks under Laravel, each with its own request and session.

  • Only a plain top-level GET of an HTML page is interrupted (interrupts()): a form posted lands where it was going, a script gets its JSON, a file downloads; never the pages that answer the prompt (the settings, the sign-in and sign-out, the registration, the password's, an identity provider's return, the profiler's).
  • The offer after a sign-in from an unknown browser (the session's SecurityPolicy::SESSION_NEW_DEVICE_PROMPT, set by the sign-in's WarnNewDevice) is made once, while the account has no second factor; the flag is forgotten otherwise (forgetsTheOffer()).
  • A second factor the account must have and does not (SecurityPolicy:: needsEnrolment()): every page, unless the session said "not now" where the application allows a "later", or the visitor is someone impersonating the account.
const EXEMPT_PREFIXES = ['/settings', '/login', '/logout', '/register', '/reset-password', '/connect/', '/_']

Path prefixes the prompt never interrupts: the settings pages hold the answer, the security paths the way in and out, /_ the profiler.

EnrolmentPrompt::__construct()

public function __construct(readonly SecurityPolicy $policy)

EnrolmentPrompt::interrupts()

public static function interrupts(string $method, bool $script, array $acceptable, string $path): bool

Whether a request asks for a page the prompt may stand in for.

$acceptable

the content types the client accepts, in order (none: anything)

EnrolmentPrompt::due()

public function due(?object $user, bool $offered, bool $skipped, bool $impersonating): bool

Whether the visitor goes to the enrolment page now.

$offered

the session holds the offer after a new device

$skipped

the session said "not now" (SecurityPolicy::SESSION_ENROLMENT_SKIPPED)

$impersonating

the visitor impersonates the account (a super-admin's support)

EnrolmentPrompt::forgetsTheOffer()

public function forgetsTheOffer(?object $user, bool $offered): bool

Whether the offer after a new device is moot (nobody signed in, or a second factor set up since): its flag goes.

EnrolmentPrompt::page()

public function page(?object $user, bool $offered): ?bool

What the enrolment page shows: null when there is nothing to ask (the page sends to the settings, and the offer's flag goes), else whether it is the optional offer after a new device (other words, a "no thanks" remembered for good) rather than the mandatory enrolment.

NotifierSender class

class NotifierSender implements Sender NotifierSender.php:23

omniauth's Sender on omnibase's e-mails (plan "omniauth", §1.9): a sign-in link (Notifier::loginLink(), the e-mail of the former loginToken()) and the second factor's code (Notifier::emailCode()), by e-mail alone - what the page tells the visitor is the same whether an account goes with the address or not.

Under Symfony the Notifier sends them; under a host without Symfony's Notifier (omnibridge/laravel) Base\Notifier\Mail\SignInMails writes the same e-mails and sends them through the host's mailer (R26).

NotifierSender::__construct()

public function __construct(protected readonly Notifier|SignInMails $notifier)

NotifierSender::send()

public function send(object $account, Message $message): void

Policy class

class Policy implements SecondFactorPolicy Policy.php:35

omnibase's rule around omniauth's (plan "omniauth", §1.6, step AU4 - the former P4 of the study): Base\Service\SecurityPolicy, asked of the account signing in, decorating the second-factor rule omniauth is given (EnrolledSecondFactors: a second factor after a password, a link or an identity provider, for an account that set one up).

  • A demonstration account (the demo environment) is never asked for a second factor: every visitor signs in with it.
  • An account a second factor is required of (the administrator's "mandatory", or one of base.security.two_factor.required_roles: the administration roles of a site) that has none is signed in, then sent to enrol, as today: needsEnrolment() is what the host's enrolment prompt asks (SecurityEnrolmentSubscriber under Symfony).
  • "The administrator wins" when a factor is turned off: onRevoking(), a listener of omniauth's Revoking event, refuses to turn off the last second factor of an account that must keep one (two-factor-mandatory), and any credential of a demonstration account (demo-account) - a hidden button and a forged POST meet the same predicate.
  • Linking by the address alone (QA3): allowsEmailLinking() refuses an account that has a second factor or an administration role (SecurityPolicy::isAdministrator()); PolicyLinking hands it to omniauth's OAuthMethod.
const MANDATORY = 'two-factor-mandatory'
const DEMO = 'demo-account'

Policy::__construct()

public function __construct(protected readonly SecurityPolicy $security, protected readonly SecondFactorPolicy $inner)

Policy::required()

public function required(object $account, array $passed, Context $context): array

Policy::needsEnrolment()

public function needsEnrolment(object $account): bool

Must this account set up a second factor before carrying on (signed in, sent to the enrolment)?

Policy::allowsEmailLinking()

public function allowsEmailLinking(object $account): bool

May this account be linked to an identity provider by its address alone (QA3)?

Policy::onRevoking()

public function onRevoking(Revoking $event): void

Listens to omniauth's Revoking event.

Policy::events()

public static function events(): array
Returns

omniauth's events and the method of this class each calls

PolicyLinking class

class PolicyLinking implements EmailLinking PolicyLinking.php:14

omniauth's rule for a link by a verified address, on omnibase's Policy (QA3): never for an account with a second factor or an administration role, nor a demonstration account; $also adds another rule (omniauth's NoSecondFactorLinking, which reads the methods mounted).

PolicyLinking::__construct()

public function __construct(protected readonly Policy $policy, protected readonly ?EmailLinking $also = null)

PolicyLinking::allows()

public function allows(object $account, Identity $identity): bool

Registration class

final class Registration Registration.php:20

A sign-up once its form holds, the same on every host (plan "omnibase agnostic", step F5c): the account approved or left to an administrator (base.user.register.autoapprove), its password, a name when its class has a username the form left empty, verified at once when a verified account signs up (a social connection), the administrators told (base.user.register.notify_admins), then kept. Symfony's SecurityController::Register() signs the account in afterwards; another host does it its own way.

Registration::__construct()

public function __construct(readonly ParameterBagInterface $parameters, readonly UnitOfWork $unitOfWork, readonly Users $users, readonly ?NotifierInterface $notifier = null)

Registration::register()

public function register(User $user, ?string $plainPassword, ?User $signedIn = null): User

The new account made ready and kept; $signedIn the account already signed in, if any.

Registration::name()

public function name(User $user): void

An application's User usually carries a username - a column of its own, unique and not null - which the sign-up form does not ask for: the account was inserted without one and the sign-up answered 500. It is given the local part of its address, numbered when somebody has it ("anne", "anne2"), as an invitation's or a demonstration's account is named. A form that asks for a username (an application's own type) keeps what was typed; a User without that column is left alone.

UserAccounts class

class UserAccounts extends UserStore implements Accounts UserAccounts.php:28

omniauth's accounts: omnibase's users (the user table, and the application's own beside it - lesringostars' userProfile, joined).

  • byIdentifier(): the address, as Base\Repository\UserRepository's loadUserByIdentifier() finds it, then the application's identifier field when it is another (User::$userIdentifier: lesringostars' username), as its own repository does (findOneByEmailOrUsername()).
  • the handle: the id, as text - the passkeys' userHandle since AU1.
  • check(): Base\Security\UserChecker's rule - an account class that implements LoginRestrictionInterface, a banned, a locked, a disabled account may not sign in; the reason is the key of its message, "@notifications.login.<reason>". A disabled account with a valid "welcome-back" token is enabled again (the e-mail that token came with is Listener\WelcomeBack's, on omniauth's AccountRefused event).
const RESTRICTED = 'restricted'
const BANNED = 'banned'
const LOCKED = 'locked'
const DISABLED = 'disabled'
const WELCOME_BACK = 'welcome-back'

The token that lets a disabled account back in (UserChecker's).

UserAccounts::byIdentifier()

public function byIdentifier(string $identifier): ?object

UserAccounts::byHandle()

public function byHandle(string $handle): ?object

UserAccounts::handle()

public function handle(object $account): string

UserAccounts::identifier()

public function identifier(object $account): string

UserAccounts::displayName()

public function displayName(object $account): string

UserAccounts::email()

public function email(object $account): ?string

UserAccounts::check()

public function check(object $account): void

UserBackupCodes class

class UserBackupCodes extends UserStore implements BackupCodes UserBackupCodes.php:8

The backup codes: user.backupCodes, a JSON list of password_hash()'s, as User::setBackupCodes() writes it.

UserBackupCodes::hashes()

public function hashes(object $account): array

UserBackupCodes::replace()

public function replace(object $account, array $hashes): void

UserEmailCodes class

class UserEmailCodes extends UserStore implements EmailCodes UserEmailCodes.php:14

The code by e-mail: user.emailAuthEnabled, and user.emailAuthCode holding, by Marco's decision QA5, the code's keyed hash (omniauth's EmailCodeMethod computes it) instead of the code scheb/2fa kept in clear; null once used or turned off. A code scheb sent before the switch matches no hash: its owner asks for another (it lived minutes).

UserEmailCodes::enabled()

public function enabled(object $account): bool

UserEmailCodes::enable()

public function enable(object $account): void

UserEmailCodes::disable()

public function disable(object $account): void

UserEmailCodes::remember()

public function remember(object $account, string $hash): void

UserEmailCodes::remembered()

public function remembered(object $account): ?string

UserEmailCodes::forget()

public function forget(object $account): void

UserIdentities class

class UserIdentities extends UserStore implements Identities UserIdentities.php:18

omniauth's identities at providers: the userIdentity table (Base\Entity\User\Identity), by Marco's decision QA3 - an account is found by the provider's subject, never by user.identityProvider (which keeps its own meaning: where the account came from) nor by the address alone. The table's two unique keys refuse what omniauth's OAuthMethod refuses before them: a subject linked to two accounts, two identities of one provider on one account.

UserIdentities::owner()

public function owner(string $provider, string $subject): ?object
public function link(object $account, string $provider, string $subject, ?string $email = null, bool $emailVerified = false): void
public function unlink(object $account, string $provider): void

UserIdentities::used()

public function used(string $provider, string $subject, \DateTimeImmutable $at): void

UserIdentities::providers()

public function providers(object $account): array

UserIdentities::of()

public function of(object $account): array

The account's identities, for its settings page.

@return list<Identity>

UserLinkTokens class

class UserLinkTokens extends UserStore implements LinkTokens, PlainLinkTokens UserLinkTokens.php:25

The sign-in links: the userToken rows named "login-token", logginable, as SecurityController::LoginTokenRequest made them - now, by Marco's decision QA4, holding the link's SHA-256 (64 hexadecimal characters) in value, never the link, until the moment omniauth gives (15 minutes), and used up at the first sign-in: claimed by marking it revoked (one UPDATE: of two requests with the same link, one only gets the account), then removed.

A new link takes the place of the account's former one (User::addToken() keeps one token per name). The links sent before the switch kept their value in clear (22 characters of base64): consumePlain() reads them as they are until their own deadline - never a value shaped like a hash, so the text of the column is no link either.

const NAME = 'login-token'

UserLinkTokens::issue()

public function issue(object $account, string $hash, \DateTimeImmutable $until): void

UserLinkTokens::consume()

public function consume(string $hash, \DateTimeImmutable $now): ?object

UserLinkTokens::consumePlain()

public function consumePlain(string $value, \DateTimeImmutable $now): ?object

UserPasskeys class

class UserPasskeys extends UserStore implements Passkeys UserPasskeys.php:20

omniauth/webauthn's passkeys: the userPasskey table through Base\Entity\User\Passkey, which the core describes since AU1. The record holds the credential id and the public key as base64 - the text of the columns -, the entity their bytes (the passkey_base64 type turns one into the other); the other eleven fields are the same values. A passkey added here is a row web-auth/webauthn-symfony-bundle reads, and one it wrote is a record here (omniauth/webauthn's tests prove both ways on those very columns).

UserPasskeys::of()

public function of(object $account): iterable

UserPasskeys::byCredentialId()

public function byCredentialId(string $credentialId): ?PasskeyRecord

UserPasskeys::add()

public function add(object $account, PasskeyRecord $record, ?string $label = null): void

UserPasskeys::used()

public function used(PasskeyRecord $record): void

UserPasskeys::record()

public static function record(Passkey $passkey): PasskeyRecord

The record of a passkey, in the values of its columns.

UserPasskeys::fill()

public static function fill(Passkey $passkey, PasskeyRecord $record): Passkey

A record's 13 fields on a passkey, the credential id and the public key as bytes.

UserPasswords class

class UserPasswords extends UserStore implements Passwords UserPasswords.php:12

The password hashes: user.password, as Symfony's "auto" hasher wrote them (bcrypt, cost 13 on lesringostars); omniauth's PasswordMethod checks them with symfony/password-hasher under any host and hands back a rehash.

UserPasswords::hash()

public function hash(object $account): ?string

UserPasswords::update()

public function update(object $account, string $hash): void

UserStore class

abstract class UserStore UserStore.php:23

What omniauth's stores over omnibase's tables share (plan "omniauth", §2.2, step AU4): the unit of work (plan "omnibase agnostic", step F2d: omnisense/omnibridge's contract - Doctrine's under Symfony, or over the entity manager a Laravel host builds by hand on the same mapping -), the repositories through it, the accounts as omnibase's users, and a write kept at once (a method that returns has written: a link issued is in the table before its e-mail leaves).

Nothing of a framework: the Base\Auth\ classes load with omniauth, Doctrine and the core alone (BareTest). The core only suggests omniauth; nothing here is wired without it.

UserStore::__construct()

public function __construct(UnitOfWork|\Doctrine\ORM\EntityManagerInterface $unitOfWork)
$unitOfWork

the entity manager is deprecated (until 6.0): adapted by UnitOfWorks

UserTotpSecrets class

class UserTotpSecrets extends UserStore implements TotpSecrets UserTotpSecrets.php:15

The authenticator applications' secrets: user.secret, as the column holds it. Sealed at rest when the site sets omniauth's totp.secret_key (QA5): the hosts' bridges then wrap this store in omniauth/otp's SealedTotpSecrets, so the column holds "otp:v1:..." and its readers the base32 secret; a secret kept in clear before (scheb/2fa's) is read as it is until the site's migration rewrites it.

UserTotpSecrets::secret()

public function secret(object $account): ?string

UserTotpSecrets::enable()

public function enable(object $account, string $secret): void

UserTotpSecrets::disable()

public function disable(object $account): void

UserTrustedVersion class

class UserTrustedVersion extends UserStore implements TrustedVersion UserTrustedVersion.php:11

The trusted devices' version: user.trustedTokenVersion, the "vsn" claim of the trusted_device cookie scheb/2fa wrote and omniauth writes alike.

UserTrustedVersion::version()

public function version(object $account): int

UserTrustedVersion::revokeAll()

public function revokeAll(object $account): void

Base\Auth\Account

AlreadySignedIn class

final class AlreadySignedIn AlreadySignedIn.php:14

The pages for visitors only - the sign-up, the forgotten password and its link -, written once for every host (plan "omnibase agnostic", step F5e, slice 5; formerly SecurityController::Register() and ResetPasswordRequest()/Response(), and the twin's AccountPages::register() again): an account signed in (and kept) is told so and sent to its profile.

const PROFILE_ROUTE = 'user_profile'

AlreadySignedIn::__construct()

public function __construct(readonly Access $access)

AlreadySignedIn::check()

public function check(): ?Outcome

Closing class

final class Closing Closing.php:17

An account closed by its owner, and opened again by the link it is sent, written once for every host (plan "omnibase agnostic", step F5e, slice 5; formerly SecurityController::DisableAccountRequest() and EnableAccountRequest()). A demonstration account is everyone's: it does not close itself.

const TOKEN = 'welcome-back'

Closing::__construct()

public function __construct(readonly Access $access, readonly UnitOfWork $unitOfWork, readonly Tokens $tokens, readonly SecurityPolicy $policy)

Closing::close()

public function close(): Outcome

Closing::welcomeBack()

public function welcomeBack(?string $value): Outcome

The link "welcome back": a closed account with its valid token opened and signed in; otherwise said why.

Devices class

final class Devices Devices.php:19

The account's sessions and passkeys on its settings page, written once for every host (plan "omnibase agnostic", step F5e, slice 5b; formerly UserSettingsController::Settings(), RenamePasskey(), DeletePasskey() and LogoutSession()): the twenty sessions last used (the list is there to spot one that should not be, the oldest of six hundred tell nobody anything), a passkey renamed or removed and a session signed out - each by its token, and only the account's own (another's: no such page) -, then back to the settings.

const SESSIONS_SHOWN = 20

How many of the account's sessions the settings page lists.

const SETTINGS = 'user_settings'
const SESSION_TOKEN = 'session_logout'

Devices::__construct()

public function __construct(readonly Access $access, readonly Connections $connections, readonly Passkeys $passkeys, readonly ?Tokens $tokens = null)

Devices::sessions()

public function sessions(): array
Returns

the account's sessions, the last used first

Devices::passkeyToken()

public static function passkeyToken(string $action, int $id): string

Devices::renamePasskey()

public function renamePasskey(int $id, ?string $token, ?string $label): Outcome

A passkey's label (none for an empty one).

Devices::deletePasskey()

public function deletePasskey(int $id, ?string $token): Outcome

Devices::signOut()

public function signOut(int $id, ?string $token): Outcome

One of the account's sessions signed out.

MemberSearch class

final class MemberSearch MemberSearch.php:13

The members' search, written once for every host (plan "omnibase agnostic", step F5e, slice 5b; formerly UserSearchController::Main()): members are looked for by their username, where the application's account has one - never by their e-mail address, which the page would show to anyone -, fifty at most, the banned and the ghosts left out; no term, no one.

const LIMIT = 50
const TEMPLATE = 'client/user/search.html.twig'

MemberSearch::__construct()

public function __construct(readonly Users $users)

MemberSearch::find()

public function find(?string $term): array

Outcome class

final readonly class Outcome Outcome.php:16

Where an account's page sends the visitor once its rule has decided (plan "omnibase agnostic", step F5e, slice 5): one of omnibase's routes, an address, the site's index - its route, or its address -, the page the visitor was going to (else the index's address), a page to show (a Template), or a refusal (403) or no such page (404); first signing an account in, remembered or not, where the rule says so. The rule decides and sends its notifications; each host turns the Outcome into its answer (omnibridge/symfony's Omnibase\Response\Outcomes, omnibridge/laravel's Http\Outcomes): which router, which referrer, which authenticator are the host's.

const ROUTE = 'route'
const URL = 'url'
const INDEX = 'index'

The index's route (base.site.index), redirected to by its name.

const HOME = 'home'

The index's address.

const BACK = 'back'

The page the visitor was going to, else the index's address.

const PAGE = 'page'
const SIGNED_IN = 'signed-in'

Nothing more than the sign-in: the host answers what signing in answers (its own page, else the index).

const DENIED = 'denied'
const MISSING = 'missing'

Outcome::route()

public static function route(string $route, array $parameters = []): self

Outcome::url()

public static function url(string $url): self

Outcome::index()

public static function index(): self

Outcome::home()

public static function home(): self

Outcome::back()

public static function back(): self

Outcome::page()

public static function page(Template $page): self

Outcome::signedIn()

public static function signedIn(object $user, bool $remember = false): self

Outcome::denied()

public static function denied(?string $reason = null): self

Outcome::missing()

public static function missing(?string $reason = null): self

Outcome::signingIn()

public function signingIn(object $user, bool $remember = false): self

The same, once this account is signed in (remembered: the remember-me cookie as well).

Outcome::toArray()

public function toArray(): array
Returns

what a test compares (the account signed in by its string)

Passwords class

final class Passwords Passwords.php:21

A forgotten password reset by a link, and a password the owner did not choose changed at the first sign-in, written once for every host (plan "omnibase agnostic", step F5e, slice 5; formerly SecurityController:: ResetPasswordRequest(), ResetPasswordResponse() and ChangePassword()). The forms stay the host's; each method is one of their moments. A demonstration account keeps its password, and says so.

const RESET_TOKEN = 'reset-password'
const CHANGE_TOKEN = \Base\Console\Task\UserCreate::PASSWORD_CHANGE

The token user:create gives an account (Base\Console\Task\UserCreate::PASSWORD_CHANGE).

const LOGIN_ROUTE = 'security_login'

Passwords::__construct()

public function __construct(readonly Access $access, readonly UnitOfWork $unitOfWork, readonly Users $users, readonly Tokens $tokens, readonly SecurityPolicy $policy, readonly ?NotifierInterface $notifier = null)

Passwords::resetRequested()

public function resetRequested(?string $email): ?Outcome

An address posted: a link sent by e-mail when it has an account and none is waiting, the one answer every address gets (null: the page again); a demonstration account's, refused aloud.

Passwords::resetToken()

public function resetToken(?string $value): Token|Outcome

The link's token when it is a reset link's, still valid, of an account that may change its password; else where to go.

Passwords::reset()

public function reset(Token $token, ?string $plainPassword): Outcome

The new password chosen: the link used up, the account signed in (remembered), the index.

Passwords::changeToken()

public function changeToken(): Token|Outcome

The account's own token to change its password; else where to go (nobody signed in: the sign-in page).

Passwords::change()

public function change(Token $token, ?string $plainPassword): Outcome

The password chosen: the token used up, signed in again at once (a new password ends the session), the index.

ProfileAccess class

final class ProfileAccess ProfileAccess.php:16

Whose profile a page shows or edits, written once for every host (plan "omnibase agnostic", step F5e, slice 5; formerly UserProfileController::Show() and Edit(), and the twin's AccountPages::profileEdit() again): an id, that account (no such account: no such page); none (-1), the account signed in, kept - else the members' search; another's profile is edited by an administrator only.

const SEARCH_ROUTE = 'user_search'

ProfileAccess::__construct()

public function __construct(readonly Access $access, readonly Users $users)

ProfileAccess::show()

public function show(int $id = -1): User|Outcome

ProfileAccess::edit()

public function edit(int $id = -1): User|Outcome

RescuePage class

final class RescuePage RescuePage.php:16

The back office's sign-in page ("rescue"), written once for every host (plan "omnibase agnostic", step F5e, slice 5; formerly RescueController::LoginRescue()): an account signed in fully goes where it was going (else the back office's home); the page shows the back office's logo (else the site's) and sends the visitor, once signed in, to the page it asked for when it is one of this site's - as a path, which the sign-in matches against the routes -, else to the back office's home. Which template and the back office's address are the host's.

const ADMIN_TEMPLATE = '@Admin/page/login.html.twig'

The admin extension's page, preferred; the page bundled with the core where it is not installed.

const TEMPLATE = '@Base/security/rescue.html.twig'
const ADMIN_ROUTE = 'admin'

RescuePage::__construct()

public function __construct(readonly Access $access, readonly ReferrerInterface $referrer, readonly ?SettingBagInterface $settings = null)

RescuePage::signedIn()

public function signedIn(string $adminUrl): ?Outcome
public function logo(): mixed

RescuePage::target()

public function target(string $adminUrl): string

The page asked for before the sign-in, as a path, when it is one of this site's; else the back office's home.

SecondFactor class

final class SecondFactor SecondFactor.php:36

The account's authenticator application, written once for every host (plan "omnibase agnostic", step F5e, slice 5b; formerly UserSettingsController's TwoFactorAuthentication*() and displayTotpQrCode()): - a demonstration account changes nothing of its second factor (refused aloud, back to the settings); - turning it on: refused where the administrator switched the feature off, nothing to do where it is on; a secret kept in the session until a code of the visitor's application confirms it, checked on a copy of the account (the account itself never carries an unconfirmed secret: another request's flush would keep it); confirmed, the secret kept (through omniauth's store, sealed at rest where the site says so), eight backup codes shown once; - turning it off: the token, then the administrator's rule (a second factor required stays), then the password; - the QR codes: the secret as the application scans it (opened by omniauth's store), or the pending one.

The host's are the form, the TOTP authenticator (generating the secret, checking a code, the QR's content: scheb's under Symfony) and the PNG's answer; every decision is here.

const PENDING = '2fa_pending_totp_secret'
const SETTINGS = 'user_settings'
const FORM_TEMPLATE = 'client/user/settings_2fa.html.twig'
const CODES_TEMPLATE = 'client/user/settings_2fa_backup_codes.html.twig'
const DISABLE_TOKEN = '2fa_disable'
const INVALID_CODE = '@notifications.settings.twoFactorInvalidCode'

SecondFactor::__construct()

public function __construct(readonly Access $access, readonly SecurityPolicy $policy, readonly UnitOfWork $unitOfWork, readonly ?Requests $requests = null, readonly ?Tokens $tokens = null, readonly ?TranslatorInterface $translator = null, readonly ?UserPasswordHasherInterface $passwords = null, readonly ?TotpSecrets $totpSecrets = null)

SecondFactor::refused()

public function refused(?object $user = null): ?Outcome

A demonstration account's request refused (null for any other): said so, back to the settings.

SecondFactor::enrolment()

public function enrolment(): ?Outcome

Whether the page that turns it on is shown (null) or where the visitor goes instead.

SecondFactor::pending()

public function pending(\Closure $generate): string

The secret waiting for its first code: the session's, else a new one (the host's authenticator makes it), kept.

SecondFactor::carrying()

public static function carrying(User $user, ?string $secret): User

The account as the code is checked against it (or its QR drawn): a copy carrying $secret.

SecondFactor::confirm()

public function confirm(User $user, string $secret, bool $codeValid): ?Outcome

The code checked by the host's authenticator on carrying(): turned on, its backup codes shown once (an Outcome); a wrong code, null - the form says so (INVALID_CODE, invalidCode()).

SecondFactor::invalidCode()

public function invalidCode(): string

What the form says of a wrong code.

SecondFactor::disable()

public function disable(?string $token, ?string $password): Outcome

Turned off: refused to a demonstration account before anything is checked, then the token, then the administrator's rule (while a second factor is required, the account cannot give its up, password or not), then the password; the secret, the backup codes and the trusted devices forgotten.

SecondFactor::enabled()

public function enabled(): ?User

The account as its application scans it (the secret opened by omniauth's store), null where it has none on.

SecondFactor::waiting()

public function waiting(): ?User

The account carrying the secret waiting for its first code, null where none waits.

SecondFactor::png()

public static function png(string $content): string

A QR code of $content, as a PNG (200 pixels, no margin).

SecondFactor::backupCodes()

public static function backupCodes(int $count = 8): array
Returns

plain-text codes (only ever shown once, right after they are made)

SignIn class

final class SignIn SignIn.php:20

The sign-in page's rules and the sign-in link's, written once for every host (plan "omnibase agnostic", step F5e, slice 5; formerly SecurityController::Login() and LoginTokenRequest()). The forms, the captcha and omniauth's link (where omniauth signs in, it issues the links: the host asks it) stay the host's.

const RESCUE_ROUTE = 'security_rescue'

The page an account allowed in during a maintenance signs in on (RescueFormAuthenticator::LOGIN_ROUTE).

const LOGIN_ROUTE = 'security_login'

The sign-in link's token: its name, how long it lives, how long before another is sent.

SignIn::__construct()

public function __construct(readonly Access $access, readonly ParameterBagInterface $parameters, readonly UnitOfWork $unitOfWork, readonly Users $users, readonly Tokens $tokens, readonly ?NotifierInterface $notifier = null)

SignIn::page()

public function page(): ?Outcome

Before the sign-in page: an account allowed in during a maintenance goes to the rescue page; an account signed in fully goes where it was going; one remembered only is told to sign in again (login.partial).

SignIn::linksEnabled()

public function linksEnabled(): bool

Whether the site signs in by a link sent by e-mail (base.user.login_with_token).

public function link(?string $token, bool $byOmniauth = false): ?Outcome

A sign-in link followed: off, the sign-in page; a valid token, its account signed in, remembered, then where it was going; null for the page asking an address (no token, or one omnibase did not issue).

SignIn::linkRequested()

public function linkRequested(?string $email, bool $byOmniauth = false): Outcome

An address posted for a link (where omnibase issues them): a link sent to it by e-mail when it has an account and none is waiting; then the one answer every address gets.

SignOutPage class

final class SignOutPage SignOutPage.php:20

The sign-out page's rules, written once for every host (plan "omnibase agnostic", step F5e, slice 5; formerly SecurityController::Logout(), whose confirmation omnibridge/laravel's SignIn::logoutPage() wrote again). Signed in: where the host's sign-out asks a CSRF token, a request without the session's is asked to confirm by a link that carries one - a link from another site, an <img>, a page kept from an ended session signs nobody out -; with it, on to the host's sign-out. Signed out: the account that just left is told goodbye (or that it was put out), and the visitor goes back where it was, the index from a secured page.

A prefetch (Base\Service\SpeculativeRequest) is answered with nothing by the host before any of this.

const TEMPLATE = 'security/logout.html.twig'

SignOutPage::__construct()

public function __construct(readonly ?Tokens $tokens, readonly ?Users $users = null, readonly ?UnitOfWork $unitOfWork = null)

SignOutPage::confirms()

public function confirms(bool $csrf, string $intent, mixed $token): bool

Whether a signed-in visitor is asked to confirm: the host checks a token ($csrf) and this one is not the session's.

SignOutPage::left()

public function left(mixed $left): void

The account that has just signed out (what the session kept of it: its id, or the account in an older session): told goodbye, or that it was put out (its kick then forgotten); its expired tokens removed.

SignOutPage::after()

public function after(bool $secured): Outcome

Where a signed-out visitor goes: back where it was, the index's address from a secured page.

Verification class

final class Verification Verification.php:19

An account's e-mail address verified, then its approval asked of the administrators, written once for every host (plan "omnibase agnostic", step F5e, slice 5; formerly SecurityController::VerifyEmailRequest(), VerifyEmailResponse() and AdminApprovalRequest()). The link's account is signed in by the host between tokenOwner() and confirm(). Each step ends on the account's profile.

const TOKEN = 'verify-email'
const APPROVAL_TOKEN = 'admin-approval'
const PROFILE_ROUTE = 'user_profile'
const REQUEST_ROUTE = 'security_verifyEmail'

Verification::__construct()

public function __construct(readonly Access $access, readonly UnitOfWork $unitOfWork, readonly Tokens $tokens, readonly ?NotifierInterface $notifier = null)

Verification::request()

public function request(): Outcome

A verification link asked: already verified, said so; one sent less than an hour ago, said when; else one sent.

Verification::tokenOwner()

public function tokenOwner(?string $value): ?Token

The link's token, the host signing its account in before confirm().

Verification::confirm()

public function confirm(?Token $token): Outcome

The link followed: its account (signed in now) verified when the token is its valid one, then its approval asked where an administrator has to approve it; nobody signed in, back to asking a link.

Verification::approval()

public function approval(): Outcome

The administrators asked to approve the account: once verified, and once.

WaitingPages class

final class WaitingPages WaitingPages.php:16

The pages a visitor waits on - the maintenance, the launch, a page not open yet, an account waiting for its approval -, written once for every host (plan "omnibase agnostic", step F5e, slice 5; formerly SecurityController::Maintenance(), Launch(), Pending() and PendingForApproval()): their templates and data.

WaitingPages::__construct()

public function __construct(readonly Access $access, readonly ?MaintenanceProviderInterface $maintenance = null, readonly ?LauncherInterface $launcher = null)

WaitingPages::maintenance()

public function maintenance(): Outcome

WaitingPages::launch()

public function launch(): Outcome

WaitingPages::pending()

public function pending(): Outcome

WaitingPages::pendingForApproval()

public function pendingForApproval(): Outcome

An account approved meanwhile goes to the site's home page (app_index).

Base\Auth\Listener

GuardSignIn class

class GuardSignIn GuardSignIn.php:23

Base\Security\SignInCaptcha on omniauth's events: each failed sign-in from an address counts (SignInFailed), a success forgets them (SignedIn), and from base.guard.sign_in_after failures on, a password sign-in from that address must pass the captcha before its password is checked (Verifying, refused captcha: SignInCaptcha::MESSAGE is what the page says).

The captcha's answer is a field of the host's form, which omniauth's events do not carry (no proof is handed to a listener): $answer gives it - the host reads its request (the field SignInGuard::field() names). As today, only the site's own sign-in ($firewalls: not the rescue door).

const REFUSED = 'captcha'

GuardSignIn::__construct()

public function __construct(protected readonly SignInCaptcha $guard, protected readonly ?\Closure $answer = null, protected readonly array $firewalls = ['main'])
$answer

the captcha's answer the visitor posted in that field

$firewalls

the sign-ins guarded (Context::$firewall)

GuardSignIn::onVerifying()

public function onVerifying(Verifying $event): void

GuardSignIn::onSignInFailed()

public function onSignInFailed(SignInFailed $event): void

GuardSignIn::onSignedIn()

public function onSignedIn(SignedIn $event): void

GuardSignIn::events()

public static function events(): array
Returns

omniauth's events and the method of this class each calls

TrackConnections class

class TrackConnections TrackConnections.php:24

The browsers an account signs in from (userConnection rows, through Base\Security\UserTracker), on omniauth's events: what Base\EntitySubscriber\ConnectionSubscriber does on Symfony's - a success marks the browser's connection succeeded (made if it is new), a failure on a known account marks it failed - the account the attempt had, or the one of the identifier typed (a wrong password: Symfony's passport loaded it too). Runs before WarnNewDevice, which looks for the connection a sign-in made.

TrackConnections::__construct()

public function __construct(protected readonly ConnectionTracker $tracker, UnitOfWork|EntityManagerInterface $unitOfWork, protected readonly ?Accounts $accounts = null)
$unitOfWork

the entity manager is deprecated (until 6.0): adapted by UnitOfWorks

TrackConnections::onSignedIn()

public function onSignedIn(SignedIn $event): void

TrackConnections::onSignInFailed()

public function onSignInFailed(SignInFailed $event): void

TrackConnections::events()

public static function events(): array
Returns

omniauth's events and the method of this class each calls

UpdateAccount class

class UpdateAccount UpdateAccount.php:19

The account brought up to date at its sign-in, what Base\Security\LoginFormAuthenticator::onAuthenticationSuccess() does under Symfony: a role the application's UserRole enum no longer knows dropped from the account's own roles (never those of its groups), its time zone and its language kept (the visitor's when it had none), its kick lifted.

UpdateAccount::__construct()

public function __construct(UnitOfWork|EntityManagerInterface $unitOfWork)
$unitOfWork

the entity manager is deprecated (until 6.0): adapted by UnitOfWorks

UpdateAccount::onSignedIn()

public function onSignedIn(SignedIn $event): void

UpdateAccount::events()

public static function events(): array
Returns

omniauth's events and the method of this class each calls

WarnNewDevice class

class WarnNewDevice WarnNewDevice.php:26

A sign-in from a browser the account had not used (a connection this sign-in made, TrackConnections running first): the e-mail "a new device" when the administrator turned it on, and - on an account with no second factor that has not declined it - the flag of the session that makes the next page offer, once, to set up a code. Base\Subscriber\NewDeviceSubscriber's rule on omniauth's SignedIn event: never at the account's very first sign-in (nothing to compare with), nothing that blocks the sign-in.

The session is omniauth's State (the host's session); whether the visitor declined the offer is a cookie the host reads ($declined).

const FRESH_SECONDS = 120

A connection made within this many seconds of the sign-in is one this sign-in made.

WarnNewDevice::__construct()

public function __construct(protected readonly SecurityPolicy $securityPolicy, protected readonly ConnectionTracker $tracker, protected readonly Connections $connections, protected readonly ?State $state = null, protected readonly ?\Closure $declined = null, protected readonly ?SignInMails $mails = null)
$declined

whether this browser said "no thanks" (SecurityPolicy::COOKIE_NEW_DEVICE_PROMPT_DISMISSED)

$mails

the e-mail written and sent without Symfony's Notifier (a host without it: omnibridge/laravel); the Notifier's otherwise

WarnNewDevice::onSignedIn()

public function onSignedIn(SignedIn $event): void

WarnNewDevice::events()

public static function events(): array
Returns

omniauth's events and the method of this class each calls

WelcomeBack class

class WelcomeBack WelcomeBack.php:22

A disabled account that proved who it is: the "welcome back" e-mail, with a token good an hour - its next sign-in within that hour enables the account again (UserAccounts::check()). Base\Security\UserChecker's checkPostAuth() under Symfony, on omniauth's AccountRefused event.

const LIFETIME = 3600

WelcomeBack::__construct()

public function __construct(UnitOfWork|EntityManagerInterface $unitOfWork, protected readonly ?Notifier $notifier = null, protected readonly ?SignInMails $mails = null)
$unitOfWork

the entity manager is deprecated (until 6.0): adapted by UnitOfWorks

$notifier

its welcome-back e-mail (Notifier::userWelcomeBack()); without it, the same e-mail, bare

$mails

the e-mail written and sent without Symfony's Notifier (a host without it: omnibridge/laravel)

WelcomeBack::onAccountRefused()

public function onAccountRefused(AccountRefused $event): void

WelcomeBack::events()

public static function events(): array
Returns

omniauth's events and the method of this class each calls

Base\Auth\Policy

Access class

class Access Access.php:27

Who may open the site while its access is restricted (plan "omnibase agnostic", step F5e, slice 1): the rule omnibridge/symfony's AccessVoter held, on the core's services, for every host.

  • ADMIN_ACCESS: base.access_restriction.admin_access, or a super administrator;
  • USER_ACCESS: user_access, or an administrator while admin_access is on;
  • ANONYMOUS_ACCESS: public_access, or a signed-in user while admin_access or user_access is on;
  • EXCEPTION_ACCESS: the address is outside the restricted firewalls (base.access_restriction.firewalls), or matches one of base.access_restriction.exceptions - its environment, locale, country, language, and the regular expressions of its scheme, host, domain, subdomain and path; the exceptions of the locale (then its language, the default locale, its language, none) read once, when the policy is made. MAINTENANCE_ACCESS and LAUNCH_ACCESS are Maintenance's and Launch's, which ask exception().

The host gives what it alone knows: the firewall an address belongs to (a callable answering its name, or null where it is in none: everything is allowed then), the environment's name, and the current address when the subject is not one (get_url() by default). The three switches and the first firewall asked are kept for the policy's life, as the voter kept them for the request's.

const ANONYMOUS_ACCESS = 'ANONYMOUS_ACCESS'
const USER_ACCESS = 'USER_ACCESS'
const ADMIN_ACCESS = 'ADMIN_ACCESS'
const EXCEPTION_ACCESS = 'EXCEPTION_ACCESS'
const ATTRIBUTES = [self::EXCEPTION_ACCESS, Maintenance::ATTRIBUTE, Launch::ATTRIBUTE, self::ANONYMOUS_ACCESS, self::USER_ACCESS, self::ADMIN_ACCESS]

Access::__construct()

public function __construct(protected readonly ParameterBagInterface $parameterBag, protected readonly LocalizerInterface $localizer, readonly \Closure $firewallOf, readonly \Closure|string $environment)
$firewall

the name of the firewall an address belongs to, null for none

$environment

the environment's name

Access::supports()

public function supports(string $attribute): bool

Access::decide()

public function decide(string $attribute, mixed $subject): bool

The decision on one of ADMIN_ACCESS, USER_ACCESS, ANONYMOUS_ACCESS, EXCEPTION_ACCESS; the subject a user or an address.

Access::exception()

public function exception(mixed $subject): bool

Whether the address (the subject when it is one, else the current one) is let through the restriction.

Admin class

class Admin Admin.php:9

BACKEND (plan "omnibase agnostic", step F5e, slice 1): the back office and the debugging tools are an administrator's. Asked only on their pages (the host says whether the current route is one).

const BACKEND = 'BACKEND'

Admin::supports()

public function supports(string $attribute, bool|\Closure $backOffice): bool

Admin::decide()

public function decide(mixed $user): bool

Complaint class

class Complaint Complaint.php:20

Who reads and answers a complaint (plan "omnibase agnostic", step F5e, slice 1; Base\Entity\User\Complaint): COMPLAINT_READ / COMPLAINT_HANDLE, the complaint as subject, or none (may this user read complaints at all).

  • to read complaints at all: the reader role (ROLE_MODERATOR by default), or the permission tag COMPLAINT.READ / COMPLAINT.HANDLE given to the user or a group (the host's own decision on the tag);
  • a complaint about somebody of the staff is only for those who OUTRANK them: whose reachable roles hold all of theirs and more (the role hierarchy, the Roles contract) - moderators do not judge a moderator;
  • nobody reads a complaint about themselves, except the top role (ROLE_SUPERADMIN by default), which reads them all.
const READ = 'COMPLAINT_READ'
const HANDLE = 'COMPLAINT_HANDLE'

Complaint::__construct()

public function __construct(readonly Roles $roles, readonly string $readerRole = 'ROLE_MODERATOR', readonly string $topRole = 'ROLE_SUPERADMIN')

Complaint::supports()

public function supports(string $attribute, mixed $subject): bool

Complaint::decide()

public function decide(string $attribute, mixed $subject, mixed $user, \Closure $hasTag): bool
$hasTag

the host's decision on a permission tag, for the same account

Launch class

class Launch Launch.php:11

LAUNCH_ACCESS (plan "omnibase agnostic", step F5e, slice 1): the site is launched, or the address is one of the restriction's exceptions (Access::exception()).

const ATTRIBUTE = 'LAUNCH_ACCESS'

Launch::__construct()

public function __construct(readonly LauncherInterface $launcher, readonly Access $access)

Launch::allows()

public function allows(mixed $subject): bool

Maintenance class

class Maintenance Maintenance.php:11

MAINTENANCE_ACCESS (plan "omnibase agnostic", step F5e, slice 1): the site is not under maintenance, or the address is one of the restriction's exceptions (Access::exception()).

const ATTRIBUTE = 'MAINTENANCE_ACCESS'

Maintenance::__construct()

public function __construct(readonly MaintenanceProviderInterface $maintenanceProvider, readonly Access $access)

Maintenance::allows()

public function allows(mixed $subject): bool

Page interface

interface Page Page.php:9

The page a request opens, as the restriction asks it (plan "omnibase agnostic", step F5e, slice 1): what only the host knows - its router, its firewalls -, asked lazily, only once the access is restricted.

Page::isSecurity()

public function isSecurity(): bool

A page of the sign-in's own (the rescue door must stay open).

Page::isProfiler()

public function isProfiler(): bool

The profiler's or the debugging toolbar's.

Page::isAdmin()

public function isAdmin(): bool

The back office's.

Page::name()

public function name(): ?string

The route's name, null for none.

Page::redirectsOnDeny()

public function redirectsOnDeny(): array
Returns

the routes a denied visitor is sent to (base.settings.access_restriction.redirect_on_deny), their default language's suffix taken off

Permission class

class Permission Permission.php:13

The permission tags (plan "omnibase agnostic", step F5e, slice 1): custom fine-grained names, backed by Base\Entity\User\Permission and granted on the user or through a group's membership ("ARTICLE.PUBLISH"; "ARTICLE.*" grants every "ARTICLE." one). Only that name space: never a ROLE_ or IS_ attribute (the role hierarchy's) nor an EA_ one (omnibase/admin's), only upper-case names of letters, digits, _ . and :.

Permission::supports()

public function supports(string $attribute): bool

Permission::decide()

public function decide(string $attribute, mixed $user): bool

Restriction class

final class Restriction Restriction.php:17

What a request meets while the site's access is restricted (plan "omnibase agnostic", step F5e, slice 1): the decision omnibridge/symfony's SecuritySubscriber::onAccessRequest() took, for every host.

The access is restricted when ADMIN_ACCESS, USER_ACCESS or ANONYMOUS_ACCESS is refused (Access). Then: a user granted one of them for themselves has a special grant (the profiler stays on for them); the sign-in's pages stay open; the back office and the profiler answer "not found" to whoever is refused BACKEND; an exception of the restriction opens the page (its special grantee told so); a page that is not one the denied are sent to sends them to the first of those (else the sign-in), lets a special grantee in (a super administrator warned outside the back office); on one of those pages a special grantee is told that the others are sent there.

Restriction::__construct()

public function __construct(readonly \Closure $granted)
$granted

the host's decision on an attribute, for the current account or the subject given

Restriction::decide()

public function decide(mixed $user, Page $page): RestrictionDecision

RestrictionDecision class

final class RestrictionDecision RestrictionDecision.php:11

Restriction's answer (plan "omnibase agnostic", step F5e, slice 1): the request goes on (a notice for the visitor, perhaps), is answered "not found", or is sent to the first of the routes the denied are sent to (the sign-in when there is none). profiler says whether the visitor keeps the profiler (a special grant): the host turns it off otherwise, outside debugging.

const OPEN = 'open'
const NOT_FOUND = 'not_found'
const REDIRECT = 'redirect'

RestrictionDecision::open()

public static function open(bool $profiler = true, ?array $notice = null): self

RestrictionDecision::notFound()

public static function notFound(bool $profiler): self

RestrictionDecision::redirect()

public static function redirect(array $routes): self

Welcome class

final class Welcome Welcome.php:17

The word of welcome a sign-in leaves (plan "omnibase agnostic", step F5e, slice 1): the key omnibridge/symfony's SecuritySubscriber::onLoginSuccess() and omnibridge/laravel's WelcomeFlash each chose, in @notifications, the account its {0}, a "success".

  • an account not yet saved (signed in by an identity provider): login.social;
  • a verified account: login.success.alien where the host says it is not authenticated (Symfony's IS_AUTHENTICATED_FULLY/REMEMBERED refused), else login.success.<period>.<active> - the period of its last activity (morning 05-10 h, afternoon 12-15 h, evening 19-05 h, day otherwise: time_is_between()), "first" when that activity is not today's, "back" when it is (daydiff());
  • nothing for any other account.
const DOMAIN = '@notifications'

Welcome::key()

public static function key(object $user, bool $authenticated = true): ?string

The key, without its domain; null when nothing is said.

Base\Bridge\Composer\Stub

AbstractBaseStub class

abstract class AbstractBaseStub extends AbstractStub AbstractBaseStub.php:20

The App\ stubs of one folder of the core: for each plain class Base\<Name>\X that the application does not define in src/<Name>/, a stub of App\<Name>\X - the alias Base\Bundle\AbstractBaseBundle declares at run time - for an IDE and static analysis.

Run by omnibridge/composer alone, on post-autoload-dump (the core declares these providers in its composer.json, extra.omnibridge.stubs): never loaded by an application, hence outside the Foundation and its bare check. The stubs land in vendor/composer/omnibridge/stubs/<Name>/, which no autoloader reads.

AbstractBaseStub::getName()

public function getName(): string

Entity for EntityStub: the folder of src/ and the namespace segment.

EntityStub class

final class EntityStub extends AbstractBaseStub EntityStub.php:6

The stubs of App\Entity\ (see AbstractBaseStub).

EnumStub class

final class EnumStub extends AbstractBaseStub EnumStub.php:6

The stubs of App\Enum\ (see AbstractBaseStub).

FormStub class

final class FormStub extends AbstractBaseStub FormStub.php:13

The stubs of App\Form\ (see AbstractBaseStub): the core's folder, and the form types, extensions and services omnibridge/symfony holds since the plan "omnibase agnostic"'s step F5b (Omnibridge\Symfony\Omnibase\Form\X), which extend them by their former names, Base\Form\X (src/Resources/former-names.php).

FormStub::generate()

public function generate(StubContext $context): iterable

NotifierStub class

final class NotifierStub extends AbstractBaseStub NotifierStub.php:6

The stubs of App\Notifier\ (see AbstractBaseStub).

RepositoryStub class

final class RepositoryStub extends AbstractBaseStub RepositoryStub.php:14

The stubs of App\Repository\ (see AbstractBaseStub). The core's repositories are omnibridge/doctrine's since the plan "omnibase agnostic"'s step F3 (Omnibridge\Doctrine\Omnibase\Repository\X): their stubs extend them by their former names, Base\Repository\X, which the core aliases (src/Resources/former-names.php) and the application's App\Repository\X stands for at run time, as before.

Base\Bridge\PHPStan

EntityAccessorReflection class

final class EntityAccessorReflection implements MethodReflection EntityAccessorReflection.php:21

One accessor of EntityAccessorsExtension: public, with the signature of the method it ends in (an alias: AliasTrait hands the arguments on), any arguments and that method's return type when $anyArguments (a translation's: TranslatableTrait reads a property and leaves them), any arguments and mixed without one.

EntityAccessorReflection::__construct()

public function __construct(readonly ClassReflection $declaringClass, readonly string $name, readonly ?MethodReflection $target, readonly bool $anyArguments = false)

EntityAccessorReflection::getDeclaringClass()

public function getDeclaringClass(): ClassReflection

EntityAccessorReflection::isStatic()

public function isStatic(): bool

EntityAccessorReflection::isPrivate()

public function isPrivate(): bool

EntityAccessorReflection::isPublic()

public function isPublic(): bool

EntityAccessorReflection::getDocComment()

public function getDocComment(): ?string

EntityAccessorReflection::getName()

public function getName(): string

EntityAccessorReflection::getPrototype()

public function getPrototype(): ClassMemberReflection

EntityAccessorReflection::getVariants()

public function getVariants(): array

EntityAccessorReflection::isDeprecated()

public function isDeprecated(): TrinaryLogic

EntityAccessorReflection::getDeprecatedDescription()

public function getDeprecatedDescription(): ?string

EntityAccessorReflection::isFinal()

public function isFinal(): TrinaryLogic

EntityAccessorReflection::isInternal()

public function isInternal(): TrinaryLogic

EntityAccessorReflection::getThrowType()

public function getThrowType(): ?Type

EntityAccessorReflection::hasSideEffects()

public function hasSideEffects(): TrinaryLogic

EntityAccessorsExtension class

final class EntityAccessorsExtension implements MethodsClassReflectionExtension EntityAccessorsExtension.php:38

The accessors an omnibase entity answers through __call() for PHPStan (audit "lesringostars face au master plan", R21b), as FinderMethodsExtension does for the repositories' finders:

  • #[Alias] (AliasTrait::__call()): get/set/is/has of an alias - the property carrying #[Alias(column: ...)], or the alias of a class-level #[Alias(column: ..., alias: ...)] - and add/remove of an alias or of its singular, as AliasTrait resolves them: Article::getDestination() is getParent(), Comment::getReplies() getChildren(), addReply() addChild(), Destination::addGallery() addChild() (R29);
  • translations (TranslatableTrait::__call()): a public method of the entity's translation class (X + "Intl", else its parent's), called on the entity - Location::getLabel() is TagIntl::getLabel() on translate().

Each is known with the signature of the method it ends in, when there is one (getDestination() returns what getParent() returns), any arguments and mixed otherwise. A name neither rule gives - an alias that is no property, a method no translation has - is still an undefined method.

Registered by extension.neon. Loaded by PHPStan alone, never at run time.

const PATTERN = '/^(get|set|add|remove|is|has)([A-Z][A-Za-z0-9_]*)$/'

AliasTrait::__call()'s actions, then the alias.

EntityAccessorsExtension::__construct()

public function __construct(readonly ReflectionProvider $reflectionProvider)

EntityAccessorsExtension::hasMethod()

public function hasMethod(ClassReflection $classReflection, string $methodName): bool

EntityAccessorsExtension::getMethod()

public function getMethod(ClassReflection $classReflection, string $methodName): MethodReflection

FinderMethodReflection class

final class FinderMethodReflection implements MethodReflection FinderMethodReflection.php:13

One method of the finder language (FinderMethodsExtension): public, any arguments, mixed.

FinderMethodReflection::__construct()

public function __construct(readonly ClassReflection $declaringClass, readonly string $name)

FinderMethodReflection::getDeclaringClass()

public function getDeclaringClass(): ClassReflection

FinderMethodReflection::isStatic()

public function isStatic(): bool

FinderMethodReflection::isPrivate()

public function isPrivate(): bool

FinderMethodReflection::isPublic()

public function isPublic(): bool

FinderMethodReflection::getDocComment()

public function getDocComment(): ?string

FinderMethodReflection::getName()

public function getName(): string

FinderMethodReflection::getPrototype()

public function getPrototype(): ClassMemberReflection

FinderMethodReflection::getVariants()

public function getVariants(): array

FinderMethodReflection::isDeprecated()

public function isDeprecated(): TrinaryLogic

FinderMethodReflection::getDeprecatedDescription()

public function getDeprecatedDescription(): ?string

FinderMethodReflection::isFinal()

public function isFinal(): TrinaryLogic

FinderMethodReflection::isInternal()

public function isInternal(): TrinaryLogic

FinderMethodReflection::getThrowType()

public function getThrowType(): ?Type

FinderMethodReflection::hasSideEffects()

public function hasSideEffects(): TrinaryLogic

FinderMethodsExtension class

final class FinderMethodsExtension implements MethodsClassReflectionExtension FinderMethodsExtension.php:24

The finder language of omnibase's repositories for PHPStan: a repository extending Base\Database\Repository\ServiceEntityRepository answers, through __call() and ServiceEntityParser, every method its name describes - findOneBySlug(), cacheByParentAndState(), countByDomainAndUpdatedAtYoungerThan(), distinctCountBy...(), lengthOf...() - which no declaration can list. Each is known to PHPStan as a public method taking any arguments and returning mixed, as ServiceEntityRepository::__call() declares; any other unknown name is still an undefined method.

Registered by extension.neon at the core's root, which the core's phpstan.neon includes and an application's may (vendor/omnisense/omnibase/extension.neon). Loaded by PHPStan alone, never at run time.

const PATTERN = '/^(?:find|cache|count|distinctCount|lengthOf|sumOf|minOf|maxOf)[A-Z]/'

The requests Finder\Parser recognises (find, cache, count, distinctCount, lengthOf, sumOf, minOf, maxOf), then the rest of the name.

FinderMethodsExtension::hasMethod()

public function hasMethod(ClassReflection $classReflection, string $methodName): bool

FinderMethodsExtension::getMethod()

public function getMethod(ClassReflection $classReflection, string $methodName): MethodReflection

Base\Bridge\Symfony

AccountScreens class

class AccountScreens AccountScreens.php:31

The account's screens under Symfony (plan "omnibase agnostique", C5): what the framework-free builder (Base\Screen\Builder\Accounts) cannot know, asked where the templates of before asked it - the viewer and their roles (the Access contract: app.user, is_granted), an avatar's thumbnail (|thumbnail), the providers one may link (oauth_available()), web push and the back-office address of a notification (push_available(), push_vapid_key(), notification_admin_url()), Twig's time zone (the days of the notifications' groups) -, handed to the builder. What the account's controllers and the Twig function account_profile() (a host page's) call; a Twig runtime, so that it may read Twig's functions and filters without a circular service. It asks them by their names, as a template does, not by the classes of omnibase's Twig extensions (plan "omnibase agnostic", F4: nothing outside src/Twig names Base\Twig\); a function no extension registered answers as it did when its extension was missing.

const AVATAR = 128

The width and height of a profile's avatar.

AccountScreens::__construct()

public function __construct(readonly Accounts $accounts, readonly Environment $twig, readonly ?Access $access = null)

AccountScreens::profile()

public function profile(User $user): ProfilePage

A member's profile, as the visitor asking sees it.

AccountScreens::settings()

public function settings(?User $user, iterable $sessions = []): SettingsPage

AccountScreens::notifications()

public function notifications(iterable $notifications, int $unread, bool $unreadOnly = false): NotificationsPage

NotificationMessages class

final class NotificationMessages NotificationMessages.php:42

The Symfony half of Base\Entity\User\Notification (plan "omnibase agnostique", step C3f): what the entity made with the framework, moved here as it was. The entity keeps what a notification is - its subject, content, importance, channels, recipients, context, templates - and its sending through the notifier; it hands this class what needs Symfony:

  • throwable(): the error an ExceptionEvent (HttpKernel) carries, or a FlattenException (ErrorHandler), made the notification's content;
  • response(): render()'s HttpFoundation Response;
  • email(): asEmailMessage(), the NotificationEmail of Symfony's Twig bridge (TemplatedEmail, WrappedTemplatedEmail), its attachments (HttpFoundation's UploadedFile), its HTML through Twig.

Same names for what the sites use: they keep calling the entity's methods, which answer what they answered.

const FRAME = EmailComposer::FRAME

The e-mail frame: the HTML of a notification whose template is missing or not found.

NotificationMessages::throwable()

public static function throwable(mixed $content): Throwable|FlattenException|null

The error to describe, when the notification's content is one: an ExceptionEvent's throwable, a FlattenException, a Throwable; null for anything else.

NotificationMessages::response()

public static function response(string $html): Response

NotificationMessages::email()

public static function email(Notification $notification, EmailRecipientInterface $recipient, BaseNotifierInterface $notifier, Views|Environment $views, string $projectDir): EmailMessage

NotificationMessages::composed()

public static function composed(Notification $notification, EmailRecipientInterface $recipient, BaseNotifierInterface $notifier, Views|Environment $views): EmailMessage

A notification's e-mail without Symfony's Twig bridge: EmailComposer::compose(), from the technical address, to the recipient or the technical address for a test one, a plain symfony/mime Email in the Notifier's EmailMessage. Forwarded to the administrators, it says so as Symfony's does.

PasskeyRecords interface

interface PasskeyRecords extends CredentialRecordRepositoryInterface, CanSaveCredentialRecord PasskeyRecords.php:16

Base\Contract\PasskeyRecords under Symfony (plan "omniauth", AU1): WebauthnBundle's CredentialRecordRepositoryInterface and CanSaveCredentialRecord, which Base\Repository\User\PasskeyRepository implemented itself up to AU1 and which the contract is an alias of when the bundle is installed. Not to be named by a class: implement Base\Contract\PasskeyRecords.

PasskeyUsers interface

interface PasskeyUsers extends PublicKeyCredentialUserEntityRepositoryInterface PasskeyUsers.php:14

Base\Contract\PasskeyUsers under Symfony (plan "omniauth", AU1): WebauthnBundle's PublicKeyCredentialUserEntityRepositoryInterface, which Base\Security\WebauthnUserEntityRepository implemented itself up to AU1 and which the contract is an alias of when the bundle is installed. Not to be named by a class: implement Base\Contract\PasskeyUsers.

SecurityUser interface

interface SecurityUser extends UserInterface, PasswordAuthenticatedUserInterface SecurityUser.php:15

Base\Contract\SecurityUser under Symfony (plan "omnibase agnostique", C7b): the interfaces Base\Entity\User implemented itself up to 4.0 - Security's UserInterface and PasswordAuthenticatedUserInterface -, which the contract is an alias of when symfony/security-core is installed. Not to be named by a class: implement Base\Contract\SecurityUser.

SecurityUserLoader interface

interface SecurityUserLoader extends UserLoaderInterface SecurityUserLoader.php:18

Base\Contract\SecurityUserLoader under Symfony (audit "lesringostars face au master plan", R2): doctrine-bridge's UserLoaderInterface - the repository an entity user provider loads a user by its identifier from -, which Base\Repository\UserRepository implemented itself up to 4.0 and which the contract is an alias of when symfony/doctrine-bridge is installed. Apart from Base\Bridge\Symfony\SecurityUserProvider: an interface cannot extend both (loadUserByIdentifier() answers ?UserInterface here, UserInterface there), a class implements both. Not to be named by a class: implement Base\Contract\SecurityUserLoader.

SecurityUserProvider interface

interface SecurityUserProvider extends UserProviderInterface, PasswordUpgraderInterface SecurityUserProvider.php:16

Base\Contract\SecurityUserProvider under Symfony (audit "lesringostars face au master plan", R2): Security's UserProviderInterface and PasswordUpgraderInterface, which Base\Repository\UserRepository implemented itself up to 4.0 and which the contract is an alias of when symfony/security-core is installed. Not to be named by a class: implement Base\Contract\SecurityUserProvider.

TwoFactorUser interface

interface TwoFactorUser extends TotpTwoFactorInterface, EmailTwoFactorInterface, BackupCodeInterface, TrustedDeviceInterface TwoFactorUser.php:17

Base\Contract\TwoFactorUser with scheb/2fa (plan "omnibase agnostique", C7b): the interfaces Base\Entity\User implemented itself up to 4.0 - TOTP and e-mail codes, backup codes, trusted devices -, which the contract is an alias of when scheb/2fa is installed. Not to be named by a class: implement Base\Contract\TwoFactorUser.

Base\Cache

SimpleCache class

final class SimpleCache extends AbstractLocalCache implements SimpleCacheInterface SimpleCache.php:8

SimpleCache::warmUp()

public function warmUp(string $cacheDir, ?string $buildDir = null): array

SimpleCache::useSimpleCacheVersion3()

public static function useSimpleCacheVersion3(): bool

SimpleCache::get()

public function get(string $key, mixed $default = null): mixed

SimpleCache::set()

public function set(string $key, mixed $value, null|int|\DateInterval $ttl = null): bool

SimpleCache::delete()

public function delete(string $key): bool

SimpleCache::clear()

public function clear(): bool

SimpleCache::getMultiple()

public function getMultiple(iterable $keys, mixed $default = null): iterable

SimpleCache::setMultiple()

public function setMultiple(iterable $keys, null|int|\DateInterval $ttl = null): bool

SimpleCache::deleteMultiple()

public function deleteMultiple(iterable $keys): bool

SimpleCache::has()

public function has(string $key): bool

SimpleCacheInterface interface

interface SimpleCacheInterface extends AbstractLocalCacheInterface, CacheInterface SimpleCacheInterface.php:8

Base\Cache\Abstract

AbstractLocalCache class

abstract class AbstractLocalCache implements AbstractLocalCacheInterface AbstractLocalCache.php:8

AbstractLocalCacheInterface interface

interface AbstractLocalCacheInterface AbstractLocalCacheInterface.php:17

A service's own cache, warmed by omnibase's cache warmers (Base\Cache\Warmer\*, which call warmUp()). warmUp() is declared here, with the signature of HttpKernel's WarmableInterface, which this interface no longer extends (plan "omnibase agnostique", C6): the AttributeReader and the ClassMetadataManipulator - what an entity manager built by hand reads its mapping through - load nothing of the framework. Symfony asks WarmableInterface of the kernel, its router and its translator only, none of which is one of these.

AbstractLocalCacheInterface::warmUp()

public function warmUp(string $cacheDir, ?string $buildDir = null): array

Warms up the cache.

Returns

A list of classes or files to preload

AbstractLocalCacheInterface::hasCache()

public function hasCache(string $key): bool

AbstractLocalCacheInterface::deleteCache()

public function deleteCache(?string $key = null): bool

AbstractLocalCacheInterface::getCache()

public function getCache(?string $key = null, mixed $fallback = null, int|\DateInterval|null $ttl = null, $deferred = false): mixed

AbstractLocalCacheInterface::setCache()

public function setCache(CacheItemPoolInterface|string $cacheOrKey, mixed $value = null, int|\DateInterval|null $ttl = null, bool $deferred = false)

AbstractLocalCacheInterface::executeOnce()

public function executeOnce(callable $fn, int|\DateInterval|null $ttl = null)

AbstractLocalCacheInterface::commitCache()

public function commitCache()

AbstractLocalCacheWarmerInterface interface

interface AbstractLocalCacheWarmerInterface AbstractLocalCacheWarmerInterface.php:7

AbstractLocalCacheWarmerInterface::getCache()

public function getCache(): ArrayAdapter

Base\Cache\Pool

MemoryItem class

final class MemoryItem implements CacheItemInterface MemoryItem.php:11

An item of Base\Cache\Pool\MemoryPool (PSR-6). The parameters are left untyped so that it implements psr/cache 1, 2 and 3 alike.

MemoryItem::__construct()

public function __construct(readonly string $key)

MemoryItem::getKey()

public function getKey(): string

MemoryItem::get()

public function get(): mixed

MemoryItem::isHit()

public function isHit(): bool

MemoryItem::set()

public function set($value): static

MemoryItem::expiresAt()

public function expiresAt($expiration): static

MemoryItem::expiresAfter()

public function expiresAfter($time): static

MemoryPool class

final class MemoryPool implements CacheItemPoolInterface MemoryPool.php:17

A PSR-6 pool held in memory, for the core's local caches (Base\Cache\Abstract\AbstractLocalCache: the obfuscator's map, the icons...) where no pool is given and symfony/cache is not installed (since 5.0, plan "omnibase agnostic", step F6: the core requires psr/cache, not symfony/cache).

What it holds lasts as long as the process; a host that wants it on disk gives a pool of its own, as omnibridge/symfony's configuration does (symfony/cache's PhpArrayAdapter, as before).

The parameters are left untyped so that it implements psr/cache 1, 2 and 3 alike.

MemoryPool::getItem()

public function getItem($key): CacheItemInterface

MemoryPool::getItems()

public function getItems(array $keys = []): iterable

MemoryPool::hasItem()

public function hasItem($key): bool

MemoryPool::clear()

public function clear(): bool

MemoryPool::deleteItem()

public function deleteItem($key): bool

MemoryPool::deleteItems()

public function deleteItems(array $keys): bool

MemoryPool::save()

public function save(CacheItemInterface $item): bool

MemoryPool::saveDeferred()

public function saveDeferred(CacheItemInterface $item): bool

MemoryPool::commit()

public function commit(): bool

Base\Console

Commands interface

interface Commands Commands.php:10

The host's other console commands, for a task that runs some (plan "omnibase agnostic", step F5e, slice 3: demo:reset runs the fixtures, uploader:entities, the cache pools). Each host answers the names it has; a name it has not got answers null. Their output goes where the host prints, not to the task's Report.

Commands::run()

public function run(string $name, array $arguments = []): ?int
$arguments

the options by name ('--all' => true)

Returns

the command's status, null when the host has no such command

ConsoleInterface interface

interface ConsoleInterface ConsoleInterface.php:5

ConsoleInterface::exec()

public function exec(string $command, array $parameters = []): ?string

Report class

final class Report extends AbstractLogger Report.php:20

What a console task said and how it ended (plan "omnibase agnostic", step F5e, slice 3: Base\Console\Task\*), for every host to print: omnibridge/symfony's commands and omnibridge/laravel's artisan commands print the same Report, neither writes anything of its own.

A PSR-3 logger where a logger is enough ($report->warning(...): a block of its level), plus the console's own pieces: text written as it is (with or without its line's end, at a verbosity), a success block, a table. The text keeps the console's markup (<info>, <warning>, <ln>, <red>, <magenta>... the styles of STYLES, which both hosts declare); text() gives it plain, as --no-ansi prints it.

Each entry is handed to the sink given (the host's printer) as soon as it is said, so a long task's output comes as it goes and between what the host prints itself; entries() keeps them all.

const SUCCESS = 0
const FAILURE = 1
const INVALID = 2
const QUIET = 16

The verbosities, Symfony Console's values (OutputInterface::VERBOSITY_*), which artisan shares.

const NORMAL = 32
const VERBOSE = 64
const VERY_VERBOSE = 128
const DEBUG = 256
const TEXT = 'text'
const SUCCESS_BLOCK = 'success'
const TABLE = 'table'
const STYLES = ['info' => ['green', null, []], 'bold,info' => ['green', null, ['bold']], 'info,bold' => ['green', null, ['bold']], 'info,bkg' => ['black', 'green', []], 'bk…

The styles the tasks' markup names: name => [foreground, background, options]. omnibase's commands declared them on the output; the hosts declare these.

Report::__construct()

public function __construct(readonly ?\Closure $sink = null)

Report::write()

public function write(string $text, bool $newline = false, int $verbosity = self::NORMAL): self

Text as it is, its line ended or not.

Report::line()

public function line(string $text = '', int $verbosity = self::NORMAL): self

A line of text.

Report::success()

public function success(string|\Stringable $message): self

Report::table()

public function table(array $headers, array $rows): self

Report::log()

public function log($level, $message, array $context = []): void

A block of the level given (PSR-3), {placeholders} replaced from the context.

Report::fail()

public function fail(int $status = self::FAILURE): self

The task ends with this status (not 0: failed).

Report::status()

public function status(): int

Report::entries()

public function entries(): array

Report::text()

public function text(int $verbosity = self::NORMAL): string

What the report says up to a verbosity, plain: the markup taken out as --no-ansi prints it, a block as "[LEVEL] text", a table's cells joined by " | ". What the hosts print is compared through it.

Report::plain()

public static function plain(string $text): string

The markup of STYLES (and the formatter's own: error, comment, question, fg=...;bg=...) taken out.

Base\Console\Task

AutocompleteEntities class

final class AutocompleteEntities extends EntitiesTask AutocompleteEntities.php:12

autocomplete:entities (plan "omnibase agnostic", step F5e, slice 3): the entities a picker searches (AutocompleteInterface), or an entity's rows and what each one answers a picker (its text and its data).

AutocompleteEntities::run()

public function run(EntitiesInput $input, ?\Closure $sink = null): Report

BaseMapping class

final class BaseMapping BaseMapping.php:12

base:mapping (plan "omnibase agnostic", step F5e, slice 3): the core's enumerations, forms, entities and repositories, each aliased to the App\ class of the same name where the application has none (the App\ convention), and the application's classes that take their place.

const FOLDERS = ['Enum', 'Form', 'Entity', 'Repository']

The core's folders whose classes the App\ convention aliases.

BaseMapping::run()

public function run(BaseMappingInput $input, ?\Closure $sink = null): Report

BaseMappingInput class

final readonly class BaseMappingInput BaseMappingInput.php:6

base:mapping's options (plan "omnibase agnostic", step F5e, slice 3).

public string $source

the application's App\ folder (Symfony: ./src)

BaseMappingInput::__construct()

public function __construct(public string $source = 'src')
$source

the application's App\ folder (Symfony: ./src)

CacheClear class

final class CacheClear CacheClear.php:25

cache:clear's part that is omnibase's (plan "omnibase agnostic", step F5e, slice 3; formerly Base\Traits\ CacheClearTrait and the command's lock), around the host's own clear, given as a closure:

  • one clear at a time: a lock file in the cache folder (stale after LOCK_TTL seconds); a second process skips, successfully;
  • before (omnibase's checks): the PHP configuration, the disk and the memory, the cache folder, Docker, the extensions, omnibase's components and their fallbacks; the warmers asked; node_modules, the technical recipient, public/phpinfo.php (written in debug, removed otherwise), the storages' public links once the application started;
  • the host's clear, the counter of clears (CacheClears), the sessions if asked;
  • after: the second clear of a first one (base.autoclear: the host's $again), OPcache emptied.

Everything said goes to the Report; its status is the host's clear's.

const LOCK_TTL = 120

CacheClear::__construct()

public function __construct(readonly ParameterBagInterface $parameterBag, readonly ?FlysystemInterface $flysystem = null, readonly ?BaseNotifierInterface $notifier = null)

CacheClear::run()

public function run(CacheClearInput $input, \Closure $clear, ?\Closure $again = null, ?\Closure $sessions = null, ?\Closure $sink = null): Report
$clear

the host's clear (its status)

$again

the host's second clear, in a process of its own

$sessions

the host's sessions killed (--sessions)

CacheClearInput class

final readonly class CacheClearInput CacheClearInput.php:6

cache:clear's options and what the host knows of itself (plan "omnibase agnostic", step F5e, slice 3).

public string $projectDir
public string $cacheDir
public bool $checks

omnibase's checks around the host's clear (not --no-extension)

public bool $optionalWarmers

the optional cache warmers run (not --no-optional-warmers nor --no-warmup)

public bool $sessions

the sessions killed after the clear (--sessions)

public ?bool $phpInfo

public/phpinfo.php written (debug: true) or removed (false); null: the host has none

public ?bool $hostFallback

whether the host's router has a host fallback (null: it has no such router)

public ?bool $customMetadataFactory

whether the persistence's metadata factory is omnibase's (null: not asked)

CacheClearInput::__construct()

public function __construct(public string $projectDir, public string $cacheDir, public bool $checks = true, public bool $optionalWarmers = true, public bool $sessions = false, public ?bool $phpInfo = null, public ?bool $hostFallback = null, public ?bool $customMetadataFactory = null)
$checks

omnibase's checks around the host's clear (not --no-extension)

$optionalWarmers

the optional cache warmers run (not --no-optional-warmers nor --no-warmup)

$sessions

the sessions killed after the clear (--sessions)

$phpInfo

public/phpinfo.php written (debug: true) or removed (false); null: the host has none

$hostFallback

whether the host's router has a host fallback (null: it has no such router)

$customMetadataFactory

whether the persistence's metadata factory is omnibase's (null: not asked)

CacheClearInput::clears()

public function clears(): CacheClears

The counter of clears beside the cache folder.

CacheClearSessions class

final class CacheClearSessions CacheClearSessions.php:11

cache:clear:sessions (plan "omnibase agnostic", step F5e, slice 3): every session file of the host's folder removed, so that every visitor is signed out.

CacheClearSessions::run()

public function run(CacheClearSessionsInput $input, ?\Closure $sink = null): Report

CacheClearSessionsInput class

final readonly class CacheClearSessionsInput CacheClearSessionsInput.php:6

cache:clear:sessions' input (plan "omnibase agnostic", step F5e, slice 3): where the host keeps its session files.

public string $directory
public string $pattern

the session files' names (Symfony's native handler: sess_*)

CacheClearSessionsInput::__construct()

public function __construct(public string $directory, public string $pattern = 'sess_*')
$pattern

the session files' names (Symfony's native handler: sess_*)

CacheClears class

final class CacheClears CacheClears.php:11

How many times the cache was cleared since it was made, kept in a file beside it (<cache dir>.txt): the first clear of an application that has not started yet, the second one that cache:clear runs by itself (base.autoclear). omnibridge/symfony's CacheClearCommand answers its static questions from it (plan "omnibase agnostic", step F5e, slice 3).

public readonly string $file

CacheClears::__construct()

public function __construct(public readonly string $file)

CacheClears::count()

public function count(): int

CacheClears::notStarted()

public function notStarted(): bool

No clear yet: the application has not started.

CacheClears::isFirst()

public function isFirst(): bool

CacheClears::markFirst()

public function markFirst(bool $first = true): void

The counter set to none, when $first.

CacheClears::increment()

public function increment(): void

One more clear (the counter made first if it was not there).

DemoReset class

final class DemoReset DemoReset.php:34

demo:reset (plan "omnibase agnostic", step F5e, slice 3): the demonstration back to what the fixtures say - what the cron container runs every night in the demo environment, and nowhere else.

1. refused outside demo, and on what DemoGuard refuses (debug, the production database); 2. under a lock (symfony/lock): two resets never overlap; 3. the folders of base.demo.reset.purge emptied - the files the visitors sent; 4. the fixtures reloaded (the host's doctrine:fixtures:load, the groups named), then the declared demonstration accounts they left out created (by DemoAccountFactory, where the host has one); 5. the uploaded files no row names any more deleted (uploader:entities --delete-orphans, unless base.demo.reset.orphans is off); 6. the caches that would go on answering yesterday's rows emptied: every cache pool (cache:pool:clear --all), then the host's second-level cache.

Each step is a line of the Report, timestamped, and logged; the Report fails when one failed.

const LOCK = 'base-demo-reset'
const FIXTURES = 'doctrine:fixtures:load'

The host's commands the reset runs (Commands answers them by these names).

const ORPHANS = 'uploader:entities'
const POOLS = 'cache:pool:clear'

DemoReset::__construct()

public function __construct(readonly DemoMode $mode, readonly DemoGuard $guard, readonly ?DemoAccountFactory $accounts = null, readonly UnitOfWork|\Closure|null $unitOfWork = null, readonly ?LockFactory $lockFactory = null, readonly ?LoggerInterface $logger = null, readonly ?DemoAccountRegistry $registry = null, readonly ?\Closure $evict = null)
$unitOfWork

the persistence the created accounts are flushed to (a closure: asked only then, as the host's manager may not be made before)

$evict

the host's second-level cache emptied

DemoReset::run()

public function run(DemoResetInput $input, Commands $commands, ?\Closure $sink = null): Report

DemoResetInput class

final readonly class DemoResetInput DemoResetInput.php:6

demo:reset's options and the base.demo.reset.* parameters (plan "omnibase agnostic", step F5e, slice 3).

public bool $keepFiles
public array $purge

folders emptied before the fixtures are loaded (base.demo.reset.purge)

public bool $orphans

the uploaded files no row names deleted (base.demo.reset.orphans)

public array $groups

the fixture groups loaded (base.demo.reset.groups); none: every fixture

DemoResetInput::__construct()

public function __construct(public bool $keepFiles = false, public array $purge = [], public bool $orphans = true, public array $groups = [])
$purge

folders emptied before the fixtures are loaded (base.demo.reset.purge)

$orphans

the uploaded files no row names deleted (base.demo.reset.orphans)

$groups

the fixture groups loaded (base.demo.reset.groups); none: every fixture

EntitiesInput class

final readonly class EntitiesInput EntitiesInput.php:6

icon:entities' and autocomplete:entities' options (plan "omnibase agnostic", step F5e, slice 3).

public string $source

the application's App\ folder (Symfony: ./src)

public ?string $entity

one entity's rows (its class), the candidate classes otherwise

public ?string $id

one row of it

EntitiesInput::__construct()

public function __construct(public string $source = 'src', public ?string $entity = null, public ?string $id = null)
$source

the application's App\ folder (Symfony: ./src)

$entity

one entity's rows (its class), the candidate classes otherwise

$id

one row of it

EntitiesTask class

abstract class EntitiesTask EntitiesTask.php:13

A console task on the entities of a class (plan "omnibase agnostic", step F5e, slice 3): icon:entities, autocomplete:entities, entity:discriminator. Whether a class is an entity is the unit of work's shapes' answer (Doctrine's ClassMetadataManipulator::isEntity() before), its rows its repository's.

EntitiesTask::__construct()

public function __construct(protected readonly UnitOfWork $unitOfWork)

EntityDiscriminator class

final class EntityDiscriminator extends EntitiesTask EntityDiscriminator.php:8

entity:discriminator (plan "omnibase agnostic", step F5e, slice 3): a class that is no entity refused aloud.

EntityDiscriminator::run()

public function run(EntityDiscriminatorInput $input, ?\Closure $sink = null): Report

EntityDiscriminatorInput class

final readonly class EntityDiscriminatorInput EntityDiscriminatorInput.php:6

entity:discriminator's argument (plan "omnibase agnostic", step F5e, slice 3).

public string $entity

EntityDiscriminatorInput::__construct()

public function __construct(public string $entity)

Folders class

final class Folders Folders.php:12

Where the console tasks look for classes (plan "omnibase agnostic", step F5e, slice 3): the core's src/ folder (it was BaseBundle::getBundleDir().'/src'), and the classes of a folder in the order the filesystem lists them.

Folders::core()

public static function core(): string

The core's src/ folder.

Folders::classes()

public static function classes(string $folder, string $prefix = ''): array

The classes of a folder, as AbstractBaseBundle::getAllClasses() answered them: by their full names, or relative to a root namespace ($prefix: "App", "Base") - a class of another namespace by its short name.

IconEntities class

final class IconEntities extends EntitiesTask IconEntities.php:12

icon:entities (plan "omnibase agnostic", step F5e, slice 3): the entities that have icons (IconizeInterface) and their class's icons, or an entity's rows and each one's icons.

IconEntities::run()

public function run(EntitiesInput $input, ?\Closure $sink = null): Report

IconEnums class

final class IconEnums IconEnums.php:12

icon:enums (plan "omnibase agnostic", step F5e, slice 3): the core's enumerations, then the application's, and each value's icons (#[Iconize]); the native PHP enums and the groups without values of their own left out.

IconEnums::run()

public function run(IconEnumsInput $input, ?\Closure $sink = null): Report

IconEnumsInput class

final readonly class IconEnumsInput IconEnumsInput.php:6

icon:enums' options (plan "omnibase agnostic", step F5e, slice 3).

public string $source

the application's App\ folder (Symfony: ./src)

public string $enum

only the enumerations whose name starts so

IconEnumsInput::__construct()

public function __construct(public string $source = 'src', public string $enum = '')
$source

the application's App\ folder (Symfony: ./src)

$enum

only the enumerations whose name starts so

MailerTrap class

final class MailerTrap MailerTrap.php:14

base:mailer:trap (plan "omnibase agnostic", step F5e, slice 3): outgoing mail held during an incident (the trap sits at send time, so mail already queued is caught too), what was held looked at, the wrong ones thrown away and the rest let go - released through the host's transport ($send), around the trap. Held mail outlives the trap on purpose: disarming restores delivery without deciding, silently, what happens to what was caught.

MailerTrap::__construct()

public function __construct(readonly MailTrap $trap)

MailerTrap::run()

public function run(MailerTrapInput $input, ?\Closure $sink = null, ?\Closure $send = null): Report
$send

the host's transport (not its mailer, which would hand a release back to an armed trap)

MailerTrapInput class

final readonly class MailerTrapInput MailerTrapInput.php:6

base:mailer:trap's arguments and options (plan "omnibase agnostic", step F5e, slice 3).

public string $action

status, on (arm), off (disarm), list, show, purge, release

public ?string $id

the held message, for show, purge and release

public bool $all

every held message

public ?string $reason

why the trap was armed, for whoever finds it later

MailerTrapInput::__construct()

public function __construct(public string $action = 'status', public ?string $id = null, public bool $all = false, public ?string $reason = null)
$action

status, on (arm), off (disarm), list, show, purge, release

$id

the held message, for show, purge and release

$all

every held message

$reason

why the trap was armed, for whoever finds it later

NotifierMailTest class

final class NotifierMailTest NotifierMailTest.php:17

notifier:mail:test (plan "omnibase agnostic", step F5e, slice 3): a test e-mail sent to an account (by its id, e-mail address or username), else to the technical recipient's account, else to an account made up for the technical recipient's address (not stored), else to the first account.

NotifierMailTest::__construct()

public function __construct(readonly NotifierInterface $notifier, readonly UnitOfWork $unitOfWork)

NotifierMailTest::run()

public function run(NotifierMailTestInput $input, ?\Closure $sink = null): Report

NotifierMailTestInput class

final readonly class NotifierMailTestInput NotifierMailTestInput.php:6

notifier:mail:test's options (plan "omnibase agnostic", step F5e, slice 3).

public ?string $user

the account mailed (its id, e-mail address or username); the technical recipient's otherwise

NotifierMailTestInput::__construct()

public function __construct(public ?string $user = null)
$user

the account mailed (its id, e-mail address or username); the technical recipient's otherwise

NotifierOverview class

final class NotifierOverview NotifierOverview.php:12

app:notifier (plan "omnibase agnostic", step F5e, slice 3): the templated notifications the application's notifier offers - its methods and its parents', BaseNotifier's own left out.

NotifierOverview::run()

public function run(NotifierOverviewInput $input = new NotifierOverviewInput(), ?\Closure $sink = null): Report

NotifierOverviewInput class

final readonly class NotifierOverviewInput NotifierOverviewInput.php:6

app:notifier's options (plan "omnibase agnostic", step F5e, slice 3).

public string $notifier

the application's notifier (App\Notifier\Notifier, the core's where it has none)

NotifierOverviewInput::__construct()

public function __construct(public string $notifier = 'App\Notifier\Notifier')
$notifier

the application's notifier (App\Notifier\Notifier, the core's where it has none)

ThreadPublishable class

final class ThreadPublishable ThreadPublishable.php:18

thread:publishable (plan "omnibase agnostic", step F5e, slice 3): the scheduled threads (ThreadState::FUTURE), those whose time has come, and - asked - those published, each under its row's lock and read again, so that two runs at once (the cron, an administrator's edit) publish it once.

ThreadPublishable::__construct()

public function __construct(readonly Threads $threads, readonly UnitOfWork $unitOfWork, readonly TranslatorInterface $translator)

ThreadPublishable::run()

public function run(ThreadPublishableInput $input, ?\Closure $sink = null): Report

ThreadPublishable::banner()

public static function banner(Report $report, string $style, string $message, bool $around = true): Report

omnibase's banner: the message between two blank lines of its width, on the style's background.

ThreadPublishableInput class

final readonly class ThreadPublishableInput ThreadPublishableInput.php:6

thread:publishable's options (plan "omnibase agnostic", step F5e, slice 3).

public bool $publish

publish the threads whose time has come (listed only otherwise)

ThreadPublishableInput::__construct()

public function __construct(public bool $publish = false)
$publish

publish the threads whose time has come (listed only otherwise)

TimeMachineSnapshot class

final class TimeMachineSnapshot TimeMachineSnapshot.php:14

timemachine:snapshot (plan "omnibase agnostic", step F5e, slice 3): the database connections, the storages and the snapshots each storage holds; backup() and restore() list them first, then back up or restore - each step confirmed by the host's question ($confirm: the question, its default answer).

TimeMachineSnapshot::__construct()

public function __construct(readonly TimeMachineInterface $timeMachine, readonly Storages $flysystem)

TimeMachineSnapshot::run()

public function run(TimeMachineSnapshotInput $input, ?\Closure $sink = null): Report

TimeMachineSnapshot::backup()

public function backup(TimeMachineSnapshotBackupInput $input, \Closure $confirm, ?\Closure $sink = null): Report

TimeMachineSnapshot::restore()

public function restore(TimeMachineSnapshotRestoreInput $input, \Closure $confirm, ?\Closure $sink = null): Report

TimeMachineSnapshotBackupInput class

final readonly class TimeMachineSnapshotBackupInput extends TimeMachineSnapshotInput TimeMachineSnapshotBackupInput.php:6

timemachine:snapshot:backup's options (plan "omnibase agnostic", step F5e, slice 3).

public bool $batch

no confirmation asked

public bool $userlog

the users' configuration in the backup too

TimeMachineSnapshotBackupInput::__construct()

public function __construct(array $storages = [], ?string $database = null, ?string $prefix = null, int $cycle = -1, public bool $batch = false, public bool $userlog = false)
$batch

no confirmation asked

$userlog

the users' configuration in the backup too

TimeMachineSnapshotInput class

readonly class TimeMachineSnapshotInput TimeMachineSnapshotInput.php:6

timemachine:snapshot's arguments and options, and those of its backup and restore (plan "omnibase agnostic", step F5e, slice 3).

public array $storages

the storages looked into (written to, read from)

public ?string $database

the database connection backed up

public ?string $prefix

the snapshots' prefix (Symfony: the environment's name)

public int $cycle

the cycle (-1: the current one)

TimeMachineSnapshotInput::__construct()

public function __construct(public array $storages = [], public ?string $database = null, public ?string $prefix = null, public int $cycle = -1)
$storages

the storages looked into (written to, read from)

$database

the database connection backed up

$prefix

the snapshots' prefix (Symfony: the environment's name)

$cycle

the cycle (-1: the current one)

TimeMachineSnapshotRestoreInput class

final readonly class TimeMachineSnapshotRestoreInput extends TimeMachineSnapshotInput TimeMachineSnapshotRestoreInput.php:6

timemachine:snapshot:restore's options (plan "omnibase agnostic", step F5e, slice 3).

public int $id

the snapshot restored (-1: the latest)

TimeMachineSnapshotRestoreInput::__construct()

public function __construct(array $storages = [], ?string $database = null, ?string $prefix = null, int $cycle = -1, public int $id = -1)
$id

the snapshot restored (-1: the latest)

TimeMachineStorage class

final class TimeMachineStorage TimeMachineStorage.php:9

timemachine:storage (plan "omnibase agnostic", step F5e, slice 3): the storages a snapshot can be written to.

TimeMachineStorage::__construct()

public function __construct(readonly TimeMachineInterface $timeMachine)

TimeMachineStorage::run()

public function run(?\Closure $sink = null): Report

TranslationControllers class

final class TranslationControllers extends TranslationTask TranslationControllers.php:12

translation:controllers (plan "omnibase agnostic", step F5e, slice 3): the routes served by an App\ or a Base\ controller and, for each language, the key of their page's title, "@controllers.<route>.<suffix>", with its translation or "no translation found". The host gives its routes.

TranslationControllers::run()

public function run(TranslationControllersInput $input, ?\Closure $sink = null): Report

TranslationControllersInput class

final readonly class TranslationControllersInput TranslationControllersInput.php:6

translation:controllers' options (plan "omnibase agnostic", step F5e, slice 3).

public array $routes

the host's routes: name => controller ("App\...::action")

public string $controller
public string $suffix
public ?string $locale

TranslationControllersInput::__construct()

public function __construct(public array $routes = [], public string $controller = '', public string $suffix = 'title', public ?string $locale = null)
$routes

the host's routes: name => controller ("App\...::action")

TranslationCrud class

final class TranslationCrud extends TranslationTask TranslationCrud.php:14

translation:crud (plan "omnibase agnostic", step F5e, slice 3): the back office's CRUD controllers - the core's, then the application's - and, for each language, the key of their page's title, "@admin.crud.<the class's path>.<action>.<suffix>", with its translation or "no translation found".

TranslationCrud::run()

public function run(TranslationCrudInput $input, ?\Closure $sink = null): Report

TranslationCrudInput class

final readonly class TranslationCrudInput TranslationCrudInput.php:6

translation:crud's options (plan "omnibase agnostic", step F5e, slice 3).

public string $source

the application's App\ folder (Symfony: ./src)

public string $crud
public string $action
public string $suffix
public ?string $locale

TranslationCrudInput::__construct()

public function __construct(public string $source = 'src', public string $crud = '', public string $action = 'index', public string $suffix = 'title', public ?string $locale = null)
$source

the application's App\ folder (Symfony: ./src)

TranslationEntities class

final class TranslationEntities extends TranslationTask TranslationEntities.php:14

translation:entities (plan "omnibase agnostic", step F5e, slice 3): the application's entities, then the core's - their namespaces first, then their classes, the translations' tables (…Intl) left out - and, for each language, the key of their noun, "@entities.<the path>.<suffix>", with its translation or "no translation found".

TranslationEntities::run()

public function run(TranslationEntitiesInput $input, ?\Closure $sink = null): Report

TranslationEntitiesInput class

final readonly class TranslationEntitiesInput TranslationEntitiesInput.php:8

translation:entities' options (plan "omnibase agnostic", step F5e, slice 3).

public string $source

the application's App\ folder (Symfony: ./src)

public string $entity
public string $suffix
public ?string $locale

TranslationEntitiesInput::__construct()

public function __construct(public string $source = 'src', public string $entity = '', public string $suffix = TranslatorInterface::NOUN_SINGULAR, public ?string $locale = null)
$source

the application's App\ folder (Symfony: ./src)

TranslationEnums class

final class TranslationEnums extends TranslationTask TranslationEnums.php:15

translation:enums (plan "omnibase agnostic", step F5e, slice 3): the application's enumerations, then the core's (the native PHP enums and the groups without values of their own left out) and, for each language, the key of their noun, "@enums.<the path>.<suffix>", then of each value's, "@enums.<the path>.<value>.<suffix>", with their translations or "no translation found".

TranslationEnums::run()

public function run(TranslationEnumsInput $input, ?\Closure $sink = null): Report

TranslationEnumsInput class

final readonly class TranslationEnumsInput TranslationEnumsInput.php:8

translation:enums' options (plan "omnibase agnostic", step F5e, slice 3).

public string $source

the application's App\ folder (Symfony: ./src)

public string $enum
public string $suffix
public ?string $locale

TranslationEnumsInput::__construct()

public function __construct(public string $source = 'src', public string $enum = '', public string $suffix = TranslatorInterface::NOUN_SINGULAR, public ?string $locale = null)
$source

the application's App\ folder (Symfony: ./src)

TranslationSettings class

final class TranslationSettings extends TranslationTask TranslationSettings.php:15

translation:settings (plan "omnibase agnostic", step F5e, slice 3): the settings under a path and their value in each language (a setting of a single language marked so), or, raw, each one's label and help per language.

TranslationSettings::__construct()

public function __construct(TranslatorInterface $translator, LocalizerInterface $localizer, Locales $locales, readonly SettingBagInterface $settingBag)

TranslationSettings::run()

public function run(TranslationSettingsInput $input, ?\Closure $sink = null): Report
Throws

Exception no setting under the path, or a language the site has not got

TranslationSettingsInput class

final readonly class TranslationSettingsInput TranslationSettingsInput.php:6

translation:settings' options (plan "omnibase agnostic", step F5e, slice 3).

public ?string $path
public bool $raw
public ?string $locale

TranslationSettingsInput::__construct()

public function __construct(public ?string $path = null, public bool $raw = false, public ?string $locale = null)

TranslationTask class

abstract class TranslationTask TranslationTask.php:16

What the translation keys' tasks share (plan "omnibase agnostic", step F5e, slice 3): the languages listed (the site's, or the one asked, refused when the site has not got it), a key's line - found, or "no translation found" - and where the core's and the application's classes are.

TranslationTask::__construct()

public function __construct(protected readonly TranslatorInterface $translator, protected readonly LocalizerInterface $localizer, protected readonly Locales $locales)

TrashPurge class

final class TrashPurge TrashPurge.php:13

trash:purge (plan "omnibase agnostic", step F5e, slice 3): the trash emptied of everything past its grace period (base.extension.empty_trash, "+7 days" by default). A dry run unless forced: nothing else in the stack destroys content beyond recovery.

TrashPurge::__construct()

public function __construct(readonly TrashManager $trashManager)

TrashPurge::run()

public function run(TrashPurgeInput $input, ?\Closure $sink = null, ?\DateTimeInterface $now = null): Report

TrashPurgeInput class

final readonly class TrashPurgeInput TrashPurgeInput.php:6

trash:purge's options (plan "omnibase agnostic", step F5e, slice 3).

public bool $force

destroy them (only reported otherwise: a dry run)

public ?int $limit

at most this many in this run

TrashPurgeInput::__construct()

public function __construct(public bool $force = false, public ?int $limit = null)
$force

destroy them (only reported otherwise: a dry run)

$limit

at most this many in this run

UploaderEntities class

class UploaderEntities UploaderEntities.php:21

uploader:entities (plan "omnibase agnostic", step F5e, slice 3): the properties holding uploaded files (#[Uploader]) of the application's entities and the core's, the files each one's folder holds, and - asked - the orphans: the files no row names, and the names no file answers; deleted if asked (demo:reset's nightly step).

uploader:images and uploader:images:crop are this task with more to do on each property (process()).

UploaderEntities::__construct()

public function __construct(protected readonly Repositories $repositories)

UploaderEntities::run()

public function run(UploaderEntitiesInput $input, ?\Closure $sink = null): Report

UploaderEntitiesInput class

readonly class UploaderEntitiesInput UploaderEntitiesInput.php:6

uploader:entities' options (plan "omnibase agnostic", step F5e, slice 3).

public string $source

the application's App\ folder (Symfony: <project>/src)

public ?string $entity

an entity's name under App\Entity\ or Base\Entity\ (either prefix taken off), none: all

public ?string $property
public ?string $uuid
public bool $orphans
public bool $deleteOrphans

UploaderEntitiesInput::__construct()

public function __construct(public string $source = 'src', public ?string $entity = null, public ?string $property = null, public ?string $uuid = null, public bool $orphans = false, public bool $deleteOrphans = false)
$source

the application's App\ folder (Symfony: <project>/src)

$entity

an entity's name under App\Entity\ or Base\Entity\ (either prefix taken off), none: all

UploaderEntitiesInput::entityName()

public function entityName(): string

The entity's name without its App\Entity\ or Base\Entity\ prefix ("" for all).

UploaderImages class

class UploaderImages extends UploaderEntities UploaderImages.php:16

uploader:images (plan "omnibase agnostic", step F5e, slice 3): uploader:entities, and - asked - each image and its thumbnails (the formats of its #[Uploader] and of base.uploader.formats) made in the cache, original and WebP, at most a batch per run.

UploaderImages::__construct()

public function __construct(Repositories $repositories, protected readonly MediaServiceInterface $mediaService, protected readonly array $defaultFormats = [])
$defaultFormats

base.uploader.formats

UploaderImages::run()

public function run(UploaderEntitiesInput $input, ?\Closure $sink = null): Report

UploaderImages::isCached()

public function isCached(string $data): bool

Whether the image (an address of the media service's) is already in the cache, as WebP.

UploaderImagesCrop class

final class UploaderImagesCrop extends UploaderImages UploaderImagesCrop.php:25

uploader:images:crop (plan "omnibase agnostic", step F5e, slice 3): uploader:images on the images (Base\Entity\ Layout\Image and its App\ classes), each image's crops made in the cache too; and - asked, confirmed - the crops' coordinates renormalised against a resolution (Base\Imagine\Filter\Basic\Definition\*).

The crops are made by the host's media controller (its ImageWebp, Image and ImageCrop actions), given; without it the warm-up of the crops is refused aloud.

UploaderImagesCrop::__construct()

public function __construct(Repositories $repositories, MediaServiceInterface $mediaService, array $defaultFormats = [], readonly ?UnitOfWork $unitOfWork = null, readonly ?object $mediaController = null)
$mediaController

the host's media controller (ImageWebp, Image, ImageCrop)

UploaderImagesCrop::definitions()

public static function definitions(): array
Returns

the resolutions the crops can be renormalised against

UploaderImagesCrop::run()

public function run(UploaderEntitiesInput $input, ?\Closure $sink = null, ?\Closure $confirm = null): Report
$confirm

the host's question to the user (the renormalisation is asked for confirmation); none: refused

UploaderImagesCrop::isCropCached()

public function isCropCached(string $data, ImageCrop $imageCrop): bool

Whether a crop of the image (an address of the media service's) is already in the cache.

UploaderImagesCropInput class

readonly class UploaderImagesCropInput extends UploaderImagesInput UploaderImagesCropInput.php:6

uploader:images:crop's options (plan "omnibase agnostic", step F5e, slice 3).

public bool $normalize

the crops' coordinates renormalised (x0, y0, width0, height0 from x, y, width, height)

public ?object $maxDefinition

the resolution (a Base\Imagine\Filter\Basic\Definition\*) they are renormalised against

UploaderImagesCropInput::__construct()

public function __construct(string $source = 'src', ?string $entity = null, ?string $property = null, ?string $uuid = null, bool $orphans = false, bool $deleteOrphans = false, bool $warmup = false, int $batch = 0, ?string $format = null, public bool $normalize = false, public ?object $maxDefinition = null)
$normalize

the crops' coordinates renormalised (x0, y0, width0, height0 from x, y, width, height)

$maxDefinition

the resolution (a Base\Imagine\Filter\Basic\Definition\*) they are renormalised against

UploaderImagesInput class

readonly class UploaderImagesInput extends UploaderEntitiesInput UploaderImagesInput.php:6

uploader:images' options (plan "omnibase agnostic", step F5e, slice 3).

public bool $warmup

the images and their thumbnails made in the cache

public int $batch

at most this many made per run (0: no limit)

public ?string $format

only this format ("<width>x<height>")

UploaderImagesInput::__construct()

public function __construct(string $source = 'src', ?string $entity = null, ?string $property = null, ?string $uuid = null, bool $orphans = false, bool $deleteOrphans = false, public bool $warmup = false, public int $batch = 0, public ?string $format = null)
$warmup

the images and their thumbnails made in the cache

$batch

at most this many made per run (0: no limit)

$format

only this format ("<width>x<height>")

UserCreate class

final class UserCreate UserCreate.php:20

user:create (plan "omnibase agnostic", step F5e, slice 3): an account made from the command line, verified and approved, with a password it did not choose - generated and shown once, or given -, to be changed at its first sign-in (a PASSWORD_CHANGE token, which omnibridge/symfony's PasswordChangeSubscriber asks) unless kept; e-mailed its username and password (Notifier::accountCreated) unless not.

const PASSWORD_CHANGE = 'change-password'

The token an account must change its password under (omnibridge/symfony's PasswordChangeSubscriber::TOKEN).

const ALPHABET = 'abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789'

The generated password's alphabet: letters and digits without the ones read alike (0/O, 1/l/I).

UserCreate::__construct()

public function __construct(readonly UnitOfWork $unitOfWork, readonly ?NotifierInterface $notifier = null)

UserCreate::run()

public function run(UserCreateInput $input, ?\Closure $sink = null): Report

UserCreateInput class

final readonly class UserCreateInput UserCreateInput.php:6

user:create's arguments and options (plan "omnibase agnostic", step F5e, slice 3).

public string $username
public string $email
public array $roles

USER, ADMIN, SUPERADMIN... (ROLE_ optional)

public ?string $password

its password (generated otherwise)

public bool $keepPassword

not to be changed at the first sign-in

public bool $noEmail

not e-mailed its username and password

UserCreateInput::__construct()

public function __construct(public string $username, public string $email, public array $roles = ['USER'], public ?string $password = null, public bool $keepPassword = false, public bool $noEmail = false)
$roles

USER, ADMIN, SUPERADMIN... (ROLE_ optional)

$password

its password (generated otherwise)

$keepPassword

not to be changed at the first sign-in

$noEmail

not e-mailed its username and password

UserNotification class

final class UserNotification UserNotification.php:17

user:notifications (plan "omnibase agnostic", step F5e, slice 3): the notifications kept in the database counted (an account's, or everyone's), listed, and the read ones erased when older than base.user.notifications.expiry (or the expiry given), or whatever their age. An unread notification is never erased.

UserNotification::__construct()

public function __construct(readonly UnitOfWork $unitOfWork, readonly ParameterBagInterface $parameterBag)

UserNotification::run()

public function run(UserNotificationInput $input, ?\Closure $sink = null): Report

UserNotificationInput class

final readonly class UserNotificationInput UserNotificationInput.php:6

user:notifications' options (plan "omnibase agnostic", step F5e, slice 3).

public ?string $user

the account (its identifier); every account's without it

public ?string $expiry

the age past which a read notification is erased ("+30 days"); base.user.notifications.expiry without it

public bool $show

list them

public bool $clear

erase the read ones older than the expiry

public bool $clearAll

erase every read one, whatever its age

UserNotificationInput::__construct()

public function __construct(public ?string $user = null, public ?string $expiry = null, public bool $show = false, public bool $clear = false, public bool $clearAll = false)
$user

the account (its identifier); every account's without it

$expiry

the age past which a read notification is erased ("+30 days"); base.user.notifications.expiry without it

$show

list them

$clear

erase the read ones older than the expiry

$clearAll

erase every read one, whatever its age

Base\Contract

Framework class

final class Framework Framework.php:22

Whether omnibase's classes declare a framework's interfaces where they would (plan "omnibase agnostique", C7b, C7c): Base\Entity\User implements Security's UserInterface and PasswordAuthenticatedUserInterface and scheb/2fa's models through Base\Contract\SecurityUser and Base\Contract\TwoFactorUser, which are those interfaces when they are installed and empty otherwise.

Installed means declared, and nothing else decides: no environment variable, no switch. Whatever loads the user first (a kernel, a unit test, PHP's preloading, a Laravel application reading a vendor that holds Symfony's packages) gets the same class. A host without the framework is a vendor without its packages (composer install --no-dev of the core alone, where docker/bin/bare measures the Foundation). Kept as a class, not written out in each contract: the one place of the rule, which a third contract follows the same way.

Framework::declares()

public static function declares(string ...$interfaces): bool

Whether the interfaces named are to be declared: every one of them is installed (autoloaded here).

final class Link Link.php:24

A route's address by a router's reference type, through the Urls contract (plan "omnibase agnostique", C3e): what an entity's __toLink() made with BaseTrait's router, $this->getRouter()->generate($name, $parameters, $referenceType), made where there is no framework too.

Not a contract: the static door of Base\Service\Links (step E1), a service on Runtime::urls(). The entities' __toLink() take Symfony's reference types (UrlGeneratorInterface's constants); their values are named here, so that a link is made without the routing component. An absolute path is Urls::path(), an absolute URL Urls::url(): the two the core, its bundles and the sites ask for. A relative path and a network path have no equivalent in the contract; they are asked of the Urls implementation's own generate($name, $parameters, $referenceType) when it has one (omnibridge/symfony's Omnibridge\Symfony\RouterUrls: the router, as before), and refused otherwise.

Symfony's UrlGeneratorInterface::ABSOLUTE_URL: scheme, host and path

Symfony's UrlGeneratorInterface::ABSOLUTE_PATH: the path from the root

Symfony's UrlGeneratorInterface::RELATIVE_PATH

Symfony's UrlGeneratorInterface::NETWORK_PATH: "//host/path"

public static function to(string $name, array $parameters = [], int $referenceType = self::ABSOLUTE_PATH): string

The address, made by Base\Service\Links on the host's Urls (the service the registry gives where the host lists it, else one on Runtime::urls()).

Media interface

interface Media Media.php:20

The image route as an entity builds its addresses (plan "omnibase agnostique", C4b): a stored image is served by omnibase's route ux_image (or ux_imageExtension) with its path and how to serve it - a crop, a thumbnail, the filters, a salt - obfuscated in one data parameter, and the extension it is served with. Image::__toLink() and ImageCrop::__toLink() ask it instead of BaseTrait's MediaService.

The Foundation's own contract, reached by Runtime::media(). Under Symfony, Base\Bridge\Symfony\ServiceMedia: MediaService's answers. A host without the framework that serves omnibase's images gives its own (the obfuscation is Base\Service\Obfuscator's, a class of the Foundation).

Media::extension()

public function extension(?string $path): ?string

The extension a stored file is served with, from its type ("jpg", "png"); null when none is known.

Media::obfuscate()

public function obfuscate(?string $path, array $config = [], array $filters = []): ?string

The image route's data for a stored file: its path, the config (identifier, salt, webp...) and the filters, obfuscated; null for no path.

public function link(string $route, array $parameters, ?string $path, array $config = []): ?string

The address of an image route (ux_image, ux_imageExtension) for a stored file, its data made from the config (reference_type, identifier, salt, filters...); null for no path.

$parameters

the route's other parameters (extension...)

MediaRouter interface

interface MediaRouter MediaRouter.php:25

The router as omnibase's media rule asks it (audit "lesringostars face au master plan", R6): FileService and MediaService - the image route's obfuscated addresses, their resolution, the files they serve - and Base\Service\ImageRoute, the route's answers, need only these five questions of a router: an address of a named route, the route and the parameters an address matches, the route's name of an address, the public address of a file, an address by name or as it is.

Under Symfony, omnibase's AdvancedRouterInterface extends it: the advanced_router service is passed as before, the same answers. A host without the framework that serves omnibase's images gives its own over its router, on the image routes declared in Base\Service\ImageRoute::ROUTES (omnibridge/laravel's, over Laravel's router).

The reference types are those of Symfony's UrlGeneratorInterface and of Base\Contract\Link: 0 an absolute URL, 1 an absolute path (the default), 2 a relative path, 3 a network path. No constant is declared here, so that AdvancedRouterInterface inherits these methods from both interfaces.

MediaRouter::generate()

public function generate(string $name, array $parameters = [], int $referenceType = 1): string

The address of a named route (ux_image, ux_imageExtension...) with its parameters, by its reference type.

MediaRouter::getRouteMatch()

public function getRouteMatch(?string $routeUrl = null): ?array

What an address matches: its route's name under "_route" and the route's parameters ("data", "extension"...); null when it matches none.

MediaRouter::getRouteName()

public function getRouteName(?string $routeUrl = null): ?string

The name of the route an address matches, null for none.

MediaRouter::getAssetUrl()

public function getAssetUrl(string $nameOrUrl, ?string $packageName = null): string

A public file's address ("" is the public root's, "/" for most hosts).

MediaRouter::getUrl()

public function getUrl(?string $nameOrUrl = null, array $parameters = [], int $referenceType = 1): string

An address by a route's name, or an address as it is, by its reference type.

Nouns interface

interface Nouns Nouns.php:26

What an entity is called: its noun, singular or plural, at a level of politeness, for a gender - "Article", "Articles", "Commande" - and the label of one of its properties, from the "entities" catalogues (plan "omnibase agnostique", C4b): what an entity's __toString() falls back on when it has no title, what a list or a message names it by.

The options are Base\Service\Translator's: TranslatorInterface::NOUN_SINGULAR or NOUN_PLURAL, Translator::GENDERNESS_* and POLITENESS_*, alone or in an array. The key is the class's name less its entity namespace (App\Entity\, Base\Entity\, a bundle's Base\Marketplace\Entity\ as "marketplace."), in snake case: Base\Entity\Thread\Tag is "thread.tag", Base\Marketplace\Entity\ Order "marketplace.order".

The rule is the Foundation's, Base\Service\Model\EntityNouns, over the Translations contract and the entity namespaces of the application's bundles; a host gives it those two. Under Symfony it is the one Base\Service\Translator::transEntity() answers by, the same strings.

Nouns::entity()

public function entity(object|string $entityOrClass, ?string $property = null, string|array $options = TranslatorInterface::NOUN_SINGULAR): ?string

The noun of an entity (an object or its class), or of one of its properties when one is named; when the catalogues have none, the key asked in lower case ("thread.tag._singular"). Null for a name that is no class's key at all (an empty string).

Nouns::entityExists()

public function entityExists(object|string $entityOrClass, ?string $property = null, string|array $options = TranslatorInterface::NOUN_SINGULAR): bool

Whether the catalogues hold that noun, under one of the keys entity() tries.

Pictures interface

interface Pictures Pictures.php:15

An image's address at the size a page shows it (plan "omnibase agnostique", C5): what omnibase's |picture filter answers - a thumbnail of a stored image, an address or a public path as it is, an asset of the build. Null for no image.

The Foundation's own contract, reached by Runtime::pictures() or given to a screen's builder. Under Symfony, Base\Bridge\Symfony\MediaPictures: the filter's own answers (MediaService's thumbnails).

Pictures::picture()

public function picture(?string $image, ?int $width = null, ?int $height = null): ?string

Runtime class

final class Runtime extends HostRuntime Runtime.php:41

The registry through which omnibase's framework-free code reaches its contracts (plan "omnibase agnostique", C4): an entity's getter, an attribute, a value object asks Runtime::urls(), ::access(), ::nouns()... instead of the services Base\Traits\BaseTrait hands out.

Since A2, omnisense/omnibridge's registry (Omnibridge\Runtime: the same state, the same container, filled once at boot by the host) with omnibase's own contracts beside the host's. From omnibridge, generic to any host: Urls (path, url, asset), Translations (trans, ICU, exists()), Locales, Access (isGranted, the user), Sessions (a user signed out), Tokens (a form's token for an intent), Files (public URL, local path of a stored file), Routes (a route's declared path, the route of an address, its icons), Environment (its name, debug, the secret), PSR-20's clock (the machine's, SystemClock, when none was given) and PSR-14's event dispatcher. omnibase's own, here: the application's parameters (Base\Service\ParameterBagInterface, C4b), Nouns (what an entity is called, the rule of Base\Service\Model\EntityNouns), Media (the image route's addresses, C4b), Pictures (an image's address at a size) and Texts (a stored text rendered, its table of contents) for the screens (C5), and symfony/mailer's MailerInterface (a standalone component, allowed in the Foundation by D1; Laravel's own mail is built on it).

Under Symfony, omnibase's bundle hands its base.contracts locator in BaseBundle::boot() (the locator of Base\Discovery's contracts, omnibridge/symfony's DiscoveryPass); under Laravel, omnibridge/laravel hands the application. A contract asked and not filled throws MissingContractException; find() answers null instead, for a caller that can do without.

Runtime::parameters()

public static function parameters(): ParameterBagInterface

The application's parameters (C4b), read by a dotted path; under Symfony the container's with the settings stored in the database (parameter_bag).

Runtime::nouns()

public static function nouns(): Nouns

What an entity is called (C4b): its noun, singular or plural, from the "entities" catalogues.

Runtime::media()

public static function media(): Media

The image route's addresses for a stored image (C4b): its extension, its data, its link.

Runtime::pictures()

public static function pictures(): Pictures

Runtime::texts()

public static function texts(): Texts

Runtime::mailer()

public static function mailer(): MailerInterface

Runtime::notifier()

public static function notifier(): BaseNotifierInterface

omnibase's notifier, which a Notification sends itself through (step E1: an entity asks this registry, never BaseTrait's accessors): the one BaseTrait::getNotifier() answered, the registry's else the host's seeded at boot; MissingContractException without one.

Runtime::translator()

public static function translator(): TranslatorInterface

omnibase's translator (step E1), the one BaseTrait::getTranslator() answered: a Notification's words.

Runtime::projectDir()

public static function projectDir(): string

The application's folder (step E1), the one BaseTrait::getProjectDir() answered.

Texts interface

interface Texts Texts.php:15

A stored text as a page shows it (plan "omnibase agnostique", C5): an Editor.js document or the HTML of an older editor, rendered - mentions, links, media, headings anchored - and its table of contents. What omnibase's |wysiwyg and |wysiwyg_toc filters answer.

The Foundation's own contract, reached by Runtime::texts() or given to a screen's builder. Under Symfony, Base\Bridge\Symfony\WysiwygTexts: the filters' own pipeline, so a screen's HTML is the page's of before.

Texts::isEditor()

public function isEditor(?string $text): bool

Whether the text is an Editor.js document (rather than HTML).

Texts::render()

public function render(?string $text, array $options = []): string

The text rendered, '' for none (null).

$options

those of |wysiwyg (headings, media, semantics...)

Texts::toc()

public function toc(?string $text, ?int $maxLevel = null): array

The text's headings, in its order.

Tickets interface

interface Tickets Tickets.php:15

Short-lived signed tickets to a service that checks them by itself (a WebSocket relay, a game server): a browser or a client asks the application for one, presents it to the service, and the service verifies the signature with the secret they share, never calling the application back. What it says (who, what room, what rights) is each factory's own, so mint is not part of the contract; how it is signed is Base\Service\Ticket\TicketSigner's, the one format the services read.

Implemented by Base\Service\Collab\CollabTicketFactory (the editors' collaboration relay) and by an application's own factories, one a service, each with its own secret.

Tickets::isConfigured()

public function isConfigured(): bool

Whether tickets can be given: a secret and the service's public address are both set.

Tickets::getWsUrl()

public function getWsUrl(): string

The service's public address, where a ticket is presented.

Tickets::verifyServiceToken()

public function verifyServiceToken(string $token, string $room): bool

Whether a token the service signed itself (a report, an autosave) holds for a room or scope: signature, expiry, room.

Base\Controller

SignatureController class

final class SignatureController SignatureController.php:16

A signing provider's callback (omnisense/omnisign: Yousign, DocuSign, DocuSeal...): its signature checked by the gateway, the envelope it names asked again and kept (Base\Service\Signatures::notify()). Without omnisense/omnisign there is nothing to update: 404.

SignatureController::__construct()

public function __construct(readonly ?Signatures $signatures = null)

SignatureController::webhook()

public function webhook(Request $request, string $gateway): JsonResponse

Base\Controller\Action\Notification

Delete class

final class Delete Delete.php:19

The bell's removals, written once for every host (step R29 of the audit "lesringostars face au master plan"; formerly NotificationController:: Delete()). Body: {token, id?} - one notification of the account, or every read one when id is absent. The token is checked as Read checks it; 403 without it or for a visitor.

Delete::__construct()

public function __construct(readonly Access $access, readonly Tokens $tokens, readonly Notifications $notifications)

Delete::__invoke()

public function __invoke(array $body = []): Json

Latest class

final class Latest Latest.php:26

The bell's payload, written once for every host (step R27 of the audit "lesringostars face au master plan"; formerly NotificationController:: Latest(), and the closure of lesringostars-laravel's routes/web.php): the signed-in account's unread count and latest entries (?limit=, 1 to 20, 8 by default), for a tab open a while - the page's own dropdown is only as fresh as the page; 401 for a visitor. Private to the account.

A host's routes read its #[Route]: Symfony's router (under src/Controller, which an omnibase site's routes import, @BaseBundle/Controller), omnibridge/laravel's Routing\ActionRoutes (this folder).

Latest::__construct()

public function __construct(readonly Access $access, readonly Notifications $notifications, readonly ?NotificationLinkerInterface $linker = null)

Latest::__invoke()

public function __invoke(array $query = []): Json

Latest::item()

public function item(Notification $notification): array
Returns

a notification as the bell's script reads it

Read class

final class Read Read.php:22

The bell's read marks, written once for every host (step R29 of the audit "lesringostars face au master plan"; formerly NotificationController:: MarkRead()). Body: {token, id?, read?} - one notification of the account, or every unread one when id is absent; read defaults to true, false puts one back to unread. The "notifications" token in the body (the toolbar's data-csrf) is checked through the host's Tokens; without it, or for a visitor, 403. JSON rather than a redirect: the bell updates in place.

const TOKEN = 'notifications'

The intent of the bell's token.

Read::__construct()

public function __construct(readonly Access $access, readonly Tokens $tokens, readonly Notifications $notifications)

Read::__invoke()

public function __invoke(array $body = []): Json

Read::account()

public static function account(Access $access, Tokens $tokens, array $body): ?User

The account signed in, when the body carries its bell's token; null otherwise.

Base\Controller\Action\Settings

EmailCodeToggle class

final class EmailCodeToggle EmailCodeToggle.php:27

The e-mailed code as a second factor, turned on or off, written once for every host (step R29 of the audit "lesringostars face au master plan"; formerly UserSettingsController::TwoFactorAuthentication_ToggleEmail()): the method the enrolment page (Enrolment) and the settings offer with a button. A demonstration account changes nothing; its form's token (intent "2fa_email", the field _token) is checked through the host's Tokens, 403 without it; turned on only where the administrator allows a second factor, off only when it is not the last one a required second factor leaves. The account told (Notice), then the settings.

A visitor is sent to sign in (Symfony's firewall does it first: ^/settings is for members).

const TOKEN = '2fa_email'

EmailCodeToggle::__construct()

public function __construct(readonly Access $access, readonly Tokens $tokens, readonly SecurityPolicy $policy, readonly Urls $urls, readonly Users $users, readonly ?\Closure $notice = null)
$notice

how the host tells the account (Notice)

EmailCodeToggle::__invoke()

public function __invoke(array $body = []): Redirect

Enrolment class

final class Enrolment Enrolment.php:30

The one-off "your account needs a second factor" page, written once for every host (step R29 of the audit "lesringostars face au master plan"; formerly UserSettingsController::Enrolment()).

Reached by being sent here (EnrolmentPrompt: Symfony's SecurityEnrolmentSubscriber, omnibridge/laravel's enrolment middleware), while the administrator or a role requires a second factor the account does not have, or once after a sign-in from an unknown browser (the optional offer: other words, a "no thanks" remembered for good). It offers the methods the settings page does, plus a way out where the application allows a "later" (EnrolmentSkip). Nothing to ask: the settings, and the offer's flag forgotten. The session is omniauth's State, the host's. A visitor is sent to sign in (Symfony's firewall does it first: ^/settings is for members).

Enrolment::__construct()

public function __construct(readonly Access $access, readonly SecurityPolicy $policy, readonly Urls $urls, readonly ?State $session = null)

Enrolment::__invoke()

public function __invoke(): Template|Redirect

EnrolmentSkip class

final class EnrolmentSkip EnrolmentSkip.php:31

The enrolment page's "not now", written once for every host (step R29 of the audit "lesringostars face au master plan"; formerly UserSettingsController::EnrolmentSkip()). Its form's token (intent "2fa_enrolment_skip", the field _token) is checked through the host's Tokens: without it, 403. Where the application allows no "later", back to the enrolment page (a hand-made POST gets the same answer as the missing button). Otherwise the session says so (SESSION_ENROLMENT_SKIPPED) and the offer's flag goes; after the offer, the profile and, for a year, a cookie of this browser (SecurityPolicy::COOKIE_NEW_DEVICE_PROMPT_DISMISSED: the only memory there is without a column of the account); after the mandatory enrolment, the settings. The account is told ("@notifications.settings.enrolmentSkipped", info: Notice).

A visitor is sent to sign in (Symfony's firewall does it first: ^/settings is for members).

const TOKEN = '2fa_enrolment_skip'
const NOTICE = '@notifications.settings.enrolmentSkipped'

EnrolmentSkip::__construct()

public function __construct(readonly Access $access, readonly Tokens $tokens, readonly SecurityPolicy $policy, readonly Urls $urls, readonly ?State $session = null, readonly ?\Closure $notice = null)
$notice

how the host tells the account (a flash)

EnrolmentSkip::__invoke()

public function __invoke(array $body = []): Redirect

Notice class

final class Notice Notice.php:13

How an account action written once for every host tells the account what it did (step R29): the host's own notice where it gives one (omnibridge/laravel: its flash, in the visitor's language), else omnibase's Notifier (Notification::send(), a flash under Symfony).

Notice::send()

public static function send(?\Closure $notice, string $label, string $message): void

Base\Controller\Action\Widget

Page class

final class Page Page.php:19

A page of the site's widgets (/page/{slug}: the legal notice, the privacy policy...), written once for every host (step R27 of the audit "lesringostars face au master plan"; formerly WidgetController::Page()): widget/page.html.twig with the page, none of that slug not found.

A host's routes read its #[Route]: Symfony's router (under src/Controller, which an omnibase site's routes import, @BaseBundle/Controller), omnibridge/laravel's Routing\ActionRoutes (this folder).

Page::__construct()

public function __construct(readonly PageRepository $pages)

Page::__invoke()

public function __invoke(string $slug): ?Template

Base\Database

Events class

final class Events Events.php:5

const resolveDiscriminator = 'resolveDiscriminator'
const preQuery = 'preQuery'
const onQuery = 'onQuery'
const postQuery = 'postQuery'

FormerNames class

final class FormerNames FormerNames.php:12

The former names of the core's classes that moved to omnibridge/doctrine and omnibridge/symfony (plan "omnibase agnostic", steps F3 and F5b), as data: former => new, read from src/Resources/former-names.{doctrine,symfony}.php, whose lists src/Resources/former-names.php aliases. For what names a moved class the way it was named before - MetadataSnapshot, which compares the mapping and not where a class lives, and the tests.

FormerNames::moved()

public static function moved(): array
Returns

former => new

FormerNames::former()

public static function former(string $class): ?string

The former name of a moved class, null for any other.

FormerNames::name()

public static function name(string $class): string

The former name of a moved class, the class itself for any other.

UnitOfWorks class

final class UnitOfWorks UnitOfWorks.php:25

omnisense/omnibridge's UnitOfWork for what a service of the core was given (plan "omnibase agnostic", step F2d): the unit of work itself, or a persistence's own manager - Doctrine's entity manager, which the hosts and the applications still hand to the core's services (omnibridge/laravel, the tests, a bundle's own wiring) - adapted once.

And, from a unit of work, the parts of its persistence registered in Backends: its repositories by class (Repositories), its entities' shapes (EntityShapes), and what only that persistence does (Base\Database\Backend\*). A service of the core takes a UnitOfWork and asks nothing else of the ORM.

The entity manager accepted in place of a unit of work is deprecated: it goes at 6.0, with the Doctrine-typed hooks.

const ADAPTERS = ['Doctrine\ORM\EntityManagerInterface' => 'Omnibridge\Doctrine\Omnibase\DoctrineUnitOfWork']

The persistences' managers a unit of work is made from, by name, so that nothing here loads them: omnibridge/doctrine's adapter (in the core until step F3).

UnitOfWorks::register()

public static function register(string $manager, string|\Closure $adapter): void
$manager

the persistence's manager class (an interface matches its implementations)

UnitOfWorks::of()

public static function of(object $persistence): UnitOfWork

The unit of work itself, or one made from a persistence's manager.

UnitOfWorks::repositories()

public static function repositories(UnitOfWork $unitOfWork): Repositories

The repositories of the unit of work's persistence, by entity class.

UnitOfWorks::shapes()

public static function shapes(UnitOfWork $unitOfWork): EntityShapes

The entities' shapes as the unit of work's persistence maps them.

Base\Database\Attribute

Alias class

class Alias extends AbstractAttribute implements ExtensionOptionInterface Alias.php:17

public string $alias
public string $column
public ?string $type

Alias::__construct()

public function __construct(string $column = "", string $alias = "", ?string $type = null)

Alias::supports()

public function supports(string $target, ?string $targetValue = null, $object = null): bool

Alias::loadClassMetadata()

public function loadClassMetadata(ClassMetadata $classMetadata, string $target, ?string $targetValue = null): void

Alias::complete()

public function complete(Completor $completor, string $target, ?string $targetValue = null): void

The alias's name, bound to its column (plan "omnibase agnostic", step E3): the property it is on, or the class's #[Alias(column:, alias:)]. Doctrine checked here, as it loaded the class, that neither is mapped already; that check stays in loadClassMetadata().

Alias::bind()

public function bind($entity, $column, $alias)

Alias::onPostLoad()

public function onPostLoad(Lifecycle\PostLoad $event, ?string $property = null): void

The neutral hooks (plan "omnibase agnostic", step F2c): the alias bound to its column.

Alias::onPrePersist()

public function onPrePersist(Lifecycle\PrePersist $event, ?string $property = null): void

Alias::onPreUpdate()

public function onPreUpdate(Lifecycle\PreUpdate $event, ?string $property = null): void

Associate class

class Associate extends AbstractAttribute implements ExtensionOptionInterface Associate.php:20

public string $metadata

Associate::__construct()

public function __construct(string $metadata)

Associate::supports()

public function supports(string $target, ?string $targetValue = null, $object = null): bool

Associate::onPreUpdate()

public function onPreUpdate(Lifecycle\PreUpdate $event, ?string $property = null): void

The neutral hooks (plan "omnibase agnostic", step F2c): before a write, an associated entity kept as its identifier and its root class; after, the entity read back by that identifier.

Associate::onPrePersist()

public function onPrePersist(Lifecycle\PrePersist $event, ?string $property = null): void

Associate::onPostUpdate()

public function onPostUpdate(Lifecycle\PostUpdate $event, ?string $property = null): void

Associate::onPostPersist()

public function onPostPersist(Lifecycle\PostPersist $event, ?string $property = null): void

Associate::onPostLoad()

public function onPostLoad(Lifecycle\PostLoad $event, ?string $property = null): void

Blameable class

class Blameable extends AbstractAttribute implements ExtensionOptionInterface Blameable.php:16

Class Blameable package Base\AttributeReader\Abstract\Blameable

Blameable::__construct()

public function __construct(string|array $on = [], array $fields = [], bool $impersonator = false)

Blameable::getContext()

public function getContext(): array

Blameable::getFields()

public function getFields(): array

Blameable::supports()

public function supports(string $target, ?string $targetValue = null, $object = null): bool

Blameable::onPrePersist()

public function onPrePersist(Lifecycle\PrePersist $event, ?string $property = null): void

The neutral hook (plan "omnibase agnostic", step F2b): the entity and its unit of work.

Blameable::onPreUpdate()

public function onPreUpdate(Lifecycle\PreUpdate $event, ?string $property = null): void

The neutral hook (plan "omnibase agnostic", step F2b): the entity and its unit of work.

Cache class

class Cache extends AbstractAttribute implements ExtensionOptionInterface Cache.php:16

Caching to an entity or a collection.

public string $usage = self::READ_ONLY
const READ_ONLY = "READ_ONLY"
const NONSTRICT_READ_WRITE = "NONSTRICT_READ_WRITE"
const READ_WRITE = "READ_WRITE"
public ?string $region
public int $associations = 0
const ONE_TO_ONE = "ONE_TO_ONE"
const MANY_TO_ONE = "MANY_TO_ONE"
const ONE_TO_MANY = "ONE_TO_MANY"
const MANY_TO_MANY = "MANY_TO_MANY"
const FLAG_ONE_TO_ONE = 1

The association types as Doctrine's ClassMetadata numbers them (ONE_TO_ONE = 1, MANY_TO_ONE = 2, ONE_TO_MANY = 4, MANY_TO_MANY = 8), so that the attribute is made without Doctrine loaded.

const FLAG_MANY_TO_ONE = 2
const FLAG_ONE_TO_MANY = 4
const FLAG_MANY_TO_MANY = 8
const TO_ONE = "TO_ONE"
const TO_MANY = "TO_MANY"
const ALL = "ALL"
const NONE = "NONE"

Cache::__construct()

public function __construct(string $usage = 'READ_ONLY', ?string $region = null, ?string $associations = null)

Cache::supports()

public function supports(string $target, ?string $targetValue = null, $object = null): bool

Cache::getRegion()

public function getRegion(ClassMetadata $classMetadata)

Cache::getRegionProperty()

public function getRegionProperty(ClassMetadata $classMetadata, string $property)

Cache::onPrePersist()

public function onPrePersist(Lifecycle\PrePersist $event, ?string $property = null): void

The neutral hooks (plan "omnibase agnostic", step F2b): what the persistence's cache keeps of the entity, or of the property's association, dropped through its CacheBackend (Doctrine's second-level cache; nothing for a persistence without one).

Cache::onPreUpdate()

public function onPreUpdate(Lifecycle\PreUpdate $event, ?string $property = null): void

Cache::onPreRemove()

public function onPreRemove(Lifecycle\PreRemove $event, ?string $property = null): void

Cascade class

class Cascade extends AbstractAttribute implements ExtensionOptionInterface Cascade.php:11

Cascade::__construct()

public function __construct(string $column = "", array $value = [])

Cascade::supports()

public function supports(string $target, ?string $targetValue = null, $object = null): bool

Cascade::loadClassMetadata()

public function loadClassMetadata(ClassMetadata $classMetadata, string $target, ?string $targetValue = null): void

Countify class

class Countify extends AbstractAttribute implements ExtensionOptionInterface Countify.php:15

const COUNT_CHARS = "chars"
const COUNT_LETTERS = "letters"
const COUNT_WORDS = "words"
const COUNT_SENTENCES = "sentences"
const COUNT_BLOCKS = "blocks"

Countify::__construct()

public function __construct(?string $reference = null, string $type = "")

Countify::getReferenceColumn()

public function getReferenceColumn()

Countify::supports()

public function supports(string $target, ?string $targetValue = null, $object = null): bool

Countify::getCount()

public function getCount($entity, ?UnitOfWork $unitOfWork = null): int
Throws

Exception

Countify::onPostLoad()

public function onPostLoad(Lifecycle\PostLoad $event, ?string $property = null): void

The neutral hook (plan "omnibase agnostic", step F2b): the entity and its unit of work.

Throws

Exception

Countify::onPrePersist()

public function onPrePersist(Lifecycle\PrePersist $event, ?string $property = null): void

The neutral hook (plan "omnibase agnostic", step F2b): the entity and its unit of work.

Throws

Exception

Countify::onPreUpdate()

public function onPreUpdate(Lifecycle\PreUpdate $event, ?string $property = null): void

The neutral hook (plan "omnibase agnostic", step F2b): the entity and its unit of work.

Throws

Exception

DiscriminatorEntry class

class DiscriminatorEntry extends AbstractAttribute implements ExtensionOptionInterface DiscriminatorEntry.php:11

DiscriminatorEntry::__construct()

public function __construct(?string $value = null)

DiscriminatorEntry::getValue()

public function getValue(object|string $object_or_class): string

DiscriminatorEntry::supports()

public function supports(string $target, ?string $targetValue = null, $object = null): bool
Throws

Exception

DiscriminatorEntry::loadClassMetadata()

public function loadClassMetadata(ClassMetadata $classMetadata, string $target, ?string $targetValue = null): void

GenerateUuid class

class GenerateUuid extends AbstractAttribute implements ExtensionOptionInterface GenerateUuid.php:20

Class GenerateUuid package Base\Database\Attribute\GenerateUuid

const V1_MAC = 1
const V2_DCE = 2
const V3_MD5 = 3
const V4_RANDOM = 4
const V5_SHA1 = 5
const V6_SORTABLE = 6
const UUID_NS_DNS = "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
const UUID_NS_URL = "6ba7b811-9dad-11d1-80b4-00c04fd430c8"
const UUID_NS_OID = "6ba7b812-9dad-11d1-80b4-00c04fd430c8"
const UUID_NS_X500 = "6ba7b814-9dad-11d1-80b4-00c04fd430c8"

GenerateUuid::__construct()

public function __construct(int $version = self::V4_RANDOM, ?string $namespace = null)

GenerateUuid::getVersion()

public function getVersion()

GenerateUuid::getUuid()

public function getUuid($entity): string

GenerateUuid::supports()

public function supports(string $target, ?string $targetValue = null, $object = null): bool

GenerateUuid::onOnFlush()

public function onOnFlush(Lifecycle\OnFlush $event, object $entity, ?string $property = null): void

The neutral hook (plan "omnibase agnostic", step F2b): the flush's unit of work.

Throws

Exception

Hashify class

class Hashify extends AbstractAttribute implements ExtensionOptionInterface Hashify.php:23

Class Hashify package Base\Database\Attribute\Hashify

public ?string $referenceColumn
public bool $random
public string $algorithm
public string $hashAlgorithm
public string $plain
public bool $nullable
public array $migrateFrom
public int $keyLength
public bool $ignoreCase
public bool $encodeAsBase64
public int $iterations
public ?int $cost
public ?int $memoryCost
public ?int $timeCost

Hashify::__construct()

public function __construct(?string $reference = null, bool $random = false, string $algorithm = "auto", string $hash_algorithm = "sha512", bool $nullable = false, array $migrateFrom = [], int $key_length = 40, bool $ignore_case = false, bool $encore_as_base64 = true, int $iterations = 5000, ?int $cost = null, ?int $memory_cost = null, ?int $time_cost = null)

Hashify::getHashify()

public static function getHashify($className, $property)
Throws

Exception

Hashify::getMessageHasher()

public function getMessageHasher($entity)

Hashify::needsRehash()

public function needsRehash($entity, string $hashedMessage): bool

Hashify::isValid()

public static function isValid($entity, $property, $hashedMessage): bool
Throws

Exception

Hashify::supports()

public function supports(string $target, ?string $targetValue = null, $object = null): bool

Hashify::onPrePersist()

public function onPrePersist(Lifecycle\PrePersist $event, ?string $property = null): void

The neutral hook (plan "omnibase agnostic", step F2b): the entity and its unit of work.

Hashify::onPreUpdate()

public function onPreUpdate(Lifecycle\PreUpdate $event, ?string $property = null): void

The neutral hook (plan "omnibase agnostic", step F2b): the entity and its unit of work.

Hashify::onPostPersist()

public function onPostPersist(Lifecycle\PostPersist $event, ?string $property = null): void

The neutral hook (plan "omnibase agnostic", step F2b): the entity and its unit of work.

Throws

Exception

Hashify::onPostUpdate()

public function onPostUpdate(Lifecycle\PostUpdate $event, ?string $property = null): void

The neutral hook (plan "omnibase agnostic", step F2b): the entity and its unit of work.

Throws

Exception

Hierarchify class

class Hierarchify extends AbstractAttribute implements ExtensionOptionInterface Hierarchify.php:17

Class Hierarchify package Base\Database\Attribute\Hierarchify.

public array|string $hierarchy
public ?string $separator

Hierarchify::__construct()

public function __construct(string|array|null $hierarchy = null, ?string $separator = "/")

Hierarchify::supports()

public function supports(string $target, ?string $targetValue = null, $object = null): bool

Hierarchify::loadClassMetadata()

public function loadClassMetadata(ClassMetadata $classMetadata, string $target, ?string $targetValue = null): void

Hierarchify::complete()

public function complete(Completor $completor, string $target, ?string $targetValue = null): void

The hierarchy and its separator, on the class (plan "omnibase agnostic", step E3).

Hierarchify::parent_method_exists()

public function parent_method_exists($object, $method)

OrderColumn class

class OrderColumn extends AbstractAttribute implements ExtensionInlineInterface OrderColumn.php:22

const ASC = "ASC"
const DESC = "DESC"
public ?string $orderBy
public string $type

OrderColumn::__construct()

public function __construct(?string $orderBy = null, string $type = self::ASC)

OrderColumn::supports()

public function supports(string $target, ?string $targetValue = null, $object = null): bool
Throws

Exception

OrderColumn::onPrePersist()

public function onPrePersist(Lifecycle\PrePersist $event, ?string $property = null): void

The neutral hook (plan "omnibase agnostic", step F2c): the stored order written before the insertion.

OrderColumn::onPreUpdate()

public function onPreUpdate(Lifecycle\PreUpdate $event, ?string $property = null): void

The neutral hook (plan "omnibase agnostic", step F2c): the stored order written before the update.

OrderColumn::onPostLoad()

public function onPostLoad(Lifecycle\PostLoad $event, ?string $property = null): void

The neutral hook (plan "omnibase agnostic", step F2c): the property sorted by its stored order - a lazy association by the persistence when it can (OrderColumnBackend), the rest at once.

OrphanRemoval class

class OrphanRemoval extends AbstractAttribute implements ExtensionOptionInterface OrphanRemoval.php:19

OrphanRemoval::__construct()

public function __construct(string $column = "", bool $value = true)

OrphanRemoval::supports()

public function supports(string $target, ?string $targetValue = null, $object = null): bool

OrphanRemoval::loadClassMetadata()

public function loadClassMetadata(ClassMetadata $classMetadata, string $target, ?string $targetValue = null): void

Randomize class

class Randomize extends AbstractAttribute implements ExtensionOptionInterface Randomize.php:18

Class Randomize package Base\Database\Attribute\Randomize

Randomize::__construct()

public function __construct(?int $length = null, ?string $chars = null)

Randomize::supports()

public function supports(string $target, ?string $targetValue = null, $object = null): bool

Randomize::onOnFlush()

public function onOnFlush(Lifecycle\OnFlush $event, object $entity, ?string $property = null): void

The neutral hook (plan "omnibase agnostic", step F2b): the flush's unit of work.

Throws

Exception

Slugify class

class Slugify extends AbstractAttribute implements ExtensionOptionInterface Slugify.php:18

Class Slugify package Base\Database\Attribute\Slugify

Slugify::__construct()

public function __construct(?string $reference = null, bool $unique = true, bool $sync = false, bool $nullable = false, string $separator = "-", array $keep = [], bool $capital = false, ?string $locale = null, ?array $map = null, bool $perType = false)

Slugify::getReferenceColumn()

public function getReferenceColumn()

Slugify::getInvalidSlugs()

public function getInvalidSlugs($event, $entity, $property)

The slugs the entities written before this one in the running flush take (first in, first out), so that two of the same flush do not get the same one. $event is the neutral flush event (plan "omnibase agnostic", step F2b): the persistence's SlugifyBackend knows the pending writes.

Throws

Exception

Slugify::slug()

public function slug($entity, ?string $input = null, string $suffix = ''): ?string
Throws

Exception

Slugify::getSlug()

public function getSlug($entity, string $property, ?string $defaultInput = null, array $invalidSlugs = []): ?string

Slugify::supports()

public function supports(string $target, ?string $targetValue = null, $object = null): bool

Slugify::onOnFlush()

public function onOnFlush(Lifecycle\OnFlush $event, object $entity, ?string $property = null): void

The neutral hook (plan "omnibase agnostic", step F2b): the slug computed while the flush runs, the entity's changes computed again when it has some.

Throws

Exception

Timestamp class

class Timestamp extends AbstractAttribute implements ExtensionOptionInterface Timestamp.php:19

Class Timestamp package Base\Database\Attribute\Timestamp

Timestamp::__construct()

public function __construct(string|array $on = [], bool $immutable = false, array $fields = [], string $value = "")

Timestamp::getContext()

public function getContext(): array

Timestamp::getFields()

public function getFields(): array

Timestamp::isImmutable()

public function isImmutable(): bool

Timestamp::getValue()

public function getValue(): DateTime

Timestamp::supports()

public function supports(string $target, ?string $targetValue = null, $object = null): bool

Timestamp::onPrePersist()

public function onPrePersist(Lifecycle\PrePersist $event, ?string $property = null): void

The neutral hook (plan "omnibase agnostic", step F2b): the entity and its unit of work.

Timestamp::onPreUpdate()

public function onPreUpdate(Lifecycle\PreUpdate $event, ?string $property = null): void

The neutral hook (plan "omnibase agnostic", step F2b): the entity and its unit of work.

Timezone class

class Timezone extends AbstractAttribute implements ExtensionOptionInterface Timezone.php:18

Class Timezone package Base\Database\Attribute\Timezone

const DEFAULT_TIMEZONE = "UTC"

Timezone::__construct()

public function __construct(string|array $on = [], string $value = "")

Timezone::getContext()

public function getContext(): array

Timezone::getValue()

public function getValue(): string

Timezone::supports()

public function supports(string $target, ?string $targetValue = null, $object = null): bool

Timezone::onPrePersist()

public function onPrePersist(Lifecycle\PrePersist $event, ?string $property = null): void

The neutral hook (plan "omnibase agnostic", step F2b): the entity and its unit of work.

Timezone::onPreUpdate()

public function onPreUpdate(Lifecycle\PreUpdate $event, ?string $property = null): void

The neutral hook (plan "omnibase agnostic", step F2b): the entity and its unit of work.

Trasheable class

class Trasheable extends AbstractAttribute implements EntityExtensionInterface Trasheable.php:33

Marks an entity as soft-deletable: $em->remove() stamps the deletion field instead of issuing a DELETE, and TrashFilter hides the row from every read.

The behaviour itself lives in TrasheableSubscriber - this class only carries the configuration and knows how to find itself on a class.

## Why resolve() exists

ReflectionClass::getAttributes() is NOT inheriting, and AttributeReader caches per exact class name, so #[Trasheable] declared on Thread is invisible to Article, Gallery, ArticleCommentReply and every other subtype - which is to say invisible to all of the content this bundle actually manages. Property attributes do not have the problem (getProperties() walks parents), which is why Versionable needs no equivalent.

Making AttributeReader inherit class attributes wholesale is not an option: DiscriminatorEntry, Cache and Hierarchify are all class-level and all mean something different on a subclass. So the walk is done here, by the one attribute that wants it.

public string $deletedAt

Field carrying the deletion date.

public ?string $expiry

How long a trashed entity survives before the purge command may destroy it for good. Null means "use base.extension.empty_trash".

public bool $cascade

Whether the cascade-remove children of a trashed entity are kept.

Translations are cascade:remove, so leaving this off would empty an article of its title and content the moment it hit the trash - and restoring would hand back a blank row.

Trasheable::__construct()

public function __construct(string $field = "deletedAt", ?string $expiry = null, bool $cascade = true)

Trasheable::supports()

public function supports(string $target, ?string $targetValue = null, $object = null): bool
Throws

Exception

Trasheable::resolve()

public static function resolve(object|string $entityOrClass): ?self

Find the attribute on $entityOrClass or on any of its ancestors, nearest declaration first. Doctrine proxies are normalised by the caller passing a ClassMetadata (or its name) rather than get_class($proxy).

Trasheable::has()

public static function has(object|string $entityOrClass): bool

Uploader class

class Uploader extends AbstractAttribute implements ExtensionOptionInterface Uploader.php:30

Class Uploader package Base\Database\Attribute\Uploader

const SYMFONY_FILE = 'Symfony\Component\HttpFoundation\File\File'

The file an upload is handed as (plan "omnibase agnostique", step C3d): what the uploader takes is any \SplFileInfo - Symfony's File and UploadedFile are ones - and what it gives back is Symfony's HttpFoundation File where that component is installed (every Symfony application: an entity's getter typed ?File, a form's FileType get the class they always had), a plain \SplFileInfo elsewhere. The class is named by its string, so the uploader loads nothing of the framework.

Uploader::__construct()

public function __construct(?string $pool = "_", ?string $max_size = null, ?string $storage = null, bool $missable = false, bool $fetch = false, array $config = [], array $mime_types = [], array $formats = [])

Uploader::file()

public static function file(string $path): \SplFileInfo

Uploader::getFileMimeType()

public static function getFileMimeType(\SplFileInfo $file): ?string

The MIME type of a file: its own getMimeType() when it has one (Symfony's File), symfony/mime's guess otherwise.

Uploader::getUploadMaxFilesize()

public static function getUploadMaxFilesize(): int|float

The largest upload PHP accepts, in bytes: the smaller of post_max_size and upload_max_filesize, as Symfony's UploadedFile::getMaxFilesize() reads them (the same parsing: k, m, g, t suffixes; octal and hexadecimal; 0 for no limit).

Uploader::onOnFlush()

public function onOnFlush(Lifecycle\OnFlush $event, object $entity, ?string $property = null): void

The neutral hook (plan "omnibase agnostic", step F2b): a new entity reached by cascade gets its files stored now; an entity updated keeps what it was, for preUpdate.

Uploader::getStorage()

public function getStorage()

Uploader::getFormats()

public function getFormats()

Uploader::storage()

public function storage()

Uploader::formats()

public function formats()

Uploader::mimeTypes()

public function mimeTypes()

Uploader::isImage()

public function isImage()

Uploader::getPool()

public function getPool()

Uploader::getMissable()

public function getMissable()

Uploader::getDeclaringEntity()

public function getDeclaringEntity(mixed $entity, string $fieldName)
Throws

Exception

Uploader::getPath()

public function getPath(mixed $entity, string $fieldPath, ?string $uuid = null): ?string

Uploader::getPublic()

public static function getPublic($entity, $fieldName)
Throws

Exception

Uploader::getMimeTypes()

public static function getMimeTypes($entity, $fieldName): array

Uploader::getMaxFilesize()

public static function getMaxFilesize($entity, $fieldName): int

Uploader::materializeTemporaryFile()

public static function materializeTemporaryFile(string $index, callable $read): ?\SplFileInfo

Remote objects are copied into a tmpfile() so callers get a real file (see file()). One handle per (adapter, uuid), kept open for the request because closing a tmpfile() deletes it.

Until 2026-09-14 every call fwrite()'d the object into the SAME handle again without rewinding: a second get() of the same field within one request - an entity getter and FileType rendering the same upload, say - handed back a file holding the content twice over, i.e. a corrupt image or document, after paying for a second full download. An upload never changes under its uuid, so once materialized the copy is simply reused.

The table is request-scoped; see forgetTemporaryFiles().

Uploader::forgetTemporaryFiles()

public static function forgetTemporaryFiles(): void

Close every materialized copy; closing a tmpfile() deletes it.

Under FPM, or FrankenPHP classic mode, statics die with the request and this never mattered. A process that outlives the request - FrankenPHP worker mode, a messenger consumer - kept every handle open forever (file descriptors and /tmp space growing without bound), and because spl_object_hash() values are recycled once an adapter is freed, a later request could even be handed one object's bytes under another's key.

Called at the start of every main request and on kernel.reset, by Base\Subscriber\RequestScopedStateSubscriber.

Uploader::get()

public static function get($entity, string $fieldName)
Throws

FilesystemException

Uploader::supports()

public function supports(string $target, ?string $targetValue = null, $object = null): bool

Uploader::onPreFlush()

public function onPreFlush(Lifecycle\PreFlush $event, object $entity, ?string $property = null): void

The neutral hook (plan "omnibase agnostic", step F2b): the files given to the entity stored before the flush computes its changes; on a failure, those already stored deleted and the field emptied.

Throws

InvalidMimeTypeException

Throws

InvalidSizeException

Uploader::onPreUpdate()

public function onPreUpdate(Lifecycle\PreUpdate $event, ?string $property = null): void

The neutral hook (plan "omnibase agnostic", step F2b): the new files stored and the replaced ones deleted; on a failure, the field keeps its former files. The entity's changes computed again.

Throws

Exception

Uploader::onPostRemove()

public function onPostRemove(Lifecycle\PostRemove $event, ?string $property = null): void

The neutral hook (plan "omnibase agnostic", step F2b): the files of a removed entity deleted.

Vault class

class Vault extends AbstractAttribute Vault.php:20

public string $vault
public array $fields
public array $unique

Vault::__construct()

public function __construct(string $vault = "vault", array $fields = [], array $unique = [])

Vault::supports()

public function supports(string $target, ?string $targetValue = null, $object = null): bool
Throws

Exception

Vault::getKeyPath()

public function getKeyPath(?string $vault = null): string

Where the key pair of a vault is: Symfony's own secrets vault of that environment (bin/console secrets:generate-keys).

Vault::loadKeys()

public function loadKeys(?string $vault = null): array

The key pair of a vault: config/secrets/<vault>/<vault>.decrypt.private.php, else - for the running environment - the SYMFONY_DECRYPTION_SECRET variable (the same key, base64-encoded: how a production server is given it without the file).

Vault::getMarshaller()

public function getMarshaller(?string $vault = null): ?MarshallerInterface

Vault::allowsPlaintext()

public function allowsPlaintext(): bool

base.vault.allow_plaintext: the behaviour of before - without a key pair, a secured field is stored as it is. Off unless a site turns it on.

Vault::canSeal()

public function canSeal(?string $vault = null): bool

Whether a secured field can be stored in this vault: its key pair is there, or the site accepted clear text.

Vault::seal()

public function seal(?MarshallerInterface $marshaller, mixed $value, ?string $vault = null): string

Fails closed: without the vault's key pair the value is refused (VaultKeyNotFoundException), never stored in clear - unless the site said so (base.vault.allow_plaintext).

Throws

VaultKeyNotFoundException

Vault::reveal()

public function reveal(?MarshallerInterface $marshaller, ?string $value): mixed

Vault::onPreFlush()

public function onPreFlush(Lifecycle\PreFlush $event, object $entity, ?string $property = null): void

The neutral hook (plan "omnibase agnostic", step F2b): a secured field given a new plain value is written again, through the persistence's VaultBackend (the field holds the sealed value it read when the plain one equals it, so the persistence would see no change to write).

Vault::onPreUpdate()

public function onPreUpdate(Lifecycle\PreUpdate $event, ?string $property = null): void

The neutral hook (plan "omnibase agnostic", step F2b): the secured fields sealed before the update.

Vault::onPrePersist()

public function onPrePersist(Lifecycle\PrePersist $event, ?string $property = null): void

The neutral hook (plan "omnibase agnostic", step F2b): the secured fields sealed before the insertion.

Vault::sealFields()

public function sealFields(object $entity): void

Each secured field of the entity sealed in its vault, the sealed and the plain value kept in its vault bag (formerly preLifecycleEvent(), which took Doctrine's event and metadata it did not read).

Vault::onPostFlush()

public function onPostFlush(Lifecycle\PostFlush $event, object $entity, ?string $property = null): void

The neutral hook (plan "omnibase agnostic", step F2b): the secured fields revealed after the flush.

Vault::onPostLoad()

public function onPostLoad(Lifecycle\PostLoad $event, ?string $property = null): void

The neutral hook (plan "omnibase agnostic", step F2b): the secured fields revealed once read.

Vault::revealFields()

public function revealFields(object $entity): void

Each sealed field of the entity revealed, the sealed and the plain value kept in its vault bag (formerly postLifecycleEvent(), which took Doctrine's event and metadata it did not read).

Versionable class

class Versionable extends AbstractAttribute implements EntityExtensionInterface Versionable.php:24

Marks a property as worth remembering: every flush that changes it appends the old value to the entity's revision history (see VersionableSubscriber, which writes one Revision per entity per flush - not one per field).

Pure metadata, deliberately: the subscriber needs to see ALL of an entity's versioned fields at once to write a single coherent revision, which a per-property lifecycle hook cannot do.

Unlike Trasheable this needs no hierarchy walk - AttributeReader builds property attributes from ReflectionClass::getProperties(), which does include inherited properties, so #[Versionable] on Thread::$slug is seen on Article.

public bool $restorable

Whether the history badge offers to restore this field, or only to read it. Fields whose form widget has no value setter are shown read-only rather than given a button that silently does nothing.

public array $ignore

Top-level keys ignored when deciding whether a JSON-valued field changed. The stored diff still holds the real values - this only governs equality.

EditorJS is why this exists: its payload carries a "time" stamped at save, so opening an article and saving it again without touching a word yields a value that differs from the previous one in that field alone. Left unfiltered, every save would append a ~28 KB revision recording nothing, and five of those would be all the history an article ever had.

Versionable::__construct()

public function __construct(bool $restorable = true, array $ignore = [])

Versionable::comparable()

public function comparable(mixed $value): mixed

The comparable form of a value: same value, minus the volatile keys.

A value that is not a JSON object is returned untouched.

Versionable::supports()

public function supports(string $target, ?string $targetValue = null, $object = null): bool

Versionable::resolve()

public static function resolve(object|string $entityOrClass): array

Versioned property names for a class, mapped to their attribute.

Versionable::anchor()

public static function anchor(object $entity): array

Where an entity's revisions live, and the prefix its field names carry there.

A translation is not versioned in its own right: its history belongs to the translatable it translates, under a locale-prefixed key. Shared by the subscriber that writes revisions and the form extension that reads them back, so the two can never disagree about the key.

Versionable::has()

public static function has(object|string $entityOrClass, ?string $property = null): bool

Base\Database\Attribute\Backend

Backends class

final class Backends Backends.php:25

The persistence's part of each behaviour, by unit of work (plan "omnibase agnostic", step F2b).

A behaviour attribute answers omnisense/omnibridge's neutral lifecycle hooks with the entity and its unit of work. What only a given persistence can do (Doctrine's forced update, its scheduled writes, its schema, its second-level cache) is asked of a small interface of this namespace - VaultBackend, SlugifyBackend, CacheBackend -, implemented once per persistence and registered here for that persistence's UnitOfWork class. Doctrine's are in Base\Bridge\Doctrine\Behaviour (they move to omnibridge/doctrine at step F3, an Eloquent version comes with omnibridge/eloquent at F7).

One instance of a backend per unit of work, made on first use from the unit of work itself (the implementation's constructor takes it), so that two entity managers never share one.

Backends::register()

public static function register(string $unitOfWork, string $behaviour, string|\Closure $backend): void
$unitOfWork

the persistence's UnitOfWork class (a subclass matches too)

$behaviour

the backend interface (VaultBackend::class...)

$backend

its implementation, built with the unit of work

Backends::has()

public static function has(UnitOfWork $unitOfWork, string $behaviour): bool

Backends::of()

public static function of(UnitOfWork $unitOfWork, string $behaviour): object
Throws

UnsupportedBehaviourException when the persistence registered none

CacheBackend interface

interface CacheBackend CacheBackend.php:13

#[Cache]'s part of the persistence (plan "omnibase agnostic", step F2b): the cache that keeps entities and their associations between requests (Doctrine's second-level cache). A persistence without such a cache implements it as nothing to do.

CacheBackend::evict()

public function evict(Cache $cache, object $entity, ?string $property = null): void

What the cache keeps of the entity dropped, so the next read goes to the database: with a property, that association of the entity (its collection, or the entity for a to-one side); without, every association of it whose target is cached too.

OrderColumnBackend interface

interface OrderColumnBackend OrderColumnBackend.php:12

#[OrderColumn]'s part of the persistence (plan "omnibase agnostic", step F2c): a to-many association the persistence loads lazily keeps its stored positions until it is first read, instead of being loaded at every entity loaded to be sorted. Doctrine: the PersistentCollection's inner collection swapped for an OrderedArrayCollection. A persistence without lazy collections answers false, and the association is sorted at once.

OrderColumnBackend::orderLazily()

public function orderLazily(object $entity, mixed $collection, array $positions): bool

Whether the persistence took the ordering of that collection over (it sorts itself when loaded).

$positions

the stored order (identifiers or keys)

SlugifyBackend interface

interface SlugifyBackend SlugifyBackend.php:12

#[Slugify]'s part of the persistence (plan "omnibase agnostic", step F2b): what the running flush is about to write, so that two new entities of the same flush do not get the same slug, and whether the database still holds a unique index on the slug's column alone (per-type slugs wait for its migration).

SlugifyBackend::pendingWrites()

public function pendingWrites(): array

The entities the running flush inserts, then those it updates, in the order it writes them.

SlugifyBackend::uniqueAlone()

public function uniqueAlone(string $class, string $property): bool

Whether the table of that class holds a unique index (not the primary key) on the property's column alone.

VaultBackend interface

interface VaultBackend VaultBackend.php:12

#[Vault]'s part of the persistence (plan "omnibase agnostic", step F2b): an entity whose secured field was given a new plain value is written again, though the persistence sees no change in it (the field still holds the value it read, the new one is sealed at the update). Doctrine: the unit of work's scheduleForUpdate().

VaultBackend::scheduleUpdate()

public function scheduleUpdate(object $entity): void

The entity updated at the running flush, whatever its change set says.

Base\Database\Attribute\Extension

ExtensionHookInterface interface

interface ExtensionHookInterface extends EntityExtensionInterface ExtensionHookInterface.php:7

ExtensionHookInterface::getProperties()

public function getProperties(): array

Returns the properties of the extension.

ExtensionInlineInterface interface

interface ExtensionInlineInterface extends EntityExtensionInterface ExtensionInlineInterface.php:7

ExtensionMetadataInterface interface

interface ExtensionMetadataInterface extends EntityExtensionInterface ExtensionMetadataInterface.php:7

ExtensionMetadataInterface::payload()

public function payload(string $action, string $className, array $properties, object $entity): array

ExtensionMetadataInterface::get()

public static function get(): array

ExtensionMetadataInterface::has()

public static function has(string $className, ?string $property = null): bool

ExtensionOptionInterface interface

interface ExtensionOptionInterface extends EntityExtensionInterface ExtensionOptionInterface.php:8

ExtensionOptionInterface::supports()

public function supports(string $target, ?string $targetValue = null, mixed $object = null): bool

ExtensionOptionInterface::loadClassMetadata()

public function loadClassMetadata(ClassMetadata $classMetadata, string $target, ?string $targetValue = null): void

Base\Database\Backend

BulkDeletes interface

interface BulkDeletes BulkDeletes.php:11

Rows deleted by criteria in one statement, their entities never read (plan "omnibase agnostic", step F2e): what is recorded about an entity destroyed for good (its revisions, its trash entry's siblings). Doctrine's is a DQL DELETE; registered per unit of work in Base\Database\Attribute\Backend\Backends.

BulkDeletes::deleteWhere()

public function deleteWhere(string $class, array $criteria): int
$class

the entity class (its subclasses' rows too, as the persistence maps them)

$criteria

field => value, combined with And

Returns

the rows deleted

ColumnTypes interface

interface ColumnTypes ColumnTypes.php:14

What a persistence knows of its column types that the core's code asks (plan "omnibase agnostic", step F5c, item 3): whether a field of a type holds a PHP array, which EntityHydrator gives an empty one by default.

Doctrine's answers by its DBAL types (a JsonType, a set enumeration); registered per unit of work in Base\Database\Attribute\Backend\Backends. A persistence registering none is read by the neutral rule: json, or an enumeration that is a SetType (EntityHydrator::holdsArray()).

ColumnTypes::isArray()

public function isArray(string $type): bool

Whether a field of that type (its name, as the shape gives it) holds a PHP array.

ConditionalUpdates interface

interface ConditionalUpdates ConditionalUpdates.php:12

One field of an entity's row written only if it still holds a value, in a single statement (plan "omnibase agnostic", step F2d): of two requests claiming the same sign-in link at once, one wins. Doctrine's is a DQL UPDATE ... WHERE id = :id AND field = :from; registered per unit of work in Base\Database\Attribute\Backend\Backends.

ConditionalUpdates::compareAndSet()

public function compareAndSet(object $entity, string $field, mixed $from, mixed $to): bool

Sets the field of the entity's row to $to where it is $from; the entity itself is not changed.

Returns

whether the row was written (false: another wrote it first, or it is gone)

EntityCache interface

interface EntityCache EntityCache.php:12

The cache a persistence keeps of entities between requests (plan "omnibase agnostic", step F2d): what is evicted when a row is written behind it.

Doctrine's is its second-level cache, a persistence with none answers nothing to evict; registered per unit of work in Base\Database\Attribute\Backend\Backends.

EntityCache::enabled()

public function enabled(): bool

Whether the persistence keeps such a cache (Doctrine: the second-level cache is enabled).

EntityCache::evict()

public function evict(string $class, mixed $id): void

The entity of that class and identifier forgotten by the cache.

EntityCache::evictClass()

public function evictClass(string $class): void

Every entity of that class forgotten by the cache.

RowLocks interface

interface RowLocks RowLocks.php:12

An entity's row locked for writing while some work runs, in a transaction (plan "omnibase agnostic", step F2d): the work sees no concurrent write of that row - a double click on "like" makes one Like, not two. Doctrine's is a pessimistic write lock (SELECT ... FOR UPDATE); registered per unit of work in Base\Database\Attribute\Backend\Backends.

RowLocks::locked()

public function locked(object $entity, callable $work): mixed

Begins a transaction, locks the entity's row, runs the work and commits; rolls back and throws again when the work throws. The work flushes what it writes itself.

Base\Database\Common\Collections

OrderedArrayCollection class

class OrderedArrayCollection extends ArrayCollection OrderedArrayCollection.php:13

OrderedArrayCollection::__construct()

public function __construct(Collection|array $array = [], array $positions = [])

OrderedArrayCollection::loadedBy()

public function loadedBy(AbstractLazyCollection $collection): static

The lazy collection that fills this one (OrderColumn::postLoad(): the PersistentCollection of the association, not loaded yet). Until it is loaded the positions are kept: Doctrine reads this collection while it loads it (the entries added before, then the snapshot), and sorting then would spend the positions on what is not all there yet. Kept in a WeakMap, not a property: this collection is serialized with its entity (a session's user) as before, and nothing holds the lazy one.

OrderedArrayCollection::isLoaded()

public function isLoaded(): bool

Whether the entries are all there: no lazy collection fills this one, or it has been loaded.

OrderedArrayCollection::getPositions()

public function getPositions()

OrderedArrayCollection::reorder()

public function reorder()

OrderedArrayCollection::toArray()

public function toArray(): array

OrderedArrayCollection::first()

public function first(): mixed

{@inheritDoc}

OrderedArrayCollection::last()

public function last(): mixed

{@inheritDoc}

OrderedArrayCollection::key()

public function key(): int|string|null

{@inheritDoc}

OrderedArrayCollection::next()

public function next(): mixed

{@inheritDoc}

OrderedArrayCollection::current()

public function current(): mixed

{@inheritDoc}

OrderedArrayCollection::offsetExists()

public function offsetExists(mixed $offset): bool

{@inheritDoc}

OrderedArrayCollection::offsetGet()

public function offsetGet(mixed $offset): mixed

{@inheritDoc}

OrderedArrayCollection::offsetSet()

public function offsetSet(mixed $offset, mixed $value): void

{@inheritDoc}

OrderedArrayCollection::offsetUnset()

public function offsetUnset(mixed $offset): void

{@inheritDoc}

OrderedArrayCollection::indexOf()

public function indexOf($element): string|int|false

{@inheritDoc}

OrderedArrayCollection::get()

public function get(string|int $key): mixed

{@inheritDoc}

OrderedArrayCollection::getKeys()

public function getKeys(): array

{@inheritDoc}

OrderedArrayCollection::getValues()

public function getValues(): array

{@inheritDoc}

OrderedArrayCollection::set()

public function set(string|int $key, mixed $value): void

OrderedArrayCollection::getIterator()

public function getIterator(): Traversable

OrderedArrayCollection::map()

public function map(Closure $func): static

OrderedArrayCollection::reduce()

public function reduce(Closure $func, $initial = null): mixed

OrderedArrayCollection::filter()

public function filter(Closure $p): static

OrderedArrayCollection::findFirst()

public function findFirst(Closure $p): mixed

OrderedArrayCollection::forAll()

public function forAll(Closure $p): bool

OrderedArrayCollection::partition()

public function partition(Closure $p): array

OrderedArrayCollection::slice()

public function slice(int $offset, int|null $length = null): array

OrderedArrayCollection::matching()

public function matching(Criteria $criteria): Collection&Selectable

Collection&Selectable satisfies both doctrine/collections majors: 2.x declares ReadableCollection&Selectable here (Collection extends ReadableCollection), 3.x narrowed ArrayCollection::matching() to Collection - and the old ReadableCollection&Selectable is not a subtype of that, a compile error that took the whole kernel down.

Base\Database\Entity

EntityExtension class

class EntityExtension EntityExtension.php:5

const TARGET_CLASS = "class"
const TARGET_METHOD = "method"
const TARGET_PROPERTY = "property"
const ACTION_CREATE = 'create'
const ACTION_UPDATE = 'update'
const ACTION_REMOVE = 'remove'

EntityExtension::getExtensions()

public function getExtensions(): array

EntityExtension::addExtension()

public function addExtension(EntityExtensionInterface $extension): self

EntityExtensionInterface interface

interface EntityExtensionInterface EntityExtensionInterface.php:5

EntityHydrator class

class EntityHydrator implements EntityHydratorInterface EntityHydrator.php:50

An entity filled from data, or turned into data, and an entity rebuilt as it was read (plan "omnibase agnostic", step F5c, item 3: on omnisense/omnibridge's UnitOfWork and the entities' shapes, no ORM's metadata). What it reads of the mapping is the entity's EntityShape (fields, their types and nullability, associations, their kind, side, target and mappedBy, the identifier) and its aliases (EntityFields); what it asks of the persistence goes through the unit of work (references), its repositories (UnitOfWorks::repositories(): an association by id, uuid or slug), its Snapshots (the original values) and its ColumnTypes where it registers one (which types hold an array).

Doctrine's entity manager and ClassMetadataManipulator are still accepted in place of the unit of work and the shapes, deprecated until 6.0 (the entity manager made a unit of work by UnitOfWorks::of(), the manipulator's shapes taken).

const HYDRATE_BY_FIELD = 1
const HYDRATE_BY_COLUMN = 2
const DEFAULT_AGGREGATE = 0b0

Aggregate methods: by default, it is "object properties" by "deep copy" method without fallback, but initializing properties

const CLASS_METHODS = 0b1
const OBJECT_PROPERTIES = 0b10
const PREVENT_ASSOCIATIONS = 0b100
const ARRAY_OBJECT = 0b1000
const DEEPCOPY = 0b10000
const CONSTRUCT = 0b100000
const INITIALIZE = 0b1000000
const IGNORE_NULLS = 0b10000000
const AUTOTYPE = 0b100000000
const OBJECT_INHERITED = 0b1000000000
const FETCH_ASSOCIATIONS = 0b10000000000

EntityHydrator::__construct()

public function __construct(UnitOfWork|EntityManagerInterface $unitOfWork, EntityShapes|ClassMetadataManipulator|null $shapes = null)
$unitOfWork

the entity manager deprecated until 6.0

$shapes

the unit of work's persistence's by default (UnitOfWorks::shapes()); the manipulator deprecated until 6.0

EntityHydrator::getUnitOfWork()

public function getUnitOfWork(): UnitOfWork

EntityHydrator::getShapes()

public function getShapes(): EntityShapes

EntityHydrator::hydrate()

public function hydrate(mixed $entity, null|array|object $data = [], array $fieldExceptions = [], int $aggregateModel = self::DEFAULT_AGGREGATE, ...$constructArguments): mixed

EntityHydrator::dehydrate()

public function dehydrate(mixed $entity, array $fieldExceptions = [], int $aggregateModel = self::CLASS_METHODS | self::OBJECT_PROPERTIES): ?array

EntityHydrator::fromProxy()

public function fromProxy(object $proxy): object

The entity behind a proxy (or a lazy object), read from the database: refreshed through the unit of work, which initialises it.

EntityHydrator::toArray()

public function toArray(object|array $objectOrArray, bool $deepcast = false): array

EntityHydrator::clone()

public function clone(object $entity, int $aggregateModel = self::DEEPCOPY)

EntityHydrator::setHydrateAssociationReferences()

public function setHydrateAssociationReferences(bool $hydrateAssociationReferences)

EntityHydrator::getEntityFromData()

public function getEntityFromData($className, $data): ?object
Throws

Exception

EntityHydrator::getOriginalEntity()

public function getOriginalEntity($eventOrEntity)

The entity as it was read or last flushed (its original values hydrated into a new one): of an entity, of a lifecycle event's (omnisense/omnibridge's, or Doctrine's - deprecated until 6.0), a PreUpdate's changes read as the values before.

Throws

Exception

EntityHydrator::getOriginalEntityData()

public function getOriginalEntityData($eventOrEntity)

The original values of an entity, or of a lifecycle event's: its identifier, what the unit of work's Snapshots remember, and before a PreUpdate the values its changes replace.

Throws

UnsupportedBehaviourException when the persistence keeps no Snapshots

EntityHydratorInterface interface

interface EntityHydratorInterface EntityHydratorInterface.php:5

EntityHydratorInterface::hydrate()

public function hydrate(mixed $entity, null|array|object $data = [], array $fieldExceptions = [], int $aggregateModel = EntityHydrator::DEFAULT_AGGREGATE, ...$constructArguments): mixed

EntityHydratorInterface::dehydrate()

public function dehydrate(mixed $entity, array $fieldExceptions = []): ?array

EntityHydratorInterface::getOriginalEntity()

public function getOriginalEntity($eventOrEntity)

EntityValues class

final class EntityValues EntityValues.php:32

An entity's values as the behaviours read and write them, on the shapes of the unit of work's persistence (plan "omnibase agnostic", step F7c): what omnibridge/doctrine's ClassMetadataManipulator does with Doctrine's metadata (getFieldValue(), setFieldValue(), getPropertyValue(), setPropertyValue()), with omnibase's EntityShapes in its place, so that the same calls give the same values whichever persistence keeps the entity.

  • A mapped property (a field or an association of the shape) is read and written as it is held, without its getter nor its setter and without loading a lazy object to write it - Doctrine's property accessors -, a field with an enumeration type as its backing value; any other property through Symfony's property accessor.
  • A path (translations.title, parent.slug) is followed through the values, translations of a translatable entity being its translations; a key (images[0]) picks a list's or a collection's member.
  • A lazy object is loaded before it is read (PHP 8.4's lazy ghosts, and Doctrine's proxies by name).

AbstractAttribute's helpers use it when they are given the unit of work their hook's event carries (Slugify, Uploader); without one they keep omnibridge/doctrine's ClassMetadataManipulator, deprecated until 6.0.

EntityValues::__construct()

public function __construct(readonly EntityShapes $shapes)

EntityValues::of()

public static function of(UnitOfWork $unitOfWork): self

The values of the entities of that unit of work, on its persistence's shapes (one per unit of work).

EntityValues::shapes()

public function shapes(): EntityShapes

EntityValues::isEntity()

public function isEntity(object|string $entityOrClass): bool

Whether the entity's class is one the persistence maps.

EntityValues::isMapped()

public function isMapped(object|string $entityOrClass, string $property): bool

Whether the property is a field or an association of the entity's class.

EntityValues::get()

public function get(mixed $entity, string|array $path): mixed

The value at the path (ClassMetadataManipulator::getFieldValue()): the entity itself for an empty path, null for a null entity or one the persistence does not map.

Throws

Exception when the path cannot be followed

EntityValues::set()

public function set(object $entity, string $field, mixed $value): void

The field written as the persistence writes it (ClassMetadataManipulator::setFieldValue()): no setter, no lazy load; an enumeration field given its backing value takes the case, a non-nullable typed property given null is unset. A property the persistence does not map is written the same way.

EntityValues::property()

public function property(?object $entity, string $property): mixed

A property read through its getter (ClassMetadataManipulator::getPropertyValue()): a column's name is read as its field's; null for a property the entity has not.

EntityValues::setProperty()

public function setProperty(object $entity, string $property, mixed $value): void

A property written through its setter (ClassMetadataManipulator::setPropertyValue()).

EntityValues::declaringClass()

public function declaringClass(object|string $entityOrClass, string $property): ?string

The class declaring the property in the entity's hierarchy, as the shape says or as the class does.

EntityValues::fieldName()

public function fieldName(object|string $entityOrClass, string $name): ?string

The field (or association) a name is of: an alias's property (#[Alias]), a column's field, an association by its name, the field itself - ClassMetadataManipulator::getFieldName()'s answer, from the shape: null for a name the entity does not map.

EntityValues::declaringEntity()

public function declaringEntity(object|string $entityOrClass, string $fieldPath): ?string

The entity class whose folder a field's files go to (Uploader's path): the class declaring the field in the hierarchy, the target of a path's first association (gallery.photos), else the entity's own class - ClassMetadataManipulator::getDeclaringEntity()'s answer, from the shape.

EntityValues::load()

public static function load(object $entity): void

A lazy object loaded before it is read: PHP 8.4's lazy ghosts and proxies, and Doctrine's proxies (by name).

Base\Database\Entity\AggregateHydrator

PopulableInterface interface

interface PopulableInterface PopulableInterface.php:5

PopulableInterface::populate()

public function populate(array $data = [])

SerializableInterface interface

interface SerializableInterface SerializableInterface.php:5

SerializableInterface::exchangeArray()

public function exchangeArray(array|object $array): array

SerializableInterface::getArrayCopy()

public function getArrayCopy(): array

Base\Database\Entity\Extension

AliasInterface interface

interface AliasInterface AliasInterface.php:5

AliasInterface::__call()

public function __call(string $method, array $args): mixed

AliasInterface::__isset()

public function __isset(string $property): bool

AliasInterface::__get()

public function __get(string $property): mixed

AliasInterface::__set()

public function __set(string $property, mixed $value): void

AliasTrait trait

trait AliasTrait AliasTrait.php:13

AliasTrait::__get()

public function __get(string $name): mixed

------------------- Magic Accessors -------------------

AliasTrait::__set()

public function __set(string $name, mixed $value): void

AliasTrait::__isset()

public function __isset(string $name): bool

AliasTrait::__call()

public function __call(string $name, array $arguments): mixed

TranslatableAliasTrait trait

trait TranslatableAliasTrait TranslatableAliasTrait.php:7

TranslatableAliasTrait::__call()

public function __call(string $method, array $arguments): mixed

TranslatableAliasTrait::__isset()

public function __isset(string $property): bool

TranslatableAliasTrait::__get()

public function __get(string $property): mixed

TranslatableAliasTrait::__set()

public function __set(string $property, mixed $value): void

TranslatableInterface interface

interface TranslatableInterface TranslatableInterface.php:11

Each implementation has, by TranslatableTrait, the class of its translations: the schema (Base\Database\Schema\TranslationRule) asks it of the class itself.

TranslatableInterface::translate()

public function translate(?string $locale)

TranslatableInterface::getTranslations()

public function getTranslations()

TranslatableInterface::clearTranslations()

public function clearTranslations()

TranslatableInterface::addTranslation()

public function addTranslation(TranslationInterface $translation)

TranslatableInterface::removeTranslation()

public function removeTranslation(TranslationInterface $translation)

TranslatableTrait trait

trait TranslatableTrait TranslatableTrait.php:18

TranslatableTrait::getEntityFqcn()

public static function getEntityFqcn(): string

TranslatableTrait::getTranslationEntityClass()

public static function getTranslationEntityClass(bool $withInheritance = true, bool $selfClass = false): ?string

TranslatableTrait::getTranslations()

public function getTranslations()

TranslatableTrait::commitPendingTranslations()

public function commitPendingTranslations()

Moves into the collection the translations translate() handed out that have since been written in; the empty ones stay aside. Called by getTranslations() and translate(), and before each flush by IntlSubscriber::preFlush, so a value written through translate($locale)->setX() is persisted like before.

TranslatableTrait::removeTranslation()

public function removeTranslation(TranslationInterface $translation)

TranslatableTrait::clearTranslations()

public function clearTranslations()

TranslatableTrait::addTranslation()

public function addTranslation(TranslationInterface $translation)

TranslatableTrait::translate()

public function translate(?string $locale = null)

The translation to read or write in a language.

  • translate($locale) is that locale's translation. When the entity has none, a new one for that locale - which the entity holds aside, out of its collection, until a value is written in it: a mere read (a getter asking about a language nothing was written in) creates nothing, and a write (translate('de')->setTitle(...)) is kept as it always was (commitPendingTranslations()).
  • translate() (no locale) is the one to show on the current page: the page's language when something is written in it, else the same language in another region, else the default locale's, else the first available locale's, else any written one; only when nothing is written at all, a new one for the page's language, as above.

A read in a language used to add an empty translation for it to the collection, and a later translate() on a page in that language found it: the default language was lost (Attribute::resolve(null) after resolve('ja') gave null).

Throws

Exception

TranslatableTrait::__call()

public function __call(string $method, array $arguments): mixed
Throws

Exception

TranslatableTrait::__set()

public function __set(string $property, mixed $value): void
Throws

Exception

TranslatableTrait::__get()

public function __get(string $property): mixed
Throws

Exception

TranslatableTrait::__isset()

public function __isset(string $property): bool

TranslationInterface interface

interface TranslationInterface TranslationInterface.php:11

Each implementation has, by TranslationTrait, the class it translates: the schema (Base\Database\Schema\TranslationRule) asks it of the class itself.

TranslationInterface::getTranslatable()

public function getTranslatable(): ?TranslatableInterface

TranslationInterface::setTranslatable()

public function setTranslatable(?TranslatableInterface $translatable)

TranslationInterface::getLocale()

public function getLocale(): ?string

TranslationInterface::setLocale()

public function setLocale(string $locale)

TranslationInterface::isEmpty()

public function isEmpty(): bool

TranslationTrait trait

trait TranslationTrait TranslationTrait.php:11

TranslationTrait::getId()

public function getId(): ?int

TranslationTrait::getEntityFqcn()

public static function getEntityFqcn(): string

Translatable related methods

TranslationTrait::getTranslatableEntityClass()

public static function getTranslatableEntityClass(): string

TranslationTrait::getTranslatable()

public function getTranslatable(): ?TranslatableInterface

TranslationTrait::setTranslatable()

public function setTranslatable(?TranslatableInterface $translatable)

TranslationTrait::getLocale()

public function getLocale(): ?string

TranslationTrait::setLocale()

public function setLocale(string $locale)

TranslationTrait::isEmpty()

public function isEmpty(array $addIgnoredVars = [], ?callable $addConditions = null): bool

TrasheableInterface interface

interface TrasheableInterface TrasheableInterface.php:5

TrasheableTrait trait

trait TrasheableTrait TrasheableTrait.php:9

TrasheableTrait::isDeleted()

public function isDeleted()

TrasheableTrait::getDeletedAt()

public function getDeletedAt(): ?DateTimeInterface

TrasheableTrait::setDeletedAt()

public function setDeletedAt(?DateTimeInterface $deletedAt): self

TrasheableTrait::restore()

public function restore(): self

Take the entity back out of the trash. Nullable is the whole point of the widened setter above: without it there was no way, in code, to undo a soft deletion.

VaultInterface interface

interface VaultInterface VaultInterface.php:5

VaultTrait trait

trait VaultTrait VaultTrait.php:9

VaultTrait::getVault()

public function getVault(): ?string

VaultTrait::setVault()

public function setVault(?string $vault): self

VaultTrait::getPlainVaultBag()

public function getPlainVaultBag(mixed $key): mixed

VaultTrait::getSealedVaultBag()

public function getSealedVaultBag(string $key): ?string

VaultTrait::setVaultBag()

public function setVaultBag(?string $key, string $sealedValue, mixed $plainValue): self

VaultTrait::isSecured()

public function isSecured(): bool

VaultTrait::getSecure()

public function getSecure(): bool

VaultTrait::setSecure()

public function setSecure(bool $secure)

Base\Database\Entity\Extension\Type

EntityHookInterface interface

interface EntityHookInterface EntityHookInterface.php:5

EntityInlineInterface interface

interface EntityInlineInterface EntityInlineInterface.php:5

EntityInlineInterface::getProperties()

public function getProperties(): array

EntityMetadataInterface interface

interface EntityMetadataInterface EntityMetadataInterface.php:5

EntityOptionInterface interface

interface EntityOptionInterface EntityOptionInterface.php:5

EntityOptionInterface::supports()

public function supports(string $target, ?string $targetValue = null, mixed $object = null): bool

Base\Database\Lifecycle

RevisionRecorder class

final class RevisionRecorder RevisionRecorder.php:23

What a revision records, whatever persistence writes it (plan "omnibase agnostic", step F2b): the diff of an entity's #[Versionable] properties, their values in a comparable form, and the revision entry - not twice for the same diff in a row.

The persistence's part - which entities the flush updates, the to-many collections' snapshots, the revision inserted in the running flush, the oldest ones trimmed - is Base\EntitySubscriber\VersionableSubscriber's on Doctrine (moves to omnibridge/doctrine at step F3).

RevisionRecorder::__construct()

public function __construct(readonly UnitOfWork $unitOfWork)

RevisionRecorder::diff()

public function diff(array $versioned, array $changes, array $collections, string $prefix): array

The versioned properties' diff, keyed by the anchor's prefix and the property.

$changes

the entity's field and to-one changes

$collections

a changed to-many property => [its snapshot, its items]

RevisionRecorder::revision()

public function revision(string $class, object $target, array $diff): ?Revision

The revision of $target for that diff, or null when it repeats the previous one recorded for the same entity (compared with the previous diff only: A→B, B→A, A→B in one request stays three).

The persistence sets its creation date AFTER persisting it (see TrashRecorder::entry()).

RevisionRecorder::normalize()

public function normalize(mixed $value): mixed

A value as a revision stores it: scalars, dates as ATOM, enums by value, entities by identifier and label.

SettingsInvalidation class

final class SettingsInvalidation SettingsInvalidation.php:15

The SettingBag's snapshot emptied at every Setting or SettingIntl written, whatever writes it (the admin CRUD's plain flush included), on omnisense/omnibridge's neutral lifecycle events (plan "omnibase agnostic", step F2b). Base\EntitySubscriber\SettingSubscriber relays Doctrine's to it.

SettingsInvalidation::__construct()

public function __construct(readonly \Closure $settingBag)
$settingBag

lazy: see SettingSubscriber

SettingsInvalidation::onPostPersist()

public function onPostPersist(Lifecycle\PostPersist $event): void

SettingsInvalidation::onPostUpdate()

public function onPostUpdate(Lifecycle\PostUpdate $event): void

SettingsInvalidation::onPostRemove()

public function onPostRemove(Lifecycle\PostRemove $event): void

ThreadParticipants class

final class ThreadParticipants ThreadParticipants.php:27

Who takes part in a thread besides its owners, on omnisense/omnibridge's neutral lifecycle events (plan "omnibase agnostic"): the followers of a reply and the users its text mentions.

  • A reply (a thread with a parent) is followed by its parent's owners, from its creation (PrePersist) and when it is moved under another parent (follow(), which the persistence calls at its flush: a collection changed while an update is written is not written).
  • The users a thread's text mentions (<mention> tags, in every translation) each have one Mention, kept in step at every flush that writes the text (OnFlush): a mention added to the text gets one, persisted in the running flush; one taken out of it loses its own, removed in the same flush. ThreadSubscriber::onPublishable() mails them at the thread's publication.

Base\EntitySubscriber\ThreadSubscriber relays Doctrine's events to it and lists the threads a flush writes the text of (the neutral OnFlush carries no list of entities).

ThreadParticipants::__construct()

public function __construct(readonly \Closure $mentionEnhancer)
$mentionEnhancer

lazy: Doctrine builds its listeners when the event manager initialises, and the enhancer's repositories read the mapping

ThreadParticipants::onPrePersist()

public function onPrePersist(Lifecycle\PrePersist $event): void

ThreadParticipants::onFlush()

public function onFlush(Lifecycle\OnFlush $event, iterable $threads): void

The mentions of the threads whose text this flush writes, made to match their text.

ThreadParticipants::follow()

public function follow(Thread $thread): bool

A reply followed by its parent's owners; whether it gained a follower.

ThreadParticipants::mentionees()

public function mentionees(Thread $thread): array

The users the thread's text mentions, in every translation (an editor's JSON read by its leaves).

TrashRecorder class

final class TrashRecorder TrashRecorder.php:20

What a soft delete is, whatever persistence cancels the deletion (plan "omnibase agnostic", step F2b): which removal becomes a trashing, and the trash entry the trash listing and the purge read.

The persistence's part - the deletion cancelled, the stamp written, what the removal cascaded to rescued, the second-level cache evicted - is Base\EntitySubscriber\TrasheableSubscriber's on Doctrine (moves to omnibridge/doctrine at step F3).

TrashRecorder::__construct()

public function __construct(string|int $emptyTrash = '+7 days')
$emptyTrash

base.extension.empty_trash: a relative date ("+7 days"), or a number of days

TrashRecorder::expiry()

public static function expiry(string|int|null $value, string $default = '+7 days'): string

An expiry as new DateTime() reads it: a bare number of days ("5", 5) becomes "+5 days", anything else is kept (a relative date, "+1 month").

The configuration's default was 5 once, and new DateTime("5") throws.

TrashRecorder::isPurge()

public function isPurge(mixed $deletedAt): bool

Whether removing a #[Trasheable] entity whose deletion field holds $deletedAt is its purge, deleted for real: it is in the trash already. That is the only escape hatch - emptying the trash and "delete permanently" both work by removing an already-trashed entity. Otherwise the removal becomes a trashing.

TrashRecorder::entry()

public function entry(object $entity, string $class, Trasheable $trasheable, DateTime $deletedAt): TrashBall

The trash entry of an entity trashed at $deletedAt. Its label is snapshotted rather than resolved at display time: the trash has to stay readable even for an entity whose __toString() depends on translations or on a parent that has since gone.

The persistence sets its creation date to $deletedAt AFTER persisting it: #[Timestamp(on: "create")]'s own prePersist would overwrite it, with a DateTime it memoised on a cached attribute instance.

Base\Database\Mapping

Completor class

class Completor Completor.php:11

What omnibase's attributes add to an entity class's mapping, as plain data (plan "omnibase agnostic", step E3): #[Alias]'s names (aliasNames, alias => property), #[Hierarchify]'s hierarchy (entityHierarchy, entityHierarchySeparator)... Completors::of() fills it from the class's attributes (their complete() hook), on no ORM. omnibridge/doctrine's ClassMetadataCompletor is this class under its former name.

Completor::__construct()

public function __construct(string $className, array $payload = [])

Completor::getName()

public function getName(): ?string

Completor::payload()

public function payload(): array
Returns

what the attributes wrote, by name

Completor::exists()

public function exists($name)

Completor::__get()

public function __get($name)

Completor::__set()

public function __set(string $name, mixed $value)

Completors class

final class Completors Completors.php:18

Each entity class's completor - what omnibase's attributes add to its mapping (#[Alias]'s names, #[Hierarchify]'s hierarchy) - read from the class itself, on no ORM (plan "omnibase agnostic", step E3). It was written by the attributes' loadClassMetadata() into Doctrine's metadata as Doctrine loaded it, then cached by omnibridge/doctrine's ClassMetadataManipulator: a manipulator made again over an empty cache (a second kernel in the same process, in eloquent mode) answered without the aliases until the cache was cleared. Here it is the attributes' complete() hook, run over the class's attributes as omnibase's AttributeReader gives them to the mapping - the class's own, its methods' and its properties' (its own and the inherited ones that are not private) -, once per class and process: the same answer whichever persistence maps the class, and Doctrine's manipulator answers from here too.

Completors::of()

public static function of(string|object $class): Completor

The completor of a class (an object's class), filled by its attributes' complete() hook.

Completors::payload()

public static function payload(string|object $class): array

What the completor of a class holds, its keys sorted, the values left unread (null) out: a snapshot's.

DescriptionShapes class

final class DescriptionShapes implements EntityShapes DescriptionShapes.php:13

The entities' shapes read from a Description (plan "omnibase agnostic", step F2c): Base\Database\Schema\ Describer's (built from the entities' folders without any ORM), or a JSON file's. Mapped superclasses and embeddables have a shape, and are no entities for has().

DescriptionShapes::__construct()

public function __construct(readonly Description $description)

DescriptionShapes::has()

public function has(string|object $class): bool

DescriptionShapes::classes()

public function classes(): array

The mapped entities' classes, those has() counts (step B1d: what a listing of the entities asks - the back office's pickable pages -, where it read Doctrine's metadata).

DescriptionShapes::shape()

public function shape(string|object $class): EntityShape

EntityFields class

final class EntityFields EntityFields.php:19

An entity's properties by the names the core's code gives them, on no ORM (plan "omnibase agnostic", step F5c, item 3): its fields and associations from its shape, and its aliases - a property bound to another by #[Alias] (Gallery's "galleries" to "children") -, read from the attributes. What ClassMetadataManipulator's getFieldNames(), getFieldName(), resolveFieldPath() and fetchEntityName() answered from Doctrine's metadata and its completor (the aliases Alias::loadClassMetadata() wrote there), for EntityHydrator.

The aliases are read as omnibase's attribute reader gives them to the mapping: the class's own #[Alias(column:, alias:)] attributes, and #[Alias(column:)] on each of its properties - its own and the inherited ones that are not private -, the property being the alias.

EntityFields::__construct()

public function __construct(readonly EntityShapes $shapes)

EntityFields::shapes()

public function shapes(): EntityShapes

EntityFields::aliases()

public static function aliases(string|object $class): array

The aliases of a class, alias => the property it is bound to.

EntityFields::names()

public function names(string|object $class): array

Every name of the class's properties, name => property: its aliases, its fields by their columns and its associations (ClassMetadataManipulator::getFieldNames(), Doctrine's fieldNames being column => field).

EntityFields::name()

public function name(string|object $class, string $name): ?string

The property a name designates (an alias resolved), null for none.

EntityFields::hasAssociation()

public function hasAssociation(string|object $class, ?string $name): bool

Whether the name (an alias of one included) is one of the class's associations.

EntityFields::resolve()

public function resolve(string|object $class, array|string $path): ?string

A path of names resolved to the properties it goes through ("parent.slug"), each alias replaced, a name the class lacks looked for in its parents; null when it leads nowhere (ClassMetadataManipulator::resolveFieldPath()).

EntityFields::target()

public function target(string $class, array|string $path): ?string

The class an association path leads to (ClassMetadataManipulator::fetchEntityName()), null for a field or nothing.

EntityFields::mapped()

public function mapped(string|object $class): bool

Whether the class has a shape (an entity, a mapped superclass, an embeddable).

EntityShape class

final class EntityShape EntityShape.php:18

What the core's code reads of an entity's mapping, on no ORM (plan "omnibase agnostic", step F2c): its class, root, identifier, fields and their types, associations and their kind, side and target, and its discriminator - one Omnibridge\Schema\Entity of the application's Description.

The behaviours and ClassMetadataManipulator ask it in place of Doctrine's ClassMetadata, through EntityShapes: built from a Description (DescriptionShapes), or from what the installed persistence resolved (Base\Bridge\Doctrine\DoctrineShapes, omnibridge/doctrine's MetadataDescription of each class - the same description, SchemaDescriptionTest proves it).

public readonly Entity $entity

EntityShape::__construct()

public function __construct(public readonly Entity $entity)

EntityShape::className()

public function className(): string

EntityShape::rootClass()

public function rootClass(): string

The root of its inheritance, itself without one.

EntityShape::parentClass()

public function parentClass(): ?string

EntityShape::table()

public function table(): ?string

EntityShape::identifier()

public function identifier(): array

EntityShape::primaryKey()

public function primaryKey(): ?string

The single identifier's property, null for a composite one or none.

EntityShape::fieldNames()

public function fieldNames(): array

EntityShape::hasField()

public function hasField(string $property): bool

EntityShape::fieldType()

public function fieldType(string $property): ?string

The field's column type by name ("string", "datetime", an enumeration's...), null for no field.

EntityShape::associationNames()

public function associationNames(): array

EntityShape::hasAssociation()

public function hasAssociation(string $property): bool

EntityShape::associationKind()

public function associationKind(string $property): ?string

Relation::ONE_TO_ONE, MANY_TO_ONE, ONE_TO_MANY or MANY_TO_MANY; null for no association.

EntityShape::targetClass()

public function targetClass(string $property): ?string

EntityShape::isToOne()

public function isToOne(string $property): bool

EntityShape::isToMany()

public function isToMany(string $property): bool

EntityShape::isOwningSide()

public function isOwningSide(string $property): bool

EntityShape::isInverseSide()

public function isInverseSide(string $property): bool

EntityShape::mappedBy()

public function mappedBy(string $property): ?string

EntityShape::inversedBy()

public function inversedBy(string $property): ?string

EntityShape::discriminatorColumn()

public function discriminatorColumn(): ?string

EntityShape::discriminatorMap()

public function discriminatorMap(): array
Returns

value => class

EntityShape::discriminatorValue()

public function discriminatorValue(): ?string

EntityShapes interface

interface EntityShapes EntityShapes.php:12

The entities' shapes (plan "omnibase agnostic", step F2c): from a Description (DescriptionShapes), or from the installed persistence (Base\Bridge\Doctrine\DoctrineShapes on Doctrine).

Both list the mapped entities' classes as well, classes(): list<string> (step B1d). Not declared here yet: an implementation written against this interface before would no longer load; it is at 6.0 (step S done).

EntityShapes::has()

public function has(string|object $class): bool

Whether the class (or the entity's, a proxy seen through) is a mapped entity.

EntityShapes::shape()

public function shape(string|object $class): EntityShape

The shape of a mapped class: an entity, or a mapped superclass or an embeddable (which has() does not count as entities).

Throws

OutOfBoundsException for a class that is not mapped

MetadataManipulator class

class MetadataManipulator extends AbstractLocalCache MetadataManipulator.php:33

What omnibase's AttributeReader and the attributes ask of the entities' mapping, read from the entities' shapes - the Description (Omnibridge\Schema) a persistence maps them with - and their completors, on no ORM (plan "omnibase agnostic", step E3). omnibridge/doctrine's ClassMetadataManipulator answered them from Doctrine's ClassMetadataFactory, so the reader, the behaviours on writes and the aliases (#[Alias]) needed doctrine/orm installed whatever the persistence; it extends this class now and keeps Doctrine's own (the mappings, the entity manager, the forms').

Built on a unit of work (the persistence's shapes, UnitOfWorks::shapes(), asked when first needed: the reader is made before any metadata may be loaded) or on the shapes themselves. The answers are those ClassMetadataManipulator gives on Doctrine's metadata, method by method (MetadataManipulatorTest compares them for every class of lesringostars and of the core's harness): - a class is an entity when it has a shape - an entity, a mapped superclass or an embeddable, as Doctrine's isTransient() said -, a proxy or a lazy object by its parent; - a name is an alias (its completor's aliasNames), a column's name or an association's (getFieldNames()); - an association's kind is Doctrine's number (ONE_TO_ONE 1, MANY_TO_ONE 2, ONE_TO_MANY 4, MANY_TO_MANY 8); - the values are read and written as Base\Database\Entity\EntityValues does. getDoctrineType() answers an enumeration's type only (an instance of the enumeration, as Doctrine's EnumTypeAdapter gave it back), null for any other: no DBAL type exists here.

const ASSOCIATION_KINDS = [Relation::ONE_TO_ONE => 1, Relation::MANY_TO_ONE => 2, Relation::ONE_TO_MANY => 4, Relation::MANY_TO_MANY => 8]

Doctrine's numbers of the association kinds (ClassMetadata::ONE_TO_ONE...), as getAssociationType() answers.

MetadataManipulator::__construct()

public function __construct(UnitOfWork|EntityShapes $source)

MetadataManipulator::getShapes()

public function getShapes(): EntityShapes

The entities' shapes this manipulator reads.

MetadataManipulator::getShape()

public function getShape(null|string|object $entityOrClass): ?EntityShape

The shape of an entity or an entity class, null for anything else.

MetadataManipulator::isEntity()

public function isEntity($entityOrClassOrMetadata): bool

MetadataManipulator::isEnumType()

public function isEnumType($entityOrClassOrMetadata): bool

MetadataManipulator::isSetType()

public function isSetType($entityOrClassOrMetadata): bool

MetadataManipulator::isNativeEnum()

public function isNativeEnum(mixed $class): bool

A PHP enum (backed or not), as opposed to omnibase's own EnumType / SetType column types.

MetadataManipulator::getEnumClass()

public function getEnumClass(null|string|object $entityOrClassOrMetadata, string $fieldName): ?string

The PHP enum a column holds, null for any other column.

MetadataManipulator::getDoctrineType()

public function getDoctrineType(?string $type)

An enumeration's column type: an instance of the enumeration (UserRole, a SetType...), as Doctrine's type registry gave it back; null for any other type.

MetadataManipulator::getPrimaryKey()

public function getPrimaryKey($entity)

The identifier's single field; refused for a composite identifier or none, as Doctrine's getSingleIdentifierFieldName().

MetadataManipulator::getDiscriminatorColumn()

public function getDiscriminatorColumn($entity): ?string

MetadataManipulator::getDiscriminatorValue()

public function getDiscriminatorValue($entity): ?string

MetadataManipulator::getDiscriminatorMap()

public function getDiscriminatorMap($entity): array

MetadataManipulator::getRootEntityName()

public function getRootEntityName($entity): ?string

MetadataManipulator::getFieldValue()

public function getFieldValue($entity, string|array $fieldPath): mixed

MetadataManipulator::setFieldValue()

public function setFieldValue($entity, string|array $fieldPath, $value)

MetadataManipulator::hasField()

public function hasField(null|string|object $entityOrClassOrMetadata, string $fieldName): bool

MetadataManipulator::hasProperty()

public function hasProperty(null|string|object $entityOrClassOrMetadata, string $fieldName): ?string

MetadataManipulator::getPropertyValue()

public function getPropertyValue($entity, string $property)

MetadataManipulator::setPropertyValue()

public function setPropertyValue($entity, string $property, $value)

MetadataManipulator::getDeclaringEntity()

public function getDeclaringEntity(null|string|object $entityOrClassOrMetadata, $fieldPath)
Returns

the entity class whose folder a field's files go to (Uploader's path)

MetadataManipulator::getTargetClass()

public function getTargetClass(null|string|object $entityOrClassOrMetadata, $fieldName)
Returns

an association's target, a field's enumeration (a PHP enum, an EnumType or a SetType)

MetadataManipulator::getTypeOfField()

public function getTypeOfField(null|string|object $entityOrClassOrMetadata, string $property)

A field's column type by its name; false where the class is no entity or the path goes through an association, as ClassMetadataManipulator answered (a dotted path read the association as a field, then nothing).

MetadataManipulator::fetchEntityName()

public function fetchEntityName(string $entityName, array|string $fieldPath): ?string

MetadataManipulator::isAlias()

public function isAlias(null|object|string $entityOrClassOrMetadata, array|string $fieldPath): bool

MetadataManipulator::getFieldName()

public function getFieldName(null|object|string $entityOrClassOrMetadata, array|string $fieldName): ?string

MetadataManipulator::getFieldNames()

public function getFieldNames(null|object|string $entityOrClassOrMetadata): ?array
Returns

every name of the class's properties, name => property

MetadataManipulator::resolveFieldPath()

public function resolveFieldPath(null|object|string $entityOrClassOrMetadata, array|string $fieldPath): ?string

MetadataManipulator::getAssociationTargetClass()

public function getAssociationTargetClass(null|string|object $entityOrClassOrMetadata, string $fieldName): string

MetadataManipulator::hasAssociation()

public function hasAssociation(null|string|object $entityOrClassOrMetadata, ?string $fieldName)

MetadataManipulator::hasRecursiveAssociation()

public function hasRecursiveAssociation(null|string|object $entityOrClassOrMetadata, ?string $fieldName)

MetadataManipulator::isOwningSide()

public function isOwningSide(null|string|object $entityOrClassOrMetadata, string $fieldName): bool

MetadataManipulator::isInverseSide()

public function isInverseSide(null|string|object $entityOrClassOrMetadata, string $fieldName): bool

MetadataManipulator::isToOneSide()

public function isToOneSide(null|string|object $entityOrClassOrMetadata, string $fieldName): bool

MetadataManipulator::isToManySide()

public function isToManySide(null|string|object $entityOrClassOrMetadata, string $fieldName): bool

MetadataManipulator::isManyToSide()

public function isManyToSide(null|string|object $entityOrClassOrMetadata, string $fieldName): bool

MetadataManipulator::isOneToSide()

public function isOneToSide(null|string|object $entityOrClassOrMetadata, string $fieldName): bool

MetadataManipulator::isManyToMany()

public function isManyToMany(null|string|object $entityOrClassOrMetadata, string $fieldName): bool

MetadataManipulator::isOneToMany()

public function isOneToMany(null|string|object $entityOrClassOrMetadata, string $fieldName): bool

MetadataManipulator::isManyToOne()

public function isManyToOne(null|string|object $entityOrClassOrMetadata, string $fieldName): bool

MetadataManipulator::isOneToOne()

public function isOneToOne(null|string|object $entityOrClassOrMetadata, string $fieldName): bool

MetadataManipulator::getAssociationType()

public function getAssociationType(null|string|object $entityOrClassOrMetadata, string $fieldName)
Returns

Doctrine's number of the association's kind, false for no association

MetadataManipulator::getAllClassNames()

public function getAllClassNames()
Returns

the mapped entities' classes

MetadataManipulator::getClassMetadataCompletor()

public function getClassMetadataCompletor(null|string|object $entityOrClassOrMetadata): ?Completor

The completor of a mapped class (its attributes' additions: aliases, hierarchy), null for any other.

MetadataManipulator::warmUp()

public function warmUp(string $cacheDir, ?string $buildDir = null): array

Base\Database\Repository

BackendOnly class

final class BackendOnly BackendOnly.php:17

A repository method that only the persistences named run (plan "omnibase agnostic", step E2): its query is no finder (Base\Database\Repository\Finder) but the backend's own language - native SQL with an upsert or a DATE() grouping, a bulk UPDATE -, so no persistence compiles it from the core: each one named writes the method in its own terms, any other refuses it aloud with refuse(), never answers it silently wrong.

Declared on the core's interface method (Base\Repository\Analytics\PageViews::dailyBreakdown(), for doctrine and eloquent since step F7f) and on an implementation that runs it (omnibridge/doctrine's PageViewRepository, for doctrine): declared() lists them, the inventory a new persistence works from, and the core's BackendOnlyTest keeps that list as recorded.

public readonly array $backends
public readonly string $reason

what the query needs of that backend ("ON DUPLICATE KEY UPDATE")

BackendOnly::__construct()

public function __construct(string|array $backends, public readonly string $reason = '')
$reason

what the query needs of that backend ("ON DUPLICATE KEY UPDATE")

BackendOnly::of()

public static function of(string $class, string $method): ?self

The declaration of $class::$method, on the method itself or on one of the interfaces it implements.

BackendOnly::runs()

public static function runs(string $class, string $method, string $backend): bool

Whether $backend runs $class::$method: true for any method not declared backend-only.

BackendOnly::refuse()

public static function refuse(string $class, string $method, string $backend): never

Refuses aloud, under $backend, a method declared for others: what a persistence's implementation of the interface answers until it writes the query in its own terms.

Throws

UnsupportedQueryException always

BackendOnly::declared()

public static function declared(iterable $classes): array

Every method of these classes or interfaces declared backend-only, "Class::method" => declaration.

Entities interface

interface Entities Entities.php:26

The entities of one class, whatever keeps them: what an application asks every repository of omnibase, with nothing of the ORM in what it takes or gives back - arrays of criteria and of order (field => ASC|DESC), the entities themselves, lists of them, integers.

The persistence half of Marco's bridge principle (audit "lesringostars face au master plan", step R15): the structure is described outside Doctrine (R14, Omnibridge\Schema), and the code of an application and of the core reaches its repositories through interfaces - this one and those of each entity, Base\Repository\Threads, Users... and an application's own (App\Repository\Article\Articles...) -, Doctrine's repository behind them. Another persistence (Eloquent, or anything better suited to a host) implements the same interfaces over the same tables.

ServiceEntityRepository implements it with Doctrine's methods of the same names: find(), findAll(), findBy(), findOneBy(), count(); persist(), remove() and flush() its unit of work.

Entities::find()

public function find($id): ?object

Entities::findAll()

public function findAll(): array

Entities::findBy()

public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null): array
$criteria

field => value, a list of values for one of them

$orderBy

field => ASC|DESC

Entities::findOneBy()

public function findOneBy(array $criteria, ?array $orderBy = null): ?object

Entities::count()

public function count(array $criteria = []): int

Entities::persist()

public function persist($entity, bool $flush = false): void
$entity

kept at the next flush, at once with $flush

Entities::remove()

public function remove($entity, bool $flush = false): void

Entities::flush()

public function flush(bool $autoclear = false)

Writes what was persisted, changed or removed.

Repositories interface

interface Repositories Repositories.php:18

The entities of any class, by its name (audit "lesringostars face au master plan", step R28): what code that is handed a class at run time - a form field's choices, a command over every uploading entity, the search's sort by hierarchy - asks, where it called the entity manager's getRepository() before. Nothing of the ORM in or out.

Base\Bridge\Doctrine\DoctrineRepositories answers it with the entity manager's repositories: omnibase's (ServiceEntityRepository, every Base\Repository\ and App\Repository\ class) as they are, Doctrine's plain EntityRepository behind an Entities adapter. Another persistence answers the same.

Repositories::of()

public function of(string $class): Entities

Repositories::byIds()

public function byIds(string $class, array $ids): array

The entities of these ids, through omnibase's finder cache where the repository is omnibase's (cacheById), else by its identifier.

Repositories::oneById()

public function oneById(string $class, mixed $id): ?object

The entity of this id, through omnibase's finder cache where the repository is omnibase's (cacheOneById), else find().

UnsupportedQueryException class

final class UnsupportedQueryException extends LogicException UnsupportedQueryException.php:9

A repository method the persistence installed does not run: declared #[BackendOnly] for another one (plan "omnibase agnostic", step E2), refused aloud rather than answered wrong.

Base\Database\Repository\Finder

Criterion class

final class Criterion Criterion.php:13

One criterion of a finder: a field (a path, "image.source"), the value it is compared with, and the words of the language that say how (EqualTo, YoungerThan, Partial, Insensitive, ClosestTo, InstanceOf...). $index numbers the criteria a name declares on the same field (findByIdGreaterThanAndIdLowerThan: id 0, id 1); null for a criterion given in the criteria array, compared for equality (or IN for a list).

public readonly string $field
public readonly ?int $index
public readonly mixed $value
public readonly array $options

Criterion::__construct()

public function __construct(public readonly string $field, public readonly ?int $index, public readonly mixed $value, public readonly array $options = [])

Criterion::of()

public static function of(string $field, mixed $value, string ...$words): self

A member of a group built from its members (Group::of(), step B1b): a field, its value and the words that say how it compares (Parser::OPTION_*: EqualTo when none says it), numbered by the group.

Criterion::is()

public function is(string $option): bool

Criterion::byKey()

public function byKey(): bool

Whether the criterion compares a to-one association by its key, without a join (its value a Key, step E2b): a persistence compiles it on the row's own foreign key.

Criterion::key()

public function key(): string

The key the criterion has in the criteria array the compilers read ("slug:0", or the field itself).

Group class

final class Group Group.php:50

A parenthesised part of a finder: a name of the language and its arguments, given as one entry of the criteria array (plan "omnibase agnostic", step E2).

A name joins its criteria with one separator, And or Or, never both: a query such as user = :user AND (title <> '' OR subject <> '') had to be written by hand. A group says the parentheses, in the language itself:

$notifications->count([
    'user' => $user,
    Group::by('TitleNotEmptyOrSubjectNotEmptyOrContentNotEmpty'),
]);
$translations->findBy([
    Group::by('InsensitivePartialTitleOrInsensitivePartialExcerpt', '%word%', '%word%'),
    'translatable.state' => ['publish'],
]);

The name is read by the same Parser, as the criteria part of findBy<name>: every word of a criterion is allowed (EqualTo, NotEmpty, Partial, Insensitive, StartingWith, Null, YoungerThan...), and its own separator joins its members. The group is then one criterion of the query, combined with the others by the query's separator. Not allowed in a group: what is no condition (ClosestTo and FarestTo order the rows, Model expands a select), WithRoute, a criteria array or any argument after the named values.

Parser::parse() hands back the group read ($query), which a persistence compiles as it compiles a query's criteria: omnibridge/doctrine into a parenthesised DQL expression, omnibridge/eloquent into a nested where.

A group can also be built from its members, without a name (step B1b): code that holds fields at run time - the back office's search over the text fields a list shows, its filters - says the same parentheses with criteria, and a field holding a word of the language ("sortOrder", "colorAndSize") stays a field:

Group::of(Parser::SEPARATOR_OR,
    Criterion::of('title', '%word%', Parser::OPTION_INSENSITIVE, Parser::OPTION_PARTIAL),
    Criterion::of('sortOrder', 3, Parser::OPTION_GREATER),
    Group::of(Parser::SEPARATOR_AND, Criterion::of('parent', Key::of(null)), Criterion::of('state', 'draft')),
);

It is the group already read: the Parser leaves it as it is, and both compilers read its members as those of a named group.

Group::by()

public static function by(string $name, mixed ...$arguments): self

Group::of()

public static function of(string $separator, Criterion|self ...$members): self

A group built from its members (step B1b): criteria (Criterion::of()) and groups, joined by $separator. A member's words are those a group's name may say - the comparisons, Partial, Insensitive, StartingWith and EndingWith, Null, Empty, True, False and their Not..., the dates' words -, EqualTo when it says no comparison; the members of a field are numbered in order ("id:0", "id:1"). An empty group adds no condition.

Throws

InvalidArgumentException another separator, a word that is no condition, two comparisons on one member

Group::isRead()

public function isRead(): bool

Whether the group was read (by the Parser, or built from its members).

Group::read()

public function read(Query $query): self

The same group, read by the parser: findBy<name> with its arguments.

Group::separator()

public function separator(): string

How the members join: And or Or (Parser::SEPARATOR_*).

Group::criterions()

public function criterions(): array

The members, each with its words, as a query's criterions.

Key class

final class Key Key.php:38

A to-one association compared by its key, without a join (plan "omnibase agnostic", step E2b): the value of a criterion, given in the criteria array or to a name of the language.

$comments->findBy([ 'state' => CommentState::APPROVED, 'thread' => Key::of($thread), // thread_id = :id, or thread_id IS NULL for null 'parent' => Key::of(null), ], ['createdAt' => 'DESC'], 200);

A criterion on an association is otherwise compiled through a join of it (LEFT JOIN e.thread e_thread ... e_thread = :thread), and a persistence that scopes the joined entity there - Doctrine's trash filter on Thread, in the join's ON - changes the rows: a comment whose thread is in the trash reads as a comment "without a thread". A key criterion reads the row's own foreign key: omnibridge/doctrine compiles it to e.thread = :key (IS NULL, IN), what a hand-written c.thread = :thread said, and omnibridge/eloquent to the foreign-key column.

What a key criterion compares: - an entity, its identifier, or null (no associated row); - a list of them (IN); an empty list leaves the criterion out, as any list of the language does; - with EqualTo (the default) or NotEqualTo only (NotEqualTo null: IS NOT NULL); any other word of the language is refused by the Parser; - an association of the entity itself (not a path such as "thread.parent", which needs the join), single-valued: the compilers refuse the others.

Not a word of the name: "Key" in a name would make every field holding the word (Passkey's publicKeyCredentialId) a name the language refuses.

const OPTIONS = [Parser::OPTION_EQUAL, Parser::OPTION_NOT_EQUAL]

The words a key criterion may carry: equality and its negation.

Key::of()

public static function of(mixed $value): self
$value

an entity, its identifier, a list of them, or null

Key::isNull()

public function isNull(): bool

Whether the key compared is none (IS NULL, IS NOT NULL with NotEqualTo).

Key::isList()

public function isList(): bool

Whether a list of keys is compared (IN, NOT IN with NotEqualTo).

Parser class

final class Parser Parser.php:36

The finder language of omnibase - findByEmailAndUsername(), findOneBySlug(), cacheOneByStateAndSlugStartingWith(), countByStateAndPublishedAtYoungerThan(), findPreviousOneByClassOfAndState(), lengthOfTagsBy()... - read from a method's name and its arguments into a Query: the request, the internal method it leads to, its arguments, the criteria the name declares with their options (EqualTo, NotEqualTo, GreaterThan, LowerThan, GreaterEqualTo, LowerEqualTo, YoungerThan, OlderThan, Within, IsOver, StartingWith, EndingWith, Null, Empty, True, False and their Not..., Insensitive, Partial, ClosestTo, FarestTo, InstanceOf, ClassOf, MemberOf, But, WithRoute, Model), the separator (And, Or), the column (countFor...By, lengthOf...By), the specials (One, All, Randomly, AtMost<N>, Last<N>, LastOne, Previous<N>, PreviousOne, Next<N>, NextOne), cache and Eagerly; since step E2, the aggregates sumOf<Column>By, minOf<Column>By and maxOf<Column>By, and the groups (Group::by('AOrB', ...) as an entry of the criteria array: a parenthesised part of the finder, read by this parser; since step B1b also Group::of() from its members, read already); since step E2b, a to-one association compared by its key without a join (Key::of($x), a criterion's value, EqualTo or NotEqualTo only).

Nothing of an ORM: what it asks of the entity is a Subject (its class, its fields, a Query-by-Example's criteria), and a host's request (WithRoute) is turned into route parameters by the resolver it is given. A persistence compiles the Query into its own query language - Doctrine's DQL in ServiceEntityParser (omnibridge/doctrine at step F3), Eloquent's builder in omnibridge/eloquent (F7) - so the language is one, whatever the backend (plan "omnibase agnostic", 2026-11-01, step F1: Marco's invention, kept whole in the core). The parse is the one ServiceEntityParser::__parse() made before: tests/Database/Repository/FinderParityTest compares it, word for word.

const REQUEST_FIND = "find"
const REQUEST_CACHE = "cache"
const REQUEST_COUNT = "count"
const REQUEST_DISTINCT = "distinctCount"
const REQUEST_LENGTH = "lengthOf"
const REQUEST_SUM = "sumOf"
const REQUEST_MIN = "minOf"
const REQUEST_MAX = "maxOf"
const LOAD_EAGERLY = "Eagerly"
const SPECIAL_ALL = "All"
const SPECIAL_ONE = "One"
const SPECIAL_RAND = "Randomly"
const SPECIAL_ATMOST = "AtMost(?P<atMost>[0-9])*"
const SPECIAL_LASTONE = "LastOne"
const SPECIAL_LAST = "Last(?P<last>[0-9])*"
const SPECIAL_PREVONE = "PreviousOne"
const SPECIAL_PREV = "Previous(?P<prev>[0-9]*)"
const SPECIAL_NEXTONE = "NextOne"
const SPECIAL_NEXT = "Next(?P<next>[0-9]*)"
const OPTION_EMPTY = "Empty"
const OPTION_NOT_EMPTY = "NotEmpty"
const OPTION_TRUE = "True"
const OPTION_NOT_TRUE = "NotTrue"
const OPTION_FALSE = "False"
const OPTION_NOT_FALSE = "NotFalse"
const OPTION_NULL = "Null"
const OPTION_NOT_NULL = "NotNull"
const OPTION_EQUAL = "EqualTo"
const OPTION_NOT_EQUAL = "NotEqualTo"
const OPTION_GREATER = "GreaterThan"
const OPTION_GREATER_EQUAL = "GreaterEqualTo"
const OPTION_LOWER = "LowerThan"
const OPTION_LOWER_EQUAL = "LowerEqualTo"
const OPTION_WITHIN = "Within"
const OPTION_OLDER = "OlderThan"
const OPTION_OLDER_EQUAL = "OlderEqualTo"
const OPTION_YOUNGER = "YoungerThan"
const OPTION_YOUNGER_EQUAL = "YoungerEqualTo"
const OPTION_OVER = "IsOver"
const OPTION_NOT_OVER = "IsNotOver"
const OPTION_STARTING_WITH = "StartingWith"
const OPTION_ENDING_WITH = "EndingWith"
const OPTION_NOT_STARTING_WITH = "NotStartingWith"
const OPTION_NOT_ENDING_WITH = "NotEndingWith"
const OPTION_INSENSITIVE = "Insensitive"
const OPTION_WITH_ROUTE = "WithRoute"
const OPTION_PARTIAL = "Partial"
const OPTION_MODEL = "Model"
const OPTION_CLASSOF = "ClassOf"
const OPTION_NOT_CLASSOF = "NotClassOf"
const OPTION_INSTANCEOF = "InstanceOf"
const OPTION_NOT_INSTANCEOF = "NotInstanceOf"
const OPTION_MEMBEROF = "MemberOf"
const OPTION_NOT_MEMBEROF = "NotMemberOf"
const OPTION_BUT = "But"
const OPTION_CLOSESTTO = "ClosestTo"
const OPTION_FARESTTO = "FarestTo"
const SEPARATOR = ":"
const SEPARATOR_OR = "Or"
const SEPARATOR_AND = "And"
const SEPARATOR_FOR = "For"
const SEPARATOR_BY = "By"
const COUNT_ALL = "ALL"
const COUNT_DISTINCT = "DISTINCT"

Parser::getSpecial()

public static function getSpecial(string $special): string

Parser::getSpecials()

public static function getSpecials(): array

Parser::__construct()

public function __construct(readonly Subject $subject, readonly ?\Closure $routeParameters = null)
$subject

the entity the finder is asked of

$routeParameters

a host's request or event (WithRoute's first argument when it is no array) => its route parameters (an array or null), false for anything else

Parser::parse()

public function parse(string $method, array $arguments): Query

Reads a finder's name and arguments.

Throws

Exception an unknown request, an ambiguous name (And with Or), a field whose name holds a word of the language, a missing or wrong argument

Parser::getCustomOption()

public function getCustomOption(string $id)

Parser::findCustomOption()

public function findCustomOption(string $id, string $option)

Query class

final class Query Query.php:26

A finder call read by the Parser: the neutral form of the finder language, which a persistence compiles into its own queries.

  • $method, $arguments: the internal request the name leads to (__findBy, __findOneBy, __findLastBy, __findAtMostBy, __findPreviousBy, __findNextBy, __findRandomlyBy, __findAll, __countBy, __distinctCountBy, __lengthOfBy...) and its arguments: the criteria (those the name declares merged into those given, then the specials' numbers and keys as "special:..."), then the order, the limit, the offset, the grouping and the selected expressions;
  • $criteria, $options: the criteria the name declares, "field:index" => value, and their options, "field:index" => list of words;
  • $separator: And or Or, how the criteria combine (never both);
  • $column: the column counted, measured or aggregated (countFor<Column>By, lengthOf<Column>By, sumOf<Column>By, minOf<Column>By, maxOf<Column>By), null when the name has none;
  • $cacheable: a cache... request outside the command line;
  • $eagerly: the associations an ...Eagerly... request loads, false otherwise;
  • $request: find, count (distinctCount too), lengthOf, or an aggregate (sumOf, minOf, maxOf: __sumOfBy... with the criteria alone, one value back); $special: One, All, Randomly, AtMost, Last, LastOne, Previous, PreviousOne, Next, NextOne, or null.
public readonly string $method
public readonly array $arguments
public readonly array $criteria
public readonly array $options
public readonly ?string $separator
public readonly ?string $column
public readonly bool $cacheable
public readonly array|bool $eagerly
public readonly string $request
public readonly ?string $special

Query::__construct()

public function __construct(public readonly string $method, public readonly array $arguments, public readonly array $criteria, public readonly array $options, public readonly ?string $separator, public readonly ?string $column, public readonly bool $cacheable, public readonly array|bool $eagerly, public readonly string $request, public readonly ?string $special)

Query::criterions()

public function criterions(): array

Every criterion of the call, in order: those of the criteria array given, then those the name declares, each with its options; not the specials' numbers and keys (extras()). A group of the criteria array (Group::by()) is one criterion whose value is the Group read, its members in Group::criterions(); a key criterion (Key::of(), step E2b) one whose value is the Key (Criterion::byKey()).

Query::extras()

public function extras(): array

The specials' numbers and keys: atMost, last, prev, next, prevKeys, nextKeys.

Subject interface

interface Subject Subject.php:10

What the finder language asks of the entity a finder is called on, whatever keeps it: Doctrine's metadata (ServiceEntityParser), Eloquent's tables from Omnibridge\Schema (omnibridge/eloquent), or anything that knows its fields.

Subject::getClassName()

public function getClassName(): string

The entity's class, the one its mapping names (App\Entity\X where the application has one).

Subject::getFieldNames()

public function getFieldNames(): array

The entity's fields, those a name must not mistake for a word of the language (a field "postedOrDrafted" holds "Or").

Subject::hasField()

public function hasField(string $name): bool

Whether the entity has that field or association (a real one wins over a Query-by-Example clause).

Subject::criteriaFromSelect()

public function criteriaFromSelect(object $select): array

A Query-by-Example's criteria (findByModel($select)): the set fields of the object given, as field => value.

Base\Database\Schema

DiscriminatorRule class

final class DiscriminatorRule implements Rule DiscriminatorRule.php:29

omnibase's discriminators, as Base\Bridge\Doctrine\MappingDriver and #[DiscriminatorEntry] give them to Doctrine (plan "omnibase agnostique", C6), on the description built without it:

  • once the declaration is read, the map of a root entity that declares an inheritance and no map is generated: the class and every subclass among the classes described, each under its own class name (Doctrine's default would take the short names, which collide: App\Entity\Thread\Tag, Base\Entity\Thread\Tag);
  • once the class is whole, a root that carries #[DiscriminatorEntry] has the keys of its map renamed: each class of the map by its own entry's value - the value written, else the one DiscriminatorEntry::getValue() derives from the class's name and its parent's entry (common and abstract for a root of Base\Entity, the namespace below Entity\ in lower camel case joined by underscores, the parent's value in place of the namespace it covers). A subclass takes its parent's map as it is, and its own value in it.

DiscriminatorRule::before()

public function before(Draft $class, ClassDeclaration $declaration, Builder $builder): void

DiscriminatorRule::declared()

public function declared(Draft $class, ClassDeclaration $declaration, Builder $builder): void

DiscriminatorRule::loaded()

public function loaded(Draft $class, ClassDeclaration $declaration, Builder $builder): void

DiscriminatorRule::value()

public static function value(string $className): string

DiscriminatorEntry::getValue(), on the class's name and its parent's entry.

@param class-string $className

EntitySchema class

final class EntitySchema EntitySchema.php:46

The schema of omnibase's entities and an application's, with no persistence installed (plan "omnibase agnostic", answer 11 and step F7a): their description (Omnibridge\Schema\Description) built from the entities' folders - their declarations read by reflection, omnibase's naming and its rules in the order Doctrine's listeners run them -, and what omnibase's own column types are (Omnibridge\Schema\Database\ColumnTypes): its enumerations' and sets' values, the serialized arrays and the passkeys' columns as the portable types they are written as.

What omnibridge:schema:create reads on every host (omnibridge/symfony's console, omnibridge/laravel's artisan, src/Resources/schema.php for omnisense/omnibridge's plain-PHP script):

$options = ['project_dir' => $projectDir];
$description = EntitySchema::describe(EntitySchema::directories($projectDir), $options);
(new Omnibridge\Schema\Database\SchemaCreator($pdo, EntitySchema::columnTypes($options)))->create($description);

Options: project_dir (its src/Entity, src/Enum; the current folder by default), enumerations (more folders of enumerations), types (column types by name, a bundle's enumerations among them), resolve_target_entities (interface => class), declarations (a Declarations source in place of the attributes), rules (more rules, after omnibase's), column_types (more ColumnTypes, over omnibase's: an application's own column types).

The description is omnibridge/doctrine's Describer's (the same classes, the same rules: SchemaDescriptionTest compares them), which feeds Doctrine; the column types give the SQL Doctrine's types declare (the same test).

const ALIASES = ['array' => 'text', 'passkey_base64' => 'text', 'passkey_aaguid' => 'text', 'passkey_trust_path' => 'json']

omnibase's column types that are no enumeration, by the portable type they are written as: the serialized arrays of before DBAL 4 (a CLOB), the passkeys' base64 values and AAGUID (CLOBs), their trust path (JSON) - omnibridge/doctrine's ArrayType and Passkey\{Base64, Aaguid, TrustPath}. Its datetime types (datetime, datetimetz, utc_datetime, utc_datetime_immutable) are portable types already.

EntitySchema::describe()

public static function describe(array $directories, array $options = []): Description

The description of the entities the folders hold.

$directories

the entities' folders (directories())

EntitySchema::rules()

public static function rules(array $options = []): array

omnibase's rules, in the order Doctrine's listeners run.

EntitySchema::types()

public static function types(array $options = []): array

The column types by name that are classes of omnibase's: those given, then the enumerations of the core, of the project (src/Enum) and of the folders given, each under its name (the first of a name kept).

EntitySchema::columnTypes()

public static function columnTypes(array $options = []): ColumnTypes

omnibase's column types as data: ALIASES, each enumeration's values (an ENUM on MySQL), each set's (a SET), then the column_types given.

EntitySchema::directories()

public static function directories(string $projectDir, array $more = []): array

The entities' folders of an omnibase application: the core's src/Entity, the project's src/Entity if it has one, then those given (a bundle's).

EntitySchema::coreDirectory()

public static function coreDirectory(string $folder): string

A folder of the core's src/ (Entity, Enum).

ExtensionRule class

final class ExtensionRule implements Rule ExtensionRule.php:17

The extensions' index, as Base\EntitySubscriber\ExtensionSubscriber gives it to Doctrine: on AbstractExtension's table, <table>_entity over entityClass and entityId (an index, not a unique constraint: a Revision is one row per flush).

ExtensionRule::before()

public function before(Draft $class, ClassDeclaration $declaration, Builder $builder): void

ExtensionRule::declared()

public function declared(Draft $class, ClassDeclaration $declaration, Builder $builder): void

ExtensionRule::loaded()

public function loaded(Draft $class, ClassDeclaration $declaration, Builder $builder): void

OrderColumnRule class

final class OrderColumnRule implements Rule OrderColumnRule.php:20

#[OrderColumn(orderBy: ...)]'s column, as the attribute gives it to Doctrine: on a to-many relation or a set column, the field named by orderBy is mapped if nothing maps it - a nullable json column, where the positions are kept; a property that is an #[Alias] of a relation counts as that relation. The set types by name, to know a set column (omnibase's enumerations: Base\Bridge\Doctrine\Types::enumerations()).

OrderColumnRule::__construct()

public function __construct(readonly array $types = [])
$types

the column types by name, the sets among them

OrderColumnRule::before()

public function before(Draft $class, ClassDeclaration $declaration, Builder $builder): void

OrderColumnRule::declared()

public function declared(Draft $class, ClassDeclaration $declaration, Builder $builder): void

OrderColumnRule::loaded()

public function loaded(Draft $class, ClassDeclaration $declaration, Builder $builder): void

TargetRule class

final class TargetRule implements Rule TargetRule.php:16

The targets resolved, as Doctrine's ResolveTargetEntityListener resolves them (DoctrineBundle's resolve_target_entities, Mapping::register()'s option): a relation toward an interface points to the class the application gave for it, the rest of the relation as it was.

TargetRule::__construct()

public function __construct(readonly array $targets = [])
$targets

interface => class

TargetRule::before()

public function before(Draft $class, ClassDeclaration $declaration, Builder $builder): void

TargetRule::declared()

public function declared(Draft $class, ClassDeclaration $declaration, Builder $builder): void

TargetRule::loaded()

public function loaded(Draft $class, ClassDeclaration $declaration, Builder $builder): void

TranslationRule class

final class TranslationRule implements Rule TranslationRule.php:30

The translations' mapping, as Base\DatabaseSubscriber\IntlSubscriber gives it to Doctrine, on the description built without it:

  • before its declaration is read, a translation class (ThreadIntl, the TranslationInterface) takes the inheritance of its translatable (Thread): its type and its discriminator column, its map translated class by class (each translatable of the map to its own translation class, where one exists), its subclasses likewise, and its own value, the translatable's;
  • once the class is whole, a translatable gets the translations relation (one-to-many, mapped by translatable, indexed by locale) and a translation the translatable relation (many-to-one, the join column translatable_id deleted in cascade), the locale column (string, 5) and, on the root of its hierarchy, the unique constraint <table>_unique_translation over translatable_id and locale (a #[Vault] adds its column to it first: VaultRule comes before).
const LOCALE = 'locale'

The names the translations are mapped under - omnibridge/doctrine's TranslatableWalker queries them by the same values (SchemaDescriptionTest compares both) -, here so that the description is built with no persistence installed (plan "omnibase agnostic", step F7a; they were read from the walker's class).

const FOREIGN_KEY = 'translatable_id'
const COLUMN_NAME = 'translations'
const SALT = 'unique_translation'

TranslationRule::before()

public function before(Draft $class, ClassDeclaration $declaration, Builder $builder): void

TranslationRule::declared()

public function declared(Draft $class, ClassDeclaration $declaration, Builder $builder): void

TranslationRule::loaded()

public function loaded(Draft $class, ClassDeclaration $declaration, Builder $builder): void

VaultRule class

final class VaultRule implements Rule VaultRule.php:18

#[Vault]'s constraints, as the attribute gives them to Doctrine: the unique constraint <table>_unique over the columns it names, and on the root of a translation hierarchy its vault column added to <table>_unique_translation (before translatable_id and locale: TranslationRule comes after).

VaultRule::before()

public function before(Draft $class, ClassDeclaration $declaration, Builder $builder): void

VaultRule::declared()

public function declared(Draft $class, ClassDeclaration $declaration, Builder $builder): void

VaultRule::loaded()

public function loaded(Draft $class, ClassDeclaration $declaration, Builder $builder): void

Base\Database\Scope

TrashScope class

final class TrashScope implements Scope TrashScope.php:15

The trashed rows left out of every read (plan "omnibase agnostic", step F2e): an entity whose class, or a parent's, is #[Trasheable] is read only while its deletion field is null. Base\Service\TrashManager::withTrash() disables it to look at the trash. Doctrine compiles it as its SQL filter "trash_filter" (Base\Database\Filter\TrashFilter).

const NAME = 'trash'

TrashScope::name()

public function name(): string

TrashScope::appliesTo()

public function appliesTo(string $class): bool

TrashScope::criteria()

public function criteria(string $class, array $parameters = []): array
Returns

the deletion field => null (IS NULL)

VaultScope class

final class VaultScope implements Scope VaultScope.php:16

The rows of another environment's vault left out of every read (plan "omnibase agnostic", step F2e): an entity whose class is #[Vault] is read when its vault field is null or names the environment the scope was enabled with ("environment"). Doctrine compiles it as its SQL filter "vault_filter" (Base\Database\Filter\VaultFilter).

const NAME = 'vault'

VaultScope::name()

public function name(): string

VaultScope::appliesTo()

public function appliesTo(string $class): bool

VaultScope::criteria()

public function criteria(string $class, array $parameters = []): array
Returns

the vault field => [null, the environment]: null or equal (a list holding null reads "null, or one of the others")

VaultScope::vault()

public static function vault(string $class): ?Vault

The class's #[Vault], the last one declared.

Base\Database\Type

EnumType class

abstract class EnumType implements SelectInterface EnumType.php:24

An enumeration of omnibase: its values are its constants (UserRole::ADMIN = "ROLE_ADMIN"), with their icons, colours and texts, grouped by the "_" of their values. A plain PHP class, no type of an ORM (plan "omnibase agnostic", step F2a): a persistence maps a column named by getStaticName() to it - on Doctrine Base\Bridge\Doctrine\EnumTypeAdapter, registered under that name for each enumeration (Base\Bridge\Doctrine\Types), with the values converted by toDatabaseValue() and toPHPValue(). Base\Database\Type\Enumerations knows them by name. Until F2a it was Doctrine's Type itself.

EnumType::getIcons()

public static function getIcons(): array

EnumType::getColor()

public static function getColor(string $id): ?string

EnumType::getIcon()

public static function getIcon(string $id, int $index = -1): ?string

EnumType::getText()

public static function getText(string $id, ?TranslatorInterface $translator = null): ?string

EnumType::getHtml()

public static function getHtml(string $id): ?string

EnumType::getData()

public static function getData(string $id): ?array

EnumType::getName()

public function getName(): string

EnumType::getStaticName()

public static function getStaticName()

EnumType::hasKey()

public static function hasKey(string $key, bool $inheritance = true)
Throws

Exception

EnumType::getValue()

public static function getValue(string $key, bool $inheritance = true)
Throws

Exception

EnumType::hasValue()

public static function hasValue(string $value, bool $inheritance = true)
Throws

Exception

EnumType::getPermittedValues()

public static function getPermittedValues(bool $inheritance = true, bool $preserve_keys = false): array

EnumType::getPermittedValuesByGroup()

public static function getPermittedValuesByGroup(bool $inheritance = true, bool $preserve_keys = false): array

EnumType::getPermittedValuesByClass()

public static function getPermittedValuesByClass(bool $preserve_groups = true, bool $preserve_keys = false): array

EnumType::toDatabaseValue()

public static function toDatabaseValue(mixed $value): mixed

A value as the database keeps it: the value itself, refused when it is none of the enumeration's (or a list, which an enumeration is not).

Throws

InvalidArgumentException

EnumType::toPHPValue()

public static function toPHPValue(mixed $value): mixed

A value read from the database, as the entity holds it.

Enumerations class

final class Enumerations Enumerations.php:11

omnibase's enumerations by the name a column's type gives them (user_role => Base\Enum\UserRole, or the application's App\Enum\UserRole): what code that holds a column's type asks to reach its enumeration, whatever persistence maps it (plan "omnibase agnostic", step F2a). Filled by the persistence when it registers them (Base\Bridge\Doctrine\Types on Doctrine).

Enumerations::register()

public static function register(string $name, string $class): void

Enumerations::classOf()

public static function classOf(?string $name): ?string
Returns

the enumeration a type of that name is (or the enumeration's class given), null for any other type

Enumerations::all()

public static function all(): array
Returns

every enumeration registered, by name

SetType class

abstract class SetType extends EnumType SetType.php:10

An enumeration whose field holds a set of its values (UserRole: an account's roles), kept as those values joined by commas (a MySQL SET). A plain PHP class (plan "omnibase agnostic", step F2a): Base\Bridge\Doctrine\EnumTypeAdapter maps it on Doctrine.

SetType::toDatabaseValue()

public static function toDatabaseValue(mixed $value): mixed

The values joined by commas, those of the enumeration only.

SetType::toPHPValue()

public static function toPHPValue(mixed $value): mixed
Returns

the values read back, those of the enumeration only

SetType::getOrderingKeys()

public static function getOrderingKeys(array $array): array

Utc class

final class Utc Utc.php:13

Moments in UTC, for the code around a utc_datetime_immutable column: the present, and any date as the same moment in UTC - what a query parameter compared with such a column must be when it is bound without its type.

->setParameter('since', Utc::from($since)) // or, typed: ->setParameter('since', $since, UtcDateTimeImmutableType::NAME)

Utc::zone()

public static function zone(): \DateTimeZone

The zone moments are kept in: omnibridge/doctrine's, the one its types (and these) write with.

Utc::now()

public static function now(): \DateTimeImmutable

Utc::from()

public static function from(?\DateTimeInterface $moment): ?\DateTimeImmutable

Any date, as the same moment in UTC.

Base\Demo

DemoAccount class

final class DemoAccount DemoAccount.php:15

A demonstration account, as a bundle or the application declares it (DemoAccountProviderInterface): who signs in, as what, and what that role sees. The fixtures create the accounts from these declarations (DemoAccountFactory); in the demo environment the sign-in page offers one button for each (docs/20-architecture/demo.md).

A super-administrator is never a demonstration account: the registry refuses a declaration whose roles reach ROLE_SUPERADMIN.

public readonly string $identifier

what the account signs in with (the field the application's User names in $userIdentifier)

public readonly string $label

the button's text: a translation key ("@health.demo.practitioner.label") or the text itself

public readonly string $description

one sentence on what this role sees: a translation key or the text itself

public readonly array $roles

the account's own roles

public readonly ?string $group

the name of a Base\Entity\User\Group the account belongs to (it holds the group's roles)

public readonly array $groupRoles

the roles of that group, when the fixtures have to create it

public readonly ?string $password

null: the identifier (demonstration accounts are public)

public readonly ?string $email

null: <identifier>@example.org

public readonly int $position

the order on the sign-in page, lowest first

DemoAccount::__construct()

public function __construct(public readonly string $identifier, public readonly string $label, public readonly string $description = '', public readonly array $roles = ['ROLE_USER'], public readonly ?string $group = null, public readonly array $groupRoles = [], public readonly ?string $password = null, public readonly ?string $email = null, public readonly int $position = 0)
$identifier

what the account signs in with (the field the application's User names in $userIdentifier)

$label

the button's text: a translation key ("@health.demo.practitioner.label") or the text itself

$description

one sentence on what this role sees: a translation key or the text itself

$roles

the account's own roles

$group

the name of a Base\Entity\User\Group the account belongs to (it holds the group's roles)

$groupRoles

the roles of that group, when the fixtures have to create it

$password

null: the identifier (demonstration accounts are public)

$email

null: <identifier>@example.org

$position

the order on the sign-in page, lowest first

DemoAccount::getPassword()

public function getPassword(): string

DemoAccount::getEmail()

public function getEmail(): string

DemoAccount::getAllRoles()

public function getAllRoles(): array
Returns

the account's own roles and its group's

DemoAccountFactory class

class DemoAccountFactory DemoAccountFactory.php:28

The declared demonstration accounts as rows: what the fixtures call instead of writing each account by hand, and what demo:reset calls after them so that every declared account exists.

$docteur = $this->demoAccounts->account('docteur', $manager); // found, or created from its declaration $this->demoAccounts->load($manager); // every declared account

An account the database already has is returned as it is: fixtures that create theirs themselves keep them, identifier included. Nothing is flushed here - the fixture does.

Read and written through omnisense/omnibridge's unit of work, the persistence chosen's (plan "omnibase agnostic", step F7d-3: on Eloquent, the account a one-click sign-in gives is the one its connections are written for), or through Doctrine's registry (deprecated until 6.0); a fixture's ObjectManager given to a call is used as it is.

DemoAccountFactory::__construct()

public function __construct(readonly DemoAccountRegistry $registry, readonly UnitOfWork|ManagerRegistry $doctrine, readonly string $userClass = 'App\Entity\User')

DemoAccountFactory::find()

public function find(string $identifier, ?ObjectManager $manager = null): ?object

The row of a declared account, null when the database has none.

DemoAccountFactory::account()

public function account(string $identifier, ?ObjectManager $manager = null): object

The account of that identifier: the database's, or a new one made from its declaration (verified, approved, in its group - created with its roles when missing).

DemoAccountFactory::load()

public function load(?ObjectManager $manager = null): array

Every declared account, created when missing.

Returns

by identifier

DemoAccountFactory::missing()

public function missing(?ObjectManager $manager = null): array

The identifiers of the declared accounts the database lacks.

DemoAccountLock class

final class DemoAccountLock DemoAccountLock.php:18

A demonstration account stays what its declaration says (plan "omnibase agnostic", step F5a: the logic of Base\DatabaseSubscriber\DemoAccountLockSubscriber, on no persistence nor host): its identifier, its address, its password, its second factor are put back as the database had them, it is not disabled. The persistence's listener gives each account's original row and how to read and write its columns; the host says the message.

const LOCKED_FIELDS = ['email', 'secret', 'backupCodes', 'emailAuthEnabled']

The columns put back as they were (the identifier's and the password's are handled apart).

DemoAccountLock::__construct()

public function __construct(readonly DemoAccountRegistry $accounts, readonly PasswordHasherFactoryInterface $hashers, readonly ?TranslatorInterface $translator = null)

DemoAccountLock::declarationOf()

public function declarationOf(User $user, array $original): ?DemoAccount

The declaration of this account as the database knows it: by the identifier it was loaded with, not the one just typed.

$original

the row as loaded, empty for an account not written yet

DemoAccountLock::restore()

public function restore(User $user, DemoAccount $account, array $original, array $fields, \Closure $read, \Closure $write): bool

Puts back what may not change; true when something had.

$original

the row as loaded

$fields

the columns the account's class maps

$read

a column's value on the object

$write

a column's value put back on the object

DemoAccountLock::message()

public function message(string $key): string

The words of a refusal: "deleted" (an account cannot be deleted), "locked" (what was changed was put back).

DemoAccountProviderInterface interface

interface DemoAccountProviderInterface DemoAccountProviderInterface.php:19

Declares demonstration accounts: implemented by a bundle for the roles of its trade (a practitioner, a secretary, a patient) and by the application for its own. Autoconfigured (tag base.demo_account_provider); the application's declaration replaces a bundle's for the same identifier.

final class ShopDemoAccounts implements DemoAccountProviderInterface { public function getDemoAccounts(): iterable { yield new DemoAccount('client', 'demo.client.label', 'demo.client.description'); } }

DemoAccountProviderInterface::getDemoAccounts()

public function getDemoAccounts(): iterable

DemoAccountRegistry class

class DemoAccountRegistry DemoAccountRegistry.php:26

Every demonstration account declared by the bundles and the application (DemoAccountProviderInterface), by identifier. The application's declarations come last and replace a bundle's; base.demo.exclude drops the ones a site has no use for.

It exists in every environment - the fixtures of dev and test create the same accounts as the demonstration's - but only the demo environment does anything with it at sign-in (DemoMode).

A declared account that opens the back office (base.demo.admin_roles) is created like the others and offered to nobody: offered() leaves it out.

A demonstration has one account for each role of the application's user_role type (App\Enum\UserRole, else Base\Enum\UserRole) below the back office: missingRoles() names those without one.

const SUPER_ADMIN = 'ROLE_SUPERADMIN'

DemoAccountRegistry::__construct()

public function __construct(readonly iterable $providers = [], readonly array $exclude = [], readonly ?RoleHierarchyInterface $roleHierarchy = null, readonly array $adminRoles = ['ROLE_ADMIN'])
$exclude

identifiers left out (base.demo.exclude)

$adminRoles

the roles that open the back office (base.demo.admin_roles)

DemoAccountRegistry::all()

public function all(): array
Returns

by identifier, in the order of the sign-in page

DemoAccountRegistry::offered()

public function offered(): array

The declared accounts a visitor is offered - in the banner, on the sign-in page, at a click: every one but those that open the back office.

Returns

by identifier, in the order of the sign-in page

DemoAccountRegistry::missingRoles()

public function missingRoles(?array $roles = null): array

The roles of the application's user_role type (or of $roles) that no account offered holds - leaving out those that open the back office.

ROLE_USER is everyone's: any account offered holds it. Empty when the demonstration has one account for each role it should.

$roles

null: the constants of the user_role type

DemoAccountRegistry::get()

public function get(?string $identifier): ?DemoAccount

DemoAccountRegistry::has()

public function has(?string $identifier): bool

DemoAccountRegistry::of()

public function of(?object $user): ?DemoAccount

The declaration this account was created from, if it is a demonstration account.

DemoAccountRegistry::reachesSuperAdmin()

public function reachesSuperAdmin(array $roles): bool

Do these roles reach ROLE_SUPERADMIN, directly or through the role hierarchy (a ROLE_EDITOR above it, in the sites where Glitch Art is one)?

DemoAccountRegistry::isSuperAdmin()

public function isSuperAdmin(?object $user): bool

DemoAccountRegistry::reachesAdministration()

public function reachesAdministration(array $roles): bool

Do these roles open the back office - one of base.demo.admin_roles, directly or through the role hierarchy? A super-administrator's do, wherever the hierarchy puts ROLE_SUPERADMIN above them.

DemoAccountRegistry::isAdministrator()

public function isAdministrator(?object $user): bool

DemoGuard class

class DemoGuard DemoGuard.php:21

What the demo environment refuses to start on (BaseBundle::boot() asks, for a page as for a command):

  • debug on: the demonstration behaves as production does, and a debug kernel shows its traces to visitors;
  • the production database: demo:reset empties the database it runs on every night. The application says which one production's is (base.demo.production_database, a DSN); a connection that reaches the same server, port and database name is refused, whoever signs in to it. Left unset, nothing can be compared: refused too.

DemoGuard::__construct()

public function __construct(readonly DemoMode $mode, readonly bool $debug, readonly ?string $productionDatabase = null, readonly ?ConnectionRegistry $doctrine = null)

DemoGuard::check()

public function check(): void
Throws

DemoRefusedException

DemoGuard::target()

public static function target(string|array $database): ?string

Where a connection leads - "host:port/name", or a file's path for SQLite - whoever signs in to it: from a DSN or from DBAL's parameters.

Null when it names no database.

DemoMode class

final class DemoMode DemoMode.php:13

Whether the kernel runs the demonstration: the demo environment, and no other. There is no switch to turn it on elsewhere - what it lifts (the staff's second factor) and what it offers (signing in as anyone declared) has no place on a production site.

const ENVIRONMENT = 'demo'

DemoMode::__construct()

public function __construct(readonly string $environment)

DemoMode::isActive()

public function isActive(): bool

DemoSignIn class

final class DemoSignIn DemoSignIn.php:16

Signing in as a demonstration account in one click, written once for every host (plan "omnibase agnostic", step F5e, slice 5; formerly DemoController::Login()): the demo environment only, a POST with its token (never a link a prefetch would follow), a declared account only, and never one that opens the back office (base.demo.admin_roles) or reaches ROLE_SUPERADMIN - declared so or promoted since: those sign in with their secret. A refusal is said and leads back to the sign-in page.

const TOKEN = 'demo_login'
const LOGIN_ROUTE = 'security_login'

DemoSignIn::__construct()

public function __construct(readonly DemoMode $demo, readonly DemoAccountRegistry $accounts, readonly Tokens $tokens)

DemoSignIn::isActive()

public function isActive(): bool

DemoSignIn::decide()

public function decide(?string $token, ?string $account, \Closure $load): Outcome

The account to sign in (the host then answers what its sign-in answers, else the index), or the refusal.

$load

the host's account by its identifier, null for none

Base\Entity

Thread class

class Thread implements TranslatableInterface, IconizeInterface, GraphInterface, CacheableInterface Thread.php:47

Thread::__toKey()

public function __toKey(mixed ...$variadic): string

Thread::__iconize()

public function __iconize(): ?array

Thread::__iconizeStatic()

public static function __iconizeStatic(): ?array

Thread::__toString()

public function __toString()

Its title, its slug, else what its class is called (the Nouns contract, C4b: Base\Service\Translator::transEntity()'s answer under Symfony).

public function __toLink(array $routeParameters = [], int $referenceType = Link::ABSOLUTE_PATH): ?string

Its page's address: none for a thread as the core knows it - the core has no route showing one. A thread that has a page (a blog's Post, a forum's Topic...) says where, overriding this with the same signature.

It is not a LinkableInterface for that: a bare thread links nowhere. Before, a core Thread had no __toLink() at all, and a member's profile listing one failed.

Thread::__construct()

public function __construct(?User $owner = null, ?Thread $parent = null, ?string $title = null, ?string $slug = null)

Thread::getId()

public function getId(): ?int

Thread::getUuid()

public function getUuid()

Thread::getParent()

public function getParent(): ?self

Thread::setParent()

public function setParent(?self $parent): self

Thread::getChildren()

public function getChildren(): Collection

Thread::addChild()

public function addChild(self $child): self

Thread::removeChild()

public function removeChild(self $child): self

Thread::getConnexes()

public function getConnexes(): Collection

Thread::addConnex()

public function addConnex($connex): self

Thread::removeConnex()

public function removeConnex($connex): self

Thread::getSlug()

public function getSlug(): ?string

Thread::setSlug()

public function setSlug(string $slug): self

Thread::getState()

public function getState()

Thread::setState()

public function setState($state): self

Thread::setIsPublished()

public function setIsPublished(bool $newState): self

Thread::isFuture()

public function isFuture(): bool

Thread::isDeleted()

public function isDeleted(): bool

Thread::isScheduled()

public function isScheduled(): bool

Thread::isSecret()

public function isSecret(): bool

Thread::isPublished()

public function isPublished(null|DateTime|string $within = null): bool

Thread::isVisible()

public function isVisible(): bool

An administrator sees every thread; anyone else an approved, published, not secret one. Asked of the Access contract (plan "omnibase agnostique", C3e), not of BaseService: under Symfony the same authorization checker (Omnibridge\Symfony\Contract\SecurityAccess).

It also asked whether the owners contained the token storage's token - a token compared with users, never one of them: never true, so dropped with the token storage, the answers unchanged. Whether an owner should see their own unpublished thread is a decision left for later (plan, C3e).

Thread::isPublishable()

public function isPublishable(): bool

Thread::isApproved()

public function isApproved()

Thread::getWorkflow()

public function getWorkflow()

Thread::setWorkflow()

public function setWorkflow($workflow): self

Thread::getOwner()

public function getOwner(int $i = 0)

Thread::getOwners()

public function getOwners(): Collection

Thread::addOwner()

public function addOwner(?User $owner): self

Thread::removeOwner()

public function removeOwner(?User $owner): self

Thread::getFollowers()

public function getFollowers(): Collection

Thread::addFollower()

public function addFollower(User $follower): self

Thread::removeFollower()

public function removeFollower(User $follower): self

Thread::getPrimaryTag()

public function getPrimaryTag()

Thread::getSecondaryTags()

public function getSecondaryTags(): array

Thread::getTags()

public function getTags(): Collection

Thread::addTag()

public function addTag(Tag $tag): self

Thread::removeTag()

public function removeTag(?Tag $tag): self

Thread::getTaxa()

public function getTaxa(): Collection

Thread::getTaxonomy()

public function getTaxonomy(): Collection

Thread::addTaxon()

public function addTaxon($taxon): self

Thread::removeTaxon()

public function removeTaxon($taxon): self

Thread::getMentions()

public function getMentions(): Collection

Thread::addMention()

public function addMention(Mention $mention): self

Thread::removeMention()

public function removeMention(Mention $mention): self

Thread::getLikes()

public function getLikes(): Collection

Thread::addLike()

public function addLike(Like $like): self

Thread::removeLike()

public function removeLike(?Like $like): self

Thread::isLiked()

public function isLiked(?User $user, ?string $icon = null): bool

Thread::getCreatedAt()

public function getCreatedAt(): ?DateTimeInterface

Thread::getUpdatedAt()

public function getUpdatedAt(): ?DateTimeInterface

Thread::poke()

public function poke(): self

Thread::getPublishedAt()

public function getPublishedAt(): ?DateTimeInterface

Thread::getPublishTime()

public function getPublishTime(): ?int

Thread::getPublishTimeStr()

public function getPublishTimeStr(): ?string

Thread::setPublishedAt()

public function setPublishedAt(?DateTimeInterface $publishedAt): self

Thread::getKeywords()

public function getKeywords(?string $locale = null, int $inheritanceDepthIfNotSet = 0): array

Thread::setKeywords()

public function setKeywords(array $keywords, ?string $locale = null, int $inheritanceDepthIfNotSet = 0)
Throws

Exception

Thread::getHeadline()

public function getHeadline(?string $locale = null, int $inheritanceDepthIfNotSet = 0): ?string

Thread::setHeadline()

public function setHeadline(?string $headline, ?string $locale = null, int $inheritanceDepthIfNotSet = 0)
Throws

Exception

Thread::getTitle()

public function getTitle(?string $locale = null, int $inheritanceDepthIfNotSet = 0): ?string

Thread::setTitle()

public function setTitle(?string $title, ?string $locale = null, int $inheritanceDepthIfNotSet = 0)
Throws

Exception

Thread::getExcerpt()

public function getExcerpt(?string $locale = null, int $inheritanceDepthIfNotSet = 0): ?string

Thread::setExcerpt()

public function setExcerpt(?string $excerpt, ?string $locale = null, int $inheritanceDepthIfNotSet = 0)
Throws

Exception

Thread::getContent()

public function getContent(?string $locale = null, int $inheritanceDepthIfNotSet = 0): ?string

Thread::setContent()

public function setContent(?string $content, ?string $locale = null, int $inheritanceDepthIfNotSet = 0)
Throws

Exception

ThreadIntl class

class ThreadIntl implements TranslationInterface ThreadIntl.php:14

ThreadIntl::getTitle()

public function getTitle(): ?string

ThreadIntl::setTitle()

public function setTitle(?string $title)

ThreadIntl::getHeadline()

public function getHeadline(bool $fallback = false): ?string

ThreadIntl::setHeadline()

public function setHeadline(?string $headline)

ThreadIntl::getKeywords()

public function getKeywords(): array

ThreadIntl::setKeywords()

public function setKeywords(array $keywords)

ThreadIntl::getExcerpt()

public function getExcerpt(): ?string

ThreadIntl::setExcerpt()

public function setExcerpt(?string $excerpt)

ThreadIntl::getContent()

public function getContent(): ?string

ThreadIntl::setContent()

public function setContent(?string $content)

User class

class User implements SecurityUser, TwoFactorUser, IconizeInterface, AutocompleteInterface User.php:59

public static $userIdentifier = "email"
const TOTP_LENGTH = 6
const TOTP_TIMEOUT = 30
const LEVELS = [0, 100, 250, 500, 1000]

Where that score puts them, as a discrete level.

Thresholds are the lower bound of each level and must stay ascending. A public constant rather than a setting because nothing reads it yet: when levels start gating anything real this wants to move behind base.settings, and one constant is a smaller thing to move than a scattering of inline numbers.

User::__autocomplete()

public function __autocomplete(): string

User::__autocompleteData()

public function __autocompleteData(): array

User::__toString()

public function __toString()

User::nameOf()

public static function nameOf(?self $user): ?string

How a member is named in a record of what they did (revisions, trash): the application's username when it has one, else the display name.

Not getUsername() on the base class: the admin builds URLs from any getUsername() it finds, and only a real column resolves back.

User::__iconize()

public function __iconize(): ?array

User::__iconizeStatic()

public static function __iconizeStatic(): ?array

User::getUserIdentifierField()

public static function getUserIdentifierField(): string

User::getUserIdentifier()

public function getUserIdentifier(): string

User::equals()

public function equals($other): bool

User::__construct()

public function __construct(?string $email = null)
Throws

Exception

User::getRecipient()

public function getRecipient(): Recipient

User::isGranted()

public function isGranted($role): bool

Whether the visitor is granted $role on this user, asked of the Access contract (plan "omnibase agnostique", C3e) where it was BaseService's: under Symfony the same authorization checker, with this user as the subject.

User::killSession()

public function killSession()

User::logout()

public function logout()

Signs this user out when it is the one signed in here (the Sessions contract, C4b: Security's token storage and the remember-me cookie under Symfony), else kicks it out of its sessions elsewhere.

User::getId()

public function getId(): ?int

User::setId()

public function setId($id): self

User::getTotpSecret()

public function getTotpSecret()

User::isTotpAuthenticationEnabled()

public function isTotpAuthenticationEnabled(): bool

User::getTotpAuthenticationUsername()

public function getTotpAuthenticationUsername(): string

User::getTotpAuthenticationConfiguration()

public function getTotpAuthenticationConfiguration(): ?TotpConfigurationInterface

User::setTotpSecret()

public function setTotpSecret($secret): self

User::isBackupCode()

public function isBackupCode(string $code): bool

User::invalidateBackupCode()

public function invalidateBackupCode(string $code): void

User::getBackupCodesCount()

public function getBackupCodesCount(): int

User::getBackupCodeHashes()

public function getBackupCodeHashes(): array

The backup codes as they are kept: password_hash()'s of each (omniauth's BackupCodes store, Base\Auth\UserBackupCodes).

User::setBackupCodeHashes()

public function setBackupCodeHashes(array $hashes): self
$hashes

password_hash()'s of the codes, never the codes

User::setBackupCodes()

public function setBackupCodes(array $plainCodes): self

User::isEmailAuthEnabled()

public function isEmailAuthEnabled(): bool

User::setEmailAuthEnabled()

public function setEmailAuthEnabled(bool $emailAuthEnabled): self

User::getEmailAuthRecipient()

public function getEmailAuthRecipient(): string

User::getEmailAuthCode()

public function getEmailAuthCode(): ?string

User::setEmailAuthCode()

public function setEmailAuthCode(?string $authCode): void

The code sent by e-mail as it is kept: scheb/2fa wrote the code itself, omniauth its keyed hash (Base\Auth\UserEmailCodes, QA5); null once used.

User::getTrustedTokenVersion()

public function getTrustedTokenVersion(): int

User::invalidateTrustedDevices()

public function invalidateTrustedDevices(): self

Bump this to invalidate every previously-trusted device for this user (e.g. after disabling 2FA).

User::getEmail()

public function getEmail(): ?string

User::setEmail()

public function setEmail(string $email): self

User::getPhone()

public function getPhone(): ?string

User::setPhone()

public function setPhone(?string $phone): self

User::getAvatar()

public function getAvatar()
Throws

Exception

User::getAvatarFile()

public function getAvatarFile()
Throws

FilesystemException

User::setAvatar()

public function setAvatar($avatar)

User::getColor()

public function getColor(): ?string

User::setColor()

public function setColor(?string $color): self

User::getLocale()

public function getLocale(): ?string

User::setLocale()

public function setLocale(?string $locale = null): self

User::getPlainPassword()

public function getPlainPassword(): ?string

User::setPlainPassword()

public function setPlainPassword(?string $password): void

User::__serialize()

public function __serialize(): array

User::erasePlainPassword()

public function erasePlainPassword()

User::eraseCredentials()

public function eraseCredentials(): void

User::getPassword()

public function getPassword(): ?string

User::setPassword()

public function setPassword(string $password): self

User::getIdentityProvider()

public function getIdentityProvider(): ?string

User::setIdentityProvider()

public function setIdentityProvider(?string $identityProvider): self

User::isFederated()

public function isFederated(): bool

User::isPersistent()

public function isPersistent(): bool

User::getRoles()

public function getRoles(): array

Effective roles for security checks: this user's own roles unioned with every group they belong to. Memoized per-instance (busted by setRoles()/addGroup()/removeGroup()) since this is called on every auth check and getGroups() would otherwise trigger a lazy load each time.

User::getOwnRoles()

public function getOwnRoles(): array

Only this user's own roles - what the roles column stores, what edit forms bind to.

User::setRoles()

public function setRoles(array $roles): self

User::setOwnRoles()

public function setOwnRoles(array $roles): self

Alias so form binding on 'ownRoles' has a matching setter - writes only the own column, same as setRoles().

User::getGroups()

public function getGroups(): Collection

User::addGroup()

public function addGroup(Group $group): self

User::removeGroup()

public function removeGroup(Group $group): self

User::getPermissions()

public function getPermissions(): Collection

User::addPermission()

public function addPermission(Permission $permission): self

User::removePermission()

public function removePermission(Permission $permission): self

User::getSanctions()

public function getSanctions(): Collection

User::getActiveSanctions()

public function getActiveSanctions(?DateTimeInterface $at = null): Collection

Only the ones still standing: not lifted, not lapsed.

User::addSanction()

public function addSanction(Sanction $sanction): self

User::removeSanction()

public function removeSanction(Sanction $sanction): self

User::getPenalties()

public function getPenalties(?DateTimeInterface $at = null): array

The catalogue entries behind the sanctions still standing.

Kept under the old name so callers asking "what penalties does this user have" still read naturally, but it now answers with what is in force rather than with everything ever recorded.

User::getScore()

public function getScore(?DateTimeInterface $at = null): int

What this account is worth right now.

The sum of every sanction still in force, plus whatever the groups it belongs to carry. Signed, because the catalogue is: a penalty may cost points and a credit may award them, so one number answers both "is this account in trouble" and "has it earned its way in somewhere".

Group penalties count because membership is the point of a group - a group under sanction puts every member under it, without having to write the same sanction out per head.

Not cached. The obvious cache is per-request, and the obvious bug is a moderator lifting a sanction and the score not moving until the next page load; callers that need it hot should hold it themselves.

User::getLevel()

public function getLevel(?DateTimeInterface $at = null): int

User::getNotifications()

public function getNotifications()

User::addNotification()

public function addNotification(Notification $notification): self

User::removeNotification()

public function removeNotification(Notification $notification): self

User::isTester()

public function isTester()

User::getExpiredTokens()

public function getExpiredTokens(): Collection

User::getValidTokens()

public function getValidTokens(): Collection

User::getTokens()

public function getTokens($type = Token::ALL): Collection

User::removeExpiredTokens()

public function removeExpiredTokens(): self

User::getExpiredToken()

public function getExpiredToken(string $name): ?Token

User::getValidToken()

public function getValidToken(string $name): ?Token

User::getToken()

public function getToken(string $name, $type = Token::ALL): ?Token

User::addToken()

public function addToken(Token $token): self

User::removeTokenByName()

public function removeTokenByName(?string $name): self

User::removeToken()

public function removeToken(Token $token): self

User::getThreads()

public function getThreads(): Collection

User::addThread()

public function addThread(Thread $thread): self

User::removeThread()

public function removeThread(Thread $thread): self

User::isFollowing()

public function isFollowing(Thread $followedThread): bool

User::getFollowedThreads()

public function getFollowedThreads(): Collection

User::addFollowedThread()

public function addFollowedThread(Thread $thread): self

User::removeFollowedThread()

public function removeFollowedThread(Thread $thread): self

User::getMentions()

public function getMentions(): Collection

User::addMentions()

public function addMentions(Mention $mentions): self

User::removeMentions()

public function removeMentions(Mention $mentions): self

User::getLikes()

public function getLikes(): Collection

User::addLike()

public function addLike(Like $like): self

User::removeLike()

public function removeLike(Like $like): self

User::getStates()

public function getStates(): array

User::setStates()

public function setStates(array $states): self

User::newcomer()

public function newcomer(bool $newState = true): self

User::elder()

public function elder(bool $newState = true): self

User::isNewcomer()

public function isNewcomer(): bool

User::isElder()

public function isElder(): bool

User::setIsNewcomer()

public function setIsNewcomer(bool $newState): self

User::approve()

public function approve(bool $newState = true): self

User::disregarded()

public function disregarded(bool $newState = true): self

User::isApproved()

public function isApproved(): bool

User::isDisregarded()

public function isDisregarded(): bool

User::setIsApproved()

public function setIsApproved(bool $newState): self

User::verify()

public function verify(bool $newState = true): self

User::isVerified()

public function isVerified(): bool

User::setIsVerified()

public function setIsVerified(bool $newState)

User::enable()

public function enable(bool $newState = true): self

User::disable()

public function disable(bool $newState = true): self

User::isEnabled()

public function isEnabled(): bool

User::isDisabled()

public function isDisabled(): bool

User::setIsEnabled()

public function setIsEnabled(bool $newState): self

User::lock()

public function lock(bool $newState = true): self

User::unlock()

public function unlock(bool $newState = true): self

User::isLocked()

public function isLocked(): bool

User::setIsLocked()

public function setIsLocked(bool $newState): self

User::ban()

public function ban(bool $newState = true): self

User::unban()

public function unban(bool $newState = true): self

User::isBanned()

public function isBanned(): bool

User::setIsBanned()

public function setIsBanned(bool $newState = true): self

User::kick()

public function kick(bool $newState = true): self

User::unkick()

public function unkick(bool $newState = true): self

User::isKicked()

public function isKicked(): bool

User::setIsKicked()

public function setIsKicked(bool $newState = true): self

User::ghost()

public function ghost(bool $newState = true): self

User::isGhost()

public function isGhost(): bool

User::setIsGhost()

public function setIsGhost(bool $newState): self

User::getBirthdate()

public function getBirthdate(): ?DateTimeInterface

User::setBirthdate()

public function setBirthdate(?DateTimeInterface $birthdate): self

User::getAge()

public function getAge(): ?int

User::getCreatedAt()

public function getCreatedAt(): ?DateTimeInterface

User::getUpdatedAt()

public function getUpdatedAt(): ?DateTimeInterface

User::getActiveAt()

public function getActiveAt(): ?DateTimeInterface

User::poke()

public function poke(?DateTimeInterface $activeAt): self

User::getActiveDelay()

public static function getActiveDelay(): int

User::isActive()

public function isActive(): bool

User::getOnlineDelay()

public static function getOnlineDelay(): int

User::isOnline()

public function isOnline(): bool

User::getAddresses()

public function getAddresses(): Collection

User::getAddress()

public function getAddress(int $i = 0): ?Address

User::addAddress()

public function addAddress(Address $address): self

User::removeAddress()

public function removeAddress(Address $address): self

User::getConnections()

public function getConnections(): Collection

User::addConnection()

public function addConnection(Connection $connection): self

User::removeConnection()

public function removeConnection(Connection $connection): self

User::getPasskeys()

public function getPasskeys(): Collection

User::addPasskey()

public function addPasskey(Passkey $passkey): self

User::removePasskey()

public function removePasskey(Passkey $passkey): self

Base\EntityDispatcher

AbstractEvent class

abstract class AbstractEvent extends Event implements EventInterface, NamedEvent AbstractEvent.php:25

NB: Flushing object manager from within listener should be avoided, this is done already in event dispatcher if needed.

A NamedEvent (plan "omnibase agnostic", F5c): its dispatcher gives it the name it is raised under (user.register...), which a host's PSR-14 dispatcher listening by name reads. The request is the host's own object (Symfony's, or Laravel's, a subclass of it).

It carries the persistence's arguments of the moment it was dispatched at (plan "omnibase agnostic", step B leftover (a)): omnisense/omnibridge's Lifecycle event (AbstractEventDispatcher::lifecycle(), any persistence), or Doctrine's LifecycleEventArgs where Doctrine's event manager called the dispatcher. getObject() and getUnitOfWork() read either.

AbstractEvent::__construct()

public function __construct(LifecycleEventArgs|EntityEvent $eventArgs, ?object $request)

AbstractEvent::setEventName()

public function setEventName(string $eventName): static

AbstractEvent::eventName()

public function eventName(): string

AbstractEvent::getLifecycle()

public function getLifecycle(): LifecycleEventArgs|EntityEvent

The persistence's arguments of the moment: omnisense/omnibridge's Lifecycle event, or Doctrine's LifecycleEventArgs.

AbstractEvent::getUnitOfWork()

public function getUnitOfWork(): UnitOfWork

The unit of work the entity was written through, whichever persistence.

AbstractEvent::getRequest()

public function getRequest(): ?Request

AbstractEvent::getObjectManager()

public function getObjectManager()

since omnisense/omnibase 5.x, removed at 6.0: getUnitOfWork()

Doctrine's object manager under Doctrine's event manager; the unit of work otherwise.

AbstractEvent::getObjectClass()

public function getObjectClass(): string

AbstractEvent::getObject()

public function getObject(): object

AbstractEventDispatcher class

abstract class AbstractEventDispatcher implements EventDispatcherInterface, ResetInterface AbstractEventDispatcher.php:40

An entity dispatcher notes events before a write (persisting(), updating(), removing(): addEvent()) and dispatches them once the write is done, through any PSR-14 dispatcher (user.register, thread.published...).

It is called at a persistence's moments in two ways (plan "omnibase agnostic", step B leftover (a)): - lifecycle(), with omnisense/omnibridge's Lifecycle events (Omnibridge\Persistence\Lifecycle\PrePersist...): what a persistence other than Doctrine calls (omnibridge/eloquent), so that no Doctrine package is needed there; - prePersist() ... postRemove(), with doctrine/persistence's LifecycleEventArgs: Doctrine's event manager, where the dispatchers are its listeners (omnibridge/symfony's doctrine.event_listener tags, omnibridge/laravel's). Both reach the same hooks, persisting(PrePersist), updating(PreUpdate), removing(PreRemove). The former hooks, typed on doctrine/persistence (onPersist(), onUpdate(), onRemove() and the entries above), are deprecated until 6.0: a dispatcher that still overrides one is given it under Doctrine as before; on another persistence lifecycle() refuses it aloud, and a host that can build doctrine/persistence's arguments calls it the former way (formerHooks()).

const FORMER_HOOKS = ['onPersist' => 'persisting', 'onUpdate' => 'updating', 'onRemove' => 'removing', 'prePersist' => null, 'preUpdate' => null, 'preRemove' => null, 'postPersis…

The former hooks, typed on doctrine/persistence's LifecycleEventArgs => their neutral counterpart (null: none).

const DISPATCHER_SUFFIX = "Dispatcher"

AbstractEventDispatcher::live()

public static function live(): array
Returns

the dispatchers built in this process

AbstractEventDispatcher::__construct()

public function __construct(PsrEventDispatcherInterface $dispatcher, EntityHydratorInterface $entityHydrator, UnitOfWork|EntityManagerInterface $unitOfWork, Requests|RequestStack|null $requests = null)
$unitOfWork

the entity manager is deprecated (until 6.0): adapted by UnitOfWorks

$requests

Symfony's RequestStack is deprecated (until 6.0): adapted by RequestsOf

AbstractEventDispatcher::getEventClass()

public static function getEventClass()
Throws

Exception

AbstractEventDispatcher::addEvent()

public function addEvent(string $event, mixed $object)

AbstractEventDispatcher::dispatchEvents()

public function dispatchEvents(LifecycleEventArgs $event)

since omnisense/omnibase 5.x, removed at 6.0: the events are dispatched by lifecycle() or by the former entries postPersist(), postUpdate(), postRemove()

AbstractEventDispatcher::lifecycle()

public function lifecycle(Lifecycle\EntityEvent $event): void

A persistence's moment, as omnisense/omnibridge's Lifecycle event (plan "omnibase agnostic", step B leftover (a)): before a write the dispatcher notes its events (persisting(), updating(), removing(), for an entity it supports), after it dispatches them. The other moments (a flush, a load) are not the dispatchers'. Nothing of doctrine/persistence is needed. A dispatcher still overriding a former hook is refused aloud: it is called with doctrine/persistence's arguments, by a host that can build them (formerHooks()).

AbstractEventDispatcher::formerHooks()

public static function formerHooks(string|self $dispatcher): array

The former hooks a dispatcher overrides (FORMER_HOOKS), each without its neutral counterpart overridden at the same level or below: what only doctrine/persistence's LifecycleEventArgs can call. [] for a dispatcher on the neutral hooks.

AbstractEventDispatcher::postFlush()

public function postFlush(PostFlushEventArgs $event): void

Nothing is flushed here any more: see $flushPending.

AbstractEventDispatcher::flushPending()

public function flushPending(): void

What the listeners changed, flushed - outside any flush. A flush may raise events again, whose listeners change more: a few rounds at most.

AbstractEventDispatcher::reset()

public function reset(): void

Keyed by spl_object_id, which PHP gives again to a new object once the old one is gone: in a worker, a message's entity inherited the events (or the "already sent" mark) of an earlier one's.

AbstractEventDispatcher::getEntityManager()

public function getEntityManager()

since omnisense/omnibase 4.x, removed at 6.0: getUnitOfWork()

AbstractEventDispatcher::getUnitOfWork()

public function getUnitOfWork(): UnitOfWork

AbstractEventDispatcher::getAssociationChangeSet()

public function getAssociationChangeSet($entity): array

AbstractEventDispatcher::getAssociationDeleteDiff()

public function getAssociationDeleteDiff($entity, $field): array

AbstractEventDispatcher::getAssociationInsertDiff()

public function getAssociationInsertDiff($entity, $field): array

AbstractEventDispatcher::prePersist()

public function prePersist(LifecycleEventArgs $event)

Doctrine's event manager's prePersist (deprecated until 6.0 for any other caller: lifecycle()).

AbstractEventDispatcher::preUpdate()

public function preUpdate(LifecycleEventArgs $event)

Doctrine's event manager's preUpdate, its changes (PreUpdateEventArgs) given to updating().

AbstractEventDispatcher::preRemove()

public function preRemove(LifecycleEventArgs $event)

Doctrine's event manager's preRemove.

AbstractEventDispatcher::postPersist()

public function postPersist(LifecycleEventArgs $event)

AbstractEventDispatcher::postUpdate()

public function postUpdate(LifecycleEventArgs $event)

AbstractEventDispatcher::postRemove()

public function postRemove(LifecycleEventArgs $event)

AbstractEventDispatcher::persisting()

public function persisting(Lifecycle\PrePersist $event): void

Before a supported entity is inserted: the events to dispatch once it is (addEvent()).

AbstractEventDispatcher::updating()

public function updating(Lifecycle\PreUpdate $event): void

Before a supported entity is updated, its changes in the event (the original entity: EntityHydrator::getOriginalEntity($event)).

AbstractEventDispatcher::removing()

public function removing(Lifecycle\PreRemove $event): void

Before a supported entity is removed.

AbstractEventDispatcher::onPersist()

public function onPersist(LifecycleEventArgs $event)

since omnisense/omnibase 5.x, removed at 6.0: persisting()

AbstractEventDispatcher::onUpdate()

public function onUpdate(LifecycleEventArgs $event)

since omnisense/omnibase 5.x, removed at 6.0: updating()

AbstractEventDispatcher::onRemove()

public function onRemove(LifecycleEventArgs $event)

since omnisense/omnibase 5.x, removed at 6.0: removing()

EventDispatcherInterface interface

interface EventDispatcherInterface EventDispatcherInterface.php:14

An entity dispatcher (AbstractEventDispatcher). The methods typed on doctrine/persistence's LifecycleEventArgs are deprecated since omnisense/omnibase 5.x and leave at 6.0: AbstractEventDispatcher's neutral hooks (persisting(), updating(), removing()) and its entry lifecycle() need no Doctrine package (plan "omnibase agnostic", step B leftover (a)).

EventDispatcherInterface::supports()

public function supports(mixed $subject): bool

EventDispatcherInterface::addEvent()

public function addEvent(string $event, mixed $subject)

EventDispatcherInterface::dispatchEvents()

public function dispatchEvents(LifecycleEventArgs $event)

EventDispatcherInterface::onPersist()

public function onPersist(LifecycleEventArgs $event)

EventDispatcherInterface::onUpdate()

public function onUpdate(LifecycleEventArgs $event)

EventDispatcherInterface::onRemove()

public function onRemove(LifecycleEventArgs $event)

EventInterface interface

interface EventInterface EventInterface.php:7

EventInterface::getObjectManager()

public function getObjectManager()

EventInterface::getObjectClass()

public function getObjectClass(): string

EventInterface::getObject()

public function getObject(): object

Base\EntityDispatcher\Event

ThreadEvent class

class ThreadEvent extends AbstractEvent ThreadEvent.php:8

const SCHEDULED = 'thread.scheduled'
const PUBLISHABLE = 'thread.publishable'
const PUBLISHED = 'thread.published'

ThreadEvent::getThread()

public function getThread(): Thread

ThreadEventDispatcher class

class ThreadEventDispatcher extends AbstractEventDispatcher ThreadEventDispatcher.php:10

ThreadEventDispatcher::supports()

public function supports(mixed $subject): bool

ThreadEventDispatcher::persisting()

public function persisting(Lifecycle\PrePersist $event): void

ThreadEventDispatcher::updating()

public function updating(Lifecycle\PreUpdate $event): void

UserEvent class

class UserEvent extends AbstractEvent UserEvent.php:14

The user.* events: UserEventDispatcher dispatches user.register when an account is persisted, and each other one when an update puts the account in that state (approved, verified, enabled, disabled, kicked out, locked, newcomer, banned; user.ghost when it stops being a ghost).

const REGISTER = 'user.register'
const VERIFIED = 'user.verified'
const APPROVAL = 'user.approval'
const DISABLED = 'user.disabled'
const ENABLED = 'user.enabled'
const KICKED = 'user.kickout'
const LOCKED = 'user.locked'
const NEWCOMER = 'user.newcomer'
const GHOST = 'user.ghost'
const BANNED = 'user.banned'

UserEvent::getUser()

public function getUser(): User

UserEventDispatcher class

class UserEventDispatcher extends AbstractEventDispatcher UserEventDispatcher.php:9

UserEventDispatcher::supports()

public function supports(mixed $subject): bool

UserEventDispatcher::persisting()

public function persisting(Lifecycle\PrePersist $event): void

UserEventDispatcher::updating()

public function updating(Lifecycle\PreUpdate $event): void

Base\EntitySubscriber

ConnectionSubscriber class

class ConnectionSubscriber implements EventSubscriberInterface ConnectionSubscriber.php:21

ConnectionSubscriber::__construct()

public function __construct(UserTracker $userTracker, UnitOfWork|EntityManagerInterface $unitOfWork)

ConnectionSubscriber::getSubscribedEvents()

public static function getSubscribedEvents(): array

ConnectionSubscriber::onCheckPassport()

public function onCheckPassport(CheckPassportEvent $event)

ConnectionSubscriber::onLoginFailure()

public function onLoginFailure(LoginFailureEvent $event)

ConnectionSubscriber::onLoginSuccess()

public function onLoginSuccess(LoginSuccessEvent $event)

ConnectionSubscriber::onLogout()

public function onLogout(LogoutEvent $event)

ThreadSubscriber class

class ThreadSubscriber implements EventSubscriberInterface ThreadSubscriber.php:24

The threads' kernel events (thread.scheduled, thread.publishable: the state, the authors' and the mentionees' mails) and the Doctrine wiring of their followers and mentions (prePersist, onFlush), whose logic is Base\Database\Lifecycle\ThreadParticipants, on the neutral lifecycle events.

ThreadSubscriber::__construct()

public function __construct(MentionEnhancerInterface|\Closure $mentionEnhancer)

ThreadSubscriber::getSubscribedEvents()

public static function getSubscribedEvents(): array

ThreadSubscriber::onSchedule()

public function onSchedule(ThreadEvent $event)

ThreadSubscriber::onPublishable()

public function onPublishable(ThreadEvent $event)

ThreadSubscriber::prePersist()

public function prePersist(PrePersistEventArgs $event): void

A new reply followed by its parent's owners.

ThreadSubscriber::onFlush()

public function onFlush(OnFlushEventArgs $event): void

The mentions of every thread whose text this flush writes (a translation inserted, or its content changed) or that this flush makes publishable (an update that leaves the text alone otherwise - poke(), a counter - parses nothing), and the followers of a reply moved under another parent.

The followers are added here, not at preUpdate, where Doctrine writes no collection changed; the thread's change set is then computed again with its collections (computeChangeSet(), Doctrine's: the neutral UnitOfWork::recompute() is recomputeSingleEntityChangeSet(), fields only).

UserSubscriber class

class UserSubscriber implements EventSubscriberInterface, ResetInterface UserSubscriber.php:24

What an account's owner is told when the account changes (UserEventDispatcher raises the events): a registration asks to verify the address, an approval is confirmed, an account its owner closes is said goodbye to, one reopened welcomed back. Each notification goes out with its importance, through the site's channel policy (framework.notifier.channel_policy).

The owner is told only of what they did themselves, or of what happened with nobody signed in (a command, a worker): an administrator closing someone's account sends nothing.

const VERIFY_EMAIL_EXPIRY = 24 * 3600

The verification link's lifetime and the delay before another can be asked, as SecurityController's.

const VERIFY_EMAIL_THROTTLE = 3600

UserSubscriber::__construct()

public function __construct(protected Notifier $notifier, protected Access|TokenStorageInterface $access)
$access

who is signed in (plan "omnibase agnostic", F5c); Symfony's token storage is deprecated (until 6.0)

UserSubscriber::listen()

public function listen(callable $listen): void

The listeners of a host that listens by name (Laravel's: omnibridge/laravel's DispatcherEvents gives a NamedEvent to the listeners of its name), as getSubscribedEvents() gives them to Symfony's.

UserSubscriber::preFlush()

public function preFlush(): void

The events come from inside a flush (UserEventDispatcher, postPersist/postUpdate): a token revoked there leaves its user, but its orphan removal is forgotten when the flush ends (postFlush included), and the next flush wrote the token with no user (userToken.user_id is NOT NULL). Revoked as the next flush begins (the response's, EntityDispatcherFlushSubscriber), it is removed by it.

UserSubscriber::reset()

public function reset(): void

UserSubscriber::getSubscribedEvents()

public static function getSubscribedEvents(): array

UserSubscriber::onRegistration()

public function onRegistration(UserEvent $event): void

UserSubscriber::onApproval()

public function onApproval(UserEvent $event): void

UserSubscriber::onEnabling()

public function onEnabling(UserEvent $event): void

UserSubscriber::onDisabling()

public function onDisabling(UserEvent $event): void

Base\Entity\Analytics

PageView class

class PageView PageView.php:27

One row per (path, HOUR, source) - an hourly rolling aggregate, not a per-request event log. $views is incremented atomically (see PageViewRepository, which buckets any timestamp down to the top of its hour before writing) on every trackable request; time windows ("24h", "7 days", "all time") are just a SUM over however many of these rows fall in range, and a calendar-day figure (dailyBreakdown()) is itself a SUM over that day's up-to-24 hourly rows rather than its own storage grain - this is what lets "today" plot an hour-by-hour curve instead of the single flat point a pure daily rollup could ever produce.

$source splits that aggregate three ways (see Base\Service\Analytics\ UserAgentClassifier, which is what decides it at track() time) so a dashboard can tell real visitors apart from search/monitoring crawlers (SOURCE_BOT) and AI/LLM crawlers (SOURCE_AI) instead of one number that silently mixes all three. Rows written before this column existed (or by a raw INSERT that omits it, as the test suite's seed data does) default to SOURCE_HUMAN - the historic assumption this table always made.

const SOURCE_HUMAN = "human"
const SOURCE_BOT = "bot"
const SOURCE_AI = "ai"

PageView::getId()

public function getId(): ?int

PageView::getPath()

public function getPath(): ?string

PageView::setPath()

public function setPath(string $path): self

PageView::getDate()

public function getDate(): ?\DateTimeImmutable

PageView::setDate()

public function setDate(\DateTimeImmutable $date): self

PageView::getViews()

public function getViews(): int

PageView::setViews()

public function setViews(int $views): self

PageView::getSource()

public function getSource(): string

PageView::setSource()

public function setSource(string $source): self

PageVisit class

class PageVisit PageVisit.php:22

An HOURLY PRESENCE record per page: at most one row per (hour, path, subjectType, subjectId), inserted on first sight and ignored afterwards - the same mechanism as Visit, with the path added.

It exists because neither existing table can answer "unique views". PageView is a raw hit counter per (path, hour, source), so reloading a page ten times is ten views; Visit knows who came but not what they looked at, and nothing links the two. A unique view is one subject on one page, which is exactly the row this table keeps. PageView stays the non-unique count.

Human traffic only, and only for an identified subject: a consented visitor cookie or an authenticated user - see Analytics::track().

PageVisit::getId()

public function getId(): ?int

PageVisit::getDate()

public function getDate(): ?\DateTimeImmutable

PageVisit::setDate()

public function setDate(\DateTimeImmutable $date): self

PageVisit::getPath()

public function getPath(): ?string

PageVisit::setPath()

public function setPath(string $path): self

PageVisit::getSubjectType()

public function getSubjectType(): ?string

PageVisit::setSubjectType()

public function setSubjectType(string $subjectType): self

PageVisit::getSubjectId()

public function getSubjectId(): ?string

PageVisit::setSubjectId()

public function setSubjectId(string $subjectId): self

Visit class

class Visit Visit.php:29

An HOURLY PRESENCE record, not a per-request event log: at most one row per (hour, subjectType, subjectId) - see VisitRepository, which buckets any timestamp down to the top of its hour before writing - inserted on first sight that hour and ignored on every later request the same hour.

COUNT(DISTINCT subjectId) still gives an exact unique count over any window regardless of grain (a subject seen in two different hours of the same day contributes two rows but ONE distinct id, so a day/week/all-time total is never inflated); the finer grain only changes what an hour-by- hour BREAKDOWN can show (a subject active at 9am and 2pm now shows up in both hourly buckets, same as it already showed up on multiple separate DAYS in a multi-day breakdown before this). Unlike PageView (a raw hit counter), a returning subject never inflates this table twice in the same hour, and the table stays bounded by (subjects x hours), not raw traffic.

subjectType is "visitor" (an anonymous, cookie-identified browser - see Base\Service\Analytics for the consent-gating this depends on) or "user" (an authenticated Base\Entity\User's id) - two independent counters sharing one mechanism rather than two parallel tables.

const TYPE_VISITOR = "visitor"
const TYPE_USER = "user"

Visit::getId()

public function getId(): ?int

Visit::getDate()

public function getDate(): ?\DateTimeImmutable

Visit::setDate()

public function setDate(\DateTimeImmutable $date): self

Visit::getSubjectType()

public function getSubjectType(): ?string

Visit::setSubjectType()

public function setSubjectType(string $subjectType): self

Visit::getSubjectId()

public function getSubjectId(): ?string

Visit::setSubjectId()

public function setSubjectId(string $subjectId): self

Base\Entity\Extension

Revision class

class Revision extends AbstractExtension Revision.php:25

One entry of an entity's modification history: what changed in a single flush, as entityData = {"<field>": [old, new]}.

NB the hash used to be #[ORM\Column(type:"integer")] #[Hashify(random:true)], which could not work in either direction: Hashify hands prePersist a hashed STRING for an integer column, and its postPersist calls erasePlainMessage(), which throws outright when no reference column is configured - so the very first Revision ever persisted would have taken the flush down with it. It went unnoticed because nothing ever wrote one. getHashShort() shows the intent was a git-style short hash, so that is what it now is.

Revision::__iconizeStatic()

public static function __iconizeStatic(): ?array

Revision::__construct()

public function __construct()

Revision::getHash()

public function getHash()

Revision::getHashShort()

public function getHashShort()

Revision::getFields()

public function getFields(): array

Field names this revision touched, with the locale prefix stripped off.

Revision::getPreviousValue()

public function getPreviousValue(string $field): mixed

The value $field held BEFORE this revision - what a restore puts back.

Revision::getNextValue()

public function getNextValue(string $field): mixed

Revision::supports()

public function supports(): bool

TrashBall class

class TrashBall extends AbstractExtension TrashBall.php:13

TrashBall::__iconizeStatic()

public static function __iconizeStatic(): ?array

TrashBall::getPermanentAfter()

public function getPermanentAfter(): ?DateTimeInterface

TrashBall::setPermanentAfter()

public function setPermanentAfter(DateTimeInterface $permanentAfter): self

TrashBall::supports()

public function supports(): bool

Base\Entity\Extension\Abstract

AbstractExtension class

abstract class AbstractExtension implements AbstractExtensionInterface, IconizeInterface AbstractExtension.php:17

AbstractExtension::__iconize()

public function __iconize(): ?array

AbstractExtension::__iconizeStatic()

public static function __iconizeStatic(): ?array

AbstractExtension::getId()

public function getId()

AbstractExtension::getImpersonator()

public function getImpersonator(): ?User

AbstractExtension::getInitiator()

public function getInitiator(): ?User

AbstractExtension::getEntityId()

public function getEntityId()

AbstractExtension::setEntityId()

public function setEntityId(mixed $entityOrId)

AbstractExtension::getEntityClass()

public function getEntityClass()

AbstractExtension::setEntityClass()

public function setEntityClass(object|string $entity)

AbstractExtension::getAction()

public function getAction()

AbstractExtension::setAction()

public function setAction(string $action)

AbstractExtension::isEmpty()

public function isEmpty()

AbstractExtension::getEntityData()

public function getEntityData(): array

AbstractExtension::setEntityData()

public function setEntityData(array $entityData)

AbstractExtension::getCreatedAt()

public function getCreatedAt(): ?DateTimeInterface

AbstractExtension::setCreatedAt()

public function setCreatedAt(DateTimeInterface $createdAt): self

AbstractExtensionInterface interface

interface AbstractExtensionInterface extends EntityMetadataInterface AbstractExtensionInterface.php:7

Base\Entity\Hours

ScopedWeek class

class ScopedWeek ScopedWeek.php:18

The usual week of one place, when a site has several: a shop among the shops, a practice among the practices. The place is a scope key - any string its owner chooses ("store:12"), or an entity (Base\Service\OpeningHours::scopeOf()).

The site's own week stays where it was (WeekDayHours, one row per day, else base.opening_hours.week): a place without a row here follows it. One row per place, the seven days together: {"1": [["09:00","13:00"]], ...}.

ScopedWeek::__construct()

public function __construct(string $scope, array $week = [])

ScopedWeek::getId()

public function getId(): ?int

ScopedWeek::getScope()

public function getScope(): string

ScopedWeek::getWeek()

public function getWeek(): array
Returns

all seven days

ScopedWeek::setWeek()

public function setWeek(array $week): static
$week

ISO day => hours, in order, closing after opening

SpecialDay class

class SpecialDay SpecialDay.php:19

A day (or a run of days) off the usual week: closed (holidays, a bank holiday), or open at other hours ([["10:00","14:00"]]). Read by Base\Service\OpeningHours everywhere (the day an order is for, the time slots, the footer, a banner, the JSON-LD's specialOpeningHoursSpecification).

Without a scope it is the whole site's; with one, that place's only (ScopedWeek: "store:12"), where it wins over the site's on the same date.

Its own table (hoursSpecialDay), see WeekDayHours.

SpecialDay::__construct()

public function __construct(\DateTimeInterface $from, ?\DateTimeInterface $until = null, ?string $reason = null, ?string $scope = null)

SpecialDay::getId()

public function getId(): ?int

SpecialDay::getStartsOn()

public function getStartsOn(): string

SpecialDay::getEndsOn()

public function getEndsOn(): string

SpecialDay::getReason()

public function getReason(): ?string

SpecialDay::setReason()

public function setReason(?string $reason): static

SpecialDay::getCreatedAt()

public function getCreatedAt(): \DateTimeImmutable

SpecialDay::getScope()

public function getScope(): ?string

SpecialDay::getHours()

public function getHours(): ?array

SpecialDay::setHours()

public function setHours(?array $hours): static

SpecialDay::isClosed()

public function isClosed(): bool

SpecialDay::covers()

public function covers(\DateTimeInterface $day): bool

SpecialDay::isOneDay()

public function isOneDay(): bool

SpecialDay::from()

public function from(): \DateTimeImmutable

SpecialDay::until()

public function until(): \DateTimeImmutable

WeekDayHours class

class WeekDayHours WeekDayHours.php:18

The usual hours of one day of the week: [["09:00","13:00"],["16:30","19:00"]], or none (closed). No row at all: the week the site was configured with (base.opening_hours.week), read by Base\Service\OpeningHours. Special days (SpecialDay) override a date.

Its own table (hoursWeekDay): an application that still keeps a copy of its own (Nakaya's weekDayHours) is not disturbed; moving onto this one is a RENAME TABLE.

WeekDayHours::__construct()

public function __construct(int $weekday, array $hours = [])

WeekDayHours::getWeekday()

public function getWeekday(): int

WeekDayHours::getId()

public function getId(): int

omnibase's listeners ask every entity for one.

WeekDayHours::getHours()

public function getHours(): array

WeekDayHours::setHours()

public function setHours(array $hours): static
$hours

in order, closing after opening

Base\Entity\Layout

Attribute class

abstract class Attribute extends AbstractAttribute implements TranslatableInterface Attribute.php:15

Attribute::__construct()

public function __construct(AbstractAdapter $adapter, mixed $value = null)

Attribute::__toString()

public function __toString()

Attribute::get()

public function get(?string $locale = null): mixed

Attribute::set()

public function set(...$args): self

Attribute::resolve()

public function resolve(?string $locale = null): mixed

AttributeIntl class

class AttributeIntl implements TranslationInterface AttributeIntl.php:16

AttributeIntl::isEmpty()

public function isEmpty(): bool

AttributeIntl::getValue()

public function getValue()
Throws

Exception

AttributeIntl::getValueFile()

public function getValueFile()
Throws

FilesystemException

AttributeIntl::setValue()

public function setValue($value)

AttributeIntl::getClass()

public function getClass(): ?string

AttributeIntl::setClass()

public function setClass(?string $class)

Image class

class Image implements IconizeInterface, ImageInterface, SaltInterface Image.php:27

Image::getSalt()

public function getSalt(): string
public function __toLink(array $routeParameters = [], int $referenceType = Link::ABSOLUTE_PATH): ?string

The image route's address for this image (its source obfuscated with the crop, thumbnail and filters asked): the Media contract and the Urls contract (C4b), MediaService's and the router's strings under Symfony.

Image::__iconize()

public function __iconize(): ?array

Image::__iconizeStatic()

public static function __iconizeStatic(): ?array

Image::__toString()

public function __toString()

Image::__construct()

public function __construct($src = null)

Image::getId()

public function getId(): ?int

Image::getSource()

public function getSource()
Throws

Exception

Image::getSourceFile()

public function getSourceFile()
Throws

FilesystemException

Image::setSource()

public function setSource($source): static

Image::getNaturalWidth()

public function getNaturalWidth(): ?int

Image::getNaturalHeight()

public function getNaturalHeight(): ?int

Image::getSourceMeta()

public function getSourceMeta(): array|null|false

Image::get()

public function get()

Image::getFile()

public function getFile()

Image::set()

public function set($source): self

Image::getQuadrant()

public function getQuadrant(): string

Image::getQuadrantPosition()

public function getQuadrantPosition(): string

Image::setQuadrant()

public function setQuadrant(string $quadrant): self

Image::getCrops()

public function getCrops(): Collection

Image::getCrop()

public function getCrop(string $identifier): ?ImageCrop

Image::addCrop()

public function addCrop(ImageCrop $crop): self

Image::removeCrop()

public function removeCrop(ImageCrop $crop): self

ImageCrop class

class ImageCrop implements LinkableInterface, SaltInterface ImageCrop.php:16

ImageCrop::getSalt()

public function getSalt(): string
public function __toLink(array $routeParameters = [], int $referenceType = Link::ABSOLUTE_PATH): ?string

The image route's address for this crop of its image: the Media contract (C4b), MediaService's strings under Symfony.

ImageCrop::__toString()

public function __toString()

ImageCrop::getRatio()

public function getRatio()

ImageCrop::isNormalized()

public function isNormalized()

ImageCrop::getId()

public function getId(): ?int

ImageCrop::getImage()

public function getImage(): ?Image

ImageCrop::setImage()

public function setImage(?Image $image): self

ImageCrop::getLabel()

public function getLabel(): ?string

ImageCrop::setLabel()

public function setLabel(?string $label): self

ImageCrop::getSlug()

public function getSlug(): ?string

ImageCrop::setSlug()

public function setSlug(?string $slug): self

ImageCrop::__construct()

public function __construct(?Image $image = null)

ImageCrop::getData()

public function getData(): array

ImageCrop::getX()

public function getX(?int $width = null): ?int

ImageCrop::getX0()

public function getX0(): ?float

ImageCrop::setX0()

public function setX0(float $x0): self

ImageCrop::getY()

public function getY(?int $height = null): ?int

ImageCrop::getY0()

public function getY0(): ?float

ImageCrop::setY0()

public function setY0(float $y0): self

ImageCrop::getPivotX()

public function getPivotX(?int $width = null)

ImageCrop::getXp()

public function getXp(): ?float

ImageCrop::setXp()

public function setXp(float $xP): self

ImageCrop::getPivotY()

public function getPivotY(?int $height = null)

ImageCrop::getYp()

public function getYp(): ?float

ImageCrop::setYp()

public function setYp(float $yP): self

ImageCrop::getNaturalWidth()

public function getNaturalWidth(): ?int

ImageCrop::getWidth()

public function getWidth(?int $width = null): ?int

ImageCrop::getWidth0()

public function getWidth0(): ?float

ImageCrop::setWidth0()

public function setWidth0(float $width0): self

ImageCrop::getNaturalHeight()

public function getNaturalHeight(): ?int

ImageCrop::getHeight()

public function getHeight(?int $height = null): ?int

ImageCrop::getHeight0()

public function getHeight0(): ?float

ImageCrop::setHeight0()

public function setHeight0(float $height0): self

ImageCrop::getScaleX()

public function getScaleX(): ?float

ImageCrop::setScaleX()

public function setScaleX(float $scaleX): self

ImageCrop::getScaleY()

public function getScaleY(): ?float

ImageCrop::setScaleY()

public function setScaleY(float $scaleY): self

ImageCrop::getRotate()

public function getRotate(): ?int

ImageCrop::setRotate()

public function setRotate(int $rotate): self

ImageCropInterface interface

interface ImageCropInterface ImageCropInterface.php:5

ImageCropInterface::getPivotX()

public function getPivotX()

ImageCropInterface::getPivotY()

public function getPivotY()

ImageCropInterface::getX()

public function getX(): ?int

ImageCropInterface::setX()

public function setX(int $x): self

ImageCropInterface::getY()

public function getY(): ?int

ImageCropInterface::setY()

public function setY(int $y): self

ImageCropInterface::getWidth()

public function getWidth(): ?int

ImageCropInterface::setWidth()

public function setWidth(int $width): self

ImageCropInterface::getHeight()

public function getHeight(): ?int

ImageCropInterface::setHeight()

public function setHeight(int $height): self

ImageCropInterface::getScaleX()

public function getScaleX(): ?float

ImageCropInterface::setScaleX()

public function setScaleX(float $scaleX): self

ImageCropInterface::getScaleY()

public function getScaleY(): ?float

ImageCropInterface::setScaleY()

public function setScaleY(float $scaleY): self

ImageCropInterface::getRotate()

public function getRotate(): ?int

ImageCropInterface::setRotate()

public function setRotate(int $rotate)

ImageInterface interface

interface ImageInterface ImageInterface.php:5

ImageInterface::getSource()

public function getSource()

ImageInterface::getSourceFile()

public function getSourceFile()

ImageInterface::setSource()

public function setSource($source): static

ImageInterface::getNaturalWidth()

public function getNaturalWidth(): ?int

ImageInterface::getNaturalHeight()

public function getNaturalHeight(): ?int

Redirection class

class Redirection Redirection.php:25

An address the site no longer answers, and where it leads now: the pages of a site taken over (/produit/enseigne-lumineuse/ -> /savoir-faire/enseigne), a page renamed. Asked only when a request ends in "not found" (Base\Subscriber\RedirectionSubscriber): a page that exists is never shadowed, and a page that is found costs nothing.

The source is a path, kept without its trailing slash ("/produit/enseigne"); with a query string ("/?p=123") it is matched with that query. Ending in "*" it covers everything beneath ("/categorie-produit/*"), and a "*" in the target then carries what the star stood for.

301 by default: the old address is gone for good, and search engines move what they know of it to the new one. 302 for a detour that will not last.

const PERMANENT = 301
const TEMPORARY = 302
const STATUSES = [self::PERMANENT, self::TEMPORARY]

Redirection::__construct()

public function __construct(string $source = '', string $target = '', int $status = self::PERMANENT)

Redirection::__toString()

public function __toString(): string

Redirection::normalize()

public static function normalize(string $address): string

An address as it is stored and compared: its path, without the site's host, without its trailing slash, with its query when it has one.

"https://old.example/produit/enseigne/?x=1#top" is "/produit/enseigne?x=1".

Redirection::getId()

public function getId(): ?int

Redirection::getSource()

public function getSource(): string

Redirection::setSource()

public function setSource(string $source): static

Redirection::isPrefix()

public function isPrefix(): bool

Covers everything beneath its path ("/categorie-produit/*").

Redirection::getTarget()

public function getTarget(): string

Redirection::setTarget()

public function setTarget(string $target): static

A path of the site ("/savoir-faire/enseigne") or a whole address ("https://...").

Redirection::getStatus()

public function getStatus(): int

Redirection::setStatus()

public function setStatus(int $status): static

Redirection::isEnabled()

public function isEnabled(): bool

Redirection::setEnabled()

public function setEnabled(bool $enabled): static

Redirection::getHits()

public function getHits(): int

Redirection::getLastHitAt()

public function getLastHitAt(): ?\DateTimeImmutable

Redirection::getCreatedAt()

public function getCreatedAt(): \DateTimeImmutable

Redirection::resolve()

public function resolve(string $address): ?string

Where this redirection sends $address (normalized), or null when it is not for it. A prefix carries what its star stood for into the target's.

Semantic class

class Semantic implements TranslatableInterface, IconizeInterface Semantic.php:20

Semantic::__iconize()

public function __iconize(): ?array

Semantic::__iconizeStatic()

public static function __iconizeStatic(): ?array
public function __toLink(int $referenceType = Link::ABSOLUTE_PATH): ?string

Semantic::__construct()

public function __construct(?string $routeName, array $routeParameters = [], ?string $label = null)

Semantic::getId()

public function getId(): ?int

Semantic::getRouteName()

public function getRouteName(): ?string

Semantic::setRouteName()

public function setRouteName(?string $routeName): self

Semantic::getRouteParameters()

public function getRouteParameters(): ?array

Semantic::setRouteParameters()

public function setRouteParameters(?array $routeParameters): self

Semantic::getPath()

public function getPath()

The path its route is declared with ("/articles/{slug}"): the Routes contract (C4b), the router's route collection under Symfony.

Semantic::getRoute()

public function getRoute(): ?string

The name of the route its address leads to (the Routes contract, C4b).

It handed the router's Route object to a string return type before, which threw for every route found.

Semantic::getRouteIcons()

public function getRouteIcons()

Its route's icons (the Routes contract, C4b: the IconProvider's under Symfony); null without a route.

Semantic::getUrl()

public function getUrl(): ?string

Semantic::enhance()

public function enhance(string $text, array $attributes = [])

Semantic::enhanceBy()

public function enhanceBy(string $text, array|string $keywords, array $attributes)

SemanticIntl class

class SemanticIntl implements TranslationInterface SemanticIntl.php:12

SemanticIntl::getLabel()

public function getLabel(): ?string

SemanticIntl::setLabel()

public function setLabel(?string $label)

SemanticIntl::getKeywords()

public function getKeywords(): array

SemanticIntl::setKeywords()

public function setKeywords(array $keywords)

Setting class

class Setting implements TranslatableInterface, IconizeInterface Setting.php:15

Setting::__iconize()

public function __iconize(): ?array

Setting::__iconizeStatic()

public static function __iconizeStatic(): ?array

Setting::__toString()

public function __toString()

Setting::__construct()

public function __construct(string $path, $value = null, $locale = null)
Throws

Exception

Setting::getId()

public function getId(): ?int

Setting::getPath()

public function getPath(): string

Setting::setPath()

public function setPath(string $path)

Setting::isLocked()

public function isLocked(): bool

Setting::getLocked()

public function getLocked(): bool

Setting::lock()

public function lock(): self

Setting::unlock()

public function unlock(): self

Setting::setLocked()

public function setLocked(bool $locked)

Setting::getBag()

public function getBag(): ?string

Setting::setBag()

public function setBag(?string $bag)

SettingIntl class

class SettingIntl implements TranslationInterface SettingIntl.php:16

SettingIntl::isEmpty()

public function isEmpty(): bool

SettingIntl::getLabel()

public function getLabel(): ?string

SettingIntl::setLabel()

public function setLabel(?string $label)

SettingIntl::getHelp()

public function getHelp(): ?string

SettingIntl::setHelp()

public function setHelp(?string $help)

SettingIntl::getValue()

public function getValue()
Throws

Exception

SettingIntl::getValueRaw()

public function getValueRaw()

Raw stored value (e.g. the upload uuid for file-backed settings), without the Uploader public-URL resolution applied by getValue().

Used by SettingBag's compiled snapshot so cached settings stay independent of the active media storage — the URL is derived at read time instead of being baked in at compile time.

SettingIntl::getValueFile()

public function getValueFile()
Throws

FilesystemException

SettingIntl::setValue()

public function setValue($value)

SettingIntl::getClass()

public function getClass(): ?string

SettingIntl::setClass()

public function setClass(?string $class)

class ShortLink implements TranslatableInterface, IconizeInterface, LinkableInterface ShortLink.php:19

public function __iconize(): ?array
public static function __iconizeStatic(): ?array
public function __toLink(array $routeParameters = [], int $referenceType = Link::ABSOLUTE_PATH): ?string

The short address, through the Urls contract (Base\Contract\Link): the router's own string under Symfony, made where there is no framework too.

public function __toString()
public function __construct(string $url = "", ?string $label = null)
public function getId(): ?int
public function getSlug(): ?string
public function setSlug(?string $slug)

ShortLinkIntl class

class ShortLinkIntl implements TranslationInterface ShortLinkIntl.php:12

ShortLinkIntl::getLabel()

public function getLabel(): ?string

ShortLinkIntl::setLabel()

public function setLabel(?string $label)

ShortLinkIntl::getUrl()

public function getUrl(): ?string

ShortLinkIntl::setUrl()

public function setUrl(string $url)

TextOverride class

class TextOverride TextOverride.php:19

A text of the site, as the team rewrote it from the back office: it replaces the one in translations/ for that key, domain and language (Base\Translation\OverridingTranslator), on every page and in every e-mail. Deleting it brings the original back. Same syntax as the original: {placeholders}, ICU plurals. Moved here from the apps' App\Entity\TextOverride (table textOverride there; this one is layoutTextOverride, so an app not moved yet keeps its own).

TextOverride::__construct()

public function __construct()

TextOverride::__toString()

public function __toString(): string

TextOverride::getId()

public function getId(): ?int

TextOverride::getDomain()

public function getDomain(): string

TextOverride::setDomain()

public function setDomain(string $domain): static

TextOverride::getKey()

public function getKey(): string

TextOverride::setKey()

public function setKey(string $key): static

TextOverride::getLocale()

public function getLocale(): string

TextOverride::setLocale()

public function setLocale(string $locale): static

TextOverride::getValue()

public function getValue(): string

TextOverride::setValue()

public function setValue(string $value): static

TextOverride::getUpdatedAt()

public function getUpdatedAt(): \DateTimeImmutable

Tooltip class

class Tooltip implements TranslatableInterface, IconizeInterface Tooltip.php:18

Tooltip::__iconize()

public function __iconize(): ?array

Tooltip::__iconizeStatic()

public static function __iconizeStatic(): ?array

Tooltip::__toString()

public function __toString()

Tooltip::__construct()

public function __construct(string $url = "", ?string $label = null)

Tooltip::getId()

public function getId(): ?int

Tooltip::getIcon()

public function getIcon()
Throws

Exception

Tooltip::getIconFile()

public function getIconFile()
Throws

FilesystemException

Tooltip::setIcon()

public function setIcon($icon)

Tooltip::getContent()

public function getContent(?string $locale = null, int $inheritanceDepthIfNotSet = 0): ?string

Tooltip::setContent()

public function setContent(?string $content, ?string $locale = null, int $inheritanceDepthIfNotSet = 0)
Throws

Exception

Tooltip::getCreatedAt()

public function getCreatedAt(): ?DateTimeInterface

Tooltip::getUpdatedAt()

public function getUpdatedAt(): ?DateTimeInterface

Tooltip::getStartedAt()

public function getStartedAt(): ?DateTimeInterface

Tooltip::getEndedAt()

public function getEndedAt(): ?DateTimeInterface

TooltipIntl class

class TooltipIntl implements TranslationInterface TooltipIntl.php:10

TooltipIntl::getTitle()

public function getTitle(): ?string

TooltipIntl::setTitle()

public function setTitle(?string $title)

TooltipIntl::getContent()

public function getContent(): ?string

TooltipIntl::setContent()

public function setContent(?string $content)

Widget class

class Widget implements TranslatableInterface, IconizeInterface, CacheableInterface Widget.php:29

Widget::__toKey()

public function __toKey(mixed ...$variadic): string

Widget::__iconize()

public function __iconize(): ?array

Widget::__iconizeStatic()

public static function __iconizeStatic(): ?array

Widget::__toString()

public function __toString()

Its title, else what a widget is called (the Nouns contract, C4b) and its number.

Widget::__construct()

public function __construct(?string $title = null, ?string $excerpt = null, ?string $content = null)

Widget::getTemplate()

public function getTemplate()

Widget::setTemplate()

public function setTemplate(?string $template)

Widget::getId()

public function getId(): ?int

Widget::getUuid()

public function getUuid()

Widget::getThumbnail()

public function getThumbnail()
Throws

Exception

Widget::getThumbnailFile()

public function getThumbnailFile()
Throws

FilesystemException

Widget::setThumbnail()

public function setThumbnail($thumbnail)

Widget::getConnexes()

public function getConnexes(): Collection

Widget::addConnex()

public function addConnex(Widget $connex): self

Widget::removeConnex()

public function removeConnex(Widget $connex): self

Widget::getCreatedAt()

public function getCreatedAt(): ?DateTimeInterface

Widget::getUpdatedAt()

public function getUpdatedAt(): ?DateTimeInterface

WidgetIntl class

class WidgetIntl implements TranslationInterface WidgetIntl.php:10

WidgetIntl::getTitle()

public function getTitle(): ?string

WidgetIntl::setTitle()

public function setTitle(?string $title): self

WidgetIntl::getHeadline()

public function getHeadline(): ?string

WidgetIntl::setHeadline()

public function setHeadline(?string $headline): self

WidgetIntl::getExcerpt()

public function getExcerpt(): ?string

WidgetIntl::setExcerpt()

public function setExcerpt(?string $excerpt): self

WidgetIntl::getContent()

public function getContent(): ?string

WidgetIntl::setContent()

public function setContent(?string $content): self

Base\Entity\Layout\Attribute

class Hyperlink extends AbstractAttribute implements TranslatableInterface, IconizeInterface Hyperlink.php:19

public function __construct(AbstractAdapter $adapter, mixed $value = null)
public function __iconize(): ?array
public static function __iconizeStatic(): ?array
public function __toString()
public function getHyperpattern(): ?HyperpatternAdapter
public function setHyperpattern(?HyperpatternAdapter $hyperpattern): self
public function generate(?string $locale = null)
public function getLabel(): string
public function get(?string $locale = null): mixed
public function set(...$args): self
public function resolve(?string $locale = null): mixed

HyperlinkIntl class

class HyperlinkIntl implements TranslationInterface HyperlinkIntl.php:9

HyperlinkIntl::isEmpty()

public function isEmpty(): bool

HyperlinkIntl::getValue()

public function getValue(): array

HyperlinkIntl::setValue()

public function setValue($value)

Base\Entity\Layout\Attribute\Adapter

ArrayAdapter class

class ArrayAdapter extends AbstractAdapter ArrayAdapter.php:13

ArrayAdapter::__iconizeStatic()

public static function __iconizeStatic(): ?array

ArrayAdapter::__construct()

public function __construct(string $label, ?string $path = null, ?int $length = null)

ArrayAdapter::getLength()

public function getLength(): ?int

ArrayAdapter::setLength()

public function setLength(?int $length)

ArrayAdapter::getType()

public static function getType(): string

ArrayAdapter::getOptions()

public function getOptions(): array

ArrayAdapter::resolve()

public function resolve(mixed $value): mixed

ColorAdapter class

class ColorAdapter extends AbstractAdapter ColorAdapter.php:14

ColorAdapter::__iconizeStatic()

public static function __iconizeStatic(): ?array

ColorAdapter::getType()

public static function getType(): string

ColorAdapter::getOptions()

public function getOptions(): array

ColorAdapter::resolve()

public function resolve(mixed $value): mixed

ColorAdapter::getName()

public function getName(?string $locale = null): string

CountryAdapter class

class CountryAdapter extends AbstractAdapter CountryAdapter.php:13

CountryAdapter::__iconizeStatic()

public static function __iconizeStatic(): ?array

CountryAdapter::getType()

public static function getType(): string

CountryAdapter::getOptions()

public function getOptions(): array

CountryAdapter::resolve()

public function resolve(mixed $value): mixed

DateRangeAdapter class

class DateRangeAdapter extends AbstractRuleAdapter DateRangeAdapter.php:43

"Are we inside this window?" - the coupon predicate.

Two shapes, because the two questions people actually ask are different:

{"from": "2026-12-01", "to": "2026-12-25"}
    one window, once. A launch offer.
{"from": "12-01", "to": "12-25", "annual": true}
    the same window every year. "Valid in December", which is what a
    seasonal coupon means and what a single absolute range cannot say
    without being rewritten each December.

Either end may be omitted: from alone is "from then on", to alone is "until then". Both omitted is always true, which is the right reading of a rule that has been created but not yet filled in - a half-configured condition should not silently deny everybody.

The annual form handles a window that crosses new year. "from 12-15 to 01-15" is a real offer, and comparing month-day pairs naively would make it match nothing at all, because 12-15 sorts after 01-15. When the ends are inverted the test is inverted with them: inside means at or after the start, OR at or before the end.

The subject is the instant to judge, so a rule can be asked about a date other than now ("would this coupon have been valid on the order date?"). Anything that is not a date means now.

DateRangeAdapter::__iconizeStatic()

public static function __iconizeStatic(): ?array

DateRangeAdapter::getType()

public static function getType(): string

DateRangeAdapter::getOptions()

public function getOptions(): array

DateRangeAdapter::resolve()

public function resolve(mixed $value): mixed

DateRangeAdapter::supports()

public function supports(mixed $value): bool

DateRangeAdapter::compliesWith()

public function compliesWith(mixed $value, mixed $subject): bool

DateTimeAdapter class

class DateTimeAdapter extends AbstractAdapter DateTimeAdapter.php:13

DateTimeAdapter::__iconizeStatic()

public static function __iconizeStatic(): ?array

DateTimeAdapter::getType()

public static function getType(): string

DateTimeAdapter::getOptions()

public function getOptions(): array

DateTimeAdapter::resolve()

public function resolve(mixed $value): mixed

HyperpatternAdapter class

class HyperpatternAdapter extends AbstractAdapter HyperpatternAdapter.php:13

HyperpatternAdapter::__iconizeStatic()

public static function __iconizeStatic(): ?array

HyperpatternAdapter::getType()

public static function getType(): string

HyperpatternAdapter::resolve()

public function resolve(mixed $value): mixed

HyperpatternAdapter::getOptions()

public function getOptions(): array

HyperpatternAdapter::__construct()

public function __construct(string $label = "", ?string $code = null, ?string $icon = "fa-solid fa-laptop", string $pattern = "https://{0}")

HyperpatternAdapter::getPattern()

public function getPattern(): string

HyperpatternAdapter::setPattern()

public function setPattern(string $pattern = "https://{0}")

HyperpatternAdapter::getNumberOfArguments()

public function getNumberOfArguments(): int

HyperpatternAdapter::generate()

public function generate(...$replace): ?string

HyperpatternAdapterIntl class

class HyperpatternAdapterIntl extends AbstractAdapterIntl HyperpatternAdapterIntl.php:8

HyperpatternAdapterIntl::getPlaceholder()

public function getPlaceholder(): ?array

HyperpatternAdapterIntl::setPlaceholder()

public function setPlaceholder(?array $placeholder): self

ImageAdapter class

class ImageAdapter extends AbstractAdapter ImageAdapter.php:13

ImageAdapter::__iconizeStatic()

public static function __iconizeStatic(): ?array

ImageAdapter::getType()

public static function getType(): string

ImageAdapter::getOptions()

public function getOptions(): array

ImageAdapter::resolve()

public function resolve(mixed $value): mixed

MoneyAdapter class

class MoneyAdapter extends AbstractAdapter MoneyAdapter.php:13

MoneyAdapter::__iconizeStatic()

public static function __iconizeStatic(): ?array

MoneyAdapter::getType()

public static function getType(): string

MoneyAdapter::getOptions()

public function getOptions(): array

MoneyAdapter::resolve()

public function resolve(mixed $value): mixed

MoneyAdapter::__construct()

public function __construct(string $label = "", ?string $code = null, ?int $minimum = null, ?int $maximum = null)

MoneyAdapter::getMinimum()

public function getMinimum(): ?int

MoneyAdapter::setMinimum()

public function setMinimum(?int $minimum)

MoneyAdapter::getMaximum()

public function getMaximum(): ?int

MoneyAdapter::setMaximum()

public function setMaximum(?int $maximum)

NumberAdapter class

class NumberAdapter extends AbstractAdapter NumberAdapter.php:13

NumberAdapter::__iconizeStatic()

public static function __iconizeStatic(): ?array

NumberAdapter::getType()

public static function getType(): string

NumberAdapter::getOptions()

public function getOptions(): array

NumberAdapter::resolve()

public function resolve(mixed $value): mixed

NumberAdapter::__construct()

public function __construct(string $label = "", ?string $code = null, ?int $minimum = null, ?int $maximum = null)

NumberAdapter::getMinimum()

public function getMinimum(): ?int

NumberAdapter::setMinimum()

public function setMinimum(?int $minimum)

NumberAdapter::getMaximum()

public function getMaximum(): ?int

NumberAdapter::setMaximum()

public function setMaximum(?int $maximum)

PercentAdapter class

class PercentAdapter extends AbstractAdapter PercentAdapter.php:13

PercentAdapter::__iconizeStatic()

public static function __iconizeStatic(): ?array

PercentAdapter::getType()

public static function getType(): string

PercentAdapter::getOptions()

public function getOptions(): array

PercentAdapter::resolve()

public function resolve(mixed $value): mixed

PercentAdapter::__construct()

public function __construct(string $label = "", ?string $code = null, int $epsilon = 4, int $scale = 2)

PercentAdapter::getPrecision()

public function getPrecision(): int

PercentAdapter::setPrecision()

public function setPrecision(int $epsilon)

PercentAdapter::getScale()

public function getScale(): int

PercentAdapter::setScale()

public function setScale(int $scale)

ScalarAdapter class

class ScalarAdapter extends AbstractAdapter ScalarAdapter.php:13

ScalarAdapter::__iconizeStatic()

public static function __iconizeStatic(): ?array

ScalarAdapter::getType()

public static function getType(): string

ScalarAdapter::getOptions()

public function getOptions(): array

ScalarAdapter::resolve()

public function resolve(mixed $value): mixed

ScalarAdapter::__construct()

public function __construct(string $label = "", ?string $code = null, ?int $unit = null, ?int $minimum = null, ?int $maximum = null)

ScalarAdapter::getUnit()

public function getUnit(): ?int

ScalarAdapter::setUnit()

public function setUnit(?int $unit)

ScalarAdapter::getMinimum()

public function getMinimum(): ?int

ScalarAdapter::setMinimum()

public function setMinimum(?int $minimum)

ScalarAdapter::getMaximum()

public function getMaximum(): ?int

ScalarAdapter::setMaximum()

public function setMaximum(?int $maximum)

ScoreAdapter class

class ScoreAdapter extends AbstractRuleAdapter ScoreAdapter.php:32

"Is this account's score <operation> this number?"

Modelled on the marketplace's TotalPriceAdapter rather than on a bespoke shape: the comparison is a stored Operation (LESS, GREATER_EQUAL, EQUAL...) rather than baked into the class, so one adapter covers every threshold a rule might want instead of needing a MinScoreAdapter and a MaxScoreAdapter. It also means a band is expressed the way the engine already expresses everything else - as two rules on the same subject, AND-ed together by the caller, which is exactly what MarketplaceManager does with $validRules &=.

The subject is anything that can state a score - a User today, and a Group, since both grew a getScore(). Deliberately duck-typed rather than hinted on User: this class lives in the layout engine, and hinting it there would stop the same rule judging anything else that learns to score itself later. A subject that cannot state one returns false, the same way TotalPriceAdapter returns false for anything that is not an Order.

ScoreAdapter::__iconizeStatic()

public static function __iconizeStatic(): ?array

ScoreAdapter::getType()

public static function getType(): string

ScoreAdapter::getOptions()

public function getOptions(): array

ScoreAdapter::resolve()

public function resolve(mixed $value): mixed

ScoreAdapter::supports()

public function supports(mixed $value): bool

ScoreAdapter::compliesWith()

public function compliesWith(mixed $value, mixed $subject): bool

ScoreAdapter::getOperation()

public function getOperation()

ScoreAdapter::setOperation()

public function setOperation($operation): self

TextAdapter class

class TextAdapter extends AbstractAdapter TextAdapter.php:13

TextAdapter::__iconizeStatic()

public static function __iconizeStatic(): ?array

TextAdapter::getType()

public static function getType(): string

TextAdapter::getOptions()

public function getOptions(): array

TextAdapter::resolve()

public function resolve(mixed $value): mixed

TextAdapter::getLength()

public function getLength(): ?int

TextAdapter::setLength()

public function setLength(?int $length)

TextareaAdapter class

class TextareaAdapter extends AbstractAdapter TextareaAdapter.php:13

TextareaAdapter::__iconizeStatic()

public static function __iconizeStatic(): ?array

TextareaAdapter::getType()

public static function getType(): string

TextareaAdapter::getOptions()

public function getOptions(): array

TextareaAdapter::resolve()

public function resolve(mixed $value): mixed

Base\Entity\Layout\Attribute\Adapter\Common

AbstractActionAdapter class

abstract class AbstractActionAdapter extends AbstractAdapter implements ActionAdapterInterface AbstractActionAdapter.php:11

AbstractActionAdapter::__iconizeStatic()

public static function __iconizeStatic(): ?array

AbstractActionAdapter::apply()

public function apply(mixed $value, mixed $subject): mixed

AbstractAdapter class

abstract class AbstractAdapter implements AttributeAdapterInterface, AutocompleteInterface, TranslatableInterface, IconizeInterface AbstractAdapter.php:22

AbstractAdapter::__iconize()

public function __iconize(): ?array

AbstractAdapter::__iconizeStatic()

public static function __iconizeStatic(): ?array

AbstractAdapter::__toString()

public function __toString()

AbstractAdapter::__autocomplete()

public function __autocomplete(): ?string

AbstractAdapter::__autocompleteData()

public function __autocompleteData(): array

AbstractAdapter::__construct()

public function __construct(string $label = "", ?string $code = null)

AbstractAdapter::getId()

public function getId(): ?int

AbstractAdapter::getAttributes()

public function getAttributes(): Collection

AbstractAdapter::addAttribute()

public function addAttribute(AttributeInterface $attribute): self

AbstractAdapter::removeAttribute()

public function removeAttribute(AttributeInterface $attribute): self

AbstractAdapter::getCode()

public function getCode(): ?string

AbstractAdapter::setCode()

public function setCode(?string $code): self

AbstractAdapter::getIcon()

public function getIcon(): ?string

AbstractAdapter::setIcon()

public function setIcon(?string $icon): static

AbstractAdapterIntl class

class AbstractAdapterIntl implements TranslationInterface AbstractAdapterIntl.php:10

AbstractAdapterIntl::getLabel()

public function getLabel(): ?string

AbstractAdapterIntl::setLabel()

public function setLabel(?string $label): static

AbstractAdapterIntl::getHelp()

public function getHelp(): ?string

AbstractAdapterIntl::setHelp()

public function setHelp(?string $help): static

AbstractRuleAdapter class

abstract class AbstractRuleAdapter extends AbstractAdapter implements RuleAdapterInterface AbstractRuleAdapter.php:12

AbstractRuleAdapter::__iconizeStatic()

public static function __iconizeStatic(): ?array

AbstractRuleAdapter::compliesWith()

public function compliesWith(mixed $value, mixed $subject): bool

AbstractScopeAdapter class

abstract class AbstractScopeAdapter extends AbstractAdapter implements ScopeAdapterInterface AbstractScopeAdapter.php:12

AbstractScopeAdapter::__iconizeStatic()

public static function __iconizeStatic(): ?array

AbstractScopeAdapter::contains()

public function contains(mixed $value, mixed $subject): bool

ActionAdapterInterface interface

interface ActionAdapterInterface extends AttributeAdapterInterface ActionAdapterInterface.php:5

ActionAdapterInterface::apply()

public function apply(mixed $value, mixed $subject): mixed

AttributeAdapterInterface interface

interface AttributeAdapterInterface AttributeAdapterInterface.php:5

AttributeAdapterInterface::getType()

public static function getType(): string

AttributeAdapterInterface::getOptions()

public function getOptions(): array

AttributeAdapterInterface::resolve()

public function resolve(mixed $value): mixed

RuleAdapterInterface interface

interface RuleAdapterInterface extends AttributeAdapterInterface RuleAdapterInterface.php:5

RuleAdapterInterface::supports()

public function supports(mixed $value): bool

RuleAdapterInterface::compliesWith()

public function compliesWith(mixed $value, mixed $subject): bool

ScopeAdapterInterface interface

interface ScopeAdapterInterface extends AttributeAdapterInterface ScopeAdapterInterface.php:5

ScopeAdapterInterface::supports()

public function supports(mixed $value): bool

ScopeAdapterInterface::contains()

public function contains(mixed $value, mixed $subject): bool

Base\Entity\Layout\Attribute\Common

AbstractAction class

abstract class AbstractAction extends AbstractAttribute implements ActionInterface AbstractAction.php:13

AbstractAction::__iconizeStatic()

public static function __iconizeStatic(): ?array

AbstractAction::apply()

public function apply(mixed $subject): mixed

AbstractAction::getValue()

public function getValue()

AbstractAction::setValue()

public function setValue($value): static

AbstractAction::getClass()

public function getClass(): ?string

AbstractAction::setClass()

public function setClass(?string $class): static

AbstractAttribute class

abstract class AbstractAttribute implements IconizeInterface, AttributeInterface AbstractAttribute.php:13

AbstractAttribute::__iconize()

public function __iconize(): ?array

AbstractAttribute::__iconizeStatic()

public static function __iconizeStatic(): ?array

AbstractAttribute::__toString()

public function __toString()

AbstractAttribute::__construct()

public function __construct(AbstractAdapter $adapter)

AbstractAttribute::getId()

public function getId(): ?int

AbstractAttribute::getAdapter()

public function getAdapter(): ?AbstractAdapter

AbstractAttribute::setAdapter()

public function setAdapter(?AbstractAdapter $adapter): self

AbstractAttribute::getCode()

public function getCode(): ?string

AbstractAttribute::getType()

public function getType(): ?string

AbstractAttribute::getOptions()

public function getOptions(): array

AbstractRule class

abstract class AbstractRule extends AbstractAttribute implements RuleInterface AbstractRule.php:12

AbstractRule::__iconizeStatic()

public static function __iconizeStatic(): ?array

AbstractRule::compliesWith()

public function compliesWith(mixed $subject): bool

AbstractRule::getValue()

public function getValue()

AbstractRule::setValue()

public function setValue($value)

AbstractRule::getClass()

public function getClass(): ?string

AbstractRule::setClass()

public function setClass(?string $class)

AbstractScope class

abstract class AbstractScope extends AbstractAttribute implements ScopeInterface AbstractScope.php:12

AbstractScope::__iconizeStatic()

public static function __iconizeStatic(): ?array

AbstractScope::contains()

public function contains(mixed $subject): bool

AbstractScope::getValue()

public function getValue()

AbstractScope::setValue()

public function setValue($value)

AbstractScope::getClass()

public function getClass(): ?string

AbstractScope::setClass()

public function setClass(?string $class)

ActionInterface interface

interface ActionInterface extends AttributeInterface ActionInterface.php:5

ActionInterface::apply()

public function apply(mixed $subject): mixed

AttributeInterface interface

interface AttributeInterface AttributeInterface.php:7

AttributeInterface::get()

public function get(?string $locale = null): mixed

AttributeInterface::set()

public function set(...$args): self

AttributeInterface::resolve()

public function resolve(?string $locale = null): mixed

AttributeInterface::getAdapter()

public function getAdapter()

AttributeInterface::setAdapter()

public function setAdapter(?AbstractAdapter $adapter): self

AttributeInterface::getCode()

public function getCode(): ?string

AttributeInterface::getType()

public function getType(): ?string

AttributeInterface::getOptions()

public function getOptions(): array

RuleInterface interface

interface RuleInterface extends AttributeInterface RuleInterface.php:5

RuleInterface::compliesWith()

public function compliesWith(mixed $subject): bool

ScopeInterface interface

interface ScopeInterface extends AttributeInterface ScopeInterface.php:5

ScopeInterface::contains()

public function contains(mixed $subject): bool

Base\Entity\Layout\Widget

Attachment class

class Attachment extends Widget implements IconizeInterface, LinkableInterface Attachment.php:21

Attachment::__iconize()

public function __iconize(): ?array

Attachment::__iconizeStatic()

public static function __iconizeStatic(): ?array
public function __toLink(array $routeParameters = [], int $referenceType = Link::ABSOLUTE_PATH): ?string

Attachment::__toString()

public function __toString()

Attachment::getSlug()

public function getSlug(): ?string

Attachment::setSlug()

public function setSlug(string $slug): self

Attachment::getDownload()

public function getDownload()
Throws

Exception

Attachment::getDownloadFile()

public function getDownloadFile()
Throws

FilesystemException

Attachment::setDownload()

public function setDownload($file)

class Link extends Widget implements IconizeInterface, LinkableInterface Link.php:15

public function __iconize(): ?array
public static function __iconizeStatic(): ?array
public function __toLink(array $routeParameters = [], int $referenceType = \Base\Contract\Link::ABSOLUTE_PATH): ?string
public function __toString()
public function __construct(?Hyperlink $hyperlink = null)
public function getHyperlink(): ?Hyperlink
public function setHyperlink(Hyperlink $hyperlink)

LinkIntl class

class LinkIntl extends WidgetIntl LinkIntl.php:9

LinkIntl::getTitle()

public function getTitle(): ?string

Page class

class Page extends Widget implements IconizeInterface, LinkableInterface Page.php:19

Page::__iconize()

public function __iconize(): ?array

Page::__iconizeStatic()

public static function __iconizeStatic(): ?array
public function __toLink(array $routeParameters = [], int $referenceType = Link::ABSOLUTE_PATH): ?string

Page::__toString()

public function __toString()

Page::__construct()

public function __construct(?string $title = null, ?string $slug = null)

Page::getSlug()

public function getSlug(): ?string

Page::setSlug()

public function setSlug(?string $slug): self

Page::getBook()

public function getBook(): ?Book

Page::setBook()

public function setBook(?Book $book): self

Route class

class Route extends Widget implements IconizeInterface, LinkableInterface Route.php:17

Route::__iconize()

public function __iconize(): ?array

Route::__iconizeStatic()

public static function __iconizeStatic(): ?array
public function __toLink(array $routeParameters = [], int $referenceType = Link::ABSOLUTE_PATH): ?string

Route::__toString()

public function __toString()

Route::__construct()

public function __construct(?string $title = null, ?string $routeName = null, array $routeParameters = [])

Route::getRouteName()

public function getRouteName(): ?string

Route::setRouteName()

public function setRouteName(?string $routeName): self

Route::getRouteParameters()

public function getRouteParameters(): ?array

Route::setRouteParameters()

public function setRouteParameters(?array $routeParameters): self

Route::getPath()

public function getPath()

The path its route is declared with ("/articles/{slug}"): the Routes contract (C4b), the router's route collection under Symfony.

Route::getRoute()

public function getRoute(): ?string

The name of the route its address leads to (the Routes contract, C4b).

It handed the router's Route object to a string return type before, which threw for every route found.

Route::getRouteIcons()

public function getRouteIcons()

Its route's icons (the Routes contract, C4b: the IconProvider's under Symfony); null without a route.

Route::getUrl()

public function getUrl(): ?string

Route::generate()

public function generate(int $referenceType = Link::ABSOLUTE_PATH): ?string

Its route's address through the Urls contract (Base\Contract\Link, C4b), not BaseTrait's router: the same string under Symfony. A route the router cannot make is null, as before; a registry with no Urls is said aloud, never taken for a missing route.

Slot class

class Slot extends Widget implements TranslatableInterface, IconizeInterface Slot.php:17

Slot::__iconize()

public function __iconize(): ?array

Slot::__iconizeStatic()

public static function __iconizeStatic(): ?array

Slot::__toString()

public function __toString()

Slot::__construct()

public function __construct(string $path, ?string $label = null, ?string $help = null)

Slot::getPath()

public function getPath(): string

Slot::setPath()

public function setPath(string $path): self

Slot::getWidget()

public function getWidget(): ?Widget

Slot::setWidget()

public function setWidget(?Widget $widget): self

SlotIntl class

class SlotIntl extends WidgetIntl SlotIntl.php:10

SlotIntl::getLabel()

public function getLabel(): ?string

SlotIntl::setLabel()

public function setLabel(?string $label): self

SlotIntl::getHelp()

public function getHelp(): ?string

SlotIntl::setHelp()

public function setHelp(?string $help): self

Base\Entity\Layout\Widget\Set

Book class

class Book extends Widget implements IconizeInterface, SetInterface Book.php:18

Book::__iconize()

public function __iconize(): ?array

Book::__iconizeStatic()

public static function __iconizeStatic(): ?array

Book::__construct()

public function __construct(?string $title = null, array $pages = [])

Book::getPages()

public function getPages(): Collection

Book::addPage()

public function addPage(Page $page): self

Book::removePage()

public function removePage(Page $page): self

Linkset class

class Linkset extends Widget implements IconizeInterface, SetInterface Linkset.php:19

Linkset::__iconize()

public function __iconize(): ?array

Linkset::__iconizeStatic()

public static function __iconizeStatic(): ?array

Linkset::__construct()

public function __construct(?string $title = null, array $hyperlinks = [])
public function getHyperlinks(): Collection
public function addHyperlink(Hyperlink $hyperlink): self
public function removeHyperlink(Hyperlink $hyperlink): self

Menu class

class Menu extends Widget implements IconizeInterface, SetInterface Menu.php:18

Menu::__iconize()

public function __iconize(): ?array

Menu::__iconizeStatic()

public static function __iconizeStatic(): ?array

Menu::__construct()

public function __construct(?string $title = null)

Menu::getItems()

public function getItems(): Collection

Menu::addItem()

public function addItem(Widget $item): self

Menu::removeItem()

public function removeItem(Widget $item): self

Network class

class Network extends Widget implements IconizeInterface, SetInterface Network.php:19

Network::__iconize()

public function __iconize(): ?array

Network::__iconizeStatic()

public static function __iconizeStatic(): ?array

Network::__construct()

public function __construct(?string $title = null, array $routes = [])

Network::getRoutes()

public function getRoutes(): Collection

Network::addRoute()

public function addRoute(Route $route): self

Network::removeRoute()

public function removeRoute(Route $route): self

Paperclip class

class Paperclip extends Widget implements IconizeInterface Paperclip.php:19

Paperclip::__iconize()

public function __iconize(): ?array

Paperclip::__iconizeStatic()

public static function __iconizeStatic(): ?array

Paperclip::__construct()

public function __construct(?string $title = null, array $attachments = [])

Paperclip::getAttachments()

public function getAttachments(): Collection

Paperclip::addAttachment()

public function addAttachment(Attachment $attachment): self

Paperclip::removeAttachment()

public function removeAttachment(Attachment $attachment): self

SetInterface interface

interface SetInterface SetInterface.php:5

Base\Entity\Signature

AbstractEnvelope class

abstract class AbstractEnvelope AbstractEnvelope.php:15

What an envelope keeps (Base\Entity\Signature\Envelope): what it is about - any entity, by its class and id -, the omnisense/omnisign gateway it went through and that gateway's reference, where it stands, its signers, and the signed document and its evidence once kept in the private storage. A mapped superclass: no table of its own; Envelope is an entity only when omnisense/omnisign is installed.

const STATUS_DRAFT = 'draft'
const STATUS_SENT = 'sent'
const STATUS_COMPLETED = 'completed'
const STATUS_DECLINED = 'declined'
const STATUS_EXPIRED = 'expired'
const STATUS_CANCELED = 'canceled'

AbstractEnvelope::__construct()

public function __construct(string $subjectClass, string $subjectId, string $title, string $gateway)

AbstractEnvelope::getId()

public function getId(): ?int

AbstractEnvelope::getSubjectClass()

public function getSubjectClass(): string

AbstractEnvelope::getSubjectId()

public function getSubjectId(): string

AbstractEnvelope::getTitle()

public function getTitle(): string

AbstractEnvelope::getGateway()

public function getGateway(): string

AbstractEnvelope::getReference()

public function getReference(): ?string

AbstractEnvelope::getStatus()

public function getStatus(): string

AbstractEnvelope::isCompleted()

public function isCompleted(): bool

AbstractEnvelope::isOver()

public function isOver(): bool

Over: nothing more will happen to it (completed, declined, expired, canceled).

AbstractEnvelope::getEnvelope()

public function getEnvelope(): array

AbstractEnvelope::getSigners()

public function getSigners(): array

AbstractEnvelope::update()

public function update(?string $reference, string $status, array $envelope, ?\DateTimeImmutable $completedAt = null): static

Where it stands, as the gateway answered.

AbstractEnvelope::getSignedFile()

public function getSignedFile(): ?string

AbstractEnvelope::getEvidenceFile()

public function getEvidenceFile(): ?string

AbstractEnvelope::keep()

public function keep(?string $signedFile, ?string $evidenceFile): static

The signed document and its evidence, kept: their paths in the private storage.

AbstractEnvelope::getCreatedAt()

public function getCreatedAt(): \DateTimeImmutable

AbstractEnvelope::getUpdatedAt()

public function getUpdatedAt(): \DateTimeImmutable

AbstractEnvelope::getCompletedAt()

public function getCompletedAt(): ?\DateTimeImmutable

Base\Entity\Thread

Comment class

class Comment implements SpamProtectionInterface Comment.php:32

What a visitor leaves under a thread (a blog post, a sequence, a video) - or, with no thread, in the site's visitors' book: a name, an e-mail (never shown), a site, a text, and for a reply the comment it answers. Signed in, the author is kept too. Moved here from omnibase/blog.

It implements SpamProtectionInterface: the form's model sends the text to Akismet before it is saved (base.spam.akismet), and the score lands in getSpamCallback(): a doubtful comment waits (PENDING), a clean one is APPROVED when $autoApprove says so.

JOINED, with a discriminator: a bundle that needs more on its comments (a video's time code) extends it with a #[DiscriminatorEntry] of its own.

public bool $autoApprove = true

Set before the spam check: whether a clean comment goes online at once.

Comment::__construct()

public function __construct(?Thread $thread = null, ?User $author = null)

Comment::__toString()

public function __toString(): string

Comment::getId()

public function getId(): ?int

Comment::getThread()

public function getThread(): ?Thread

Comment::setThread()

public function setThread(?Thread $thread): static

Comment::getAuthor()

public function getAuthor(): ?User

Comment::setAuthor()

public function setAuthor(?User $author): static

Comment::getName()

public function getName(): ?string

Comment::setName()

public function setName(?string $name): static

Comment::getEmail()

public function getEmail(): ?string

Comment::setEmail()

public function setEmail(?string $email): static

Comment::getWebsite()

public function getWebsite(): ?string

Comment::setWebsite()

public function setWebsite(?string $website): static

Comment::getContent()

public function getContent(): ?string

Comment::setContent()

public function setContent(?string $content): static

Comment::getParent()

public function getParent(): ?Comment

Comment::setParent()

public function setParent(?Comment $parent): static

Comment::getReplies()

public function getReplies(): Collection

Comment::getVisibleReplies()

public function getVisibleReplies(): array
Returns

the replies online

Comment::getState()

public function getState(): CommentState

Comment::setState()

public function setState(CommentState $state): static

Comment::isVisible()

public function isVisible(): bool

Comment::isPending()

public function isPending(): bool

Comment::approve()

public function approve(): static

Comment::markAsSpam()

public function markAsSpam(): static

Comment::trash()

public function trash(): static

Comment::getSpamScore()

public function getSpamScore(): ?int

Comment::getIp()

public function getIp(): ?string

Comment::setIp()

public function setIp(?string $ip): static

Comment::getUserAgent()

public function getUserAgent(): ?string

Comment::setUserAgent()

public function setUserAgent(?string $userAgent): static

Comment::getCreatedAt()

public function getCreatedAt(): ?\DateTimeInterface

Comment::setCreatedAt()

public function setCreatedAt(?\DateTimeInterface $createdAt): static

Comment::getModeratedAt()

public function getModeratedAt(): ?\DateTimeInterface

Comment::getDisplayName()

public function getDisplayName(): string

How the comment is signed: the account's name, or the name typed.

Comment::getSpamBlameable()

public function getSpamBlameable(): ?User

Comment::getSpamText()

public function getSpamText(): ?string

Comment::getSpamDate()

public function getSpamDate(): \DateTime

Comment::getSpamCallback()

public function getSpamCallback(int $score): void

The classifier's verdict (Akismet). NOT_SPAM goes online when the site auto-approves, else waits (PENDING); spam is kept aside (SPAM), for a person to read - and to report as ham if it was not; NO_TEXT (no classifier, or an empty text) is treated as clean - the form already refused an empty text.

Like class

class Like implements IconizeInterface Like.php:16

Like::__iconize()

public function __iconize(): ?array

Like::__iconizeStatic()

public static function __iconizeStatic(): ?array

Like::__construct()

public function __construct(?User $user = null)

Like::getId()

public function getId(): ?int

Like::getUser()

public function getUser(): ?User

Like::setUser()

public function setUser(?User $user): self

Like::getThread()

public function getThread(): ?Thread

Like::setThread()

public function setThread(?Thread $thread): self

Like::getIcon()

public function getIcon(): ?string

Like::setIcon()

public function setIcon(string $icon): self

Mention class

class Mention implements IconizeInterface Mention.php:16

Mention::__iconize()

public function __iconize(): ?array

Mention::__iconizeStatic()

public static function __iconizeStatic(): ?array

Mention::__construct()

public function __construct(?User $mentionee = null, ?Thread $thread = null)

Mention::getId()

public function getId(): ?int

Mention::getMentionee()

public function getMentionee(): ?User

Mention::setMentionee()

public function setMentionee(?User $mentionee): self

Mention::getMentioners()

public function getMentioners(): Collection

Mention::addMentioner()

public function addMentioner(User $mentioner): self

Mention::removeMentioner()

public function removeMentioner(User $mentioner): self

Mention::getThread()

public function getThread(): ?Thread

Mention::setThread()

public function setThread(?Thread $thread): self

Tag class

class Tag implements TranslatableInterface, IconizeInterface, AliasInterface Tag.php:26

Tag::__toString()

public function __toString()

Tag::__iconize()

public function __iconize(): ?array

Tag::__iconizeStatic()

public static function __iconizeStatic(): ?array

Tag::__construct()

public function __construct(?string $label = null, ?string $slug = null)

Tag::getId()

public function getId(): ?int

Tag::getSlug()

public function getSlug(): ?string

Tag::setSlug()

public function setSlug(?string $slug): self

Tag::getColor()

public function getColor(): ?string

Tag::setColor()

public function setColor(?string $color): self

Tag::getPriority()

public function getPriority(): ?int

Tag::setPriority()

public function setPriority(?int $priority): self

Tag::getIcon()

public function getIcon()
Throws

Exception

Tag::getIconFile()

public function getIconFile()
Throws

FilesystemException

Tag::setIcon()

public function setIcon($icon)

Tag::getThreads()

public function getThreads(): Collection

Tag::addThread()

public function addThread(Thread $thread): self

Tag::removeThread()

public function removeThread(Thread $thread): self

TagIntl class

class TagIntl implements TranslationInterface TagIntl.php:11

TagIntl::getLabel()

public function getLabel(): ?string

TagIntl::setLabel()

public function setLabel(?string $label): self

TagIntl::getKeywords()

public function getKeywords(): array

TagIntl::setKeywords()

public function setKeywords(array $keywords)

TagIntl::getDescription()

public function getDescription(): ?string

TagIntl::setDescription()

public function setDescription(?string $description): self

Taxon class

class Taxon implements TranslatableInterface, IconizeInterface, GraphInterface Taxon.php:26

Taxon::__iconize()

public function __iconize(): ?array

Taxon::__iconizeStatic()

public static function __iconizeStatic(): ?array

Taxon::__toString()

public function __toString()

Taxon::__construct()

public function __construct(?string $label = null, ?string $slug = null)

Taxon::validateLabel()

public function validateLabel(ExecutionContextInterface $context): void

A taxon is named in one language at least: the screen asks for the label of the site's language only (the others may stay empty), and a taxon without any label has nothing to show in a list, a picker or its slug.

Taxon::getId()

public function getId(): ?int

Taxon::getSlug()

public function getSlug(): ?string

Taxon::setSlug()

public function setSlug(?string $slug): self

Taxon::getIcon()

public function getIcon()
Throws

Exception

Taxon::getIconFile()

public function getIconFile()
Throws

FilesystemException

Taxon::setIcon()

public function setIcon($icon)

Taxon::getParent()

public function getParent(): ?self

Taxon::setParent()

public function setParent(?self $parent): self

Taxon::removeParent()

public function removeParent(self $parent): self

Taxon::getChildren()

public function getChildren(): Collection

Taxon::addChild()

public function addChild(self $child): self

Taxon::removeChild()

public function removeChild(self $child): self

Taxon::getThreads()

public function getThreads(): Collection

Taxon::addThread()

public function addThread(Thread $thread): self

Taxon::removeThread()

public function removeThread(Thread $thread): self

Taxon::getConnexes()

public function getConnexes(): Collection

Taxon::addConnex()

public function addConnex(self $connex): self

Taxon::removeConnex()

public function removeConnex(self $connex): self

TaxonIntl class

class TaxonIntl implements TranslationInterface TaxonIntl.php:11

TaxonIntl::getLabel()

public function getLabel(): ?string

TaxonIntl::setLabel()

public function setLabel(?string $label): self

TaxonIntl::getDescription()

public function getDescription(): ?string

TaxonIntl::setDescription()

public function setDescription(?string $description): self

TaxonIntl::getKeywords()

public function getKeywords(): array

TaxonIntl::setKeywords()

public function setKeywords(array $keywords)

Base\Entity\User

Address class

class Address implements IconizeInterface, HtmlizeInterface Address.php:14

Address::__toHtml()

public function __toHtml(array $options = [], ...$args): ?string

Address::__toString()

public function __toString()

Address::__iconize()

public function __iconize(): ?array

Address::__iconizeStatic()

public static function __iconizeStatic(): ?array

Address::__construct()

public function __construct(?string $name = null, ?Address $address = null)

Address::getId()

public function getId()

Address::getName()

public function getName(): ?string

Address::setName()

public function setName(string $name): self

Address::getCountry()

public function getCountry(): ?string

Address::setCountry()

public function setCountry(string $country): self

Address::getState()

public function getState(): ?string

Address::setState()

public function setState(?string $state): self

Address::getCity()

public function getCity(): ?string

Address::setCity()

public function setCity(string $city): self

Address::getZipCode()

public function getZipCode(): ?string

Address::setZipCode()

public function setZipCode(string $zipCode): self

Address::getStreetAddress()

public function getStreetAddress(): ?string

Address::setStreetAddress()

public function setStreetAddress(?string $streetAddress): self

Address::getAffix()

public function getAffix(): ?string

Address::setAffix()

public function setAffix(?string $affix): self

Address::getPhone()

public function getPhone(): ?string

Address::setPhone()

public function setPhone(?string $phone): self

Address::getFax()

public function getFax(): ?string

Address::setFax()

public function setFax(?string $fax): self

Address::getAdditional()

public function getAdditional(): ?string

Address::setAdditional()

public function setAdditional(?string $additional): self

Address::getUser()

public function getUser(): ?User

Address::setUser()

public function setUser(?User $user): self

Complaint class

class Complaint implements IconizeInterface Complaint.php:26

A user's complaint about another one (or about something), for the staff to answer.

Where it was made is the app's business: source names it (a game world, a forum…) and location where in it (a room, a topic), and context carries whatever makes it answerable there - for a game world, what was said in the room before it and every act of the staff that touched the people in it. The two users are kept by name as well as by account: an account may go, the complaint stays readable. targetStatus is the rank the one complained about held when it was made.

Who may read one is Base\Security\Voter\ComplaintVoter's call (COMPLAINT_READ / COMPLAINT_HANDLE on the complaint): the staff whose roles outrank the one it is about - a complaint about a moderator goes to the ranks above them, never to the moderator - and never the one it is about.

Settled, it may point at the Sanction it led to.

const OPEN = "open"
const HANDLED = "handled"
const DISMISSED = "dismissed"
const STATUSES = [self::OPEN => "À traiter", self::HANDLED => "Traitée", self::DISMISSED => "Classée sans suite"]

Complaint::__construct()

public function __construct(?User $complainant = null, ?string $text = null, ?string $source = null)

Complaint::__iconize()

public function __iconize(): ?array

Complaint::__iconizeStatic()

public static function __iconizeStatic(): ?array

Complaint::getId()

public function getId(): ?int

Complaint::getCreatedAt()

public function getCreatedAt(): DateTime

Complaint::setCreatedAt()

public function setCreatedAt(DateTime $at): self

Complaint::getComplainant()

public function getComplainant(): ?User

Complaint::setComplainant()

public function setComplainant(?User $user): self

Complaint::getComplainantName()

public function getComplainantName(): string

Complaint::setComplainantName()

public function setComplainantName(string $name): self

Complaint::getTarget()

public function getTarget(): ?User

Complaint::setTarget()

public function setTarget(?User $user): self

Complaint::getTargetName()

public function getTargetName(): ?string

Complaint::setTargetName()

public function setTargetName(?string $name): self

Complaint::getTargetStatus()

public function getTargetStatus(): ?string

Complaint::setTargetStatus()

public function setTargetStatus(?string $status): self

Complaint::getSource()

public function getSource(): ?string

Complaint::setSource()

public function setSource(?string $source): self

Complaint::getLocation()

public function getLocation(): ?string

Complaint::setLocation()

public function setLocation(?string $location): self

Complaint::getLocationName()

public function getLocationName(): ?string

Complaint::setLocationName()

public function setLocationName(?string $name): self

Complaint::getText()

public function getText(): string

Complaint::setText()

public function setText(string $text): self

Complaint::getContext()

public function getContext(): array

Complaint::setContext()

public function setContext(array $context): self

Complaint::getStatus()

public function getStatus(): string

Complaint::getStatusLabel()

public function getStatusLabel(): string

Complaint::isOpen()

public function isOpen(): bool

Complaint::getHandledBy()

public function getHandledBy(): ?User

Complaint::getHandledAt()

public function getHandledAt(): ?DateTime

Complaint::getAnswer()

public function getAnswer(): ?string

Complaint::getSanction()

public function getSanction(): ?Sanction

Complaint::setSanction()

public function setSanction(?Sanction $sanction): self

Complaint::settle()

public function settle(string $status, ?User $by, ?string $answer = null): self

Handled or dismissed (or opened again), by whom, with what answer.

Connection class

class Connection implements IconizeInterface Connection.php:14

Connection::__iconize()

public function __iconize(): ?array

Connection::__iconizeStatic()

public static function __iconizeStatic(): ?array

Connection::__construct()

public function __construct(string $uniqid = "", ?User $user = null)

Connection::getId()

public function getId(): ?int

Connection::getUniqid()

public function getUniqid(): ?string

Connection::setUniqid()

public function setUniqid(string $uniqid): self

Connection::getUser()

public function getUser(): ?User

Connection::setUser()

public function setUser(?User $user): self

Connection::getImpersonator()

public function getImpersonator(): ?User

Connection::setImpersonator()

public function setImpersonator(?User $impersonator): self

Connection::getLoginAttempts()

public function getLoginAttempts(): ?string

Connection::setLoginAttempts()

public function setLoginAttempts(int $loginAttempts): self

Connection::getState()

public function getState(): ?string

Connection::isValid()

public function isValid(): bool

Connection::markAsSucceeded()

public function markAsSucceeded(): self

Connection::markAsFailed()

public function markAsFailed(): self

Connection::markAsLogout()

public function markAsLogout(): self

Connection::getIpList()

public function getIpList(): ?array

Connection::addIp()

public function addIp(string $ip): self

Connection::removeIp()

public function removeIp(string $ip): self

Connection::getAgent()

public function getAgent(): ?string

Connection::setAgent()

public function setAgent(string $agent): self

Connection::getAgentLabel()

public function getAgentLabel(): ?string

A short, readable name for the browser behind this connection.

Purely for display: a settings page listing "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.5 Safari/605.1.15" twenty times over tells nobody which session is theirs. The full string stays available - this is a label beside it, not a replacement for it.

Order matters in both lists: Edge and Chrome both claim to be Safari, and Chrome claims to be Safari too, so the most specific claim has to be tested first. Anything unrecognised keeps the raw string.

Connection::getLocale()

public function getLocale(): ?string

Connection::setLocale()

public function setLocale(string $locale): self

Connection::getTimezones()

public function getTimezones(): ?array

Connection::addTimezone()

public function addTimezone(?string $timezone): self

Connection::removeTimezone()

public function removeTimezone(?string $timezone): self

Connection::getHostnames()

public function getHostnames(): ?array

Connection::addHostname()

public function addHostname(?string $hostname): self

Connection::removeHostname()

public function removeHostname(?string $hostname): self

Connection::getCreatedAt()

public function getCreatedAt(): ?\DateTimeInterface

Connection::setCreatedAt()

public function setCreatedAt(\DateTimeInterface $createdAt): self

Connection::getUpdatedAt()

public function getUpdatedAt(): ?\DateTimeInterface

Connection::setUpdatedAt()

public function setUpdatedAt(\DateTimeInterface $updatedAt): self

Group class

class Group implements IconizeInterface Group.php:31

Open to extension the way User is: JOINED inheritance on a class discriminator, so an application can add its own group (a leader, a motto, a join mode...) as a subclass in its own table, while roles, permissions, rules, scopes and actions keep working on the base row. An application without a subclass sees no change but the discriminator column.

const DEFAULT_ICON = "fa-solid fa-users"

The icon a group gets until it is given one: the column is NOT NULL.

Group::__iconize()

public function __iconize(): ?array

Group::__iconizeStatic()

public static function __iconizeStatic(): ?array

Group::__toString()

public function __toString(): string

Its name, wherever a group is shown as one line: the pickers (a permission's groups, a user's), the back office's titles and lists.

Without it a picker fell back to the translation key of the class and the id ("occasion_group._singular #1" for an application's subclass).

Group::__construct()

public function __construct()

Group::getId()

public function getId(): ?int

Group::getRoles()

public function getRoles(): array

Group::setRoles()

public function setRoles(array $roles): self

Group::getName()

public function getName(): ?string

Group::setName()

public function setName(string $name): self

Group::getMembers()

public function getMembers(): Collection

Group::addMember()

public function addMember(User $member): self

Group::removeMember()

public function removeMember(User $member): self

Group::getCreatedAt()

public function getCreatedAt(): ?DateTimeInterface

Group::setCreatedAt()

public function setCreatedAt(DateTimeInterface $createdAt): self

Group::getPermissions()

public function getPermissions(): Collection

Group::addPermission()

public function addPermission(Permission $permission): self

Group::removePermission()

public function removePermission(Permission $permission): self

Group::getRules()

public function getRules(): Collection

Group::addRule()

public function addRule(GroupRule $rule): self

Group::removeRule()

public function removeRule(GroupRule $rule): self

Group::getScopes()

public function getScopes(): Collection

Group::addScope()

public function addScope(GroupScope $scope): self

Group::removeScope()

public function removeScope(GroupScope $scope): self

Group::getActions()

public function getActions(): Collection

Group::addAction()

public function addAction(GroupAction $action): self

Group::removeAction()

public function removeAction(GroupAction $action): self

Group::awardsFor()

public function awardsFor(mixed $subject): array

Everything this group would award $subject, or nothing if it would not admit them.

Computes; it does not grant. The marketplace's manager accumulates what its actions return and applies the total itself ($discount += $action->apply($product)), and the same separation is what lets this be used to SHOW somebody what reaching the next level would give them - a preview that grants nothing.

Awards are merged and de-duplicated per kind, because two actions on one group may legitimately award the same role, and the caller wants the set rather than the tally.

Returns e.g. ["roles" => ["ROLE_X"], "permissions" => ["ALLIANCE.SENIOR"]]. The keys are the shapes the shipped adapters return; an adapter awarding something else lands under "other" rather than being silently dropped.

Group::isOpenTo()

public function isOpenTo(mixed $subject): bool

Whether this group would admit $subject as things stand.

Says nothing about whether they are already a member: this answers "have they earned it", so a group can be offered when it becomes reachable and a membership can be re-checked when a score moves.

No scopes means the group concerns everybody - the right default for one whose entry is purely a matter of score. No rules means nothing is being asked of them, so it admits anyone in scope rather than nobody: a group still being configured must not read as "closed".

Group::getScore()

public function getScore(): int

What belonging to this group costs, or earns.

A group carries penalties directly rather than through Sanction: a penalty on a group is a standing property of the group, not an incident with a date and an author, and it applies to whoever is a member at the time rather than to the people who were members when it was issued.

Group::getPenalties()

public function getPenalties(): Collection

Group::addPenalty()

public function addPenalty(Penalty $penalty): self

Group::removePenalty()

public function removePenalty(Penalty $penalty): self

Group::getColor()

public function getColor(): ?string

Group::setColor()

public function setColor(?string $color): self

Group::getIcon()

public function getIcon(): ?string

Group::setIcon()

public function setIcon(?string $icon): self

Identity class

class Identity Identity.php:25

An account's identity at a provider (Google...): the provider's own identifier of the person ("sub"), which is what links the account - never the address alone (plan "omniauth", Marco's decision QA3). omniauth's Contract\Identities over this table is Base\Auth\UserIdentities.

One subject of a provider has one account (unique provider + subject); an account has one identity per provider (unique account + provider, which also serves the account's own lookups). Removing the account removes its identities (ON DELETE CASCADE). The address the provider gave when the link was made, and whether it vouched for it, are kept as they were then; the last use is a sign-in by that identity. User::$identityProvider keeps its own meaning: where the account came from.

Identity::__construct()

public function __construct(User $user, string $provider, string $subject, ?string $email = null, bool $emailVerified = false)

Identity::getId()

public function getId(): ?int

Identity::getUser()

public function getUser(): ?User

Identity::getProvider()

public function getProvider(): string

Identity::getSubject()

public function getSubject(): string

Identity::getEmail()

public function getEmail(): ?string

Identity::isEmailVerified()

public function isEmailVerified(): bool

Identity::getCreatedAt()

public function getCreatedAt(): ?DateTimeInterface

Identity::getLastUsedAt()

public function getLastUsedAt(): ?DateTimeInterface

Identity::markUsed()

public function markUsed(DateTimeInterface $at): self

Invitation class

abstract class Invitation Invitation.php:18

An e-mail that opens something: whoever follows its link before it runs out gets an account (or signs in with theirs), attached to what it was made for. Only the token's hash is kept; the token itself is sent, never stored (Base\Service\Invitations).

A mapped superclass: each bundle keeps its own table and says what an invitation opens (omnibase/estate's Invitation: an associate, a tenant, a contractor, a member of the management, in estate_invitation).

Invitation::__construct()

public function __construct(string $email, string $name, string $tokenHash, \DateTimeImmutable $expiresAt)

Invitation::getId()

abstract public function getId(): ?int

Invitation::__toString()

public function __toString(): string

Invitation::getEmail()

public function getEmail(): string

Invitation::getName()

public function getName(): string

Invitation::getTokenHash()

public function getTokenHash(): string

Invitation::getCreatedAt()

public function getCreatedAt(): \DateTimeImmutable

Invitation::getExpiresAt()

public function getExpiresAt(): \DateTimeImmutable

Invitation::getAcceptedAt()

public function getAcceptedAt(): ?\DateTimeImmutable

Invitation::accept()

public function accept(): static

Invitation::getInvitedBy()

public function getInvitedBy(): ?User

Invitation::setInvitedBy()

public function setInvitedBy(?User $invitedBy): static

Invitation::isOpen()

public function isOpen(): bool

Notification class

class Notification extends SymfonyNotification implements BaseNotificationInterface, SmsNotificationInterface, EmailNotificationInterface, ChatNotificationInterface, IconizeInterface Notification.php:44

A notification: its subject, content, importance, channels, recipients, context and templates, and its sending through omnibase's notifier. Cut in two (plan "omnibase agnostique", step C3f): what needs Symfony - an ExceptionEvent or a FlattenException made content, render()'s Response, the e-mail built on Twig's TemplatedEmail and HttpFoundation's uploaded files - is Base\Bridge\Symfony\NotificationMessages'; this class names nothing of the framework (Symfony's Notifier is a standalone component).

const IMPORTANCE_DEFAULT = "default"
const IMPORTANCE_SUCCESS = "success"
const IMPORTANCE_INFO = "info"
const IMPORTANCE_NOTICE = "notice"
const IMPORTANCE_DANGER = "danger"

Notification::__toPrune()

public function __toPrune(?RecipientInterface $recipient = null): SymfonyNotification

Notification::__iconize()

public function __iconize(): ?array

Notification::__iconizeStatic()

public static function __iconizeStatic(): ?array

Notification::getId()

public function getId(): ?int

Notification::getUser()

public function getUser(): ?User

Notification::setUser()

public function setUser(?User $user): self

Notification::getAttachments()

public function getAttachments(): array

Notification::addAttachment()

public function addAttachment(\SplFileInfo $attachment): self

An e-mail's attachment: what the e-mail embeds is an uploaded file (HttpFoundation's UploadedFile, Base\Bridge\Symfony\NotificationMessages::email()), as before; the type is its parent, \SplFileInfo, so that this class names nothing of the framework.

Notification::removeAttachment()

public function removeAttachment(\SplFileInfo $attachment): self

Notification::getRecipients()

public function getRecipients(): array

Notification::addRecipient()

public function addRecipient(RecipientInterface $recipient): self

Notification::removeRecipient()

public function removeRecipient(RecipientInterface $recipient): self

Notification::getChannels()

public function getChannels(?RecipientInterface $recipient = null): array

Notification::setChannels()

public function setChannels(array $channels): self

Notification::getImportance()

public function getImportance(): string

Notification::setImportance()

public function setImportance(?string $importance): self

Notification::getSubject()

public function getSubject(): string

Notification::setSubject()

public function setSubject(string $subject): self

Notification::getContent()

public function getContent(): string

Notification::setContent()

public function setContent(string $content): self

Notification::getUrl()

public function getUrl(): ?string

Notification::setUrl()

public function setUrl(?string $url): self

Notification::getTargetClass()

public function getTargetClass(): ?string

Notification::getTargetId()

public function getTargetId(): ?string

Notification::setTarget()

public function setTarget(?object $entity): self

Notification::getTitle()

public function getTitle(): string

Notification::setTitle()

public function setTitle(string $title): self

Notification::isRead()

public function isRead(): bool

Notification::setIsRead()

public function setIsRead(bool $isRead): self

Notification::markAsRead()

public function markAsRead(bool $isRead)

Notification::markAsReadIfNeeded()

public function markAsReadIfNeeded(array $channels = [])

Notification::getSentAt()

public function getSentAt(): ?DateTimeInterface

Notification::setSentAt()

public function setSentAt(?DateTimeInterface $sentAt): self

Notification::getBacktrace()

public function getBacktrace(): string

Notification::isMarkAsAdmin()

public function isMarkAsAdmin()

Notification::markAsAdmin()

public function markAsAdmin(bool $markAsAdmin = true)

Notification::getContext()

public function getContext(array $additionalContext = [])

Notification::addContextKey()

public function addContextKey(string $key, $value = null): self

Notification::addContext()

public function addContext(array $context = []): self

Notification::setContext()

public function setContext(array $context): self

Notification::removeContextKey()

public function removeContextKey(string $key): self

Notification::getHtmlTemplate()

public function getHtmlTemplate()

Notification::setHtmlTemplate()

public function setHtmlTemplate(?string $htmlTemplate, array $htmlParameters = [])

Notification::getHtmlParameters()

public function getHtmlParameters(): array

Notification::setHtmlParameters()

public function setHtmlParameters(array $htmlParameters)

Notification::addHtmlParameter()

public function addHtmlParameter(string $key, $value)

Notification::removeHtmlParameter()

public function removeHtmlParameter(string $key)

Notification::getExcerpt()

public function getExcerpt()

Notification::setExcerpt()

public function setExcerpt(string $excerpt)

Notification::getFooter()

public function getFooter()

Notification::setFooter()

public function setFooter(string $footer)

Notification::__construct()

public function __construct($content = null, array $parameters = array(), string $domain = "@notifications", ?string $locale = null)
Throws

Exception

Notification::render()

public function render()

The notification as a page: Symfony's Response of renderHtml() (Base\Bridge\Symfony\NotificationMessages::response()).

Notification::renderHtml()

public function renderHtml(): string

The notification's HTML: its template rendered with its context, else its content.

Notification::send()

public function send(?string $importance = null, RecipientInterface ...$recipients)

Notification::sendBy()

public function sendBy(array $channels, RecipientInterface ...$recipients)

Notification::sendAdmins()

public function sendAdmins(string $importance)

Notification::asSmsMessage()

public function asSmsMessage(SmsRecipientInterface $recipient, ?string $transport = null): ?SmsMessage

Notification::asEmailMessage()

public function asEmailMessage(EmailRecipientInterface $recipient, ?string $transport = null): ?EmailMessage

The e-mail: Base\Bridge\Symfony\NotificationMessages::email(), with the notifier and the project's directory this notification reaches through Runtime (step E1; BaseTrait before), and the views through omnibridge's Views (Runtime::views(), since step F5a; Twig's environment through Base\Bridge\Symfony\FrameworkLocator before).

Notification::asChatMessage()

public function asChatMessage(RecipientInterface $recipient, ?string $transport = null): ?ChatMessage

Passkey class

class Passkey Passkey.php:33

A passkey of an account (WebAuthn's credential record), described by the core (plan "omniauth", AU1; decision O6): its 13 fields are its own attributes, no longer inherited from web-auth's Webauthn\CredentialRecord and mapped by WebauthnBundle's XML, so the table is described once, read the same by any host (the Laravel twin maps it as Symfony does) and the entity loads nothing of webauthn-lib. The columns are those the bundle made (userPasskey, Version20260726133116 on lesringostars): the same names, and the types passkey_base64, passkey_aaguid and passkey_trust_path (omnibridge/doctrine's Passkey\{Base64, Aaguid, TrustPath}; named by their names, so the attributes read with no persistence installed) declare the same SQL and write the same text as the bundle's base64, aaguid and trust_path - no migration, a row written by either read by the other.

The fields keep CredentialRecord's public names; their values are plain: the credential id and the public key as bytes, the AAGUID as its text, the trust path as the array webauthn-lib normalizes it to. The objects of the library are made from it where the library is used: Base\Repository\User\PasskeyRepository gives WebauthnBundle the CredentialRecord it asks for and saves what it hands back.

public string $publicKeyCredentialId

The credential's id: bytes, unique to the authenticator.

public string $type = 'public-key'
public array $transports = []
public string $attestationType = 'none'
public array $trustPath = []
public string $aaguid = '00000000-0000-0000-0000-000000000000'

The authenticator's model, a UUID's text (all zeros: none said).

public string $credentialPublicKey

The public key, COSE-encoded bytes.

public string $userHandle

The account's handle (its id, as text).

public int $counter = 0

The signature counter the authenticator last gave.

public ?array $otherUI = null
public ?bool $backupEligible = null
public ?bool $backupStatus = null
public ?bool $uvInitialized = null

Passkey::getId()

public function getId(): ?int

Passkey::getUser()

public function getUser(): ?User

Passkey::setUser()

public function setUser(?User $user): self

Passkey::getLabel()

public function getLabel(): ?string

Passkey::setLabel()

public function setLabel(?string $label): self

Passkey::getCreatedAt()

public function getCreatedAt(): ?DateTimeInterface

Passkey::getLastUsedAt()

public function getLastUsedAt(): ?DateTimeInterface

Passkey::touch()

public function touch(): self

Passkey::createFromCredentialRecord()

public static function createFromCredentialRecord(\Webauthn\CredentialRecord $record, User $user, ?string $label = null): self

A new passkey of $user, from the credential record webauthn-lib made at its registration (the bundle hands saveCredentialRecord() a plain Webauthn\CredentialRecord, never an instance of this class). A type in a signature loads nothing: the copy is PasskeyRepository's, the one place that speaks webauthn-lib.

Penalty class

class Penalty implements IconizeInterface Penalty.php:33

A penalty an administrator has defined, NOT one somebody has received.

This is a catalogue: an administrator writes the set of penalties the site recognises once - what each is called, what it costs, how long it lasts - and a moderator then applies one from that list rather than inventing a sanction and a number on the spot. Applying one creates a Sanction, which is where the per-case facts live (who, by whom, why, until when).

That split is why the user side is a Sanction and not the plain many-to-many it used to be: a join table has nowhere to record when a penalty expires or who issued it, so every application of the same penalty would have had to share one expiry.

Groups keep a direct many-to-many, because a penalty carried by a group is a property of the group itself rather than an incident with a date.

Penalty::__construct()

public function __construct(?string $type = null, int $weight = 0)

Penalty::__iconize()

public function __iconize(): ?array

Penalty::__iconizeStatic()

public static function __iconizeStatic(): ?array

Penalty::__toString()

public function __toString(): string

Penalty::getId()

public function getId(): ?int

Penalty::getFormType()

public function getFormType(): ?string

Penalty::getType()

public function getType(): ?string

Penalty::setType()

public function setType(string $type): self

Penalty::getWeight()

public function getWeight(): int

Penalty::setWeight()

public function setWeight(int $weight): self

Penalty::getDurationDays()

public function getDurationDays(): ?int

Penalty::setDurationDays()

public function setDurationDays(?int $durationDays): self

Penalty::expiresFrom()

public function expiresFrom(?DateTimeInterface $from = null): ?DateTime

When a sanction issued at $from would lapse, or null for one that never does. Kept here rather than in the moderator's hands so that changing a penalty's length in the catalogue changes it everywhere it is applied next, which is the point of having a catalogue.

Penalty::getExtra()

public function getExtra(): ?string

Penalty::setExtra()

public function setExtra(string $extra): self

Penalty::getCreatedAt()

public function getCreatedAt(): ?DateTimeInterface

Penalty::setCreatedAt()

public function setCreatedAt(DateTimeInterface $createdAt): self

Penalty::getSanctions()

public function getSanctions(): Collection

Penalty::getGid()

public function getGid(): Collection

Penalty::addGid()

public function addGid(Group $gid): self

Penalty::removeGid()

public function removeGid(Group $gid): self

Permission class

class Permission implements IconizeInterface Permission.php:14

Permission::__iconize()

public function __iconize(): ?array

Permission::__iconizeStatic()

public static function __iconizeStatic(): ?array

Permission::__construct()

public function __construct()

Permission::getId()

public function getId(): ?int

Permission::__toString()

public function __toString(): string

Its tag, wherever a permission is shown as one line (a group's permissions picker).

Permission::getTag()

public function getTag(): ?string

Permission::setTag()

public function setTag(string $tag): self

Permission::getDescription()

public function getDescription(): ?string

Permission::setDescription()

public function setDescription(string $description): self

Permission::getEmpoweredRoles()

public function getEmpoweredRoles(): array

Permission::setEmpoweredRoles()

public function setEmpoweredRoles(array $empower): self

Permission::getUid()

public function getUid(): Collection

Permission::addUid()

public function addUid(User $uid): self

Permission::removeUid()

public function removeUid(User $uid): self

Permission::getGid()

public function getGid(): Collection

Permission::addGid()

public function addGid(Group $gid): self

Permission::removeGid()

public function removeGid(Group $gid): self

Permission::getIcon()

public function getIcon(): ?string

Permission::setIcon()

public function setIcon(?string $icon): self

PushSubscription class

class PushSubscription PushSubscription.php:20

One browser's Web Push endpoint for one user. A person has one of these per browser they enabled notifications in (phone, laptop, ...), and each one dies on its own when the browser revokes it - the push service then answers 404/410 and WebPushService prunes the row.

Endpoint URLs run to ~300 characters, longer than an indexable MySQL unique key on utf8mb4, so uniqueness is enforced on a sha1 of it instead.

PushSubscription::getId()

public function getId(): ?int

PushSubscription::getUser()

public function getUser(): ?User

PushSubscription::setUser()

public function setUser(?User $user): self

PushSubscription::getEndpoint()

public function getEndpoint(): string

PushSubscription::setEndpoint()

public function setEndpoint(string $endpoint): self

PushSubscription::getEndpointHash()

public function getEndpointHash(): string

PushSubscription::getP256dh()

public function getP256dh(): string

PushSubscription::setP256dh()

public function setP256dh(string $p256dh): self

PushSubscription::getAuth()

public function getAuth(): string

PushSubscription::setAuth()

public function setAuth(string $auth): self

PushSubscription::getUserAgent()

public function getUserAgent(): ?string

PushSubscription::setUserAgent()

public function setUserAgent(?string $userAgent): self

PushSubscription::getCreatedAt()

public function getCreatedAt(): DateTimeInterface

PushSubscription::getLastUsedAt()

public function getLastUsedAt(): ?DateTimeInterface

PushSubscription::touch()

public function touch(): self

PushSubscription::__construct()

public function __construct()

PushSubscription::toArray()

public function toArray(): array

The shape minishlink/web-push expects.

Sanction class

class Sanction implements IconizeInterface Sanction.php:33

One penalty, given to one user, once.

The counterpart to Penalty: that one is the catalogue an administrator curates, this one is a moderator picking an entry from it and applying it. Everything that varies per case lives here - who received it, who issued it, why, and until when - while what the penalty IS and what it costs stays in the catalogue entry, so an administrator can restate the cost of "spam" in one place.

This exists as an entity rather than the join table it replaces (user_penalties) because a join row has room for nothing but the two ids. With one, every application of the same penalty would have shared a single expiry, and there would have been nowhere to record the moderator or the reason - the two things anybody asks for first when a sanction is disputed.

Expiry is stored, not derived. Penalty::expiresFrom() decides it when the sanction is created, and it is then frozen: shortening "spam" in the catalogue must not silently pardon everyone already serving one, and lengthening it must not silently extend them either.

Sanction::__construct()

public function __construct(?User $user = null, ?Penalty $penalty = null, ?User $moderator = null, ?string $reason = null)

Sanction::__iconize()

public function __iconize(): ?array

Sanction::__iconizeStatic()

public static function __iconizeStatic(): ?array

Sanction::getId()

public function getId(): ?int

Sanction::getUser()

public function getUser(): ?User

Sanction::setUser()

public function setUser(?User $user): self

Sanction::getPenalty()

public function getPenalty(): ?Penalty

Sanction::setPenalty()

public function setPenalty(?Penalty $penalty): self

Sanction::getModerator()

public function getModerator(): ?User

Sanction::setModerator()

public function setModerator(?User $moderator): self

Sanction::getReason()

public function getReason(): ?string

Sanction::setReason()

public function setReason(?string $reason): self

Sanction::getCreatedAt()

public function getCreatedAt(): ?DateTimeInterface

Sanction::getExpiresAt()

public function getExpiresAt(): ?DateTimeInterface

Sanction::setExpiresAt()

public function setExpiresAt(?DateTimeInterface $expiresAt): self

Sanction::getLiftedAt()

public function getLiftedAt(): ?DateTimeInterface

Sanction::lift()

public function lift(?DateTimeInterface $at = null): self

Sanction::isActive()

public function isActive(?DateTimeInterface $at = null): bool

Sanction::getWeight()

public function getWeight(?DateTimeInterface $at = null): int

What this contributes to a score right now - nothing once it has lapsed.

Token class

class Token implements IconizeInterface Token.php:20

const ALL = "ALL_TOKENS"
const VALID = "VALID_TOKENS"
const EXPIRED = "EXPIRED_TOKENS"

Token::__iconize()

public function __iconize(): ?array

Token::__iconizeStatic()

public static function __iconizeStatic(): ?array

Token::__construct()

public function __construct(string $name, ?int $expiry = null, ?int $throttle = null)

Token::__sleep()

public function __sleep()

Token::encode()

public function encode()

Token::decode()

public function decode(string $hash)

Token::getId()

public function getId(): ?int

Token::getUser()

public function getUser(): ?User

Token::setUser()

public function setUser(?User $user): self

Token::getName()

public function getName(): ?string

Token::setName()

public function setName(string $name): self

Token::get()

public function get(): ?string

Token::getValue()

public function getValue(): ?string

Token::setValue()

public function setValue(string $value): self

Keeps another value than the one generate() drew: a sign-in link's SHA-256, whose value only the mailbox holds (Base\Auth\UserLinkTokens, plan "omniauth", QA4).

Token::generate()

public function generate(?int $expiry = null, ?int $throttle = null): self

Token::getCreatedAt()

public function getCreatedAt(): ?DateTimeInterface

Token::setCreatedAt()

public function setCreatedAt(DateTimeInterface $createdAt): self

Token::getExpireAt()

public function getExpireAt(): ?DateTimeInterface

Token::setExpireAt()

public function setExpireAt(DateTimeInterface $expireAt): self

Token::getExpiry()

public function getExpiry(): ?DateTimeInterface

Token::setExpiry()

public function setExpiry(DateTimeInterface $expireAt): self

Token::isValid()

public function isValid(): bool

Token::getElapsedTime()

public function getElapsedTime(): int

Token::getLifetime()

public function getLifetime(): int

Token::getRemainingTime()

public function getRemainingTime(): int

Token::getRemainingTimeStr()

public function getRemainingTimeStr(): string

Token::getAllowAt()

public function getAllowAt(): ?DateTimeInterface

Token::setAllowAt()

public function setAllowAt(DateTimeInterface $allowAt): self

Token::hasVeto()

public function hasVeto(): bool

Token::getThrottleTime()

public function getThrottleTime(): int

Token::getThrottleTimeStr()

public function getThrottleTimeStr(): string

Token::setThrottleTime()

public function setThrottleTime(DateTimeInterface $allowAt): self

Token::isThrottled()

public function isThrottled(): bool

Token::revoke()

public function revoke(): self

Token::isRevoked()

public function isRevoked(): bool

Token::markAsRevoked()

public function markAsRevoked(): self

Token::isLogginable()

public function isLogginable(): bool

Token::markAsLogginable()

public function markAsLogginable(bool $isLogginable = true): self

Base\Entity\User\Attribute

GroupAction class

class GroupAction extends AbstractAction GroupAction.php:29

What a group DOES for somebody who qualifies for it.

The third of the triad, and the half that was missing: scopes decide who a group concerns, rules decide whether they qualify, and actions are what actually happens when they do. Without this the engine could only ever answer yes or no, which is why "reaching level 3 unlocks that alliance" stopped at "is eligible" and never became "has the role".

Modelled on the marketplace's DiscountAction: owned by the thing it belongs to, delegating the work to an adapter, and - importantly - COMPUTING rather than mutating. There, MarketplaceManager accumulates what the actions return ($discount += $action->apply($product)) and applies the total itself. Group::grantTo() does the same, gathering what every action awards before touching the user once, so an action can be evaluated (previewed, listed, explained) without granting anything.

GroupAction::get()

public function get(?string $locale = null): mixed

GroupAction::set()

public function set(...$args): self

GroupAction::resolve()

public function resolve(?string $locale = null): mixed

GroupAction::getGroup()

public function getGroup(): ?Group

GroupAction::setGroup()

public function setGroup(?Group $group): self

GroupRule class

class GroupRule extends AbstractRule GroupRule.php:26

A condition a user must satisfy for a group to be open to them.

Shaped after the marketplace's DiscountRule rather than as a free-floating rule: a rule belongs to the thing it qualifies, and carries a foreign key to it. That is what lets one rule table serve a discount, a shipping method and a group without any of them knowing about each other - the concrete subclass is the only thing that names an owner.

The predicate itself is not here. It lives in the adapter (ScoreAdapter and friends), which is why "reaching level 3 unlocks this alliance" needs no class of its own: it is a GroupRule pointing at a ScoreAdapter whose operation is GREATER_EQUAL.

GroupRule::get()

public function get(?string $locale = null): mixed

GroupRule::set()

public function set(...$args): self

GroupRule::resolve()

public function resolve(?string $locale = null): mixed

GroupRule::getGroup()

public function getGroup(): ?Group

GroupRule::setGroup()

public function setGroup(?Group $group): self

GroupScope class

class GroupScope extends AbstractScope GroupScope.php:26

Who a group's rules are about in the first place.

Scope and rule answer different questions, and the marketplace evaluates them differently for that reason (MarketplaceManager): scopes are OR-ed - any one matching brings the subject into range - while rules are AND-ed, because every condition has to hold. Scope is "does this concern you", rule is "do you qualify".

For a group that means a scope can narrow an alliance to, say, a region or a taxon, and the rules then decide whether a user inside that scope has earned their way in. A group with no scopes concerns everyone, which is the right default for one whose entry is purely a matter of score.

GroupScope::get()

public function get(?string $locale = null): mixed

GroupScope::set()

public function set(...$args): self

GroupScope::resolve()

public function resolve(?string $locale = null): mixed

GroupScope::getGroup()

public function getGroup(): ?Group

GroupScope::setGroup()

public function setGroup(?Group $group): self

Base\Entity\User\Attribute\Action

GrantPermissionAdapter class

class GrantPermissionAdapter extends AbstractActionAdapter GrantPermissionAdapter.php:33

Awards one or more fine-grained permission tags.

This is the piece that closes the loop the site already had half of. PermissionVoter has been live for a while, resolving custom tags like ARTICLE.PUBLISH from a user and their groups, with "ARTICLE.*" wildcards - but nothing could ever GRANT a tag except an administrator doing it by hand. With this, a score threshold can:

score >= 250  ->  grant "ALLIANCE.SENIOR"  ->  isGranted() says yes

so a level becomes a real capability with no code between the two.

Returns tags, not Permission entities, and deliberately: resolving a tag to its row is a repository lookup, and an entity that queries is an entity you cannot evaluate offline. The caller resolves and attaches, the same way MarketplaceManager applies the totals its adapters return.

GrantPermissionAdapter::__iconizeStatic()

public static function __iconizeStatic(): ?array

GrantPermissionAdapter::getType()

public static function getType(): string

GrantPermissionAdapter::getOptions()

public function getOptions(): array

GrantPermissionAdapter::resolve()

public function resolve(mixed $value): mixed

GrantPermissionAdapter::apply()

public function apply(mixed $value, mixed $subject): mixed

GrantRoleAdapter class

class GrantRoleAdapter extends AbstractActionAdapter GrantRoleAdapter.php:33

Awards one or more roles to whoever qualified.

This is the action behind "passing a level gives access": a group whose rules say score >= 250 and whose action grants ROLE_ALLIANCE_SENIOR turns a number into an actual capability, without anything hard-coding either the threshold or the role.

Returns the roles rather than assigning them, following the marketplace's adapters, which compute an amount and let MarketplaceManager apply the total. Group::grantTo() accumulates across every action and writes to the user once - so listing what a group WOULD give somebody costs nothing and changes nothing.

A role already held is still returned; deduplicating is the caller's job, because "what does this action award" and "what would change" are different questions and only the caller knows the user's current roles.

GrantRoleAdapter::__iconizeStatic()

public static function __iconizeStatic(): ?array

GrantRoleAdapter::getType()

public static function getType(): string

GrantRoleAdapter::getOptions()

public function getOptions(): array

GrantRoleAdapter::resolve()

public function resolve(mixed $value): mixed

GrantRoleAdapter::apply()

public function apply(mixed $value, mixed $subject): mixed

Base\Entity\User\Attribute\Scope

GroupAdapter class

class GroupAdapter extends AbstractScopeAdapter GroupAdapter.php:34

Narrows something to the members of another group.

This is what makes groups chain. An alliance scoped to "Explorers" with a rule of score >= 250 admits a senior explorer and nobody else, so membership can be built in tiers without any tier knowing the rules of the one below it - the same way the marketplace scopes a coupon to a Taxon and lets the category tree do the work.

Membership is read from the SUBJECT rather than from the scoped group, so this asks a user which groups they are in rather than asking a group to enumerate its members. On a group with many members that is the difference between one collection and a table scan, and it is also the direction that survives a user being scoped without the group being loaded.

Deliberately not transitive: being in a group that is itself scoped to Explorers does not make you an Explorer. Chaining is a thing you express by pointing a scope at each tier, not something inferred - inferred transitive membership is how a cycle becomes an infinite loop.

GroupAdapter::__iconizeStatic()

public static function __iconizeStatic(): ?array

GroupAdapter::getType()

public static function getType(): string

GroupAdapter::getOptions()

public function getOptions(): array

GroupAdapter::resolve()

public function resolve(mixed $value): mixed

GroupAdapter::supports()

public function supports(mixed $value): bool

GroupAdapter::contains()

public function contains(mixed $value, mixed $subject): bool

UserAdapter class

class UserAdapter extends AbstractScopeAdapter UserAdapter.php:34

Narrows something to named people.

The scope half of the engine, ported from the marketplace's own UserAdapter - the one that limits a coupon to particular customers. Here it limits a group to particular users, which is what makes an alliance invitational rather than open to anyone who clears its score.

The stored value is a User entity, not an id: supports() says so, and the form is an entity picker. That follows the original rather than being a choice - scopes there hold Products, Regions and Users, and comparing rows rather than ids is what lets a scope be checked without a lookup.

contains() walks from whatever subject it is handed to the user it is really about, exactly as the marketplace's walks Order and OrderItem to their customer. A Sanction is asked about its user, so a scope can be pointed at moderation records as readily as at people. Anything with no user behind it falls through to the parent, which throws rather than quietly answering false - a scope that cannot judge a subject is a misconfiguration, not a "no".

UserAdapter::__iconizeStatic()

public static function __iconizeStatic(): ?array

UserAdapter::getType()

public static function getType(): string

UserAdapter::getOptions()

public function getOptions(): array

UserAdapter::resolve()

public function resolve(mixed $value): mixed

UserAdapter::supports()

public function supports(mixed $value): bool

UserAdapter::contains()

public function contains(mixed $value, mixed $subject): bool

Base\Enum

Allergen enum

enum Allergen Allergen.php:15

The fourteen allergens a food business must declare in the European Union (Regulation (EU) No 1169/2011, Annex II), in the Annex's order. A plain string enum: stored as is (a JSON list of values on a dish, a varchar), labelled through the "enums" translation domain (allergen.<value>).

#[ORM\Column(type: 'json')] private array $allergens = []; // ['gluten', 'milk'] Allergen::fromList($dish->getAllergens()) {{ ('@enums.allergen.' ~ a.value)|trans }}

case GLUTEN = 'gluten'
case CRUSTACEANS = 'crustaceans'
case EGGS = 'eggs'
case FISH = 'fish'
case PEANUTS = 'peanuts'
case SOYBEANS = 'soybeans'
case MILK = 'milk'
case NUTS = 'nuts'
case CELERY = 'celery'
case MUSTARD = 'mustard'
case SESAME = 'sesame'
case SULPHITES = 'sulphites'
case LUPIN = 'lupin'
case MOLLUSCS = 'molluscs'

Allergen::number()

public function number(): int

Its number in Annex II (1 to 14), as menus often print it.

Allergen::trans()

public function trans(): string

The translation key of its name, in the "enums" domain.

Allergen::fromList()

public static function fromList(iterable $values): array

Stored values back to cases, unknown ones dropped, in the Annex's order.

Allergen::choices()

public static function choices(): array
Returns

translation key => value, for a ChoiceType (choice_translation_domain: 'enums')

CommentState enum

enum CommentState CommentState.php:10

Where a comment is: waiting for the moderator, online, filed as spam, or taken down. A string enum (not omnibase's EnumType) so the column reads plainly in the database and in the admin's filters.

case PENDING = 'pending'
case APPROVED = 'approved'
case SPAM = 'spam'
case TRASH = 'trash'

CommentState::isVisible()

public function isVisible(): bool

ConnectionState class

class ConnectionState extends EnumType implements IconizeInterface ConnectionState.php:8

const FAILED = "CONNECTION_FAILED"
const REQUESTED = "CONNECTION_REQUESTED"
const SUCCEEDED = "CONNECTION_SUCCEEDED"
const CLOSED = "CONNECTION_CLOSED"

ConnectionState::__iconize()

public function __iconize(): ?array

ConnectionState::__iconizeStatic()

public static function __iconizeStatic(): ?array

EntityAction class

class EntityAction extends EnumType implements IconizeInterface EntityAction.php:8

const INSERT = "ACTION_INSERT"
const UPDATE = "ACTION_UPDATE"
const DELETE = "ACTION_DELETE"

EntityAction::__iconize()

public function __iconize(): ?array

EntityAction::__iconizeStatic()

public static function __iconizeStatic(): ?array

LogLevel class

class LogLevel extends EnumType implements IconizeInterface LogLevel.php:8

const INFO = "INFO"
const DEBUG = "DEBUG"
const WARNING = "WARNING"
const CRITICAL = "CRITICAL"

LogLevel::__iconize()

public function __iconize(): ?array

LogLevel::__iconizeStatic()

public static function __iconizeStatic(): ?array

Operation class

class Operation extends EnumType implements IconizeInterface Operation.php:8

const LT = "LESS"
const LTE = "LESS_EQUAL"
const EQ = "EQUAL"
const GTE = "GREATER_EQUAL"
const GT = "GREATER"
const NEQ = "NOTEQUAL"

Operation::__iconize()

public function __iconize(): ?array

Operation::__iconizeStatic()

public static function __iconizeStatic(): ?array

SpamApi class

class SpamApi extends EnumType implements IconizeInterface SpamApi.php:12

the classifier is a gateway of omnisense/omnishield, named by base.guard.classifier (Akismet by default): SpamChecker no longer reads this value

const AKISMET = "AKISMET"

SpamApi::__iconize()

public function __iconize(): ?array

SpamApi::__iconizeStatic()

public static function __iconizeStatic(): ?array

SpamScore class

class SpamScore extends EnumType implements IconizeInterface SpamScore.php:8

const NO_TEXT = "NO_TEXT"
const NOT_SPAM = "NOT_SPAM"
const MAYBE_SPAM = "MAYBE_SPAM"
const BLATANT_SPAM = "BLATANT_SPAM"

SpamScore::__iconize()

public function __iconize(): ?array

SpamScore::__iconizeStatic()

public static function __iconizeStatic(): ?array

SpamScore::__toInt()

public static function __toInt()

ThreadState class

class ThreadState extends EnumType implements IconizeInterface, ColorizeInterface ThreadState.php:9

const DRAFT = "STATE_DRAFT"
const FUTURE = "STATE_FUTURE"
const PUBLISH = "STATE_PUBLISH"
const SECRET = "STATE_PUBLISH_SECRET"
const ARCHIVE = "STATE_PUBLISH_ARCHIVE"
const PASSWORD = "STATE_PUBLISH_PASSWORD"
const DELETE = "STATE_DELETE"

ThreadState::__iconize()

public function __iconize(): ?array

ThreadState::__iconizeStatic()

public static function __iconizeStatic(): ?array

ThreadState::__colorize()

public function __colorize(): ?array

ThreadState::__colorizeStatic()

public static function __colorizeStatic(): ?array

UploadState class

class UploadState extends SetType implements IconizeInterface UploadState.php:8

const UPLOAD_ERROR = "UPLOAD_ERROR"
const UPLOAD_FILESIZE = "UPLOAD_FILESIZE"
const UPLOAD_MIMETYPE = "UPLOAD_MIMETYPE"

UploadState::__iconize()

public function __iconize(): ?array

UploadState::__iconizeStatic()

public static function __iconizeStatic(): ?array

UserGender class

class UserGender extends EnumType implements IconizeInterface UserGender.php:8

const MALE = "MALE"
const FEMALE = "FEMALE"
const HYBRID = "HYBRID"
const GENDERLESS = "GENDERLESS"

UserGender::__iconize()

public function __iconize(): ?array

UserGender::__iconizeStatic()

public static function __iconizeStatic(): ?array

UserRole class

class UserRole extends SetType implements IconizeInterface UserRole.php:8

const EDITOR = "ROLE_EDITOR"
const SUPERADMIN = "ROLE_SUPERADMIN"
const ADMIN = "ROLE_ADMIN"
const USER = "ROLE_USER"

UserRole::__iconize()

public function __iconize(): ?array

UserRole::__iconizeStatic()

public static function __iconizeStatic(): ?array

UserRole::getCrudController()

public static function getCrudController(string $role): ?string

The back office's screen of the accounts of that role: omnibase/admin's, when it is installed.

UserState class

class UserState extends SetType implements IconizeInterface UserState.php:8

const NEWCOMER = "USER_NEWCOMER"
const GHOST = "USER_GHOST"
const BANNED = "USER_BANNED"
const LOCKED = "USER_LOCKED"
const KICKED = "USER_KICKED"
const VERIFIED = "USER_VERIFIED"
const APPROVED = "USER_APPROVED"
const ENABLED = "USER_ENABLED"

UserState::__iconize()

public function __iconize(): ?array

UserState::__iconizeStatic()

public static function __iconizeStatic(): ?array

WorkflowState class

class WorkflowState extends EnumType implements IconizeInterface WorkflowState.php:8

const SUBMITTED = "WORKFLOW_SUBMITTED"
const SUSPENDED = "WORKFLOW_SUSPENDED"
const PENDING = "WORKFLOW_PENDING"
const REVIEWING = "WORKFLOW_REVIEWING"
const REJECTED = "WORKFLOW_REJECTED"
const APPROVED = "WORKFLOW_APPROVED"

WorkflowState::__iconize()

public function __iconize(): ?array

WorkflowState::__iconizeStatic()

public static function __iconizeStatic(): ?array

Base\Enum\Quadrant

Quadrant class

class Quadrant extends EnumType implements IconizeInterface Quadrant.php:8

const O = "ORIGIN"
const N = "NORTH"
const E = "EAST"
const S = "SOUTH"
const W = "WEST"

Quadrant::__iconize()

public function __iconize(): ?array

Quadrant::__iconizeStatic()

public static function __iconizeStatic(): ?array

Quadrant::getDefault()

public static function getDefault()

Quadrant::getTheta()

public static function getTheta()

Quadrant::getRotation()

public static function getRotation(string $quadrant): ?float

Quadrant::getRotations()

public static function getRotations(): array

Quadrant::getPosition()

public static function getPosition(string $quadrant): string

Quadrant::getPositions()

public static function getPositions(): array

Quadrant16 class

class Quadrant16 extends Quadrant8 Quadrant16.php:5

const NNE = "NORTH_NORTHEAST"
const ENE = "EAST_NORTHEAST"
const ESE = "EAST_SOUTHEAST"
const SSE = "SOUTH_SOUTHEAST"
const SSW = "SOUTH_SOUTHWEST"
const WSW = "WEST_SOUTHWEST"
const WNW = "WEST_NORTHWEST"
const NNW = "NORTH_NORTHWEST"

Quadrant16::__iconize()

public function __iconize(): ?array

Quadrant16::__iconizeStatic()

public static function __iconizeStatic(): ?array

Quadrant16::getTheta()

public static function getTheta()

Quadrant16::getRotation()

public static function getRotation(string $quadrant): ?float

Quadrant16::getRotations()

public static function getRotations(): array

Quadrant16::getPosition()

public static function getPosition(string $quadrant): string

Quadrant16::getPositions()

public static function getPositions(): array

Quadrant32 class

class Quadrant32 extends Quadrant16 Quadrant32.php:5

const NbW = "NORTH_BY_WEST"
const NbE = "NORTH_BY_EAST"
const NEbN = "NORTHEAST_BY_NORTH"
const NEbE = "NORTHEAST_BY_EAST"
const EbN = "EAST_BY_NORTH"
const EbS = "EAST_BY_SOUTH"
const SEbE = "SOUTHEAST_BY_EAST"
const SEbS = "SOUTHEAST_BY_SOUTH"
const SbE = "SOUTH_BY_EAST"
const SbW = "SOUTH_BY_WEST"
const SWbS = "SOUTHWEST_BY_SOUTH"
const SWbW = "SOUTHWEST_BY_WEST"
const WbS = "WEST_BY_SOUTH"
const WbN = "WEST_BY_NORTH"
const NWbW = "NORTHWEST_BY_WEST"
const NWbN = "NORTHWEST_BY_NORTH"

Quadrant32::__iconize()

public function __iconize(): ?array

Quadrant32::__iconizeStatic()

public static function __iconizeStatic(): ?array

Quadrant32::getTheta()

public static function getTheta()

Quadrant32::getRotation()

public static function getRotation(string $quadrant): ?float

Quadrant32::getRotations()

public static function getRotations(): array

Quadrant32::getPosition()

public static function getPosition(string $quadrant): string

Quadrant32::getPositions()

public static function getPositions(): array

Quadrant8 class

class Quadrant8 extends Quadrant Quadrant8.php:5

const NE = "NORTHEAST"
const SE = "SOUTHEAST"
const SW = "SOUTHWEST"
const NW = "NORTHWEST"

Quadrant8::__iconize()

public function __iconize(): ?array

Quadrant8::__iconizeStatic()

public static function __iconizeStatic(): ?array

Quadrant8::getTheta()

public static function getTheta()

Quadrant8::getRotation()

public static function getRotation(string $quadrant): ?float

Quadrant8::getRotations()

public static function getRotations(): array

Quadrant8::getPosition()

public static function getPosition(string $quadrant): string

Quadrant8::getPositions()

public static function getPositions(): array

Base\Enum\SystemOfUnits

BritishImperialUnits class

class BritishImperialUnits extends EnumType implements IconizeInterface BritishImperialUnits.php:8

BritishImperialUnits::__iconize()

public function __iconize(): ?array

BritishImperialUnits::__iconizeStatic()

public static function __iconizeStatic(): ?array

StandardBaseUnits class

class StandardBaseUnits extends EnumType implements IconizeInterface, ColorizeInterface StandardBaseUnits.php:9

const SECOND = "s"
const METER = "m"
const KILOGRAM = "kg"
const AMPERE = "A"
const KELVIN = "K"
const MOLE = "mol"
const CANDELA = "cd"

StandardBaseUnits::__iconize()

public function __iconize(): ?array

StandardBaseUnits::__iconizeStatic()

public static function __iconizeStatic(): ?array

StandardBaseUnits::__colorize()

public function __colorize(): ?array

StandardBaseUnits::__colorizeStatic()

public static function __colorizeStatic(): ?array

StandardBaseUnits::getBaseUnit()

public static function getBaseUnit(string $name): ?string

StandardBaseUnits::getBaseUnits()

public static function getBaseUnits(): ?array

StandardBaseUnits::getBaseUnitName()

public static function getBaseUnitName(string $name): ?string

StandardBaseUnits::getBaseUnitNames()

public static function getBaseUnitNames(): ?array

StandardBaseUnits::getConstant()

public static function getConstant(string $name): ?string

StandardBaseUnits::getConstants()

public static function getConstants(): ?array

StandardBaseUnits::getConstantSymbol()

public static function getConstantSymbol(string $name): ?string

StandardBaseUnits::getConstantSymbols()

public static function getConstantSymbols(): ?array

StandardBaseUnits::getConstantUnit()

public static function getConstantUnit(string $name): ?string

StandardBaseUnits::getConstantUnits()

public static function getConstantUnits(): ?array

StandardBaseUnits::getConstantName()

public static function getConstantName(string $name): ?string

StandardBaseUnits::getConstantNames()

public static function getConstantNames(): ?array

StandardUnits class

class StandardUnits extends StandardBaseUnits implements IconizeInterface StandardUnits.php:7

StandardUnits::__iconize()

public function __iconize(): ?array

StandardUnits::__iconizeStatic()

public static function __iconizeStatic(): ?array

UnitedStatesCustomaryUnits class

class UnitedStatesCustomaryUnits extends EnumType implements IconizeInterface UnitedStatesCustomaryUnits.php:8

UnitedStatesCustomaryUnits::__iconize()

public function __iconize(): ?array

UnitedStatesCustomaryUnits::__iconizeStatic()

public static function __iconizeStatic(): ?array

Base\Event

SignatureEvent class

final class SignatureEvent extends Event SignatureEvent.php:19

An envelope moved (Base\Service\Signatures): completed, declined, expired, canceled - or a signer signed. The application answers on what it is about: a quote accepted once signed, a lease in force.

#[AsEventListener(event: SignatureEvent::COMPLETED)] public function onSigned(SignatureEvent $event): void { if (Quote::class === $event->getEnvelope()->getSubjectClass()) { ... } }

const COMPLETED = 'base.signature.completed'
const DECLINED = 'base.signature.declined'
const EXPIRED = 'base.signature.expired'
const CANCELED = 'base.signature.canceled'
const SIGNED = 'base.signature.signed'

A signer signed; the others may not have yet.

SignatureEvent::__construct()

public function __construct(readonly Envelope $envelope, readonly ?object $subject = null, readonly ?string $signer = null)

SignatureEvent::getEnvelope()

public function getEnvelope(): Envelope

SignatureEvent::getSubject()

public function getSubject(): ?object

The entity it is about, when it still exists.

SignatureEvent::getSigner()

public function getSigner(): ?string

For SIGNED: the signer's key.

SitemapEvent class

class SitemapEvent extends Event SitemapEvent.php:18

Dispatched while /sitemap.xml is being built, once the routes carrying a Sitemap attribute have been registered.

registerAttributes() can only see routes it can generate on its own, so it skips every route taking a parameter - which is every entity page a site actually wants indexed. The bundle has no way to know what those entities are, and must not: listen to this event from the application and call register() or registerUrl() for the URLs it alone can enumerate.

const BUILD = 'sitemap.build'

SitemapEvent::__construct()

public function __construct(readonly SitemapperInterface $sitemapper, readonly string $hostname)

SitemapEvent::getSitemapper()

public function getSitemapper(): SitemapperInterface

SitemapEvent::getHostname()

public function getHostname(): string

Base\Exception

DemoRefusedException class

class DemoRefusedException extends RuntimeException DemoRefusedException.php:6

The demo environment refuses to start, or demo:reset to run (Base\Demo\DemoGuard).

InvalidMimeTypeException class

class InvalidMimeTypeException extends Exception InvalidMimeTypeException.php:7

InvalidMimeTypeException::getMessageKey()

public function getMessageKey()

{}

InvalidPageException class

class InvalidPageException extends Exception InvalidPageException.php:7

InvalidPageException::getMessageKey()

public function getMessageKey()

{}

InvalidSizeException class

class InvalidSizeException extends Exception InvalidSizeException.php:7

InvalidSizeException::getMessageKey()

public function getMessageKey()

{}

InvalidUuidException class

class InvalidUuidException extends Exception InvalidUuidException.php:7

InvalidUuidException::getMessageKey()

public function getMessageKey()

{}

MissingDiscriminatorMapException class

class MissingDiscriminatorMapException extends Exception MissingDiscriminatorMapException.php:7

MissingDiscriminatorMapException::getMessageKey()

public function getMessageKey()

{}

MissingDiscriminatorValueException class

class MissingDiscriminatorValueException extends Exception MissingDiscriminatorValueException.php:7

MissingDiscriminatorValueException::getMessageKey()

public function getMessageKey()

{}

MissingLocaleException class

class MissingLocaleException extends Exception MissingLocaleException.php:7

MissingLocaleException::getMessageKey()

public function getMessageKey()

{}

MissingPublicPathException class

class MissingPublicPathException extends Exception MissingPublicPathException.php:7

MissingPublicPathException::getMessageKey()

public function getMessageKey()

{}

NotDeletableException class

class NotDeletableException extends Exception NotDeletableException.php:7

NotDeletableException::getMessageKey()

public function getMessageKey()

{}

NotFoundResourceException class

class NotFoundResourceException extends Exception NotFoundResourceException.php:7

NotFoundResourceException::getMessageKey()

public function getMessageKey()

{}

NotReadableException class

class NotReadableException extends Exception NotReadableException.php:7

NotReadableException::getMessageKey()

public function getMessageKey()

{}

NotWritableException class

class NotWritableException extends Exception NotWritableException.php:7

NotWritableException::getMessageKey()

public function getMessageKey()

{}

OwnerSideException class

class OwnerSideException extends Exception OwnerSideException.php:7

OwnerSideException::getMessageKey()

public function getMessageKey()

{}

SitemapNotFoundException class

class SitemapNotFoundException extends Exception SitemapNotFoundException.php:7

SitemapNotFoundException::getMessageKey()

public function getMessageKey()

{}

TranslationAmbiguityException class

class TranslationAmbiguityException extends Exception TranslationAmbiguityException.php:7

TranslationAmbiguityException::getMessageKey()

public function getMessageKey()

{}

UnsupportedBehaviourException class

final class UnsupportedBehaviourException extends LogicException UnsupportedBehaviourException.php:11

A behaviour (#[Vault], #[Slugify], #[Cache]...) needs a part of the persistence that the installed one does not provide: refused aloud, where a behaviour that found nothing would leave a row unsealed, a slug not unique or a cache stale in silence (plan "omnibase agnostic", step F2b).

UnsupportedBehaviourException::for()

public static function for(string $behaviour, object $unitOfWork): self

UploaderAmbiguityException class

class UploaderAmbiguityException extends Exception UploaderAmbiguityException.php:7

UploaderAmbiguityException::getMessageKey()

public function getMessageKey()

{}

VaultKeyNotFoundException class

class VaultKeyNotFoundException extends RuntimeException VaultKeyNotFoundException.php:9

A field secured by #[Vault] is about to be stored and the vault has no key pair: the value is refused rather than written in clear.

public readonly string $vault
public readonly string $path

VaultKeyNotFoundException::__construct()

public function __construct(public readonly string $vault, public readonly string $path, ?string $reason = null, ?\Throwable $previous = null)

Base\Field

ArrayField class

class ArrayField extends CollectionField implements FieldInterface ArrayField.php:6

const OPTION_ASSOCIATIVE = 'associative'
const OPTION_LENGTH = 'length'
const OPTION_PATTERN_FIELD_NAME = 'pattern'
const OPTION_PLACEHOLDER = 'placeholder'

ArrayField::new()

public static function new(string $propertyName, $label = null): self

ArrayField::useAssociativeKeys()

public function useAssociativeKeys(bool $use_associative = true): self

ArrayField::setPlaceholder()

public function setPlaceholder(array $placeholder): self

ArrayField::setPatternFieldName()

public function setPatternFieldName(string $fieldName): self

ArrayField::allowAdd()

public function allowAdd(bool $allow = true): self

ArrayField::allowDelete()

public function allowDelete(bool $allow = true): self

ArrayField::setEntryIsComplex()

public function setEntryIsComplex(bool $isComplex): self

Set this option to TRUE if the collection items are complex form types composed of several form fields (EasyAdmin applies a special rendering to make them look better).

ArrayField::setEntryType()

public function setEntryType(string $entryType): self

ArrayField::setEntryOptions()

public function setEntryOptions(array $entryOptions): self

ArrayField::renderExpanded()

public function renderExpanded(bool $renderExpanded = true): self

ArrayField::setLength()

public function setLength(string|int $length): self

AssociationField class

final class AssociationField implements FieldInterface AssociationField.php:8

const OPTION_RENDER_FORMAT = 'renderFormat'
const OPTION_ICONS = 'icons'
const OPTION_CLASS = 'class'
const OPTION_CRUD_CONTROLLER = 'crudControllerFqcn'
const OPTION_DISPLAY_LIMIT = 'displayLimit'
const OPTION_ENTITY_DISPLAY = 'entityDisplay'
const OPTION_ICON_ALIGN = 'iconAlign'
const OPTION_SHOW_FIRST = 'showFirst'
const OPTION_SHOW = 'show'
const NO_SHOW = 0
const SHOW_NAME_ONLY = 1
const SHOW_ICON_ONLY = 2
const SHOW_ALL = 3
const OPTION_ALLOW_ADD = 'allowAdd'
const OPTION_ALLOW_DELETE = 'allowDelete'
const OPTION_LENGTH = 'length'
const OPTION_DOCTRINE_ASSOCIATION_TYPE = 'associationType'

AssociationField::new()

public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): self

AssociationField::embed()

public function embed(bool $embed = true): self

The related record's own form, inside the form of the record being edited. By default the back office does that only for what the record owns (one-to-many, one-to-one); a record that exists on its own (many-to-one, many-to-many, a user account) is chosen in a list.

embed(false) asks for the list whatever the association.

AssociationField::justDisplay()

public function justDisplay(): self

AssociationField::autoload()

public function autoload($autoload = true): self

AssociationField::setFields()

public function setFields(array $fields): self

AssociationField::allowAdd()

public function allowAdd(bool $allowAdd = true): self

AssociationField::setTextAlign()

public function setTextAlign(string $textAlign)

AssociationField::setIconAlign()

public function setIconAlign(string $iconAlign)

AssociationField::allowMultipleChoices()

public function allowMultipleChoices(bool $allow = true)

AssociationField::allowDelete()

public function allowDelete(bool $allow = true)

AssociationField::turnHorizontal()

public function turnHorizontal(bool $horizontal)

AssociationField::showVertical()

public function showVertical(bool $vertical = true)

AssociationField::setDisplayLimit()

public function setDisplayLimit(int $limit = 2)

AssociationField::setEntityDisplay()

public function setEntityDisplay(string $mode = FieldValueResolver::DISPLAY_USERNAME)
$mode

one of FieldValueResolver::DISPLAY_*

AssociationField::setIcons()

public function setIcons(array $icons)

AssociationField::setClass()

public function setClass(?string $class = null)

AssociationField::showFirst()

public function showFirst(int $show = self::SHOW_ALL)

AssociationField::show()

public function show(int $show = self::SHOW_ALL)

AssociationField::useHtml()

public function useHtml(bool $useHtml = true)

AssociationField::renderAsCount()

public function renderAsCount()

AssociationField::renderAsText()

public function renderAsText()

AssociationField::setLength()

public function setLength(int $length): self

AssociationField::showEmbedded()

public function showEmbedded($embed = true): self

AssociationField::showEmbeddedRow()

public function showEmbeddedRow($embed = true): self

AssociationField::showCollapsed()

public function showCollapsed($collapsed = true): self

AssociationFileField class

final class AssociationFileField implements FieldInterface AssociationFileField.php:11

const OPTION_SHOWFIRST = "showFirst"
const OPTION_ICONS = 'icons'
const OPTION_RENDER_FORMAT = "renderFormat"
const OPTION_CRUD_CONTROLLER = 'crudControllerFqcn'
const OPTION_DOCTRINE_ASSOCIATION_TYPE = 'associationType'
const OPTION_CLASS = 'class'
const OPTION_DISPLAY_LIMIT = 'displayLimit'
const OPTION_ICON_ALIGN = 'iconAlign'
const OPTION_SHOW_FIRST = 'showFirst'
const OPTION_SHOW = 'show'
const NO_SHOW = 0
const SHOW_NAME_ONLY = 1
const SHOW_ICON_ONLY = 2
const SHOW_ALL = 3

AssociationFileField::new()

public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): self

AssociationFileField::setClass()

public function setClass(?string $class = null)

AssociationFileField::renderAsText()

public function renderAsText(): self

AssociationFileField::renderAsCount()

public function renderAsCount(): self

AssociationFileField::renderAsImage()

public function renderAsImage(): self

AssociationFileField::renderAsAvatar()

public function renderAsAvatar(): self

AssociationFileField::setFieldFile()

public function setFieldFile(string $fieldFile): self

AssociationFileField::setFieldData()

public function setFieldData(array|callable $data): self

AssociationFileField::setTextAlign()

public function setTextAlign(string $textAlign)

AssociationFileField::setIconAlign()

public function setIconAlign(string $iconAlign)

AssociationFileField::allowMultipleChoices()

public function allowMultipleChoices(bool $allow = true)

AssociationFileField::allowDelete()

public function allowDelete(bool $allow = true)

AssociationFileField::setMaxSize()

public function setMaxSize(int $filesize)

AssociationFileField::setMaxFiles()

public function setMaxFiles(int $nFiles)

AssociationFileField::setMimeTypes()

public function setMimeTypes(array $mimeTypes)

AssociationFileField::setDisplayLimit()

public function setDisplayLimit(int $limit = 2)

AssociationFileField::setIcons()

public function setIcons(array $icons)

AssociationFileField::showFirst()

public function showFirst(int $show = self::SHOW_ALL)

AssociationFileField::show()

public function show(int $show = self::SHOW_ALL)

AttributeField class

final class AttributeField implements FieldInterface AttributeField.php:7

const OPTION_CLASS = 'class'
const OPTION_CHOICES = 'choices'
const OPTION_ICONS = 'icons'
const OPTION_FILTER = 'filter'
const OPTION_DISPLAY_LIMIT = 'displayLimit'
const OPTION_ICON_ALIGN = 'iconAlign'
const OPTION_RENDER_FORMAT = 'renderFormat'
const OPTION_SHOW_FIRST = 'showFirst'
const OPTION_SHOW = 'show'
const NO_SHOW = 0
const SHOW_NAME_ONLY = 1
const SHOW_ICON_ONLY = 2
const SHOW_ALL = 3
const OPTION_FILTER_CODE = 'filter_code'

AttributeField::new()

public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): self

AttributeField::setFilterCode()

public function setFilterCode(?string $filter = null): self

AttributeField::setClass()

public function setClass(?string $class = null)

AttributeField::allowDelete()

public function allowDelete(bool $allowDelete = true): self

AttributeField::allowAdd()

public function allowAdd(bool $allowAdd = true): self

AttributeField::setFields()

public function setFields(array $fields): self

AttributeField::setTextAlign()

public function setTextAlign(string $textAlign)

AttributeField::setIconAlign()

public function setIconAlign(string $iconAlign)

AttributeField::allowMultipleChoices()

public function allowMultipleChoices(bool $allow = true)

AttributeField::allowMultiValues()

public function allowMultiValues(bool $allow = true)

AttributeField::setChoices()

public function setChoices($choiceGenerator)

AttributeField::setFilter()

public function setFilter(...$filter)

AttributeField::setDisplayLimit()

public function setDisplayLimit(int $limit = 2)

AttributeField::setIcons()

public function setIcons(array $icons)

AttributeField::showFirst()

public function showFirst(int $show = self::SHOW_ALL)

AttributeField::show()

public function show(int $show = self::SHOW_ALL)

AttributeField::renderAsCount()

public function renderAsCount()

AudioField class

class AudioField extends FileField implements FieldInterface AudioField.php:8

const OPTION_RENDER_FORMAT = 'renderFormat'

AudioField::new()

public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): self

AvatarField class

class AvatarField extends ImageField implements FieldInterface AvatarField.php:8

const OPTION_RENDER_FORMAT = 'renderFormat'

AvatarField::new()

public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): self

BooleanField class

final class BooleanField implements FieldInterface BooleanField.php:7

const OPTION_RENDER_AS_SWITCH = 'switch'
const OPTION_CONFIRMATION_MODAL_ON_CHECK = 'confirmation[onCheck]'
const OPTION_CONFIRMATION_MODAL_ON_UNCHECK = 'confirmation[onUncheck]'
const OPTION_TOGGLE_URL = 'toggleUrl'

BooleanField::new()

public static function new(string $propertyName, $label = null): self

BooleanField::renderAsSwitch()

public function renderAsSwitch(bool $isASwitch = true): self

BooleanField::showInline()

public function showInline(bool $inline = true): self

BooleanField::withConfirmation()

public function withConfirmation(bool $onCheck = true, bool $onUncheck = true): self

CodeField class

class CodeField implements FieldInterface CodeField.php:11

A code of known length, one box per character (Base\Field\Type\CodeType).

Reads as plain text on index/detail.

CodeField::new()

public static function new(string $propertyName, $label = null)

CodeField::setLength()

public function setLength(int $length): static

CodeField::setAlphabet()

public function setAlphabet(string $alphabet): static

'alnum' (default), 'digits' or 'alpha'.

CodeField::setUppercase()

public function setUppercase(bool $uppercase = true): static

CollectionField class

class CollectionField implements FieldInterface CollectionField.php:7

const OPTION_ALLOW_ADD = 'allow_add'
const OPTION_ALLOW_OBJECT = 'allow_object'
const OPTION_ALLOW_DELETE = 'allow_delete'
const OPTION_ENTRY_IS_COMPLEX = 'entryIsComplex'
const OPTION_ENTRY_TYPE = 'entry_type'
const OPTION_ENTRY_OPTIONS = 'entry_options'
const OPTION_ENTRY_LABEL = 'entry_label'
const OPTION_RENDER_EXPANDED = 'renderExpanded'
const OPTION_LENGTH = 'length'

CollectionField::new()

public static function new(string $propertyName, $label = null): self

CollectionField::allowAdd()

public function allowAdd(bool $allow = true): self

CollectionField::allowObject()

public function allowObject(bool $allow = true): self

CollectionField::allowDelete()

public function allowDelete(bool $allow = true): self

CollectionField::setEntryType()

public function setEntryType(string $entryType): self

CollectionField::setEntryOptions()

public function setEntryOptions(array $entryOptions): self

CollectionField::setEntryLabel()

public function setEntryLabel($entryLabel): self

CollectionField::renderExpanded()

public function renderExpanded(bool $renderExpanded = true): self

CollectionField::setLength()

public function setLength(int $length): self

CollectionField::showEmbedded()

public function showEmbedded($embed = true): self

CollectionField::showEmbeddedRow()

public function showEmbeddedRow($embed = true): self

CollectionField::showCollapsed()

public function showCollapsed($collapsed = true): self

ColorField class

final class ColorField implements FieldInterface ColorField.php:9

ColorField::new()

public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): self

ColorPickerField class

final class ColorPickerField implements FieldInterface ColorPickerField.php:8

ColorPickerField::new()

public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): self

CountryField class

class CountryField extends SelectField implements FieldInterface CountryField.php:8

CountryField::new()

public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): self

CropperField class

class CropperField implements FieldInterface CropperField.php:8

const OPTION_SHOWFIRST = 'showFirst'
const OPTION_RENDER_FORMAT = 'renderFormat'

CropperField::new()

public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): self

CurrencyField class

class CurrencyField extends SelectField implements FieldInterface CurrencyField.php:7

CurrencyField::new()

public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): self

DateField class

class DateField implements FieldInterface DateField.php:7

DateField::new()

public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): self

DateTimeField class

class DateTimeField implements FieldInterface DateTimeField.php:7

DateTimeField::new()

public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): self

DateTimePickerField class

final class DateTimePickerField implements FieldInterface DateTimePickerField.php:8

const FORMAT_FULL = 'full'
const FORMAT_LONG = 'long'
const FORMAT_MEDIUM = 'medium'
const FORMAT_SHORT = 'short'
const FORMAT_NONE = 'none'
const VALID_DATE_FORMATS = [self::FORMAT_NONE, self::FORMAT_SHORT, self::FORMAT_MEDIUM, self::FORMAT_LONG, self::FORMAT_FULL]
const INTL_DATE_PATTERNS = [self::FORMAT_FULL => 'EEEE, MMMM d, y', self::FORMAT_LONG => 'MMMM d, y', self::FORMAT_MEDIUM => 'MMM d, y', self::FORMAT_SHORT => 'M/d/yy', self::FORMAT_NO…
const INTL_TIME_PATTERNS = [self::FORMAT_FULL => 'h:mm:ss a zzzz', self::FORMAT_LONG => 'h:mm:ss a z', self::FORMAT_MEDIUM => 'h:mm:ss a', self::FORMAT_SHORT => 'h:mm a', self::FORMAT_…
const WIDGET_NATIVE = 'native'
const WIDGET_CHOICE = 'choice'
const WIDGET_TEXT = 'text'
const OPTION_DATE_PATTERN = 'datePattern'
const OPTION_TIME_PATTERN = 'timePattern'
const OPTION_TIMEZONE = 'timezone'
const OPTION_WIDGET = 'widget'
const OPTION_DEFAULT = 'default_value'

DateTimePickerField::new()

public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): self

DateTimePickerField::setDebug()

public function setDebug(bool $debug = true): self

DateTimePickerField::setTimezone()

public function setTimezone(string $timezoneId): self
$timezoneId

A valid PHP timezone ID

DateTimePickerField::setFormat()

public function setFormat(string $dateFormatOrPattern, string $timeFormat = self::FORMAT_NONE): self
$dateFormatOrPattern

A format name ('none', 'short', 'medium', 'long', 'full') or a valid ICU Datetime Pattern (see http://userguide.icu-project.org/formatparse/datetime)

$timeFormat

A format name ('none', 'short', 'medium', 'long', 'full')

DateTimePickerField::renderAsNativeWidget()

public function renderAsNativeWidget(bool $asNative = true): self

Uses native HTML5 widgets when rendering this field in forms.

DateTimePickerField::renderAsChoice()

public function renderAsChoice(bool $asChoice = true): self

Uses <select> lists when rendering this field in forms.

DateTimePickerField::renderAsText()

public function renderAsText(bool $asText = true): self

Uses <input type="text"> elements when rendering this field in forms.

DateTimePickerField::setDefault()

public function setDefault(?\DateTime $datetime = null)

DateTimePickerField::now()

public function now()

DiscriminatorField class

class DiscriminatorField extends SelectField implements FieldInterface DiscriminatorField.php:8

const OPTION_DISCRIMINATOR_AUTOLOAD = 'discriminatorAutoload'
const OPTION_SHOW_COLUMN = 'discriminatorColumn'
const OPTION_SHOW_INLINE = 'discriminatorInline'
const OPTION_SHOW_LEAF = 'discriminatorLeaf'

DiscriminatorField::new()

public static function new(string $propertyName = "id", TranslatableInterface|string|bool|null $label = null): self

DiscriminatorField::showColumnLabel()

public function showColumnLabel(bool $show = true): self

DiscriminatorField::showInline()

public function showInline(bool $inline = true): self

DiscriminatorField::showLeaf()

public function showLeaf(bool $show = true): self

EditorField class

final class EditorField implements FieldInterface EditorField.php:8

EditorField::new()

public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): self

EmailField class

class EmailField implements FieldInterface EmailField.php:7

const OPTION_ICON_CUSTOM = 'icon'
const OPTION_SHOW = 'show'
const SHOW_ICON = 'icon'
const SHOW_EMAIL = 'email'
const SHOW_ALL = 'all'

EmailField::setTargetFieldName()

public function setTargetFieldName(string $show): self

EmailField::new()

public static function new(string $propertyName, $label = null): self

EmailField::setCustomIcon()

public function setCustomIcon(string $faIcon)

EmailField::renderIcon()

public function renderIcon()

EmailField::renderAll()

public function renderAll()

EmailField::renderText()

public function renderText()

EmojiPickerField class

final class EmojiPickerField implements FieldInterface EmojiPickerField.php:9

EmojiPickerField::new()

public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): self

FieldDescriptor class

final class FieldDescriptor FieldDescriptor.php:22

Single mutable descriptor carried by every field: what property it maps, what kind of field it is (Kind), its options and constraints, where it is displayed, and how.

Neutral: a descriptor names a kind, never a host's widget. The host maps the kind (Kinds: Symfony's form type, a theme's block); getFormType() answers Symfony's type of the kind, or the type named directly with setFormType() (the escape hatch of a Symfony-only field). The options are plain data, the constraints plain objects the host's Validation reads.

This is the EasyCorp-free replacement for both FieldDto and its KeyValueStore bags: one class, plain arrays, no builder/DTO split.

const PAGE_INDEX = 'index'
const PAGE_DETAIL = 'detail'
const PAGE_EDIT = 'edit'
const PAGE_NEW = 'new'
const ALL_PAGES = [self::PAGE_INDEX, self::PAGE_DETAIL, self::PAGE_EDIT, self::PAGE_NEW]
const FORM_PAGES = [self::PAGE_EDIT, self::PAGE_NEW]

FieldDescriptor::__construct()

public function __construct()

FieldDescriptor::getUniqueId()

public function getUniqueId(): string

FieldDescriptor::setUniqueId()

public function setUniqueId(string $uniqueId): static

FieldDescriptor::getFieldFqcn()

public function getFieldFqcn(): ?string

FieldDescriptor::setFieldFqcn()

public function setFieldFqcn(?string $fieldFqcn): static

FieldDescriptor::getProperty()

public function getProperty(): ?string

FieldDescriptor::setProperty()

public function setProperty(?string $propertyName): static

FieldDescriptor::getPropertySuffix()

public function getPropertySuffix(): ?string

FieldDescriptor::setPropertySuffix()

public function setPropertySuffix(?string $propertyNameSuffix): static

FieldDescriptor::getPropertyWithSuffix()

public function getPropertyWithSuffix(): ?string

FieldDescriptor::getValue()

public function getValue(): mixed

FieldDescriptor::setValue()

public function setValue(mixed $value): static

FieldDescriptor::getFormattedValue()

public function getFormattedValue(): mixed

FieldDescriptor::setFormattedValue()

public function setFormattedValue(mixed $formattedValue): static

FieldDescriptor::getFormatValueCallable()

public function getFormatValueCallable(): ?callable

FieldDescriptor::setFormatValueCallable()

public function setFormatValueCallable(?callable $callable): static

FieldDescriptor::getLabel()

public function getLabel(): TranslatableInterface|string|bool|null

FieldDescriptor::setLabel()

public function setLabel(TranslatableInterface|string|bool|null $label): static

FieldDescriptor::getHelp()

public function getHelp(): TranslatableInterface|string|null

FieldDescriptor::setHelp()

public function setHelp(TranslatableInterface|string|null $help): static

FieldDescriptor::getTranslationParameters()

public function getTranslationParameters(): array

FieldDescriptor::setTranslationParameters()

public function setTranslationParameters(array $translationParameters): static

FieldDescriptor::getKind()

public function getKind(): ?string

The field's neutral kind (Kind::TEXT, Kind::CHOICE...): the one set, else the kind of the Symfony type named with setFormType() (Kinds), else Kind::CUSTOM for a type no kind renders; null for neither.

FieldDescriptor::setKind()

public function setKind(?string $kind): static

FieldDescriptor::getFormType()

public function getFormType(): ?string

The Symfony form type rendering this field: the one named with setFormType(), else the type of its kind (Kinds). The generic renderers read getKind() instead.

FieldDescriptor::setFormType()

public function setFormType(?string $formTypeFqcn): static

Names a Symfony form type directly: a field no kind describes, or a kind rendered by another type. A type a kind maps to (Kinds) sets that kind too (TextField's ChoiceType is a choice); another keeps the kind set (what the generic renderers print), Kind::CUSTOM when none was.

FieldDescriptor::hasExplicitFormType()

public function hasExplicitFormType(): bool

Whether the Symfony type was named directly rather than by the kind.

FieldDescriptor::getConstraints()

public function getConstraints(): array

The constraints the field's value is checked against (plain objects the host's Validation reads: omnibridge's neutral constraints, or a host's own, symfony/validator's), beside those the data's class declares.

FieldDescriptor::setConstraints()

public function setConstraints(array $constraints): static

FieldDescriptor::addConstraint()

public function addConstraint(object ...$constraints): static

FieldDescriptor::getOptions()

public function getOptions(): array

The field's options as plain data: what getFormTypeOptions() answers, by its neutral name.

FieldDescriptor::getOption()

public function getOption(string $optionName, mixed $default = null): mixed

One option, "." paths supported ("attr.autofocus").

FieldDescriptor::getFormTypeOptions()

public function getFormTypeOptions(): array

FieldDescriptor::setFormTypeOptions()

public function setFormTypeOptions(array $formTypeOptions): static

FieldDescriptor::getFormTypeOption()

public function getFormTypeOption(string $optionName, mixed $default = null): mixed

Option names support "." paths, e.g. "attr.autofocus".

FieldDescriptor::setFormTypeOption()

public function setFormTypeOption(string $optionName, mixed $optionValue): static

FieldDescriptor::setFormTypeOptionIfNotSet()

public function setFormTypeOptionIfNotSet(string $optionName, mixed $optionValue): static

FieldDescriptor::isSortable()

public function isSortable(): ?bool

FieldDescriptor::setSortable()

public function setSortable(?bool $sortable): static

FieldDescriptor::isVirtual()

public function isVirtual(): ?bool

FieldDescriptor::setVirtual()

public function setVirtual(?bool $virtual): static

FieldDescriptor::isDisabled()

public function isDisabled(): ?bool

FieldDescriptor::setDisabled()

public function setDisabled(?bool $disabled): static

FieldDescriptor::isRequired()

public function isRequired(): ?bool

FieldDescriptor::setRequired()

public function setRequired(?bool $required): static

FieldDescriptor::getEmptyData()

public function getEmptyData(): mixed

FieldDescriptor::setEmptyData()

public function setEmptyData(mixed $emptyData): static

FieldDescriptor::getPermission()

public function getPermission(): string|Expression|null

FieldDescriptor::setPermission()

public function setPermission(string|Expression|null $permission): static

FieldDescriptor::getTextAlign()

public function getTextAlign(): ?string

FieldDescriptor::setTextAlign()

public function setTextAlign(?string $textAlign): static

FieldDescriptor::getCssClass()

public function getCssClass(): string

FieldDescriptor::setCssClass()

public function setCssClass(string $cssClass): static

FieldDescriptor::addCssClass()

public function addCssClass(string $cssClass): static

FieldDescriptor::getHtmlAttributes()

public function getHtmlAttributes(): array

FieldDescriptor::setHtmlAttributes()

public function setHtmlAttributes(array $htmlAttributes): static

FieldDescriptor::setHtmlAttribute()

public function setHtmlAttribute(string $attributeName, mixed $attributeValue): static

FieldDescriptor::getColumns()

public function getColumns(): null|int|string

FieldDescriptor::setColumns()

public function setColumns(null|int|string $columns): static

FieldDescriptor::getDefaultColumns()

public function getDefaultColumns(): null|int|string

FieldDescriptor::setDefaultColumns()

public function setDefaultColumns(null|int|string $defaultColumns): static

FieldDescriptor::getTemplateName()

public function getTemplateName(): ?string

FieldDescriptor::setTemplateName()

public function setTemplateName(?string $templateName): static

FieldDescriptor::getTemplatePath()

public function getTemplatePath(): ?string

FieldDescriptor::setTemplatePath()

public function setTemplatePath(?string $templatePath): static

FieldDescriptor::getFormThemes()

public function getFormThemes(): array

FieldDescriptor::addFormTheme()

public function addFormTheme(string ...$formThemePaths): static

FieldDescriptor::getCssAssets()

public function getCssAssets(): array

FieldDescriptor::addCssAsset()

public function addCssAsset(string $asset): static

FieldDescriptor::getJsAssets()

public function getJsAssets(): array

FieldDescriptor::addJsAsset()

public function addJsAsset(string $asset): static

FieldDescriptor::getWebpackEncoreEntries()

public function getWebpackEncoreEntries(): array

FieldDescriptor::addWebpackEncoreEntry()

public function addWebpackEncoreEntry(string $entry): static

FieldDescriptor::getHeadContents()

public function getHeadContents(): array

FieldDescriptor::addHtmlContentToHead()

public function addHtmlContentToHead(string $content): static

FieldDescriptor::getBodyContents()

public function getBodyContents(): array

FieldDescriptor::addHtmlContentToBody()

public function addHtmlContentToBody(string $content): static

FieldDescriptor::getCustomOptions()

public function getCustomOptions(): array

FieldDescriptor::setCustomOptions()

public function setCustomOptions(array $customOptions): static

FieldDescriptor::getCustomOption()

public function getCustomOption(string $optionName, mixed $default = null): mixed

FieldDescriptor::setCustomOption()

public function setCustomOption(string $optionName, mixed $optionValue): static

FieldDescriptor::getDoctrineMetadata()

public function getDoctrineMetadata(): array

FieldDescriptor::setDoctrineMetadata()

public function setDoctrineMetadata(array $doctrineMetadata): static

FieldDescriptor::getDisplayedOn()

public function getDisplayedOn(): array

FieldDescriptor::setDisplayedOn()

public function setDisplayedOn(array $pages): static

FieldDescriptor::displayOn()

public function displayOn(string ...$pages): static

FieldDescriptor::hideOn()

public function hideOn(string ...$pages): static

FieldDescriptor::isDisplayedOn()

public function isDisplayedOn(string $page): bool

FieldInterface interface

interface FieldInterface FieldInterface.php:7

FieldInterface::new()

public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null)

FieldInterface::getAsDto()

public function getAsDto(): FieldDescriptor

FieldInterface::__clone()

public function __clone(): void

FieldTrait trait

trait FieldTrait FieldTrait.php:15

Fluent configuration surface shared by every field.

Method names intentionally match the ones CRUD controllers already call, so porting a controller does not require rewriting configureFields(). All state lives in a single FieldDescriptor (see getAsDto()).

FieldTrait::__clone()

public function __clone(): void

FieldTrait::setFieldFqcn()

public function setFieldFqcn(string $fieldFqcn): static

FieldTrait::setProperty()

public function setProperty(string $propertyName): static

FieldTrait::setPropertySuffix()

public function setPropertySuffix(string $propertyNameSuffix): static

FieldTrait::setLabel()

public function setLabel(TranslatableInterface|string|bool|null $label): static

FieldTrait::setValue()

public function setValue(mixed $value): static

FieldTrait::setFormattedValue()

public function setFormattedValue(mixed $value): static

FieldTrait::formatValue()

public function formatValue(?callable $callable): static

FieldTrait::setVirtual()

public function setVirtual(bool $isVirtual): static

FieldTrait::setDisabled()

public function setDisabled(bool $disabled = true): static

FieldTrait::setRequired()

public function setRequired(bool $isRequired): static

FieldTrait::setEmptyData()

public function setEmptyData(mixed $emptyData = null): static

FieldTrait::setKind()

public function setKind(string $kind): static

The field's neutral kind (Kind::TEXT, Kind::CHOICE...): what every host renders it by.

FieldTrait::addConstraint()

public function addConstraint(object ...$constraints): static

Constraints the field's value is checked against, beside those of the data's class.

FieldTrait::setOptions()

public function setOptions(array $options): static

Options as plain data, "." paths supported: setFormTypeOptions() by its neutral name.

FieldTrait::setOption()

public function setOption(string $optionName, mixed $optionValue): static

FieldTrait::setFormType()

public function setFormType(string $formTypeFqcn): static

Names a Symfony form type directly (Symfony only, the escape hatch): a field no kind describes. Prefer setKind().

FieldTrait::setFormTypeOptions()

public function setFormTypeOptions(array $options): static

FieldTrait::setFormTypeOption()

public function setFormTypeOption(string $optionName, mixed $optionValue): static

FieldTrait::setFormTypeOptionIfNotSet()

public function setFormTypeOptionIfNotSet(string $optionName, mixed $optionValue): static

FieldTrait::setHtmlAttribute()

public function setHtmlAttribute(string $attributeName, mixed $attributeValue): static

FieldTrait::setHtmlAttributes()

public function setHtmlAttributes(array $attributes): static

FieldTrait::setSortable()

public function setSortable(bool $isSortable): static

FieldTrait::setPermission()

public function setPermission(string|Expression $permission): static

FieldTrait::setTextAlign()

public function setTextAlign(string $textAlign): static
$textAlign

one of "left", "center", "right"

FieldTrait::setHelp()

public function setHelp(TranslatableInterface|string $help): static

FieldTrait::addCssClass()

public function addCssClass(string $cssClass): static

FieldTrait::setCssClass()

public function setCssClass(string $cssClass): static

FieldTrait::setTranslationParameters()

public function setTranslationParameters(array $parameters): static

FieldTrait::setTemplateName()

public function setTemplateName(string $name): static

FieldTrait::setTemplatePath()

public function setTemplatePath(string $path): static

FieldTrait::addFormTheme()

public function addFormTheme(string ...$formThemePaths): static

FieldTrait::addWebpackEncoreEntries()

public function addWebpackEncoreEntries(string ...$entryNames): static

FieldTrait::addCssFiles()

public function addCssFiles(string ...$paths): static

FieldTrait::addJsFiles()

public function addJsFiles(string ...$paths): static

FieldTrait::addHtmlContentsToHead()

public function addHtmlContentsToHead(string ...$contents): static

FieldTrait::addHtmlContentsToBody()

public function addHtmlContentsToBody(string ...$contents): static

FieldTrait::setCustomOption()

public function setCustomOption(string $optionName, mixed $optionValue): static

FieldTrait::setCustomOptions()

public function setCustomOptions(array $options): static

FieldTrait::hideOnDetail()

public function hideOnDetail(): static

FieldTrait::hideOnForm()

public function hideOnForm(): static

FieldTrait::hideWhenCreating()

public function hideWhenCreating(): static

FieldTrait::hideWhenUpdating()

public function hideWhenUpdating(): static

FieldTrait::hideOnIndex()

public function hideOnIndex(): static

FieldTrait::showOnIndex()

public function showOnIndex(bool $show = true): static

FieldTrait::showOnDetail()

public function showOnDetail(bool $show = true): static

FieldTrait::onlyOnDetail()

public function onlyOnDetail(): static

FieldTrait::onlyOnForms()

public function onlyOnForms(): static

FieldTrait::onlyOnIndex()

public function onlyOnIndex(): static

FieldTrait::onlyWhenCreating()

public function onlyWhenCreating(): static

FieldTrait::onlyWhenUpdating()

public function onlyWhenUpdating(): static

FieldTrait::setColumns()

public function setColumns(int|string $cols): static
$cols

an integer 1..12 or a responsive spec like "col-md-6 col-xxl-3"

FieldTrait::setDefaultColumns()

public function setDefaultColumns(int|string $cols): static

FieldTrait::getAsDto()

public function getAsDto(): FieldDescriptor

FieldValueResolver class

class FieldValueResolver FieldValueResolver.php:16

Resolves a field's raw and formatted value for one entity instance: property access, then the field's formatValue() callable if any.

Returns a clone so one descriptor list can serve every row of an index.

const DISPLAY_USERNAME = 'username'

How a related entity should be labelled in a list/detail cell.

formatValue() above always yields __toString(), which for a User is the username - fine as a default, useless when the usernames are short handles ("NN") and the reader wants a person's actual name or just their face. Fields opt into one of these via setEntityDisplay(); see SelectField/AssociationField.

const DISPLAY_FULLNAME = 'fullname'
const DISPLAY_AVATAR = 'avatar'
const DEFAULT_IDENTIFIER_FIELDS = ['slug', 'uuid']

Fields that may stand in for the primary key in an admin URL when nothing is configured, most readable first.

Deliberately does NOT include "username": a username is an APPLICATION-level idea (an app may or may not have one, and may or may not want it in URLs), whereas the base app's User is identified by its id. An app that wants it opts in per entity:

admin:
    url_identifier:
        entities:
            App\Entity\User: ['username']

Set fields: [] to switch the whole admin back to plain numeric ids - the escape hatch for slugs long enough to make URLs unwieldy.

FieldValueResolver::__construct()

public function __construct(?PropertyAccessorInterface $accessor = null, ?array $identifierFields = null, array $identifierFieldsByEntity = [], bool $lowercaseIdentifiers = false, protected ?ManagerRegistry $doctrine = null)
$identifierFields

null = DEFAULT_IDENTIFIER_FIELDS

$identifierFieldsByEntity

per-class overrides

$lowercaseIdentifiers

see $this->lowercaseIdentifiers

$doctrine

says which identifier fields are columns, see isStoredField()

FieldValueResolver::resolve()

public function resolve(FieldDescriptor $descriptor, object $entity): FieldDescriptor

FieldValueResolver::formatValue()

public function formatValue(mixed $value): mixed

Default display formatting, done here rather than in Twig: templates cannot reliably type-check values behind entity magic methods (BaseTrait's __get makes any attribute look "defined"). Public so templates that must format individual items of a raw collection themselves (a SelectField's index badge, iterating real entity objects one by one) can reuse the exact same logic via the admin_display() twig function instead of duplicating it.

FieldValueResolver::entityLabel()

public function entityLabel(mixed $entity, string $mode = self::DISPLAY_USERNAME): mixed

The text to show for a related entity under the requested mode.

Every mode degrades rather than blanking the cell: an entity with no getFullname() (or one returning an empty string, which User does when both name parts are unset) falls back to the __toString() label, so switching a field to 'fullname' can never turn a populated column into empty cells. AVATAR returns the same text too - the templates use it for the alt/title and as the visible fallback when the entity has no avatar image.

FieldValueResolver::identifierFieldsFor()

public function identifierFieldsFor(object|string $entity): array

The identifier fields that apply to one entity class, honouring any per-class override. Shared with AbstractCrudController::findEntity(), which resolves a URL segment back to an entity by walking this same list - asking ONE method is what guarantees that every identifier the admin generates is one the admin can also resolve, under whatever configuration is in force.

An override configured on a PARENT class covers its subclasses (and therefore Doctrine's runtime proxies, which extend the entity), so configuring App\Entity\User does not have to be repeated for every discriminator subtype.

FieldValueResolver::resolvableIdentifierFieldsFor()

public function resolvableIdentifierFieldsFor(object|string $entity): array

Every field a URL segment may be RESOLVED from - deliberately wider than identifierFieldsFor(), which says only what we GENERATE.

Config decides what the admin emits; it must not decide what the admin still understands. Otherwise switching fields: [] to shorten URLs would 404 every slug link already sitting in someone's bookmarks, history or an email - a silent breakage of old links, which is exactly what the id fallback was designed to avoid.

The configured fields come FIRST so they win a tie; the rest are accepted afterwards. Candidates the entity does not actually map are skipped by the caller, so a wide list costs no extra queries.

FieldValueResolver::entityIdentifier()

public function entityIdentifier(object $entity): string|int|null

The identifier to put in an admin URL for this entity: the first populated configured field, else the numeric id.

A readable URL is the point ("/admin/articles/petit-cours-..." rather than "/admin/articles/1147", "/admin/users/alice" rather than "/admin/users/14"), and a slug is also stable across environments in a way a database id is not. The id is the last resort and remains valid everywhere, since resolution accepts all of these.

Two kinds of candidate are rejected rather than trusted:

  • Empty/whitespace-only, which would generate "/admin/articles/" and silently point at the collection instead of the record.
  • All-digits, which is genuinely AMBIGUOUS: resolution reads a numeric segment as a primary key first, so a user literally named "12345" (the username validator allows digits-only) would link to whichever account holds id 12345 - someone else's. Falling through to the real id keeps the URL unambiguous by construction.

And a field the entity does not STORE is not a candidate at all: a getSlug() computed from the title (no column behind it) reads well but cannot be looked up again - the address it gave answered 404. Such an entity is linked by its id (isStoredField()).

FieldValueResolver::entityAvatar()

public function entityAvatar(mixed $entity): ?string

The avatar URL for a related entity, or null when it has none (the templates then fall back to the label). getFormattedAvatar() is the app-side accessor that already resolves the stored file to a usable URL; getAvatar() is the raw column and only worth using when the formatted one isn't there.

FieldValueResolver::entityImage()

public function entityImage(mixed $entity): ?string

The raw STORAGE PATH of an entity's image, or null.

Deliberately the source and not a URL: callers hand it to the media pipeline (|thumbnail(w, h)), which is what resizes, caches and obfuscates. Handing them a built URL would make the pipeline fetch a full-size original just to draw a 96px chip - the exact cost this exists to avoid.

Only an ImageInterface counts. An entity whose getAvatar() already returns a rendered URL is a different contract (entityAvatar()), and treating its return value as a path would silently produce broken thumbnails.

FieldValueResolver::resolveAll()

public function resolveAll(iterable $fields, object $entity, ?string $page = null): array

FileField class

class FileField implements FieldInterface FileField.php:8

const OPTION_RENDER_FORMAT = 'renderFormat'
const OPTION_SHOWFIRST = 'showFirst'
const OPTION_ALLOW_URL = 'allow_url'
const OPTION_ALLOW_REUPLOAD = 'allow_reupload'
const OPTION_PREFERRED_DOWNLOAD_NAME = 'preferredDownloadName'

FileField::new()

public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): self

FileField::setMaxSize()

public function setMaxSize(int $filesize)

FileField::setMaxFiles()

public function setMaxFiles(int $nFiles)

FileField::setMimeTypes()

public function setMimeTypes(array $mimeTypes)

FileField::allowDelete()

public function allowDelete(bool $allowDelete = true): self

FileField::downloadable()

public function downloadable(bool $allowDownload = true): self

FileField::noReupload()

public function noReupload(bool $noReupload = true): self

FileField::setPreferredDownloadName()

public function setPreferredDownloadName(string $targetName): self

FileField::setMultipleFiles()

public function setMultipleFiles(bool $multipleFiles = true): self

FileField::renderAsText()

public function renderAsText(): self

FileField::renderAsCount()

public function renderAsCount(): self

FileField::renderAsImage()

public function renderAsImage(): self

FileField::showFirst()

public function showFirst(bool $show = true): self

ForexField class

class ForexField extends SelectField implements FieldInterface ForexField.php:8

const OPTION_TARGET_FIELD_NAME = 'targetFieldName'

ForexField::new()

public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): self

GenderField class

class GenderField extends SelectField implements FieldInterface GenderField.php:8

GenderField::new()

public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): self

IconField class

class IconField extends SelectField implements FieldInterface IconField.php:9

const OPTION_TARGET_FIELD_NAME = 'targetFieldName'

IconField::new()

public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): self

IconField::setTargetColor()

public function setTargetColor(string $fieldName)

IconField::setAdapter()

public function setAdapter(IconAdapterInterface|string $objectOrClass)

IdField class

final class IdField implements FieldInterface IdField.php:7

const OPTION_MAX_LENGTH = 'maxLength'
const OPTION_IMPERSONATE = 'impersonate'

IdField::new()

public static function new(string $propertyName = 'id', TranslatableInterface|string|bool|null $label = null): self

IdField::setMaxLength()

public function setMaxLength(int $length): self

Set maxLength to -1 to define an unlimited max length.

IdField::enableImpersonation()

public function enableImpersonation()

IdField::disableImpersonation()

public function disableImpersonation()
public function enableLink()
public function disableLink()

ImageField class

class ImageField extends FileField implements FieldInterface ImageField.php:9

const OPTION_RENDER_FORMAT = "renderFormat"

ImageField::new()

public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): self

ImageField::setCropper()

public function setCropper(null|array|bool $cropper = true)

IntegerField class

class IntegerField implements FieldInterface IntegerField.php:7

IntegerField::new()

public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): self

Kind class

final class Kind Kind.php:15

What a field is, whatever renders it: the neutral kind a FieldDescriptor names in place of a form type class. A host maps a kind to its own widget (Kinds: the Symfony form type, a Twig or Blade theme's block, a React component); the generic binder (Base\Form\Definition\FormBinder) reads the kind to turn a submitted string into the value the data keeps.

A kind is a plain string: a bundle or an application adds its own ("map_point", "signature") and registers what renders it with Kinds.

const TEXT = 'text'
const TEXTAREA = 'textarea'
const EMAIL = 'email'
const PASSWORD = 'password'
const URL = 'url'
const TEL = 'tel'
const SLUG = 'slug'
const CODE = 'code'
const EDITOR = 'editor'
const WYSIWYG = 'wysiwyg'
const HIDDEN = 'hidden'
const INTEGER = 'integer'
const NUMBER = 'number'
const MONEY = 'money'
const FOREX = 'forex'
const STOCK = 'stock'
const YEAR = 'year'
const BOOLEAN = 'boolean'
const CHECKBOX = 'checkbox'
const CHOICE = 'choice'
const COUNTRY = 'country'
const CURRENCY = 'currency'
const LOCALE = 'locale'
const GENDER = 'gender'
const ROLE = 'role'
const STATE = 'state'
const ROUTE = 'route'
const ICON = 'icon'
const EMOJI = 'emoji'
const COLOR = 'color'
const COLOR_PICKER = 'color_picker'
const QUADRANT = 'quadrant'
const DATE = 'date'
const DATETIME = 'datetime'
const DATETIME_PICKER = 'datetime_picker'
const TIME = 'time'
const FILE = 'file'
const IMAGE = 'image'
const CROPPER = 'cropper'
const AVATAR = 'avatar'
const AUDIO = 'audio'
const VIDEO = 'video'
const ASSOCIATION = 'association'
const ASSOCIATION_FILE = 'association_file'
const ATTRIBUTE = 'attribute'
const ARRAY = 'array'
const COLLECTION = 'collection'
const REPEATED = 'repeated'

One value typed twice: its option type is the kind of the two inputs, first_options and second_options theirs.

const TRANSLATION = 'translation'
const DISCRIMINATOR = 'discriminator'
const SUBMIT = 'submit'
const BUTTON = 'button'
const HTML = 'html'

Markup given whole (a captcha's widget), printed as it is.

const CUSTOM = 'custom'

A field whose host type was named directly (setFormType()): the escape hatch.

const INPUT_TYPES = [self::TEXT => 'text', self::EMAIL => 'email', self::PASSWORD => 'password', self::URL => 'url', self::TEL => 'tel', self::SEARCH => 'search', self::SLUG => …

The kinds a renderer prints as a text input, with their HTML type.

const CHOICE_KINDS = [self::CHOICE, self::COUNTRY, self::CURRENCY, self::LOCALE, self::GENDER, self::ROLE, self::STATE, self::ROUTE, self::QUADRANT, self::ASSOCIATION]

The kinds whose value is a choice among a list.

const FILE_KINDS = [self::FILE, self::IMAGE, self::CROPPER, self::AVATAR, self::AUDIO, self::VIDEO, self::ASSOCIATION_FILE]

The kinds whose value is a file sent with the form.

const UNMAPPED_KINDS = [self::SUBMIT, self::BUTTON, self::HTML]

The kinds that are not a value of the data: buttons and markup.

Kind::all()

public static function all(): array

Every kind the core names, in the order of the constants above (a host's coverage declares each: Kinds::coverage()).

Kind::inputType()

public static function inputType(?string $kind): ?string

The HTML input type of a kind printed as an input, null for any other widget.

Kind::isChoice()

public static function isChoice(?string $kind): bool

Kind::isFile()

public static function isFile(?string $kind): bool

Kinds class

final class Kinds Kinds.php:26

What renders each kind on a host: kind => the host's own name for it (a Symfony form type class, a theme's block). The core names no host type: a host registers its map, or the core finds a known adapter's map by its name (ADAPTERS, read only when that class exists).

And what each host draws (plan "omnibase agnostic", step F5d): its coverage, every kind declared implemented or unsupported with the reason (omnisense/omnibridge's Form\Coverage), the adapter's COVERAGE constant completed by declare(). faults() names a kind a host leaves undeclared, the shared conformance suite (Base\Field\Conformance) runs every implemented one: a kind added to the core without a host's word is red there, never a plain input in silence.

Several kinds may share one host type (id and discriminator are Symfony's HiddenType); type() answers a kind, kind() the first kind of a type, then the map's ALIASES (Symfony types no descriptor names: ChoiceType is a choice, CheckboxType a checkbox).

const ADAPTERS = ['symfony' => 'Omnibridge\Symfony\Omnibase\Form\SymfonyKinds', 'laravel' => 'Omnibridge\Laravel\Form\LaravelKinds']

The adapters' maps the core knows by name: a class with the constants MAP (kind => type), optionally ALIASES (type => kind), and COVERAGE (kind => Coverage::IMPLEMENTED or Coverage::unsupported('why')).

Kinds::register()

public static function register(string $host, array $map, array $aliases = []): void

Registers (or completes) a host's map: an application's or a bundle's own kinds, or a whole host's map in place of the known one.

$map

kind => type

$aliases

type => kind

Kinds::type()

public static function type(?string $kind, string $host = 'symfony'): ?string

The host's type of a kind; null for an unknown kind, or with no map for that host.

Kinds::kind()

public static function kind(?string $type, string $host = 'symfony'): ?string

The kind a host's type renders; null when the map does not know that type.

Kinds::map()

public static function map(string $host = 'symfony'): array
Returns

kind => type

Kinds::declare()

public static function declare(string $host, array $coverage): void

Declares what a host draws of some kinds (an application's or a bundle's own, or the host's word in place of its adapter's): kind => Coverage::IMPLEMENTED or Coverage::unsupported('why').

Kinds::coverage()

public static function coverage(string $host): array

What a host draws: kind => its declaration; [] for a host the core knows no adapter of and nothing declared.

Kinds::declaration()

public static function declaration(string $kind, string $host): ?string

A kind's declaration on a host; null when it declares none.

Kinds::known()

public static function known(): array

Every kind there is: the core's (Kind::all()) and those an application registered or declared on any host.

Kinds::faults()

public static function faults(string $host): array

What is wrong with a host's coverage: a kind left undeclared, a declaration without its reason (Coverage::verify()).

Kinds::reset()

public static function reset(): void

Forgets what was registered and declared (tests).

LocaleField class

class LocaleField implements FieldInterface LocaleField.php:10

const OPTION_SHOW_CODE = 'showCode'
const OPTION_SHOW_NAME = 'showName'
const OPTION_LOCALE_CODES_TO_KEEP = 'localeCodesToKeep'
const OPTION_LOCALE_CODES_TO_REMOVE = 'localeCodesToRemove'

LocaleField::new()

public static function new(string $propertyName, $label = null)

LocaleField::showCode()

public function showCode(bool $isShown = true)

LocaleField::showName()

public function showName(bool $isShown = true)

LocaleField::includeOnly()

public function includeOnly(array $countryCodesToKeep)

Restricts the list of locales shown by the field to the given list of locale codes.

e.g. ->includeOnly(['de', 'en', 'fr']).

LocaleField::remove()

public function remove(array $countryCodesToRemove)

Removes the given list of locale codes from the locales displayed by the field.

e.g. ->remove(['de', 'fr']).

MoneyField class

final class MoneyField implements FieldInterface MoneyField.php:8

const OPTION_CURRENCY = 'currency'
const OPTION_SWAP = 'use_swap'
const OPTION_CURRENCY_PROPERTY_PATH = 'currencyPropertyPath'
const OPTION_NUM_DECIMALS = 'numDecimals'
const OPTION_STORED_AS_CENTS = 'storedAsCents'

MoneyField::new()

public static function new(string $propertyName, $label = null): self

MoneyField::useSwap()

public function useSwap(bool $swap = true): self

MoneyField::setCurrency()

public function setCurrency(string $currencyCode): self

MoneyField::setCurrencyPropertyPath()

public function setCurrencyPropertyPath(string $propertyPath): self

MoneyField::showCurrencyCode()

public function showCurrencyCode(bool $show = true): self

MoneyField::setCurrencyList()

public function setCurrencyList(array $moneyList = []): self

MoneyField::setNumDecimals()

public function setNumDecimals(int $num): self

MoneyField::setStoredAsCents()

public function setStoredAsCents(bool $asCents = true): self

NumberField class

final class NumberField implements FieldInterface NumberField.php:6

const OPTION_MINIMUM = 'min'
const OPTION_MAXIMUM = 'max'
const OPTION_SUFFIX = 'suffix'
const OPTION_PREFIX = 'prefix'
const OPTION_DIVISOR = 'divisor'
const OPTION_NUM_DECIMALS = 'numDecimals'
const OPTION_ROUNDING_MODE = 'roundingMode'
const OPTION_STORED_AS_STRING = 'storedAsString'
const OPTION_THROTTLE = 'throttle'

NumberField::new()

public static function new(string $propertyName, $label = null): self

NumberField::percentage()

public function percentage(int $min, int $max): self

NumberField::setDivisor()

public function setDivisor(float $num): self

NumberField::setThrottle()

public function setThrottle(int $num): self

NumberField::setNumDecimals()

public function setNumDecimals(int $num): self

NumberField::setMinimum()

public function setMinimum(int $num): self

NumberField::setMaximum()

public function setMaximum(int $num): self

NumberField::setSuffix()

public function setSuffix(string $suffix): self

NumberField::setPrefix()

public function setPrefix(int $prefix): self

NumberField::step()

public function step(float $step)

NumberField::stepUp()

public function stepUp(float $stepUp)

NumberField::stepDown()

public function stepDown(float $stepDown)

NumberField::throttle()

public function throttle(float $throttle)

NumberField::throttleUp()

public function throttleUp(float $throttleUp)

NumberField::throttleDown()

public function throttleDown(float $throttleDown)

NumberField::setRoundingMode()

public function setRoundingMode(int $mode): self

NumberField::setStoredAsString()

public function setStoredAsString(bool $asString = true): self

PasswordField class

final class PasswordField implements FieldInterface PasswordField.php:7

PasswordField::new()

public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): self

PasswordField::setRevealer()

public function setRevealer(bool $revealer): self

PasswordField::secure()

public function secure(bool $secure = true): self

PasswordField::setRepeater()

public function setRepeater(bool $repeater): self

PasswordField::showInline()

public function showInline(bool $inline = true): self

QuadrantField class

final class QuadrantField implements FieldInterface QuadrantField.php:8

const OPTION_RENDER_FORMAT = 'renderFormat'
const OPTION_ICON_ALIGN = 'iconAlign'
const OPTION_SHOW_FIRST = 'showFirst'
const OPTION_SHOW = 'show'
const NO_SHOW = 0
const SHOW_NAME_ONLY = 1
const SHOW_ICON_ONLY = 2
const SHOW_ALL = 3

QuadrantField::new()

public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): self

QuadrantField::setTextAlign()

public function setTextAlign(string $textAlign)

QuadrantField::setIconAlign()

public function setIconAlign(string $iconAlign)

QuadrantField::show()

public function show(int $show = self::SHOW_ALL)

QuadrantField::showIconOnly()

public function showIconOnly()

QuadrantField::showNameOnly()

public function showNameOnly()

RoleField class

class RoleField extends SelectField RoleField.php:8

RoleField::new()

public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): self

RouteField class

class RouteField extends SelectField implements FieldInterface RouteField.php:8

RouteField::new()

public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): self

SelectField class

class SelectField implements FieldInterface SelectField.php:8

const OPTION_CONFIRMATION_MODAL_ON_CHECK = 'confirmationModalOnCheck'
const OPTION_CONFIRMATION_MODAL_ON_UNCHECK = 'confirmationModalOnUncheck'
const OPTION_AUTOCOMPLETE = 'autocomplete'
const OPTION_DEFAULT_CHOICE = 'default_choice'
const OPTION_CLASS = 'class'
const OPTION_CHOICES = 'choices'
const OPTION_ENUM_CLASS = 'enumClass'
const OPTION_ICONS = 'icons'
const OPTION_FILTER = 'choice_filter'
const OPTION_DISPLAY_LIMIT = 'displayLimit'
const OPTION_ENTITY_DISPLAY = 'entityDisplay'

How a related entity is labelled in the cell - one of FieldValueResolver::DISPLAY_* (username | fullname | avatar). Shares the option NAME with AssociationField on purpose: the two render through different templates but the choice means the same thing, and a single name keeps the templates and any future field consistent.

const OPTION_CRUD_CONTROLLER = 'crudControllerFqcn'

Makes each rendered entity a link to its own CRUD detail page. Same option name as AssociationField::OPTION_CRUD_CONTROLLER for the same reason - a SelectField over a real association (Comment::owners) had no way to be clickable at all before this.

const OPTION_ICON_ALIGN = 'iconAlign'
const OPTION_RENDER_FORMAT = 'renderFormat'
const OPTION_SHOW_FIRST = 'showFirst'
const OPTION_USE_COLOR = 'useColor'
const OPTION_SHOW = 'show'
const NO_SHOW = 0
const SHOW_NAME_ONLY = 1
const SHOW_ICON_ONLY = 2
const SHOW_ALL = 3

SelectField::new()

public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): self

SelectField::useColor()

public function useColor(bool $useColor = true)

SelectField::useHtml()

public function useHtml(bool $useHtml = true)

SelectField::useAvatar()

public function useAvatar(bool $avatar = true)

Show entries as profile pictures rather than as their __iconize() icon, wherever one is available.

Off by default (see SelectType's avatar option): that icon carries meaning - for a User it is their role - and a photo silently replaces it only for the people who happen to have uploaded one. Worth turning on where telling individuals apart is the point, such as an article's authors.

SelectField::autocomplete()

public function autocomplete(string $endpoint)

SelectField::setTextAlign()

public function setTextAlign(string $textAlign)

SelectField::setIconAlign()

public function setIconAlign(string $iconAlign)
public function allowCrudLink(bool $allow = true)

SelectField::allowMultipleChoices()

public function allowMultipleChoices(bool $allow = true)

SelectField::allowDelete()

public function allowDelete(bool $allow = true)

SelectField::allowSearch()

public function allowSearch(bool $allow = true)

SelectField::turnHorizontal()

public function turnHorizontal(bool $horizontal)

SelectField::showVertical()

public function showVertical(bool $vertical = true)

SelectField::allowTags()

public function allowTags(bool|array $tokenSeparators = [])

SelectField::setChoices()

public function setChoices($choiceGenerator)

SelectField::setEntityDisplay()

public function setEntityDisplay(string $mode = FieldValueResolver::DISPLAY_USERNAME)
$mode

one of FieldValueResolver::DISPLAY_*

SelectField::setCrudController()

public function setCrudController(string $crudControllerFqcn)

SelectField::setEnumClass()

public function setEnumClass(string $class)

SelectField::setAutoFilter()

public function setAutoFilter()

SelectField::setFilter()

public function setFilter(...$filter)

SelectField::setDisplayLimit()

public function setDisplayLimit(int $limit = 2)

SelectField::setIcons()

public function setIcons(array $icons)

SelectField::setClass()

public function setClass(?string $class = null)

SelectField::showFirst()

public function showFirst(int $show = self::SHOW_ALL)

SelectField::show()

public function show(int $show = self::SHOW_ALL)

SelectField::showIconOnly()

public function showIconOnly()

SelectField::showNameOnly()

public function showNameOnly()

SelectField::renderAsCount()

public function renderAsCount()

SelectField::renderAsText()

public function renderAsText()

SelectField::setDefault()

public function setDefault($defaultChoices)

SelectField::withConfirmation()

public function withConfirmation(bool $onCheck = true, bool $onUncheck = true): self

SlugField class

final class SlugField implements FieldInterface SlugField.php:7

const OPTION_LEADING_HASH = 'leadingHash'
const OPTION_TARGET_FIELD_NAME = 'targetFieldName'
const OPTION_UNLOCK_CONFIRMATION_MESSAGE = 'unlockConfirmationMessage'

SlugField::new()

public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): self

SlugField::setTargetFieldName()

public function setTargetFieldName(string $fieldName): self

SlugField::setSeparator()

public function setSeparator(string $separator): self

SlugField::keep()

public function keep(string $keep): self

SlugField::uppercase()

public function uppercase(bool $upper = true): self

SlugField::setUnlockConfirmationMessage()

public function setUnlockConfirmationMessage(string $message): self

SlugField::showLeadingHash()

public function showLeadingHash(bool $show = true): self

StateField class

class StateField extends SelectField StateField.php:9

const OPTION_CLASS = 'class'

StateField::new()

public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): self

StockField class

final class StockField implements FieldInterface StockField.php:6

const OPTION_NUM_DECIMALS = 'numDecimals'
const OPTION_ROUNDING_MODE = 'roundingMode'
const OPTION_STORED_AS_STRING = 'storedAsString'
const OPTION_ALLOW_INFINITY = 'allowInfinity'
const OPTION_TARGET_FIELD_NAME = 'targetFieldName'

StockField::new()

public static function new(string $propertyName, $label = null): self

StockField::setTargetFieldName()

public function setTargetFieldName(string $fieldName): self

StockField::step()

public function step(float $step)

StockField::stepUp()

public function stepUp(float $stepUp)

StockField::stepDown()

public function stepDown(float $stepDown)

StockField::setNumDecimals()

public function setNumDecimals(int $num): self

StockField::setAllowInfinity()

public function setAllowInfinity(bool $nullable = true)

StockField::setRoundingMode()

public function setRoundingMode(int $mode): self

StockField::setStoredAsString()

public function setStoredAsString(bool $asString = true): self

TextField class

class TextField implements FieldInterface TextField.php:8

const OPTION_MAX_LENGTH = 'maxLength'
const OPTION_RENDER_AS_HTML = 'renderAsHtml'
const OPTION_RENDER_AS_BOOLEAN = 'renderAsBoolean'
const OPTION_STRIP_TAGS = 'stripTags'

TextField::new()

public static function new(string $propertyName, $label = null)

TextField::setMaxLength()

public function setMaxLength(int $length)

This option is ignored when using 'renderAsHtml()' to avoid truncating contents in the middle of an HTML tag.

TextField::renderAsHtml()

public function renderAsHtml(bool $asHtml = true)

TextField::renderAsBoolean()

public function renderAsBoolean(bool $asBool = true)

TextField::stripTags()

public function stripTags(bool $stripTags = true)

TextareaField class

class TextareaField implements FieldInterface TextareaField.php:7

const OPTION_MAX_LENGTH = 'maxLength'
const OPTION_NUM_OF_ROWS = 'numOfRows'

TextareaField::new()

public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): self

TextareaField::setMaxLength()

public function setMaxLength(int $length): self

TextareaField::setNumOfRows()

public function setNumOfRows(int $rows): self

TranslationField class

class TranslationField implements FieldInterface TranslationField.php:9

const OPTION_MAX_LENGTH = 'maxLength'
const OPTION_RENDER_AS_HTML = 'renderAsHtml'
const OPTION_STRIP_TAGS = 'stripTags'

TranslationField::new()

public static function new(?string $propertyName = null, TranslatableInterface|string|bool|null $label = null): self

TranslationField::setMaxLength()

public function setMaxLength(int $length): self

TranslationField::autoload()

public function autoload($autoload = true): self

TranslationField::renderAsHtml()

public function renderAsHtml(bool $asHtml = true): self

TranslationField::stripTags()

public function stripTags(bool $stripTags = true): self

TranslationField::setFields()

public function setFields(array $fields): self

TranslationField::showOnIndex()

public function showOnIndex(?string $field = null): self

TranslationField::setRequired()

public function setRequired(bool $isRequired = true)

TranslationField::setExcludedFields()

public function setExcludedFields($excludedFields): self

TranslationField::setTranslationClass()

public function setTranslationClass($translationClass): self

TranslationField::setDefaultLocale()

public function setDefaultLocale(string $defaultLocale): self

TranslationField::renderSingleLocale()

public function renderSingleLocale(?string $singleLocale = null): self

VideoField class

class VideoField extends FileField implements FieldInterface VideoField.php:8

const OPTION_RENDER_FORMAT = 'renderFormat'

VideoField::new()

public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): self

WysiwygField class

final class WysiwygField implements FieldInterface WysiwygField.php:7

const OPTION_SHORTEN_LENGTH = 'shortenStrLength'
const OPTION_SHORTEN_POSITION = 'shortenStrPosition'
const OPTION_SHORTEN_SEPARATOR = 'shortenStrSeparator'
const OPTION_STRIP_TAGS = 'stripTags'
const OPTION_RENDER_AS_BOOLEAN = 'renderAsBoolean'

WysiwygField::new()

public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): self

WysiwygField::renderAsBoolean()

public function renderAsBoolean(bool $asBool = true)

WysiwygField::shorten()

public function shorten(int $length = 100, int $position = SHORTEN_BACK, string $separator = ' [..] '): self

WysiwygField::stripTags()

public function stripTags(bool $stripTags = true)

YearField class

final class YearField implements FieldInterface YearField.php:10

YearField::new()

public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): self

Base\Field\Behaviour

AbstractBehaviour class

abstract class AbstractBehaviour implements FieldBehaviour AbstractBehaviour.php:14

A behaviour's plain parts: its defaults under the given options, no vars, the value as it is both ways, no front end, no route. The generic binder (Base\Form\Definition\FormBinder) completes a value a behaviour leaves as a string by its kind's rule (a date, a number).

AbstractBehaviour::options()

public function options(array $given): array

AbstractBehaviour::vars()

public function vars(array $options, mixed $shown, string $id): array

AbstractBehaviour::transform()

public function transform(mixed $data, array $options): mixed

AbstractBehaviour::reverse()

public function reverse(mixed $submitted, array $options): mixed

AbstractBehaviour::assets()

public function assets(array $options): FieldAssets

AbstractBehaviour::endpoints()

public function endpoints(array $options): array

Association class

final class Association Association.php:33

A related record's form embedded in its owner's (Kind::ASSOCIATION; plan "omnibase agnostic", step F5d, slice 7), as omnibase's AssociationType builds it, on every host: one record, its fields; or several (a to-many association), a collection (Collection) whose every entry is one record's form - an article's comments, a comment's replies. What AssociationType decides itself is here, and it asks it:

  • options(): its defaults and what its normalizers make of them - several records are never required (no entry is a legitimate value: a Count constraint says why it refuses), an entry is required by entry_required; entries are added and deleted only inside a group;
  • collection(): the options of the collection holding several records' forms (_collection);
  • entry(): the options of one record's form among them.

And for the hosts without Symfony's forms (the neutral FormView and FormBinder): isMultiple() (the association's own word where the field gives none), targetClass(), fields() (a record's fields as FieldDescriptors, from its shape: RecordFields), records() (the related records, by index), and bind() (what is sent written into them: each entry's fields bound by the neutral binder, an entry added from the prototype a new record told its owner, one taken out removed where the field deletes).

const DEFAULTS = ['class' => null, 'form_type' => null, 'embed' => null, 'autoload' => true, 'href' => null, 'html' => false, 'entry_collapsed' => true, 'max_entries' => null…
const COLLECTION = '_collection'

The name of the collection holding several records' forms, and of an entry's index.

const INDEX = '_index'

Association::options()

public static function options(array $options): array

Association::collection()

public static function collection(array $options): array

What the collection of several records' forms is given (AssociationType's _collection): its entries this type, each one record's form (entry()).

$options

the association's, its class and multiplicity known

Association::entry()

public static function entry(array $options): array

Association::targetClass()

public static function targetClass(array $options, ?string $ownerClass, string $property): ?string

The related records' class: the field's, else its association's target.

Association::property()

public static function property(?string $ownerClass, string $property): string

The association a field's property names: itself, or the one its alias designates (#[Alias]: a comment's replies).

Association::isMultiple()

public static function isMultiple(array $options, ?string $ownerClass, string $property): bool

Several records: the field's word, else its association's (FormFactory::guessMultiple()).

Association::fields()

public static function fields(string $class, array $options, ?string $formName = null): array

One record's fields, as AssociationType adds them: those named and, where it autoloads, the record's others; a related record's own form, or a field kept out of records, left out.

Association::records()

public static function records(mixed $value): array
Returns

the related records, by their index in the association

Association::bind()

public static function bind(object $owner, string $property, array $submitted, array $options, array $fields, FormBinder $binder): array

What is sent for several records written into them: each entry sent (by its index) bound into the record at that index, or into a new one (an entry added from the prototype, told its owner where the association is its inverse side); a record whose entry was not sent removed where the field deletes, kept otherwise (and always where a windowed page did not draw it). An entry's own collection of records (a comment's replies, listed by a CollectionType) is not written from it, as AssociationType leaves it.

$submitted

the _collection part

$options

the association's, its class known

$fields

one record's fields

Returns

the entries' violations, under _collection.<index>.<field>

AssociationFile class

final class AssociationFile AssociationFile.php:34

Records made from uploads (Kind::ASSOCIATION_FILE, plan "omnibase agnostic", step F5d): a gallery's photos, a photo's image - what omnibase's AssociationFileType decided, on every host. The field is a compound holding one upload field (Upload: file, image or avatar) named by the first part of entity_file, the path from the related record to its file ("image.source": a photo's image's source). What the type decided itself is here, and it asks it:

  • options(): its defaults and normalizers (the class required, entity_file required, form_type an upload's: FileType, ImageType, AvatarType or a variant's name), variant();
  • child() and path(): the upload field's name and the file's path in a related record;
  • files(): the related records' public files, what the upload field shows;
  • entries(): each stored file's name by its record's id (the block's data-entry-id);
  • childOptions(): the upload field's options, as the type adds it;
  • records(): what was sent made into the related records - a file sent a new record (hydrated, then given entity_data, a callable or values, else its file), a stored file's name its record kept.

And for the hosts without Symfony's forms (the neutral FormView and FormBinder): bind(), the related records written into the record (a to-many association replaced, its inverse side told its owner, as the type writes a PersistentCollection), read from the entity's shape.

const DEFAULTS = ['class' => null, 'form_type' => Upload::FILE, 'entity_file' => null, 'entity_data' => [], 'multiple' => null, 'allow_delete' => false, 'allow_delete[confirm…

AssociationFileType's defaults.

const VARIANTS = [Upload::FILE => Kind::FILE, Upload::IMAGE => Kind::IMAGE, Upload::AVATAR => Kind::AVATAR]

The upload kinds a related record's file is drawn with.

AssociationFile::options()

public static function options(array $given): array

The options with the type's defaults, normalized as it normalizes them: no data class for several records, a class and the file's path required, an upload's form type.

AssociationFile::variant()

public static function variant(array $options): string

The upload's variant its form_type names (Upload::FILE, IMAGE, AVATAR): a variant's name, or the type's class - FileType, ImageType, AvatarType, under any namespace -; anything else is refused, as the type refuses a form type that is no FileType.

AssociationFile::kind()

public static function kind(array $options): string

The upload kind its file is drawn with (Kind::FILE, IMAGE, AVATAR).

@param array<string, mixed> $options

AssociationFile::child()

public static function child(array $options): string

The upload field's name: the first part of entity_file ("image" of "image.source").

@param array<string, mixed> $options

AssociationFile::path()

public static function path(array $options): string

The file's path in a related record (entity_file).

@param array<string, mixed> $options

AssociationFile::list()

public static function list(mixed $records): array

The related records as a list: the collection's, the record itself, none.

AssociationFile::files()

public static function files(mixed $records, array $options): array

The related records' public files (Uploader::getPublic(), the first of several), what the upload field shows (the type's PRE_SET_DATA).

AssociationFile::entries()

public static function entries(mixed $records, array $options): string

Each stored file's name by its record's id, as the block's data-entry-id carries it (the type's finishView(): for several records only, [] otherwise); JSON-encoded.

AssociationFile::childOptions()

public static function childOptions(array $options, bool $required): array

The upload field's options, as the type adds it: its class, whether it is removable, required (where the record's column may not be empty), several and in order, its address, its size, its number of files and types.

AssociationFile::records()

public static function records(mixed $files, mixed $existing, array $options, ?object $owner, EntityHydratorInterface $hydrator): array|object|null

What was sent made into the related records (the type's mapFormsToData()): for several, each file sent a new record, each stored file's name the record holding it; for one, the record (or a new one) given the file. A record made is given entity_data - a callable ($record, $owner, $file), or values hydrated with the file -, else its file. Null where nothing is sent for one.

$files

what the upload field reads (Upload::reverse()): a file, a name, a list of them

$existing

the records held before

AssociationFile::bind()

public static function bind(object $owner, string $property, array|object|null $records, array $options): void

The related records written into the record (the neutral FormBinder): several replace the collection's (an inverse side's records told their owner: its mappedBy, read from the entity's shape; those left told none), one is set where something was sent.

$records

records() answer

AssociationFile::required()

public static function required(?string $dataClass, string $property): bool

Whether the upload field is required: where the record's column may not be empty (an association's, as the type reads Doctrine's mapping, has no such word: required).

AssociationFile::isToMany()

public static function isToMany(?string $dataClass, string $property): ?bool

Whether the record's property holds several (a to-many association, named by itself or its alias).

Attribute class

final class Attribute Attribute.php:42

A record's attributes (Kind::ATTRIBUTE; plan "omnibase agnostic", step F5d, slice 7) - an account's hyperlinks -, as omnibase's AttributeType builds them, on every host: a select of the adapters offered (searched remotely, the field's filter narrowing them to its adapters' classes), then, for each attribute held, its value drawn by its adapter's field (a hyperlink's pattern, a number...). What AttributeType decides itself is here, and it asks it:

  • options(): its defaults;
  • classes(): the attribute's class (the field's, else Attribute) and its adapters' (a rule's, a scope's, an action's, any adapter otherwise);
  • choice(): the options of its select (choice): the adapters' class, their code searched, the filter, disabled while its record is not stored;
  • key() and value(): an attribute's part, named by its adapter's code and its id, and the field its adapter draws its value with.

And for the hosts without Symfony's forms: bind() writes what is sent into the record's attributes - an attribute kept for each adapter still chosen (its value written from its part), a new one for an adapter newly chosen, the others taken out. A translated attribute's value (its intl part, a TranslationType of several records at once) is not drawn there: such a field, once it holds one, is refused aloud by those hosts (translated()). The core's attributes (Attribute, Hyperlink) are all translated: on those hosts, the adapters are chosen and the attributes made or taken out; their values are written where Symfony's forms draw them.

const DEFAULTS = ['abstract_class' => null, 'class' => null, 'recursive' => false, 'multiple' => null, 'multivalue' => false, 'filter' => null, 'filter_code' => null, 'sortab…

Attribute::options()

public static function options(array $options): array

Attribute::classes()

public static function classes(array $options, ?string $guessed = null): array

The attribute's class and its adapters', as AttributeType settles them before building its parts.

Attribute::choice()

public static function choice(array $options, ?object $record): array

Its select of adapters (SelectType's options, as AttributeType gives them).

$options

the attribute's, its classes, multiplicity and order known

Attribute::held()

public static function held(mixed $value, bool $multiple): array
Returns

the attributes held, the first only for a single one

Attribute::key()

public static function key(AbstractAttribute $attribute): string

An attribute's part's name: its adapter's code and its id.

Attribute::translated()

public static function translated(AbstractAttribute $attribute): bool

Attribute::value()

public static function value(AbstractAttribute $attribute): FieldDescriptor

The field an attribute's value is drawn with: its adapter's type and options, its label and help, never required (AttributeType's part: an AssociationType of the one field value).

Attribute::bind()

public static function bind(object $owner, string $property, array $submitted, array $options, array $chosen, FormBinder $binder): void

What is sent written into the record's attributes (AttributeType::mapFormsToData()): the adapters chosen (their ids under choice), each attribute kept for an adapter still chosen - its value written from its part ({code}-{id}[value]) -, a new one for an adapter newly chosen.

$options

the attribute's, its classes known

$chosen

the adapters chosen, as the select's binding reads them

Behaviours class

final class Behaviours Behaviours.php:21

The behaviour of each kind, as every host asks it (plan "omnibase agnostic", step F5d): kind => an Omnibridge\Form\FieldBehaviour. The Symfony form types read their options and vars from it, the neutral FormView and FormBinder (Laravel's, React's props) too. A kind without a behaviour is a plain value its kind's generic rule reads (Kind::INPUT_TYPES, FormBinder).

An application adds or replaces a kind's behaviour with register(). A field whose host type was named directly (FieldDescriptor::setFormType(), Symfony's ChoiceType for a plain list) has none: its host type decides.

Behaviours::register()

public static function register(string $kind, FieldBehaviour $behaviour): void

Behaviours::of()

public static function of(?string $kind): ?FieldBehaviour

The behaviour of a kind; null for a plain one.

Behaviours::ofField()

public static function ofField(FieldDescriptor $field): ?FieldBehaviour

The behaviour of a field: its kind's, none when its host type was named directly.

Behaviours::complete()

public static function complete(FieldDescriptor $field): FieldDescriptor

A field completed with its behaviour's defaults (the options it does not set), as the neutral FormView and FormBinder read it; the field itself when it has no behaviour.

Behaviours::kinds()

public static function kinds(): array
Returns

the kinds that have a behaviour

Behaviours::reset()

public static function reset(): void

Forgets what was registered (tests).

ChoiceList class

final class ChoiceList extends AbstractBehaviour ChoiceList.php:9

Kind::LOCALE: a plain select of the locales Intl names (Symfony's LocaleType), its choices given when the field names none.

ChoiceList::__construct()

public function __construct(readonly \Closure $choices)

Choices class

final class Choices Choices.php:15

The choices a choosing kind offers when the field names none: an enum's (a PHP enum's cases, or one of omnibase's EnumType or SetType values: the role, the state, the gender), the countries, the locales - what Symfony's types guess or load themselves (FormGuessTrait::guessChoices(), CountryType, LocaleType).

Choices::of()

public static function of(?string $class): ?array

label => value, groups as nested lists; null when the class offers none.

Choices::locales()

public static function locales(): array
Returns

name => code, as Symfony's LocaleType lists them

Choices::countries()

public static function countries(): array

Collection class

final class Collection Collection.php:22

A list of entries drawn one under the other (Kind::COLLECTION, Kind::ARRAY; plan "omnibase agnostic", step F5d, slice 7), as omnibase's CollectionType and ArrayType decide it, on every host. They ask it:

  • options(): their defaults (CollectionType's, ArrayType's over them for an array) and what their normalizers made of them - a fixed length (an array's pattern, its {n} counted) neither adds nor deletes, an entry carries no label of its own, a collection is required;
  • length(): an array's length, read from its pattern;
  • window(): the entries a page shows of a capped collection (max_entries from entry_offset), the others kept aside and never removed by a submission that did not show them;
  • rendered(): the indexes a windowed page says it drew (its _rendered input);
  • empty(): the markup a page shows for no entry (collection2_empty);
  • entries(): what is sent, read as the list the data keeps (an array's values in order, an associative one's key => value; _rendered left out).
const DEFAULTS = ['form2' => false, 'length' => 0, 'max_entries' => null, 'entry_offset' => 0, 'allow_object' => false, 'allow_add' => false, 'allow_delete' => true, 'html' =…

The defaults of CollectionType (the entry a hidden input, entries neither added nor kept apart).

const ARRAY_DEFAULTS = ['target' => null, 'associative' => null, 'allow_add' => true, 'allow_delete' => true, 'entry_type' => Kind::TEXT, 'webpack_entry' => 'form.array', 'pattern'…

What ArrayType sets over them: a text per entry, added and deleted, its script form.array.

Collection::options()

public static function options(array $options, string $kind = Kind::COLLECTION): array

Collection::length()

public static function length(array $options): int|string

Collection::window()

public static function window(array $entries, array $options): array

The entries a page shows: all of them, or a capped collection's window (CollectionType's max_entries, on a page asked for; a submission builds them all).

Collection::rendered()

public static function rendered(mixed $raw): array
Returns

the indexes a windowed page drew, from its _rendered input

Collection::empty()

public static function empty(): string

collection2_empty: what a page shows of a collection without an entry.

Collection::entries()

public static function entries(mixed $submitted, array $options): array

What is sent for a list (an array's texts, a collection's hidden values), as the data keeps it: in its order, _rendered left out; an associative array's entries ({key, value}) as key => value.

Collection::shown()

public static function shown(mixed $value, array $options): array

A list's values as a page shows them: in order, an associative one's as {key, value}.

@return array<int|string, mixed>

ColorPickr class

final class ColorPickr extends AbstractBehaviour ColorPickr.php:11

Kind::COLOR_PICKER: a colour picked in Pickr (its settings in pickr, the swatches and the buttons' words included), shown as #RRGGBBAA: a short colour completed with an opaque alpha, anything else as the transparent black, which is no colour when the field may be empty (is_nullable).

const NONE = '#00000000'
const SWATCHES = ['#001F3F', '#0074d9', '#7fdbff', '#39cccc', '#3d9970', '#2ecc40', '#01ff70', '#ffdc00', '#ff851b', '#ff4136', '#85144B', '#f012be', '#b10dc9', '#111111', '#…

ColorPickr::vars()

public function vars(array $options, mixed $shown, string $id): array

ColorPickr::transform()

public function transform(mixed $data, array $options): mixed

ColorPickr::reverse()

public function reverse(mixed $submitted, array $options): mixed

CountrySelect class

final class CountrySelect extends Select CountrySelect.php:6

Kind::COUNTRY: a select2 of the countries (Base\Field\Choice\Countries), with their flags (use_html).

CountrySelect::entry()

public function entry(array $entry, array $options): array

Its name and its flag, as CountryType gives them (SelectInterface::getText(), getHtml()).

DateTimePicker class

final class DateTimePicker extends AbstractBehaviour DateTimePicker.php:12

Kind::DATETIME_PICKER: a date (and time) typed or picked in flatpickr. Its value is shown and read in the field's ICU format (yyyy-MM-dd HH:mm by default; a date-only picker gives yyyy-MM-dd), the picker's settings in datetimepicker, merged over the defaults key by key: a caller that turns the time off keeps the page's language.

const FORMAT = 'yyyy-MM-dd HH:mm'

DateTimePicker::picker()

public static function picker(mixed $given = [], ?string $language = null): array

The picker's settings: the given ones over the defaults, key by key.

DateTimePicker::options()

public function options(array $given): array

DateTimePicker::vars()

public function vars(array $options, mixed $shown, string $id): array

DateTimePicker::transform()

public function transform(mixed $data, array $options): mixed

A date written in the field's format, as Symfony's DateTimeType writes it (IntlDateFormatter).

DateTimePicker::reverse()

public function reverse(mixed $submitted, array $options): mixed

What is typed, in the field's format, as the binder reads a date and time (Y-m-d H:i:s); refused when it is not in that format.

Editor class

final class Editor extends AbstractBehaviour Editor.php:23

Kind::EDITOR: an Editor.js document (forms/form-type-editor.js) kept as JSON in a hidden input - what omnibridge/symfony's EditorType decided, which it now asks.

  • options(): the placeholder, the script's entry, collab_autosave and collab_live (a debounced save through ux_editorjs_autosave; a relay's live editing, its ticket through ux_editorjs_collabTicket).
  • vars(): the widget's id (dashes made underscores), the value with each picture's address made from its stored origin in the editor's storage (base.twig.editor.storage, omnibase's MediaEnhancer), the five addresses of the editor's routes with their token (Base\Field\Editor\EditorJs), and editor (JSON): the placeholder and, for a record the persistence maps when a collaboration is asked, the room of that field (its token, its version hash, the account signed in). The record, the field's name and its language are given by the host: editor_record, editor_field, editor_locale.
  • reverse(): a document without a block is no text (null).

Editor::vars()

public function vars(array $options, mixed $shown, string $id): array

Editor::reverse()

public function reverse(mixed $submitted, array $options): mixed

An empty document (no block) is no text.

Editor::endpoints()

public function endpoints(array $options): array

Guess class

final class Guess Guess.php:20

What a field's options leave out and the record's mapping says, as omnibase's Symfony types guess it from Doctrine (FormGuessTrait, SlugType): read from the entity's shape on any host (the unit of work's EntityShapes) - the class a select chooses among (an association's target, an enumeration column's class) and whether it holds several (a to-many association, a set enumeration), and whether a slug may be empty (its column nullable).

Guess::from()

public static function from(FieldDescriptor $field, ?string $dataClass): FieldDescriptor

The field with what its record's mapping says set where its options say nothing; itself without a mapping.

Icon class

final class Icon extends Select Icon.php:17

Kind::ICON: a select2 of the icon provider's icons, always searched remotely (ux_autocomplete_icons, 200 a page, the provider's adapter: the parameter base.icon_provider.default_adapter, Font Awesome's by default).

An icon chosen is shown as IconType shows it: itself, named by its adapter's list (fa-solid fa-icons is "Icons").

Icon::options()

public function options(array $given): array

Icon::entry()

public function entry(array $entry, array $options): array

IconType::getIcon() and getText(): the icon itself where an adapter knows it, its name in that adapter's list.

JsColor class

final class JsColor extends AbstractBehaviour JsColor.php:10

Kind::COLOR: a colour typed or picked in jscolor, shown as #RRGGBBAA (an empty one as #00000000), kept as short as it can be written (#F00); the transparent black is no colour when the field may be empty (is_nullable).

const NONE = '#00000000'

JsColor::vars()

public function vars(array $options, mixed $shown, string $id): array

JsColor::transform()

public function transform(mixed $data, array $options): mixed

JsColor::reverse()

public function reverse(mixed $submitted, array $options): mixed

Number class

final class Number extends AbstractBehaviour Number.php:12

Kind::NUMBER: a number shown in the page's language (48,857 in French, as Symfony's NumberType writes it: its scale, else three decimals at most; grouping off by default), divided by divisor when shown and multiplied back when read, its prefix and suffix stripped; the steppers' settings (step, throttle, min, max, the keys) for the number script.

Number::vars()

public function vars(array $options, mixed $shown, string $id): array

Number::transform()

public function transform(mixed $data, array $options): mixed

Number::reverse()

public function reverse(mixed $submitted, array $options): mixed

What is typed, its prefix and suffix stripped, read in the page's language; the number for the binder.

Password class

final class Password extends AbstractBehaviour Password.php:11

Kind::PASSWORD: omnibase's password, typed twice by default (plain, then plain_repeater, as PasswordType names its two inputs), its strength shown (hint, the strength bounds) and checked; the value is what was typed, untrimmed, refused when the two inputs differ.

Password::options()

public function options(array $given): array

Password::vars()

public function vars(array $options, mixed $shown, string $id): array

Password::reverse()

public function reverse(mixed $submitted, array $options): mixed

The typed password, from its two inputs; refused when they differ.

Password::transform()

public function transform(mixed $data, array $options): mixed

A password is never shown.

RecordFields class

final class RecordFields RecordFields.php:28

A record's fields as a form embedding it lists them (plan "omnibase agnostic", step F5d): what ClassMetadataManipulator::getFields() answers omnibase's TranslationType and AssociationType from Doctrine's metadata, read here from the entity's shape (the unit of work's EntityShapes) on any host.

of() gives the fields named first, in their order, then the record's other columns in its order (the identifier, the translation's own record and language left out, and the excluded ones), each with the kind its column says - a string a text, a text a textarea, a list (json, array) a select of free tags, an integer a number, a date and time a datetime picker, an enumeration a select of its values - and the options given over it; a column no kind fits is left out. descriptor() makes one of them a field as AssociationType adds it: its kind (a host type named by form_type read as the kind it renders), its options, not required where its column may be empty and nothing says otherwise.

const EXCLUDED = ['id', 'translatable', 'locale']

What every embedded form leaves out (ClassMetadataManipulator's global excluded fields).

RecordFields::of()

public static function of(string $class, array $fields = [], array $excluded = []): array
$fields

name => options (a host type's name alone, or [])

Returns

name => options, with kind or form_type

RecordFields::descriptor()

public static function descriptor(string $class, string $name, array $field): ?FieldDescriptor

One of them as a field (AssociationType's child): null where nothing renders it - no kind, a related record (an embedded form's own), a field kept out of records (allow_entity: false).

RecordFields::kindOf()

public static function kindOf(string $type): string

The kind a host type's name renders: the host's map (Kinds::kind()), else its name read as the kind's (Base\Field\Type\TextareaType or Symfony's TextareaType a textarea, SelectType a choice, EmojiPickerType an emoji); a type no kind names is custom, the type its own.

Select class

class Select extends AbstractBehaviour Select.php:20

Kind::CHOICE and the kinds that choose among a list (role, state, gender, country, currency, locale, icon, an association picked rather than embedded): a select2 select, its entries given or searched remotely.

The neutral part of omnibase's SelectType: its options and their normalization (required unless tags are typed, a highlight only without tags, the tags' own separators), select2's settings as SelectType hands them to its script (select2()), the remote search's route (endpoints(), autocomplete_endpoint, the host's ux_autocomplete). What reads records - guessing the class from the data, the records chosen, an admin's edit link - stays with the host's type, which passes it in as context.

Select::__construct()

public function __construct(readonly array $defaults = [])
$defaults

a kind's own over the select's (the role's enum, the state's)

Select::options()

public function options(array $given): array

The options resolved; without choices, those of the class when it is an enum (Choices::of()), a remote search when it is a record's.

Select::normalize()

public static function normalize(array $options): array

SelectType's normalizers, on resolved options.

Select::select2()

public static function select2(array $options, bool $multiple, ?string $search, string $language, ?string $placeholder = null, array $entries = [], array $selected = []): array

select2's settings, as SelectType hands them to its script (data-select2-options): the given select2 completed by the options.

$options

resolved

$multiple

what the field is, once guessed

$search

the remote search's address; null without one

$language

select2's language, fr

$placeholder

the placeholder in the page's words; translated here when null

$entries

the entries select2 starts with (data)

$selected

the values chosen

Select::vars()

public function vars(array $options, mixed $shown, string $id): array

The vars select2's row reads (select2_widget): the settings as JSON, the highlight, the tags' separators, the tabulation, the sorting. A host that searches remotely passes its address in $options['search_url'].

Select::entry()

public function entry(array $entry, array $options): array

One of select2's entries as this kind shows it, once resolved (Autocomplete's id, icon, text, html): a kind whose type says more of its choices (the countries' flags) completes it.

Select::reverse()

public function reverse(mixed $submitted, array $options): mixed

A select2 is drawn as its form's choice part (name[choice], as SelectType's compound form names it): the value is that part's.

Select::endpoints()

public function endpoints(array $options): array

The remote search, where the field is autocompleted: the host's ux_autocomplete (or the field's own route).

Slug class

final class Slug extends AbstractBehaviour Slug.php:13

Kind::SLUG: an address's word, made from another field as it is typed (its target, a path in the form: "translations.title" is the default language's title) and locked once written by hand. Its settings are the slug script's: the separator, the characters kept, upper case, whether anything else is dropped (strict, by default when nothing is kept), the lock.

Slug::options()

public function options(array $given): array

Slug::vars()

public function vars(array $options, mixed $shown, string $id): array

keep, separator, upper, strict, lock as the slug script reads them; target the path of the field it is made from, as a list (null: the form's own), its id resolved by the renderer in the whole form.

Toggle class

final class Toggle extends AbstractBehaviour Toggle.php:10

Kind::BOOLEAN: a switch, asking for a confirmation when it is ticked or unticked (both by default), possibly saved at once through a toggle route (toogle_url, the option's historical spelling).

Toggle::vars()

public function vars(array $options, mixed $shown, string $id): array

Translation class

final class Translation Translation.php:29

A translations field (Kind::TRANSLATION, plan "omnibase agnostic", step F5d), as omnibase's TranslationType builds it, on every host: one part per language, each the translation entity's fields (RecordFields, the entity's shape). What TranslationType decides itself is here, and it asks it:

  • options(): its defaults - the page's language, the default one, the languages offered (the Locales contract), the required ones among them;
  • locales(): the languages drawn, the default one alone for a single-language field (the record's one language when it has exactly one);
  • entryRequired(): whether a language's part is required (the default one, the required ones);
  • perLocale(): each language's fields, a field's locale_options applied (or the field left out where they say display: false);
  • required(): a field's required given as a callable ($required, $locale, $options), called.

And for the hosts without Symfony's forms (the neutral FormView and FormBinder): fields(), each language's FieldDescriptors; read(), a record's translations as the values shown; bind(), what is sent written into the record's translations (TranslatableInterface::translate()).

Translation::options()

public static function options(array $options): array

The options with TranslationType's defaults: locale, single_locale, default_locale, required_locales (only the offered ones), available_locales, autoload, fields, excluded_fields, translation_class, translatable_class, multiple.

Translation::requiredLocales()

public static function requiredLocales(array $required, array $available): array

TranslationType's normalizer: the required languages among those offered.

Translation::locales()

public static function locales(array $options, array $recordLocales): array

The languages drawn, each with the language whose fields its part takes, and the default one they are measured against: every offered language, each its own; for a single-language field, the default one - or the record's one language when it has exactly one, with the default's fields.

$options

completed (options())

$recordLocales

the languages the record has a translation in

Returns

drawn => the language of its fields

Translation::entryRequired()

public static function entryRequired(string $locale, string $default, array $options): ?bool

Whether a language's part is required: the default one and the required ones are; the others are not when the required ones are named; null (the part's own default, required) otherwise.

$options

completed (options())

Translation::perLocale()

public static function perLocale(array $fields, array $locales): array

Each language's fields: a field's locale_options (by language) over its own, a field left out of a language whose options say display: false.

$fields

name => options

$locales

the offered languages

Returns

locale => name => options

Translation::required()

public static function required(array $field, bool $entryRequired, string $locale, array $options): array

A field's options with its required given as a callable called: fn (bool $required, string $locale, array $options): bool, told whether the language's part is required.

Translation::translationClass()

public static function translationClass(array $options, ?string $dataClass): ?string

The translation entity's class of a field: its translation_class, else its translatable_class's, else the record's (the form's data class); null when none is translatable.

Translation::fields()

public static function fields(string $translationClass, array $options, array $recordLocales = []): array

Each language's fields as descriptors, as TranslationType adds them: the translation entity's fields (RecordFields), each language's options (perLocale()), a callable required called, and the field required only where the language's part is (a part not required makes its fields optional).

$options

completed (options())

Returns

locale => name => descriptor

Translation::recordLocales()

public static function recordLocales(mixed $translations): array

The languages a record has a translation in: its translations' keys.

Translation::read()

public static function read(mixed $translations, array $fields, \Base\Form\Definition\FormBinder $binder): array

A record's translations as each language's values, read by each field's kind.

$fields

locale => name => descriptor (fields())

Returns

locale => name => value shown

Translation::bind()

public static function bind(TranslatableInterface $record, array $submitted, array $fields, \Base\Form\Definition\FormBinder $binder): array

What is sent for each language written into the record's translations: a language's translation (the record's, else a new one, TranslatableInterface::translate()) given each field's value; a translation left empty is not kept (TranslationType's SUBMIT: an empty one is removed).

$submitted

locale => name => raw

$fields

locale => name => descriptor

Returns

locale => name => value shown again

Throws

UnexpectedValueException a value that cannot be read, its path (locale.name) as message

Upload class

final class Upload extends AbstractBehaviour Upload.php:37

A file sent with its form (plan "omnibase agnostic", step F5d): what omnibase's FileType and its children (ImageType, AvatarType, AudioType, VideoType) decided, which they now ask - their options, and what their blocks read of the record's files: the stored files' public addresses, thumbnails, previews, download links, the largest size and the types accepted (the record's #[Uploader] and #[File]), the dropzone's settings and its address (Base\Field\Upload\Dropzone), the cropper's. The same on every host: the Symfony types read it, the neutral FormView gives it to omnibridge/laravel's renderer.

What a form sends back is FileType's compound - file (the stored file's name, or a dropzone's uuids "|"-separated), raw (the file sent), url (a file to fetch, with allow_url) - read by reverse() as FileType reads it (mapFormsToData(), then SUBMIT): the file sent, else the one fetched, else what file names (a file the dropzone kept, or the name of one already stored); nothing is null. The record's #[Uploader] stores the file when it is flushed.

vars() reads the record from the options FormView and FileType give it: upload_record (the form's data), upload_property (the field's name), upload_data (its value, for data that is not a record), and upload_media and upload_files (the host's MediaService and FileService, where its runtime does not give them).

const FILE = 'file'
const IMAGE = 'image'
const AVATAR = 'avatar'
const AUDIO = 'audio'
const VIDEO = 'video'
const DEFAULTS = ['class' => null, 'empty_data' => null, 'webpack_entry' => 'form.dropzone', 'dropzone' => [], 'allow_delete' => true, 'allow_delete[confirmation]' => true, '…

FileType's defaults (its sortable-js, the Symfony parameter of the script's address, stays its own).

const VARIANTS = [self::FILE => [], self::IMAGE => ['thumbnail' => 'bundles/base/images/image.svg', 'clipboard' => true, 'modal' => ['keyboard' => false, 'backdrop' => 'stati…

What each child type sets over FileType's defaults.

const CROPPER = ['viewMode' => 2, 'autoCropArea' => true, 'movable' => false, 'zoomable' => false, 'rotatable' => false, 'scalable' => false]

The cropper's settings an image's cropper gets where it says nothing (ImageType).

public readonly string $variant

Upload::__construct()

public function __construct(public readonly string $variant = self::FILE)

Upload::variantOf()

public static function variantOf(?string $kind): ?string

The variant of a kind (file, image, avatar, audio, video); null for a kind that is no upload of its own.

Upload::isImage()

public function isImage(): bool

Upload::options()

public function options(array $given): array

Upload::endpoints()

public function endpoints(array $options): array

Upload::vars()

public function vars(array $options, mixed $shown, string $id): array

What FileType's block reads (and ImageType's, AvatarType's, AudioType's): files, value (the stored files' names, "|"-separated for several), path, previews, download, clippable, max_size, max_files, mime_types, the dropzone's settings and its ajax address; an image's thumbnail, modal and cropper.

Upload::reverse()

public function reverse(mixed $submitted, array $options): mixed

What the form sent, as FileType reads it: the file sent (raw), else the one fetched (url), else what file names - a dropzone's uuids its kept files, a stored file's name itself; null for nothing.

A value that is no compound (a plain file input) is read as it is.

Upload::refusal()

public function refusal(mixed $submitted, array $options, string $property): ?array

The file sent refused as FileType's constraint refuses it (Base\Validator\Constraints\File on its raw part, when the form is validated): a type its mime_types do not match, else a size over the ceiling - PHP's upload limit, narrowed by the class' #[Uploader] and #[File] (its class option) and its max_size. Its message and parameters are the constraint's (the validators catalogue: file.mime_type, file.max_size); null for a file accepted, for none sent, for several (the constraint reads one file).

$options

the field's options, completed

Wysiwyg class

final class Wysiwyg extends AbstractBehaviour Wysiwyg.php:11

Kind::WYSIWYG: an HTML text written in Quill (forms/form-type-wysiwyg.js), kept in a hidden input - what omnibridge/symfony's WysiwygType decided, which it now asks. Its settings are Quill's: the theme, the toolbar's modules, the placeholder, the height; no route. The widget's id has its dashes made underscores (a translation's fr-FR part: Quill's script reads the id as a name).

const MODULES = ['syntax' => true, 'toolbar' => [[['header' => [1, 2, false]]], ['bold', 'italic', 'underline', 'strike'], [['color' => []], ['background' => []], ['script' …

Quill's toolbar, as WysiwygType gives it.

Wysiwyg::vars()

public function vars(array $options, mixed $shown, string $id): array

The widget's id (dashes made underscores) and Quill's settings as the script reads them (wysiwyg, JSON).

Base\Field\Choice

Countries class

final class Countries Countries.php:13

The countries a country field offers, neutral (symfony/intl only): their names by code, the codes added by an application, those left out for want of a flag. Base\Field\CountryField reads its choices here, so describing a country field loads no form library; CountryType (Symfony) delegates here.

Countries::addCountry()

public static function addCountry($code, $country)

Countries::addCountries()

public static function addCountries($array)

Countries::getName()

public static function getName(string $code)

Countries::getNamesWithoutAddons()

public static function getNamesWithoutAddons()

Countries::getNames()

public static function getNames($addons = false)

Countries::getChoices()

public static function getChoices(): array
Returns

name => code

Base\Field\Conformance

Host interface

interface Host Host.php:13

A host as the field conformance suite drives it (Suite): its name (the one Base\Field\Kinds knows its coverage by), a definition drawn as the host draws it for a page, a submission bound and validated as the host processes it.

Host::name()

public function name(): string

symfony, laravel: the host's name in Base\Field\Kinds.

Host::render()

public function render(FormDefinition $form, mixed $data): string

The form's markup, as a page of this host prints it.

Host::submit()

public function submit(FormDefinition $form, array $submitted, mixed $data): Outcome

What is submitted under the form's name, bound to the data and validated.

Outcome class

final readonly class Outcome Outcome.php:6

A submission's outcome on a host: the data as bound, the errors by field name ("" for the form's own).

public mixed $data
public array $errors

Outcome::__construct()

public function __construct(public mixed $data, public array $errors)

Sample class

final readonly class Sample Sample.php:23

One kind as the conformance suite tries it: a field of that kind named value, the data it starts from, what the page shows of it, what a visitor sends (under the field's name, as that host's markup sends it), the value the data then holds, and a value the field refuses.

$drawn: the markup names the field (an input, a select, a textarea whose name is the form's name and the field's, or starts with it); $shown, when given, is found in it as a value. A sample with $bound = self::RENDER_ONLY is drawn and not submitted: what it holds needs a host's records or files. A sample with a $dataClass is drawn over a new record of that class (the core's own entities, on every host) under the property $name: the kinds whose host reads the record's mapping (an upload, an embedded form). A sample not $exercised is declared only: the core has no record its kind holds (an attribute's adapter); an application's suite tries it on its own.

const RENDER_ONLY = "\x00render-only"
const NONE = "\x00none"
public string $kind
public \Closure $field
public mixed $data
public mixed $shown
public mixed $submitted
public mixed $bound
public mixed $invalid
public bool $drawn
public ?string $dataClass
public string $name
public bool $exercised

Sample::__construct()

public function __construct(public string $kind, public \Closure $field, public mixed $data = null, public mixed $shown = self::NONE, public mixed $submitted = null, public mixed $bound = self::RENDER_ONLY, public mixed $invalid = self::NONE, public bool $drawn = true, public ?string $dataClass = null, public string $name = Suite::FIELD, public bool $exercised = true)

Sample::field()

public function field(): FieldDescriptor

Sample::submits()

public function submits(): bool

Samples class

final class Samples Samples.php:20

A sample of every kind the core names (Kind::all()), as Symfony draws and reads it: the reference every other host conforms to. The page's language is French (fr-FR), the host's test sets it.

A select2 kind is sent as its form's choice part (name[choice]), as omnibase's SelectType names it on both hosts. The kinds whose value is a record, a file or a list of sub-forms are drawn only (RENDER_ONLY): what they hold needs the host's records or an upload.

Samples::all()

public static function all(): array
Returns

kind => its sample, for every kind of Kind::all()

Samples::field()

public static function field(string $kind, array $options = []): \Closure

Suite class

final class Suite Suite.php:26

The field conformance suite (plan "omnibase agnostic", step F5d), the same on every host: a host's coverage declares every kind (Kinds::faults()), and each kind it implements draws its field, shows the data's value, binds what is sent to the same value, refuses what it cannot read. A kind it declares unsupported is refused aloud when drawn (a host's exception), never a plain input.

A host's test runs it over Samples::all() (one case per kind):

foreach (Samples::all() as $kind => $sample) {
    self::assertSame([], Suite::check($host, $sample), $kind);
}

The samples' expected values are Symfony's, the host whose types the behaviours were taken from.

const FORM = 'conformance'
const FIELD = 'value'

Suite::definition()

public static function definition(Sample $sample): FormDefinition

Suite::data()

public static function data(Sample $sample): mixed

The data a sample starts from: a new record of its class, or the form's array.

Suite::coverage()

public static function coverage(Host $host): array
Returns

what is wrong with the host's coverage

Suite::check()

public static function check(Host $host, Sample $sample): array
Returns

what the host does wrong with this kind, [] when it conforms

Suite::normal()

public static function normal(mixed $value): mixed

A bound value as the suite compares it: a date written out, an enum's value, a record's id, a float as it reads.

Base\Field\Editor

EditorJs class

class EditorJs EditorJs.php:45

An Editor.js field's routes, answered for any host (plan "omnibase agnostic", step F5d): what omnibase's EditorController answered under Symfony, moved here as it was, so that every host serves an editor at the same addresses (ROUTES) with the same answers.

  • data(): what an editor hands its routes (their data), obfuscated (Obfuscator, long form): a token of intent "editorjs" (the Tokens contract) that the mentions and the uploads check first. addresses(): the five routes' addresses with it, as EditorType gives them to the widget.
  • users(), keywords(), threads(): the mentions' search (@someone, #keyword, a thread), five by page.
  • uploadByFile(), uploadByUrl(): a picture of the text stored in the editor's storage (base.twig.editor.storage), its public address answered.
  • ticket(): a collaboration relay's ticket for one room; autosave(): one field of one record written outside its form, refused on a conflict (an optimistic version hash). Both check the room's own token.

The host's controller - Symfony's EditorController, omnibridge/laravel's EditorController - hands the request's parts and sends the Answer as JSON (a refusal as text); the profiler stays its own.

const ROUTES = ['ux_editorjs_collabTicket' => ['/ux/editorjs/collab-ticket', 'ticket', ['POST']], 'ux_editorjs_autosave' => ['/ux/editorjs/autosave', 'autosave', ['POST']],…

The routes, in the order a host declares them (the collaboration's first: /ux/editorjs/{data} would take their paths): name => [path, action, methods]. {page} is optional.

const ADDRESSES = ['uploadByFile' => 'ux_editorjs_uploadByFile', 'uploadByUrl' => 'ux_editorjs_uploadByUrl', 'endpointByUser' => 'ux_editorjs_endpointByUser', 'endpointByThrea…

The editor's addresses as the widget reads them: its var => route.

const TOKEN = 'editorjs'

The intent of the token the mentions and the uploads check.

const STATUS_OK = 1
const STATUS_BAD = 0
const STATUS_NOTOKEN = -1

EditorJs::__construct()

public function __construct(readonly ObfuscatorInterface $obfuscator, readonly Tokens $tokens, readonly UnitOfWork $unitOfWork, readonly ?TranslatorInterface $translator = null, readonly ?PaginatorInterface $paginator = null, readonly ?MediaServiceInterface $mediaService = null, readonly ?Storages $storages = null, readonly ?Access $access = null, readonly ?Urls $urls = null, ?CollabRoomResolver $rooms = null, readonly ?CollabTicketFactory $tickets = null, ?SluggerInterface $slugger = null, readonly ?MediaEnhancerInterface $enhancer = null, readonly ?string $storage = null, readonly ?bool $debug = null)

EditorJs::data()

public function data(): string

What an editor hands its routes (their data): the visitor's token.

EditorJs::addresses()

public function addresses(): array

The five addresses the widget reads (ADDRESSES), with data(); an address is null where the host has no such route.

EditorJs::rooms()

public function rooms(): CollabRoomResolver

The room's routes (autosave, ticket), the collaboration's rooms and tickets.

EditorJs::tickets()

public function tickets(): ?CollabTicketFactory

EditorJs::roomToken()

public function roomToken(string $room): string

The token of one room (one record's one field), which its autosave and its ticket check.

EditorJs::author()

public function author(): ?array

The account signed in, as the collaboration shows it; null for no one.

@return array<string, mixed>|null

EditorJs::picture()

public function picture(string $origin): mixed

A picture of a document by its stored origin: the image route's address in the editor's storage (omnibase's MediaEnhancer), the origin itself where the host has no enhancer.

EditorJs::address()

public function address(string $route): ?string

A route's address, null where the host has none.

EditorJs::users()

public function users(?string $data, string $method, array $body = [], int|string|null $page = 1, array $fields = []): Answer

The accounts whose identifier holds the query (@someone), among $fields where given.

$body

the request's JSON body: query, page

$fields

the columns compared (a site's username, first and last names), the identifier's by default

EditorJs::keywords()

public function keywords(?string $data, string $method, array $body = [], int|string|null $page = 1, array $fields = ['slug']): Answer

The keywords (thread tags) whose slug holds the query's (#keyword).

@param array<string, mixed> $body

EditorJs::threads()

public function threads(?string $data, string $method, array $body = [], int|string|null $page = 1, array $fields = []): Answer

The threads whose identifier holds the query's slug.

@param array<string, mixed> $body

EditorJs::uploadByFile()

public function uploadByFile(?string $data, ?\SplFileInfo $file, int $error = \UPLOAD_ERR_OK): Answer

A picture sent under image, stored in the editor's storage under a new uuid's subfolders. $file is the host's uploaded file (Symfony's UploadedFile, Laravel's), $error its UPLOAD_ERR_*.

EditorJs::uploadByUrl()

public function uploadByUrl(?string $data, ?string $url): Answer

A picture fetched from the address the JSON body gives (url), stored as uploadByFile() stores one.

EditorJs::ticket()

public function ticket(array $body): Answer

A collaboration relay's ticket for one room (collab_live), for the account signed in, with the room's own token handed out with its field.

$body

the request's JSON body: room, token

EditorJs::autosave()

public function autosave(array $body): Answer

One field of one record written outside its form (collab_autosave, and the relay's saves), with the room's token or the relay's service token; refused with the current value when another save came after the version the client read (409).

$body

the request's JSON body: fqcn, id, field, locale, value, baseVersion, token or serviceToken and room

EditorJs::who()

public static function who(User $user): array

An account as the relay and the editor's collaboration show it.

Base\Field\Option

TextAlign class

final class TextAlign TextAlign.php:5

const LEFT = 'left'
const CENTER = 'center'
const RIGHT = 'right'

Answer class

final class Answer Answer.php:10

What a remote search answers (RemoteSearch): its status and its JSON body - the page of entries ({pagination, results}) or the reason it refused, a string, as omnibase's AutocompleteController answered them. Each host sends it as its JSON response.

public readonly int $status
public readonly array|string $body

Answer::__construct()

public function __construct(public readonly int $status, public readonly array|string $body)

Answer::page()

public static function page(array $page): self

Answer::refused()

public static function refused(string $reason, int $status = 500): self

ExchangeRate class

final class ExchangeRate ExchangeRate.php:16

A money field's exchange rate (/ux/autocomplete/currency/{source}/{target}/{data}), written once for every host (plan "omnibase agnostic", step F5e, slice 5b; formerly AutocompleteController::Forex()): the payload the field hands (obfuscated, short form) names the token and its intent, checked first; then the stored rate only - a visitor's request never spends the provider's quota, whether the application's Trading is live or not.

const ROUTE = 'ux_autocomplete_forex'

ExchangeRate::__construct()

public function __construct(readonly ObfuscatorInterface $obfuscator, readonly Tokens $tokens, readonly TradingInterface $trading)

ExchangeRate::rate()

public function rate(string $source, string $target, string $data): Json

RemoteSearch class

class RemoteSearch RemoteSearch.php:38

A select's remote search, answered for any host (plan "omnibase agnostic", step F5d): what omnibase's AutocompleteController answered under Symfony, moved here as it was, so that every host searches a select's records and an icon picker's icons from the same addresses (ROUTES) with the same answers.

  • data(): what a select hands its search, obfuscated (Obfuscator, short form: an identifier of the payload kept in its cache) - the class, the fields, the filters, the case, whether the entries are HTML and show faces, and a token of intent "select2" (the Tokens contract) that the search checks before answering. SelectType gives it under Symfony, FormView elsewhere.
  • records(): the records of the class (its repository's cacheByInstanceOf(), the finder language), paged by the Paginator, each resolved by Autocomplete and kept when its text holds the term; an enumeration's values; {pagination: {more, page}, results}.
  • icons(): an icon adapter's icons for the term, paged the same way.

Asked in debug, both read the term and the page from the query or the body, GET or POST; otherwise from the body of a POST only. The host's controller - Symfony's AutocompleteController, omnibridge/laravel's SearchController - passes the request's parts and sends the Answer as JSON; the profiler stays its own.

const ROUTES = ['ux_autocomplete' => ['/ux/autocomplete/{data}', 'records'], 'ux_autocomplete_icons' => ['/ux/autocomplete/{provider}/{pageSize}/{data}', 'icons']]

The search routes, in the order AutocompleteController declares them: name => [path, action]. ux_autocomplete_forex (ForexType's rates) stays Symfony's.

const TOKEN = 'select2'

The intent of the token a search checks.

RemoteSearch::__construct()

public function __construct(readonly ObfuscatorInterface $obfuscator, readonly Tokens $tokens, readonly PaginatorInterface $paginator, readonly UnitOfWork $unitOfWork, ?TranslatorInterface $translator = null, ?MediaServiceInterface $mediaService = null, readonly ?Icons $icons = null, readonly ?bool $debug = null)

RemoteSearch::data()

public function data(?string $class, array $fields = [], array $filters = [], ?bool $capitalize = null, bool $html = false, bool $avatar = false): string

What a select hands its search (the route's data), as SelectType built it.

$fields

the columns the term is compared with

$filters

the classes the records are instances of; none for every one

RemoteSearch::filters()

public static function filters(array $options): array

The filters of a select's search, as FormGuessTrait::guessChoiceFilter() guesses them without the record: none when choice_filter is false, the class when it is null.

RemoteSearch::records()

public function records(string $data, string $method, array $query = [], array $body = [], ?\Closure $repository = null): Answer

A page of records, or of an enumeration's values.

$query

the request's query string

$body

the request's body

$repository

the repository of a class, the host's (by default the unit of work's)

RemoteSearch::icons()

public function icons(IconAdapterInterface|string $provider, int $pageSize, string $data, string $method, array $query = [], array $body = []): Answer

A page of an icon adapter's icons.

$provider

the adapter, or its name (fa, bi) among the host's Icons

RemoteSearch::adapter()

public function adapter(string $idOrClass): ?IconAdapterInterface

The adapter of that name or class among the host's icons; null without one.

Base\Field\Upload

Dropzone class

class Dropzone Dropzone.php:30

A file field's uploads before its form is sent, answered for any host (plan "omnibase agnostic", step F5d): what omnibase's DropzoneController answered under Symfony, moved here as it was, so that every host takes a dropzone's files at the same addresses (ROUTES) with the same answers.

  • data(): what a dropzone hands its address (the route's data), obfuscated (Obfuscator, short form) - the dropzone's settings and a token of intent "dropzone" (the Tokens contract) that every action checks first. FileType gives it under Symfony, the Upload behaviour elsewhere.
  • store(): the file sent under file kept in the cache folder's dropzone/ under a new uuid - {status, uuid, mime_type, size, error} - or the reason it is refused, in the fields' words.
  • preview(): a kept file by its uuid, to show it again; delete(): one removed.
  • files(): what the form sends back - the uuids it kept, "|"-separated - as the files to store (FileType's SUBMIT): a kept file, or the name of one the record holds already.

The host's controller - Symfony's DropzoneController, omnibridge/laravel's UploadController - hands the request's file and sends the Answer (a file's path for a preview).

const ROUTES = ['ux_dropzone' => ['/ux/dropzone/{data}', 'store'], 'ux_dropzone_preview' => ['/ux/dropzone/{data}/{uuid}', 'preview'], 'ux_dropzone_delete' => ['/ux/dropzon…

The dropzone's routes, in the order DropzoneController declares them: name => [path, action].

const TOKEN = 'dropzone'

The intent of the token every action checks.

const STATUS_OK = 'OK'
const STATUS_BAD = 'BAD'
const STATUS_NOTOKEN = 'NO_TOKEN'

Dropzone::__construct()

public function __construct(readonly ObfuscatorInterface $obfuscator, readonly Tokens $tokens, readonly string $cacheDir, readonly ?Translations $translations = null)

Dropzone::directory()

public function directory(): string

The folder the uploads wait in until their form is sent.

Dropzone::data()

public function data(array $settings): string

What a dropzone hands its address (the route's data): its settings and the visitor's token.

$settings

Dropzone's options (maxFilesize in MB, acceptedFiles...)

Dropzone::store()

public function store(string $data, ?\SplFileInfo $file, int $error = \UPLOAD_ERR_OK, ?\Closure $moved = null): Answer

The file sent, kept under a new uuid. $file is the host's uploaded file (Symfony's UploadedFile, Laravel's); $error its UPLOAD_ERR_* when the host tells it apart, $moved how to move it where it is kept (move_uploaded_file() by default, which takes only a file PHP received).

Dropzone::preview()

public function preview(string $data, string $uuid): Answer|string|null

A kept file's path, to send it again; an Answer when it is refused, null when there is none.

Dropzone::delete()

public function delete(string $data, string $uuid): Answer

A kept file removed.

Dropzone::files()

public static function files(string $submitted, string $directory, bool $multiple): array|\SplFileInfo|string|null

What a dropzone's form sends back ("uuid|uuid"), as FileType's SUBMIT reads it: each uuid a file kept here (a file to store), or the name of a file the record holds already; one value, or the list of them for a field holding several; null for nothing.

Base\Field\Validation

Autovalidate class

final class Autovalidate Autovalidate.php:17

A field's validation asked while the form is filled (/ux/validation/{hashid}), written once for every host (plan "omnibase agnostic", step F5e, slice 5b; formerly AutovalidateController): the payload - the token, the value, the form's type - serialised and hidden by Hashids on the site's secret; answered "Fine" when its "validation" token is the visitor's and the method the environment expects (GET in debug, POST otherwise), "Invalid request" (500) otherwise. No check of the value is made yet.

const TOKEN = 'validation'

Autovalidate::__construct()

public function __construct(readonly Environment $environment, readonly Tokens $tokens)

Autovalidate::encode()

public function encode(array $payload): string

Autovalidate::decode()

public function decode(string $hash): array

Autovalidate::answer()

public function answer(string $hash, string $method): Json

Base\Form\Common

AbstractModel class

class AbstractModel implements FormModelInterface AbstractModel.php:5

AbstractModel::getTypeClass()

public static function getTypeClass(): string

FormModelInterface interface

interface FormModelInterface FormModelInterface.php:5

FormModelInterface::getTypeClass()

public static function getTypeClass(): string

NativeEnum class

final class NativeEnum NativeEnum.php:13

A PHP enum as a list of choices: what a select holds for a case (its value, or its name when the enum is not backed), the case back from it, and the words that name it.

NativeEnum::is()

public static function is(mixed $class): bool

NativeEnum::id()

public static function id(\UnitEnum $case): string

What the select holds for a case: the backed value, else the case's name.

NativeEnum::of()

public static function of(string $class, mixed $id): ?\UnitEnum

The case a select's value names; null for anything else.

NativeEnum::ids()

public static function ids(string $class): array

NativeEnum::key()

public static function key(\UnitEnum $case): string

The translation key of a case in the "enums" domain: the enum's short name in snake case, then the select's value in lower case (Base\Enum\CommentState::PENDING is "comment_state.pending").

NativeEnum::label()

public static function label(\UnitEnum $case, ?TranslatorInterface $translator = null, ?string $locale = null): string

A case's label: what the enum says itself when it is translatable (Symfony's TranslatableInterface), else its key in the "enums" domain, else its name made readable (NOT_CONTRACTED: "Not contracted").

Base\Form\Definition

AccountForms class

final class AccountForms AccountForms.php:16

The account's forms, neutral (plan "omnibase agnostic", step F5b): what omnibridge/symfony's types build, what a generic host renders and processes. A site adds its own fields to them.

const PLAIN_PASSWORD_TYPE = 'Symfony\Component\Form\Extension\Core\Type\PasswordType'

The Symfony form type of the two inputs of a sign-up's password: the plain one, no strength meter.

AccountForms::signIn()

public static function signIn(?string $identifier = null, string $name = '_base_security_login'): FormDefinition

The sign-in: its fields, posted to whatever answers it (the firewall's authenticator).

$identifier

what was typed before, shown again

public static function signInLink(?string $email = null, string $name = '_base_security_login_token'): FormDefinition

The sign-in by a link: an address. A trap, the time, the captcha; no list: the same answer for every address.

AccountForms::signUp()

public static function signUp(string $name = '_base_security_registration'): FormDefinition

The sign-up: an address, the terms, a password twice; a trap, the time, the lists, the captcha.

AccountForms::profile()

public static function profile(string $name = '_base_user_profile'): FormDefinition

The profile's editor: the avatar, the address, a new password.

Binding class

final class Binding Binding.php:12

What FormBinder::bind() gives: the data with the submitted values written, the values the form shows again, and the violations of the fields whose value could not be read.

public readonly mixed $data
public readonly array $values

by field name

public readonly array $violations

Binding::__construct()

public function __construct(public readonly mixed $data, public readonly array $values, public readonly array $violations = [])
$values

by field name

FormBinder class

final class FormBinder FormBinder.php:40

Data binding, neutral: what a form sends (an array of strings, files, lists) into the data it edits (an array, an entity, a DTO), and that data back into the values a form shows. The kind of each field says how (Kind): a trimmed string, an integer, a date, a choice among the field's choices, an association by its id (through the UnitOfWork's references), a file as the host gives it.

Symfony Form's behaviour where a form relies on it: an empty string is null (or the field's empty data), a missing checkbox is false, a disabled field keeps the data's value, a value that cannot be read ("abc" for an integer, a choice not offered) is a violation of that field - with Symfony's own message - and leaves the data untouched, the data is written only where its value changes.

Transformers are plain callables: per kind (withTransformer()), or per field with the custom options OPTION_REVERSE (submitted => data) and OPTION_TRANSFORM (data => shown); a reverse transformer throws \UnexpectedValueException for a value it cannot read.

A kind's behaviour (Base\Field\Behaviour\Behaviours, the same object the Symfony type reads) reads first, with the field's options completed by its defaults: a colour shortened, a date in the picker's format, a localized number, a select's part of a compound name; the kind's generic rule then reads what it gives (a string to a date, to a number).

const OPTION_REVERSE = 'binder.reverse'

Custom option (FieldDescriptor::setCustomOption()): callable(mixed $submitted, FieldDescriptor): mixed

const OPTION_TRANSFORM = 'binder.transform'

Custom option: callable(mixed $data, FieldDescriptor): mixed

const INVALID_MESSAGES = [Kind::INTEGER => 'Please enter an integer.', Kind::YEAR => 'Please enter an integer.', Kind::STOCK => 'Please enter an integer.', Kind::NUMBER => 'Please en…

Symfony's invalid messages, by kind (its types' invalid_message).

const INVALID_MESSAGE = 'This value is not valid.'
const UNTRIMMED_KINDS = [Kind::PASSWORD]

The kinds whose submitted string is kept as it is sent, without trimming (Symfony's trim: false).

FormBinder::__construct()

public function __construct(readonly ?UnitOfWork $unitOfWork = null)

FormBinder::withTransformer()

public function withTransformer(string $kind, callable $reverse, ?callable $transform = null): self

A copy reading a kind with these callables: $reverse(submitted, field) gives the data's value, $transform(data, field) the value shown.

FormBinder::read()

public function read(FormDefinition $form, mixed $data): array

The values the form shows for this data: one per field, by name - a string, a list of strings (a multiple choice), a bool (a checkbox), the host's file, an array (a collection) or null.

FormBinder::bind()

public function bind(FormDefinition $form, array $submitted, mixed $data = null): Binding

Binds what is submitted to the data: the data with the values written (the same object, or the array completed), the values to show again (as sent, for a field that could not be read), and the violations of the fields that could not be read.

$submitted

the form's part of the request (its name's key), files merged in

FormBinder::reverse()

public function reverse(mixed $raw, FieldDescriptor $field): mixed

The submitted value of one field read as the data keeps it; throws \UnexpectedValueException when it cannot be.

FormBinder::transform()

public function transform(mixed $value, FieldDescriptor $field): mixed

The data's value of one field as the form shows it.

FormBinder::choices()

public static function choices(FieldDescriptor $field): ?iterable

A field's choices, a callable called once it is asked (a query's answer); null without any.

FormBinder::flatten()

public static function flatten(iterable $choices): array

The values of a choices list, groups flattened.

FormDefinition class

final class FormDefinition FormDefinition.php:22

A form, neutral: its fields (FieldDescriptors, each naming a kind), their groups, its actions (the buttons that submit it), the intent its token is made for, how it is sent. No host's form library: Symfony builds its form from a definition (omnibridge/symfony), a Twig, Blade or React renderer prints its FormView, FormProcessor binds, validates and keeps what is sent.

$form = FormDefinition::new('comment') ->add(TextareaField::new('content', 'comment.content')->setRequired(true)) ->addAction('submit', 'comment.submit');

The admin builds one from a CRUD controller's fields (fromFields()).

const METHOD_POST = 'POST'
const METHOD_GET = 'GET'
const TOKEN_FIELD = '_csrf_token'

The name a submitted token is sent under.

FormDefinition::__construct()

public function __construct(readonly string $name)

FormDefinition::new()

public static function new(string $name): self

FormDefinition::field()

public static function field(string $name, string $kind, ?string $label = null): FieldDescriptor

A bare field of a kind (Base\Field\Kind), for a form that is no CRUD page's: none of what a descriptor class adds for the back office.

FormDefinition::fromFields()

public static function fromFields(string $name, iterable $fields, string $page = FieldDescriptor::PAGE_NEW): self

The form of the fields a page shows (a CRUD controller's configureFields()): those displayed on that page, in order.

FormDefinition::getName()

public function getName(): string

FormDefinition::add()

public function add(FieldInterface|FieldDescriptor $field, ?string $group = null): self

Adds a field, under its property's name (with its suffix), optionally in a group. A field of the same name is replaced.

FormDefinition::remove()

public function remove(string $name): self

FormDefinition::only()

public function only(array $names): self

A copy of the form with only these fields, its other settings kept: a host's type that adds them to its parent's asks its own part.

FormDefinition::has()

public function has(string $name): bool

FormDefinition::get()

public function get(string $name): FieldDescriptor

FormDefinition::getFields()

public function getFields(): array
Returns

by name, in order

FormDefinition::addGroup()

public function addGroup(string $name, ?string $label = null): self

A group of fields (a fieldset, a tab), its label a translatable key.

FormDefinition::getGroups()

public function getGroups(): array

FormDefinition::addAction()

public function addAction(string $name, ?string $label = null, string $kind = Kind::SUBMIT, array $attr = [], array $options = []): self

A button that submits the form: its name is the submitted intent (FormSubmission::getClicked()), its label a translatable key.

The options are plain data a renderer reads: confirmation (the button asks in a modal first) and type (what its HTML element says: "submit" on a button that is an action of Kind::BUTTON).

FormDefinition::getActions()

public function getActions(): array

FormDefinition::getMethod()

public function getMethod(): string

FormDefinition::setMethod()

public function setMethod(string $method): self

FormDefinition::getTarget()

public function getTarget(): ?string

Where the form is sent (its action attribute); null for the page itself.

FormDefinition::setTarget()

public function setTarget(?string $url): self

FormDefinition::getIntent()

public function getIntent(): string

The intent its token is made for (Omnibridge\Contract\Tokens): the form's name unless set.

FormDefinition::hasIntent()

public function hasIntent(): bool

Whether an intent was set: without one, a host may name the token as it does (Symfony: the form's own name).

FormDefinition::setIntent()

public function setIntent(?string $intent): self

FormDefinition::hasCsrf()

public function hasCsrf(): bool

FormDefinition::setCsrf()

public function setCsrf(bool $csrf): self

FormDefinition::getDataClass()

public function getDataClass(): ?string

The class of the data the form edits (an entity, a DTO); null for an array.

FormDefinition::setDataClass()

public function setDataClass(?string $dataClass): self

FormDefinition::getTranslationDomain()

public function getTranslationDomain(): ?string

The catalogue its labels, helps and placeholders are translated from; null for the host's default (Symfony's: fields).

FormDefinition::setTranslationDomain()

public function setTranslationDomain(?string $domain): self

FormDefinition::setGuard()

public function setGuard(array|bool $guard): self

Base\Service\FormGuard over this form: the trap, the time, the lists, the captcha. true, or Symfony's option guard's array: trap, min_delay, challenge, action, reputation, email, name, captcha_after.

FormDefinition::getGuard()

public function getGuard(): array|false

FormDefinition::addRewrite()

public function addRewrite(callable $rewrite): self

What was sent, rewritten before it is read (Symfony's PRE_SUBMIT): a "tick everything" box expanded into the list it stands for.

FormDefinition::rewrite()

public function rewrite(array $submitted): array

FormDefinition::getValidationGroups()

public function getValidationGroups(): ?array
Returns

the groups the form validates, the host's default when null

FormDefinition::setValidationGroups()

public function setValidationGroups(?array $groups): self

FormDefinition::getValidationEntity()

public function getValidationEntity(): ?string
Returns

the record the form makes, whose class-level rules (its uniqueness) the data must hold

FormDefinition::setValidationEntity()

public function setValidationEntity(?string $class, array $errorFields = []): self
$errorFields

the fields whose refusal is said under them; the others' is the form's own

FormDefinition::getEntityErrorFields()

public function getEntityErrorFields(): array

FormDefinition::getAttr()

public function getAttr(): array
Returns

the <form> element's attributes

FormDefinition::setAttr()

public function setAttr(array $attr): self

FormDefinition::getHostOptions()

public function getHostOptions(string $host = 'symfony'): array

Options only one host reads (Symfony's form options: 'validation_groups', 'allow_extra_fields'...): the escape hatch, ignored by the others.

FormDefinition::setHostOptions()

public function setHostOptions(array $options, string $host = 'symfony'): self

FormProcessor class

final class FormProcessor FormProcessor.php:35

A form's processing, neutral: bind what was sent (FormBinder), check the token (Omnibridge\Contract\Tokens), validate (Omnibridge\Contract\Validation: the data against what its class declares, each field's value against the field's constraints), then keep the data (Omnibridge\Persistence\UnitOfWork) when asked and valid. Each piece is optional: without Validation nothing is validated but what the binder could not read, without Tokens no token is made nor checked, without a unit of work nothing is kept. A form that asks for it (FormDefinition::setGuard()) goes through Base\Service\FormGuard when one is given: its trap and stamp are added to the view, what they say comes first; $translations says the guard's and the token's refusals.

$submission = $processor->handle($form, $request->request->all($form->getName()), $comment, persist: true); if ($submission->isValid()) { ... redirect ... } return render('comment.html.twig', ['form' => $submission->createView()]);

The Symfony form of a definition keeps Symfony's own processing (omnibridge/symfony); this one is the other hosts' (Laravel, plain PHP).

const CSRF_MESSAGE = 'The CSRF token is invalid. Please try to resubmit the form.'

Symfony's message for a missing or wrong token (its csrf_message).

FormProcessor::__construct()

public function __construct(readonly ?Validation $validation = null, readonly ?Tokens $tokens = null, readonly ?UnitOfWork $unitOfWork = null, ?FormBinder $binder = null, readonly ?FormGuard $guard = null, readonly ?Translations $translations = null)

FormProcessor::readers()

public static function readers(): void

omnibase's own rules, read as the kept constraints wherever a class declares them.

FormProcessor::createView()

public function createView(FormDefinition $form, mixed $data = null): FormView

The form's view before any submission: the data's values, a token.

FormProcessor::handle()

public function handle(FormDefinition $form, ?array $submitted, mixed $data = null, bool $persist = false, ?array $groups = null, ?string $address = null): FormSubmission

Handles a request's part for the form: null (or nothing under the form's name) is a form not submitted.

$submitted

the values under the form's name, files merged in

$groups

validation groups, the form's when null

$address

the visitor's address, for the guard's lists and counts

FormSubmission class

final class FormSubmission FormSubmission.php:12

A form handled by FormProcessor: whether it was submitted, the data with what was sent written into it, the violations (the binder's, the validator's, the token's), the button clicked, whether the data was kept.

public readonly FormDefinition $form
public readonly bool $submitted
public readonly mixed $data
public readonly array $values

the values the form shows again, by field name

public readonly array $violations
public readonly ?string $clicked
public readonly bool $persisted
public readonly ?string $token

FormSubmission::__construct()

public function __construct(public readonly FormDefinition $form, public readonly bool $submitted, public readonly mixed $data, public readonly array $values = [], public readonly array $violations = [], public readonly ?string $clicked = null, public readonly bool $persisted = false, public readonly ?string $token = null)
$values

the values the form shows again, by field name

FormSubmission::isSubmitted()

public function isSubmitted(): bool

FormSubmission::isValid()

public function isValid(): bool

FormSubmission::getClicked()

public function getClicked(): ?string

The action (FormDefinition::addAction()) whose button sent the form, null for none named.

FormSubmission::getErrors()

public function getErrors(): array

The messages by field name: a violation's path is its field's name (the first segment of a nested path, "" for the form's own when no field has that name).

FormSubmission::isTaken()

public function isTaken(string $field): bool

Whether the record's rules refused this field's value as already taken.

FormSubmission::withError()

public function withError(string $message, string $field = ''): self

The same submission refused with one more error: what the code that keeps the data says once the form holds (a spam, a record not found), as Symfony's FormInterface::addError() adds it. A field's name, or '' for the form's own.

FormSubmission::createView()

public function createView(?string $token = null): FormView

The view to render again: the values sent, their errors, a fresh token.

FormView class

final class FormView implements ArrayAccess, IteratorAggregate, Countable, JsonSerializable FormView.php:45

A form as a renderer reads it, neutral: a plain tree of views, each with its vars - name, full_name, id, kind, type (the input's HTML type), value, label and help (translatable keys), errors, attr, required, disabled, choices, multiple, checked - and its children by name. The root carries the method, the action and the token (a hidden child under FormDefinition::TOKEN_FIELD).

Its vars are named as Symfony's FormView names them, so a theme written for either reads both: the Twig theme (omnibridge/twig), the Blade theme (omnibridge/laravel), and React through toArray() (the page's props).

A rich kind's field also carries what its behaviour gives (Base\Field\Behaviour\Behaviours, the vars omnibase's Symfony type gives its block): widget, the block its markup is (datetimepicker, slug, select2...), webpack_entry, its settings (datetimepicker, select2..., data attributes in attr), and endpoints, the address of each route it calls on this host (null where the host has no such route).

public array $vars
public array $children = []
public bool $rendered = false
public readonly ?FormView $parent

FormView::__construct()

public function __construct(string $name, array $vars = [], public readonly ?FormView $parent = null)

FormView::of()

public static function of(FormDefinition $form, array $values = [], array $errors = [], ?string $token = null, bool $submitted = false, mixed $data = null): self

The view of a definition: one child per field (with the values shown and their errors), one per action, the token's hidden child.

$values

by field name (FormBinder::read() or Binding::$values)

$errors

by field name, "" for the form's own

$data

the data the form edits: a file field shows the record's stored files

FormView::add()

public function add(string $name, array $vars = []): self

FormView::createView()

public function createView(): self

What omnibase's FormProxy hands: a form whose view is made on demand.

FormView::isSelected()

public function isSelected(string $value): bool

Whether a choice value is selected by the view's value.

FormView::toArray()

public function toArray(): array

The view as plain data (a React page's props): vars and children, recursively.

FormView::jsonSerialize()

public function jsonSerialize(): array

FormView::offsetExists()

public function offsetExists(mixed $offset): bool

FormView::offsetGet()

public function offsetGet(mixed $offset): FormView

FormView::offsetSet()

public function offsetSet(mixed $offset, mixed $value): void

FormView::offsetUnset()

public function offsetUnset(mixed $offset): void

FormView::getIterator()

public function getIterator(): \ArrayIterator

FormView::count()

public function count(): int

Properties class

final class Properties Properties.php:11

Reads and writes a property of the data a form edits, the way Symfony's PropertyAccess does for a form's paths - getX()/x()/isX()/hasX() and setX(), a public property, an array's key, "." paths - without its property-info and type-info, which the core does not keep (bare --strict).

Properties::isReadable()

public static function isReadable(mixed $data, string $path): bool

Properties::get()

public static function get(mixed $data, string $path): mixed

The value at the path; throws \UnexpectedValueException when the data has no such property.

Properties::set()

public static function set(mixed &$data, string $path, mixed $value): void

Writes the value at the path (the data given by reference: an array is completed).

RecordRules class

final class RecordRules RecordRules.php:18

A record a valid form has just written into, held to its class's rules before it is kept - its uniqueness above all: a profile's new name that another account has (plan "omnibase agnostic", step F5c: the profile's editor answered 500 on the database's refusal, and signed the session out). The host's Validation says what it reads (Symfony's validator reads omnibase's UniqueEntity itself); a class-level uniqueness it said nothing about is asked as omnisense/ omnibridge's Unique, the record itself not counted as taken.

RecordRules::violations()

public static function violations(Validation $validation, object $record, ?array $groups = null): array

UniqueLookup class

final class UniqueLookup UniqueLookup.php:12

The lookup of Omnibridge\Validation\Constraint\Unique through the entities' repositories: whether another record than the one checked holds those values. What a host's Validation is given as $exists (omnibridge/symfony's, omnibridge/laravel's).

UniqueLookup::__construct()

public function __construct(readonly Repositories $repositories)

UniqueLookup::__invoke()

public function __invoke(string $class, array $criteria, ?object $record): bool

Base\Form\Model

CommentModel class

class CommentModel implements SpamProtectionInterface CommentModel.php:18

What the comment form (Base\Form\Type\CommentType) edits - not the entity (omnibase's FormFactory refuses an entity as form data): the name, the e-mail, the site, the text. It implements SpamProtectionInterface so omnibase's FormTypeSpamExtension sends it to Akismet; the score lands here, and toComment() carries it onto the Comment to save.

public ?string $name = null
public ?string $email = null
public ?string $website = null
public ?string $content = null
public ?User $author = null
public ?int $spamScore = null

CommentModel::forUser()

public static function forUser(?User $user): static

CommentModel::getSpamBlameable()

public function getSpamBlameable(): ?User

CommentModel::getSpamText()

public function getSpamText(): ?string

CommentModel::getSpamDate()

public function getSpamDate(): \DateTime

CommentModel::getSpamCallback()

public function getSpamCallback(int $score): void

CommentModel::toComment()

public function toComment(?Thread $thread, bool $autoApprove, string $class = Comment::class): Comment

The entity to save, Akismet's score applied (the state follows from it and from $autoApprove).

$class

a subclass of Comment, for a bundle that extends it

ContactModel class

class ContactModel extends AbstractModel ContactModel.php:16

What the contact form (Base\Form\Type\ContactType) sends: a name, an e-mail, a message, and as the form is set up a phone, a subject, attachments. website is the trap: left empty by people, filled by the robots that fill every field (isRobot()).

public ?string $name = null
public ?string $email = null
public ?string $phone = null
public ?string $subject = null
public ?string $message = null
public ?string $website = null

Left empty by people; filled by the robots that fill every field.

public array $attachments = []

ContactModel::getRecipient()

public function getRecipient(): ?Recipient

ContactModel::setAttachments()

public function setAttachments(?array $attachments): void

A form sent with no file hands null to its model, not an empty list: written straight into the property, that null stopped the request ("Cannot assign null to property ... of type array") on every message without an attachment.

ContactModel::isRobot()

public function isRobot(): bool

The trap was filled: thank it all the same, and send nothing.

SecurityLoginModel class

class SecurityLoginModel extends AbstractModel SecurityLoginModel.php:11

public $identifier
public $password

SecurityLoginTokenModel class

class SecurityLoginTokenModel extends AbstractModel SecurityLoginTokenModel.php:11

public $email

SecurityRegistrationModel class

class SecurityRegistrationModel extends AbstractModel SecurityRegistrationModel.php:13

public $email
public $plainPassword
public bool $agreeTerms

SettingModel class

class SettingModel extends AbstractModel SettingModel.php:7

public mixed $value

ThreadSearchModel class

class ThreadSearchModel extends AbstractModel ThreadSearchModel.php:11

public $parent_id
public $generic
public $title
public $excerpt
public $content

UserEditModel class

class UserEditModel UserEditModel.php:10

public $avatar
public $username
public $email

UserProfileModel class

class UserProfileModel extends AbstractModel UserProfileModel.php:11

public $email
public $plainPassword
public $avatar

UserSearchModel class

class UserSearchModel UserSearchModel.php:10

public $username

Base\Http

RequestsOf class

final class RequestsOf RequestsOf.php:14

The request contract (Omnibridge\Contract\Requests) out of what a constructor was given: the contract itself, or - deprecated until 6.0 - Symfony's RequestStack, wrapped in omnibridge/symfony's StackRequests (named as a string: the core never loads the bridge itself). Null stays null: a service built outside any host reads no request.

const SYMFONY = 'Omnibridge\Symfony\Contract\StackRequests'

RequestsOf::of()

public static function of(?object $requests): ?Requests

Base\Imagine

FilterInterface interface

interface FilterInterface extends FilterInterface FilterInterface.php:5

FilterInterface::__toString()

public function __toString()

Base\Imagine\Filter

FormatFilterInterface interface

interface FormatFilterInterface extends FilterInterface FormatFilterInterface.php:8

FormatFilterInterface::getStandardExtension()

public static function getStandardExtension(): string

FormatFilterInterface::getPath()

public function getPath(): ?string

FormatFilterInterface::setPath()

public function setPath(?string $path)

FormatFilterInterface::getFilters()

public function getFilters()

FormatFilterInterface::addFilter()

public function addFilter(FilterInterface $filter)

FormatFilterInterface::apply()

public function apply(ImageInterface $image): ImageInterface

Base\Imagine\Filter\Advanced

SanitizeFilter class

class SanitizeFilter implements FilterInterface SanitizeFilter.php:10

SanitizeFilter::__toString()

public function __toString()

SanitizeFilter::__construct()

public function __construct()

SanitizeFilter::apply()

public function apply(ImageInterface $image): ImageInterface

Base\Imagine\Filter\Basic

BackgroundFilter class

class BackgroundFilter implements FilterInterface BackgroundFilter.php:13

BackgroundFilter::__toString()

public function __toString()

BackgroundFilter::__construct()

public function __construct(ImagineInterface $imagine, array $options = [])

BackgroundFilter::getRGB()

public function getRGB($hashtag = true): string

BackgroundFilter::getAlpha()

public function getAlpha(): float

BackgroundFilter::getRGBA()

public function getRGBA($hashtag = true): string

BackgroundFilter::getPosition()

public function getPosition(): string

BackgroundFilter::getSize()

public function getSize(): ?array

BackgroundFilter::getXY()

public function getXY(ImageInterface $image): array

BackgroundFilter::apply()

public function apply(ImageInterface $image): ImageInterface

{@inheritdoc}

CropFilter class

class CropFilter implements FilterInterface CropFilter.php:13

CropFilter::__toString()

public function __toString()

CropFilter::__construct()

public function __construct(float $x = 0, float $y = 0, ?float $width = null, ?float $height = null, string $position = "lefttop")

CropFilter::isNormalized()

public function isNormalized(): bool

CropFilter::getPosition()

public function getPosition(): string

CropFilter::getSize()

public function getSize(?ImageInterface $image = null): array

CropFilter::getXY()

public function getXY(?ImageInterface $image = null): array

CropFilter::apply()

public function apply(ImageInterface $image): ImageInterface

DownscaleFilter class

class DownscaleFilter extends ScaleFilter DownscaleFilter.php:5

DownscaleFilter::__toString()

public function __toString()

DownscaleFilter::__construct()

public function __construct()

FixedFilter class

class FixedFilter implements FilterInterface FixedFilter.php:13

FixedFilter::__toString()

public function __toString()

FixedFilter::__construct()

public function __construct(array $options = [])

FixedFilter::apply()

public function apply(ImageInterface $image): ImageInterface

FlipFilter class

class FlipFilter implements FilterInterface FlipFilter.php:13

FlipFilter::__toString()

public function __toString()

FlipFilter::__construct()

public function __construct(array $options = [])

FlipFilter::apply()

public function apply(ImageInterface $image): ImageInterface

InterlaceFilter class

class InterlaceFilter implements FilterInterface InterlaceFilter.php:8

InterlaceFilter::__toString()

public function __toString()

InterlaceFilter::__construct()

public function __construct(string $mode = ImageInterface::INTERLACE_LINE)

InterlaceFilter::apply()

public function apply(ImageInterface $image): ImageInterface

PasteFilter class

class PasteFilter implements FilterInterface PasteFilter.php:10

PasteFilter::__toString()

public function __toString()

PasteFilter::__construct()

public function __construct(ImageInterface $destination, int $x = 0, int $y = 0)

PasteFilter::apply()

public function apply(ImageInterface $image): ImageInterface

ResampleFilter class

class ResampleFilter implements FilterInterface ResampleFilter.php:18

ResampleFilter::__toString()

public function __toString()

ResampleFilter::__construct()

public function __construct(ImagineInterface $imagine, array $options = [])

ResampleFilter::apply()

public function apply(ImageInterface $image): ImageInterface

ResizeFilter class

class ResizeFilter implements FilterInterface ResizeFilter.php:10

ResizeFilter::__toString()

public function __toString()

ResizeFilter::__construct()

public function __construct(?int $width = null, ?int $height = null)

ResizeFilter::getSize()

public function getSize(): array

ResizeFilter::apply()

public function apply(ImageInterface $image): ImageInterface

RotateFilter class

class RotateFilter implements FilterInterface RotateFilter.php:8

RotateFilter::__toString()

public function __toString()

RotateFilter::__construct()

public function __construct(int $angle = 0)

RotateFilter::apply()

public function apply(ImageInterface $image): ImageInterface

ScaleFilter class

class ScaleFilter implements FilterInterface ScaleFilter.php:11

ScaleFilter::__toString()

public function __toString()

ScaleFilter::__construct()

public function __construct(array $options = [], $dimensionKey = 'dim', $ratioKey = 'to', $absoluteRatio = true)

ScaleFilter::apply()

public function apply(ImageInterface $image): ImageInterface

ThumbnailFilter class

class ThumbnailFilter implements FilterInterface ThumbnailFilter.php:10

ThumbnailFilter::__construct()

public function __construct(?int $width = null, ?int $height = null, $mode = ImageInterface::THUMBNAIL_INSET, $filter = ImageInterface::FILTER_UNDEFINED)

ThumbnailFilter::__toString()

public function __toString()

ThumbnailFilter::apply()

public function apply(ImageInterface $image): ImageInterface

ThumbnailFilter::getWidth()

public function getWidth()

ThumbnailFilter::getHeight()

public function getHeight()

ThumbnailFilter::getMode()

public function getMode()

ThumbnailFilter::resize()

public function resize(BoxInterface $imageSize)

UpscaleFilter class

class UpscaleFilter extends ScaleFilter UpscaleFilter.php:5

UpscaleFilter::__toString()

public function __toString()

UpscaleFilter::__construct()

public function __construct()

WatermarkFilter class

class WatermarkFilter implements FilterInterface WatermarkFilter.php:12

WatermarkFilter::__toString()

public function __toString()

WatermarkFilter::__construct()

public function __construct(ImagineInterface $imagine, ImageInterface $watermark, array $options = [])

WatermarkFilter::apply()

public function apply(ImageInterface $image): ImageInterface

Base\Imagine\Filter\Basic\Definition

FullHighDefinitionFilter class

class FullHighDefinitionFilter extends ThumbnailFilter FullHighDefinitionFilter.php:8

FullHighDefinitionFilter::__toString()

public function __toString()

FullHighDefinitionFilter::__construct()

public function __construct($mode = ImageInterface::THUMBNAIL_INSET, $filter = ImageInterface::FILTER_UNDEFINED)

HighDefinitionFilter class

class HighDefinitionFilter extends ThumbnailFilter HighDefinitionFilter.php:8

HighDefinitionFilter::__toString()

public function __toString()

HighDefinitionFilter::__construct()

public function __construct($mode = ImageInterface::THUMBNAIL_INSET, $filter = ImageInterface::FILTER_UNDEFINED)

QuadHighDefinitionFilter class

class QuadHighDefinitionFilter extends ThumbnailFilter QuadHighDefinitionFilter.php:8

QuadHighDefinitionFilter::__toString()

public function __toString()

QuadHighDefinitionFilter::__construct()

public function __construct($mode = ImageInterface::THUMBNAIL_INSET, $filter = ImageInterface::FILTER_UNDEFINED)

StandardDefinitionFilter class

class StandardDefinitionFilter extends ThumbnailFilter StandardDefinitionFilter.php:8

StandardDefinitionFilter::__toString()

public function __toString()

StandardDefinitionFilter::__construct()

public function __construct($mode = ImageInterface::THUMBNAIL_INSET, $filter = ImageInterface::FILTER_UNDEFINED)

UltraHighDefinitionFilter class

class UltraHighDefinitionFilter extends ThumbnailFilter UltraHighDefinitionFilter.php:8

UltraHighDefinitionFilter::__toString()

public function __toString()

UltraHighDefinitionFilter::__construct()

public function __construct($mode = ImageInterface::THUMBNAIL_INSET, $filter = ImageInterface::FILTER_UNDEFINED)

Base\Imagine\Filter\Format

BitmapFilter class

class BitmapFilter implements BitmapFilterInterface BitmapFilter.php:10

BitmapFilter::getStandardExtension()

public static function getStandardExtension(): string

BitmapFilter::__toString()

public function __toString()

BitmapFilter::__construct()

public function __construct(?string $path = null, array $options = [], array $filters = [])

BitmapFilter::getFilters()

public function getFilters()

BitmapFilter::addFilter()

public function addFilter(FilterInterface $filter)

BitmapFilter::getPath()

public function getPath(): ?string

BitmapFilter::setPath()

public function setPath(?string $path)

BitmapFilter::getExtension()

public function getExtension()

BitmapFilter::apply()

public function apply(ImageInterface $image): ImageInterface

BitmapFilterInterface interface

interface BitmapFilterInterface extends FormatFilterInterface BitmapFilterInterface.php:7

SvgFilter class

class SvgFilter implements SvgFilterInterface SvgFilter.php:11

SvgFilter::getStandardExtension()

public static function getStandardExtension(): string

SvgFilter::__toString()

public function __toString()

SvgFilter::__construct()

public function __construct(?string $path = null, array $options = [], array $filters = [])

SvgFilter::getFilters()

public function getFilters()

SvgFilter::addFilter()

public function addFilter(FilterInterface $filter)

SvgFilter::getPath()

public function getPath(): ?string

SvgFilter::setPath()

public function setPath(?string $path)

SvgFilter::getExtension()

public function getExtension()

SvgFilter::apply()

public function apply(ImageInterface $image): ImageInterface

SvgFilterInterface interface

interface SvgFilterInterface extends FormatFilterInterface SvgFilterInterface.php:7

WebpFilter class

class WebpFilter extends WebOptimization implements BitmapFilterInterface WebpFilter.php:11

WebpFilter::getStandardExtension()

public static function getStandardExtension(): string

WebpFilter::__toString()

public function __toString()

WebpFilter::getFilters()

public function getFilters()

WebpFilter::addFilter()

public function addFilter(FilterInterface $filter)

WebpFilter::__construct()

public function __construct(?string $path = null, array $options = [], array $filters = [])

WebpFilter::getPath()

public function getPath(): ?string

WebpFilter::setPath()

public function setPath(?string $path)

WebpFilter::apply()

public function apply(ImageInterface $image): ImageInterface

Base\Imagine\Svg

Box class

class Box implements ImageBoxInterface Box.php:11

const TYPE_ABSOLUTE = 0
const TYPE_ASPECT_RATIO = 1
const TYPE_NONE = 2

Box::__construct()

public function __construct(int $width, int $height, int $type = self::TYPE_ABSOLUTE)

Box::__toString()

public function __toString(): string

Box::createTypeAbsolute()

public static function createTypeAbsolute(int $width, int $height): self

Box::createTypeAspectRatio()

public static function createTypeAspectRatio(int $width, int $height): self

Box::createTypeNone()

public static function createTypeNone(): self

Box::getType()

public function getType(): int
Returns

one of the SvgImageBox::TYPE_* constants

Box::getWidth()

public function getWidth(): int

Box::getHeight()

public function getHeight(): int

Box::scale()

public function scale($ratio): self

Box::increase()

public function increase($size): self

Box::contains()

public function contains(ImageBoxInterface $box, PointInterface $start = null): bool

Box::square()

public function square(): int

Box::widen()

public function widen($width): self

Box::heighten()

public function heighten($height): self

Effects class

class Effects implements EffectsInterface Effects.php:16

Effects::__construct()

public function __construct(DOMDocument $document)

Effects::gamma()

public function gamma($correction): self

Effects::negative()

public function negative(): self

Effects::grayscale()

public function grayscale(): self

Effects::colorize()

public function colorize(ColorInterface $color): self

Effects::sharpen()

public function sharpen(): self

Effects::blur()

public function blur($sigma = 1): self

Effects::brightness()

public function brightness($brightness): self

Effects::convolve()

public function convolve(Matrix $matrix): self

Image class

class Image extends AbstractImage Image.php:26

Image::__construct()

public function __construct(DOMDocument $document, MetadataBag $metadata)

Image::__destruct()

public function __destruct()

Image::__toString()

public function __toString(): string

Image::__clone()

public function __clone()

Assures the DOM document instance will be cloned too.

Image::getDomDocument()

public function getDomDocument(): DOMDocument

Returns the DOM document.

Image::copy()

public function copy(): self

Image::crop()

public function crop(PointInterface $start, BoxInterface $size): self

Image::paste()

public function paste(ImageInterface $image, PointInterface $start, $alpha = 100): self

Image::sanitize()

public function sanitize()

Image::resize()

public function resize(BoxInterface $size, $filter = ImageInterface::FILTER_UNDEFINED): self

Image::thumbnail()

public function thumbnail(BoxInterface $size, $settings = ImageInterface::THUMBNAIL_INSET, $filter = ImageInterface::FILTER_UNDEFINED): self

Image::rotate()

public function rotate($angle, ColorInterface $background = null): self

Image::save()

public function save($path = null, array $options = []): self

Image::show()

public function show($format, array $options = []): self

Image::get()

public function get($format, array $options = []): string

Image::flipHorizontally()

public function flipHorizontally(): self

Image::flipVertically()

public function flipVertically(): self

Image::strip()

public function strip(): self

Image::draw()

public function draw(): DrawerInterface

Image::effects()

public function effects(): Effects

Image::getSize()

public function getSize(): Box

Image::applyMask()

public function applyMask(ImageInterface $mask): self

Image::fill()

public function fill(FillInterface $fill): self

Image::mask()

public function mask(): self

Image::histogram()

public function histogram(): array

Image::getColorAt()

public function getColorAt(PointInterface $point): ColorInterface

Image::layers()

public function layers(): LayersInterface

Image::interlace()

public function interlace($scheme): self

Image::palette()

public function palette(): PaletteInterface

Image::profile()

public function profile(ProfileInterface $profile): self

Image::usePalette()

public function usePalette(PaletteInterface $palette): self

Imagine class

class Imagine extends AbstractImagine Imagine.php:17

Imagine::create()

public function create(ImageBoxInterface $size, ?ColorInterface $color = null): Image

Imagine::open()

public function open($path): Image

Imagine::load()

public function load($string): Image

Imagine::read()

public function read($resource): Image

Imagine::font()

public function font($file, $size, ColorInterface $color): FontInterface

Base\Mailer

MailTrap class

class MailTrap MailTrap.php:27

A hold-everything switch for outgoing mail, meant for the minutes after a hotfix when you are not yet sure the site is sending the right things to the right people.

While it is armed nothing leaves: each message is written to disk instead, where it can be read, deleted, or released once you have decided. That is the difference from simply stopping the worker - a stopped worker holds mail you cannot see, and a purge then means emptying the whole queue rather than the three messages that were wrong.

Deliberately file-backed rather than a database table or a setting: this has to work in exactly the situations where you distrust the application - a bad migration, a half-applied hotfix, a broken cache - so it must not need the schema to be sound, and it must survive a cache:clear. var/ persists across deploys here; var/cache does not.

MailTrap::__construct()

public function __construct(readonly string $directory)

MailTrap::isBypassed()

public function isBypassed(): bool

MailTrap::bypass()

public function bypass(callable $send): mixed

MailTrap::isArmed()

public function isArmed(): bool

MailTrap::armedDetails()

public function armedDetails(): ?array

MailTrap::arm()

public function arm(?string $reason = null): void

MailTrap::disarm()

public function disarm(): void

MailTrap::capture()

public function capture(RawMessage $message, Envelope $envelope): string

Writes one message aside instead of sending it.

The serialized message is kept alongside a readable summary: the summary is what an operator scans under pressure, the serialized form is what release() needs to send the real thing rather than a reconstruction of it.

MailTrap::all()

public function all(): array

MailTrap::read()

public function read(string $id): ?array

The held message, rebuilt as a transport can send it.

MailTrap::forget()

public function forget(string $id): bool

MailTrap::getDirectory()

public function getDirectory(): string

Base\Notifier

ContactMessage class

final class ContactMessage ContactMessage.php:13

The contact page's message, written once for every host (plan "omnibase agnostic", step F5e, slice 5b; formerly ContactController::Contact()'s submission): sent to the site's contact address (base.settings.mail.contact, else the technical recipient), its confirmation to the sender, then the page that says so.

const TEMPLATE = 'client/contact/index.html.twig'
const SENT = 'client/contact/success.html.twig'

ContactMessage::__construct()

public function __construct(readonly object $notifier)
$notifier

the notifier whose contactEmail() and contactEmailConfirmation() make both

ContactMessage::send()

public function send(ContactModel $message): Template

NotificationCenter class

final class NotificationCenter NotificationCenter.php:23

The notification center's page and the push subscriptions, written once for every host (plan "omnibase agnostic", step F5e, slice 5b; formerly NotificationController::Index(), PushConfig(), PushSubscribe(), PushUnsubscribe() and ServiceWorker()'s file; the bell's payload, read marks and removals are Base\Controller\Action\Notification's): - the page: a visitor signs in first; ?unread=1 narrows it in the query (the list stops at a hundred: hiding the read rows in the page showed an empty page to anyone whose last hundred were read while older ones waited); - push: the VAPID public key and whether a member may subscribe; a subscription kept or forgotten by the "notifications" token of the body (JSON, same origin), answered in JSON because the bell updates in place; - the service worker's source, served from the site's root (a worker's scope cannot exceed its own path).

const TOKEN = 'notifications'
const LIMIT = 100
const TEMPLATE = 'client/user/notifications.html.twig'
const SIGN_IN = 'security_login'
const SERVICE_WORKER = __DIR__ . '/../Resources/sw/sw.js'

NotificationCenter::__construct()

public function __construct(readonly Access $access, readonly Notifications $notifications, readonly WebPushService $webPush, readonly ?Tokens $tokens = null)

NotificationCenter::page()

public function page(bool $unreadOnly): Outcome|array

The page's notifications and the unread count, or where a visitor goes.

NotificationCenter::pushConfig()

public function pushConfig(): Json

What the browser needs before it can subscribe: the VAPID public key, or null when push is off.

NotificationCenter::subscribe()

public function subscribe(array $body, ?string $userAgent): Json
$body

{token, subscription: PushSubscriptionJSON}

NotificationCenter::unsubscribe()

public function unsubscribe(array $body): Json
$body

{token, endpoint}

NotificationCenter::body()

public static function body(string $content, array $form): array

A request's body: its JSON, else its form fields.

NotificationCenter::serviceWorker()

public static function serviceWorker(): string

The service worker's source.

NotificationLinkerInterface interface

interface NotificationLinkerInterface NotificationLinkerInterface.php:14

Turns a notification's target (class + id, see Notification::setTarget()) into a back-office URL. base-bundle ships a null implementation; the admin bundle replaces it with one that knows its CRUD routes, so a notification opened from the back-office lands on the record's edit page while the same notification on the front-end keeps its public URL.

NotificationLinkerInterface::adminUrl()

public function adminUrl(Notification $notification): ?string

Notifier class

class Notifier extends BaseNotifier implements NotifierInterface Notifier.php:15

Notifier::testEmail()

public function testEmail(User $user): Notification

Notifier::contactEmail()

public function contactEmail(ContactModel $contactModel)

Notifier::contactEmailConfirmation()

public function contactEmailConfirmation(ContactModel $contactModel)

Notifier::userAccountGoodbye()

public function userAccountGoodbye(User $user)

Notifier::userApprovalRequest()

public function userApprovalRequest(User $user)

Notifier::userApprovalConfirmation()

public function userApprovalConfirmation(User $user)

Notifier::accountCreated()

public function accountCreated(User $user, string $password)

An account made for someone (user:create): its username, its temporary password - to be changed at the first sign-in - and the way in.

Notifier::resetPasswordRequest()

public function resetPasswordRequest(User $user, Token $token)

Notifier::verificationEmail()

public function verificationEmail(User $user, Token $token)

Notifier::loginToken()

public function loginToken(User $user, Token $token)
public function loginLink(User $user, string $token, \DateTimeInterface $until): Notification

The sign-in link omniauth issued (plan "omniauth", QA4): its token in the address, only here - the table keeps its hash -, and until when it serves. The same e-mail as loginToken()'s.

Notifier::emailCode()

public function emailCode(User $user, string $code, \DateTimeInterface $until): Notification

The code of the second factor by e-mail omniauth drew (plan "omniauth", QA5: the table keeps its hash), and until when it serves.

Notifier::userWelcomeBack()

public function userWelcomeBack(User $user, Token $token)

NotifierInterface interface

interface NotifierInterface extends BaseNotifierInterface NotifierInterface.php:9

NotifierInterface::testEmail()

public function testEmail(User $user): Notification

NullNotificationLinker class

final class NullNotificationLinker implements NotificationLinkerInterface NullNotificationLinker.php:8

No back-office installed: there is no admin page to link to.

NullNotificationLinker::adminUrl()

public function adminUrl(Notification $notification): ?string

TestRecipient class

final class TestRecipient TestRecipient.php:18

Who the profiler's test e-mail is written to, written once for every host (plan "omnibase agnostic", step F5e, slice 5b; formerly ProfilerController::Email() and SendEmail()): the account signed in, else the technical recipient's account, found by its address, else an account made for the e-mail only (never kept), its address the technical recipient's, its username - where the application's account has one - the recipient's name.

Fixed on the way: the account was looked for by the recipient's name, and a Query's results handed on as if they were one account (a TypeError for a recipient written without a name).

TestRecipient::__construct()

public function __construct(readonly Access $access, readonly BaseNotifierInterface $notifier, readonly Users $users)

TestRecipient::recipient()

public function recipient(): object

Base\Notifier\Abstract

BaseNotificationInterface interface

interface BaseNotificationInterface BaseNotificationInterface.php:8

BaseNotificationInterface::__toPrune()

public function __toPrune(?RecipientInterface $recipient = null): SymfonyNotification

BaseNotificationInterface::render()

public function render()

The notification as a page: Symfony's Response under Symfony (Base\Entity\User\Notification gives Base\Bridge\Symfony\NotificationMessages::response()). Untyped since step C3f of the plan "omnibase agnostique", so that the interface names nothing of the framework; an implementation typed : Response stays compatible.

BaseNotificationInterface::send()

public function send(string $importance, RecipientInterface ...$recipients)

BaseNotifier class

abstract class BaseNotifier implements BaseNotifierInterface, LoggerAwareInterface BaseNotifier.php:55

BaseNotifier::__call()

public function __call($method, $arguments): mixed

BaseNotifier::getOptions()

public function getOptions(): array

BaseNotifier::getTestRecipients()

public function getTestRecipients(): array

BaseNotifier::getViews()

public function getViews(): Views

BaseNotifier::getEnvironment()

public function getEnvironment(): Environment

since omnisense/omnibase 4.x, removed at 6.0: getViews()

BaseNotifier::setUsers()

public function setUsers(Users $users): static

BaseNotifier::__construct()

public function __construct(SymfonyNotifierInterface $notifier, ChannelPolicyInterface $policy, UnitOfWork|EntityManagerInterface $unitOfWork, ParameterBagInterface $parameterBag, TranslatorInterface $translator, LocalizerInterface $localizer, AdvancedRouterInterface|Urls $router, Views|Environment $views, SettingBag $settingBag, bool $debug = false)
$unitOfWork

the entity manager is deprecated (until 6.0): adapted by UnitOfWorks

$views

Twig's environment is deprecated (until 6.0): wrapped in omnibridge/twig's TwigViews

BaseNotifier::getPolicy()

public function getPolicy(): ChannelPolicyInterface

BaseNotifier::hasLoopback()

public function hasLoopback(): bool

BaseNotifier::isTest()

public function isTest(Recipient $recipient): bool

BaseNotifier::getAdminRecipient()

public function getAdminRecipient($i = 0): ?RecipientInterface

BaseNotifier::getAdminRecipients()

public function getAdminRecipients(): array

BaseNotifier::getTechnicalRecipient()

public function getTechnicalRecipient(): Recipient

BaseNotifier::isMarkAsAdmin()

public function isMarkAsAdmin()

BaseNotifier::markAsAdmin()

public function markAsAdmin(bool $markAsAdmin, ?Notification $notification = null)

BaseNotifier::enable()

public function enable()

BaseNotifier::disable()

public function disable()

BaseNotifier::getTranslator()

public function getTranslator(): TranslatorInterface

BaseNotifier::setTranslator()

public function setTranslator(TranslatorInterface $translator)

BaseNotifier::getRouter()

public function getRouter(): AdvancedRouterInterface|Urls

BaseNotifier::setRouter()

public function setRouter(AdvancedRouterInterface|Urls $router)

BaseNotifier::getDefaultChannels()

public function getDefaultChannels(string $importance)

BaseNotifier::send()

public function send(SymfonyNotification $notification, RecipientInterface ...$recipients): void

BaseNotifier::sendUsers()

public function sendUsers(Notification $notification, RecipientInterface ...$recipients)
Throws

Exception

BaseNotifier::sendUsersBy()

public function sendUsersBy(array $channels, Notification $notification, ...$recipients)

BaseNotifier::sendAdmins()

public function sendAdmins(Notification $notification)

BaseNotifierInterface interface

interface BaseNotifierInterface extends NotifierInterface BaseNotifierInterface.php:11

BaseNotifierInterface::sendUsers()

public function sendUsers(Notification $notification, Recipient ...$recipients)

BaseNotifierInterface::sendUsersBy()

public function sendUsersBy(array $channels, Notification $notification, Recipient ...$recipients)

BaseNotifierInterface::sendAdmins()

public function sendAdmins(Notification $notification)

BaseNotifierInterface::getTestRecipients()

public function getTestRecipients(): array

BaseNotifierInterface::getAdminRecipients()

public function getAdminRecipients(): array

BaseNotifierInterface::getTechnicalRecipient()

public function getTechnicalRecipient(): ?Recipient

BaseNotifierInterface::hasLoopback()

public function hasLoopback(): bool

BaseNotifierInterface::isTest()

public function isTest(Recipient $recipient): bool

BaseNotifierInterface::getPolicy()

public function getPolicy(): ChannelPolicyInterface

BaseNotifierInterface::getOptions()

public function getOptions(): array

BaseNotifierInterface::getTranslator()

public function getTranslator(): TranslatorInterface

BaseNotifierInterface::getViews()

public function getViews(): \Omnibridge\Contract\Views

The views the mails and pages render through (getEnvironment(), Twig's, until step F5a).

BaseNotifierInterface::enable()

public function enable()

BaseNotifierInterface::disable()

public function disable()

Base\Notifier\Channel

BrowserPlusChannel class

final class BrowserPlusChannel implements ChannelInterface BrowserPlusChannel.php:19

A notification shown once on the visitor's next page: a flash message of its importance, through the request contract (plan "omnibase agnostic", F5c: Symfony's flash bag, Laravel's session). Nothing outside a request; the same message twice under one type is shown once.

BrowserPlusChannel::__construct()

public function __construct(Requests|RequestStack|null $requests)
$requests

Symfony's RequestStack is deprecated (until 6.0)

BrowserPlusChannel::supports()

public function supports(Notification $notification, RecipientInterface $recipient): bool

BrowserPlusChannel::notify()

public function notify(Notification $notification, RecipientInterface $recipient, ?string $transportName = null): void

EmailPlusChannel class

final class EmailPlusChannel extends EmailChannel EmailPlusChannel.php:16

InAppChannel class

class InAppChannel implements ChannelInterface InAppChannel.php:30

The "inapp" channel: keeps a copy of the notification in the recipient's notification list (userNotification), which is what the bell in the toolbar and the back-office reads. Nothing else in the notifier persists a Notification - it is built, sent over its channels and dropped - so this channel is the one place a notification becomes a row.

One row per user: the notifier calls a channel once per recipient with the same Notification object, so the object itself cannot be the row (it has a single user). A detached copy is stored instead, carrying only what the list needs. Recipients that are not users (anonymous newsletter subscribers) have no list to write to and are skipped.

InAppChannel::__construct()

public function __construct(UnitOfWork|EntityManagerInterface $unitOfWork, protected readonly Users $users)
$unitOfWork

the entity manager is deprecated (until 6.0): adapted by UnitOfWorks

InAppChannel::supports()

public function supports(SymfonyNotification $notification, RecipientInterface $recipient): bool

Always true - see PushChannel::supports(). Symfony's Notifier throws on false instead of skipping the channel, so a recipient that is not a user (a plain newsletter e-mail address) would abort the whole send. notify() already ignores non-user recipients and foreign notification classes.

InAppChannel::notify()

public function notify(SymfonyNotification $notification, RecipientInterface $recipient, ?string $transportName = null): void

InAppChannel::userOf()

public function userOf(RecipientInterface $recipient): ?User

PushChannel class

class PushChannel implements ChannelInterface PushChannel.php:16

The "push" channel: a Web Push message to every browser the recipient enabled notifications in. Silent when VAPID keys are not configured or the recipient is not a user, so a policy can list it unconditionally.

PushChannel::__construct()

public function __construct(protected readonly WebPushService $webPush, protected readonly InAppChannel $inApp)

PushChannel::supports()

public function supports(SymfonyNotification $notification, RecipientInterface $recipient): bool

Always true, and that is the whole point of "silent".

Symfony's Notifier does not skip a channel whose supports() returns false: it throws LogicException('The "push" channel is not supported.') and aborts the ENTIRE send. This used to return isConfigured() && a user, so on a host without VAPID keys every "notify" send threw. In production that killed thread:publishable on every run - the announcement runs inside the cron's flush, the exception rolled the whole transaction back, and a scheduled article stayed unpublished, retried and rolled back every 5 minutes. The "nothing to do" cases are handled in notify() instead.

PushChannel::notify()

public function notify(SymfonyNotification $notification, RecipientInterface $recipient, ?string $transportName = null): void

Base\Notifier\Mail

EmailComposer class

final class EmailComposer EmailComposer.php:28

omnibase's e-mails, written the same way under every host (plan "omniauth", step AU8b; R26 of the master plan's gaps): a notification's template rendered by Twig in the e-mail frame, its subject the page's <title>, its embedded pictures as inline parts. Framework-free: the views through omnibridge's Views (plan "omnibase agnostic", step F5a: Twig's environment through omnibridge/twig's TwigViews, or any engine that has omnibase's templates) and symfony/mime, which every host has (Laravel's mail is Symfony's Mailer). The text part is written here, in PHP.

Under Symfony Base\Bridge\Symfony\NotificationMessages::email() writes a notification's e-mail with render() and alias() - the same lines it had -; compose() writes an e-mail the same way without a notification and without Symfony's Notifier, for a host that has neither (omnibridge/laravel): what the Notifier's e-mail is for a notification with no attachment, sent to its account (not a test address, not forwarded to the administrators).

const FRAME = '@Base/notifier/email.html.twig'

The e-mail frame: the HTML of a notification whose template is missing or not found.

const BODY = '@Base/notifier/raw.html.twig'

The e-mail's body: the HTML rendered, as it is (TemplatedEmail's htmlTemplate under Symfony).

const TEXT = "{% autoescape false %}{% block lead %}\n{{ subject }}\n{% endblock %}\n\n{% block content %}\n{{ content }}\n{% endblock %}\n\n{% block action %}\n{% if act…

The e-mail's text: Symfony's Twig bridge's notification text (@email/zurb_2/notification/body.txt.twig, which NotificationEmail renders under Symfony), its subject, then its notification's content - the text part is not the HTML's. Kept as the reference text() writes (EmailComposerTest renders both); no view engine renders it any more.

const TEST_PREFIX = "Test: "

Before the subject of an e-mail to a test address.

EmailComposer::__construct()

public function __construct(Views|Environment $views, readonly string|\Closure|null $from, readonly ?\Closure $isTest = null, readonly ?\Closure $trans = null, readonly ?\Closure $globals = null)
$from

the sender: the technical address (the Notifier's getTechnicalRecipient()); null where the host has none configured (base.notifier.technical_recipient.email), refused when an e-mail is composed

$isTest

whether an e-mail to that address goes to the technical address instead (the Notifier's isTest(): base.notifier.technical_loopback, test_recipients)

$trans

the words of a test e-mail (@emails.fake_test.*)

$globals

what the templates read as globals where the host's Twig has none of omnibase's (app: MailVariables)

$views

the views; Twig's environment is deprecated (until 6.0), wrapped in omnibridge/twig's TwigViews

EmailComposer::views()

public static function views(Views|Environment $views): Views

The views, Twig's environment (deprecated) wrapped in omnibridge/twig's TwigViews.

EmailComposer::text()

public static function text(string $subject, string $content): string

The e-mail's text part: its subject, then its notification's content, as Symfony's notification text template writes them with no action and no exception (TEXT, rendered by Twig until step F5a).

EmailComposer::testAddress()

public static function testAddress(string $technical, string $to, \Closure $trans): string

Who an e-mail to a test address goes to: the technical address, under the recipient's name, marked as a test ("[Test] Anne <support@...>").

EmailComposer::testFooter()

public static function testFooter(?string $footer, \Closure $trans): string

A test e-mail's footer: the notice that it is one after it.

EmailComposer::technicalAddress()

public static function technicalAddress(?string $mail, ?string $mailName, string $default): string

The technical address as the Notifier writes it (getTechnicalRecipient()): the settings' base.settings.mail and its name, else the parameter's address (base.notifier.technical_recipient.email), named after its own name or its local part. The administrators' first address, which the Notifier tries between the two, is not asked here.

EmailComposer::render()

public static function render(Views|Environment $views, ?string $template, array $parameters): array

The template rendered with its parameters - in the frame when it is not found -, and the subject its <title> gives (null without one).

EmailComposer::alias()

public static function alias(Email $email, string $html): string

The e-mail's embedded parts renamed (a random name, its extension kept), and the HTML's cid: addresses with them.

EmailComposer::compose()

public function compose(string $to, ?string $template, array $parameters, string $content = '', string $subject = '', mixed $recipient = null): Email

An e-mail to $to, written as the Notifier writes a notification's: the context it gives the template (raw, warmup, title, content, footer_text, recipient), the template's own parameters over it, the e-mail's pictures embedded (email: InlineImages, what WrappedTemplatedEmail is under Symfony), the subject from the page's <title> (else $subject), the body the frame's raw template prints, and its text the notification's subject and content (TEXT), as NotificationEmail's.

$parameters

the template's own (Notification::setHtmlParameters())

InlineImages class

final class InlineImages InlineImages.php:20

The email an e-mail's template is given where Symfony's Twig bridge is not (EmailComposer::compose()): a picture of the template's paths embedded as an inline part, its cid: address returned - what Symfony\Bridge\Twig\Mime\WrappedTemplatedEmail::image() does, which omnibase's embed() asks for. The picture is found by the views' engine (omnibridge's ViewSources: Twig's loader through TwigViews), since step F5a.

InlineImages::__construct()

public function __construct(Views|Environment $views, readonly Email $message)
$views

Twig's environment is deprecated (until 6.0)

InlineImages::image()

public function image(string $image, ?string $contentType = null, ?string $name = null): string

InlineImages::getSubject()

public function getSubject(): ?string

MailVariables class

final class MailVariables MailVariables.php:19

What omnibase's e-mail templates read of app (the site's email.html.twig: app.site.domain, app.site.logo, app.email.title, app.email.age...), for a host whose Twig has no omnibase AppVariable (omnibridge/laravel): the same settings read the same way as SiteVariable and EmailVariable read them under Symfony - the site's logo, the e-mails' title, slogan and logo (each the site's when the e-mails have none of their own), the contact address, the years since the launch (Launcher::since()), the request's domain. EmailComposer gives it to the template as app, where the host has no such global.

public readonly object $site
public readonly object $email

MailVariables::__construct()

public function __construct(SettingBagInterface $settings, \Closure $domain, ?\Closure $homepage = null)
$domain

the request's domain (AdvancedRouter::getDomain()), null outside a request

$homepage

the site's index address (EmailVariable::homepage())

SignInMails class

final class SignInMails SignInMails.php:29

The e-mails of signing in - the sign-in link, the second factor's code, "welcome back" to a disabled account, a sign-in from a new device - with the words and templates omnibase's Notifier gives them (plan "omniauth", step AU8b; R26 of the master plan's gaps).

Their words are said once, here: Base\Notifier\Notifier::loginLink(), emailCode() and userWelcomeBack() take their template's parameters from the *Parameters() functions, as Base\Auth\Listener\WarnNewDevice takes the new device's template. Under Symfony the Notifier sends them (its channels, its loopback); under a host without Symfony's Notifier (omnibridge/laravel) this class writes them with EmailComposer - the same template, parameters, frame and subject - and sends them through symfony/mailer's MailerInterface, the contract both hosts' mailers answer (Laravel's mail is Symfony's Mailer: omnibridge/laravel's adapter).

const NEW_DEVICE_TEMPLATE = '@Base/client/email/security_newDevice.html.twig'
const WELCOME_BACK_ROUTE = 'security_accountWelcomeBackWithToken'

SignInMails::__construct()

public function __construct(readonly EmailComposer $composer, readonly MailerInterface $mailer, readonly Translations $translations, readonly Urls $urls)

SignInMails::loginLinkParameters()

public static function loginLinkParameters(\Closure $trans, \Closure $duration, string $url, \DateTimeInterface $until): array

The sign-in link's template parameters (Notifier::loginLink()).

$duration

a duration spelled (Translator::transTime())

SignInMails::emailCodeParameters()

public static function emailCodeParameters(\Closure $trans, \Closure $duration, string $code, \DateTimeInterface $until): array

The second factor's code's template parameters (Notifier::emailCode()).

SignInMails::welcomeBackParameters()

public static function welcomeBackParameters(\Closure $trans, User $user, string $url): array

"Welcome back"'s template parameters (Notifier::userWelcomeBack()).

SignInMails::newDeviceParameters()

public static function newDeviceParameters(User $user, Connection $connection): array

The new device's template parameters (WarnNewDevice).

public function loginLink(User $user, string $token, \DateTimeInterface $until): void

SignInMails::emailCode()

public function emailCode(User $user, string $code, \DateTimeInterface $until): void

SignInMails::welcomeBack()

public function welcomeBack(User $user, Token $token): void

SignInMails::newDevice()

public function newDevice(User $user, Connection $connection): void

Base\Notifier\Recipient

LocaleRecipientInterface interface

interface LocaleRecipientInterface extends RecipientInterface LocaleRecipientInterface.php:7

LocaleRecipientInterface::getLocale()

public function getLocale(): string

LocaleRecipientTrait trait

trait LocaleRecipientTrait LocaleRecipientTrait.php:5

LocaleRecipientTrait::getLocale()

public function getLocale(): string

Recipient class

class Recipient extends Recipient implements LocaleRecipientInterface, TimezoneRecipientInterface Recipient.php:7

Recipient::__toString()

public function __toString()

Recipient::__construct()

public function __construct(?string $email = null, ?string $phone = null, ?string $locale = null, ?string $timezone = null)

Recipient::locale()

public function locale(string $locale): self

Recipient::timezone()

public function timezone(string $timezone): self

TimezoneRecipientInterface interface

interface TimezoneRecipientInterface extends RecipientInterface TimezoneRecipientInterface.php:7

TimezoneRecipientInterface::getTimezone()

public function getTimezone(): string

TimezoneRecipientTrait trait

trait TimezoneRecipientTrait TimezoneRecipientTrait.php:5

TimezoneRecipientTrait::getTimezone()

public function getTimezone(): string

Base\Repository

Aliases class

final class Aliases Aliases.php:14

The core's repositories by their interfaces (audit "lesringostars face au master plan", steps R15 and R27): what the code of a site and of the core type-hints, Doctrine's repository behind - one list, which Symfony's container aliases (config/services/database.php) and omnibridge/laravel binds, as a site's own repositories declare theirs by #[AsAlias]. The users' is the application's (App\Repository\UserRepository: the site's own, else omnibase's under that name).

const INTERFACES = [ Users::class => 'App\Repository\UserRepository', Threads::class => ThreadRepository::class, Thread\Tags::class => Thread\TagRepository::class, …

ThreadTranslations interface

interface ThreadTranslations extends Entities ThreadTranslations.php:18

The threads' translations, as the site-wide search reads them (audit "lesringostars face au master plan", step R28; see Base\Database\Repository\Entities): ThreadIntlRepository's query, which the core's ThreadSearchController and an application's search (lesringostars' App\Action\Search\Results) wrote by hand on a query builder before.

public function search(array $terms, array $states = [], Thread|int|string|null $parent = null): array

The translations whose fields hold their term, any of them - (title OR excerpt OR content), each compared lower-cased with LIKE '%term%' -, of threads in one of $states (any when empty), under $parent when given.

No term, no translation (not LIKE '%%', the whole site).

$terms

field (title, excerpt, content) => term; empty or non-text terms are left out

$parent

the parent thread or its id

Threads interface

interface Threads extends Entities Threads.php:26

What a site asks of its threads (a destination, an article, a gallery, a calendar...): the one of a slug, of a parent, of a state, the ones under a parent, the previous and the next by publication. The interface the code of an application and of the core is given (audit "lesringostars face au master plan", step R15; see Base\Database\Repository\Entities); Doctrine's ThreadRepository answers it, and every site repository extending it.

Nothing of the ORM in or out: $states is a state of Base\Enum\ThreadState or a list of them (an empty list: any state), $orderBy field => ASC|DESC, a thread or null, a list of threads, an integer. ThreadRepository answers each through its finder (cacheOneBySlug()...), the queries it ran before: the same SQL, its results cached the same way.

Threads::oneBySlug()

public function oneBySlug(string $slug, bool $cached = true): ?Thread
Returns

through the finder's cache unless $cached is false (a row about to be locked)

Threads::oneBySlugAndState()

public function oneBySlugAndState(?string $slug, array|string $states, array $orderBy = []): ?Thread

The first in that order of these states, of that slug when one is given (no slug: of any) - a page's thread from its address, which may name none.

Threads::oneByState()

public function oneByState(array|string $states, array $orderBy = []): ?Thread

Threads::first()

public function first(array $orderBy): ?Thread
Returns

the first of all in that order

Threads::byState()

public function byState(array|string $states, array $orderBy = []): array

Threads::byStates()

public function byStates(array $states): array

Every one in one of these states, in no order, read afresh (not from the result cache): what a crawler may list.

Threads::byStateUncached()

public function byStateUncached(array|string $states): array

The threads in a state, read again from the database - no result cache (step R28: thread:publishable, which must see what was just published).

Threads::oneByParentAndSlugAndState()

public function oneByParentAndSlugAndState(?Thread $parent, string $slug, array|string $states, array $orderBy = []): ?Thread

Threads::byParentAndState()

public function byParentAndState(?Thread $parent, array|string $states, array $orderBy = [], ?int $limit = null, ?int $offset = null): array

Threads::byParentAndStatePublishedWithin()

public function byParentAndStatePublishedWithin(?Thread $parent, array|string $states, string $within, array $orderBy = []): array

Those published within $within of now (a relative date: "+8 days").

Threads::oneByStateAndSlugStartingWith()

public function oneByStateAndSlugStartingWith(array|string $states, string $prefix): ?Thread

Threads::countByStatePublishedYoungerThan()

public function countByStatePublishedYoungerThan(array|string $states, int|string $age): int

How many were published less than $age ago (seconds, or a relative date).

Threads::previousOne()

public function previousOne(array $at, array|string $states, ?string $class = null): ?Thread

The one before $at by its field (['publishedAt' => $date]), of the class $class exactly when one is given.

Threads::nextOne()

public function nextOne(array $at, array|string $states, ?string $class = null): ?Thread

Threads::getHierarchy()

public function getHierarchy($id = -1, ?string $separator = null)

The level of the class's #[Hierarchify] (the last one by default).

Users interface

interface Users extends Entities Users.php:17

The accounts (audit "lesringostars face au master plan", step R15; see Base\Database\Repository\Entities). UserRepository answers it - an application's App\Repository\UserRepository with it -, besides what it declares to Security (Base\Contract\SecurityUserLoader and SecurityUserProvider, R2).

Users::oneByUsername()

public function oneByUsername(string $username, bool $cached = true): ?User

The account of a username, through the finder's cache unless $cached is false.

Users::oneByEmail()

public function oneByEmail(?string $email): ?User

The account of an address, read from the database (step R28: sign-in, links, OAuth).

Users::byIds()

public function byIds(array $ids): array

The accounts of these ids, through the finder's cache (step R28: the mentions).

Users::activeWithin()

public function activeWithin(int $seconds, ?int $exceptId = null): array

The accounts active within the last $seconds, but $exceptId's (step R28: the presence count), read from the database.

Users::oneById()

public function oneById(int $id): ?User

The account of an id, through the finder's cache (step R28: the profile pages).

Users::byRoles()

public function byRoles(array|string $roles): array

The accounts holding one of these roles in their own roles (step R28: the notifier's administrators), through the finder's cache.

Users::byUsernameContaining()

public function byUsernameContaining(string $term, int $limit = 50): array

The accounts whose username holds $term, case-insensitive, by username, at most $limit (step R28: the members' search). An application whose accounts have no username gets none.

Users::findActiveAdmins()

public function findActiveAdmins(int $onlineDelay, ?int $excludeId = null): array

Other administrators active within the last $onlineDelay seconds, the most recently active first.

Base\Repository\Analytics

PageViews interface

interface PageViews extends Entities PageViews.php:16

The pages' views, by day and hour (audit "lesringostars face au master plan", step R28; see Base\Database\Repository\Entities): PageViewRepository answers it with the queries its callers ran by name before.

PageViews::incrementView()

public function incrementView(string $path, \DateTimeImmutable $date, string $source = PageView::SOURCE_HUMAN): void

PageViews::countViews()

public function countViews(?string $path = null, ?\DateTimeImmutable $since = null, ?string $source = null): int

PageViews::earliestDate()

public function earliestDate(): ?\DateTimeImmutable

PageViews::dailyBreakdown()

public function dailyBreakdown(\DateTimeImmutable $since, string|array|null $path = null): array

PageViews::dailyBreakdownBySource()

public function dailyBreakdownBySource(\DateTimeImmutable $since, string|array|null $path = null): array

PageViews::hourlyBreakdown()

public function hourlyBreakdown(\DateTimeImmutable $since, string|array|null $path = null): array

PageViews::hourlyBreakdownBySource()

public function hourlyBreakdownBySource(\DateTimeImmutable $since, string|array|null $path = null): array

PageVisits interface

interface PageVisits extends Entities PageVisits.php:16

The presence on each page, by day and hour (audit "lesringostars face au master plan", step R28; see Base\Database\Repository\Entities): PageVisitRepository answers it with the queries its callers ran by name before.

PageVisits::recordPresence()

public function recordPresence(string $path, string $subjectType, string $subjectId, \DateTimeImmutable $date): void

PageVisits::countUnique()

public function countUnique(?\DateTimeImmutable $since = null, string|array|null $path = null): int

PageVisits::dailyBreakdown()

public function dailyBreakdown(\DateTimeImmutable $since, string|array|null $path = null): array

PageVisits::hourlyBreakdown()

public function hourlyBreakdown(\DateTimeImmutable $since, string|array|null $path = null): array

Visits interface

interface Visits extends Entities Visits.php:16

The visitors' and members' presence, by day and hour (audit "lesringostars face au master plan", step R28; see Base\Database\Repository\Entities): VisitRepository answers it with the queries its callers ran by name before.

Visits::recordPresence()

public function recordPresence(string $subjectType, string $subjectId, \DateTimeImmutable $date): void

Visits::countUnique()

public function countUnique(string $subjectType, ?\DateTimeImmutable $since = null): int

Visits::returning()

public function returning(string $subjectType, \DateTimeImmutable $previousSince, \DateTimeImmutable $currentSince): array

Visits::dailyBreakdown()

public function dailyBreakdown(string $subjectType, \DateTimeImmutable $since): array

Visits::hourlyBreakdown()

public function hourlyBreakdown(string $subjectType, \DateTimeImmutable $since): array

Base\Repository\Extension

Revisions interface

interface Revisions extends Entities Revisions.php:15

The entities' revisions (audit "lesringostars face au master plan", step R28; see Base\Database\Repository\Entities): an entity's history, as VersionManager reads it - RevisionRepository's query.

Revisions::history()

public function history(string $entityClass, int $entityId, ?int $limit = null): array
Returns

the newest first

TrashBalls interface

interface TrashBalls extends Entities TrashBalls.php:15

The trash (audit "lesringostars face au master plan", step R28; see Base\Database\Repository\Entities): what TrashManager and the purge ask of it, TrashBallRepository's queries.

TrashBalls::contents()

public function contents(?string $entityClass = null, ?int $limit = null, int $offset = 0): array
Returns

the newest first, of one class when given

TrashBalls::countContents()

public function countContents(?string $entityClass = null): int

TrashBalls::expired()

public function expired(?\DateTimeInterface $now = null, ?int $limit = null): array
Returns

past their grace period at $now (now when null), the oldest first

Base\Repository\Hours

ScopedWeeks interface

interface ScopedWeeks extends Entities ScopedWeeks.php:15

The opening weeks of the places that have their own (audit "lesringostars face au master plan", step R28; see Base\Database\Repository\Entities): ScopedWeekRepository answers it with the queries its callers ran by name before.

ScopedWeeks::ofScope()

public function ofScope(string $scope): ?ScopedWeek

ScopedWeeks::week()

public function week(string $scope): ?array

ScopedWeeks::save()

public function save(string $scope, array $week): ScopedWeek

ScopedWeeks::forget()

public function forget(string $scope): void

SpecialDays interface

interface SpecialDays extends Entities SpecialDays.php:15

The special days (closures, other hours) (audit "lesringostars face au master plan", step R28; see Base\Database\Repository\Entities): SpecialDayRepository answers it with the queries its callers ran by name before.

SpecialDays::upcoming()

public function upcoming(\DateTimeInterface $from, int $limit = 50, ?string $scope = null): array
Returns

from $from on, the nearest first

WeekDays interface

interface WeekDays extends Entities WeekDays.php:15

The site's opening week, day by day (audit "lesringostars face au master plan", step R28; see Base\Database\Repository\Entities): WeekDayHoursRepository answers it with the queries its callers ran by name before.

WeekDays::week()

public function week(): array

WeekDays::save()

public function save(array $week): void

Base\Repository\Layout

ImageCrops interface

interface ImageCrops extends Entities ImageCrops.php:15

The crops of the stored images (audit "lesringostars face au master plan", step R28; see Base\Database\Repository\Entities): ImageCropRepository answers it with the queries its callers ran by name before.

ImageCrops::oneBySlugOfImage()

public function oneBySlugOfImage(string $slug, string $source): ?ImageCrop

The crop of this slug of the image stored at $source, through the finder's cache.

ImageCrops::oneClosestToRatio()

public function oneClosestToRatio(float|int $ratio0, string $source): ?ImageCrop

The crop of the image stored at $source whose ratio (width0 / height0) is the closest to $ratio0, through the finder's cache.

ImageCrops::oneClosestToRatioAndSize()

public function oneClosestToRatioAndSize(float|int $ratio0, float|int $width0, float|int $height0, string $source): ?ImageCrop

The crop of the image stored at $source the closest to this ratio, then width, then height (fractions of the image's).

Redirections interface

interface Redirections extends Entities Redirections.php:16

The redirections (audit "lesringostars face au master plan", step R28; see Base\Database\Repository\Entities): RedirectionRepository answers it with the queries its callers ran by name before.

Redirections::forAddress()

public function forAddress(string $address): ?Redirection

The redirection that answers this address, if any.

Redirections::hit()

public function hit(Redirection $redirection): void

Counts a use of the redirection.

Semantics interface

interface Semantics extends Entities Semantics.php:15

The semantic links of the texts (audit "lesringostars face au master plan", step R28; see Base\Database\Repository\Entities): SemanticRepository answers it with the queries its callers ran by name before.

Semantics::every()

public function every(): array

Every semantic link, through the finder's cache.

Settings interface

interface Settings extends Entities Settings.php:15

The settings stored in the database (audit "lesringostars face au master plan", step R15; see Base\Database\Repository\Entities), with what SettingBag reads through the finder (step R28).

Settings::under()

public function under(?string $path, bool $linkedBagOnly = false, bool $cached = true): array

The settings whose path starts with $path (every setting when null), only those linked to a bag when $linkedBagOnly, through the finder's cache unless $cached is false (step R28: SettingBag's finders).

Settings::oneByInsensitivePath()

public function oneByInsensitivePath(string $path): ?Setting

The setting of this path, compared case-insensitively.

Widgets interface

interface Widgets extends Entities Widgets.php:15

The widgets by their paths (audit "lesringostars face au master plan", step R28; see Base\Database\Repository\Entities): what WidgetProvider asks, through the finder's result cache unless told otherwise.

Widgets::oneByPath()

public function oneByPath(string $path, bool $cached = true): ?Widget

Widgets::every()

public function every(bool $cached = true): array

Base\Repository\Layout\Widget

Slots interface

interface Slots extends Entities Slots.php:15

The widgets' slots by their paths (audit "lesringostars face au master plan", step R28; see Base\Database\Repository\Entities): what WidgetProvider asks, through the finder's result cache unless told otherwise.

Slots::oneByPath()

public function oneByPath(string $path, bool $cached = true): ?Slot

Slots::every()

public function every(bool $cached = true): array

Base\Repository\Thread

Comments interface

interface Comments extends Entities Comments.php:17

The comments of the threads (audit "lesringostars face au master plan", step R28; see Base\Database\Repository\Entities): CommentRepository answers it with the queries its callers ran by name before. Since the plan "omnibase agnostic"'s step E2', what omnibase/blog and omnibase/video ask of it too (the comments online and waiting).

Comments::findLastFromIp()

public function findLastFromIp(string $ip): ?Comment

The newest comment written from an address (FormGuard's flood check).

Comments::findVisible()

public function findVisible(?Thread $thread, int $limit = 200): array

The comments online under a thread - or the visitors' book when $thread is null -, the top-level ones, newest first; their replies hang under each (Comment::getVisibleReplies()). A thread in the trash keeps its comments: the thread is compared by its key, not through a join the trash scopes.

Comments::countVisible()

public function countVisible(?Thread $thread): int

How many comments are online under a thread, replies included (the visitors' book for null).

Comments::countPending()

public function countPending(): int

How many comments wait for moderation.

Comments::findPending()

public function findPending(int $limit = 20): array

The comments waiting for moderation, oldest first.

Likes interface

interface Likes extends Entities Likes.php:17

The likes of the threads (audit "lesringostars face au master plan", step R28; see Base\Database\Repository\Entities): LikeRepository answers it with the queries its callers ran by name before.

Likes::oneByThreadAndUser()

public function oneByThreadAndUser(Thread $thread, ?User $user): ?Like

A member's like of a thread, read from the database (no result cache: the like's own page writes it).

Mentions interface

interface Mentions extends Entities Mentions.php:16

The mentions of members in the threads (audit "lesringostars face au master plan", step R28; see Base\Database\Repository\Entities): MentionRepository answers it with the queries its callers ran by name before.

Mentions::byThread()

public function byThread(Thread $thread): array

A thread's mentions, through the finder's cache.

Tags interface

interface Tags extends Entities Tags.php:17

A site's tags by their slugs (audit "lesringostars face au master plan", step R15; see Base\Database\Repository\Entities): TagRepository answers it through its finder, with the queries its callers ran by name before.

Tags::oneBySlug()

public function oneBySlug(string $slug): ?Tag

Tags::bySlugs()

public function bySlugs(array $slugs): array
Returns

in no particular order

Base\Repository\User

Complaints interface

interface Complaints extends Entities Complaints.php:15

The complaints (reports) of the members (plan "omnibase agnostic", step E2'; see Base\Database\Repository\Entities): what omnibase/admin's dashboard tile asks, ComplaintRepository's answer.

Complaints::newest()

public function newest(?string $status = null, ?string $source = null, int $limit = 200): array

The newest complaints, of one status (and one source) or all.

Connections interface

interface Connections extends Entities Connections.php:16

The accounts' connections (browsers, sessions) (audit "lesringostars face au master plan", step R28; see Base\Database\Repository\Entities): ConnectionRepository answers it with the queries its callers ran by name before.

Connections::countFor()

public function countFor(User $user): int

How many connections an account has.

Connections::oneByUniqidAndUser()

public function oneByUniqidAndUser(string $uniqid, User $user): ?Connection

The connection of a browser's identifier for an account, read from the database.

Identities interface

interface Identities extends Entities Identities.php:15

The accounts' identities at providers (plan "omnibase agnostic", step F2d; see Base\Database\Repository\Entities): IdentityRepository answers it with the queries Base\Auth\UserIdentities ran on it by name before.

Identities::findOneBySubject()

public function findOneBySubject(string $provider, string $subject): ?Identity

Identities::findOfUser()

public function findOfUser(object $user): array
Returns

the account's identities, by provider

Notifications interface

interface Notifications extends Entities Notifications.php:15

A user's notifications, those with something to show (audit "lesringostars face au master plan", step R15; see Base\Database\Repository\Entities).

Notifications::countUnreadFor()

public function countUnreadFor(User $user): int

Notifications::findVisibleFor()

public function findVisibleFor(User $user, int $limit = 100, int $offset = 0, bool $unreadOnly = false): array
Returns

newest first

Passkeys interface

interface Passkeys extends Entities Passkeys.php:15

The accounts' passkeys (audit "lesringostars face au master plan", step R28; see Base\Database\Repository\Entities): PasskeyRepository answers it with the queries its callers ran by name before.

Passkeys::findOneByCredential()

public function findOneByCredential(string $publicKeyCredentialId): ?Passkey

The passkey of that credential id (its raw bytes), as Base\Auth\UserPasskeys asks it (step F2d).

PushSubscriptions interface

interface PushSubscriptions extends Entities PushSubscriptions.php:15

The browsers subscribed to Web Push (audit "lesringostars face au master plan", step R28; see Base\Database\Repository\Entities): PushSubscriptionRepository answers it with the queries its callers ran by name before.

PushSubscriptions::countDistinctUsers()

public function countDistinctUsers(): int

How many accounts have at least one subscribed browser.

Tokens interface

interface Tokens extends Entities Tokens.php:15

The accounts' tokens (sign-in links, address checks, password resets, API keys) (audit "lesringostars face au master plan", step R28; see Base\Database\Repository\Entities): TokenRepository answers it with the queries its callers ran by name before.

Tokens::oneByValueAndName()

public function oneByValueAndName(?string $value, string $name): ?Token

Tokens::oneByValue()

public function oneByValue(?string $value): ?Token

Tokens::oneSigningInByNameAndValue()

public function oneSigningInByNameAndValue(string $name, ?string $value): ?Token

A token of this name and value that signs in (isLogginable).

Tokens::oneSigningInByValue()

public function oneSigningInByValue(?string $value): ?Token

A token of this value that signs in (isLogginable): an API key.

Base\Request

AttachmentDownload class

final class AttachmentDownload AttachmentDownload.php:14

A widget's attachment downloaded (/attachment/{slug}), written once for every host (plan "omnibase agnostic", step F5e, slice 5b; formerly WidgetController::Attachment()): its stored file, typed by its content (text/plain where PHP's fileinfo is missing), downloaded under its slug; no such attachment, no such page (null).

AttachmentDownload::__construct()

public function __construct(readonly Repositories $repositories)

AttachmentDownload::file()

public function file(string $slug): ?File

AttachmentDownload::type()

public static function type(string $path): string

What a file holds, as its content says (Symfony's FileinfoMimeTypeGuesser's answer), text/plain without fileinfo.

Decision class

final class Decision Decision.php:15

What a request rule decided (plan "omnibase agnostic", step F5e, slice 2: Base\Request\Rule\*), for every host to apply: the request goes on, is sent elsewhere (a route of the site's, or an address), or is refused with a status - and, with any of them, notices for the visitor, cookies for the answer, the account signed out, the address to come back to after a sign-in, the profiler turned off. omnibridge/symfony's subscribers and omnibridge/laravel's middleware apply it; neither decides anything itself.

final is a decision that the page is served as it is and that no rule after this one runs (Symfony: the event's propagation stopped without a response).

const CONTINUE = 'continue'
const REDIRECT = 'redirect'
const DENY = 'deny'

Decision::continue()

public static function continue(): self

Decision::final()

public static function final(): self

The page served as it is, no rule after this one.

Decision::redirect()

public static function redirect(string $route, array $parameters = [], int $status = 302): self

Decision::redirectTo()

public static function redirectTo(string $url, int $status = 302): self

Decision::deny()

public static function deny(int $status = 403): self

Decision::withNotice()

public function withNotice(string $key, array $parameters = [], string $importance = 'info'): self

Decision::withCookie()

public function withCookie(string $name, ?string $value): self

Decision::withSignOut()

public function withSignOut(): self

Decision::withRemember()

public function withRemember(string $url): self

The address the visitor comes back to after signing in again.

Decision::withoutProfiler()

public function withoutProfiler(): self

Decision::isContinue()

public function isContinue(): bool

Decision::then()

public function then(self $next): self

This decision's kind, route and status with another's notices and cookies added after its own (rules run in a row).

Decision::toArray()

public function toArray(): array

A plain array, for a test or a log.

ErrorPage class

final class ErrorPage ErrorPage.php:15

Which page answers an error, written once for every host (plan "omnibase agnostic", step F5e, slice 5b; formerly ErrorController::Main() and renderException()): for the site's developers, the debug page (RESCUE), unless the error page itself is previewed (_preview_error); otherwise the site's error page - under /admin the back office's own first (matched by the path, not the route: an address that matches nothing has no route, and a mistyped /admin/... is the most common error there), then the site's.

const RESCUE = 'rescue'
const PREVIEW_ROUTE = '_preview_error'
const ADMIN_TEMPLATE = '@Admin/error.html.twig'
const TEMPLATE = 'exception.html.twig'

ErrorPage::__construct()

public function __construct(readonly Environment $environment)

ErrorPage::choose()

public function choose(?string $route, string $path): string|array
Returns

the debug page, or the templates to try in their order

LocaleSwitch class

final class LocaleSwitch LocaleSwitch.php:19

The language menu's choice (/locale/{_locale}), written once for every host (plan "omnibase agnostic", step F5e, slice 5; formerly LocalizerController::Locale(), which omnibridge/laravel's SwitchLocale wrote again): a language the site speaks, remembered in the LANG cookie (Rule\Locale reads it) and as a member's own - not while impersonating -, then the page the visitor came from on this site, at its address in that language when it has one; a language the site does not speak, the index; none given, the choice forgotten.

const ROUTE = '_switch_locale'
const MESSAGE = '@controllers.locale_changeto.action'

LocaleSwitch::__construct()

public function __construct(readonly LocalizerInterface $localizer, readonly ?TranslatorInterface $translator = null, readonly ?Access $access = null, readonly ?UnitOfWork $unitOfWork = null)

LocaleSwitch::choose()

public function choose(?string $requested): ?string

The locale chosen (as the localizer writes it), or null when the site does not speak this language.

LocaleSwitch::remember()

public function remember(string $requested, string $locale): string

The choice kept as a member's own (not while impersonating); what the visitor is told.

LocaleSwitch::referred()

public static function referred(?string $referer, string $host): ?string

The path the visitor came from, when it is one of this site's (no host, or the request's).

LocaleSwitch::back()

public function back(?array $match, string $requested): array

The routes to go back to, the first the host can generate: the referring page's route in the chosen language ("name.en"), then its own name; none for no route, or the menu's own.

$match

the referring path's route as the host matched it (_route, _canonical_route, parameters)

Page interface

interface Page extends Page Page.php:10

The page a request opens, as the request rules ask it (plan "omnibase agnostic", step F5e, slice 2): the restriction's questions (Base\Auth\Policy\Page) and a few more, which only the host answers - its router names the route, its request the address.

Page::isSecured()

public function isSecured(): bool

A route of the account's own pages, "security_*" (omnibridge/symfony's AdvancedRouter::isSecured()).

Page::isUx()

public function isUx(): bool

A route of the widgets' endpoints, "ux_*".

Page::uri()

public function uri(): string

The whole address asked.

RouterPage class

final class RouterPage implements Page RouterPage.php:10

A Page answered by omnibase's router (omnibridge/symfony's AdvancedRouter, or any router with its questions: getRouteName(), isAdmin(), isProfiler(), isUX(), isSecured()), plus what a router does not know - the sign-in's own pages, the restriction's routes, the address asked.

RouterPage::__construct()

public function __construct(readonly object $router, readonly string $uri = '', readonly array $redirectsOnDeny = [], readonly ?\Closure $isSecurity = null)

RouterPage::isSecurity()

public function isSecurity(): bool

RouterPage::isProfiler()

public function isProfiler(): bool

RouterPage::isAdmin()

public function isAdmin(): bool

RouterPage::isUx()

public function isUx(): bool

RouterPage::isSecured()

public function isSecured(): bool

RouterPage::name()

public function name(): ?string

RouterPage::redirectsOnDeny()

public function redirectsOnDeny(): array

RouterPage::uri()

public function uri(): string

ShortLinkRedirect class

final class ShortLinkRedirect ShortLinkRedirect.php:16

A short link followed (s.<host>/{slug}), written once for every host (plan "omnibase agnostic", step F5e, slice 5b; formerly ShortLinkController::Main()): to the address it stands for, no such link no such page.

Fixed on the way: the controller handed the address to a router method that does not exist (format()), so every short link that existed answered 500; it goes to its address as it is written.

ShortLinkRedirect::__construct()

public function __construct(readonly Repositories $repositories)

ShortLinkRedirect::follow()

public function follow(string $slug): Outcome

SitemapPage class

final class SitemapPage SitemapPage.php:15

The sitemap (/sitemap.xml, /sitemap.txt), written once for every host (plan "omnibase agnostic", step F5e, slice 5b; formerly SitemapController::Main()): the pages the routes' #[Sitemap] declare, on the request's origin, then those the application enumerates itself (its entities' addresses), asked through SitemapEvent::BUILD; the host serves the template of the extension asked.

const EXTENSIONS = ['xml', 'txt']

SitemapPage::__construct()

public function __construct(readonly SitemapperInterface $sitemapper, readonly ?EventDispatcherInterface $dispatcher = null)

SitemapPage::build()

public function build(string $origin): SitemapperInterface

SitemapPage::template()

public static function template(string $extension): string

TimezoneSwitch class

final class TimezoneSwitch TimezoneSwitch.php:18

The visitor's time zone chosen (/timezone/{_timezone}), written once for every host (plan "omnibase agnostic", step F5e, slice 5b; formerly LocalizerController::Timezone(), which read a _locale its path never carried: it only ever went to the index, after a deprecated setcookie(null) and a match of an empty referrer). A zone PHP knows ("Europe/Paris", "UTC") is remembered in LOCATION/TIMEZONE - the cookie the page's script writes and UserInfoTrait reads - and as a member's own (not while impersonating), then the visitor goes back to the page they came from on this site; a zone it does not know, the index, nothing changed; none given, the choice forgotten.

const ROUTE = '_switch_timezone'

TimezoneSwitch::__construct()

public function __construct(readonly ?Access $access = null, readonly ?UnitOfWork $unitOfWork = null)

TimezoneSwitch::choose()

public static function choose(?string $requested): ?string

The zone chosen, or null when PHP knows no such zone.

TimezoneSwitch::remember()

public function remember(string $timezone): void

The zone kept as a member's own (not while impersonating).

TimezoneSwitch::back()

public static function back(?string $referer, string $host): ?string

Where the visitor goes back to: the path they came from on this site (LocaleSwitch::referred()), else null (the index).

Base\Request\Rule

AccessControl class

final class AccessControl AccessControl.php:15

The pages an application keeps for some accounts, by their path (plan "omnibase agnostic", step F5e, slice 2): the access_control of Symfony's security configuration as data - its first entry whose path matches decides: PUBLIC_ACCESS opens the page; else one of its roles or attributes granted opens it; else the visitor meets the entry point (EntryPoint: the sign-in, or 403 once signed in). No entry matching, the page is open. Symfony's firewall applies its own configuration; a host without one (omnibridge/laravel) asks this rule with the same entries.

const PUBLIC_ACCESS = 'PUBLIC_ACCESS'

AccessControl::__construct()

public function __construct(readonly array $entries)
$entries

as security.yaml writes them (^/profile, ROLE_USER)

AccessControl::decide()

public function decide(string $path, bool $signedIn, \Closure $granted, ?string $uri = null): Decision
$granted

the host's decision on a role or an attribute, for the visitor

Accounts class

final class Accounts Accounts.php:15

The account rules of a request, in the order omnibridge/symfony's SecuritySubscriber::onKernelRequest() asked them (plan "omnibase agnostic", step F5e, slice 2), for an omnibase account signed in: the impersonation's reminder, the kick (which ends there), the presence (on a main request), the verification, the approval. Each host's adapter asks request() before the page and response() on its answer.

Accounts::__construct()

public function __construct(readonly Kicked $kicked, readonly Presence $presence, readonly Verification $verification, readonly Approval $approval)

Accounts::request()

public function request(mixed $user, Page $page, \Closure $administrator, bool $main = true, bool $impersonating = false, ?string $switchParameter = null): Decision
$administrator

whether the account is an administrator (the approval asks it)

Accounts::response()

public function response(mixed $user): void

On the answer: the presence of an account signed in during the request itself.

Analytics class

final class Analytics Analytics.php:16

The back office's figures (plan "omnibase agnostic", step F5e, slice 2; formerly omnibridge/symfony's AnalyticsSubscriber): on its main requests (not the profiler's), the accounts online - active within the online delay, the visitor aside - and those of them active now, as the views' globals user_analytics (labels) and user_manager (the accounts); and Google Analytics' basics, where the host has them, as user_analytics.google. The host gives its globals and puts back the ones answered.

const GOOGLE = ['users' => ['@google_users', 'fa-solid fa-user'], 'users_1day' => ['@google_users_1day', 'fa-solid fa-user-clock'], 'views' => ['@google_analytics.views',…

Analytics::__construct()

public function __construct(readonly Users $users, readonly TranslatorInterface $translator)

Analytics::applies()

public static function applies(Page $page, bool $main): bool

Analytics::users()

public function users(?object $user, int $delay, array $globals): array
$globals

the views' globals as they are

Analytics::google()

public function google(array $basics, array $globals): array
$basics

Google Analytics' (users, users_1day, views, views_1day, sessions, bounces_1day)

$globals

the views' globals as they are

Returns

user_analytics with its google entries

Approval class

final class Approval Approval.php:19

An account not approved yet (plan "omnibase agnostic", step F5e, slice 2; formerly omnibridge/symfony's SecuritySubscriber::onKernelRequest()): approved and written at its first request when it is an administrator's, or when the site approves every sign-up (base.user.register.autoapprove); left as it is otherwise, the page going on.

The former subscriber also wrote two redirections there (to security_pendingForApproval, and from it to the site's index once approved), which could never happen: each was asked only on an account's page ("security_*"), which its own exceptions (/^(security|user|ux)_/) always let through.

Approval::__construct()

public function __construct(readonly ?UnitOfWork $unitOfWork = null, readonly bool $autoapprove = false)

Approval::decide()

public function decide(User $user, \Closure $administrator): Decision
$administrator

whether the account is an administrator, asked only for an account not approved

EntryPoint class

final class EntryPoint EntryPoint.php:14

A page refused to the visitor (plan "omnibase agnostic", step F5e, slice 2): who is not signed in is sent to the sign-in - the rescue sign-in where the access restriction makes an exception of the page (EXCEPTION_ACCESS) -, the address kept for after it: what Symfony's firewall does through its entry point (omnibridge/symfony's LoginFormAuthenticator::start(), which asks this rule); who is signed in is refused (403).

const ROUTE = 'security_login'
const RESCUE_ROUTE = 'security_rescue'

EntryPoint::decide()

public static function decide(bool $signedIn, ?string $uri = null, bool $exception = false): Decision

Impersonation class

final class Impersonation Impersonation.php:12

The account seen through another's eyes (plan "omnibase agnostic", step F5e, slice 2; formerly omnibridge/symfony's SecuritySubscriber::onKernelRequest()): while an administrator impersonates an account, every page reminds them, naming the account and the query parameter that ends it.

const PARAMETER = '_switch_user'

Impersonation::decide()

public static function decide(object $user, bool $impersonating, ?string $parameter = null): Decision

Integrity class

final class Integrity Integrity.php:15

The session's integrity (plan "omnibase agnostic", step F5e, slice 2; formerly omnibridge/symfony's IntegritySubscriber, which no configuration registers): the session keeps the application's secret sealed by the vault and a checksum of the database's connection; a session whose secret or connection no longer matches, or whose account the host finds damaged, is signed out (told so), its remember-me cookie cleared, and sent to the rescue sign-in, which itself is never checked.

const SESSION_SECRET = '_integrity/secret'
const SESSION_DATABASE = '_integrity/doctrine'
const ROUTE = 'security_rescue'

The rescue sign-in (omnibridge/symfony's RescueFormAuthenticator::LOGIN_ROUTE): never checked, and where a broken session is sent.

const REMEMBER_ME = 'REMEMBERME'

Integrity::__construct()

public function __construct(readonly ?string $secret = null, ?Vault $vault = null)

Integrity::seal()

public function seal(): mixed

The secret as the session keeps it.

Integrity::secretIntact()

public function secretIntact(mixed $sealed): bool

Integrity::checksum()

public static function checksum(array $parameters): string
$parameters

the connection's (driver, user, host, port, dbname, charset)

Integrity::databaseIntact()

public static function databaseIntact(bool $signedIn, ?string $kept, string $checksum): bool

Integrity::decide()

public function decide(bool $intact, ?object $user, ?string $route): Decision

Kicked class

final class Kicked Kicked.php:16

An account an administrator kicked out (plan "omnibase agnostic", step F5e, slice 2; formerly omnibridge/symfony's SecuritySubscriber::onKernelRequest()): told so, sent to the sign-out with the token the sign-out asks (Base\Security\SignOut: the server signs it out itself), the address it was asking kept for after its next sign-in. Nothing is written: the next sign-in lifts the kick.

const ROUTE = 'security_logoutRequest'

The sign-out's request page (omnibridge/symfony's LoginFormAuthenticator::LOGOUT_REQUEST_ROUTE).

Kicked::__construct()

public function __construct(readonly ?Tokens $tokens = null)

Kicked::decide()

public function decide(object $user, Page $page): Decision

LaunchPage class

final class LaunchPage LaunchPage.php:20

The launch page (plan "omnibase agnostic", step F5e, slice 2; formerly Launcher::redirectOnDeny(), which asks it now, under omnibridge/symfony's SecuritySubscriber). Where the site waits for its launch date and sends the visitors to it (base.settings.launchdate.redirect_on_deny), outside the widgets', the profiler's, the back office's and the account's pages: before the date, an editor is told when and goes on; the launch page itself and a visitor granted LAUNCH_ACCESS (Base\Auth\Policy\Launch) go on; anyone else is signed out and sent to the launch page, the profiler off. Once launched, the launch page sends to the site's index.

const ROUTE = 'security_launch'

LaunchPage::__construct()

public function __construct(readonly LauncherInterface $launcher, readonly bool $redirectOnDeny = false, readonly ?string $index = null)

LaunchPage::decide()

public function decide(Page $page, \Closure $granted, ?string $locale = null): Decision
$granted

the host's decision on an attribute or a role, for the visitor

Locale class

final class Locale Locale.php:24

The language of a page (plan "omnibase agnostic", step F5e, slice 2; formerly omnibridge/symfony's LocalizerSubscriber and omnibridge/laravel's Http\Localize, each its copy), and the one the next page remembers.

The order: the page's address (a route of one language, "/en/..." or "/datenschutz"); then, for a member signed in, their own language - which their choice of language updates - before the one their last page was shown in (the LANG cookie: a first visit before signing in, in the browser's language, set it and kept a member whose language is French in English); while impersonating, the impersonator's choice (LANG), which does not change the member's; then the browser's (Accept-Language), on a first visit; then the site's. The browser says nothing when it sends no Accept-Language, or Symfony's Request::create() default (a test client's, a sub-request's). A language counts when the site speaks it; a route's own is the site's by declaration.

The page's language is remembered in LANG for the next one (the site's locale, en-GB), unless the page set it itself (a change of language).

const REQUEST_DEFAULT_LANGUAGE = 'en-us,en;q=0.5'

What Symfony's Request::create() says when it is told no language.

public readonly array $languages

the languages the site speaks (fr, en), its own first: Accept-Language's ties go to it

Locale::__construct()

public function __construct(public readonly array $languages, readonly \Closure $normalize)
$languages

the languages the site speaks (fr, en), its own first: Accept-Language's ties go to it

$normalize

a locale written as the site writes it ("fr" is "fr-FR")

Locale::choose()

public static function choose(?string $address, ?string $remembered, ?string $member, bool $impersonating, ?string $browser, string $site): string

Locale::available()

public function available(?string $locale, bool $declared = false): ?string

A locale of this site's ("de", "fr_FR", "fr-FR"), normalized; null for any other.

Locale::browser()

public function browser(?string $acceptLanguage, \Closure $preferred): ?string

The browser's language among the site's, null when it says nothing.

$preferred

the host's reading of Accept-Language among languages

Locale::decide()

public function decide(?string $address, ?string $cookie, ?string $member, bool $impersonating, ?string $browser, string $site): string

The page's locale, normalized.

Locale::remember()

public static function remember(string $displayed, ?string $cookie, bool $setByPage): Decision

The answer's: LANG written with the page's locale, unless it holds it already or the page wrote it.

Locale::timezone()

public static function timezone(?string $cookie): array

The visitor's time zone, from the cookie the site's script writes: UTC without one; an invalid one said, and UTC.

MaintenancePage class

final class MaintenancePage MaintenancePage.php:18

The maintenance page (plan "omnibase agnostic", step F5e, slice 2; formerly MaintenanceProvider:: redirectOnDeny(), which asks it now, under omnibridge/symfony's SecuritySubscriber). While the site is under maintenance: an editor is told so and goes on; the maintenance page itself is served as it is, nothing else asked; a visitor granted MAINTENANCE_ACCESS (Base\Auth\Policy\Maintenance) goes on; anyone else is signed out and sent to the maintenance page (base.site.maintenance.redirect_on_deny, security_maintenance by default), the profiler off. Once it is over, the maintenance page sends to the site's index.

const ROUTE = 'security_maintenance'

MaintenancePage::__construct()

public function __construct(readonly MaintenanceProviderInterface $maintenance, readonly ?string $route = null, readonly ?string $index = null)

MaintenancePage::decide()

public function decide(Page $page, \Closure $granted): Decision
$granted

the host's decision on an attribute or a role, for the visitor

Presence class

final class Presence Presence.php:19

The presence of the account signed in (plan "omnibase agnostic", step F5e, slice 2; formerly omnibridge/symfony's SecuritySubscriber and omnibridge/laravel's Middleware\Presence, each its copy): an omnibase account not active lately (User::isActive()) is poked - its activeAt now - and written.

Asked before the page is drawn, not after it: poked on the answer, the first page after a pause (a restored session, a tab left open) showed its own reader offline, and online only on the next click. Asked once more on the answer, for an account signed in during the request itself (a sign-up, a sign-in). The write keeps the unit of work as it is (a flush, never a clear): this runs on every request, and an entity manager cleared under the controller left the signed-in account detached from every row loaded after it.

Presence::__construct()

public function __construct(readonly ?UnitOfWork $unitOfWork = null)

Presence::poke()

public function poke(mixed $user): bool

Whether the account was poked.

Redirection class

final class Redirection Redirection.php:20

A page not found, looked up in the site's redirections (plan "omnibase agnostic", step F5e, slice 2; formerly Base\Service\Redirections::responseFor(), which asks it now): the old addresses of a site taken over lead to its new pages, with the redirection's status (301 or 302), its use counted.

Asked only once nothing answered (no route, or no record): a page the site answers is never redirected. A form sent to an old address is not replayed elsewhere (a safe method only); matched on its path alone, the visitor's query follows (a campaign's utm_*); a redirection onto itself is none; no table yet (a site that has not run its migration) is no redirection.

Redirection::__construct()

public function __construct(readonly Redirections $repository, readonly ?LoggerInterface $logger = null)

Redirection::decide()

public function decide(bool $safe, string $path, ?string $query = null, string $base = ''): Decision

Verification class

final class Verification Verification.php:19

An account whose address is not verified yet (plan "omnibase agnostic", step F5e, slice 2; formerly omnibridge/symfony's SecuritySubscriber::onKernelRequest()): told so on every page but the account's own ("security_*") - that the e-mail was just sent (the verification's token still under its delay), or where to ask for it. A tester's account is left alone.

The former subscriber also wrote a redirection to the profile there, which could never happen: it was reached only outside the account's pages, where its own condition always chose the notice.

const ROUTE = 'security_verifyEmail'

Verification::__construct()

public function __construct(readonly Urls $urls)

Verification::decide()

public function decide(User $user, Page $page): Decision

Base\Routing

AdminRouteNames class

final class AdminRouteNames AdminRouteNames.php:23

How omnibase/admin names a CRUD controller's routes, framework-free: the controller's namespace after Crud\ (or its short name), each segment kebab-cased and pluralised, a repeated segment collapsed, joined with "/" (Crud\Article\ArticleCrudController: "articles"; Crud\Article\ CommentReplyCrudController: "articles/comment-replies"), and the route "admin_crud_" + that slug with "-" and "/" made "_" + "_" + the action (admin_crud_articles_comments_edit).

omnibase/admin's AdminRouteRegistry names its routes by this rule (slugify()); a host without omnibase/admin's Symfony bundle - the Laravel twin of a site whose back office stays Symfony's - names a record's edit page by it too (forEntity(): the controller the admin's convention gives an entity, App\Entity\Article\Comment => ...\Crud\Article\CommentCrudController), through AdminLinks (audit "lesringostars face au master plan", R24).

const ROUTE_PREFIX = 'admin_crud_'

AdminRouteNames::slugify()

public static function slugify(string $controllerFqcn): string

A controller's slug: "articles/comment-replies".

AdminRouteNames::pluralize()

public static function pluralize(string $kebab): string

The last word of a kebab-cased segment pluralised ("comment-reply" => "comment-replies"), the qualifier words left alone; EnglishInflector's first guess, the word as it is when it gives none.

AdminRouteNames::route()

public static function route(string $slug, string $action = 'index'): string

A slug's route for an action: admin_crud_articles_comments_edit.

AdminRouteNames::forEntity()

public static function forEntity(string $entityFqcn, string $action = 'index'): ?string

The route of an entity's page for an action, by the admin's convention (its CRUD controller named after it: the namespace after Entity\, under Crud\); null for a class outside an Entity\ namespace. Doctrine's proxy is its entity.

AdminUrlGeneratorInterface interface

interface AdminUrlGeneratorInterface AdminUrlGeneratorInterface.php:19

Contract for building back-office URLs.

base-bundle is usable on its own - a front-end-only install has no back-office at all - so it must never type-hint the admin's concrete generator. It depends on this interface instead; omnibase/admin supplies the real implementation when it is installed, and NullAdminUrlGenerator stands in when it is not.

The fluent methods clone on first mutation, so a partially-built URL never leaks between call sites.

AdminUrlGeneratorInterface::setController()

public function setController(string $controllerFqcn): static

AdminUrlGeneratorInterface::setAction()

public function setAction(string $action): static

AdminUrlGeneratorInterface::setEntityId()

public function setEntityId(mixed $entityId): static

AdminUrlGeneratorInterface::set()

public function set(string $paramName, mixed $paramValue): static

AdminUrlGeneratorInterface::unset()

public function unset(string $paramName): static

AdminUrlGeneratorInterface::unsetAll()

public function unsetAll(): static

AdminUrlGeneratorInterface::generateUrl()

public function generateUrl(int $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH): string

CookieDomain class

final class CookieDomain CookieDomain.php:15

The domain a cookie of the whole site is written for, framework-free (step R29 of the audit "lesringostars face au master plan"): omnibase's rule, AdvancedRouter::getDomain()'s - the request's domain when it is one of the configured domains (base.router.host_fallbacks), else the first of them; "localhost" when the router uses no fallbacks. Its subdomains share the cookie (a cookie with a Domain attribute). Symfony's router and omnibridge/laravel's sign-in effects (the browser's PHPUSERID) write it the same way.

CookieDomain::of()

public static function of(string $url, array $configured): ?string
$url

the address asked (its domain is read as omnibase's parse_url2() reads it: "symfony.test" of "lesringostars.symfony.test")

$configured

the configured domains (domains())

CookieDomain::domains()

public static function domains(bool $useFallbacks, array $hostFallbacks, array $locales): array

The configured domains of a language, as the router picks its fallbacks: the first of base.router.host_fallbacks whose locale is the first of $locales to have one, else the first without a locale; none when the router uses no fallbacks.

$hostFallbacks

base.router.host_fallbacks

$locales

the locale, its language, the default locale, its language

NullAdminUrlGenerator class

final class NullAdminUrlGenerator implements AdminUrlGeneratorInterface NullAdminUrlGenerator.php:15

Stand-in used when omnibase/admin is not installed.

Every call site in base-bundle builds its URL fluently and only then asks for the string, so the builder methods stay silent no-ops and the failure surfaces at generateUrl() - the one point where the caller genuinely needs a back-office that isn't there.

NullAdminUrlGenerator::setController()

public function setController(string $controllerFqcn): static

NullAdminUrlGenerator::setAction()

public function setAction(string $action): static

NullAdminUrlGenerator::setEntityId()

public function setEntityId(mixed $entityId): static

NullAdminUrlGenerator::set()

public function set(string $paramName, mixed $paramValue): static

NullAdminUrlGenerator::unset()

public function unset(string $paramName): static

NullAdminUrlGenerator::unsetAll()

public function unsetAll(): static

NullAdminUrlGenerator::generateUrl()

public function generateUrl(int $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH): string

Base\Screen

Answer class

final readonly class Answer Answer.php:12

An action's answer as Negotiation gives it, before any framework (step R10 of the audit "lesringostars face au master plan"): its status, body and headers, how it may be kept, whether the body is JSON (Symfony's JsonResponse, Laravel's), or the file it is (sent as it is stored). Each host's adapter makes its response of it, nothing more.

public int $status
public string $body
public array $headers
public Cache $cache
public bool $json
public ?string $file

Answer::__construct()

public function __construct(public int $status = 200, public string $body = '', public array $headers = [], public Cache $cache = new Cache(), public bool $json = false, public ?string $file = null)

Author class

final readonly class Author implements Screen Author.php:11

Who wrote a story, a comment, a reply (lesringostars' authors): a name, the address of their page (a profile, a comment's website), an avatar's address; staff where a screen marks the site's own people (the blog's "author" pill), left out of the props where it does not.

public string $name
public ?string $profile
public ?string $avatar
public ?bool $staff

Author::__construct()

public function __construct(public string $name, public ?string $profile = null, public ?string $avatar = null, public ?bool $staff = null)

Author::toArray()

public function toArray(): array

Author::jsonSerialize()

public function jsonSerialize(): array

Cache class

final readonly class Cache Cache.php:12

How an answer may be kept (step R10 of the audit "lesringostars face au master plan"): by any cache (public) or by the visitor's browser alone (private) - null leaves it to the host -, how long, whether it is to be asked again once stale, by no cache at all (no-store), and the request headers it varies on. Each host's adapter sets them on its response.

public ?bool $shared

true: public, false: private, null: the host's default

public ?int $maxAge
public bool $mustRevalidate
public bool $noStore
public array $vary

Cache::__construct()

public function __construct(public ?bool $shared = null, public ?int $maxAge = null, public bool $mustRevalidate = false, public bool $noStore = false, public array $vary = [])
$shared

true: public, false: private, null: the host's default

Cache::private()

public static function private(): self

Kept by the visitor's browser alone.

Cache::public()

public static function public(int $maxAge, bool $mustRevalidate = false): self

Kept by any cache, that long.

Cache::with()

public function with(array $vary = [], bool $private = false, bool $noStore = false): self

A copy varying on these headers too, and private (and stored by no cache) when asked so: what the answer adds to what the action said.

Card class

readonly class Card implements Screen Card.php:14

A story on a list (lesringostars' BlogPage::card()): its slug, title, excerpt, date, reading time, authors and tags, its address. likes, likeUrl and comments are null where the screen counts none (never 0: "none counted" and "zero" stay apart). Added for omnibase's blog: the line under the title (headline), the cover's address at the width the screen shows it, the taxa, and recent - published lately, by the screen's clock (a template compares no moment: it reads this).

public string $slug
public string $title
public string $url
public ?string $excerpt
public bool $hasContent
public ?string $publishedAt
public int $readingMinutes
public array $authors
public array $tags
public ?int $likes
public ?string $likeUrl
public ?int $comments
public ?string $headline
public ?string $cover
public array $taxa
public bool $recent

Card::__construct()

public function __construct(public string $slug, public string $title, public string $url, public ?string $excerpt = null, public bool $hasContent = false, public ?string $publishedAt = null, public int $readingMinutes = 0, public array $authors = [], public array $tags = [], public ?int $likes = null, public ?string $likeUrl = null, public ?int $comments = null, public ?string $headline = null, public ?string $cover = null, public array $taxa = [], public bool $recent = false)

Card::toArray()

public function toArray(): array

Card::jsonSerialize()

public function jsonSerialize(): array

Comment class

final readonly class Comment implements Screen Comment.php:11

A comment (lesringostars' comments): its id or uuid (at least one: a front end keys and anchors on the uuid, else the id), slug, date, authors, text (as written: a template breaks its lines), the address to follow it, its replies, and whether it is recent by the screen's clock.

public ?int $id
public ?string $uuid
public ?string $slug
public ?string $publishedAt
public array $authors
public ?string $content
public ?string $followUrl
public array $replies
public bool $recent

Comment::__construct()

public function __construct(public ?int $id, public ?string $uuid, public ?string $slug = null, public ?string $publishedAt = null, public array $authors = [], public ?string $content = null, public ?string $followUrl = null, public array $replies = [], public bool $recent = false)

Comment::toArray()

public function toArray(): array

Comment::jsonSerialize()

public function jsonSerialize(): array

Confidential interface

interface Confidential extends Screen Confidential.php:12

A screen carrying secrets of its viewer's session (plan "omnibase agnostique", C5): the tokens of its forms (Base\Screen\Account\Action), the token of its requests. Whoever answers it keeps it out of every cache - under Symfony, ScreenResponder gives Cache-Control: private, no-store and Vary: Cookie, the HTML as the JSON.

ContextProvider interface

interface ContextProvider ContextProvider.php:16

What a screen needs of the request it answers (plan "omnibase agnostique", C5): the frame around the page, the visitor signed in, the messages left for the page. Under Symfony Base\Bridge\Symfony\SymfonyScreenContext; a site decorates it to add its own frame fields; another framework fills it the same.

Not in it, on purpose: the forms a page carries (Symfony by nature, D3), the assets and the injections of the layout (the host's layout stays the host's), menus (a site's links go in the frame's extra).

ContextProvider::frame()

public function frame(array $extra = []): Frame

The frame of the page being answered; $extra the site's own fields.

ContextProvider::viewer()

public function viewer(): ?Viewer

The visitor signed in, null for nobody.

ContextProvider::flashes()

public function flashes(string $type): array

The messages left for the next page under that type, read - and so taken - now.

Discussion class

final readonly class Discussion implements Screen Discussion.php:14

The comments of a page and whether one may write (lesringostars' page comments and hasMoreComments, here comments and hasMore): one model, because the block is shown on pages that are no story too (a visitors' book, a host's home). open: a comment may be written here (the site's settings, the story's, the visitor); canReply: an answer to one may; signIn: the address of the sign-in page, for whoever may not; flashes: the messages left for this page, already read.

public array $comments
public bool $hasMore
public bool $open
public bool $canReply
public ?string $signIn
public array $flashes

Discussion::__construct()

public function __construct(public array $comments = [], public bool $hasMore = false, public bool $open = false, public bool $canReply = false, public ?string $signIn = null, public array $flashes = [])

Discussion::toArray()

public function toArray(): array

Discussion::jsonSerialize()

public function jsonSerialize(): array

File class

final readonly class File File.php:10

A stored file answered as it is (step R10 of the audit "lesringostars face au master plan"): its path, its type (null: the host guesses it from the file), how it may be kept.

public string $path
public ?string $type
public Cache $cache

File::__construct()

public function __construct(public string $path, public ?string $type = null, public Cache $cache = new Cache())

Fragments class

final readonly class Fragments Fragments.php:10

Templates rendered one after the other into one string, a value of a JSON answer (step R10 of the audit "lesringostars face au master plan"): a batch of comments, the HTML a page's script inserts.

public array $templates

Fragments::__construct()

public function __construct(Template ...$templates)

Frame class

final readonly class Frame implements Screen Frame.php:16

What every page shows around its screen (lesringostars' App\Screen\Frame): the page's language, the site, the addresses of the menus, the visitor signed in and the colour scheme, and what a site adds of its own (extra: lesringostars' destination, destinations, last article, tags, map), merged in its props between site and links. Given per request by a ContextProvider.

host (the scheme, host and base path the page was asked at) serves the absolute addresses and the feed; it is not in the props.

const RESERVED = ['locale', 'site', 'links', 'viewer', 'theme']

The keys of the frame's own fields, which a site's extra may not take.

public string $locale
public Site $site

by name; locales the address of each language

public ?Viewer $viewer
public array $theme
public array $extra

the site's own fields

public string $host

Frame::__construct()

public function __construct(public string $locale, public Site $site = new Site(), public array $links = [], public ?Viewer $viewer = null, public array $theme = [], public array $extra = [], public string $host = '')
$links

by name; locales the address of each language

$extra

the site's own fields

Frame::with()

public function with(array $extra): self

A copy with the site's own fields added (a site's provider decorating the core's).

Frame::toArray()

public function toArray(): array

Frame::jsonSerialize()

public function jsonSerialize(): array

Json class

final readonly class Json Json.php:13

Data answered in JSON, what an action a page's script asks hands back (step R10 of the audit "lesringostars face au master plan"): a feed, a batch of comments, a token. A Template among the data (at any depth) is rendered by the host into its markup, Fragments into theirs joined, before the data are encoded - as Symfony's JsonResponse encodes them, under either host.

public mixed $data
public int $status
public Cache $cache

Json::__construct()

public function __construct(public mixed $data, public int $status = 200, public Cache $cache = new Cache())

final readonly class Link implements Screen Link.php:11

Another story, as a page points to it (the one before, after, to read as well; a member's latest on their profile): its title, address and state; publishedAt where a page shows the date, left out of the props where it shows none.

public function __construct(public string $title, public string $url, public string $state, public ?string $publishedAt = null)
public function toArray(): array
public function jsonSerialize(): array

Negotiation class

final class Negotiation Negotiation.php:38

How an action's result is answered, whichever framework hosts it (step R10 of the audit "lesringostars face au master plan"; formerly the body of Base\Bridge\Symfony\ScreenResponder, which is now Symfony's adapter of it, as omnibridge/laravel's Screen\Responder is Laravel's). Framework-free: the host gives what the client asked (a Visit) and a way to render a template, and makes its response of the Answer.

  • A View (a screen of omnibase, plan 0 rule 13) with the frame of the request: within a front end (omnibridge/react's X-Omnibridge, when it is installed) the page in JSON - the View's component, the frame's and the screen's props, the address, the version -, 409 and the address to reload for a front end of another version; without omnibridge/react, a request asking JSON alone gets the props; otherwise the template with frame and screen (and a site's variables of before, $legacy). Every answer varies on what chose it; one carrying a visitor is private to them and varies on Cookie; a Confidential screen is stored by no cache at all.
  • A Template: its markup, or for a client preferring JSON the data, when the template says it may (both varying on Accept).
  • Json: the data, its templates rendered, encoded as Symfony's JsonResponse encodes them.
  • A Shell: omnibridge/react's protocol - the shell on a first visit, the page in JSON within the front end, 409 for another version.
  • A File: the file, as it is stored.
  • A Redirect: the client sent to its address (Location), with its status.

A screen's props never take a key of the frame's (Frame::RESERVED): the frame's would win and the screen's be lost without a word, so such a screen is refused, in every answer.

const PAGE = 'page'

A template rendered as a page of the site: the host adds what its pages carry.

const PART = 'part'

A part of an answer (a value of a JSON answer): in the page's context, nothing added once rendered.

const ALONE = 'alone'

A page whole, its own markup alone (Template::$alone, a Shell).

const JSON = \JSON_HEX_TAG | \JSON_HEX_APOS | \JSON_HEX_AMP | \JSON_HEX_QUOT

How Symfony's JsonResponse encodes (its DEFAULT_ENCODING_OPTIONS): the JSON of either host, byte for byte.

Negotiation::__construct()

public function __construct(readonly \Closure $render, readonly ?ContextProvider $context = null, readonly ?string $version = null, readonly ?bool $omnibridge = null)
$render

the host's Twig; $as one of PAGE, PART, ALONE

$omnibridge

whether omnibridge/react's protocol is spoken for a View; null: when it is installed

Negotiation::answer()

public function answer(View|Template|Json|Shell|File|Redirect $result, Visit $visit, array $legacy = [], ?Frame $frame = null): Answer
$legacy

a View's variables of before, for a site's own template

Negotiation::props()

public function props(Frame $frame, View $view): array
Returns

the frame's props and the screen's, as a front end reads them

Negotiation::guard()

public static function guard(Screen $screen): void

A screen whose props would take a key of the frame's is refused: its own would be lost in the JSON.

Negotiation::encode()

public static function encode(mixed $data): string

Data in JSON, as Symfony's JsonResponse writes them.

Negotiation::omnibridge()

public function omnibridge(): bool

Whether omnibridge/react's protocol is spoken.

Redirect class

final readonly class Redirect Redirect.php:12

What an action hands back to send the client elsewhere (step R27 of the audit "lesringostars face au master plan": a newsletter's tracking link counts the click, then leads to its subject): the address, the status (302 by default), stored by no cache by default; more headers when it carries some (a cookie).

public string $url
public int $status
public Cache $cache
public array $headers

Redirect::__construct()

public function __construct(public string $url, public int $status = 302, public Cache $cache = new Cache(), public array $headers = [])

Reply class

final readonly class Reply implements Screen Reply.php:11

An answer to a comment (lesringostars' replies): its id or uuid (at least one: a front end keys and anchors on the uuid, else the id), date, authors, text, whether it was deleted, and whether it is recent by the screen's clock.

public ?int $id
public ?string $uuid
public ?string $publishedAt
public array $authors
public ?string $content
public bool $deleted
public bool $recent

Reply::__construct()

public function __construct(public ?int $id, public ?string $uuid, public ?string $publishedAt = null, public array $authors = [], public ?string $content = null, public bool $deleted = false, public bool $recent = false)

Reply::toArray()

public function toArray(): array

Reply::jsonSerialize()

public function jsonSerialize(): array

Screen interface

interface Screen extends JsonSerializable Screen.php:12

A view model (plan 0, rule 13; plan "omnibase agnostique", C5): what a screen shows, as plain data a view bridge renders - Twig reads the object's public properties, a front end (React) reads toArray() as its props. No entity, no service, no class of a framework inside: scalars, ISO 8601 moments, lists and other screens.

Screen::toArray()

public function toArray(): array
Returns

the props, nested arrays all the way down

Shell class

final readonly class Shell Shell.php:14

A page a front end renders (omnibridge/react's protocol), what an action of a React page hands back (step R10 of the audit "lesringostars face au master plan"): the component, its props, the front end's version, and the shell of the first visit - a template given root (the element holding the page), page and its own data. A visit within the front end gets the page in JSON, a front end of another version 409 and the address to reload, the first visit the shell, its markup alone.

public string $component
public array $props
public string $template
public array $data

the shell's own variables

public ?string $version

Shell::__construct()

public function __construct(public string $component, public array $props, public string $template, public array $data = [], public ?string $version = null)
$data

the shell's own variables

Site class

final readonly class Site implements Screen Site.php:6

The site around every page: its name, its slogan, its logo's address, the year, its description (lesringostars' frame site).

public ?string $title
public ?string $slogan
public string $age
public ?string $description

Site::__construct()

public function __construct(public ?string $title = null, public ?string $slogan = null, public ?string $logo = null, public string $age = '', public ?string $description = null)

Site::toArray()

public function toArray(): array

Site::jsonSerialize()

public function jsonSerialize(): array

Story class

readonly class Story implements Screen Story.php:11

A story on its own page (lesringostars' StoryPage article): what its card says, with its id, its text (StoryText's html, editor and toc, flattened as there), its sounds' addresses, whether it takes comments, and its state.

The cover is at the width the page shows it.

public int $id
public string $slug
public string $title
public string $url
public string $state
public ?string $headline
public ?string $excerpt
public StoryText $text
public ?string $publishedAt
public int $readingMinutes
public array $authors
public array $tags
public array $audio
public ?int $likes
public ?string $likeUrl
public bool $commentable
public ?int $comments
public ?string $cover
public array $taxa
public bool $recent

Story::__construct()

public function __construct(public int $id, public string $slug, public string $title, public string $url, public string $state, public ?string $headline = null, public ?string $excerpt = null, public StoryText $text = new StoryText(), public ?string $publishedAt = null, public int $readingMinutes = 0, public array $authors = [], public array $tags = [], public array $audio = [], public ?int $likes = null, public ?string $likeUrl = null, public bool $commentable = false, public ?int $comments = null, public ?string $cover = null, public array $taxa = [], public bool $recent = false)

Story::getHtml()

public function getHtml(): string

The text's HTML (Twig: story.html, as the props say it).

Story::isEditor()

public function isEditor(): bool

Story::getToc()

public function getToc(): array

Story::hasContent()

public function hasContent(): bool

Story::toArray()

public function toArray(): array

Story::jsonSerialize()

public function jsonSerialize(): array

StoryText class

final readonly class StoryText implements Screen StoryText.php:10

A story's text as its page shows it (lesringostars' StoryText::render()): the HTML rendered, whether it was an Editor.js document, and its table of contents (each heading's tag, anchor and title, in the text's order).

public string $html
public bool $editor
public array $toc

StoryText::__construct()

public function __construct(public string $html = '', public bool $editor = false, public array $toc = [])

StoryText::toArray()

public function toArray(): array

StoryText::jsonSerialize()

public function jsonSerialize(): array

Tag class

final readonly class Tag implements Screen Tag.php:11

A tag, a taxon (lesringostars' tags): its slug, label, colour, icon and the address that lists what carries it; count in a cloud of tags, current in a navigation by tag (the one shown), each left out of the props where a screen has none.

public string $slug
public string $label
public string $url
public ?string $color
public ?string $icon
public ?int $count
public ?bool $current

Tag::__construct()

public function __construct(public string $slug, public string $label, public string $url, public ?string $color = null, public ?string $icon = null, public ?int $count = null, public ?bool $current = null)

Tag::toArray()

public function toArray(): array

Tag::jsonSerialize()

public function jsonSerialize(): array

Template class

final readonly class Template Template.php:20

A template and its data, what an action of a page hands back (step R10 of the audit "lesringostars face au master plan"): the host renders it - Twig under either framework -, with the status and the caching the action gives.

  • json: a client preferring JSON (Accept) gets the data itself, JSON-encoded, at the same address (both answers vary on Accept): a screen described once, read by a front end;
  • alone: the page is the template's markup alone, nothing the host adds to its pages around it (under Symfony omnibase's tags: _omnibase_inject: false; under Laravel the site's page context).

The data are the template's variables: an action leaves out what only a host adds (Symfony's forms, D3) and the host adds it with with().

public string $template
public array $data
public int $status
public bool $json
public bool $alone
public Cache $cache

Template::__construct()

public function __construct(public string $template, public array $data = [], public int $status = 200, public bool $json = false, public bool $alone = false, public Cache $cache = new Cache())

Template::with()

public function with(array $data, ?int $status = null): self

A copy with these variables added (or replaced), and another status.

View class

final readonly class View View.php:12

What a controller hands back (plan 0, rule 13): the template that draws the screen, the screen itself, the name of the component a front end draws it with (omnibridge/react's Page), and the status of the answer. The view bridge renders it: Twig with frame and screen, React with the frame's and the screen's props together.

public string $template
public Screen $screen
public ?string $component
public int $status

View::__construct()

public function __construct(public string $template, public Screen $screen, public ?string $component = null, public int $status = 200)

Viewer class

final readonly class Viewer implements Screen Viewer.php:10

The visitor signed in, as a page may show them: an id, a name, an avatar's address. Nothing else (no roles: what a screen needs of the visitor, its builder decides - may they reply, is the form open).

public ?int $id
public string $name
public ?string $avatar

Viewer::__construct()

public function __construct(public ?int $id, public string $name, public ?string $avatar = null)

Viewer::toArray()

public function toArray(): array

Viewer::jsonSerialize()

public function jsonSerialize(): array

Visit class

final readonly class Visit Visit.php:12

What a client asked of an action, as far as its answer depends on it (step R10 of the audit "lesringostars face au master plan"): the address, the types it accepts, and omnibridge/react's headers (X-Omnibridge: a visit within a front end; X-Omnibridge-Version: the front end's version).

Each host's adapter reads them off its own request.

public string $uri
public string $accept
public ?string $frontEnd
public ?string $version

Visit::__construct()

public function __construct(public string $uri = '/', public string $accept = '', public ?string $frontEnd = null, public ?string $version = null)

Visit::acceptable()

public function acceptable(): array

The types of Accept, the preferred first: by quality, then in their order (Symfony's AcceptHeader), without their parameters.

Visit::prefersJson()

public function prefersJson(): bool

The client prefers JSON: the first type it accepts that names a format (a wildcard names none) is JSON's - Symfony's getPreferredFormat() "json", Laravel's wantsJson() for a type that comes first.

Visit::asksJsonAlone()

public function asksJsonAlone(): bool

The client asks JSON and not HTML at all (a script, not a browser).

Welcome class

final class Welcome Welcome.php:11

The page a new site shows at its root until it has one of its own, written once for every host (plan "omnibase agnostic", step F5e, slice 5b; formerly MainController::Index()'s): templates/welcome.html.php, plain PHP (no view engine), told the host framework's version, the project's folder and omnibase's version; answered 404, as a page the site has not written.

const STATUS = 404
const TEMPLATE = __DIR__ . '/../../templates/welcome.html.php'

Welcome::html()

public static function html(string $version, string $projectDir, string $baseVersion): string

Base\Screen\Account

AccountSummary class

final readonly class AccountSummary implements Screen AccountSummary.php:14

An account's security at a glance, on its profile, for its owner or an administrator: whether it has a second factor (null where two-factor is not available on the site), how many passkeys (null where passkeys are not - never 0 for "not counted"), the provider it signs in with (google), its language and time zone.

public ?bool $twoFactor
public ?int $passkeys
public ?string $identityProvider
public ?string $locale
public ?string $timezone

AccountSummary::__construct()

public function __construct(public ?bool $twoFactor = null, public ?int $passkeys = null, public ?string $identityProvider = null, public ?string $locale = null, public ?string $timezone = null)

AccountSummary::toArray()

public function toArray(): array

AccountSummary::jsonSerialize()

public function jsonSerialize(): array

Action class

final readonly class Action implements Screen Action.php:13

A POST a page sends (plan "omnibase agnostique", C5): the address it goes to and the token of its intent (Omnibridge\Contract\Tokens), which the action checks. Only on a confidential screen (Base\Screen\Confidential): its answers are stored by no cache.

public string $url
public string $token

Action::__construct()

public function __construct(public string $url, public string $token)

Action::toArray()

public function toArray(): array

Action::jsonSerialize()

public function jsonSerialize(): array

Member class

final readonly class Member implements Screen Member.php:16

A member as their profile shows them, to anyone who opens it: their number and name, their avatar - the stored one's address at 128 px, or the application's own rendering (avatarHtml: its User's getFormattedAvatar(), HTML) -, their roles (the names, which a template translates), whether they are online or were active lately (the account's own answers, by base.user.online_delay and active_delay), when they registered and were last seen, how many threads they own and likes they gave (counted).

public int $id
public string $name
public ?string $avatar
public ?string $avatarHtml
public array $roles
public bool $online
public bool $active
public ?string $registeredAt
public ?string $lastSeenAt
public int $threads
public int $likes

Member::__construct()

public function __construct(public int $id, public string $name, public ?string $avatar = null, public ?string $avatarHtml = null, public array $roles = [], public bool $online = false, public bool $active = false, public ?string $registeredAt = null, public ?string $lastSeenAt = null, public int $threads = 0, public int $likes = 0)

Member::toArray()

public function toArray(): array

Member::jsonSerialize()

public function jsonSerialize(): array

Notification class

final readonly class Notification implements Screen Notification.php:15

A notification in the member's list: the bell's item (NotificationController::serialize(): id, title - else the subject -, text without its tags - null when it has none -, address, back-office address, importance, read or not, when it was sent) and its group - today, yesterday, week or earlier, by the screen's clock in the page's time zone, so that no template compares a moment.

const GROUPS = ['today', 'yesterday', 'week', 'earlier']
public int $id
public string $title
public ?string $content
public ?string $url
public ?string $adminUrl
public ?string $importance
public bool $isRead
public ?string $sentAt
public string $group

Notification::__construct()

public function __construct(public int $id, public string $title = '', public ?string $content = null, public ?string $url = null, public ?string $adminUrl = null, public ?string $importance = null, public bool $isRead = false, public ?string $sentAt = null, public string $group = 'earlier')

Notification::toArray()

public function toArray(): array

Notification::jsonSerialize()

public function jsonSerialize(): array

NotificationsPage class

final readonly class NotificationsPage implements Confidential NotificationsPage.php:16

The member's notifications (/notifications): the latest with something to show (newest first; the unread ones alone when asked), how many are unread (counted), whether the page shows the unread ones alone and the address of all of them, the token every request of the page carries and the addresses of those requests (read, latest, delete, push subscribe and unsubscribe), whether push can be offered and its public key. Its token: confidential.

public array $notifications
public int $unread
public bool $unreadOnly
public string $allUrl
public string $token
public string $readUrl
public string $latestUrl
public string $deleteUrl
public string $subscribeUrl
public string $unsubscribeUrl
public bool $push
public ?string $pushKey

NotificationsPage::__construct()

public function __construct(public array $notifications, public int $unread, public bool $unreadOnly, public string $allUrl, public string $token, public string $readUrl, public string $latestUrl, public string $deleteUrl, public string $subscribeUrl, public string $unsubscribeUrl, public bool $push = false, public ?string $pushKey = null)

NotificationsPage::toArray()

public function toArray(): array

NotificationsPage::jsonSerialize()

public function jsonSerialize(): array

Passkey class

final readonly class Passkey implements Screen Passkey.php:8

A passkey of the account: its number, its label (null for none), when it was added and last used, the actions renaming and removing it.

public int $id
public Action $rename
public Action $delete
public ?string $label
public ?string $addedAt
public ?string $lastUsedAt

Passkey::__construct()

public function __construct(public int $id, public Action $rename, public Action $delete, public ?string $label = null, public ?string $addedAt = null, public ?string $lastUsedAt = null)

Passkey::toArray()

public function toArray(): array

Passkey::jsonSerialize()

public function jsonSerialize(): array

ProfilePage class

final readonly class ProfilePage implements Screen ProfilePage.php:20

A member's profile (/profile/{id}): the member, whether the viewer is that member, their five latest published threads (newest first, each dated by its publication, else its creation), the account's summary - only for its owner or an administrator, null for anyone else -, and the addresses its owner (or an administrator, for the edit) follows from there.

What a visitor's props carry is what the page shows that visitor: the header (number, name, avatar, roles, presence, dates, counts) and the threads; the account's summary and the owner's addresses stay null.

public Member $member
public bool $own
public array $recent
public ?AccountSummary $account
public ?string $editUrl
public ?string $settingsUrl
public ?string $logoutUrl

ProfilePage::__construct()

public function __construct(public Member $member, public bool $own = false, public array $recent = [], public ?AccountSummary $account = null, public ?string $editUrl = null, public ?string $settingsUrl = null, public ?string $logoutUrl = null)

ProfilePage::toArray()

public function toArray(): array

ProfilePage::jsonSerialize()

public function jsonSerialize(): array

Provider class

final readonly class Provider implements Screen Provider.php:8

A provider one may sign in with (google, "Google"): whether the account signs in with it, the address linking it (while it does not).

public string $name
public string $label
public bool $connected
public ?string $connectUrl

Provider::__construct()

public function __construct(public string $name, public string $label, public bool $connected = false, public ?string $connectUrl = null)

Provider::toArray()

public function toArray(): array

Provider::jsonSerialize()

public function jsonSerialize(): array

Session class

final readonly class Session implements Screen Session.php:13

One of the account's sessions (a connection): its number, the browser's own string and a readable label ("Safari - macOS"), the addresses it came from, when it was last seen, whether it is still open, and the action signing it out (while it is).

public int $id
public ?string $agent
public ?string $label
public array $ips
public ?string $updatedAt
public bool $valid
public ?Action $logout

Session::__construct()

public function __construct(public int $id, public ?string $agent = null, public ?string $label = null, public array $ips = [], public ?string $updatedAt = null, public bool $valid = false, public ?Action $logout = null)

Session::toArray()

public function toArray(): array

Session::jsonSerialize()

public function jsonSerialize(): array

SettingsPage class

final readonly class SettingsPage implements Confidential SettingsPage.php:18

The account's settings (/settings): its name (null for nobody signed in: the page shows its title alone), whether it is a demonstration account (changing nothing of its credentials), its second factor (null where two-factor is not available), its passkeys (null where passkeys are not) and the identifier a new one registers, the sign-in providers shown (those available, and the account's own), its latest sessions, its language (its locale, language: the frame owns locale) and time zone. Its actions carry their tokens: confidential.

public ?string $name
public bool $demo
public ?TwoFactor $twoFactor
public ?array $passkeys
public ?string $identifier
public array $providers
public array $sessions
public ?string $language
public ?string $timezone

SettingsPage::__construct()

public function __construct(public ?string $name = null, public bool $demo = false, public ?TwoFactor $twoFactor = null, public ?array $passkeys = null, public ?string $identifier = null, public array $providers = [], public array $sessions = [], public ?string $language = null, public ?string $timezone = null)

SettingsPage::toArray()

public function toArray(): array

SettingsPage::jsonSerialize()

public function jsonSerialize(): array

TwoFactor class

final readonly class TwoFactor implements Screen TwoFactor.php:17

An account's second factor on its settings page, as the security policy lets its owner change it: whether the administrator requires one (and the account still lacks it), the authenticator app - on or off, the address to switch it on (when it may be), the action switching it off (when it may be: on without it is locked by the administrator) -, the code by e-mail - on or off, locked (on, the only factor left, and required), the action toggling it (when not locked and the account may change its credentials) -, the backup codes left (null while the app is off).

public bool $mandatory
public bool $enrolmentRequired
public bool $totp
public ?string $totpEnable
public ?Action $totpDisable
public bool $email
public bool $emailLocked
public ?Action $emailToggle
public ?int $backupCodes

TwoFactor::__construct()

public function __construct(public bool $mandatory = false, public bool $enrolmentRequired = false, public bool $totp = false, public ?string $totpEnable = null, public ?Action $totpDisable = null, public bool $email = false, public bool $emailLocked = false, public ?Action $emailToggle = null, public ?int $backupCodes = null)

TwoFactor::toArray()

public function toArray(): array

TwoFactor::jsonSerialize()

public function jsonSerialize(): array

Base\Screen\Builder

Accounts class

final class Accounts Accounts.php:42

The account's pages as view models (plan "omnibase agnostique", C5): a member's profile, the account's settings, the member's notifications, from omnibase's entities (a User, its threads and passkeys, its connections, its notifications) and the site's security policy. Framework-free: the addresses through the Urls contract, the forms' tokens through Tokens (the ones given, else Runtime's), "now" from a PSR-20 clock; what only the framework knows (an avatar's thumbnail, the providers available, web push) the caller passes in.

Each page asks the policy and the entities what the template of before asked them, so the pages print the same.

const RECENT = 5

How many of a member's threads their profile lists.

const PROVIDERS = ['google' => 'Google']

The providers a settings page offers, by name: their label.

Accounts::__construct()

public function __construct(readonly ?SecurityPolicy $policy = null, readonly ?Urls $urls = null, readonly ?Tokens $tokens = null, readonly ?ClockInterface $clock = null)

Accounts::member()

public function member(User $user, ?string $avatar = null): Member

A member as their profile shows them.

$avatar

the stored avatar's address at 128 px; null when the account has none

Accounts::profile()

public function profile(User $user, bool $own = false, bool $admin = false, ?string $avatar = null): ProfilePage

A member's profile.

$own

the viewer is that member

$admin

the viewer is an administrator (sees the account's summary, edits the profile)

Accounts::recent()

public function recent(User $user): array
Returns

a member's latest published threads with a title and a page, newest first (by publication, else creation)

Accounts::summary()

public function summary(User $user): AccountSummary

An account's security at a glance, for its owner or an administrator.

Accounts::settings()

public function settings(?User $user, iterable $sessions = [], array $available = []): SettingsPage

The account's settings; for nobody signed in, its title alone.

$sessions

the sessions listed, newest first

$available

whether each provider (self::PROVIDERS) can be linked on this site

Accounts::notifications()

public function notifications(iterable $notifications, int $unread, bool $unreadOnly = false, bool $push = false, ?string $pushKey = null, ?\Closure $adminUrl = null, ?\DateTimeZone $timezone = null): NotificationsPage

The member's notifications.

$notifications

newest first

$adminUrl

the back-office address of what one is about

$timezone

the page's (the days are its days); the machine's when none is given

Accounts::notification()

public function notification(NotificationEntity $notification, ?string $adminUrl = null, ?\DateTimeZone $timezone = null): Notification

Accounts::group()

public function group(?string $moment, ?\DateTimeZone $timezone = null): string

The day a moment falls in, by the clock, in the page's time zone: today, yesterday, within the week, earlier (and earlier for no moment).

Stories class

final class Stories Stories.php:33

omnibase's threads as view models (plan "omnibase agnostique", C5): a thread on a list (Card), on its own page (Story), pointed to (Link), its text (StoryText), its tags, taxa and owners, the comments left on it.

Framework-free: the addresses come from the caller (a closure per kind of link, made with the Urls contract or the framework's router), the images from the Pictures contract, the texts from the Texts contract, "now" from a PSR-20 clock (the one given, else Runtime's); the entities are read through their getters.

What a screen counts or shows beyond that (likes, a count of comments, a site's own reading time) it passes in; what it leaves out stays null.

Stories::__construct()

public function __construct(readonly ?Texts $texts = null, readonly ?Pictures $pictures = null, readonly ?ClockInterface $clock = null, readonly string $recently = '-2 days')

Stories::card()

public function card(Thread $thread, string $url, ?\Closure $tagUrl = null, ?\Closure $taxonUrl = null, ?string $cover = null, ?int $coverWidth = null, ?int $readingMinutes = null, ?int $likes = null, ?string $likeUrl = null, ?int $comments = null): Card

A thread on a list.

$tagUrl

the address listing a tag's stories

$taxonUrl

the address listing a taxon's

$cover

the stored image (null: none); given, the card's cover is its address at $coverWidth, '' when it has none

Stories::story()

public function story(Thread $thread, string $url, ?\Closure $tagUrl = null, ?\Closure $taxonUrl = null, ?string $cover = null, ?int $coverWidth = null, ?int $readingMinutes = null, array $textOptions = [], array $audio = [], ?int $likes = null, ?string $likeUrl = null, bool $commentable = false, ?int $comments = null): Story

A thread on its own page: its card's fields, its text through Texts.

$textOptions

the options of |wysiwyg

$audio

its sounds' addresses

public function link(?Thread $thread, ?string $url): ?Link

A thread pointed to (the one before, after, to read as well); null for none.

Stories::text()

public function text(?string $content, array $options = []): StoryText

A stored text as its page shows it, through the Texts contract.

$options

the options of |wysiwyg

Stories::tags()

public function tags(iterable $tags, \Closure $url, ?string $current = null, bool $marked = false): array

Tags or taxa (any entity with a slug and a label: Base\Entity\Thread\Tag, Taxon).

$current

the slug of the one shown, when the screen marks it

Stories::owners()

public function owners(Thread $thread): array
Returns

the thread's owners, in their order, by their names

Stories::comments()

public function comments(iterable $comments): array

Comments left on a thread (Base\Entity\Thread\Comment, or none for a visitors' book), each with its visible replies: signed by the account's name or the name typed, the website typed as the author's page, staff for an account holding a role besides ROLE_USER.

Stories::isRecent()

public function isRecent(?string $moment): bool

Whether a moment is within the recent window before now (the screen's clock).

Base\Security

ConnectionTracker class

class ConnectionTracker ConnectionTracker.php:22

The browsers an account signs in from: a userConnection row per browser (its PHPUSERID) and account, with the addresses, agent, hosts, locale and time zones it came with. Framework-free (plan "omniauth", step AU8b): the host says who the browser is ($uniqid: the PHPUSERID its session or its cookie holds, a new one kept in both otherwise) and which host it reached ($host). Base\Security\UserTracker is the Symfony one (its RequestStack and omnibase's router); omnibridge/laravel builds this class on Laravel's session, cookies and request - the same rows, whichever host signed in.

const PHPUSERID = "PHPUSERID"

ConnectionTracker::__construct()

public function __construct(UnitOfWork|EntityManagerInterface $unitOfWork, Connections $connectionRepository, readonly ?\Closure $uniqid = null, readonly ?\Closure $host = null)
$uniqid

the browser's PHPUSERID (made and kept by the host when it has none)

$host

the host the request reached

$unitOfWork

the entity manager is deprecated (until 6.0): adapted by UnitOfWorks

ConnectionTracker::getUniqid()

public function getUniqid(): string

ConnectionTracker::getCurrentConnection()

public function getCurrentConnection(?User $user = NULL, bool $allowNewConnection = true): ?Connection

ConnectionTracker::createNewConnection()

public function createNewConnection(User $user): Connection

ConnectionTracker::updateConnection()

public function updateConnection(User $user)

On every authenticated request (UserProvider::refreshUser under Symfony, the guard's Authenticated event under Laravel): flushed only when the connection is new or something about it changed - it flushed the whole unit of work on every request, before the controller had even run.

CookieAnswer class

final class CookieAnswer CookieAnswer.php:13

The visitor's answer about cookies, read on the server: the page's script (@glitchr/flowjs/cookie, which omnibase/consent configures) keeps it in the cookie "cookie-consent" - {"c": {"USER": 1, "LOCATION": 0}, ...}, one yes or no per category. For the few cookies the server writes itself: the script lets nothing be written under a refused category, and neither does the server.

The library's default name; a site that renames it (consent.options.record.name) has no answer here.

CookieAnswer::of()

public static function of(string $category, ?array $cookies = null): ?bool

true or false, null when the visitor has not answered for this category - or the answer is not in this cookie.

$cookies

the request's; PHP's own by default

CookieAnswer::refused()

public static function refused(string $category, ?array $cookies = null): bool

LoginRestrictionInterface interface

interface LoginRestrictionInterface LoginRestrictionInterface.php:5

SignInCaptcha class

class SignInCaptcha SignInCaptcha.php:29

The sign-in's captcha after a few failures, framework-free (plan "omniauth", step AU8b): the failures from an address are counted - whatever identifiers they tried - and from base.guard.sign_in_after of them on, a sign-in from that address must pass the captcha; a success forgets the count. Counted in a PSR-6 pool: one both hosts reach (lesringostars' Redis) makes a captcha one host asks for asked by the other as well.

Base\Security\SignInGuard is it under Symfony (its security events, the sign-in page's form); Base\Auth\Listener\GuardSignIn is it on omniauth's events, under any host. Nothing where glitchr/ux-google's reCAPTCHA already guards the sign-in ($google), nor without omnisense/omnishield and a captcha.

const ACTION = 'login'
const MESSAGE = 'Please confirm that you are not a robot.'

SignInCaptcha::__construct()

public function __construct(protected readonly FormGuard $guard, protected readonly ?CacheItemPoolInterface $cache = null, protected readonly bool $google = false, protected readonly ?LoggerInterface $logger = null)

SignInCaptcha::requiredFor()

public function requiredFor(?string $ip): ?string

The captcha's gateway when a sign-in from this address must pass it; null otherwise.

SignInCaptcha::failures()

public function failures(string $ip): int

SignInCaptcha::failed()

public function failed(string $ip): void

One more failure from this address, remembered WINDOW seconds.

SignInCaptcha::forget()

public function forget(string $ip): void

The failures counted from an address forgotten: a success does it; a test that starts afresh too.

SignInCaptcha::field()

public function field(string $gateway): string

The form field the captcha's widget posts its answer in.

SignInCaptcha::widgetHtml()

public function widgetHtml(?string $ip, ?Translations $translations = null, ?string $locale = null, ?string $nonce = null): string

The captcha's widget for a sign-in page from this address, as the sign-in form prints it under Symfony (omnishield's ChallengeType, its WidgetLocalizer): the gateway's widget for the action "login", in the page's language - its texts from the "omnishield" catalogue -, printed by omnishield's WidgetPrinter. '' when no captcha is asked. For a host whose sign-in page is not a Symfony form (omnibridge/laravel's).

The widget's language is the locale's language ("fr" for fr_FR), as WidgetLocalizer gives it when the catalogue of the full locale defines none of the texts - omnishield ships language catalogues alone.

SignInCaptcha::passes()

public function passes(string $gateway, string $token, ?string $ip): bool

Does the captcha's answer pass? A key the captcha refuses lets the sign-in through (the site's mistake, logged); a captcha that does not answer, unless the guard rejects the unreachable (base.guard).

SignOut class

final class SignOut SignOut.php:24

The sign-out's address, its token in it, for any host.

A sign-out by a plain GET lets any other page sign a visitor out (an <img> or a link to /logout is enough). Where the firewall's logout asks a CSRF token (Symfony's logout: { enable_csrf: true }), the address a page gives carries it: /logout?_csrf_token=.... The page /logout (security_logout, SecurityController::Logout) keeps answering a prefetch with nothing, then hands the token on to the firewall's path (security_logoutRequest), which checks it. Where the firewall asks none, the token in the address is harmless: the firewall reads nothing of it.

The parameter and the intent are Symfony's defaults for the logout listener (csrf_parameter: _csrf_token, csrf_token_id: logout), which a site does not change.

const ROUTE = 'security_logout'

The page a sign-out link goes to (it hands on to REQUEST_ROUTE).

const REQUEST_ROUTE = 'security_logoutRequest'

The firewall's logout path.

const TOKEN_ID = 'logout'

The CSRF token's intent the firewall's logout checks.

const PARAMETER = '_csrf_token'

The query parameter the firewall's logout reads the token from.

SignOut::parameters()

public static function parameters(Tokens $tokens): array
Returns

the parameters a sign-out address carries

SignOut::path()

public static function path(Urls $urls, Tokens $tokens): string

The sign-out's address for the visitor's session, its token in it.

UserTracker class

class UserTracker extends ConnectionTracker UserTracker.php:17

Base\Security\ConnectionTracker under Symfony: the browser's PHPUSERID from the request's session or cookie (a new one kept in both), the host from omnibase's router.

UserTracker::__construct()

public function __construct(UnitOfWork|EntityManagerInterface $unitOfWork, RequestStack $requestStack, AdvancedRouterInterface $router, Connections $connectionRepository)
$unitOfWork

the entity manager is deprecated (until 6.0): adapted by UnitOfWorks

UserTracker::getUniqid()

public function getUniqid(): string

WebauthnUserEntityRepository class

class WebauthnUserEntityRepository implements PasskeyUsers WebauthnUserEntityRepository.php:16

The accounts as passkeys know them (WebauthnBundle's user repository): an account's username is the key's name, its id (as text) the user handle.

The bundle's interface is declared through Base\Contract\PasskeyUsers (plan "omniauth", AU1): theirs where the bundle is installed, empty elsewhere, so the class loads without the bundle.

WebauthnUserEntityRepository::__construct()

public function __construct(Users $userRepository)

WebauthnUserEntityRepository::findOneByUsername()

public function findOneByUsername(string $username): ?PublicKeyCredentialUserEntity

WebauthnUserEntityRepository::findOneByUserHandle()

public function findOneByUserHandle(string $userHandle): ?PublicKeyCredentialUserEntity

Base\Serializer

Aco class

class Aco Aco.php:13

const BYTE_SIZE = 8
const VERSION_V1 = 1
const VERSION_V2 = 2
const RGB = 0
const HSB = 1
const CMYK = 2
const LAB = 7
const GRAYSCALE = 8
const WideCMYK = 9

Aco::parseFile()

public static function parseFile(string $filename, int $flags = self::VERSION_V2): array

Aco::parse()

public static function parse($handle, int $flags = self::VERSION_V2): array
Throws

Exception

Aco::dump()

public static function dump($input, int $flags = 0): string

Aco::getHeader()

public static function getHeader($handle)

Aco::getBlock()

public static function getBlock($handle, int $version)
Throws

Exception

Aco::sortByColor()

public static function sortByColor($array)

Aco::getClosest()

public function getClosest($rgb, $colors)

Excel class

class Excel Excel.php:23

const AS_COLLECTION_KEY = CsvEncoder::AS_COLLECTION_KEY
const HEADERS_IN_BOLD_KEY = 'headers_in_bold'
const HEADERS_HORIZONTAL_ALIGNMENT_KEY = 'headers_horizontal_alignment'
const COLUMNS_AUTOSIZE_KEY = 'columns_autosize'
const COLUMNS_MAXSIZE_KEY = 'columns_maxsize'

Excel::__construct()

public function __construct(mixed $data, string $format, array $context = [])

Excel::dump()

public function dump(): string

Excel::extension()

public static function extension(string $path)

Excel::parseFile()

public static function parseFile(string $filename, array $context = []): mixed

Excel::parse()

public static function parse(string $data, string $format, array $context = []): mixed

Base\Serializer\Encoder

AcoEncoder class

class AcoEncoder implements EncoderInterface, DecoderInterface AcoEncoder.php:9

const FORMAT = 'aco'

AcoEncoder::supportsEncoding()

public function supportsEncoding(string $format, array $context = []): bool

AcoEncoder::encode()

public function encode(mixed $data, string $format, array $context = []): string

AcoEncoder::supportsDecoding()

public function supportsDecoding(string $format, array $context = []): bool

AcoEncoder::decode()

public function decode(string $data, string $format, array $context = []): mixed

ExcelEncoder class

class ExcelEncoder implements EncoderInterface, DecoderInterface ExcelEncoder.php:9

const XLS = 'xls'

Formats constants.

const XLSX = 'xlsx'
const XLSM = 'xlsm'

ExcelEncoder::supportsEncoding()

public function supportsEncoding(string $format, array $context = []): bool

ExcelEncoder::encode()

public function encode(mixed $data, string $format, array $context = []): string

ExcelEncoder::supportsDecoding()

public function supportsDecoding(string $format, array $context = []): bool

ExcelEncoder::decode()

public function decode(string $data, string $format, array $context = []): mixed

Base\Service

Analytics class

class Analytics Analytics.php:24

Single entry point for this app's traffic counters: page views (a raw hit count per path) plus two independent unique-subject counters - anonymous "visitors" (cookie-identified, see the consent note on trackVisitor()) and authenticated "users" (Base\Entity\User ids) - both sliceable by the same time windows (today/24h, 7 days, 30 days, all time) because they're built on the exact same underlying mechanism (Base\Entity\Analytics\Visit's daily presence rows), just keyed differently. Storage/aggregation strategy lives in the two repositories; this class is the only thing application code (a request subscriber, an admin sidebar widget, ...) needs to know about.

Analytics::__construct()

public function __construct(readonly PageViews $pageViews, readonly Visits $visits, readonly UserAgentClassifier $userAgentClassifier, readonly ?PageVisits $pageVisits = null)

Analytics::track()

public function track(string $path, ?string $visitorId = null, ?string $userId = null, ?string $userAgent = null): void

Call once per trackable request. $visitorId is the ANALYTICS/ VISITOR_ID cookie value if present - deliberately never generated or set here: that cookie is written client-side via Cookie.set("ANALYTICS", "VISITOR_ID", ...) (see @glitchr/flowjs/cookie), which silently no-ops without consent. A visit with no visitor cookie still counts toward pageViews() (an anonymous hit, no identity involved) but never toward uniqueVisitors() - consent is what turns a hit into a de-duplicated visitor, not the other way around. $userId has no such gating: it's the already-authenticated session's own account.

$userAgent decides which PageView::SOURCE_* bucket the hit lands in (via UserAgentClassifier) - null (the default, used by callers that never had an HTTP request to read a header from, e.g. this class's own test suite) is treated as SOURCE_HUMAN rather than run through the classifier, which would otherwise classify a truly empty/missing User-Agent as SOURCE_BOT. A hit classified as anything other than SOURCE_HUMAN never reaches the visitor/user presence tables below - a crawler's stray cookie or session should never count as a real unique visitor.

Analytics::pageViews()

public function pageViews(?string $path = null, ?string $window = null, ?string $source = null): int

Total hits. $path null = every page (site-wide). $source null = every source combined (human + bot + ai); pass a PageView::SOURCE_* constant to see just that bucket's hits.

Analytics::uniqueVisitors()

public function uniqueVisitors(?string $window = null): int

Distinct anonymous (cookie-consented) visitors.

Analytics::uniqueViews()

public function uniqueViews(?string $window = null, ?string $path = null): int

Unique views: distinct (page, identified subject) pairs in the window.

pageViews() counts hits - a reload is a view. This counts a person on a page once. Only identified subjects can be told apart, so the two are not comparable as "x% of views were unique": an anonymous visitor who declined the cookie produces views and no unique view at all.

Analytics::retention()

public function retention(?int $days = 7): array

Retention over two back-to-back windows of $days days, the second ending today: the share of subjects active in the earlier window who came back in the later one, per subject type, as a percentage.

Same day boundaries as dailyBreakdown(), so "7" means the same seven days the chart shows. Null when nobody was active in the earlier window (no base to be a share of), or when $days is null - "all time" has no earlier window.

Analytics::uniqueUsers()

public function uniqueUsers(?string $window = null): int

Distinct authenticated user accounts active in the window.

Analytics::summary()

public function summary(): array

The set of numbers an admin sidebar widget wants at a glance - every counter across every standard window in one round trip's worth of queries (9 small aggregate queries, all against the tiny daily-rollup tables - cheap regardless of how much traffic has accumulated behind them).

Analytics::dailyBreakdown()

public function dailyBreakdown(?int $days = 14, string|array|null $path = null): array

Day-by-day series for the last $days calendar days (oldest first, today included) - the raw data a dashboard trend chart plots directly. Unlike summary()'s window totals, a day with genuinely zero activity is filled in as 0 rather than omitted, so a chart never has to guess at a gap in the x-axis.

$days = null means "all time": since the earliest day anything was ever tracked (today, if nothing ever was - a 1-day series rather than an empty one, so callers never have to special-case "no data yet" separately from "no data in this window").

$path null means every page summed together (the original, site- wide semantics); pass an exact path to scope the PAGE-VIEW columns to one page instead (e.g. a single Article's own traffic trend), or a list of paths to scope to any of them (e.g. every Article's own __toLink(), for a whole-class rollup - there's no single stable path PREFIX shared by every instance of a class in this app's routing, so "all articles" means the exact set of their own generated links, not a LIKE pattern). uniqueVisitors/uniqueUsers stay SITE-WIDE regardless of $path - the underlying presence records (Visit) have no path of their own at all (see Visit's own docblock), so "unique visitors to this one page" isn't a question this data model can answer yet. A $path- scoped caller should simply not read those two columns rather than this method fabricating a page-specific number it can't back up.

Analytics::hourlyBreakdown()

public function hourlyBreakdown(string|array|null $path = null): array

Hour-by-hour series for TODAY only (hour 0 through the current hour, oldest first) - the one range short enough that a per-hour curve is actually legible, unlike dailyBreakdown()'s calendar-day grain. No hours past "now" are included (an all-zero flat tail for the rest of the day would just read as "no traffic yet", not as "hasn't happened yet" - the two look identical on a chart, so there's no honest way to zero-fill them).

Same $path convention as dailyBreakdown().

Analytics::periodOverPeriodChange()

public function periodOverPeriodChange(?int $days): array

This $days-day window vs the $days days before it, as a signed percentage per counter - the "up/down vs the prior period" badge a dashboard trend card needs, generalized from what used to be a hardcoded 7-vs-7 (see weekOverWeekChange(), now just this with $days=7 - kept as its own method since existing callers already expect that exact contract). Reuses dailyBreakdown($days*2) rather than four more window queries: the same rows already answer both halves. $days=null (an "all time" window has no prior period to compare against) short-circuits to every counter null, same shape as the "prior period was zero" case below.

Returns

null when the prior period was zero (no meaningful percentage to show) or $days is null

Analytics::weekOverWeekChange()

public function weekOverWeekChange(): array

Analytics::displayBucket()

public static function displayBucket(string $bucket): \DateTimeImmutable

A bucket key from dailyBreakdown()/hourlyBreakdown(), as a date to show.

Hourly keys ("Y-m-d H:i:s", UTC) are shifted to the viewer's own timezone, so 11:00 UTC reads 13:00 in Paris. Daily keys ("Y-m-d") are UTC calendar days and are shown as they are: shifting their midnight would move the date back a day for anyone west of Greenwich.

ArrayParameterBag class

class ArrayParameterBag extends DottedParameterBag ArrayParameterBag.php:16

The application's parameters given as an array, by their full names ("base.attributes.use_custom" => true), read by a dotted path as Base\Service\ParameterBag reads the container's (both are Base\Service\DottedParameterBag): omnibase's ParameterBagInterface where there is no container (an entity manager built by hand, Base\Bridge\Doctrine\Mapping; another framework). A path names a value or the values under it ("base.attributes" is ['use_custom' => true, ...]).

ArrayParameterBag::__construct()

public function __construct(array $parameters = [])

ArrayParameterBag::set()

public function set(string $path, array|bool|string|int|float|UnitEnum|null $value, ?array &$bag = null): void

BaseService class

class BaseService extends Locator BaseService.php:44

The facade of omnibase's services for an application's code (plan "omnibase agnostique", C9): kept, not deprecated, with BaseTrait. Framework-neutral since the plan "omnibase agnostic", step F5c, item 3: its constructor takes nothing of a framework, every host builds it from the core's list (Base\Services), and each method asks omnisense/omnibridge's contracts through Base\Contract\Runtime - the settings, the request's session and route (Requests), the addresses and assets (Urls), the environment (Environment), the visitor (Access), the forms' tokens (Tokens), the unit of work (UnitOfWork), the entity hydrator.

What only a framework has - its kernel and container, its console, its form factory, its profiler, its request, route and response objects - is the host's facade, a subclass of this one: under Symfony omnibridge/symfony's Omnibridge\Symfony\Omnibase\Service\SymfonyBaseService, which the container hands out as base.service and Base\Service\BaseService, so the applications' code and templates calling those methods keep them, with Symfony's services as the fallback of the methods below.

Under Symfony it is a lazy service - a ghost of the class until one of its methods reads a property: the methods a contract answers read none of its properties, called on the ghost they build nothing.

It no longer declares Twig's RuntimeExtensionInterface (plan "omnibase agnostic", F4: Twig is a suggestion of the core): no Twig function was ever answered by it, and the marker made the class unloadable without Twig.

BaseService::__construct()

public function __construct(?EnvironmentContract $environment = null, ?ParameterBagInterface $parameterBag = null, ?string $projectDir = null, ?float $startTime = null)
$environment

what the application runs as (its name kept for BaseTrait's getEnvironment())

$parameterBag

the parameters (kept for BaseTrait's getParameterBag(); base.user.identifier read)

$projectDir

the application's folder

$startTime

when the request (or the process) started; now by default

BaseService::getSite()

public function getSite()

BaseService::getAdmin()

public function getAdmin()

BaseService::getEmail()

public function getEmail()

BaseService::getMeta()

public function getMeta(?string $locale = null): array

BaseService::settings()

public function settings()

BaseService::getExecutionTime()

public function getExecutionTime(): float

BaseService::startTime()

public function startTime(?float $startTime = null)

BaseService::hasGet()

public function hasGet()

BaseService::hasPost()

public function hasPost()

BaseService::hasSession()

public function hasSession()

BaseService::addSession()

public function addSession($name, $value)

A value kept in the visitor's session (Requests::remember()); nothing outside a request.

BaseService::removeSession()

public function removeSession($name)

A value of the visitor's session, taken out of it (Requests::session(), forget()).

BaseService::getSession()

public function getSession($name = null)

A value of the visitor's session (Requests::session()). Without a name, the host's session object, which only the host's facade hands out (Symfony's, omnibridge/symfony): none here.

BaseService::getLocale()

public function getLocale(?string $locale = null)

BaseService::getSalt()

public function getSalt()

BaseService::getSecret()

public function getSecret()

BaseService::getParameter()

public function getParameter(string $name): array|bool|string|int|float|null

A parameter of the application, from its parameters (the host's facade reads its container's).

BaseService::hasParameter()

public function hasParameter(string $name): bool

BaseService::getAsset()

public function getAsset(string $url): string

An asset's address (Urls::asset()).

BaseService::getCurrentRouteName()

public function getCurrentRouteName(): ?string

The route of the request being answered (Requests::route()), null outside one.

BaseService::generateUrl()

public function generateUrl(string $routeName, array $routeParameters = []): string

A route's address, its absolute path (Urls::path()).

BaseService::isDevelopment()

public function isDevelopment()

BaseService::isProduction()

public function isProduction()

BaseService::isCli()

public function isCli()

BaseService::isDebug()

public function isDebug()

BaseService::setUserIdentifier()

public function setUserIdentifier(string $userIdentifier)

Security related methods

BaseService::isCsrfTokenValid()

public function isCsrfTokenValid(string $id, $tokenOrForm, $request = null, string $csrfFieldId = "_csrf_token"): bool

Whether a token sent back is the visitor's token of that intent (Tokens::isValid()). The host's facade also takes a form and its request (Symfony's).

Throws

Exception

BaseService::getUser()

public function getUser()

The visitor signed in, null for none (Access::getUser()).

BaseService::isGranted()

public function isGranted($attribute, $subject = null): bool

Whether the visitor is granted that attribute (Access::isGranted()).

BaseService::inDoctrine()

public function inDoctrine($entity): bool

Whether the unit of work manages that entity (UnitOfWork::contains()).

BaseService::inDoctrineStack()

public function inDoctrineStack()

BaseService::getOriginalEntityData()

public function getOriginalEntityData($eventOrEntity, bool $inDoctrineStack = false, bool $reopen = false)

An entity's values as read or last flushed - of the entity, or of a lifecycle event's, a PreUpdate's changes read as the values before -: the entity hydrator's, on the unit of work's Snapshots.

$reopen

the host's facade reopens a closed entity manager (Symfony's, on Doctrine)

Throws

Exception

BaseService::getOriginalEntity()

public function getOriginalEntity($eventOrEntity, bool $inDoctrineStack = false, bool $reopen = false)

The entity given (or the lifecycle event's) hydrated with its original values.

Throws

Exception

Breadgrinder class

class Breadgrinder implements BreadgrinderInterface Breadgrinder.php:8

Breadgrinder::__construct()

public function __construct(RouterInterface $router, TranslatorInterface $translator, ParameterBagInterface $parameterBag)

Breadgrinder::has()

public function has(string $name): bool

Breadgrinder::grind()

public function grind(string $name, array $options = [], ?string $template = null): Breadcrumb

BreadgrinderInterface interface

interface BreadgrinderInterface BreadgrinderInterface.php:7

BreadgrinderInterface::grind()

public function grind(string $name): Breadcrumb

ColorExtractor class

class ColorExtractor ColorExtractor.php:9

ColorExtractor::__construct()

public function __construct(Palette $palette)

ColorExtractor::extract()

public function extract(int $colorCount = 1): array

CommentGuard class

class CommentGuard CommentGuard.php:20

The comment forms' face of Base\Service\FormGuard, kept for the bundles that ask it (omnibase/blog, omnibase/video): the trap filled, a form sent faster than a person types, a second comment from the same address within the flood interval (base.comments.min_delay, base.comments.flood_interval).

Each answers with a reason the controller turns into a form error - except the trap, which should be thanked and dropped so the robot learns nothing.

Reads the form Base\Form\Type\CommentType builds: its url trap and its opened time - or the fields the option guard adds.

const TRAPPED = FormGuard::TRAPPED
const TOO_FAST = FormGuard::TOO_FAST
const FLOOD = FormGuard::FLOOD

CommentGuard::__construct()

public function __construct(protected readonly FormGuard $guard, protected readonly int $minDelay = 4, protected readonly int $floodInterval = 60)

CommentGuard::check()

public function check(FormInterface $form, Request $request, ?int $minDelay = null, ?int $floodInterval = null): ?string

null when the comment may go on to Akismet.

DottedParameterBag class

abstract class DottedParameterBag implements ParameterBagInterface DottedParameterBag.php:19

The application's parameters by their full names ("base.attributes.use_custom" => true), read by a dotted path (plan "omnibase agnostique", C9): the framework-free source both Base\Service\ArrayParameterBag (an array) and Base\Service\ParameterBag (the Symfony container's parameters) read through.

A path names a value or the values under it ("base.attributes" is ['use_custom' => true, ...]); a $bag given to get() is laid over the parameters, by key. has() is whether get() finds a value - a parameter set to false, 0 or "" is there; one set to null is not.

DottedParameterBag::all()

public function all(): array

DottedParameterBag::get()

public function get(string $key = "", ?array $bag = null): array|bool|string|int|float|UnitEnum|null

DottedParameterBag::has()

public function has(string $path, ?array $bag = null): bool

class DownloadLinks DownloadLinks.php:22

Signed download links: a route's absolute URL, signed by Symfony's UriSigner and valid for a while (base.download_links.ttl seconds unless told otherwise). Whoever holds one within that time gets the file - who may was checked when it was handed out (a licence, an entitlement, a voter). The one place for it: omnibase/forge's artifacts and omnibase/classroom's resources sign theirs here.

$url = $links->sign('forge_download_file', ['id' => 7, 'filename' => 'app.zip', 'license' => 3], 900); // in the download action: if (!$links->verify($request)) { throw $this->createAccessDeniedException(); }

public function __construct(protected readonly UriSigner $signer, protected readonly UrlGeneratorInterface $router, protected readonly int $ttl = 600)
public function sign(string $route, array $parameters = [], ?int $ttl = null): string
$parameters

the route's parameters, and who the link was issued to

public function verify(Request $request): bool

The request's URL is one this site signed, and it has not run out.

public function ttl(): int

EditorEnhancer class

class EditorEnhancer extends WysiwygEnhancer implements EditorEnhancerInterface EditorEnhancer.php:8

EditorEnhancer::supports()

public function supports(mixed $json): bool

EditorEnhancer::render()

public function render(mixed $json, array $options = []): string

EditorEnhancer::getTableOfContents()

public function getTableOfContents(mixed $json, ?int $maxLevel = null): array

EditorEnhancer::enhanceHeadings()

public function enhanceHeadings(mixed $json, ?int $maxLevel = null, array $attrs = []): mixed

EditorEnhancer::enhanceSemantics()

public function enhanceSemantics(mixed $json, null|array|string $words = null, array $attrs = []): mixed

EditorEnhancer::enhanceMentions()

public function enhanceMentions(mixed $json, array $attrs = []): mixed
public function enhanceLinks(mixed $json, array $attrs = []): mixed

EditorEnhancer::enhanceMedia()

public function enhanceMedia(mixed $json, array $config = [], FilterInterface|array $filters = [], array $attrs = []): mixed

EditorEnhancerInterface interface

interface EditorEnhancerInterface extends WysiwygEnhancerInterface EditorEnhancerInterface.php:5

Embeds class

class Embeds Embeds.php:25

An address (a video, a song, a board, a slideshow) turned into what a page can frame - the Twig function embed_url():

{% set frame = embed_url(link) %} {% if frame and frame.src %}<iframe src="{{ frame.src }}" style="aspect-ratio: {{ frame.ratio }}"…>{% endif %}

The providers known to allow framing are read from the address itself, without a request (KNOWN: YouTube in its no-cookie form, Vimeo, Canva, Padlet, LearningApps, Genially, Google Slides). Anything else is asked to its own site through the embed/embed library (oEmbed, Open Graph), once a day per address, when the library is installed; its iframe's address is kept, never its script. Nothing found: null - a plain link on the page.

const KNOWN = ['Canva', 'Padlet', 'YouTube', 'Vimeo', 'LearningApps', 'Genially', 'Google Slides']

Embeds::__construct()

public function __construct(protected readonly ?CacheInterface $cache = null, protected readonly ?LoggerInterface $logger = null, protected readonly bool $remote = true)

Embeds::resolve()

public function resolve(?string $url, bool $remote = true): ?array

Embeds::known()

public function known(string $url): ?array
Returns

the providers read from the address alone

FileService class

class FileService implements FileServiceInterface FileService.php:15

const USE_SHORT = Obfuscator::USE_SHORT

FileService::__construct()

public function __construct(Views|Environment|null $views, MediaRouter $router, ObfuscatorInterface $obfuscator, Storages $flysystem, ParameterBagInterface $parameterBag)
$views

Twig's environment is deprecated (until 6.0)

FileService::getRouter()

public function getRouter(): MediaRouter

The router the addresses are made and read with (Base\Service\ImageRoute's redirections too).

FileService::getProjectDir()

public function getProjectDir()

FileService::getPublicDir()

public function getPublicDir()

FileService::getExtension()

public function getExtension(null|string|array $fileOrMimetypeOrArray): ?string

FileService::getExtensions()

public function getExtensions(null|string|array $fileOrMimetypeOrArray): array

FileService::getMimeType()

public function getMimeType(null|string|array $fileOrContentsOrArray): null|string|array

FileService::linkable()

public function linkable(array|string|null $path, array $config = []): array|string|null

FileService::downloadable()

public function downloadable(array|string|null $path, array $config = []): array|string|null

FileService::public()

public function public(array|string|null $path, ?string $storage = null): array|string|null

FileService::asset()

public function asset(string $path, ?string $packageName = null): ?string

FileService::isEmpty()

public function isEmpty(?string $file)

FileService::isImage()

public function isImage(?string $file)

FileService::isSvg()

public function isSvg(?string $file)

FileService::filesize()

public function filesize($size, array $unitPrefix = DECIMAL_PREFIX): string

FileService::obfuscate()

public function obfuscate(string|null $path, array $config = []): ?string

FileService::generate()

public function generate(string $proxyRoute, array $proxyRouteParameters = [], ?string $path = null, array $config = []): ?string

FileService::resolve()

public function resolve(string $data): ?array

FileService::serve()

public function serve(?string $path, int $status = 200, array $headers = []): ?Response

FileService::serveContents()

public function serveContents(?string $contents, int $status = 200, array $headers = []): ?Response

FileServiceInterface interface

interface FileServiceInterface FileServiceInterface.php:7

FileServiceInterface::getExtension()

public function getExtension(null|string|array $fileOrMimetypeOrArray): ?string

FileServiceInterface::getExtensions()

public function getExtensions(null|string|array $fileOrMimetypeOrArray): null|string|array

FileServiceInterface::getMimeType()

public function getMimeType(null|string|array $fileOrContentsOrArray): null|string|array

FileServiceInterface::generate()

public function generate(string $proxyRoute, array $proxyRouteParameters, ?string $path, array $config = []): ?string

FileServiceInterface::resolve()

public function resolve(string $data): ?array

FileServiceInterface::serve()

public function serve(?string $path, int $status = 200, array $headers = []): null|bool|Response

FileServiceInterface::serveContents()

public function serveContents(?string $contents, int $status = 200, array $headers = []): null|bool|Response

Flysystem class

class Flysystem implements FlysystemInterface, Storages Flysystem.php:39

omnibase's storages, by name ("local.cache", "local.uploads", "s3.private"...), read and written through omnisense/omnidrive (plan "omnidrive", 2026-10-23): each storage is an Omnidrive\Drive of the Omnidrive\Drives the host gives - under Symfony the storages of flysystem-bundle's configuration (the services tagged flysystem.storage), or omnibase's local ones without the bundle (FlysystemStoragesPass); under Laravel its disks (omnibridge/laravel). A PSR-11 container of Flysystem operators is still accepted, read as Omnidrive\Flysystem\OperatorDrives.

New code type-hints Omnidrive\Drives (getDrives(), getDrive()). What speaks Flysystem itself - getOperator(), getAdapter(), getConnectionOptions() and the FilesystemOperator arguments - is kept for one release, deprecated (FlysystemInterface).

Flysystem::getProjectDir()

public static function getProjectDir()

Flysystem::getPublicDir()

public static function getPublicDir()

Flysystem::__construct()

public function __construct(Drives|ContainerInterface $storages)

Flysystem::getDrives()

public function getDrives(): Drives

The storages, as omnidrive's drives.

Flysystem::getDrive()

public function getDrive(FilesystemOperator|string|null $storage = null): Drive

A storage as an omnidrive drive: by its name, the default one when null.

Flysystem::createStorage()

public function createStorage(string $source, ?string $storageName = null): FilesystemOperator

since omnibase 4.0, the operator behind a drive: getDrive()

Flysystem::hasStorage()

public function hasStorage(string $storageName): bool

Flysystem::getStorageNames()

public function getStorageNames(bool $public = true): array

Flysystem::getDefaultStorage()

public function getDefaultStorage(): FilesystemOperator

since omnibase 4.0, the default drive: getDrive()

Flysystem::setDefaultStorage()

public function setDefaultStorage(FilesystemOperator|string $operator)

Flysystem::getOperator()

public function getOperator(FilesystemOperator|string|null $operator = null): FilesystemOperator

since omnibase 4.0, Flysystem's operator behind a storage: getDrive() reads and writes it

Flysystem::getAdapter()

public function getAdapter(FilesystemOperator|string|null $operator = null): FilesystemAdapter

since omnibase 4.0, Flysystem's adapter behind a storage

Flysystem::getConnectionOptions()

public function getConnectionOptions(FilesystemOperator|string|null $operator = null): ?array

Flysystem::prefixPath()

public function prefixPath(string $path, FilesystemOperator|string|null $operator = null)

Flysystem::stripPrefix()

public function stripPrefix(string $path, FilesystemOperator|string|null $operator = null)

Flysystem::read()

public function read(string $path, FilesystemOperator|string|null $operator = null): ?string

Flysystem::write()

public function write(string $path, string $contents, FilesystemOperator|string|null $operator = null, array $config = []): bool

Flysystem::delete()

public function delete(string $path, FilesystemOperator|string|null $operator = null): bool

Flysystem::fileExists()

public function fileExists(string $path, FilesystemOperator|string|null $operator = null): bool

Flysystem::mkdir()

public function mkdir(string $path, FilesystemOperator|string|null $operator = null, array $config = []): bool

Flysystem::mimeType()

public function mimeType(string $path, FilesystemOperator|string|null $operator = null): ?string

Flysystem::get()

public function get(mixed $path, FilesystemOperator|string|null $operator = null)

Flysystem::getPublicRoot()

public function getPublicRoot(FilesystemOperator|string|null $operator = null): ?string

Flysystem::isRemote()

public function isRemote(FilesystemOperator|string|null $operator = null)

Flysystem::getPublic()

public function getPublic(mixed $path, FilesystemOperator|string|null $operator = null)

FlysystemInterface interface

interface FlysystemInterface FlysystemInterface.php:14

since omnibase 4.0, kept for one release: Base\Service\Flysystem reads its storages through omnisense/omnidrive (Flysystem::getDrives(), getDrive()); new code type-hints Omnidrive\Drives.

omnibase's storages over Flysystem's types.

FlysystemInterface::getProjectDir()

public static function getProjectDir()

FlysystemInterface::getPublicDir()

public static function getPublicDir()

FlysystemInterface::hasStorage()

public function hasStorage(string $storageName): bool

FlysystemInterface::getStorageNames()

public function getStorageNames(bool $public = true): array

FlysystemInterface::getDefaultStorage()

public function getDefaultStorage(): FilesystemOperator

FlysystemInterface::setDefaultStorage()

public function setDefaultStorage(FilesystemOperator|string $operator)

FlysystemInterface::getPublic()

public function getPublic(mixed $path, FilesystemOperator|string|null $operator = null)

FlysystemInterface::getPublicRoot()

public function getPublicRoot(FilesystemOperator|string|null $operator = null): ?string

FlysystemInterface::getOperator()

public function getOperator(FilesystemOperator|string|null $operator = null): FilesystemOperator

FlysystemInterface::getAdapter()

public function getAdapter(FilesystemOperator|string|null $operator = null): FilesystemAdapter

FlysystemInterface::prefixPath()

public function prefixPath(string $path, FilesystemOperator|string|null $operator = null)

FlysystemInterface::stripPrefix()

public function stripPrefix(string $path, FilesystemOperator|string|null $operator = null)

FlysystemInterface::read()

public function read(string $path, FilesystemOperator|string|null $operator = null): ?string

FlysystemInterface::write()

public function write(string $path, string $contents, FilesystemOperator|string|null $operator = null, array $config = []): bool

FlysystemInterface::delete()

public function delete(string $path, FilesystemOperator|string|null $operator = null): bool

FlysystemInterface::fileExists()

public function fileExists(string $path, FilesystemOperator|string|null $operator = null): bool

FlysystemInterface::isRemote()

public function isRemote(FilesystemOperator|string|null $operator = null)

FlysystemInterface::mkdir()

public function mkdir(string $path, FilesystemOperator|string|null $operator = null, array $config = []): bool

FlysystemInterface::mimeType()

public function mimeType(string $path, FilesystemOperator|string|null $operator = null): ?string

FlysystemInterface::get()

public function get(mixed $path, FilesystemOperator|string|null $operator = null)

FormGuard class

class FormGuard FormGuard.php:45

What stands between a form and a robot, in the order it is asked (docs/20-architecture/guard.md):

1. the trap - a field off-screen for people, filled by robots; 2. the time - a form sent faster than a person reads it, by a stamp signed with the application's secret when it was shown; 3. the lists - whoever sends it (address, e-mail, name) asked of the gateways of base.guard.reputation: disposable e-mail domains, StopForumSpam; 4. the captcha - a field of omnisense/omnishield (ChallengeType) on the gateway of base.guard.challenge, checked by the guard - shown and asked only from base.guard.captcha_after refused tries of this form from this visitor (counted in cache.app for 15 minutes, forgotten after a form sent); 5. what was written - the classifier behind SpamChecker (Akismet), for the data that implement SpamProtectionInterface.

Without omnisense/omnishield, or without a gateway, the trap and the time alone. The option guard of a form asks for it (Base\Form\Extension\FormTypeGuardExtension); CommentGuard is the comment forms' face of it, with their flood interval.

Each answer is a reason, a translation key of the "forms" domain (guard.<reason>) - but the trap, which a controller may rather thank and forget, so that the robot learns nothing.

const TRAPPED = 'trapped'
const TOO_FAST = 'too_fast'
const STALE = 'stale'
const FLOOD = 'flood'
const KNOWN = 'known'
const DISPOSABLE = 'disposable'
const UNREACHABLE = 'unreachable'
const SPAM = 'spam'
const CHALLENGE_MISSING = 'challenge_missing'

The captcha's answers: no token, a token refused, a provider that did not answer.

const CHALLENGE_FAILED = 'challenge_failed'
const CHALLENGE_UNREACHABLE = 'challenge_unreachable'
const CHALLENGE_MESSAGES = [self::CHALLENGE_MISSING => 'Please confirm that you are not a robot.', self::CHALLENGE_FAILED => 'The check that you are not a robot did not pass. Please tr…

What they say: omnisense/omnishield's own sentences (PassesChallenge), translated in the "validators" domain.

const TRAP_FIELD = 'guard_website'

The fields the option guard adds to a form: the trap, the stamp, the captcha.

const STAMP_FIELD = 'guard_opened'
const CHALLENGE_FIELD = 'guard_captcha'
const FALLBACK_FIELD = 'guard_captcha_fallback'

The captcha that reaches nobody, shown while the visitor has not agreed to the one that does.

const ATTEMPT_WINDOW = 900

Seconds a refused try of a form is remembered (base.guard.captcha_after).

FormGuard::__construct()

public function __construct(protected readonly string $secret, protected readonly array $config = [], protected readonly ?Registry $registry = null, protected readonly ?Comments $comments = null, protected readonly ?string $defaultChallenge = null, protected readonly ?LoggerInterface $logger = null, protected readonly bool $acceptUnreachableChallenge = false, protected readonly ?CacheItemPoolInterface $cache = null, protected readonly ?ClockInterface $clock = null)
$config

base.guard

$defaultChallenge

omnishield.challenge.gateway, when omnisense/omnishield is installed (Base\Discovery's arguments)

$cache

where a form's refused tries are counted; without it, the captcha is always asked

$clock

what "now" is for the stamp and the delays: the framework's clock (Symfony's clock, autowired), else the clock contract of the Foundation (Runtime::clock(), the machine's when no framework gave one) - a test moves it instead of waiting

FormGuard::now()

public function now(): int

Now, in seconds, by the clock (never the machine's time() directly: a test moves the clock, it does not sleep).

FormGuard::hasOmnishield()

public function hasOmnishield(): bool

Whether omnisense/omnishield is here, with its gateways.

FormGuard::getRegistry()

public function getRegistry(): ?Registry

FormGuard::minDelay()

public function minDelay(): int

FormGuard::signInAfter()

public function signInAfter(): int

Failed sign-ins from an address before the sign-in form asks the captcha. 0: never.

FormGuard::captchaAfter()

public function captchaAfter(): int

Refused tries of a guarded form, from a visitor, before its captcha is shown and asked. 0: always.

FormGuard::captchaAsked()

public function captchaAsked(string $form, int $after, Request|string|null $request): bool

Whether the captcha of the form $form is shown and asked of this visitor: always when $after is 0, or when their tries cannot be counted (no cache, no address, no session); otherwise from $after tries refused.

FormGuard::failures()

public function failures(string $form, Request|string|null $request): ?int

The refused tries of the form $form from this visitor in the last 15 minutes; null when they cannot be counted.

FormGuard::failed()

public function failed(string $form, Request|string|null $request): void

One more refused try: the guard said no (trap, time, lists, captcha, spam), or the form is invalid.

FormGuard::succeeded()

public function succeeded(string $form, Request|string|null $request): void

A form sent: its tries are forgotten.

FormGuard::challengeGateway()

public function challengeGateway(bool $field = true): ?string

The captcha's gateway: base.guard.challenge, else omnishield's default - null when there is none, or, for a Symfony form ($field), when omnishield's form field is missing. A host that prints the gateway's widget itself (the sign-in page under Laravel: SignInCaptcha) asks without $field - omnishield's field is a Symfony form type, whose class does not even load without symfony/form.

FormGuard::fallbackGateway()

public function fallbackGateway(): ?string

The captcha shown to a visitor who refused the third party the default one reaches.

FormGuard::reputationGateways()

public function reputationGateways(): array
Returns

the lists asked about whoever submits, those configured in omnishield

FormGuard::classifierGateway()

public function classifierGateway(): ?string

FormGuard::rejectsUnreachable()

public function rejectsUnreachable(): bool

FormGuard::stamp()

public function stamp(?int $time = null): string

When the form was shown, signed: "<time>.<signature>".

FormGuard::elapsed()

public function elapsed(?string $stamp): ?int

Seconds since the stamp was made; null for one that is not ours (forged, cut, missing).

FormGuard::inspect()

public function inspect(FormInterface $form, ?Request $request, ?int $minDelay = null, string $emailField = 'email', string $nameField = 'name', bool $lists = true): ?array

The trap and the time of a guarded form (the fields the option guard added), then the lists. Null when the form may go on to its captcha and its classifier.

Returns

the reason, and the field it is about (null: the form)

FormGuard::inspectValues()

public function inspectValues(array $values, ?string $address, ?int $minDelay = null, ?string $email = null, ?string $name = null, bool $lists = true): ?array

inspect() on what a form sent, whichever host read it: the values of TRAP_FIELD and STAMP_FIELD, when the form has them.

Returns

the reason, and the field it is about (null: the form)

FormGuard::reputation()

public function reputation(Identity $identity): ?string

What the lists of base.guard.reputation say of whoever submits: null when none knows them; DISPOSABLE for an e-mail of a throwaway domain; KNOWN otherwise; UNREACHABLE for a list that did not answer when base.guard.unreachable is "reject".

FormGuard::challenge()

public function challenge(string $gateway, ?string $token, Request|string|null $request, ?string $action = null): ?string

The captcha's token, asked of its gateway - once, after the trap, the time and the lists: a robot they caught spends nothing at the provider.

Null when it holds; otherwise one of CHALLENGE_*. A provider that does not answer follows omnishield.challenge.unreachable; a key refused is the site's error, let through and logged.

FormGuard::check()

public function check(FormInterface $form, Request $request, ?int $minDelay = null, int $floodInterval = 0): ?string

The comment forms' check (Base\Form\Type\CommentType: its url trap, its opened time; or the fields the option guard adds), and a second comment from the same address within $floodInterval. Null when the comment may go on to its classifier.

GroupManager class

class GroupManager GroupManager.php:34

The one service that turns a score into an actual capability.

Everything up to here computes and grants nothing: Group::isOpenTo() says whether somebody qualifies and Group::awardsFor() says what they would get, both without touching them. Something has to close the gap, and in the marketplace that something is a single service - MarketplaceManager - which evaluates every candidate's scopes and rules, then applies what its actions return. This is the same thing for people.

The evaluation loop is deliberately the same shape as getPromotion()'s, including its short-circuits, with one difference that matters: a promotion stops at the first candidate that fits, because a product gets one promotion. A person can qualify for several groups at once, so nothing breaks out of the candidate loop here.

Permission tags are resolved to rows here rather than in the adapter, which is the whole reason GrantPermissionAdapter returns strings: an entity that queries is an entity you cannot evaluate offline, so the lookup belongs in the only layer that already has a repository.

GroupManager::__construct()

public function __construct(protected readonly GroupRepository $groupRepository, protected readonly PermissionRepository $permissionRepository, UnitOfWork|EntityManagerInterface $unitOfWork)
$unitOfWork

the entity manager is deprecated (until 6.0): adapted by UnitOfWorks

GroupManager::getEligibleGroups()

public function getEligibleGroups(User $user): array

Every group that would admit this user as things stand.

Includes ones they already belong to: this answers "do they qualify", not "what is new", because a group they qualified for yesterday and no longer do is exactly what a caller checking for revocation needs to see missing from this list.

GroupManager::getAwards()

public function getAwards(User $user): array

What those groups would award, merged across all of them.

GroupManager::synchronize()

public function synchronize(User $user, bool $join = true): array

Bring the user in line with what they have earned, and report what actually changed.

Additive by design. Nothing here removes a role, a permission or a membership, because "no longer eligible" and "should be stripped" are different decisions: a punitive score dip should not silently cost somebody a rank they were given, and deciding otherwise is a policy call for the caller rather than a side effect of a sync. getAwards() above is what a caller compares against to make that call.

Returns only the differences, so an unchanged user yields empty arrays and a caller can flush, notify or log on that alone.

HotParameterBagInterface interface

interface HotParameterBagInterface extends ParameterBagInterface HotParameterBagInterface.php:15

The parameters with the settings stored in the database laid over them: Base\Service\HotParameters (plan "omnibase agnostique", C9), which parameter_bag is under Symfony (omnibridge/symfony's HotParameterBag, also DependencyInjection's ParameterBagInterface) and the parameters under omnibridge/laravel. Since step F5c of plan "omnibase agnostic" it extends omnibase's ParameterBagInterface, no longer DependencyInjection's.

HotParameterBagInterface::add()

public function add(array $parameters): void

The settings, by the parameter's full name, laid over the configuration.

HotParameterBagInterface::get()

public function get(string $path = "", ?array $bag = null, bool $useHotBag = true): array|bool|string|int|float|UnitEnum|null

HotParameterBagInterface::has()

public function has(string $path, ?array $bag = null, bool $useHotBag = true): bool

HotParameterBagInterface::markAsReady()

public function markAsReady(bool $ready = true)

HotParameterBagInterface::isReady()

public function isReady(): bool

HotParameters class

class HotParameters implements HotParameterBagInterface HotParameters.php:41

The settings stored in the database laid over any parameters (plan "omnibase agnostique", C9): the "hot" overlay of HotParameterBag, framework-free. A setting linked to a parameter ("bag" in the back office) is given by add() (under Symfony HotParameterBagSubscriber, on the first request or command, from the SettingBag) and read in place of the configuration's value.

get() reads, in this order, and by the presence of a key, not by its truth: 1. the $bag given to the call, 2. the hot settings (when the overlay is on and $useHotBag is true), 3. the configuration (the parameters it is laid over). The first that has the path answers - a setting stored as false, 0 or "" wins over the configuration's true; a value of null is no value, the next source is read. A path naming values under it ("base.user") gives them all, each from the first source that has it. has() reads the same sources in the same order.

warm() takes the settings in once, from the SettingBag (or a callable that gives them): what the host does on the first request or command (Symfony: omnibridge/symfony's HotParameterBagSubscriber; omnibridge/laravel when the parameters are first built), catching its own store's errors.

The overlay is on when the configuration says so (base.parameter_bag.use_hot_bag: true) or when it is built on. Off, get() and has() read the $bag given and the configuration: the parameters are always there.

It replaces HotParameterBag's former logic, which chained the sources on their truth (a false setting gave way to the configuration's value), read nothing at all when use_hot_bag was not true (every parameter null unless a $bag was given), took its settings in through the exception the frozen bag's add() threw, and ordered has() differently from get().

const HOT_N_READY = false

HotParameters::__construct()

public function __construct(protected readonly ParameterBagInterface $config, ?bool $enabled = null)

HotParameters::isEnabled()

public function isEnabled(): bool

Whether the settings are laid over the configuration: base.parameter_bag.use_hot_bag, unless built with a choice.

HotParameters::add()

public function add(array $parameters): void

The settings given, over those given before (a value of null takes one back).

HotParameters::all()

public function all(): array

HotParameters::get()

public function get(string $path = "", ?array $bag = null, bool $useHotBag = true): array|bool|string|int|float|UnitEnum|null

HotParameters::has()

public function has(string $path, ?array $bag = null, bool $useHotBag = true): bool

HotParameters::set()

public function set(string $path, array|bool|string|int|float|UnitEnum|null $value, ?array &$bag = null): void

Writes into the $bag given, as the configuration's set() does.

HotParameters::warm()

public function warm(SettingBagInterface|callable $settings): bool

The settings taken in, once: nothing when they are in already. The store's error is left to the host, which knows its own (a database not created yet: the configuration alone, not ready).

Returns

whether they were taken in now

HotParameters::isReady()

public function isReady(): bool

HotParameters::markAsReady()

public function markAsReady(bool $ready = true)

IconProvider class

class IconProvider extends AbstractLocalCache IconProvider.php:15

IconProvider::__construct()

public function __construct(AttributeReader $attributeReader, MediaServiceInterface $mediaService, LocalizerInterface $localizer, AdvancedRouterInterface $router, string $cacheDir, ?string $buildDir = null)

IconProvider::warmUp()

public function warmUp(string $cacheDir, ?string $buildDir = null): array

IconProvider::getRouteIcons()

public function getRouteIcons(?string $route = null)

IconProvider::getAdapters()

public function getAdapters()

IconProvider::getAdapter()

public function getAdapter(string $idOrClass): ?IconAdapterInterface

IconProvider::addAdapter()

public function addAdapter(IconAdapterInterface $provider): self

IconProvider::removeAdapter()

public function removeAdapter(IconAdapterInterface $provider): self

IconProvider::icons()

public function icons(): Icons

The icons' rule over this provider's adapters and the routes' icons it reads (Icons, framework-free: what |iconify answers by).

IconProvider::iconify()

public function iconify(null|string|array|EnumType|IconizeInterface $icon, array $attributes = [], bool $wrap = true): null|string|array

Icons class

final class Icons Icons.php:21

omnibase's |iconify: an icon's name, a list of them, an enumeration's or an IconizeInterface's icons, or a route's (the icons its controller declares, #[Iconize]) as HTML, by the first adapter that knows the name (Font Awesome, Bootstrap's icons...), a question mark for none.

Framework-free (audit "lesringostars face au master plan", R24): the adapters and a route's icons are given - under Symfony by IconProvider (its adapters, the route icons it reads from the router: icons()), under Laravel by omnibridge/laravel (the same adapters, the Routes contract's icons()). The rule was IconProvider::iconify(), which now answers by it.

Icons::__construct()

public function __construct(readonly iterable|\Closure $adapters, readonly ?\Closure $routeIcons = null)
$routeIcons

a route's icons, null for none

Icons::getAdapters()

public function getAdapters(): iterable

Icons::adapter()

public function adapter(string $idOrClass): ?IconAdapterInterface

The adapter of that class, or the first that supports that name or icon (fa, fa-solid fa-icons), as IconProvider::getAdapter() finds it; null for none.

Icons::iconify()

public function iconify(null|string|array|EnumType|IconizeInterface $icon, array $attributes = [], bool $wrap = true): null|string|array

ImageRoute class

class ImageRoute ImageRoute.php:32

omnibase's image route, answered for any host (audit "lesringostars face au master plan", R6): what Base\Controller\UX\MediaController answered under Symfony, moved here as it was, so that a host without the framework serves the same images and thumbnails from the same addresses - an obfuscated data resolved by MediaService, its file filtered by Imagine (a format, a thumbnail, a crop) and kept in the local.cache storage, a redirection to the address with the right extension, the placeholder when nothing resolves.

MediaController keeps its routes and its actions, and delegates here; omnibridge/laravel declares ROUTES on Laravel's router and calls the same actions. Its answers are HttpFoundation responses, which both frameworks send as they are; what it throws for a missing image (NotFoundHttpException) both render as a 404. The profiler's part stays the host's: $profiler says whether the request keeps it (Symfony: not on an ux_ route), the served image carries that flag to MediaService::serve() as before.

const ROUTES = ['ux_serve' => ['/contents/{data}', 'contents', false], 'ux_imageCropExtension_cacheless' => ['/images/cacheless/cropper/{identifier}/{data}/image.{extension…

The image routes, in the order MediaController declares them (Symfony matches them in that order, a host that declares them keeps it): name => [path, action, cacheless]. The action is this class's method; cacheless, the same action without the local cache. The data takes any character, slashes included (".+"). tests/Service/ImageRouteTest keeps the list equal to MediaController's #[Route] attributes.

ux_debug_image and ux_debug_imageExtension (MediaController::ImageDebug, for an editor, through Security) are left out: Symfony's alone.

ImageRoute::__construct()

public function __construct(MediaService $mediaService, Storages $flysystem, ?ImageCrops $imageCropRepository = null, ?bool $localCache = null)

ImageRoute::with()

public function with(?bool $localCache = null, ?bool $profiler = null): static

The same route for one request: the local cache used or not (the cacheless routes), the profiler kept or not (MediaService::serve()).

ImageRoute::cacheless()

public function cacheless(): static

The same route without the local cache: the cacheless routes.

ImageRoute::redirectToRoute()

public function redirectToRoute(string $route, array $parameters = [], int $status = 302): RedirectResponse

A redirection to an image route, its cacheless twin when the local cache is off, as MediaController::redirectToRoute() made it.

ImageRoute::contents()

public function contents($data): Response

A stored file as it is (ux_serve), an attachment when its data says so.

ImageRoute::imageCrop()

public function imageCrop($data, string $identifier, ?string $extension = null): Response

ImageRoute::imageWebp()

public function imageWebp($data): Response

ImageRoute::imageSvg()

public function imageSvg($data): Response

ImageRoute::image()

public function image($data, ?string $extension = null, bool $debug = false): Response

Invitations class

class Invitations Invitations.php:21

Invitation by token: nobody signs up, someone is invited. The token is random, sent once and never stored - only its SHA-256 is kept, so a leaked table opens nothing. Following the link creates the account (the link proved the address) or attaches the one that exists.

A bundle extends it to say what an invitation opens and what accepting does (omnibase/estate's Invitations); the token, the lookup, the expiry and the account are here.

const TOKEN_BYTES = 24

Invitations::__construct()

public function __construct(UnitOfWork|EntityManagerInterface $unitOfWork, protected readonly string $userClass = 'App\Entity\User')
$unitOfWork

the entity manager is deprecated (until 6.0): adapted by UnitOfWorks

Invitations::token()

public static function token(): string

A new token: 48 hexadecimal characters.

Invitations::hash()

public static function hash(string $token): string

Invitations::expiry()

public static function expiry(int $days): \DateTimeImmutable

Invitations::save()

public function save(Invitation $invitation): Invitation

Saved, its token's hash only.

Invitations::findOpen()

public function findOpen(string $class, string $token): ?Invitation

The open invitation a token belongs to; null once accepted or run out.

Invitations::markAccepted()

public function markAccepted(Invitation $invitation): void

Marked accepted. What it opens is the extending bundle's business.

Invitations::createUser()

public function createUser(Invitation $invitation, string $username, string $plainPassword): User

A new account for an invitation's e-mail, verified: the link proved the address.

Invitations::existingUser()

public function existingUser(Invitation $invitation): ?User

The account that already has the invitation's e-mail, if any.

Launcher class

class Launcher implements LauncherInterface Launcher.php:16

Launcher::__construct()

public function __construct(AdvancedRouterInterface $router, ParameterBagInterface $parameterBag, SettingBagInterface $settingBag, AuthorizationCheckerInterface|Access $authorizationChecker, TokenStorageInterface|Access|null $tokenStorage = null)

Launcher::getLaunchdate()

public function getLaunchdate(?string $locale = null): ?DateTime

Launcher::date()

public static function date(mixed $launchdate): ?DateTime

A stored launch date as a date: the setting's DateTime, its text, or a DateTime as JSON holds it ({"date": ...}, a host reading the row itself).

Launcher::yearsSince()

public static function yearsSince(?DateTime $launchdate): string

The site's years ("2019-2026", "2026"), since a launch date (since()).

Launcher::isLaunched()

public function isLaunched(?string $locale = null): ?bool

Launcher::since()

public function since(?string $locale = null): string

Launcher::redirectOnDeny()

public function redirectOnDeny(?RequestEvent $event = null, ?string $locale = null): bool

The launch page's decision applied to a Symfony request event (deprecated until 6.0: the rule is Base\Request\Rule\LaunchPage, which omnibridge/symfony's SecuritySubscriber asks itself). True when the request stops there.

LauncherInterface interface

interface LauncherInterface LauncherInterface.php:8

LauncherInterface::getLaunchdate()

public function getLaunchdate(?string $locale = null): ?DateTime

LauncherInterface::isLaunched()

public function isLaunched(?string $locale = null): ?bool

LauncherInterface::since()

public function since(?string $locale = null): string

LauncherInterface::redirectOnDeny()

public function redirectOnDeny(?RequestEvent $event = null): bool

final class Links Links.php:21

A route's address by a router's reference type, made on the Urls contract (plan "omnibase agnostic", step E1): what an entity's __toLink() asks (Widget\Page, Widget\Attachment, ShortLink, Image, Semantic, Widget\Route), through Base\Contract\Link::to(), its static door.

The reference types are Symfony's UrlGeneratorInterface values, named by Base\Contract\Link: an absolute path is Urls::path(), an absolute URL Urls::url(). A relative path and a network path have no equivalent in the contract; they are asked of the Urls implementation's own generate($name, $parameters, $referenceType) when it has one (omnibridge/ symfony's RouterUrls: the router, as before), and refused otherwise.

public function __construct(readonly Urls $urls)
public function to(string $name, array $parameters = [], int $referenceType = Link::ABSOLUTE_PATH): string

LocalBusiness class

class LocalBusiness LocalBusiness.php:21

schema.org's LocalBusiness for the page's JSON-LD: who the business is, where, how to reach it, when it is open. Search engines read the address, the phone and the hours (the days off too) from there.

Each property is taken, in this order, from what the caller gives, from the back office's settings (base.settings.title, .slogan, .phone, .address.*), from the configuration (base.local_business.*). The hours are Base\Service\OpeningHours::schema(), for the whole site or for one place. A property nobody gives is left out.

In a template: {{ local_business_jsonld() }} (docs/40-commons/local-business.md).

const JSON_FLAGS = \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE | \JSON_HEX_TAG | \JSON_HEX_AMP

LocalBusiness::__construct()

public function __construct(protected readonly OpeningHours $hours, protected readonly ?SettingBagInterface $settings = null, protected readonly ?RequestStack $requests = null, protected readonly array $config = [])
$config

base.local_business

LocalBusiness::schema()

public function schema(array $overrides = [], string|object|null $scope = null): array
$overrides

schema.org properties that win over everything (null removes one)

$scope

one place's hours (OpeningHours::for()); null: the site's

LocalBusiness::jsonLd()

public function jsonLd(array $overrides = [], string|object|null $scope = null): string

The <script type="application/ld+json"> of the page.

Localizer class

class Localizer extends AbstractLocalCache implements LocalizerInterface Localizer.php:18

const LOCALE_FORMAT = "xx-XX"
const SEPARATOR = "-"
const MAX_CACHED_LOCALES = 256

Upper bound for the normalizeLocale() memo; see the check in that method.

Localizer::isLate()

public static function isLate(): bool

Localizer::markAsLate()

public static function markAsLate(?string $location = null)

Localizer::forgetRequestState()

public static function forgetRequestState(): void

isLate records that the locale has been resolved for THE CURRENT request (LocalizerSubscriber::onKernelRequest). As a static it outlives that request in any long-running process - FrankenPHP worker mode, a messenger consumer - and would claim "already resolved" for every request after the first. Cleared at the start of each main request by Base\Subscriber\RequestScopedStateSubscriber.

Localizer::localeHasChanged()

public function localeHasChanged()

Localizer::markAsChanged()

public function markAsChanged()

Localizer::__construct()

public function __construct(ParameterBagInterface|ContainerParameters $parameterBag, TranslatorInterface $translator, string $cacheDir, ?string $buildDir = null)

Localizer::warmUp()

public function warmUp(string $cacheDir, ?string $buildDir = null): array

Localizer::__toLocale()

public static function __toLocale(string $locale, ?string $separator = self::SEPARATOR): string

Localizer::__toLocaleLang()

public static function __toLocaleLang(string $locale): string

Localizer::__toLocaleCountry()

public static function __toLocaleCountry(string $locale): string

Localizer::getLocales()

public static function getLocales()

Localizer::compatibleLocale()

public function compatibleLocale(string $locale, string $preferredLocale, ?array $availableLocales = null): bool

Localizer::getLocale()

public function getLocale(?string $locale = null): string

Localizer::setLocale()

public function setLocale(string $locale, ?Request $request = null)
Throws

Exception

Localizer::setDefaultLocale()

public function setDefaultLocale(?string $defaultLocale)

Localizer::getDefaultLocale()

public static function getDefaultLocale(): ?string

Localizer::getFallbackLocales()

public static function getFallbackLocales(): array

Localizer::getAvailableLocales()

public static function getAvailableLocales(): array

Localizer::getDefaultLocaleLang()

public static function getDefaultLocaleLang(): ?string

Localizer::getFallbackLocaleLangs()

public static function getFallbackLocaleLangs(): array

Localizer::getAvailableLocaleLangs()

public static function getAvailableLocaleLangs(): array

Localizer::getDefaultLocaleCountry()

public static function getDefaultLocaleCountry(): ?string

Localizer::getFallbackLocaleCountries()

public static function getFallbackLocaleCountries(): array

Localizer::getAvailableLocaleCountries()

public static function getAvailableLocaleCountries(): array

Localizer::getLocaleLangName()

public function getLocaleLangName(?string $locale = null): ?string

Localizer::getLocaleLang()

public function getLocaleLang(?string $locale = null): string

Localizer::getLocaleCountryName()

public function getLocaleCountryName(?string $locale = null): string

Localizer::getLocaleCountry()

public function getLocaleCountry(?string $locale = null): string

Localizer::normalizeLocale()

public static function normalizeLocale(string|array $locale, string $separator = self::SEPARATOR): string|array

Localizer::getTimezone()

public function getTimezone(): string

Localizer::setTimezone()

public function setTimezone(string $timezone): self

Localizer::getDefaultTimezone()

public static function getDefaultTimezone(): string

Localizer::getAvailableTimezones()

public static function getAvailableTimezones(): array

Localizer::__toGMT()

public static function __toGMT(string $timezone): string

Localizer::__toTimezone()

public static function __toTimezone(string $countryCode)

Localizer::getCountry()

public function getCountry(): string

Localizer::getCountryName()

public function getCountryName(?string $countryCode, ?string $displayLocale = null): string

A country's name from its ISO 3166-1 code (alpha-2, "JP"; alpha-3, "JPN", is read too), in the current language or in $displayLocale ("fr", "fr-FR", "fr_FR"): JP is "Japon" on a French page. This is the |country_name filter; a locale ("fr-BE") is not a country, the filter used to read one and named Japan "Belgique". An unknown code is returned as given, an empty one as "".

Localizer::setCountry()

public function setCountry(string $countryCode): self

Localizer::__toSymbol()

public static function __toSymbol(string $currency)

Localizer::getCurrency()

public function getCurrency(): string

Localizer::setCurrency()

public function setCurrency(string $currency): self

LocalizerInterface interface

interface LocalizerInterface LocalizerInterface.php:5

LocalizerInterface::__toLocale()

public static function __toLocale(string $locale, ?string $separator = Localizer::SEPARATOR): string

LocalizerInterface::__toLocaleLang()

public static function __toLocaleLang(string $locale): string

LocalizerInterface::__toLocaleCountry()

public static function __toLocaleCountry(string $locale): string

LocalizerInterface::normalizeLocale()

public static function normalizeLocale(string|array $locale, string $separator = Localizer::SEPARATOR): string|array

LocalizerInterface::getDefaultLocale()

public static function getDefaultLocale(): ?string

LocalizerInterface::getDefaultLocaleLang()

public static function getDefaultLocaleLang(): ?string

LocalizerInterface::getDefaultLocaleCountry()

public static function getDefaultLocaleCountry(): ?string

LocalizerInterface::getFallbackLocales()

public static function getFallbackLocales(): array

LocalizerInterface::getFallbackLocaleLangs()

public static function getFallbackLocaleLangs(): array

LocalizerInterface::getFallbackLocaleCountries()

public static function getFallbackLocaleCountries(): array

LocalizerInterface::getAvailableLocaleLangs()

public static function getAvailableLocaleLangs(): array

LocalizerInterface::getAvailableLocaleCountries()

public static function getAvailableLocaleCountries(): array

LocalizerInterface::getAvailableLocales()

public static function getAvailableLocales(): array

LocalizerInterface::markAsLate()

public static function markAsLate()

LocalizerInterface::markAsChanged()

public function markAsChanged()

LocalizerInterface::setCountry()

public function setCountry(string $countryCode): self

LocalizerInterface::setTimezone()

public function setTimezone(string $timezone): self

LocalizerInterface::getLocale()

public function getLocale(?string $locale = null): string

LocalizerInterface::setLocale()

public function setLocale(string $locale)

LocalizerInterface::compatibleLocale()

public function compatibleLocale(string $locale, string $preferredLocale, ?array $availableLocales = null): bool

LocalizerInterface::getLocaleLang()

public function getLocaleLang(?string $locale = null): string

LocalizerInterface::getLocaleLangName()

public function getLocaleLangName(?string $locale = null): ?string

LocalizerInterface::getLocaleCountry()

public function getLocaleCountry(?string $locale = null): string

LocalizerInterface::getLocaleCountryName()

public function getLocaleCountryName(?string $locale = null): string

LocalizerInterface::getCountryName()

public function getCountryName(?string $countryCode, ?string $displayLocale = null): string

LocalizerInterface::getDefaultTimezone()

public static function getDefaultTimezone(): string

LocalizerInterface::getAvailableTimezones()

public static function getAvailableTimezones(): array

LocalizerInterface::getTimezone()

public function getTimezone(): string

Locator class

class Locator Locator.php:18

Where BaseTrait's static accessors keep what they resolved (audit "lesringostars face au master plan", step R28): the runtime locator BaseBundle::boot() seeds, the project's folder, the environment, each service once asked. Framework-free - a class of the Foundation -, so an entity's or an attribute's accessor no longer loads BaseService, the Symfony facade (a kernel, a form factory, a profiler in its constructor), which held them before. BaseService extends it: the same statics, its set*() calls and BaseService::getX() as before.

MaintenanceProvider class

class MaintenanceProvider implements MaintenanceProviderInterface MaintenanceProvider.php:15

MaintenanceProvider::__construct()

public function __construct(AdvancedRouterInterface $router, SettingBagInterface $settingBag, AuthorizationCheckerInterface|Access $authorizationChecker, ParameterBagInterface $parameterBag, LocalizerInterface $localizer, TokenStorageInterface|Access|null $tokenStorage = null)

MaintenanceProvider::getRemainingTime()

public function getRemainingTime(): int

MaintenanceProvider::getPercentage()

public function getPercentage(): int

MaintenanceProvider::getDowntime()

public function getDowntime(): int

MaintenanceProvider::getUptime()

public function getUptime(): int

MaintenanceProvider::isUnderMaintenance()

public function isUnderMaintenance(): bool

MaintenanceProvider::redirectOnDeny()

public function redirectOnDeny(?RequestEvent $event = null): bool

The maintenance page's decision applied to a Symfony request event (deprecated until 6.0: the rule is Base\Request\Rule\MaintenancePage, which omnibridge/symfony's SecuritySubscriber asks itself). True when the request stops there.

MaintenanceProviderInterface interface

interface MaintenanceProviderInterface MaintenanceProviderInterface.php:7

MaintenanceProviderInterface::getRemainingTime()

public function getRemainingTime(): int

MaintenanceProviderInterface::getPercentage()

public function getPercentage(): int

MaintenanceProviderInterface::getDowntime()

public function getDowntime(): int

MaintenanceProviderInterface::getUptime()

public function getUptime(): int

MaintenanceProviderInterface::isUnderMaintenance()

public function isUnderMaintenance(): bool

MaintenanceProviderInterface::redirectOnDeny()

public function redirectOnDeny(?RequestEvent $event = null): bool

MediaService class

class MediaService extends FileService implements MediaServiceInterface MediaService.php:33

MediaService::__construct()

public function __construct(Views|Environment|null $views, MediaRouter $router, ObfuscatorInterface $obfuscator, Storages $flysystem, ParameterBagInterface $parameterBag, ImagineInterface $imagineBitmap, ImagineInterface $imagineSvg, ?Profiler $profiler, ?LoggerInterface $logger = null)

MediaService::setController()

public function setController(MediaController $mediaController)

MediaService::getMaximumQuality()

public function getMaximumQuality()

MediaService::isWebpEnabled()

public function isWebpEnabled()

MediaService::audio()

public function audio(array|string|null $path, array $config = [], FilterInterface|array $filters = []): array|string|null

MediaService::video()

public function video(array|string|null $path, array $config = [], FilterInterface|array $filters = []): array|string|null

MediaService::soundify()

public function soundify(null|array|string $path, array $attributes = []): ?string

MediaService::vidify()

public function vidify(null|array|string $path, array $attributes = []): ?string

MediaService::image()

public function image(array|string|null $path, array $config = [], FilterInterface|array $filters = []): array|string|null

MediaService::imageBase64()

public function imageBase64(null|array|string $path): null|array|string

MediaService::imageSet()

public function imageSet(null|array|string $path, ...$srcset): null|array|string

MediaService::imagify()

public function imagify(null|array|string $path, array $attributes = [], ...$srcset): null|array|string

MediaService::crop()

public function crop(array|string|null $path, int $x = 0, int $y = 0, ?int $width = null, ?int $height = null, string $position = "leftop", array $config = [], FilterInterface|array $filters = []): array|string|null

MediaService::thumbnailInset()

public function thumbnailInset(array|string|null $path, ?int $width = null, ?int $height = null, array $config = [], FilterInterface|array $filters = []): array|string|null

MediaService::thumbnailOutbound()

public function thumbnailOutbound(array|string|null $path, ?int $width = null, ?int $height = null, array $config = [], FilterInterface|array $filters = []): array|string|null

MediaService::thumbnailNoclone()

public function thumbnailNoclone(array|string|null $path, ?int $width = null, ?int $height = null, array $config = [], FilterInterface|array $filters = []): array|string|null

MediaService::thumbnailUpscale()

public function thumbnailUpscale(array|string|null $path, ?int $width = null, ?int $height = null, array $config = [], FilterInterface|array $filters = []): array|string|null

MediaService::thumbnail()

public function thumbnail(array|string|null $path, ?int $width = null, ?int $height = null, array $config = [], FilterInterface|array $filters = []): array|string|null

MediaService::obfuscate()

public function obfuscate(string|null $path, array $config = [], FilterInterface|array $filters = []): ?string

MediaService::lightbox()

public function lightbox(null|array|string $path, array $attributes = [], null|array|string $lightboxId = null, null|array|string $lightboxTitle = null, array $lightboxAttributes = [], ...$srcset): null|array|string

MediaService::generate()

public function generate(string $proxyRoute, array $proxyRouteParameters = [], ?string $path = null, array $config = []): ?string

MediaService::resolve()

public function resolve(string $data, FilterInterface|array $filters = []): array

MediaService::serve()

public function serve(?string $file, int $status = 200, array $headers = []): ?Response

MediaService::isCached()

public function isCached(?string $path, array $config = [], FilterInterface|array $filters = []): bool

MediaService::filter()

public function filter(?string $path, array $config = [], FilterInterface|array $filters = []): ?string

MediaService::getNoImage()

public function getNoImage(null|string|FormatFilterInterface $extensionOrFormatter = null)
Throws

Exception

MediaServiceInterface interface

interface MediaServiceInterface extends FileServiceInterface MediaServiceInterface.php:9

MediaServiceInterface::isCached()

public function isCached(?string $path, array $config = [], FilterInterface|array $filters = []): bool

MediaServiceInterface::resolve()

public function resolve(string $data): array

MediaServiceInterface::image()

public function image(array|string|null $path, array $config = [], FilterInterface|array $filters = []): array|string|null

MediaServiceInterface::filter()

public function filter(?string $path, array $config = [], FilterInterface|array $filters = []): ?string

MediaServiceInterface::thumbnail()

public function thumbnail(array|string|null $path, ?int $width = null, ?int $height = null, array $config = [], FilterInterface|array $filters = []): array|string|null

MediaServiceInterface::audio()

public function audio(array|string|null $path, array $config = [], FilterInterface|array $filters = []): array|string|null

MediaServiceInterface::video()

public function video(array|string|null $path, array $config = [], FilterInterface|array $filters = []): array|string|null

MediaServiceInterface::setController()

public function setController(MediaController $mediaController)

NullTrading class

final class NullTrading implements TradingInterface NullTrading.php:18

The currency rates where florianv/swap is not installed: Base\Service\Trading is declared only with it (and symfony/http-client's PSR-18 adapter, which it hands Swap), and trading_market / TradingInterface are then this one (Base\Discovery's fallbacks), so the Twig filters, the money field and the facade still have their service.

It knows no rate: an amount is formatted in its own currency (|format_currency, Base\View\Money) and converted only into itself. A rate needs florianv/exchanger's ExchangeRate, which florianv/swap brings: addFallback() refuses one aloud rather than drop it, so an application that converts between currencies is told to require florianv/swap instead of showing amounts unconverted.

NullTrading::normalize()

public function normalize(string $source, string $target, mixed $value, null|string|int|DateTime $datetime): ?ExchangeRate

NullTrading::get()

public function get(string $from, string $to, array $options = []): ?ExchangeRate

NullTrading::getFallback()

public function getFallback(string $source, ?string $target = null): ExchangeRate|array|null

NullTrading::getLatest()

public function getLatest(string $source, string $target, array $options = []): ?ExchangeRate

NullTrading::isLive()

public function isLive(): bool

NullTrading::setLive()

public function setLive(bool $live): static

NullTrading::convert()

public function convert(string|float $cash, string $source, string $target, array $options = [], string $timeAgo = 'now'): ?float

The amount itself in its own currency; into another, the exception Trading throws without a rate.

NullTrading::convertLatest()

public function convertLatest(string|float $cash, string $source, string $target, array $options = []): ?float

NullTrading::convertFallback()

public function convertFallback(string|float $cash, string $source, string $target): ?float

NullTrading::getRenderedCurrency()

public function getRenderedCurrency(): ?string

NullTrading::setRenderedCurrency()

public function setRenderedCurrency(?string $renderedCurrency)

NullTrading::addFallback()

public function addFallback(string $source, string $target, mixed $value, null|string|int|DateTime $date = 'now'): self

NullTrading::removeFallback()

public function removeFallback(string $source, string $target): self

Obfuscator class

class Obfuscator extends AbstractLocalCache implements ObfuscatorInterface Obfuscator.php:12

Obfuscator::warmUp()

public function warmUp(string $cacheDir, ?string $buildDir = null): array

Obfuscator::__construct()

public function __construct(ParameterBagInterface $parameterBag, string $cacheDir, ?string $buildDir = null, iterable $compressions = [])
$compressions

the compressions known from the start (Base\Services' list, plan "omnibase agnostic", F5a); under Symfony the services tagged obfuscator.compression are added after (addCompression())

Obfuscator::addCompression()

public function addCompression(CompressionInterface $compression): self

Obfuscator::removeCompression()

public function removeCompression(CompressionInterface $compression): self

Obfuscator::getCompressions()

public function getCompressions(): array

Obfuscator::getCompression()

public function getCompression(string $idOrClass): ?CompressionInterface

Obfuscator::getUuid()

public function getUuid(string $name): ?UuidV5

Obfuscator::encode()

public function encode(array $value, bool $short = Obfuscator::NO_SHORT): string

Obfuscator::decode()

public function decode(string $hash, bool $short = Obfuscator::NO_SHORT): ?array

ObfuscatorInterface interface

interface ObfuscatorInterface ObfuscatorInterface.php:5

const NO_SHORT = false
const USE_SHORT = true

ObfuscatorInterface::encode()

public function encode(array $value, bool $short = Obfuscator::NO_SHORT): string

ObfuscatorInterface::decode()

public function decode(string $hash, bool $short = Obfuscator::NO_SHORT): ?array

OpeningHours class

class OpeningHours implements ResetInterface OpeningHours.php:28

When the place is open - one service for the footer, a banner, the time slots a customer may wish for, the day an order is for and the page's JSON-LD.

The usual week is the one saved (Base\Entity\Hours\WeekDayHours), else the one configured (base.opening_hours.week); special days (Base\Entity\Hours\SpecialDay) close a date or open it at other hours. Generalised from Nakaya's App\Service\OpeningHours.

A site with several places asks for one of them: for('store:12'), or for($store), is the same service for that place - its own week (Base\Entity\Hours\ScopedWeek) when it has one, else the site's; its own special days, which win over the site's on the same date. The service itself stays the whole site's.

OpeningHours::__construct()

public function __construct(protected readonly ?SpecialDays $specialDays = null, protected readonly ?WeekDays $weekDays = null, string $timezone = 'Europe/Paris', protected readonly array $defaultWeek = [], protected readonly ?string $cutoff = null, protected readonly ?ScopedWeeks $scopedWeeks = null)
$defaultWeek

ISO day => hours, until a week is saved

OpeningHours::for()

public function for(string|object|null $scope): static

The same service for one place: a scope key ("store:12") or an entity (scopeOf()). Null or '': the whole site. A new instance each time - the shared service is never scoped.

OpeningHours::scope()

public function scope(): ?string

The place this instance answers for; null: the whole site.

OpeningHours::scopeOf()

public static function scopeOf(object $place): string

An entity as a scope key: its class and its id ("App\Entity\Store:12").

OpeningHours::reset()

public function reset(): void

A worker serves many requests: each reads the hours again.

OpeningHours::timezone()

public function timezone(): \DateTimeZone

OpeningHours::week()

public function week(): array
Returns

the usual week, all seven days, ISO day => hours

OpeningHours::withWeek()

public function withWeek(array $week): static
$week
  • for tests, or after a change in this request

OpeningHours::withSpecialDays()

public function withSpecialDays(array $days): static
$days
  • for tests, or after a change in this request

OpeningHours::specialDays()

public function specialDays(): array
Returns

the special days still to come (or running today): for a place, its own first (they win on a shared date), then the site's

OpeningHours::specialOn()

public function specialOn(\DateTimeInterface $day): ?SpecialDay

OpeningHours::hoursOn()

public function hoursOn(\DateTimeInterface $day): array
Returns

the day's opening hours, special days included

OpeningHours::notices()

public function notices(?\DateTimeInterface $at = null, int $days = 14, int $limit = 3): array

The special days visitors should hear about: running today, or starting within $days.

OpeningHours::schema()

public function schema(): array

schema.org's openingHoursSpecification and specialOpeningHoursSpecification, to merge into the page's LocalBusiness JSON-LD: Google Search reads the special days from there.

OpeningHours::summary()

public function summary(): array

The footer's lines: the open days, those in a row with the same hours together ("Wednesday to Friday", "Saturday", "Sunday").

Returns

ISO days

OpeningHours::isOpenDay()

public function isOpenDay(\DateTimeInterface $day): bool

OpeningHours::isOpenAt()

public function isOpenAt(?\DateTimeInterface $at = null): bool

OpeningHours::nextOpenDay()

public function nextOpenDay(\DateTimeInterface $day): ?\DateTimeImmutable

The next day the place opens, $day itself when it does. Null: closed for a year.

OpeningHours::orderDay()

public function orderDay(?\DateTimeInterface $at = null): \DateTimeImmutable

The day an order (a reservation, a pick-up) made now is for: today until the cut-off (base.opening_hours.cutoff; without one, until the day's last closing), then the next day the place opens.

OpeningHours::slots()

public function slots(\DateTimeInterface $day, ?\DateTimeInterface $at = null, int $step = 30, int $notice = 30): array

Windows of $step minutes a customer may wish for on $day ("12:00-12:30"), inside the opening hours and not before $at plus $notice minutes.

Paginator class

class Paginator implements PaginatorInterface Paginator.php:11

Paginator::__construct()

public function __construct(Urls|RouterInterface $router, ParameterBagInterface $parameterBag)

Paginator::paginate()

public function paginate(array|Pages|Query $query, int $page = 1, int $pageSize = 0, int $pageRange = 0): ?Pagination
$query

the rows: an array, a query's Pages, a Doctrine Query (adapted, step F2e)

PaginatorInterface interface

interface PaginatorInterface PaginatorInterface.php:7

PaginatorInterface::paginate()

public function paginate(Query $query, int $page = 0, int $pageSize = 0, int $pageRange = 0)

ParameterBagInterface interface

interface ParameterBagInterface ParameterBagInterface.php:21

The parameters of the application, read by a dotted path ("base.uploader.storage"), as omnibase's code asks for them: the core's contract, with no class of the framework (plan "omnibase agnostique", step C3c).

Under Symfony it is the container's parameters: Base\Service\ParameterBag (and HotParameterBag, with the settings stored in the database) is the adapter - it extends DependencyInjection's ContainerBag, decorates parameter_bag and so is DependencyInjection's ParameterBagInterface as well, its other methods (resolveValue(), add()...) there for the code that types that one. This interface no longer extends it: a class that reads the parameters through omnibase's contract (AbstractAttribute, AttributeReader) loads nothing of the framework.

ParameterBagInterface::get()

public function get(string $key = "", ?array $bag = null): array|bool|string|int|float|UnitEnum|null

ParameterBagInterface::set()

public function set(string $path, array|bool|string|int|float|UnitEnum|null $value, ?array &$bag = null): void

ParameterBagInterface::has()

public function has(string $path, ?array $bag = null): bool

ParameterBagInterface::all()

public function all(): array

Every parameter, by its full name.

ReadSettings class

final class ReadSettings implements SettingBagInterface ReadSettings.php:13

The settings the administrator stored (layoutSetting), read through a host's own reader where omnibase's SettingBag (its entity manager, cache, localizer and Symfony parameters) is not built - omnibridge/laravel's DatabaseSettings (plan "omniauth", step AU8b: SecurityPolicy under Laravel). Read only: a setting is changed in the back office, which is the Symfony site's.

ReadSettings::__construct()

public function __construct(readonly \Closure $read)
$read

a setting's value, null when none is stored

ReadSettings::clearAll()

public function clearAll()

ReadSettings::all()

public function all(?string $locale = null): array

ReadSettings::get()

public function get(null|string|array $path = null, ?string $locale = null): array

ReadSettings::getScalar()

public function getScalar(null|string|array $path, ?string $locale = null): mixed

ReadSettings::getBagParameters()

public function getBagParameters(): array

ReadSettings::set()

public function set(string $path, $value, ?string $locale = null)

Redirections class

class Redirections Redirections.php:18

Where an address that is not found leads now (Base\Entity\Layout\Redirection).

$redirections->responseFor($request); // a RedirectResponse, or null: really not found $redirections->add('/produit/enseigne-lumineuse/', '/savoir-faire/enseigne');

Redirections::__construct()

public function __construct(protected readonly RedirectionRows $repository, protected readonly ?LoggerInterface $logger = null)

Redirections::responseFor()

public function responseFor(Request $request): ?RedirectResponse

Redirections::add()

public function add(string $source, string $target, int $status = Redirection::PERMANENT, bool $flush = true): Redirection

Adds a redirection, or changes the one already written for that source.

Referrer class

class Referrer implements ReferrerInterface Referrer.php:19

Where to go back to: the target path posted or kept in the session, the firewall's, the referer. The request and its session through Omnibridge\Contract\Requests (plan "omnibase agnostic", F5c).

Referrer::__toString()

public function __toString(): string

Referrer::__construct()

public function __construct(Requests|RequestStack|null $requests, AdvancedRouterInterface $router)
$requests

Symfony's RequestStack is deprecated (until 6.0)

Referrer::redirect()

public function redirect(array $headers = []): RedirectResponse

Referrer::isVetoed()

public function isVetoed(?string $routeName)

Referrer::clear()

public function clear()

Referrer::setUrl()

public function setUrl(?string $url)

Referrer::sameSite()

public function sameSite(): bool

Referrer::getUrl()

public function getUrl(): ?string

ReferrerInterface interface

interface ReferrerInterface ReferrerInterface.php:5

ReferrerInterface::getUrl()

public function getUrl(): ?string

ReferrerInterface::setUrl()

public function setUrl(?string $url)

ReferrerInterface::clear()

public function clear()

ReferrerInterface::sameSite()

public function sameSite(): bool

SecurityPolicy class

class SecurityPolicy SecurityPolicy.php:51

The site-wide account-security policy an administrator sets, and the single place that decides what a *user* is then allowed to change about their own account.

The rule the whole class exists to express: the administrator wins. A user may switch two-factor authentication on whenever the feature is available, but may only switch it back off while the administrator has not made it mandatory. Every "can the user do X" question below is asked from the settings page and from the controller that performs X, so a hidden button and a hand-crafted POST are refused by the same predicate.

Defaults matter here. A setting the administrator has never saved has no row at all, and SettingBag::getScalar() returns null for it - which filter_var() reads as false. Defaulting everything to false would silently switch passkeys and TOTP off for every existing account the moment this class shipped, so each flag below carries its own explicit default and only a real stored value overrides it.

Besides "everyone or no one" (the administrator's setting), the application may require a second factor of some roles only (base.security.two_factor.required_roles: [ROLE_STAFF]): whoever holds one of them, directly or through the role hierarchy, is asked to enrol and cannot switch the factor back off; everyone else stays free to choose. Hence the optional $user of the questions below: without one they answer for the whole site, with one for that account.

The accounts are asked of as plain objects (omnibase's users), not as Security's UserInterface: omniauth's Base\Auth\Policy asks the same questions under any host (plan "omniauth", AU4, the former P4). The role hierarchy is the host's, through omnisense/omnibridge's Contract\Roles (plan "omnibase agnostic", step F5c): Symfony's role hierarchy (omnibridge/symfony's HierarchyRoles), Laravel's role_hierarchy (omnibridge/laravel's Auth\Roles); without one, the account's own roles.

In the demo environment a demonstration account (Base\Demo) is shared by every visitor: nothing is required of it - not the second factor of its role, not the administrator's "mandatory" - and it may change none of its credentials (isDemoAccount(), canChangeCredentials()).

const TWO_FACTOR = 'base.settings.security.two_factor'
const TWO_FACTOR_MANDATORY = 'base.settings.security.two_factor.mandatory'
const PASSKEYS = 'base.settings.security.passkeys'
const NEW_DEVICE_EMAIL = 'base.settings.security.new_device_email'
const NEW_DEVICE_PROMPT = 'base.settings.security.new_device_prompt'
const ADMINISTRATION_ROLES = ['ROLE_ADMIN', 'ROLE_SUPERADMIN']

The roles of the administration: an account holding one is never linked by its address (isAdministrator()).

const SESSION_NEW_DEVICE_PROMPT = 'security_new_device_prompt'

Session key set by a sign-in from a browser this account has never used, on an account with no second factor: the next page shows, once, the optional offer to set up a one-time code. Cleared when answered.

Cookie remembering that the offer above was declined - it is never repeated.

const SESSION_ENROLMENT_SKIPPED = 'security_2fa_enrolment_skipped'

Session key holding a "not now" answer to the enrolment prompt.

SecurityPolicy::__construct()

public function __construct(SettingBagInterface $settingBag, Roles|RoleHierarchyInterface|null $roleHierarchy = null, array $requiredRoles = [], bool $postpone = true, ?DemoMode $demoMode = null, ?DemoAccountRegistry $demoAccounts = null, ?\Closure $reachableRoles = null)
$requiredRoles

roles whose holders must have a second factor (base.security.two_factor.required_roles)

$postpone

whether the enrolment prompt offers a "not now" (base.security.two_factor.postpone)

$roleHierarchy

the host's hierarchy; Security's RoleHierarchyInterface is deprecated (until 6.0)

$reachableRoles

the roles some roles reach, where the host gives no Roles (omnibridge/laravel: config/omniauth.php's role_hierarchy)

SecurityPolicy::isDemoAccount()

public function isDemoAccount(?object $user): bool

Is this one of the declared demonstration accounts, in the demo environment? Never true anywhere else: in dev and test the same accounts are ordinary ones.

SecurityPolicy::canChangeCredentials()

public function canChangeCredentials(?object $user): bool

May this account change its password, its address, its second factor, or close itself? Not a demonstration account: every visitor signs in with it, and whoever changed one of these would lock the next out.

SecurityPolicy::isTwoFactorAvailable()

public function isTwoFactorAvailable(): bool

Is two-factor authentication offered to users at all?

SecurityPolicy::isTwoFactorMandatory()

public function isTwoFactorMandatory(?object $user = null): bool

Must every user hold a second factor - or, given an account, must this one?

Mandatory only means anything while the feature is available in the first place - an administrator who turns two-factor off entirely and leaves this checkbox ticked has not thereby locked everyone out.

SecurityPolicy::getRequiredRoles()

public function getRequiredRoles(): array
Returns

the roles whose holders must have a second factor

SecurityPolicy::isTwoFactorRequiredByRole()

public function isTwoFactorRequiredByRole(?object $user): bool

Does this account hold one of the roles a second factor is required of (base.security.two_factor.required_roles), directly or through the role hierarchy? Asked of the account itself, not of the current token: the settings page and the enrolment prompt may be asked about any user.

SecurityPolicy::isAdministrator()

public function isAdministrator(?object $user): bool

Does this account hold an administration role (ROLE_ADMIN, ROLE_SUPERADMIN, directly or through the role hierarchy) or one a second factor is required of? Such an account is never linked to an identity provider by its address alone (plan "omniauth", Marco's decision QA3, Base\Auth\Policy): whoever holds the provider's account would hold the administration's.

SecurityPolicy::arePasskeysAvailable()

public function arePasskeysAvailable(): bool

Are passkeys offered as a login method?

SecurityPolicy::isNewDeviceEmailEnabled()

public function isNewDeviceEmailEnabled(): bool

Should signing in from an unrecognised browser send a confirmation email?

SecurityPolicy::hasSecondFactor()

public function hasSecondFactor(?object $user): bool

Does this account already hold a second factor?

A passkey deliberately does not count. It replaces the password rather than adding to it, so an account whose only protection is a passkey has one factor, not two, and a site that mandates two-factor should still ask for the second one.

SecurityPolicy::canDisableTwoFactor()

public function canDisableTwoFactor(?object $user = null): bool

May this user turn their second factor off again?

This is the precedence rule in one line: no, while the administrator requires one.

SecurityPolicy::canEnableTwoFactor()

public function canEnableTwoFactor(?object $user = null): bool

May this user still enrol - i.e. is the feature switched on for them? (Never a demonstration account.)

SecurityPolicy::isNewDevicePromptEnabled()

public function isNewDevicePromptEnabled(): bool

Should the first sign-in from an unknown browser offer, once, to set up a one-time code? Only meaningful while two-factor is available and not already mandatory (then the enrolment prompt does the asking).

OFF unless an administrator turns it on. It interrupts a sign-in the person did not ask to have interrupted, which is friction a public site should choose deliberately rather than inherit from a default.

SecurityPolicy::needsEnrolment()

public function needsEnrolment(?object $user): bool

Should this user be asked to enrol before carrying on?

True only while the site requires a second factor and this account has none. Whether the user is then allowed to postpone the answer is decided by the caller, not here - see canPostponeEnrolment().

SecurityPolicy::canSkipEnrolment()

public function canSkipEnrolment(?object $user = null): bool

Does the enrolment prompt offer this account a "not now"?

Yes by default: the skip exists so that a policy change strands nobody mid-task, and it only lasts the session. An application that wants no "later" for the accounts a second factor is required of (staff reading patients' files) sets base.security.two_factor.postpone: false - the prompt then comes back on every page until the account has one.

SecurityPolicy::canPostponeEnrolmentPermanently()

public function canPostponeEnrolmentPermanently(?object $user = null): bool

May a "not now" be remembered for good?

No, while enrolment is mandatory: the prompt offers a skip so nobody is trapped mid-task, but that answer lives in the session and the prompt comes back on the next sign-in. When two-factor is merely offered, a dismissal can be kept for good.

SettingBag class

class SettingBag implements SettingBagInterface SettingBag.php:26

The settings stored in the database (the back office's), compiled into one snapshot kept in a PSR-6 cache pool (plan "omnibase agnostique", C9: on psr/cache, no longer on Symfony's CacheInterface; its cache warmer is Base\Bridge\Symfony\SettingBagWarmer, which calls warmUp()).

SettingBag::warmUp()

public function warmUp(string $cacheDir, ?string $buildDir = null): array

Compile the snapshot fresh (bypassing any cached copy) and persist it, so the very first request after a deploy/cache:clear hits a warm cache instead of compiling on-demand. Under Symfony, SettingBagWarmer calls it at cache:warmup.

SettingBag::isOptional()

public function isOptional(): bool

The snapshot compiles on-demand on a cache miss regardless (see loadSnapshot()), so the warmer is safe to skip under --no-optional-warmers.

SettingBag::__construct()

public function __construct(ParameterBagInterface $parameterBag, UnitOfWork|EntityManagerInterface $unitOfWork, Settings $settingRepository, LocalizerInterface $localizer, CacheItemPoolInterface $cache, string $environment)
$unitOfWork

the entity manager is deprecated (until 6.0): adapted by UnitOfWorks

SettingBag::invalidate()

public function invalidate(): void

Drop the in-memory and persisted snapshot. The next read recompiles it from the database in one pass. Called by SettingBag::set() and by SettingSubscriber on any Setting/SettingIntl write (including ones that bypass SettingBag entirely, e.g. the admin CRUD's plain flush()).

SettingBag::getBagParameters()

public function getBagParameters(): array

Flat [bagParameterName => resolvedDefaultLocaleValue] map, read straight off the compiled snapshot — no query, no entity hydration. Replaces HotParameterBagSubscriber's former allRaw(true, true) + recursive walk, which re-ran on every request/console command for what is typically a handful of bag-linked settings.

SettingBag::all()

public function all(?string $locale = null): array

SettingBag::allRaw()

public function allRaw($useCache = true, $onlyLinkedBag = false): array
Throws

Psr\Cache\InvalidArgumentException

SettingBag::__call()

public function __call($name, $_)
Throws

Exception

SettingBag::getEnvironment()

public function getEnvironment(): ?string

SettingBag::getPaths()

public function getPaths(null|string|array $path = null)
Throws

Psr\Cache\InvalidArgumentException

SettingBag::normalize()

public function normalize(?string $path, array $settings)
Throws

Exception

SettingBag::denormalize()

public function denormalize(array $settings, ?string $path = null)
Throws

Exception

SettingBag::getRaw()

public function getRaw(null|string|array $path = null, bool $useCache = true, bool $onlyLinkedBag = false)
Throws

Psr\Cache\InvalidArgumentException

SettingBag::generateRaw()

public function generateRaw(string $path, ?string $locale = null, bool $useCache = false): Setting

SettingBag::getRawScalar()

public function getRawScalar(null|string|array $path = null, bool $useCache = true)

SettingBag::getScalar()

public function getScalar(null|string|array $path, ?string $locale = null): mixed

SettingBag::get()

public function get(null|string|array $path = null, ?string $locale = null, ?bool $useCache = true): array

SettingBag::clearAll()

public function clearAll()

SettingBag::clear()

public function clear(null|string|array $path, ?string $locale = null, $useCache = true)

Invalidates the whole compiled snapshot. $path/$locale are accepted for backward compatibility with call sites that used to target a specific cache key, but a single small snapshot is cheap enough to recompile wholesale — there is no meaningful partial-invalidate left to do.

SettingBag::set()

public function set(string $path, $value, ?string $locale = null, $useCache = true)
Throws

Psr\Cache\InvalidArgumentException

SettingBag::setLabel()

public function setLabel(string $path, ?string $label = null, ?string $locale = null)
Throws

Exception

SettingBag::setHelp()

public function setHelp(string $path, ?string $help = null, ?string $locale = null)
Throws

Exception

SettingBag::setBag()

public function setBag(string $path, ?string $parameterName = null)

SettingBag::has()

public function has(string $path, ?string $locale = null)
Throws

Exception

SettingBag::remove()

public function remove(string $path)

SettingBag::lock()

public function lock(string $path)

SettingBag::unlock()

public function unlock(string $path)

SettingBag::setLock()

public function setLock(string $path, bool $flag = true)

SettingBag::secure()

public function secure(string $path)

SettingBag::unsecure()

public function unsecure(string $path)

SettingBag::setSecure()

public function setSecure(string $path, bool $flag = true)

SettingBagInterface interface

interface SettingBagInterface SettingBagInterface.php:5

SettingBagInterface::clearAll()

public function clearAll()

SettingBagInterface::all()

public function all(?string $locale = null): array

SettingBagInterface::get()

public function get(null|string|array $path = null, ?string $locale = null): array

SettingBagInterface::getScalar()

public function getScalar(null|string|array $path, ?string $locale = null): mixed

SettingBagInterface::getBagParameters()

public function getBagParameters(): array

Flat [bagParameterName => resolvedDefaultLocaleValue] map for every bag-linked setting, used by HotParameterBagSubscriber to seed the HotParameterBag without querying/hydrating entities on every request.

SettingBagInterface::set()

public function set(string $path, $value, ?string $locale = null)

SettingSnapshotValue class

final class SettingSnapshotValue SettingSnapshotValue.php:12

Opaque per-locale value holder used inside a compiled SettingBag snapshot tree, standing in for the live Setting entity that same tree position holds in SettingBag::normalize()'s entity-tree shape. Kept as an object (not a plain array) so array_map_recursive() treats it as a leaf and does not recurse into the per-locale map itself.

public readonly array $values

locale => RAW translated Setting value (SettingIntl::getValueRaw() — Uploader public-URL resolution is deliberately NOT applied here; it happens at read time in SettingBag::get() so the snapshot stays media-storage-independent)

SettingSnapshotValue::__construct()

public function __construct(public readonly array $values)
$values

locale => RAW translated Setting value (SettingIntl::getValueRaw() — Uploader public-URL resolution is deliberately NOT applied here; it happens at read time in SettingBag::get() so the snapshot stays media-storage-independent)

Sharing class

class Sharing Sharing.php:9

Sharing::getAdapters()

public function getAdapters()

Sharing::getAdapter()

public function getAdapter(string $idOrClass): ?SharingAdapterInterface

Sharing::addAdapter()

public function addAdapter(SharingAdapterInterface $adapter): self

Sharing::removeAdapter()

public function removeAdapter(SharingAdapterInterface $adapter): self

Sharing::generate()

public function generate(string $adapterId, LinkableInterface|string $url, array $options = [], ?string $template = null)

SharingInterface interface

interface SharingInterface SharingInterface.php:7

SharingInterface::generate()

public function generate(string $adapterId, LinkableInterface|string $url, array $options = [], ?string $template = null)

Signatures class

class Signatures Signatures.php:46

Documents signed through omnisense/omnisign, for any entity of the application: an envelope sent (send()), signed by e-mail or in the site's page (signingUrl()), followed (refresh(), or the provider's webhook: notify()), and once completed its signed document and evidence kept in the private storage (base.signatures.storage: the uploads', out of public/). Each move is a SignatureEvent; the application answers on what the envelope is about.

$envelope = $signatures->send($quote, new Omnisign\Model\Envelope('Devis D-42', [$document], [$client], $fields, embedded: true)); return $this->redirect($signatures->signingUrl($envelope, 'client', $returnUrl)); ... $signatures->refresh($envelope); // on the way back; the webhook does it too $signatures->signed($envelope); // the signed PDF, once completed

Registered only when omnisense/omnisign is installed (its bundle gives the gateways: omnisign.gateways.<name>); the entity is mapped only then too.

Signatures::__construct()

public function __construct(UnitOfWork|EntityManagerInterface $unitOfWork, readonly Storages $flysystem, readonly ?Registry $registry = null, readonly ?EventDispatcherInterface $dispatcher = null, readonly ?LoggerInterface $logger = null, readonly ?string $gateway = null, readonly ?string $storage = null, readonly ?string $uploads = null)
$unitOfWork

the entity manager is deprecated (until 6.0): adapted by UnitOfWorks

Signatures::gateway()

public function gateway(?string $name = null): ?string

The gateway envelopes go through by default: base.signatures.gateway, or the only one configured.

Signatures::isEnabled()

public function isEnabled(?string $name = null): bool

Signatures::send()

public function send(object $subject, Request $request, ?string $gateway = null): Envelope

Sent to be signed, about $subject: created on the gateway and sent - by the provider's e-mail, or kept for the site's page (embedded) - and kept as an Envelope.

Signatures::signingUrl()

public function signingUrl(Envelope $envelope, string $signer, ?string $returnUrl = null): string

Where $signer signs in the site's page; asked again each time (the providers' links expire).

Signatures::refresh()

public function refresh(Envelope $envelope): Envelope

Asks the provider where it stands; kept, its events dispatched, its files kept once completed.

Signatures::remind()

public function remind(Envelope $envelope, ?string $signer = null): void

Signatures::cancel()

public function cancel(Envelope $envelope, ?string $reason = null): Envelope

Signatures::notify()

public function notify(string $gateway, string $body, array $headers): Envelope|false|null

A provider's callback: its signature checked by the gateway, the envelope it names asked again and kept.

Returns

the envelope updated; null when it names none of the site's; false when its signature does not hold

Signatures::of()

public function of(object $subject): array
Returns

the envelopes about $subject, newest first

Signatures::signed()

public function signed(Envelope $envelope): ?string

The signed document, once completed and kept; null before.

Signatures::evidence()

public function evidence(Envelope $envelope): ?string

The evidence of its signing (an audit trail, a certificate), once kept.

Signatures::subject()

public function subject(Envelope $envelope): ?object

The entity the envelope is about, when it still exists.

Sitemapper class

class Sitemapper implements SitemapperInterface Sitemapper.php:18

Sitemapper::__construct()

public function __construct(Views|Environment $views, AttributeReader $attributeReader, AdvancedRouterInterface $router, LocalizerInterface $localizer, ?LoggerInterface $logger = null)
$views

Twig's environment is deprecated (until 6.0)

Sitemapper::getSitemap()

public function getSitemap(Route $route): ?Sitemap

Sitemapper::getHostname()

public function getHostname(): string

Sitemapper::setHostname()

public function setHostname(string $hostname): self

Sitemapper::register()

public function register(string|Route $routeOrName, array $routeParameters = [], ?string $lastMod = null): self

One page into the sitemap: a route (its name, or the Route) and the parameters of the page.

Nothing here is fatal. A route that does not exist, an address that matches nothing, a route whose action carries no #[Sitemap]: the page is left out and the reason logged (warning, "sitemap" in the message). One listener registering a route nobody declared used to throw, and the whole /sitemap.xml - every other page of the site with it - answered 500.

Sitemapper::registerUrl()

public function registerUrl(string $url, ?string $lastMod = null): self

Sitemapper::registerAttributes()

public function registerAttributes(): self

Sitemapper::get()

public function get(SitemapEntry|string|null $sitemapOrRouteName = null): ?SitemapEntry

Sitemapper::getAlternates()

public function getAlternates(SitemapEntry|string|null $sitemapOrRouteName = null)

Sitemapper::serve()

public function serve(string $name, array $context = []): Response

SitemapperInterface interface

interface SitemapperInterface SitemapperInterface.php:8

SitemapperInterface::getHostname()

public function getHostname(): string

SitemapperInterface::setHostname()

public function setHostname(string $hostname): self

SitemapperInterface::register()

public function register(string|Route $routeOrName, array $routeParameters = [], ?string $lastMod = null): self

SitemapperInterface::registerUrl()

public function registerUrl(string $url, ?string $lastMod = null): self

SitemapperInterface::registerAttributes()

public function registerAttributes(): self

SitemapperInterface::serve()

public function serve(string $name, array $context = []): Response

SpamChecker class

class SpamChecker implements SpamCheckerInterface SpamChecker.php:46

Is what a visitor wrote spam? The classifier of omnisense/omnishield behind omnibase's SpamCheckerInterface (check, score), which the forms (spam_protection), the comments and omnibase/faq's questions ask:

  • base.guard.classifier, a gateway of omnishield.gateways;
  • else Akismet (omnishield/akismet), with the key typed in the back office (api.spam.akismet, admin's SpamKeySection) or configured (base.spam.akismet);
  • else nothing is asked: NOT_SPAM, as without a key before.

What is sent is built here from the request and the candidate: the visitor's address, browser and referrer, the page, the site's home page (not the current page), its language, the author's name and e-mail as text, the date. A provider that does not answer is base.guard.unreachable: accept (NOT_SPAM) or reject (MAYBE_SPAM, held for a person); a key refused is the site's error, let through and logged. Nothing is swallowed silently.

Neutral (plan "omnibase agnostic", F5c): the request through Omnibridge\Contract\Requests, the home page through omnibase's router or the host's Urls ("/"); a host without a classifier configured asks nothing (NOT_SPAM).

SpamChecker::__construct()

public function __construct(Requests|RequestStack|null $requests, protected SettingBagInterface $settingBag, protected ParameterBagInterface $parameterBag, protected TranslatorInterface $translator, protected HttpClientInterface $client, protected bool $debug, protected ?FormGuard $guard = null, protected AdvancedRouterInterface|Urls|null $router = null, protected ?LoggerInterface $logger = null)
$requests

Symfony's RequestStack is deprecated (until 6.0)

$router

the home page's address

SpamChecker::getLang()

public function getLang(): ?string

SpamChecker::getUrl()

public function getUrl(): ?string

The site's home page: what Akismet calls the blog - not the page the form is on.

SpamChecker::getKey()

public function getKey($api = SpamApi::AKISMET): ?string

$api: a classifier is named by base.guard.classifier now

The key: typed in the back office (api.spam.akismet), else configured (base.spam.akismet).

SpamChecker::classifier()

public function classifier(): ?ClassifierInterface

The classifier asked, or null when there is none.

SpamChecker::submission()

public function submission(SpamProtectionInterface $candidate, array $context = []): Submission

What the classifier is told of a candidate.

$context

what the caller knows better: comment_author, comment_author_email, comment_author_url, comment_type (Akismet's names), permalink

SpamChecker::check()

public function check(SpamProtectionInterface $candidate, array $context = [], $api = SpamApi::AKISMET): int

SpamChecker::score()

public function score(SpamProtectionInterface $candidate, array $context = [], $api = SpamApi::AKISMET): int
Returns

0: not spam, 1: maybe spam (held for a person), 2: blatant spam; -1: no text

SpamChecker::report()

public function report(Submission $submission, bool $spam): bool

Teach the classifier: a submission it let through that was spam ($spam true), one it held that was not. False when there is no classifier to tell; a provider's error is thrown.

SpamCheckerInterface interface

interface SpamCheckerInterface SpamCheckerInterface.php:8

SpamCheckerInterface::check()

public function check(SpamProtectionInterface $candidate, array $context = [], $api = SpamApi::AKISMET): int

SpamCheckerInterface::score()

public function score(SpamProtectionInterface $candidate, array $context = [], $api = SpamApi::AKISMET): int

SpeculativeRequest class

final class SpeculativeRequest SpeculativeRequest.php:18

Tells a speculative request - one a client made ahead of any user action, hoping to have the answer ready - from a real one.

Browsers announce prefetches and prerenders through request headers: Sec-Purpose: prefetch (Fetch standard), Purpose: prefetch (Chrome, Safari, prefetching proxies), X-Moz: prefetch (Firefox) and X-Purpose: preview (Safari's Top Sites). Anything with a side effect - signing out, counting a view - must treat such a request as if the user had never asked for the page, because they have not.

SpeculativeRequest::is()

public static function is(Request $request): bool

Storages interface

interface Storages Storages.php:21

omnibase's named storages over omnisense/omnidrive (audit "lesringostars face au master plan", step R28): what the core asks of them - a drive by its name (getDrive(), omnidrive's Drive: read, write, list, public address, local path...), and omnibase's rule of the public paths (getPublic(), prefixPath(), stripPrefix(): a stored file's address under public/, by the storage's prefix) with the checks it makes before a read or a write. Nothing of Flysystem in or out: a storage is named by a string.

Base\Service\Flysystem implements it, Flysystem behind omnidrive's drives; it replaces the deprecated FlysystemInterface (Flysystem's operators and adapters in its signatures) for every user of the core.

Storages::getProjectDir()

public static function getProjectDir()

Storages::getPublicDir()

public static function getPublicDir()

Storages::getDrives()

public function getDrives(): Drives

The storages, as omnidrive's drives.

Storages::getDrive()

public function getDrive(?string $storage = null): Drive

A storage as an omnidrive drive: by its name, the default one when null.

Storages::hasStorage()

public function hasStorage(string $storageName): bool

Storages::getStorageNames()

public function getStorageNames(bool $public = true): array
Returns

the storages' names, without the ".public" ones unless $public

Storages::getPublic()

public function getPublic(mixed $path, ?string $storage = null)

The public address of a stored path (the storage's public root for "" or "/"), null when it has none.

Storages::getPublicRoot()

public function getPublicRoot(?string $storage = null): ?string

Storages::prefixPath()

public function prefixPath(string $path, ?string $storage = null)

Storages::stripPrefix()

public function stripPrefix(string $path, ?string $storage = null)

Storages::read()

public function read(string $path, ?string $storage = null): ?string

The contents, null when there is no such file.

Storages::write()

public function write(string $path, string $contents, ?string $storage = null, array $config = []): bool

Writes a new file: false when one is there already.

Storages::delete()

public function delete(string $path, ?string $storage = null): bool

Deletes a file: false when there is none.

Storages::fileExists()

public function fileExists(string $path, ?string $storage = null): bool

Storages::isRemote()

public function isRemote(?string $storage = null)

Whether no file of this machine is behind the storage's paths (S3, SFTP, FTP...).

Storages::mkdir()

public function mkdir(string $path, ?string $storage = null, array $config = []): bool

Storages::mimeType()

public function mimeType(string $path, ?string $storage = null): ?string

Storages::get()

public function get(mixed $path, ?string $storage = null)

The stored path, prefixed, when the file exists.

SystemOfUnits class

class SystemOfUnits SystemOfUnits.php:5

SystemOfUnits::__construct()

public function __construct()

Themizer class

class Themizer extends AbstractLocalCache implements ThemizerInterface Themizer.php:8

Themizer::__construct()

public function __construct(ParameterBagInterface $parameterBag, TokenStorageInterface $tokenStorage, string $cacheDir, ?string $buildDir = null)

Themizer::getLayout()

public function getLayout($id = 0): string

Themizer::warmUp()

public function warmUp(string $cacheDir, ?string $buildDir = null): array

Themizer::detectLayouts()

public function detectLayouts()

Themizer::getAvailableModes()

public function getAvailableModes(): array

Themizer::color_scheme()

public function color_scheme(): string

Themizer::getMode()

public function getMode(): ?array

Themizer::getAvailableFilters()

public function getAvailableFilters(): array

Themizer::getFilter()

public function getFilter(): ?array

Themizer::getAudienceCategories()

public function getAudienceCategories(): array

Themizer::getAudience()

public function getAudience(): ?array

Themizer::getAvailableWidths()

public function getAvailableWidths(): array

Themizer::width()

public function width(): ?array

Themizer::getWidth()

public function getWidth(): ?array

Themizer::getAvailableEvents()

public function getAvailableEvents(): array

Returns the list of candidate themes (events) that are currently active.

Themizer::getEvent()

public function getEvent(): ?array

ThemizerInterface interface

interface ThemizerInterface ThemizerInterface.php:5

ThemizerInterface::getAvailableFilters()

public function getAvailableFilters(): array

ThemizerInterface::getFilter()

public function getFilter(): ?array

ThemizerInterface::getAvailableEvents()

public function getAvailableEvents(): array

ThemizerInterface::getEvent()

public function getEvent(): ?array

ThemizerInterface::getAvailableModes()

public function getAvailableModes(): array

ThemizerInterface::getMode()

public function getMode(): ?array

ThemizerInterface::color_scheme()

public function color_scheme(): string

ThemizerInterface::getAvailableWidths()

public function getAvailableWidths(): array

ThemizerInterface::getWidth()

public function getWidth(): ?array

ThemizerInterface::width()

public function width(): ?array

ThemizerInterface::getAudienceCategories()

public function getAudienceCategories(): array

ThemizerInterface::getAudience()

public function getAudience(): ?array

TimeMachine class

class TimeMachine extends BackupManager implements TimeMachineInterface TimeMachine.php:42

TimeMachine::setCommandOutput()

public function setCommandOutput(OutputInterface $output)

TimeMachine::getCacheDir()

public function getCacheDir()

TimeMachine::getExcludes()

public function getExcludes(): array

TimeMachine::setExcludes()

public function setExcludes(array $excludes)

TimeMachine::getSnapshotDir()

public function getSnapshotDir(): ?string

TimeMachine::setSnapshotDir()

public function setSnapshotDir(?string $snapshotDir)

TimeMachine::assertEnoughFreeSpace()

public function assertEnoughFreeSpace(string $directory, array $excludes = [], float $factor = 2.2): void

Refuse to start a snapshot that cannot fit, instead of filling the disk up and taking the application down with it. The tarball and its compressed copy coexist while compressing, hence the multiplier.

TimeMachine::estimateArchiveSize()

public function estimateArchiveSize(string $directory, array $excludes = []): ?int

Apparent size of what would actually go into the tarball (excludes applied), or null when du is unavailable / fails.

TimeMachine::preventAbort()

public function preventAbort()

TimeMachine::__construct()

public function __construct(Flysystem $flysystem, Registry $doctrine, ParameterBagInterface $parameterBag)

TimeMachine::getMaxCycle()

public function getMaxCycle(): ?int

TimeMachine::setMaxCycle()

public function setMaxCycle(int $maxCycle)

TimeMachine::getTimeLimit()

public function getTimeLimit(): ?DateTime

TimeMachine::setTimeLimit()

public function setTimeLimit(null|string|DateTime|int $timeLimit)

TimeMachine::getCompression()

public function getCompression(): ?string

TimeMachine::setCompression()

public function setCompression(?string $compression)

TimeMachine::getDatabase()

public function getDatabase(string $name): Database

TimeMachine::getDatabaseConfiguration()

public function getDatabaseConfiguration(string $name): Database

TimeMachine::getDatabaseList()

public function getDatabaseList(): array

TimeMachine::getStorage()

public function getStorage(string $name): Filesystem

TimeMachine::getStorageList()

public function getStorageList(): array

TimeMachine::findOneBy()

public function findOneBy(int $id, int|array $storageNames, ?string $prefix = null, int $cycle = -1)

TimeMachine::findBy()

public function findBy(int|array $storageNames = [], ?string $prefix = null, $cycle = -1): array

TimeMachine::findByCycle()

public function findByCycle(int|array $storageNames = [], ?string $prefix = null, $cycle = -1): array

TimeMachine::getLastCycle()

public function getLastCycle(array $files, ?string $prefix = null): int

TimeMachine::backup()

public function backup(null|string|array $databases, int|array $storageNames = [], bool $userInfo = false, ?string $prefix = null, int $cycle = -1): bool
Throws

CompressorTypeNotSupported

Throws

ConfigFieldNotFound

Throws

ConfigNotFoundForConnection

Throws

DatabaseTypeNotSupported

Throws

FilesystemException

Throws

FilesystemTypeNotSupported

TimeMachine::restore()

public function restore(int $id, bool $restoreDatabase, bool $restoreApplication, int|array $storageNames = [], ?string $prefix = null, int $cycle = -1)
Throws

CompressorTypeNotSupported

Throws

ConfigFieldNotFound

Throws

ConfigNotFoundForConnection

Throws

DatabaseTypeNotSupported

Throws

FilesystemTypeNotSupported

Throws

FilesystemException

TimeMachine::openCompressedArchive()

public function openCompressedArchive(string $output): ?string

TimeMachine::openArchive()

public function openArchive(string $output, bool $compression = false): ?string

TimeMachine::buildCompressedArchive()

public function buildCompressedArchive(string $output, string $directory, array $excludes = [], bool $verbose = true): ?string

TimeMachine::extractUserInfo()

public function extractUserInfo(string $output): ?string

TimeMachine::buildArchive()

public function buildArchive(string $output, string $directory, array $excludes = [], bool $compression = false, bool $verbose = true): ?string

TimeMachineInterface interface

interface TimeMachineInterface TimeMachineInterface.php:10

The backups (docs/30-operations/backups.md). Its implementation, Base\Service\TimeMachine, extends glitchr/backup-manager's Manager, a suggestion since 4.0: this interface loads without it, so the configuration reads DEFAULT_EXCLUDES here.

const DEFAULT_EXCLUDES = ["./vendor", "./node_modules", "./var/cache", "./var/log", "./var/coverage", "./var/phpunit", "./.git"]

Paths left out of the application tarball. Defaults to dependency and build output that composer install / yarn / a cache warmup rebuild from scratch - keeping them would multiply the snapshot size (and the free space it needs) for no restorable data.

TimeMachineInterface::getDatabaseList()

public function getDatabaseList(): array

The database connections a backup can take, by name (since 5.0, for the console tasks: Base\Console\Task\TimeMachineSnapshot).

TimeMachineInterface::getStorageList()

public function getStorageList(): array

The storages a snapshot can be written to, by name (since 5.0, as getDatabaseList()).

TimeMachineInterface::findOneBy()

public function findOneBy(int $id, int|array $storageNames, ?string $prefix = null, int $cycle = -1)

TimeMachineInterface::findBy()

public function findBy(int|array $storageNames, ?string $prefix = null, int $cycle = -1)

TimeMachineInterface::findByCycle()

public function findByCycle(int|array $storageNames, ?string $prefix = null, int $cycle = -1)

TimeMachineInterface::backup()

public function backup(null|string|array $databases, int|array $storageNames = [], bool $userInfo = false, ?string $prefix = null, int $cycle = -1)

TimeMachineInterface::restore()

public function restore(int $id, bool $restoreDatabase, bool $restoreApplication, int|array $storageNames = [], ?string $prefix = null, int $cycle = -1)

TimelineEventProviderInterface interface

interface TimelineEventProviderInterface TimelineEventProviderInterface.php:18

A source of "worth marking on a timeline" events (a deploy, a campaign launch, ...), collected by base-bundle-admin's TimelineEventRegistry and rendered as annotations on the analytics dashboard chart. Lives here (not base-bundle-admin) for the same reason Analytics does: it's a domain concept, not an admin-UI-specific one - a future non-admin consumer (a public changelog widget, a CLI report) could reuse it without depending on the admin package.

No implementation ships with this interface - any bundle or app service can supply one by implementing it (self-registers automatically, see AdminBundle::build()'s registerForAutoconfiguration()).

TimelineEventProviderInterface::getTimelineEvents()

public function getTimelineEvents(\DateTimeImmutable $since, ?\DateTimeImmutable $until = null): array
$until

null = up to today

Returns

'date' is Y-m-d, same granularity as Analytics::dailyBreakdown()'s own rows. 'url', when present, is what turns this event into a clickable marker on the chart (see admin-charts.js's buildAnnotations()) instead of a plain dashed line - an event with somewhere real to send an admin (an article's own page, here) is worth making directly navigable, not just visible.

Trading class

class Trading implements TradingInterface Trading.php:20

Trading::__construct()

public function __construct(HttpClientInterface $httpClient, string $cacheDir, protected bool $live = true)
$live

whether a call that does not say otherwise ("use_swap") may ask the providers. On by default; an application on a provider's free plan (a hundred requests a month, which a visitor's page views would spend in a day) sets BASE_TRADING_LIVE=0: the stored rates, laid in as fallbacks, then answer, and whoever refreshes them (an administrator's action, a command) passes ['use_swap' => true].

Trading::warmUp()

public function warmUp(string $cacheDir, ?string $buildDir = null)

Trading::getProviders()

public function getProviders()

The providers with a key, in the order Swap asks them: the highest getPriority() first, as for Symfony's tagged services - the order they were registered in only among equals. Base\Discovery's collect adds them in the container's order, which puts an application's before the bundles': without this, a keyless fallback (a central bank's rates) would answer before the keyed providers typed in the admin.

Trading::getProvider()

public function getProvider(string $idOrClass): ?CurrencyApiInterface

Trading::getRenderedCurrency()

public function getRenderedCurrency(): ?string

Trading::setRenderedCurrency()

public function setRenderedCurrency(?string $renderedCurrency)

Trading::normalize()

public function normalize(string $source, string $target, mixed $value, null|string|int|DateTime $datetime): ?ExchangeRate

Trading::getFallback()

public function getFallback(string $source, ?string $target = null): ExchangeRate|array|null

Trading::addFallback()

public function addFallback(string $source, string $target, mixed $value, null|string|int|DateTime $date = "now"): self

Trading::removeFallback()

public function removeFallback(string $source, string $target): self

Trading::addProvider()

public function addProvider(CurrencyApiInterface $provider): self

Trading::removeProvider()

public function removeProvider(CurrencyApiInterface $provider): self

Trading::setCacheTTL()

public function setCacheTTL(int $ttl)

Trading::isLive()

public function isLive(): bool

Trading::setLive()

public function setLive(bool $live): static

Trading::getLatest()

public function getLatest(string $source, string $target, array $options = []): ?ExchangeRate

Trading::get()

public function get(string $from, string $to, array $options = [], string $timeAgo = "now"): ?ExchangeRate

Trading::convert()

public function convert(string|float $cash, string $source, string $target, array $options = [], string $timeAgo = "now"): ?float

Trading::convertLatest()

public function convertLatest(string|float $cash, string $source, string $target, array $options = []): ?float

Trading::convertFallback()

public function convertFallback(string|float $cash, string $source, string $target): ?float

TradingInterface interface

interface TradingInterface TradingInterface.php:8

TradingInterface::normalize()

public function normalize(string $source, string $target, mixed $value, null|string|int|DateTime $datetime): ?ExchangeRate

TradingInterface::get()

public function get(string $from, string $to, array $options = []): ?ExchangeRate

TradingInterface::getFallback()

public function getFallback(string $source, ?string $target = null): ExchangeRate|array|null

TradingInterface::getLatest()

public function getLatest(string $source, string $target, array $options = []): ?ExchangeRate

TradingInterface::isLive()

public function isLive(): bool

Whether get()/getLatest() ask the providers when the options do not say ("use_swap").

TradingInterface::setLive()

public function setLive(bool $live): static

TradingInterface::convert()

public function convert(string|float $cash, string $source, string $target, array $options = [], string $timeAgo = "now"): ?float

TradingInterface::convertLatest()

public function convertLatest(string|float $cash, string $source, string $target, array $options = []): ?float

TradingInterface::convertFallback()

public function convertFallback(string|float $cash, string $source, string $target): ?float

TradingInterface::getRenderedCurrency()

public function getRenderedCurrency(): ?string

TradingInterface::setRenderedCurrency()

public function setRenderedCurrency(?string $renderedCurrency)

TradingInterface::addFallback()

public function addFallback(string $source, string $target, mixed $value, null|string|int|DateTime $date): self

TradingInterface::removeFallback()

public function removeFallback(string $source, string $target): self

Translator class

class Translator implements TranslatorInterface, Translations Translator.php:24

omnibase's translator, and the Translations contract of the Foundation (trans(), exists()) where it runs: an entity's noun is asked of an EntityNouns over it (getEntityNouns(), plan "omnibase agnostique", C4b), the rule a host without the framework runs over its own Translations.

const PARSE_EXTENDS = "extends"
const PARSE_NAMESPACE = "namespace"
const DOMAIN_DEFAULT = "messages"
const DOMAIN_BACKEND = "admin"
const DOMAIN_ENTITY = "entities"
const DOMAIN_ENUM = "enums"
const STRUCTURE_DOT = "^@?[a-zA-Z0-9_]+(?:-[a-zA-Z0-9_]+)*(?:[.][a-zA-Z0-9_]+(?:-[a-zA-Z0-9_]+)*)+\$"
const STRUCTURE_DOTBRACKET = "\\{[ ]*[@a-zA-Z0-9_.]+[.]{0,1}[a-zA-Z0-9_]+[ ]*\\}"
const STRUCTURE_BRACKETLIST = ['{}', "[]", "%%"]
const TRANSLATION_PROPERTIES = "_properties"
const TRANSLATION_GENDERNESS = "genderness"
const GENDERNESS_INCLUSIVE = "_inclusive"
const GENDERNESS_FEMININE = "_feminine"
const GENDERNESS_MASCULINE = "_masculine"
const GENDERNESS_NEUTRAL = "_neutral"
const TRANSLATION_POLITENESS = "politeness"

How somebody is addressed: familiar (tu, du, 常体), polite (vous, Sie, 丁寧語), formal (敬語). A text has one wording in the catalogue - its base text, at whatever level its language was written in - and may have a variant per level, under its key followed by the level: "key._plain", "key._polite", "key._formal".

The level is the site's (base.translator.politeness) unless a call gives its own - the TRANSLATION_POLITENESS parameter of trans(), or one of these among the options of transEntity() / transEnum(). What is tried, in order: formal -> polite -> the base text; polite -> the base text; plain -> the base text. See docs/20-architecture/politeness.md.

const POLITENESS_PLAIN = "_plain"
const POLITENESS_POLITE = "_polite"
const POLITENESS_FORMAL = "_formal"
const POLITENESS_LEVELS = [self::POLITENESS_PLAIN, self::POLITENESS_POLITE, self::POLITENESS_FORMAL]
const MAX_NESTED_TRANSLATION_DEPTH = 10

Translator::__construct()

public function __construct(\Symfony\Contracts\Translation\TranslatorInterface $translator, Environment|KernelInterface $kernel, ParameterBagInterface $parameterBag, ?string $politeness = null, array $applicationTexts = [])
$applicationTexts

the keys the application wrote in its own translations/ directory, by domain and locale (Base\Discovery's texts; read only when a level is set)

Translator::getPoliteness()

public function getPoliteness(): ?string

The site's level of politeness: one of POLITENESS_*, or null when none is set.

Translator::setPoliteness()

public function setPoliteness(?string $level)

Another level from here on - a message written to somebody the site addresses otherwise, a test. "plain", "polite", "formal" (or a POLITENESS_* constant); null for the texts as they are written.

Translator::politenessLevel()

public static function politenessLevel(mixed $level): ?string

A level as it may be written - "polite", "_polite", POLITENESS_POLITE - as one of POLITENESS_*; null for none (null, false, "", "none").

Throws

InvalidArgumentException for anything else

Translator::politenessChain()

public static function politenessChain(?string $level): array

The variants tried for a level, the closest first: a formal text that was not written falls back on the polite one.

Translator::getCatalogue()

public function getCatalogue(?string $locale = null): MessageCatalogueInterface

Translator::getCatalogues()

public function getCatalogues(): array

Translator::getLocale()

public function getLocale(): string

Translator::setLocale()

public function setLocale(string $locale)

Translator::getFallbackLocales()

public function getFallbackLocales(): array

Translator::transQuiet()

public function transQuiet(TranslatableMessage|string $id, array $parameters = array(), ?string $domain = null, ?string $locale = null, bool $recursive = true, bool $nullable = true): ?string

Translator::trans()

public function trans(TranslatableMessage|string $id, array $parameters = array(), ?string $domain = null, ?string $locale = null, bool $recursive = true): string

Translator::parseClass()

public function parseClass($class, string $parseBy = self::PARSE_NAMESPACE): string

Translator::transExists()

public function transExists(TranslatableMessage|string $id, ?string $domain = null, ?string $locale = null, bool $localeCountry = true): bool

Translator::transRoute()

public function transRoute(string $routeName, ?string $domain = null): ?string

Translator::transRouteExists()

public function transRouteExists(string $routeName, ?string $domain = null): bool

Translator::transEnum()

public function transEnum(?string $value, string $class, null|string|array $options = self::NOUN_SINGULAR): ?string

The words of an enumeration's value: the Foundation's rule, Base\Service\Model\EnumNouns, over this translator.

Translator::transEnumExists()

public function transEnumExists(string $value, string $class, string|array $options = self::NOUN_SINGULAR): bool

Translator::getEnumNouns()

public function getEnumNouns(): EnumNouns

The enumerations' words over this translator (EnumNouns).

Translator::transEntity()

public function transEntity(mixed $entityOrClassName, ?string $property = null, string|array $options = self::NOUN_SINGULAR): ?string

Translator::transEntityExists()

public function transEntityExists(mixed $entityOrClassName, ?string $property = null, string|array $options = self::NOUN_SINGULAR): bool

Translator::exists()

public function exists(string $id, ?string $domain = null, ?string $locale = null): bool

The Translations contract's question (Omnibridge\Contract\Translations): whether the catalogue holds the key, as transExists() answers.

Translator::getEntityNouns()

public function getEntityNouns(): EntityNouns

The entities' nouns over this translator (the Nouns contract under Symfony): the entity namespaces of the bundles omnibase's BaseBundle knows, App\Entity\ and Base\Entity\.

Translator::transTime()

public function transTime(int $time): string

A number of seconds in words (Base\Service\Model\Duration, C4b): "2 jours 3 heures".

TranslatorInterface interface

interface TranslatorInterface extends SymfonyTranslatorInterface, SymfonyTranslatorBagInterface TranslatorInterface.php:9

const TRANSLATION_NOUN = "noun"

The noun of an entity or an enumeration's value, singular or plural (transEntity(), transEnum()). Declared here, not on Translator, so that the code asking for a noun - an enumeration's type, Base\Database\Type\ EnumType::getText() - loads no class of the framework (Translator imports the kernel). Translator::NOUN_SINGULAR still names them.

const NOUN_SINGULAR = "_singular"
const NOUN_PLURAL = "_plural"

TranslatorInterface::getFallbackLocales()

public function getFallbackLocales(): array

TranslatorInterface::setLocale()

public function setLocale(string $locale)

TranslatorInterface::trans()

public function trans(TranslatableMessage|string $id, array $parameters = [], ?string $domain = null, ?string $locale = null, bool $recursive = true): string

TranslatorInterface::transQuiet()

public function transQuiet(TranslatableMessage|string $id, array $parameters = [], ?string $domain = null, ?string $locale = null, bool $recursive = true): ?string

TranslatorInterface::transExists()

public function transExists(TranslatableMessage|string $id, ?string $domain = null, ?string $locale = null): bool

TranslatorInterface::transTime()

public function transTime(int $time): string

TranslatorInterface::transEnum()

public function transEnum(?string $value, string $class, string|array $options = self::NOUN_SINGULAR): ?string

TranslatorInterface::transEnumExists()

public function transEnumExists(string $value, string $class, string|array $options = self::NOUN_SINGULAR): bool

TranslatorInterface::transEntity()

public function transEntity(mixed $entityOrClassName, ?string $property = null, string|array $options = self::NOUN_SINGULAR): ?string

TranslatorInterface::transEntityExists()

public function transEntityExists(mixed $entityOrClassName, ?string $property = null, string|array $options = self::NOUN_SINGULAR): bool

TranslatorInterface::transRoute()

public function transRoute(string $routeName, ?string $domain = null): ?string

TranslatorInterface::transRouteExists()

public function transRouteExists(string $routeName, ?string $domain = null): bool

TrashManager class

class TrashManager TrashManager.php:31

Reads and empties what TrasheableSubscriber put aside.

Every method here works with the trash filter turned off, because the whole point of the filter is that trashed entities are unreachable through the ORM - including to the code meant to bring them back. withTrash() is the only place that is allowed, and it restores the previous filter state even when the callable throws, so an exception mid-restore cannot leave the rest of the request able to see deleted content.

const FILTER = "trash_filter"

TrashManager::__construct()

public function __construct(UnitOfWork|EntityManagerInterface $unitOfWork, protected TrashBalls $trashBalls)
$unitOfWork

the entity manager is deprecated (until 6.0): adapted by UnitOfWorks

TrashManager::expired()

public function expired(?DateTimeInterface $now = null, ?int $limit = null): array

The entries past their grace period at $now (now when null), the oldest first: what purge() destroys.

TrashManager::withTrash()

public function withTrash(Closure $callable): mixed

Run something with trashed entities visible.

TrashManager::contents()

public function contents(?string $entityClass = null, ?int $limit = null, int $offset = 0): array

TrashManager::count()

public function count(?string $entityClass = null): int

TrashManager::entity()

public function entity(TrashBall $trashBall): ?object

The entity a trash entry stands for, or null if it is no longer there - a trash entry outliving its entity is possible (a hard delete elsewhere, a cascade from a parent) and must not be an error.

TrashManager::restore()

public function restore(TrashBall $trashBall): bool

Put an entity back. The trash entry goes with it - being in the trash and having a trash entry are the same fact, and leaving one behind would show a restored article as still deleted.

TrashManager::destroy()

public function destroy(TrashBall $trashBall): bool

Destroy an entity for good, along with everything recorded about it.

The removal only goes through because the deletion field is already stamped - that is the escape hatch TrasheableSubscriber leaves open, and the reason this cannot be used to bypass the trash on a live entity.

TrashManager::purge()

public function purge(?DateTimeInterface $now = null, ?int $limit = null): int

Destroy everything whose grace period has run out.

Returns

how many entities were actually destroyed

VersionManager class

class VersionManager VersionManager.php:26

Reads back what VersionableSubscriber wrote.

Two shapes of the same data:

history() the revisions of an entity, newest first - one line per save, which is what the entity-level history reads fieldHistory() the same revisions pivoted per field - which is what the per-field badge in the form label reads

A form render asks for the same entity once per locale tab, so the lookup is memoised for the life of the request: without it an article edited in three languages would issue the same query four times to draw its badges.

VersionManager::__construct()

public function __construct(UnitOfWork|EntityManagerInterface $unitOfWork, protected Revisions $revisions, protected int $maxRevisions = 5)
$unitOfWork

the entity manager is deprecated (until 6.0): adapted by UnitOfWorks

VersionManager::history()

public function history(object $entity): array

Revisions anchored on $entity - passing a translation gives its parent's history, which is where its own changes were recorded.

VersionManager::fieldHistory()

public function fieldHistory(object $entity): array

The history of every versioned field of $entity, pivoted per property and expressed in terms the form can render without knowing about revisions at all.

Only the fields declared on the class passed in are returned, under their bare property name: a ThreadIntl gets title/headline/content, not "fr-FR.title", so a form child can be matched by its own name.

VersionManager::preview()

public function preview(mixed $value, int $length = 80): string

A short, human line standing for a stored value in the dropdown.

Deliberately lossy: this is the thing you read to decide whether that is the version you want, not the thing that gets restored - restoring uses the raw value.

WidgetProvider class

class WidgetProvider implements WidgetProviderInterface WidgetProvider.php:16

The widgets and their slots by path. Through their interfaces (audit "lesringostars face au master plan", step R28), where it asked the entity manager for their repositories: the same finders, the result cache unless $useCache is false.

WidgetProvider::__construct()

public function __construct(protected Widgets $widgets, protected Slots $slots)

WidgetProvider::get()

public function get(string $widgetName, bool $useCache = true): ?Widget

WidgetProvider::getWidget()

public function getWidget(string $widgetName, bool $useCache = true): ?Widget

WidgetProvider::all()

public function all(bool $useCache = true): array

WidgetProvider::allSlots()

public function allSlots(bool $useCache = true): array

WidgetProvider::getSlot()

public function getSlot(string $widgetSlotName, bool $useCache = true): ?Slot

WidgetProvider::getWidgetSlot()

public function getWidgetSlot(string $path, bool $useCache = true): ?Slot

WidgetProviderInterface interface

interface WidgetProviderInterface WidgetProviderInterface.php:8

WidgetProviderInterface::all()

public function all(): array

WidgetProviderInterface::allSlots()

public function allSlots(): array

WidgetProviderInterface::get()

public function get(string $widgetName): ?Widget

WidgetProviderInterface::getSlot()

public function getSlot(string $widgetSlotName): ?Slot

WysiwygEnhancer class

class WysiwygEnhancer implements WysiwygEnhancerInterface WysiwygEnhancer.php:15

WysiwygEnhancer::__construct()

public function __construct(Views|Environment $views, HeadingEnhancerInterface $headingEnhancer, SemanticEnhancerInterface $semanticEnhancer, MentionEnhancerInterface $mentionEnhancer, LinkEnhancerInterface $linkEnhancer, MediaEnhancerInterface $mediaEnhancer)

WysiwygEnhancer::supports()

public function supports(mixed $html): bool

WysiwygEnhancer::render()

public function render(mixed $html, array $options = []): string

WysiwygEnhancer::getTableOfContents()

public function getTableOfContents(mixed $html, ?int $maxLevel = null): array

WysiwygEnhancer::enhanceHeadings()

public function enhanceHeadings(mixed $html, ?int $maxLevel = null, array $attrs = []): mixed

WysiwygEnhancer::enhanceSemantics()

public function enhanceSemantics(mixed $html, null|array|string $words = null, array $attrs = []): mixed

WysiwygEnhancer::enhanceMentions()

public function enhanceMentions(mixed $html, array $attrs = []): mixed
public function enhanceLinks(mixed $html, array $attrs = []): mixed

WysiwygEnhancer::enhanceMedia()

public function enhanceMedia(mixed $html, array $config = [], FilterInterface|array $filters = [], array $attrs = []): mixed

WysiwygEnhancerInterface interface

interface WysiwygEnhancerInterface WysiwygEnhancerInterface.php:7

WysiwygEnhancerInterface::supports()

public function supports(mixed $json): bool

WysiwygEnhancerInterface::render()

public function render(mixed $json, array $options = []): string

WysiwygEnhancerInterface::getTableOfContents()

public function getTableOfContents(mixed $json, ?int $maxLevel = null): mixed

WysiwygEnhancerInterface::enhanceMentions()

public function enhanceMentions(mixed $html, array $attrs = []): mixed
public function enhanceLinks(mixed $html, array $attrs = []): mixed

WysiwygEnhancerInterface::enhanceMedia()

public function enhanceMedia(mixed $html, array $config = [], FilterInterface|array $filters = [], array $attrs = []): mixed

WysiwygEnhancerInterface::enhanceHeadings()

public function enhanceHeadings(mixed $json, ?int $maxLevel = null, array $attr = []): mixed

WysiwygEnhancerInterface::enhanceSemantics()

public function enhanceSemantics(mixed $json, null|array|string $words = null, array $attr = []): mixed

Base\Service\Analytics

UserAgentClassifier class

final class UserAgentClassifier UserAgentClassifier.php:22

Buckets a request's User-Agent into one of three Base\Entity\Analytics\ PageView::SOURCE_* values. AI checks run first and take priority over the generic crawler-detect pass: several AI crawlers (GPTBot, ClaudeBot, ...) also match generic bot heuristics, but they deserve their own bucket (SOURCE_AI) rather than falling into the catch-all SOURCE_BOT one - that split is the whole point of this class over just jaybizzle/crawler-detect's plain isCrawler() boolean.

A missing/empty User-Agent is classified as SOURCE_BOT rather than SOURCE_HUMAN: real browsers always send one, so its absence is itself a signal, and defaulting to "not human" keeps the human bucket honest instead of silently inflating it with unidentified traffic.

UserAgentClassifier::__construct()

public function __construct(readonly CrawlerDetect $crawlerDetect = new CrawlerDetect())

UserAgentClassifier::classify()

public function classify(?string $userAgent): string

Base\Service\Calendar

CalendarEntry class

final class CalendarEntry CalendarEntry.php:15

One date as a calendar sees it, whatever it was in the site: a concert (omnibase/agenda's Event), an appointment, a class, a pick-up. What Ics and GoogleCalendarLink write from - a bundle maps its own entity to one (see omnibase/agenda's Event::toCalendarEntry()).

$start and $end carry the timezone the date happens in (the hall's, the office's): an hour is written in it, a whole day ($allDay) as a date. With no end, a timed date lasts $defaultDuration.

const DEFAULT_DURATION = 'PT2H'
public readonly string $uid
public readonly string $title
public readonly \DateTimeImmutable $start
public readonly ?\DateTimeImmutable $end
public readonly bool $allDay
public readonly string $description
public readonly ?string $location
public readonly ?float $latitude
public readonly ?float $longitude
public readonly ?string $url
public readonly bool $cancelled
public readonly ?\DateTimeInterface $updatedAt
public readonly string $defaultDuration

CalendarEntry::__construct()

public function __construct(public readonly string $uid, public readonly string $title, public readonly \DateTimeImmutable $start, public readonly ?\DateTimeImmutable $end = null, public readonly bool $allDay = false, public readonly string $description = '', public readonly ?string $location = null, public readonly ?float $latitude = null, public readonly ?float $longitude = null, public readonly ?string $url = null, public readonly bool $cancelled = false, public readonly ?\DateTimeInterface $updatedAt = null, public readonly string $defaultDuration = self::DEFAULT_DURATION)

CalendarEntry::timezone()

public function timezone(): \DateTimeZone

CalendarEntry::effectiveEnd()

public function effectiveEnd(): \DateTimeImmutable

The end a calendar should show: the one given, else the start plus the default duration (a whole day: that day).

class GoogleCalendarLink GoogleCalendarLink.php:10

The "add to Google Calendar" link of a date: Google's own template page, filled in. Hours go in UTC with the date's timezone beside them (ctz), whole days as dates, the last one excluded as Google wants it.

public function for(CalendarEntry $entry): string

Ics class

class Ics Ics.php:12

Dates as an iCalendar file (RFC 5545), written by hand: a calendar a phone subscribes to, or one date to add. Lines end with CRLF and are folded at 75 octets, texts are escaped, an hour is given in the date's timezone (with the VTIMEZONE that defines it) or in UTC, a date of whole days as dates. Moved here from omnibase/agenda, on CalendarEntry.

const PROD_ID = '-//omnibase//calendar//EN'

Ics::calendar()

public function calendar(iterable $entries, string $name = 'Agenda', string $prodId = self::PROD_ID): string

Ics::event()

public function event(CalendarEntry $entry): string

One date as a VEVENT block, to put in a VCALENDAR.

Ics::escape()

public static function escape(string $text): string

A text value: backslash, semicolon, comma and line break escaped.

Ics::fold()

public static function fold(string $line): string

A line of more than 75 octets continues on the next ones, each opened by a space; never inside a character.

Ics::unfold()

public static function unfold(string $ics): array

Lines folded at 75 octets read back as one (RFC 5545 §3.1).

@return list<string>

Base\Service\Collab

CollabRoomResolver class

class CollabRoomResolver CollabRoomResolver.php:16

This class supplies room-key logic and version-hash logic for the real-time collaboration feature. EditorType uses this class.

EditorController uses this class. The regular-field presence widget uses this class. Because of this shared use, the room-key format and the hash method exist in one place only.

CollabRoomResolver::__construct()

public function __construct(UnitOfWork|EntityManagerInterface $unitOfWork)
$unitOfWork

the entity manager is deprecated (until 6.0): adapted by UnitOfWorks

CollabRoomResolver::buildRoom()

public function buildRoom(string $fqcn, int|string $id, string $field, ?string $locale = null): string

The room key has this format: entity_fqcn:entity_id:field:locale.

Each field has one separate room. Example: an EditorJS field and a select2 field on the same record use two different rooms. The locale segment is always present. This method uses the placeholder value "_" for a field with no locale. Translatable content is specific to one locale. This method must not mix presence data or conflict data between two locales.

CollabRoomResolver::tokenId()

public function tokenId(string $room): string

The CSRF token id of one room - one entity's one field. The autosave and the collab ticket accept only the token of the room they act on: with the session-wide "editorjs" token, which any form with an editor hands out, anyone could write any field of any entity (a User's roles).

CollabRoomResolver::resolveEntity()

public function resolveEntity(mixed $data): ?object

The root form data is not always the mapped entity. An embedded form or a collection form can bind a separate DTO object or wrapper object instead. In this case, this method returns null. This method does not guess the correct entity. When this method returns null, the caller must skip the collaboration setup for that field.

CollabRoomResolver::hash()

public function hash(mixed $value): string

This method creates a version stamp for a field's current value.

This system uses this stamp for optimistic-concurrency control. This method uses a content hash. This method does not use a timestamp column, because not every entity has a timestamp column. This method avoids a database schema change for each entity.

CollabTicketFactory class

class CollabTicketFactory implements Tickets CollabTicketFactory.php:20

This class creates a short-lived, signed ticket. A browser presents this ticket to the collab relay (relay/src/server.js in editorjs-yjs), to join a room's WebSocket connection. The relay checks the signature by itself.

The relay does not send requests to PHP. The relay does not read the session store. Because of this, this class is the only place on this side that uses the shared secret.

Signed by Base\Service\Ticket\TicketSigner, the format the relay's own verifyTicket() reads (base64url(payload) . "." . hex(hmac_sha256)); the contract it answers is Base\Contract\Tickets.

CollabTicketFactory::__construct()

public function __construct(string $secret, string $wsUrl = "", int $ttl = 300)

$ttl is the ticket lifetime in seconds.

300, not 60: a ticket is only presented on the WebSocket handshake, and the client refreshes it well inside this window, so a short ttl bounds exposure of a leaked ticket without any legitimate client ever needing to stretch it. 60 was too tight in practice - the client's refresh timer runs at 45s, and browsers clamp timers in background tabs to once a minute (suspending them entirely while the machine sleeps), so the refresh routinely slipped past a 60s ttl and the following reconnect presented an expired ticket, which the relay rejects with 401. The client now also refreshes on socket close and on tab focus, so this margin is defence in depth rather than the only guard.

CollabTicketFactory::isConfigured()

public function isConfigured(): bool

An operator can deploy a relay with a secret value, but with no public WebSocket URL yet. The opposite case can also occur during setup. The collab_live option needs both values. Because of this, a caller must check this method before it activates the collab_live option for a field.

CollabTicketFactory::getWsUrl()

public function getWsUrl(): string

CollabTicketFactory::mint()

public function mint(string $room, array $user): ?string

CollabTicketFactory::verifyServiceToken()

public function verifyServiceToken(string $token, string $room): bool

This method checks a service-to-service token. The relay signs this token by itself. This token uses the same HMAC format as the mint() method, with payload {room, exp} and with no user fields.

The relay sends this token when the relay calls ux_editorjs_autosave, to save a room's content. The relay process is not a browser. Because of this, no Symfony session exists for that call. This method reuses the same shared secret from the other direction, instead of a second secret. This design uses one secret for symmetric use on both sides.

Base\Service\Model

Autocomplete class

class Autocomplete Autocomplete.php:10

Autocomplete::__construct()

public function __construct(TranslatorInterface $translator, ?MediaServiceInterface $mediaService = null)

Autocomplete::resolve()

public function resolve($entry, $class = null, array $entryOptions = [])

Autocomplete::resolveArray()

public static function resolveArray($entry, array $entryOptions = [])
Throws

Exception

AutocompleteInterface interface

interface AutocompleteInterface AutocompleteInterface.php:5

AutocompleteInterface::__autocomplete()

public function __autocomplete(): ?string

AutocompleteInterface::__autocompleteData()

public function __autocompleteData(): array

Autovalidate class

class Autovalidate Autovalidate.php:8

Autovalidate::__construct()

public function __construct(TranslatorInterface $translator = null)

Autovalidate::validate()

public function validate($value, Constraint ...$constraints): bool

AutovalidateInterface interface

interface AutovalidateInterface AutovalidateInterface.php:5

Breadcrumb class

class Breadcrumb implements BreadcrumbInterface, Iterator, Countable, ArrayAccess Breadcrumb.php:17

Breadcrumb::offsetExists()

public function offsetExists(mixed $offset): bool

Breadcrumb::offsetUnset()

public function offsetUnset(mixed $offset): void

Breadcrumb::offsetGet()

public function offsetGet(mixed $offset): mixed

Breadcrumb::offsetSet()

public function offsetSet(mixed $offset, mixed $value = []): void

Breadcrumb::count()

public function count(): int

Breadcrumb::rewind()

public function rewind(): void

Breadcrumb::next()

public function next(): void

Breadcrumb::key()

public function key(): mixed

Breadcrumb::valid()

public function valid(): bool

Breadcrumb::current()

public function current(): mixed

Breadcrumb::__construct()

public function __construct(AdvancedRouterInterface $router, TranslatorInterface $translator, array $options = [], ?string $template = null)

Breadcrumb::getRequest()

public function getRequest(): ?Request

Breadcrumb::setRequest()

public function setRequest(Request $request): self

Breadcrumb::compute()

public function compute(?Request $request = null)
Throws

Exception

Breadcrumb::getRouteParameters()

public function getRouteParameters(?string $url = null, ?string $urlPattern = null)

Breadcrumb::getRouteName()

public function getRouteName(?string $url = null): string

Breadcrumb::getController()

public function getController(?string $url = null): string

Breadcrumb::getRouter()

public function getRouter(): AdvancedRouterInterface

Breadcrumb::setRouter()

public function setRouter(AdvancedRouterInterface $router)

Breadcrumb::getTranslator()

public function getTranslator(): TranslatorInterface

Breadcrumb::setTranslator()

public function setTranslator(TranslatorInterface $translator)

Breadcrumb::getTemplate()

public function getTemplate(): string

Breadcrumb::setTemplate()

public function setTemplate(string $template)

Breadcrumb::getOptions()

public function getOptions(): array

Breadcrumb::addOptions()

public function addOptions(array $options)

Breadcrumb::setOptions()

public function setOptions(array $options)

Breadcrumb::getOption()

public function getOption(string $name)

Breadcrumb::addOption()

public function addOption(string $name, $value)

Breadcrumb::removeOption()

public function removeOption(string $name)

Breadcrumb::removeItem()

public function removeItem(string $offset)

Breadcrumb::prependItem()

public function prependItem(string $label, ?string $route = null, array $routeParameters = [])

Breadcrumb::appendItem()

public function appendItem(string $label, ?string $route = null, array $routeParameters = [])

Breadcrumb::clear()

public function clear()

Breadcrumb::getLength()

public function getLength()

Breadcrumb::getItems()

public function getItems()

Breadcrumb::getFirstItem()

public function getFirstItem()

Breadcrumb::getLastItem()

public function getLastItem()

Breadcrumb::getItem()

public function getItem(int $index)

BreadcrumbInterface interface

interface BreadcrumbInterface BreadcrumbInterface.php:5

CacheableInterface interface

interface CacheableInterface CacheableInterface.php:5

CacheableInterface::__toKey()

public function __toKey(?string ...$context): string

CacheableInterface::__toKeyTTL()

public function __toKeyTTL(): ?int

CacheableInterface::__toKeyTags()

public function __toKeyTags(): array

ClassAliases class

final class ClassAliases ClassAliases.php:19

omnibase's class convention, without the bundle: App\Entity\X is Base\Entity\X when the application declares no App\Entity\X of its own - and so for App\Repository, App\Enum, App\Tests, App\Notifier, App\Form. Under Symfony, BaseBundle::warmUp() declares these aliases from its pool and AbstractBaseBundle's last-resort autoloader answers by the same convention (it asks base()); an entity manager built by hand (Base\Bridge\Doctrine\ Mapping) registers the convention as an autoloader of its own - an association names its target App\Entity\User\Notification.

Composer is asked first: an application's own class is never replaced (the stubs omnibridge/composer writes for the others, from the core's Base\Bridge\Composer\Stub providers, are read by no autoloader).

const NAMESPACES = ["Entity", "Repository", "Enum", "Tests", "Notifier", "Form"]

The namespaces mapped App\X => Base\X.

ClassAliases::base()

public static function base(string $class): ?string

The Base class an App class is by convention, null for any other.

ClassAliases::register()

public static function register(): void

The convention as an autoloader, appended after Composer's: once a process.

ClassFinder class

final class ClassFinder ClassFinder.php:11

The classes a folder of PHP files declares, read from the files: each file's namespace and its name, the interfaces (*Interface.php) and the empty files left out - what Base\Bundle\AbstractBaseBundle::getAllClasses() answers, without loading the bundle (and with it the framework) to ask.

ClassFinder::classes()

public static function classes(string $path): array

ClassFinder::listed()

public static function listed(string $path): array

The classes of a folder (or of one file) in the order the filesystem lists them, the interfaces and the empty files left out: what AbstractBaseBundle::getAllClasses() answers, in its order (the translation keys' commands print them so: plan "omnibase agnostic", step F5e, slice 3).

ClassFinder::namespaces()

public static function namespaces(string $path): array

The namespaces the files of a folder declare, in the order the filesystem lists them (an interface's too): what AbstractBaseBundle::getAllNamespaces() answers.

ColorizeInterface interface

interface ColorizeInterface ColorizeInterface.php:5

ColorizeInterface::__colorize()

public function __colorize(): ?array

ColorizeInterface::__colorizeStatic()

public static function __colorizeStatic(): ?array

DevelopmentEnvironment class

final class DevelopmentEnvironment DevelopmentEnvironment.php:13

Whether the application runs for its developers (plan "omnibase agnostique", C9): BaseService::isDevelopment()'s rule, moved here so that a class that needs it asks the Environment contract instead of BaseService - debug on, or an environment named "dev", "local", or starting with "dev_" or "local_".

DevelopmentEnvironment::is()

public static function is(Environment $environment): bool

DevelopmentEnvironment::named()

public static function named(string $name, bool $debug = false): bool

Duration class

final class Duration Duration.php:19

A number of seconds in words - "2 jours 3 heures 5 minutes" - from the application's texts (base.years, base.months, base.days, base.hours, base.minutes, base.seconds: ICU plurals on {0}), as Base\Service\Translator:: transTime() said it: the time left before a token expires, before a thread is published, an order abandoned (plan "omnibase agnostique", C4b).

Asked through the Translations contract, so the texts are the ones the pages print: under Symfony omnibase's translator chain, the texts rewritten in the back office first. A month is 30 days, a year 12 months. Nothing for no time left (zero or less).

Duration::spell()

public static function spell(int $seconds, Translations $translations): string

EntityNouns class

class EntityNouns implements Nouns EntityNouns.php:26

The Nouns contract's rule (plan "omnibase agnostique", C4b): an entity's noun read from the "entities" catalogues through the Translations contract, by the key of its class and the variants its options ask for (Base\Service\Model\NounVariants), the first one the catalogues hold.

It was Base\Service\Translator::transEntity(), transEntityExists() and parseClass(), which now answer by an instance of this class over the translator itself, so Symfony and a host without it name an entity alike. What the rule needs of a framework is given to its constructor: the Translations contract, and the entity namespaces of the application's bundles (namespacesOf() turns a list of bundle classes into them: under Symfony, omnibase's BaseBundle::getBundles(), the Base\<Name>\<Name>Bundle classes declared). App\Entity\, Base\Entity\ and Doctrine's proxies are always known.

const DOMAIN = Translator::DOMAIN_ENTITY
const NAMESPACES = ["Proxies\\__CG__\\" => "", "App\\Entity\\" => "", "Base\\Entity\\" => ""]

The entity namespaces every application has, and what each becomes in a key: nothing (App\Entity\Thread and Base\Entity\Thread are "thread").

EntityNouns::__construct()

public function __construct(readonly Translations $translations, array $namespaces = [])
$namespaces

the bundles' entity namespaces and their prefixes (namespacesOf())

EntityNouns::namespacesOf()

public static function namespacesOf(iterable $bundles): array

The entity namespaces of these bundles (classes or objects): a bundle Base\Marketplace\MarketplaceBundle has its entities under Base\Marketplace\Entity\, whose keys start with "marketplace.".

EntityNouns::getNamespaces()

public function getNamespaces(): array
Returns

the entity namespaces known, and their prefixes

EntityNouns::key()

public function key(object|string $entityOrClass): string

The key of a class in the "entities" catalogues: its name less its entity namespace, dotted, in snake case (Base\Entity\Thread\Tag: "thread.tag"; Base\Marketplace\Entity\Order: "marketplace.order").

EntityNouns::entity()

public function entity(object|string $entityOrClass, ?string $property = null, string|array $options = TranslatorInterface::NOUN_SINGULAR): ?string

EntityNouns::entityExists()

public function entityExists(object|string $entityOrClass, ?string $property = null, string|array $options = TranslatorInterface::NOUN_SINGULAR): bool

EnumNouns class

class EnumNouns EnumNouns.php:26

The words of an enumeration's values (omnibase's |trans_enum): a value of an Base\Database\Type\EnumType - by its class or by the name of its DBAL type ("thread_state") - read from the "enums" catalogues through the Translations contract, under the key of the class that declares the value and its parents down to the type (Base\Enum\ThreadState: "thread_state"), the value lower-cased, the noun's variant its options ask for (Base\Service\Model\NounVariants), the first one the catalogues hold.

It was Base\Service\Translator::transEnum() and transEnumExists(), which now answer by an instance of this class over the translator itself (as EntityNouns for the entities): Symfony and a host without it say an enumeration's values alike. Framework-free: the Translations contract, and Doctrine DBAL's types where a type is named rather than its class.

const DOMAIN = Translator::DOMAIN_ENUM

EnumNouns::__construct()

public function __construct(readonly Translations $translations)

EnumNouns::value()

public function value(?string $value, string $class, null|string|array $options = TranslatorInterface::NOUN_SINGULAR): ?string

The words of $value; when the catalogues have none, the key asked in lower case; $value itself for a class or a type that is none.

EnumNouns::exists()

public function exists(string $value, string $class, string|array $options = TranslatorInterface::NOUN_SINGULAR): bool

Whether the catalogues hold the words of $value, under one of the keys value() tries ($class an enumeration's class).

EnumNouns::extends()

public static function extends(object|string $class): string

A class and its parents, dotted, in snake case (Translator::parseClass(), PARSE_EXTENDS).

GraphInterface interface

interface GraphInterface GraphInterface.php:7

GraphInterface::getParent()

public function getParent()

GraphInterface::getChildren()

public function getChildren(): Collection

GraphInterface::getConnexes()

public function getConnexes(): Collection

HtmlizeInterface interface

interface HtmlizeInterface HtmlizeInterface.php:5

HtmlizeInterface::__toHtml()

public function __toHtml(array $options = [], ...$args): ?string

IconizeInterface interface

interface IconizeInterface IconizeInterface.php:5

IconizeInterface::__iconize()

public function __iconize(): ?array

IconizeInterface::__iconizeStatic()

public static function __iconizeStatic(): ?array

IntlDateTime class

class IntlDateTime extends DateTime IntlDateTime.php:11

IntlDateTime::__construct()

public function __construct(DateTime|string $datetime = "now", ?string $locale = null, int $dateType = IntlDateFormatter::FULL, int $timeType = IntlDateFormatter::FULL, IntlTimeZone|DateTimeZone|string|null $timezone = null, IntlCalendar|int|null $calendar = null)

IntlDateTime::format()

public function format(string $format): string

IntlDateTime::createFromDateTime()

public static function createFromDateTime(DateTime $datetime, ?string $locale = null, int $dateType = IntlDateFormatter::FULL, int $timeType = IntlDateFormatter::FULL, DateTimeZone|string|null $timezone = null, int|null $calendar = null)
Throws

Exception

LinkableInterface interface

interface LinkableInterface LinkableInterface.php:13

A thing with an address. $referenceType is one of Symfony's UrlGeneratorInterface reference types, by their values (Base\Contract\Link's constants, so that the interface names nothing of the routing component); Link::to() makes the address through the Urls contract.

LinkableInterface::__toString()

public function __toString()
public function __toLink(array $routeParameters = [], int $referenceType = Link::ABSOLUTE_PATH): ?string

LocaleNormalizer class

final class LocaleNormalizer LocaleNormalizer.php:29

omnibase's locale form, xx-XX, without the framework (plan "omnibase agnostique", C3e): the rule Base\Service\Localizer::normalizeLocale() and __toLocaleLang() apply, taken out of the Localizer (a Symfony service, its statics filled at its warm-up), which now asks it with its own default and fallback locales - the same strings, by construction.

  • "fr_FR", "fr-FR": five characters, the separator made a dash;
  • "fr", "fr-XX": the language when intl knows it (else the default locale's), and its country among the available locales of that language (the first of them; else the default locale's country), keeping the one given when it is available.

here() is what the entities ask (TranslatableTrait, TranslationTrait): the default and available locales of the Locales contract (Runtime::locales(); under Symfony Base\Bridge\Symfony\LocalizerLocales, the Localizer's own), none when the registry has no Locales, as the Localizer's statics are empty before it is built. Not a contract: a rule over one.

const SEPARATOR = '-'

LocaleNormalizer::getLocales()

public static function getLocales(): array

Every language of intl's xx-YY locales, and its countries.

LocaleNormalizer::normalize()

public static function normalize(string $locale, ?string $defaultLocale, array $availableLocales, ?array $locales = null): string
$availableLocales

the default first, in omnibase's form

$locales

every language and its countries; intl's when null

LocaleNormalizer::lang()

public static function lang(string $locale, ?string $defaultLocale, ?array $locales = null): string

The language of a locale: its first two letters when intl knows them, else the default locale's.

$locales

every language and its countries; intl's when null

LocaleNormalizer::here()

public static function here(string $locale): string

normalize() with the Locales contract's default and available locales (Runtime), as the entities ask; none when the registry has no Locales.

NounVariants class

final class NounVariants NounVariants.php:20

The keys tried for a noun - an entity's (Base\Service\Model\EntityNouns), an enumeration's value (Base\Service\Translator::transEnum()) - after its base key, for the options a call gives: a level of politeness (Translator::POLITENESS_*), a gender (Translator::GENDERNESS_*), singular or plural (TranslatorInterface::NOUN_*).

Moved out of Translator::permutations() (plan "omnibase agnostique", C4b), which now answers by it, so that the entities' nouns are tried in the same order where there is no framework. Plain PHP: the constants are Translator's, a class that loads nothing of the framework.

NounVariants::of()

public static function of(array $options): array

The suffixes to try after a key for these options, the most precise first: every ordering of the level of politeness, the gender and the number asked; then, for a level of politeness the call gave, the levels it falls back on (formal -> polite) and the same key without any; then the bare key.

Returns

the suffixes, the parts asked, whether the call gave a level of its own

Pages interface

interface Pages Pages.php:12

Rows to page through, counted and sliced by whatever runs the query (plan "omnibase agnostic", step F2e): what Base\Service\Model\Pagination asks in place of Doctrine's Query and Paginator. Doctrine's is Base\Bridge\Doctrine\QueryPages (a DQL query, with omnibase's walkers); a plain array is paged by Pagination itself.

Pages::count()

public function count(): int

How many rows in all.

Pages::slice()

public function slice(int $offset, int $limit): array

The rows of one page.

Pagination class

class Pagination implements PaginationInterface, Iterator, Countable Pagination.php:13

const ADAPTERS = ['Doctrine\ORM\Query' => 'Omnibridge\Doctrine\Omnibase\QueryPages']

A query is paged by what runs it (step F2e): Pages, which a Doctrine Query is adapted to (Base\Bridge\Doctrine\QueryPages, by name: nothing of Doctrine is loaded here).

Pagination::__construct()

public function __construct(array|Pages|Query $arrayOrQuery, Urls|RouterInterface $router, ?string $parameterName = "page")
$arrayOrQuery

the rows: an array, or a query's Pages (a Doctrine Query is adapted)

Pagination::pages()

public static function pages(object $query): Pages

The rows of a query as Pages: Pages as they are, a backend's query through its adapter.

Pagination::getCountQuery()

public function getCountQuery(Query $query, bool $bHint = true): Query

since step F2e of the plan "omnibase agnostic": Base\Bridge\Doctrine\QueryPages::countQuery()

Pagination::rewind()

public function rewind(): void

Pagination::next()

public function next(): void

Pagination::count()

public function count(): int

Pagination::key()

public function key(): mixed

Pagination::valid()

public function valid(): bool

Pagination::current()

public function current(): mixed

Pagination::getBookmark()

public function getBookmark(): mixed

Pagination::get()

public function get()
Returns

the rows: the array, or the query's Pages

Pagination::getQuery()

public function getQuery(): ?Query

The page's query, when the Pages are a query's that gives it (Doctrine's QueryPages).

Pagination::isQuery()

public function isQuery()

Whether the rows are a query's Pages (else an array).

Pagination::getTotalCount()

public function getTotalCount()

Pagination::getLastPage()

public function getLastPage()

Pagination::getTotalPages()

public function getTotalPages()

Pagination::getTemplate()

public function getTemplate()

Pagination::setTemplate()

public function setTemplate(string $template)

Pagination::setParameterName()

public function setParameterName($parameterName)

Pagination::getParameterName()

public function getParameterName()

Pagination::getPageRange()

public function getPageRange()

Pagination::setPageRange()

public function setPageRange(int $pageRange)

Pagination::getPageSize()

public function getPageSize()

Pagination::setPageSize()

public function setPageSize($pageSize)

Pagination::getPage()

public function getPage()

Pagination::setPage()

public function setPage($page)

Pagination::getPath()

public function getPath(string $name, int $page = 0, array $parameters = [])

Pagination::getResult()

public function getResult()
Throws

InvalidPageException

PaginationInterface interface

interface PaginationInterface PaginationInterface.php:7

PaginationInterface::getPage()

public function getPage()

PaginationInterface::getPageSize()

public function getPageSize()

PaginationInterface::getPageRange()

public function getPageRange()

PaginationInterface::getTotalPages()

public function getTotalPages()

PaginationInterface::getTemplate()

public function getTemplate()

PaginationInterface::getPath()

public function getPath(string $name, int $page = 0, array $parameters = [])

PaginationInterface::getResult()

public function getResult()

PaginationInterface::getTotalCount()

public function getTotalCount()

SaltInterface interface

interface SaltInterface SaltInterface.php:5

SaltInterface::getSalt()

public function getSalt(): string

SelectInterface interface

interface SelectInterface SelectInterface.php:5

SelectInterface::getIcon()

public static function getIcon(string $id, int $index = -1): ?string

SelectInterface::getText()

public static function getText(string $id): ?string

SelectInterface::getHtml()

public static function getHtml(string $id): ?string

SelectInterface::getData()

public static function getData(string $id): ?array

SitemapEntry class

class SitemapEntry SitemapEntry.php:5

SitemapEntry::getLoc()

public function getLoc(): ?string

SitemapEntry::getLocale()

public function getLocale(): ?string

SitemapEntry::setLocale()

public function setLocale(string $locale): self

SitemapEntry::getPriority()

public function getPriority(): ?float

SitemapEntry::setPriority()

public function setPriority(float $priority): self

SitemapEntry::getLastMod()

public function getLastMod(): ?string

SitemapEntry::setLastMod()

public function setLastMod(string $lastMod): self

SitemapEntry::getChangeFreq()

public function getChangeFreq(): ?string

SitemapEntry::setChangeFreq()

public function setChangeFreq(string $changeFreq): self

SitemapEntry::hasAlternate()

public function hasAlternate(SitemapEntry $entry)

SitemapEntry::getAlternates()

public function getAlternates(): array

SitemapEntry::addAlternate()

public function addAlternate(SitemapEntry $entry): self

SitemapEntry::removeAlternate()

public function removeAlternate(SitemapEntry $entry): self

SitemapEntry::__construct()

public function __construct($loc)

SitemapEntry::toArray()

public function toArray(): array

SpamProtectionInterface interface

interface SpamProtectionInterface SpamProtectionInterface.php:8

SpamProtectionInterface::getSpamBlameable()

public function getSpamBlameable(): ?User

SpamProtectionInterface::getSpamText()

public function getSpamText(): ?string

SpamProtectionInterface::getSpamDate()

public function getSpamDate(): DateTime

SpamProtectionInterface::getSpamCallback()

public function getSpamCallback(int $score)

WorkflowInterface interface

interface WorkflowInterface extends WorkflowInterface WorkflowInterface.php:5

WorkflowInterface::getWorkflowName()

public static function getWorkflowName(): string

WorkflowInterface::getWorkflowType()

public static function getWorkflowType(): string

WorkflowInterface::supports()

public static function supports(): array

WorkflowInterface::supportStrategy()

public static function supportStrategy(): ?string

Base\Service\Model\Color

Palette class

class Palette implements Countable, IteratorAggregate Palette.php:11

Palette::getColorKey()

public function getColorKey()

Palette::setColorKey()

public function setColorKey(int|null $colorKey)

Palette::count()

public function count(): int

Palette::getIterator()

public function getIterator(): ArrayIterator

Palette::getCount()

public function getCount(int $color): int

Palette::getDominantColors()

public function getDominantColors(?int $limit = null): array

Palette::fromFilename()

public static function fromFilename(string $filename, int|null $colorKey = null): self

Palette::fromGD()

public static function fromGD(GdImage $image, int|null $colorKey = null): self

Palette::load()

public function load($filenameOrImage, int|null $colorKey = null): Palette

Palette::loadResource()

public function loadResource(GdImage|false $resource, int|null $colorKey = null): Palette

Base\Service\Model\Color\Intl

Colors class

final class Colors Colors.php:10

Colour names: the CSS named colours (CSS Color Module Level 4) with their sRGB hex codes, one name per code (aqua for cyan, fuchsia for magenta, the -gray spellings for -grey).

symfony/intl ships no colour bundle: the names are CSS's, the same in every locale.

const NAMES = ['aliceblue' => '#F0F8FF', 'antiquewhite' => '#FAEBD7', 'aqua' => '#00FFFF', 'aquamarine' => '#7FFFD4', 'azure' => '#F0FFFF', 'beige' => '#F5F5DC', 'bisque' …

Colors::getLocaleLanguageCodes()

public static function getLocaleLanguageCodes(): array
Returns

the locales the names are given in: CSS's names are English

Colors::exists()

public static function exists(string $color): bool

A CSS colour name, or a "#RRGGBB" code.

Colors::getName()

public static function getName(string $color, ?string $displayLocale = null): string

A colour's name: a name as it is, a "#RRGGBB" code the nearest CSS name (by RGB distance). The locale is not used: the names are CSS's.

Colors::getNames()

public static function getNames(?string $displayLocale = null): array
Returns

"#RRGGBB" => name, sorted by name

Colors::getHSL()

public static function getHSL(string $color): array

Colors::getRGB()

public static function getRGB(string $color): array

Colors::getHexCode()

public static function getHexCode(string $color): string

A CSS name's "#RRGGBB" code (a code as it is).

Colors::getHexCodes()

public static function getHexCodes(): array
Returns

name => "#RRGGBB"

Base\Service\Model\Currency

AbstractCurrencyApi class

abstract class AbstractCurrencyApi implements CurrencyApiInterface AbstractCurrencyApi.php:7

AbstractCurrencyApi::__construct()

public function __construct(SettingBag $settingBag)

AbstractCurrencyApi::getName()

public static function getName(): string

AbstractCurrencyApi::supports()

public function supports(string $key): bool

AbstractCurrencyApi::getPriority()

public function getPriority(): int

AbstractCurrencyApi::getOptions()

public function getOptions(): array

AbstractCurrencyApi::getKey()

public function getKey(): ?string

CurrencyApiInterface interface

interface CurrencyApiInterface CurrencyApiInterface.php:5

CurrencyApiInterface::supports()

public function supports(string $key): bool

CurrencyApiInterface::getPriority()

public function getPriority(): int

CurrencyApiInterface::getOptions()

public function getOptions(): array

CurrencyApiInterface::getKey()

public function getKey(): ?string

Base\Service\Model\Currency\Api

AbstractApi class

class AbstractApi extends AbstractCurrencyApi AbstractApi.php:9

AbstractApi::getOptions()

public function getOptions(): array

CurrencyLayer class

class CurrencyLayer extends AbstractCurrencyApi CurrencyLayer.php:10

CurrencyLayer::__construct()

public function __construct(SettingBagInterface $settings, bool $enterprise = false)

CurrencyLayer::getOptions()

public function getOptions(): array

ExchangeRatesApi class

class ExchangeRatesApi extends AbstractCurrencyApi ExchangeRatesApi.php:9

ExchangeRatesApi::getOptions()

public function getOptions(): array

Fixer class

class Fixer extends AbstractCurrencyApi Fixer.php:9

Fixer::getOptions()

public function getOptions(): array

Base\Service\Model\IconProvider

AbstractIconAdapter class

abstract class AbstractIconAdapter extends AbstractLocalCache implements IconAdapterInterface AbstractIconAdapter.php:12

AbstractIconAdapter::__construct()

public function __construct(string $cacheDir, ?string $buildDir = null)

AbstractIconAdapter::warmUp()

public function warmUp(string $cacheDir, ?string $buildDir = null): array

AbstractIconAdapter::getVersion()

public function getVersion(): string

AbstractIconAdapter::getContents()

public function getContents()

AbstractIconAdapter::getMetadata()

public function getMetadata()

AbstractIconAdapter::getEntries()

public function getEntries()

AbstractIconAdapter::getEntry()

public function getEntry(?string $value = null): string

AbstractIconAdapter::iconify()

public function iconify(IconizeInterface|string $icon, array $attributes = []): string

IconAdapterInterface interface

interface IconAdapterInterface IconAdapterInterface.php:7

IconAdapterInterface::supports()

public function supports(IconizeInterface|string|null $icon): bool

IconAdapterInterface::iconify()

public function iconify(IconizeInterface|string $icon, array $attributes): string

IconAdapterInterface::getName()

public static function getName(): string

IconAdapterInterface::getOptions()

public static function getOptions(): array

IconAdapterInterface::getVersion()

public function getVersion(): string

IconAdapterInterface::getAssets()

public function getAssets(): array

IconAdapterInterface::getChoices()

public function getChoices(string $term = "")

Base\Service\Model\IconProvider\Adapter

BootstrapTwitterAdapter class

class BootstrapTwitterAdapter extends AbstractIconAdapter BootstrapTwitterAdapter.php:8

const STYLE_REGULAR = "regular"
const STYLE_FILL = "filled"

BootstrapTwitterAdapter::getName()

public static function getName(): string

BootstrapTwitterAdapter::getOptions()

public static function getOptions(): array

BootstrapTwitterAdapter::__construct()

public function __construct(string $metadata, string $cacheDir, ?string $buildDir = null, ?string $stylesheet = null)

BootstrapTwitterAdapter::getAssets()

public function getAssets(): array

BootstrapTwitterAdapter::supports()

public function supports(IconizeInterface|string|null $icon): bool

BootstrapTwitterAdapter::warmUp()

public function warmUp(string $cacheDir, ?string $buildDir = null): array

BootstrapTwitterAdapter::getChoices()

public function getChoices(string $term = ""): array

BootstrapTwitterAdapter::getStyle()

public function getStyle(string $name)

BootstrapTwitterAdapter::getIdentifier()

public function getIdentifier(string $name)
Throws

Exception

BootstrapTwitterAdapter::getValues()

public function getValues()

BootstrapTwitterAdapter::getValue()

public function getValue(string $name)

BootstrapTwitterAdapter::getLabels()

public function getLabels()

BootstrapTwitterAdapter::getLabel()

public function getLabel(string $name)

FontAwesomeAdapter class

class FontAwesomeAdapter extends AbstractIconAdapter FontAwesomeAdapter.php:8

const STYLE_SOLID = "solid"
const STYLE_REGULAR = "regular"
const STYLE_LIGHT = "light"
const STYLE_THIN = "thin"
const STYLE_DUOTONE = "duotone"
const STYLE_BRANDS = "brands"
const STYLE_KIT = "kit"

FontAwesomeAdapter::__construct()

public function __construct(string $metadata, string $cacheDir, ?string $buildDir = null, ?string $javascript = null, ?string $stylesheet = null)

FontAwesomeAdapter::getName()

public static function getName(): string

FontAwesomeAdapter::getOptions()

public static function getOptions(): array

FontAwesomeAdapter::getAssets()

public function getAssets(): array

FontAwesomeAdapter::warmUp()

public function warmUp(string $cacheDir, ?string $buildDir = null): array

FontAwesomeAdapter::supports()

public function supports(IconizeInterface|string|null $icon): bool

FontAwesomeAdapter::getClass()

public function getClass(string $style): ?string

FontAwesomeAdapter::getChoices()

public function getChoices(string $term = ""): array

FontAwesomeAdapter::getStyle()

public function getStyle(string $name)

FontAwesomeAdapter::getIdentifier()

public function getIdentifier(string $name)
Throws

Exception

FontAwesomeAdapter::getStyles()

public function getStyles(?string $name = null)

FontAwesomeAdapter::getValues()

public function getValues()

FontAwesomeAdapter::getValue()

public function getValue(string $name)

FontAwesomeAdapter::getLabels()

public function getLabels()

FontAwesomeAdapter::getLabel()

public function getLabel(string $name)

FontAwesomeAdapter::getUnicodes()

public function getUnicodes()

FontAwesomeAdapter::getUnicode()

public function getUnicode(string $name)

Base\Service\Model\Obfuscator

AbstractCompression class

abstract class AbstractCompression implements CompressionInterface AbstractCompression.php:7

AbstractCompression::supports()

public function supports(string $name): bool

AbstractCompression::getLevel()

public function getLevel(): int

AbstractCompression::setLevel()

public function setLevel(int $level): static

AbstractCompression::getEncoding()

public function getEncoding(): ?string

AbstractCompression::setEncoding()

public function setEncoding(?string $encoding): static

AbstractCompression::getMaxLength()

public function getMaxLength(): int

AbstractCompression::setMaxLength()

public function setMaxLength(int $maxLength): static

AbstractCompression::encode()

public function encode(string $data): ?string

AbstractCompression::decode()

public function decode(string $hex): ?string

CompressionInterface interface

interface CompressionInterface CompressionInterface.php:5

CompressionInterface::getName()

public function getName(): string

CompressionInterface::supports()

public function supports(string $name): bool

CompressionInterface::encode()

public function encode(string $data): ?string

CompressionInterface::decode()

public function decode(string $hex): ?string

Base\Service\Model\Obfuscator\Compression

DeflateCompression class

class DeflateCompression extends AbstractCompression DeflateCompression.php:7

DeflateCompression::getName()

public function getName(): string

DeflateCompression::getEncoding()

public function getEncoding(): ?string

GzipCompression class

class GzipCompression extends AbstractCompression GzipCompression.php:7

GzipCompression::getName()

public function getName(): string

GzipCompression::getEncoding()

public function getEncoding(): ?string

HashidsCompression class

class HashidsCompression extends AbstractCompression HashidsCompression.php:8

HashidsCompression::__construct()

public function __construct(string $secret)

HashidsCompression::getName()

public function getName(): string

HashidsCompression::getEncoding()

public function getEncoding(): ?string

HashidsCompression::isValid()

public function isValid(string $hash): bool

NullCompression class

class NullCompression extends AbstractCompression NullCompression.php:7

NullCompression::getName()

public function getName(): string

ZlibCompression class

class ZlibCompression extends AbstractCompression ZlibCompression.php:7

ZlibCompression::getName()

public function getName(): string

ZlibCompression::getEncoding()

public function getEncoding(): ?string

Base\Service\Model\Sharing

AbstractSharingAdapter class

abstract class AbstractSharingAdapter implements SharingAdapterInterface, IconizeInterface AbstractSharingAdapter.php:10

AbstractSharingAdapter::__iconize()

public function __iconize(): ?array

AbstractSharingAdapter::__construct()

public function __construct(Views|Environment $views)
$views

Twig's environment is deprecated (until 6.0)

AbstractSharingAdapter::getTemplate()

public function getTemplate(): string

AbstractSharingAdapter::generate()

public function generate(array $options, ?string $template = null): string

SharingAdapterInterface interface

interface SharingAdapterInterface SharingAdapterInterface.php:5

SharingAdapterInterface::getIdentifier()

public function getIdentifier(): string

SharingAdapterInterface::getUrl()

public function getUrl(): string

SharingAdapterInterface::getTemplate()

public function getTemplate(): string

SharingAdapterInterface::generate()

public function generate(array $options, ?string $template = null): string

Base\Service\Model\Sharing\Adapter

FacebookAdapter class

class FacebookAdapter extends AbstractSharingAdapter FacebookAdapter.php:7

FacebookAdapter::getIdentifier()

public function getIdentifier(): string

FacebookAdapter::getUrl()

public function getUrl(): string

FacebookAdapter::__iconizeStatic()

public static function __iconizeStatic(): ?array

GooglePlusAdapter class

class GooglePlusAdapter extends AbstractSharingAdapter GooglePlusAdapter.php:7

GooglePlusAdapter::getIdentifier()

public function getIdentifier(): string

GooglePlusAdapter::getUrl()

public function getUrl(): string

GooglePlusAdapter::__iconizeStatic()

public static function __iconizeStatic(): ?array

LinkedInAdapter class

class LinkedInAdapter extends AbstractSharingAdapter LinkedInAdapter.php:7

LinkedInAdapter::getIdentifier()

public function getIdentifier(): string

LinkedInAdapter::getUrl()

public function getUrl(): string

LinkedInAdapter::__iconizeStatic()

public static function __iconizeStatic(): ?array

PinterestAdapter class

class PinterestAdapter extends AbstractSharingAdapter PinterestAdapter.php:7

PinterestAdapter::getIdentifier()

public function getIdentifier(): string

PinterestAdapter::getUrl()

public function getUrl(): string

PinterestAdapter::__iconizeStatic()

public static function __iconizeStatic(): ?array

TumblrAdapter class

class TumblrAdapter extends AbstractSharingAdapter TumblrAdapter.php:7

TumblrAdapter::getIdentifier()

public function getIdentifier(): string

TumblrAdapter::getUrl()

public function getUrl(): string

TumblrAdapter::__iconizeStatic()

public static function __iconizeStatic(): ?array

TwitterAdapter class

class TwitterAdapter extends AbstractSharingAdapter TwitterAdapter.php:7

TwitterAdapter::getIdentifier()

public function getIdentifier(): string

TwitterAdapter::getUrl()

public function getUrl(): string

TwitterAdapter::__iconizeStatic()

public static function __iconizeStatic(): ?array

Base\Service\Model\Wysiwyg

EditorJsRenderer class

final class EditorJsRenderer EditorJsRenderer.php:17

EditorJS's saved document ({"blocks": [...]}) as HTML, on the server: what a page shows without the editor's script, what a crawler, an e-mail or a feed reads. The blocks of omnibase's editor: paragraph, header, list (nested, ordered, checklist), checklist, quote, image, embed, table, code, delimiter, warning, alert, raw, linkTool, attaches. A block of a type it does not know is left out.

The text of a block is the editor's inline HTML (bold, links, marks, mentions): kept, minus what could run (tags outside the list below, on* attributes, javascript: addresses).

EditorJsRenderer::render()

public static function render(mixed $document): string

HeadingEnhancer class

class HeadingEnhancer implements HeadingEnhancerInterface HeadingEnhancer.php:11

HeadingEnhancer::__construct()

public function __construct(UnitOfWork|EntityManagerInterface $unitOfWork, SluggerInterface $slugger)
$unitOfWork

the entity manager is deprecated (until 6.0): adapted by UnitOfWorks

HeadingEnhancer::toc()

public function toc(mixed $html, ?int $maxLevel = null): array

HeadingEnhancer::enhance()

public function enhance(mixed $html, ?int $maxLevel = null, array $attrs = []): mixed

HeadingEnhancerInterface interface

interface HeadingEnhancerInterface HeadingEnhancerInterface.php:5

HeadingEnhancerInterface::enhance()

public function enhance(string|array|null $strOrArray, ?int $maxLevel, array $attributes = []): mixed

HeadingEnhancerInterface::toc()

public function toc(mixed $strOrArray, ?int $maxLevel): array

LinkEnhancer class

class LinkEnhancer implements LinkEnhancerInterface LinkEnhancer.php:7

LinkEnhancer::enhance()

public function enhance(string|array|null $strOrArray, array $attributes = []): string|array|null

Rewrites same-site absolute <a href> links back to relative, leaving everything else (external links, already-relative paths, anchors, mailto:/tel:, ...) untouched.

An editor authoring/pasting a link always bakes in whatever host they were browsing at the time (EditorJS's built-in inline "link" tool stores the href verbatim, no normalization) - on this app that means an absolute https://m.example.org/... URL sits in the stored content forever, so viewing that same article on beta.m.example.org (or any other environment sharing the DB) silently bounces the reader back to production instead of following the link on the current host (reported live).

"Same site" is deliberately domain+subdomain, NOT the full host: AdvancedRouter's own getDomain()/getSubdomain()/getMachine() split (see parse_url2()) treats "example.org" + "m" as the stable site identity and "machine" (beta/empty) as the part that legitimately varies per environment - comparing full hosts would never match beta against prod, which is exactly the case this exists to fix.

LinkEnhancerInterface interface

interface LinkEnhancerInterface LinkEnhancerInterface.php:5

LinkEnhancerInterface::enhance()

public function enhance(string|array|null $strOrArray, array $attributes = []): string|array|null

MediaEnhancer class

class MediaEnhancer implements MediaEnhancerInterface MediaEnhancer.php:11

MediaEnhancer::__construct()

public function __construct(MediaServiceInterface $mediaService, Storages $flysystem, ?LoggerInterface $logger = null)

MediaEnhancer::enhance()

public function enhance(string|array|null $strOrArray, array $config = [], FilterInterface|array $filters = [], array $attributes = []): string|array|null

MediaEnhancerInterface interface

interface MediaEnhancerInterface MediaEnhancerInterface.php:7

MediaEnhancerInterface::enhance()

public function enhance(string|array|null $strOrArray, array $config = [], FilterInterface|array $filters = [], array $attributes = []): string|array|null

MentionEnhancer class

class MentionEnhancer implements MentionEnhancerInterface MentionEnhancer.php:14

MentionEnhancer::__construct()

public function __construct(Mentions $mentionRepository, Users $userRepository, Repositories $repositories, ObfuscatorInterface $obfuscator)

MentionEnhancer::mentions()

public function mentions(): Mentions

MentionEnhancer::getRepository()

public function getRepository(): Mentions

since omnibase 4.0 (step R28), the mentions by their interface: mentions()

MentionEnhancer::extractMentionees()

public function extractMentionees(string|array|null $strOrArray, array $attributes = []): array

MentionEnhancer::enhance()

public function enhance(string|array|null $strOrArray, array $attributes = []): string|array|null

MentionEnhancerInterface interface

interface MentionEnhancerInterface MentionEnhancerInterface.php:7

MentionEnhancerInterface::mentions()

public function mentions(): Mentions

The mentions, by their interface (step R28).

MentionEnhancerInterface::getRepository()

public function getRepository(): Mentions

since omnibase 4.0 (step R28): mentions()

MentionEnhancerInterface::extractMentionees()

public function extractMentionees(string|array|null $strOrArray, array $attributes = []): array

MentionEnhancerInterface::enhance()

public function enhance(string|array|null $strOrArray, array $attributes = []): string|array|null

SemanticEnhancer class

class SemanticEnhancer implements SemanticEnhancerInterface SemanticEnhancer.php:7

SemanticEnhancer::__construct()

public function __construct(Semantics $semanticRepository)

SemanticEnhancer::enhance()

public function enhance(string|array|null $strOrArray, null|array|string $words = null, array $attributes = []): string|array|null

SemanticEnhancerInterface interface

interface SemanticEnhancerInterface SemanticEnhancerInterface.php:5

SemanticEnhancerInterface::enhance()

public function enhance(string|array|null $strOrArray, null|array|string $words = null, array $attributes = []): string|array|null

Base\Service\Push

WebPushService class

class WebPushService WebPushService.php:27

Web Push delivery (RFC 8030 + VAPID) to the browsers a user enabled notifications in. The service is a no-op until VAPID keys are configured (VAPID_PUBLIC_KEY / VAPID_PRIVATE_KEY / VAPID_SUBJECT), so the rest of the notification center works without it - the in-app list, the badge - and push simply switches on the day the keys land in .env.local.

Generate a pair once per site with bin/console push:vapid (or VAPID::createVapidKeys()); rotating them invalidates every subscription, so treat them like a credential, not a config knob.

WebPushService::__construct()

public function __construct(UnitOfWork|EntityManagerInterface $unitOfWork, protected readonly PushSubscriptions $repository, protected readonly ?LoggerInterface $logger = null, protected readonly ?string $publicKey = null, protected readonly ?string $privateKey = null, protected readonly ?string $subject = null)
$unitOfWork

the entity manager is deprecated (until 6.0): adapted by UnitOfWorks

WebPushService::isConfigured()

public function isConfigured(): bool

WebPushService::getPublicKey()

public function getPublicKey(): ?string

WebPushService::createKeys()

public static function createKeys(): array

WebPushService::countReachableUsers()

public function countReachableUsers(): int

How many people would receive a push right now (one per user, however many browsers they enabled it in).

WebPushService::subscriptionsOf()

public function subscriptionsOf(User $user): array

WebPushService::subscribe()

public function subscribe(User $user, array $subscription, ?string $userAgent = null): PushSubscription

Registers (or refreshes) one browser's subscription for a user. The browser may re-send the same endpoint (page reload, permission re-prompt); that is an update, not a duplicate.

WebPushService::unsubscribe()

public function unsubscribe(User $user, string $endpoint): bool

WebPushService::sendToUsers()

public function sendToUsers(iterable $users, array $payload): int

Sends one payload to every browser of every given user. Returns the number of subscriptions accepted by their push service. Dead subscriptions (404/410: the browser revoked it) are deleted on the way.

Base\Service\Qr

QrCode class

class QrCode QrCode.php:16

A QR code for an address (or any text), drawn by endroid/qr-code: as SVG - sharp at any print size, the default - or PNG. Used by QrSheet for its pages, and directly for a poster or a ticket:

<img src="{{ qr_code(url('app_menu')) }}" alt="">

QrCode::svg()

public function svg(string $data, int $size = 600, int $margin = 0): string

The SVG markup.

QrCode::dataUri()

public function dataUri(string $data, int $size = 600, int $margin = 0, string $format = 'svg'): string

A data: URI to put in an <img src>: SVG, or PNG when asked (needs GD).

QrSheet class

class QrSheet QrSheet.php:24

QR codes laid out on A4 pages to print: one big code per page (a poster for a counter, a door, a table), or a sheet of Avery labels - each label a code and a caption, at the label's place on the sheet, in millimetres.

return new Response($sheet->render([ ['data' => $url, 'label' => 'Table 4'], ... ], 'L7160', 'Tables'));

Layouts (LAYOUTS): 'a4' one per page; Avery 'L7160' (21 labels of 63.5 x 38.1 mm), 'L7163' (14 of 99.1 x 38.1 mm), 'L7121' (20 squares of 45 x 45 mm, made for QR codes). The page prints at 100 % (no "fit to page") with @page margins of zero - the template sets both.

const LAYOUTS = ['a4' => ['width' => 210.0, 'height' => 297.0, 'columns' => 1, 'rows' => 1, 'top' => 0.0, 'left' => 0.0, 'pitchX' => 210.0, 'pitchY' => 297.0], 'L7160' => ['…

In millimetres: label size, columns x rows, the first label's top-left corner, the step from one label to the next.

QrSheet::__construct()

public function __construct(protected readonly QrCode $qr, Views|Environment|null $views = null)

QrSheet::layout()

public static function layout(string $name): array

QrSheet::pages()

public function pages(iterable $items, string $layout = 'a4', int $skip = 0): array

The items placed on their pages: each label's position (mm) and its code as a data URI. $skip leaves the first labels of the first sheet empty - those already used on a sheet put back in the printer.

Returns

pages of labels

QrSheet::render()

public function render(iterable $items, string $layout = 'a4', ?string $title = null, int $skip = 0): string

The printable HTML page (@Base/qr/sheet.html.twig).

Base\Service\Ticket

TicketSigner class

final class TicketSigner TicketSigner.php:14

The tickets' one format: base64url(json payload) . "." . hex(hmac_sha256(that base64url, secret)). Every service that checks tickets by itself reads exactly this, so it is written once, here, rather than in each factory - two copies checking a signature two slightly different ways is the bug nobody finds. The payload always names its room and when it expires (room, exp, a Unix time); the rest is the factory's.

Pure: no state, no framework. Used by Base\Contract\Tickets implementations (Base\Service\Collab\CollabTicketFactory and an application's own).

TicketSigner::sign()

public static function sign(array $payload, string $secret): string

TicketSigner::verify()

public static function verify(string $token, string $secret, string $room): ?array

A token's payload when its signature holds, it has not expired and it is for this room; null otherwise (an empty secret never verifies anything).

Base\Thread

ThreadActions class

final class ThreadActions ThreadActions.php:28

The threads' API (/api/thread/{slug}/...), written once for every host (plan "omnibase agnostic", step F5e, slice 5b; formerly Api\ThreadController): a thread published or hidden by an administrator, followed or no longer followed by a member, liked or no longer liked - each by the "api_thread" token (the body's _token or an X-CSRF-Token header: as plain GET routes, a link or a picture elsewhere published a thread for a signed-in administrator, and made anyone like it). Each answers the JSON the controller answered, statuses included (a visitor's "Unauthorized" carries 401 in its body under a 200, as it did); null is no such thread (404).

const TOKEN = 'api_thread'

ThreadActions::__construct()

public function __construct(readonly Access $access, readonly Tokens $tokens, readonly UnitOfWork $unitOfWork, readonly Threads $threads, readonly Likes $likes, readonly ?TranslatorInterface $translator = null, readonly ?Requests $requests = null)

ThreadActions::denied()

public function denied(?string $token): ?Json

The refusal of a request without the token, null with it.

ThreadActions::publish()

public function publish(string $slug, ?string $token): ?Json

ThreadActions::hide()

public function hide(string $slug, ?string $token): ?Json

ThreadActions::follow()

public function follow(string $slug, ?string $token): ?Json

ThreadActions::unfollow()

public function unfollow(string $slug, ?string $token): ?Json

ThreadActions::like()

public function like(string $slug, ?string $token): ?Json

ThreadActions::unlike()

public function unlike(string $slug, ?string $token): ?Json

ThreadSearch class

final class ThreadSearch ThreadSearch.php:18

The threads' search, written once for every host (plan "omnibase agnostic", step F5e, slice 5b; formerly ThreadSearchController::Main()): the generic term stands for the title, the excerpt and the content where they are not given apart; the published threads only, every state for an administrator; under the parent asked; the threads of the class highest in the hierarchy first. The model keeps the raw terms: the page highlights them.

const TEMPLATE = 'client/thread/search.html.twig'

ThreadSearch::__construct()

public function __construct(readonly Access $access, readonly ThreadTranslations $translations, readonly Repositories $repositories)

ThreadSearch::find()

public function find(?object $model): array

The model completed (a copy) and the threads found; no model, nothing looked for.

Base\Traits

BagTrait trait

trait BagTrait BagTrait.php:7

BagTrait::read()

public static function read(?string $path, array $bag = [])
Throws

Exception

BagTrait::write()

public static function write($path, $value, array &$bag = [])

BaseCommonTrait trait

trait BaseCommonTrait BaseCommonTrait.php:28

BaseCommonTrait::setRuntime()

public static function setRuntime(?RuntimeLocatorInterface $runtime): void

Installing a DIFFERENT locator means a different kernel, and everything memoised from the previous one (by runtimeGet() or by an eagerly built BaseService's set*() calls) belongs to a container that is gone. Those statics are cleared, so every accessor re-resolves lazily from the new kernel - the process then behaves exactly like a fresh first boot.

Without this, a second kernel in the same process silently ran on the FIRST kernel's services. It never shows in production (an FPM request or a messenger worker boots once), but any process that boots twice does - a PHPUnit run of several KernelTestCase tests that persist entities failed three different ways at once: "The kernel service is synthetic", "Undefined array key preQuery" (a dead event manager), and "Column uuid cannot be null" (GenerateUuid wired to the old one).

The first installation (from null) resets nothing: there is nothing stale yet, and values pre-filled before it must survive. Re-installing the SAME locator resets nothing either.

projectDir/environment are reset too; BaseBundle::boot() re-seeds both right after calling this.

BaseCommonTrait::runtimeGet()

public static function runtimeGet(string $property, string $serviceId)

Resolve a static property, lazily pulling the backing service from the runtime locator on first access. Memoizes into the static property, so each service is resolved at most once per RUNTIME (per kernel; see setRuntime(), which clears these when a new kernel boots) — and an eagerly constructed BaseService (which still calls the set*() methods) simply pre-fills the same properties.

BaseCommonTrait::hasInstance()

public function hasInstance()

BaseCommonTrait::getInstance()

public function getInstance()

BaseCommonTrait::setInstance()

public function setInstance($instance)

BaseCommonTrait::setProjectDir()

public static function setProjectDir($projectDir)

BaseCommonTrait::setEnvironment()

public static function setEnvironment(?string $environment)

BaseCommonTrait::setTranslator()

public static function setTranslator(?TranslatorInterface $translator)

BaseCommonTrait::setRequestStack()

public static function setRequestStack(RequestStack $requestStack)

BaseCommonTrait::setObfuscator()

public static function setObfuscator(Obfuscator $obfuscator)

BaseCommonTrait::setDoctrine()

public static function setDoctrine(?ManagerRegistry $doctrine)

BaseCommonTrait::setEntityHydrator()

public static function setEntityHydrator(EntityHydratorInterface $entityHydrator)

BaseCommonTrait::setLocalizer()

public static function setLocalizer(?LocalizerInterface $localizer)

BaseCommonTrait::setTrading()

public static function setTrading(?TradingInterface $tradingMarket)

BaseCommonTrait::setTokenStorage()

public static function setTokenStorage(?TokenStorageInterface $tokenStorage)

BaseCommonTrait::setSlugger()

public static function setSlugger(?SluggerInterface $slugger)

BaseCommonTrait::setIconProvider()

public static function setIconProvider(?IconProvider $iconProvider)

BaseCommonTrait::setClassMetadataManipulator()

public static function setClassMetadataManipulator(null|MetadataManipulator|\Omnibridge\Doctrine\Omnibase\Database\Mapping\ClassMetadataManipulator $classMetadataManipulator)

BaseCommonTrait::setMediaService()

public static function setMediaService(?MediaServiceInterface $mediaService)

BaseCommonTrait::setFirewallMap()

public static function setFirewallMap(?FirewallMapInterface $firewallMap)

BaseCommonTrait::setRouter()

public static function setRouter(AdvancedRouterInterface $router)

BaseCommonTrait::setTwig()

public static function setTwig(Environment $twig)

BaseCommonTrait::setSettingBag()

public static function setSettingBag(SettingBagInterface $settings)

BaseCommonTrait::setParameterBag()

public static function setParameterBag(ParameterBagInterface $parameterBag)

BaseCommonTrait::setNotifier()

public static function setNotifier(NotifierInterface $notifier)

BaseTrait trait

trait BaseTrait BaseTrait.php:59

Static service accessors usable from anywhere (entities, attributes, subscribers, ...): the tool for writing an application quickly (plan "omnibase agnostique", C9 - Marco: "BaseTrait était un outil qui me permettait de développer rapidement"). It stays, and is not deprecated.

The rule: BaseTrait to go fast in an application; the contracts (Base\Contract\Runtime and its interfaces) in the core and the bundles, which add no new use of it (docs/20-architecture/contracts.md).

**Contracts only** (plan "omnibase agnostic", step F2f): every accessor here names a contract - an interface of omnisense/omnibridge or Base\Contract, or a class of the agnostic core (tests/Agnostic.php) -, never a class of Symfony, Doctrine or Twig (tests/Traits/BaseTraitContractsTest.php). Each service comes in two forms: - getX() answers it, or throws Omnibridge\Exception\MissingContractException when the host has none: for a caller that needs it, which used to fail further on a call on null; - findX() answers it or null: for a caller that does without (an optional service, a command without a request, a host that does not answer it).

The framework's services it handed out before (the router, Twig, Doctrine's registry and entity manager, the request stack, the token storage, the firewall map, the slugger, the BaseService facade) are in Base\Traits\FrameworkAccessorsTrait, which this trait still uses: deprecated, typed and nullable as they were, removed at 6.0. The core's host code asks them of Base\Bridge\Symfony\FrameworkLocator.

An accessor whose answer a contract gives asks the registry first, so it answers wherever the registry is filled, Symfony or not: getParameterBag() (Runtime::parameters()), getEnvironment() (Runtime::environment()->name()), getMediaService() (omnibridge/laravel binds omnibase's MediaService). The others are resolved one at a time, lazily, through the base.runtime ServiceLocator seeded in BaseBundle::boot() (BaseCommonTrait::runtimeGet()), or pre-filled when BaseService is built - which nothing does any more on a page's path (BaseService is a lazy service, C9). What they resolve is kept on Base\Service\Locator, framework-free (step R28).

BaseTrait::findAttributeReader()

public static function findAttributeReader(): ?AttributeReader

BaseTrait::getAttributeReader()

public static function getAttributeReader(): AttributeReader

BaseTrait::findSettingBag()

public static function findSettingBag(): ?SettingBag

BaseTrait::getSettingBag()

public static function getSettingBag(): SettingBag

BaseTrait::isEntity()

public static function isEntity(mixed $entityOrClassOrMetadata): bool

Whether the persistence maps it as an entity (an object, a class, a metadata): Doctrine's manipulator where the host gives it, else the unit of work's shapes for an object or a class (a host without it: omnibridge/laravel; a metadata is Doctrine's, which the manipulator answers).

BaseTrait::getProjectDir()

public static function getProjectDir(): string

BaseTrait::getEnvironment()

public static function getEnvironment(): string

The Environment contract's name when the registry has it (C9), else the kernel's, seeded at boot.

BaseTrait::getPublicDir()

public static function getPublicDir(): string

BaseTrait::getTemplateDir()

public static function getTemplateDir(): string

BaseTrait::getTranslationDir()

public static function getTranslationDir(): string

BaseTrait::getCacheDir()

public static function getCacheDir(): string

BaseTrait::getLogDir()

public static function getLogDir(): string

BaseTrait::getDataDir()

public static function getDataDir(): string

BaseTrait::getFixtureDir()

public static function getFixtureDir(): string

BaseTrait::findEntityHydrator()

public static function findEntityHydrator(): ?EntityHydratorInterface

BaseTrait::getEntityHydrator()

public static function getEntityHydrator(): EntityHydratorInterface

BaseTrait::findMediaService()

public static function findMediaService(): ?MediaService

BaseTrait::getMediaService()

public static function getMediaService(): MediaService

BaseTrait::findObfuscator()

public static function findObfuscator(): ?Obfuscator

BaseTrait::getObfuscator()

public static function getObfuscator(): Obfuscator

BaseTrait::findIconProvider()

public static function findIconProvider(): ?IconProvider

BaseTrait::getIconProvider()

public static function getIconProvider(): IconProvider

BaseTrait::findLocalizer()

public static function findLocalizer(): ?LocalizerInterface

BaseTrait::getLocalizer()

public static function getLocalizer(): LocalizerInterface

BaseTrait::findNotifier()

public static function findNotifier(): ?BaseNotifierInterface

BaseTrait::getNotifier()

public static function getNotifier(): BaseNotifierInterface

BaseTrait::findTranslator()

public static function findTranslator(): ?TranslatorInterface

BaseTrait::getTranslator()

public static function getTranslator(): TranslatorInterface

BaseTrait::findTrading()

public static function findTrading(): ?TradingInterface

BaseTrait::getTrading()

public static function getTrading(): TradingInterface

BaseTrait::findParameterBag()

public static function findParameterBag(): ?ParameterBagInterface

The parameters contract when the registry has it (C9): under Symfony the same parameter_bag (the settings stored in the database over the container's).

BaseTrait::getParameterBag()

public static function getParameterBag(string $key = "", ?array $bag = null)

The application's parameters, or one of them by its dotted path (null when it has no such key); MissingContractException when the host has no parameters at all.

CacheClearTrait trait

trait CacheClearTrait CacheClearTrait.php:18

since 5.0 (plan "omnibase agnostic", step F5e, slice 3): its checks are Base\Console\Task\CacheClear's, printed through a Base\Console\Report. Kept for omnibridge/symfony's former cache:clear (its Legacy\, which omnibase 4.x runs); removed at 6.0.

CacheableTrait trait

trait CacheableTrait CacheableTrait.php:5

CacheableTrait::__toKey()

public function __toKey(mixed ...$variadic): string

CacheableTrait::__toKeyTTL()

public function __toKeyTTL(): ?int

CacheableTrait::__toKeyTags()

public function __toKeyTags(): array

FrameworkAccessorsTrait trait

trait FrameworkAccessorsTrait FrameworkAccessorsTrait.php:46

since omnisense/omnibase 4.0 (F2f): removed with the former names at 6.0, after the sites have moved (step S of the plan).

BaseTrait's accessors of the framework's services, from before BaseTrait named contracts only (plan "omnibase agnostic", step F2f). BaseTrait still uses this trait, so that the bundles and the applications that call them keep working; each call is deprecated (E_USER_DEPRECATED) and answers as before - the service, or null where the host has none.

What to call instead, in an application or a bundle: - getRouter()->generate($name, $parameters, $referenceType): Base\Contract\Link::to() (the same string under Symfony), or Runtime::urls(); - getTwig(): Omnibridge\Contract\Views (Runtime::views()) where the host answers it; - getEntityManager(), getDoctrine(), getObjectManager(), getRepository(): the unit of work (Runtime::unitOfWork(), an injected Omnibridge\Persistence\UnitOfWork), the repositories by interface or Base\Database\UnitOfWorks::repositories(); - getClassMetadataManipulator(): Base\Database\UnitOfWorks::shapes(); BaseTrait::isEntity(); - getTokenStorage(), getRequestStack(), getFirewallMap(): Runtime::access(), Runtime::sessions(), Runtime::routes(); - getService(): the contracts the facade answered (Runtime::environment(), ::access()...); - getSlugger(): symfony/string's AsciiSlugger, or an injected slugger. Host code of the core and the Symfony half of a bundle: omnibridge/symfony's Omnibridge\Symfony\Omnibase\FrameworkLocator (formerly Base\Bridge\Symfony\FrameworkLocator, step F5c; each accessor answers null without the bridge), the same services without the deprecation.

FrameworkAccessorsTrait::getService()

public static function getService(): ?BaseService

since omnisense/omnibase 4.0: the contracts the facade answered

FrameworkAccessorsTrait::getDoctrine()

public static function getDoctrine(): ?ManagerRegistry

since omnisense/omnibase 4.0: the unit of work, the repositories

FrameworkAccessorsTrait::getObjectManager()

public static function getObjectManager(mixed $entity): ?ObjectManager

since omnisense/omnibase 4.0: the unit of work

FrameworkAccessorsTrait::getEntityManager()

public static function getEntityManager(bool $reopen = false): ?EntityManagerInterface

since omnisense/omnibase 4.0: the unit of work

FrameworkAccessorsTrait::getRepository()

public static function getRepository(mixed $object = null): ?ObjectRepository

since omnisense/omnibase 4.0: the repository by its interface, or UnitOfWorks::repositories()

FrameworkAccessorsTrait::getClassMetadataManipulator()

public static function getClassMetadataManipulator(): ?ClassMetadataManipulator

since omnisense/omnibase 4.0: UnitOfWorks::shapes(), BaseTrait::isEntity()

FrameworkAccessorsTrait::getTokenStorage()

public static function getTokenStorage(): ?TokenStorageInterface

since omnisense/omnibase 4.0: Runtime::access()

FrameworkAccessorsTrait::getRequestStack()

public static function getRequestStack(): ?RequestStack

since omnisense/omnibase 4.0: Runtime::sessions(), Runtime::locales()

FrameworkAccessorsTrait::getFirewallMap()

public static function getFirewallMap(): ?FirewallMapInterface

since omnisense/omnibase 4.0: Runtime::routes()

FrameworkAccessorsTrait::getTwig()

public static function getTwig(): ?Environment

since omnisense/omnibase 4.0: Omnibridge\Contract\Views (Runtime::views())

FrameworkAccessorsTrait::getSlugger()

public static function getSlugger(): ?SluggerInterface

since omnisense/omnibase 4.0: symfony/string's AsciiSlugger, or an injected slugger

FrameworkAccessorsTrait::getRouter()

public static function getRouter(): ?AdvancedRouterInterface

since omnisense/omnibase 4.0: Base\Contract\Link::to(), Runtime::urls()

ProxyTrait trait

trait ProxyTrait ProxyTrait.php:8

ProxyTrait::hasProxy()

public function hasProxy(): bool

ProxyTrait::getProxy()

public function getProxy(): ?object

ProxyTrait::setProxy()

public function setProxy(object $proxy)

ProxyTrait::__call()

public function __call(string $methodOrProperty, array $arguments)
Throws

Exception

SimpleCacheTrait trait

trait SimpleCacheTrait SimpleCacheTrait.php:12

SimpleCacheTrait::__construct()

public function __construct(string $cacheDir, ?string $buildDir = null, ?CacheItemPoolInterface $pool = null)

The local cache is a PSR-6 pool (psr/cache, since 5.0: plan "omnibase agnostic", step F6): the one given, or symfony/cache's PHP array file over a filesystem pool in the cache folder where symfony/cache is installed (as before 5.0, every Symfony site), or one held in memory (Base\Cache\Pool\MemoryPool).

SimpleCacheTrait::hasCache()

public function hasCache(string $key): bool

SimpleCacheTrait::deleteCache()

public function deleteCache(?string $key = null): bool

SimpleCacheTrait::getCacheAdapter()

public function getCacheAdapter(): mixed

SimpleCacheTrait::invalidateCache()

public function invalidateCache(?string $key = null): self

SimpleCacheTrait::getCache()

public function getCache(?string $key = null, mixed $fallback = null, int|DateInterval|null $ttl = null, $deferred = false): mixed
Throws

InvalidArgumentException

SimpleCacheTrait::setCache()

public function setCache(CacheItemPoolInterface|string $cacheOrKey, mixed $value = null, int|DateInterval|null $ttl = null, bool $deferred = false)
Throws

Psr\Cache\InvalidArgumentException

SimpleCacheTrait::commitCache()

public function commitCache()

SimpleCacheTrait::executeOnce()

public function executeOnce(callable $fn, int|DateInterval|null $ttl = null): mixed

SingletonTrait trait

trait SingletonTrait SingletonTrait.php:8

SingletonTrait::hasInstance()

public static function hasInstance()

SingletonTrait::setInstance()

public static function setInstance($instance)

SingletonTrait::getInstance()

public static function getInstance(bool $instantiateIfNotFound = true): ?self

SingletonTrait::__clone()

public function __clone()

SingletonTrait::__sleep()

public function __sleep()

SingletonTrait::__wakeup()

public function __wakeup()

UserInfoTrait trait

trait UserInfoTrait UserInfoTrait.php:8

const __TIMEZONE_IDENTIFIER__ = "LOCATION/TIMEZONE"

The time zone, where the visitor answers for it apart (the LOCATION category of the page's script, assets/styles/js/user.js).

UserInfoTrait::getCookie()

public static function getCookie(?string $key = null)

What the page's script wrote of the visitor's browser: its language, calendar, light or dark theme (USER/INFO), its time zone (LOCATION/TIMEZONE, else USER/INFO's "timezone") and, read from that zone, its country. Nothing is written here: the cookies are the visitor's to accept or refuse, and the script's to write.

UserInfoTrait::setCookie()

public static function setCookie(string $key, $value, int $lifetime = 0)

UserInfoTrait::getAgent()

public static function getAgent(): ?string

UserInfoTrait::getIp()

public static function getIp(): ?string

UserInfoTrait::getCountryCode()

public function getCountryCode(): ?string

UserInfoTrait::getTimezone()

public function getTimezone(): string

UserInfoTrait::setTimezone()

public function setTimezone(?string $timezone = null): self

Base\Translation

ApplicationTexts class

final class ApplicationTexts ApplicationTexts.php:18

Which texts the application wrote itself (its own translations folder), for the level of politeness (base.translator.politeness, docs/20-architecture/politeness.md).

An application that rewrote a bundle's text under its key - a practice's "Aucun message." in place of a forum's "Tu n'as aucun message dans ta boîte" - wrote it as it speaks. When the bundle later brings a polite variant of its own text ("key._polite"), that variant must not come back in place of the application's: once the catalogues are merged nothing tells whose a text is, so the keys are read while the services are built and given to omnibase's translator (Base\Discovery's texts registry: omnibridge/symfony compiles it; plan "omnibase agnostic", step F5e slice 4c - until then omnibridge/symfony's ApplicationTextsPass::read()).

ApplicationTexts::read()

public static function read(string $directory): array

The keys of every catalogue of a directory: "<domain>[+intl-icu].<locale>.<yaml|yml|php|json>".

Returns

domain => locale => keys, flattened with dots

OverridingTranslator class

class OverridingTranslator implements TranslatorInterface, TranslatorBagInterface, LocaleAwareInterface, ResetInterface OverridingTranslator.php:27

The site's texts as the team rewrote them in the back office (Base\Entity\Layout\TextOverride, omnibase/admin's "Textes du site"): a rewritten key, in that language, wins over translations/. Between omnibase's translator (which resolves "@messages.key" and falls back between languages) and Symfony's: it sees a plain key and domain, and only answers when it has something.

The rewritten texts are read once per request from the cache - the shared Redis pool (cache.redis) when the application has one, so the web, the worker and cron agree; TextOverrideCacheListener empties it when one changes. Moved here from the apps' App\Translation\OverridingTranslator.

const CACHE_KEY = 'base.text_overrides'

OverridingTranslator::__construct()

public function __construct(protected readonly TranslatorInterface&TranslatorBagInterface&LocaleAwareInterface $inner, protected readonly \Closure $overrides, protected readonly CacheItemPoolInterface $cache)

OverridingTranslator::trans()

public function trans(?string $id, array $parameters = [], ?string $domain = null, ?string $locale = null): string

OverridingTranslator::isRewritten()

public function isRewritten(string $id, ?string $domain = null, ?string $locale = null): bool

Whether the team rewrote this key in that language. omnibase's translator asks it when a level of politeness is set (base.translator.politeness): a text rewritten at its base wins over a variant of the files, and a rewritten variant ("key._polite") is one.

OverridingTranslator::getCatalogue()

public function getCatalogue(?string $locale = null): MessageCatalogueInterface

OverridingTranslator::getCatalogues()

public function getCatalogues(): array

OverridingTranslator::setLocale()

public function setLocale(string $locale): void

OverridingTranslator::getLocale()

public function getLocale(): string

OverridingTranslator::getFallbackLocales()

public function getFallbackLocales(): array

The languages after the default one (framework.translator.fallbacks): asked by name - method_exists(), which __call does not answer - by the translator above (the profiler's) and through it by omnibase's Localizer.

OverridingTranslator::__call()

public function __call(string $method, array $arguments): mixed

What the inner translator offers beyond the interfaces.

OverridingTranslator::reset()

public function reset(): void

OverridingTranslator::invalidate()

public function invalidate(): void

Forget the rewritten texts: the next call reads them again.

TextOverrideCacheListener class

class TextOverrideCacheListener TextOverrideCacheListener.php:16

A rewritten text saved or deleted: the next page reads them all again.

Noted on the row's events, cleared once the flush is over (postFlush): cleared inside it, before the commit, a page read in between would put the old texts back in the cache.

TextOverrideCacheListener::__construct()

public function __construct(protected readonly \Closure $translator)
$translator

lazy: a Doctrine listener is built while Doctrine starts

TextOverrideCacheListener::postPersist()

public function postPersist(LifecycleEventArgs $args): void

TextOverrideCacheListener::postUpdate()

public function postUpdate(LifecycleEventArgs $args): void

TextOverrideCacheListener::postRemove()

public function postRemove(LifecycleEventArgs $args): void

TextOverrideCacheListener::postFlush()

public function postFlush(PostFlushEventArgs $args): void

Base\Twig

AppVariable class

class AppVariable AppVariable.php:21

public ReferrerInterface $referrer
public Environment $twig
public SettingBagInterface $settingBag
public ParameterBagInterface $parameterBag
public SiteVariable $site
public RandomVariable $random
public EmailVariable $email
public AdminVariable $admin
public LocalizerInterface $localizer
public ThemizerInterface $themizer

AppVariable::__construct()

public function __construct(SymfonyAppVariable $appVariable, RandomVariable $random, SiteVariable $site, EmailVariable $email, AdminVariable $admin, SettingBag $settingBag, ParameterBagInterface $parameterBag, ReferrerInterface $referrer, Environment $twig, LocalizerInterface $localizer, ThemizerInterface $themizer)

AppVariable::getGlobals()

public function getGlobals()
Throws

Exception

AppVariable::bag()

public function bag(?string $key = null, ?array $bag = null)

AppVariable::settings()

public function settings()
Throws

Exception

AppVariable::referrer()

public function referrer()

AppVariable::locale()

public function locale()

AppVariable::theme()

public function theme()

AssetPackage class

class AssetPackage implements PackageInterface AssetPackage.php:20

This defines a Symfony Asset named package that groups all the assets provided by EasyAdmin. This is needed because EasyAdmin uses asset versioning, so the full absolute URLs of assets isn't known (the URL contain changing hashes).

In practice this uses the same strategy (and even the same "manifest.json" file) used by Webpack Encore. We do this because we want to keep EasyAdmin dependencies as lean as possible, so we don't want to require Webpack Encore to use EasyAdmin.

const PACKAGE_NAME = 'base.assets.package'

AssetPackage::__construct()

public function __construct(RequestStack $requestStack)

AssetPackage::getBasePath()

public function getBasePath(): string

AssetPackage::stripPrefix()

public function stripPrefix(string $path): string

AssetPackage::getUrl()

public function getUrl(string $path): string

AssetPackage::getVersion()

public function getVersion(string $path): string

Environment class

class Environment extends TwigEnvironment implements AssetPaths Environment.php:23

omnibase's Twig environment: Twig's, with the page's globals as parameters, the tag renderers (TagRendererPass) and an asset's path as the page links it (Base\View\AssetPaths, through the HTML renderer).

Environment::__construct()

public function __construct(LoaderInterface $loader, array $options, RequestStack $requestStack, LocalizerInterface $localizer, AdvancedRouterInterface $router, ParameterBagInterface $parameterBag)

Environment::getParameter()

public function getParameter(string $name = '')

Environment::addGlobal()

public function addGlobal(string $name, $value): bool

Environment::hasParameter()

public function hasParameter(string $name)

Environment::setParameter()

public function setParameter(string $name, $value)

Environment::addParameter()

public function addParameter(string $name, $newValue)
Throws

Exception

Environment::appendParameter()

public function appendParameter($name, $value)
Throws

Exception

Environment::addRenderer()

public function addRenderer(TagRendererInterface $renderer)

Environment::getRenderer()

public function getRenderer(string $className): ?TagRendererInterface

Environment::getAsset()

public function getAsset(string $url): string

Environment::render()

public function render($name, array $context = []): string
Throws

LoaderError

Throws

RuntimeError

Throws

SyntaxError

Globals class

class Globals extends AbstractExtension implements GlobalsInterface Globals.php:11

Globals::__construct()

public function __construct(BaseService $base, AppVariable $app, RandomVariable $random)

Globals::getGlobals()

public function getGlobals(): array

Base\Twig\Extension

AccountTwigExtension class

final class AccountTwigExtension extends AbstractExtension AccountTwigExtension.php:18

account_profile(user): a member's profile as its view model (Base\Screen\Account\ProfilePage), as the visitor asking sees it - what a host page gives the core's profile template when it renders it with the user alone (lesringostars' /profile/of/{username}: @Base/client/user/profile_show.html.twig with {user}), so that the template reads its screen whoever renders it (plan "omnibase agnostique", C5). Answered by the AccountScreens runtime.

AccountTwigExtension::getFunctions()

public function getFunctions(): array

AnalyticsTwigExtension class

final class AnalyticsTwigExtension extends AbstractExtension AnalyticsTwigExtension.php:15

Thin Twig-side wrapper around Base\Service\Analytics - lets any template (the admin sidebar widget, a future public "N readers this week" badge, ...) reach the counters directly, without every consumer needing its own controller/Twig-global plumbing just to display a number.

AnalyticsTwigExtension::__construct()

public function __construct(readonly Analytics $analytics)

AnalyticsTwigExtension::getFunctions()

public function getFunctions(): array

AnalyticsTwigExtension::pageViews()

public function pageViews(?string $path = null, ?string $window = null, ?string $source = null): int

{{ analytics_page_views() }} - site-wide, all-time {{ analytics_page_views(window: '7d') }} - site-wide, last 7 days {{ analytics_page_views(app.request.pathInfo, 'today') }} - this page, today {{ analytics_page_views(window: '7d', source: 'ai') }} - AI crawler hits only, last 7 days

AnalyticsTwigExtension::uniqueVisitors()

public function uniqueVisitors(?string $window = null): int

{{ analytics_unique_visitors('30d') }}

AnalyticsTwigExtension::uniqueUsers()

public function uniqueUsers(?string $window = null): int

{{ analytics_unique_users('today') }}

AnalyticsTwigExtension::summary()

public function summary(): array

{% set stats = analytics_summary() %} {{ stats.today.pageViews }} / {{ stats['7d'].uniqueVisitors }} / .

..

AnalyticsTwigExtension::dailyBreakdown()

public function dailyBreakdown(?int $days = 14): array

{% set series = analytics_daily_breakdown(14) %} {% set series = analytics_daily_breakdown(null) %} - all time

AnalyticsTwigExtension::weekOverWeekChange()

public function weekOverWeekChange(): array

{% set change = analytics_week_over_week_change() %} {{ change.pageViews }}% vs last week

BreadgrinderTwigExtension class

final class BreadgrinderTwigExtension extends AbstractExtension BreadgrinderTwigExtension.php:11

BreadgrinderTwigExtension::__construct()

public function __construct(BreadgrinderInterface $breadgrinder)

BreadgrinderTwigExtension::getName()

public function getName()

BreadgrinderTwigExtension::getFunctions()

public function getFunctions(): array

BreadgrinderTwigExtension::renderBreadcrumb()

public function renderBreadcrumb(Environment $twig, string $name, Request $request, array $options = []): ?string

ClassTwigExtension class

final class ClassTwigExtension extends AbstractExtension ClassTwigExtension.php:12

ClassTwigExtension::getFunctions()

public function getFunctions(): array

ClassTwigExtension::getName()

public function getName()

ClassTwigExtension::getShortClass()

public function getShortClass($object)

ClipboardTwigExtension class

final class ClipboardTwigExtension extends AbstractExtension ClipboardTwigExtension.php:9

ClipboardTwigExtension::getName()

public function getName()

ClipboardTwigExtension::getFunctions()

public function getFunctions(): array

ClipboardTwigExtension::clipboard()

public function clipboard(Environment $twig, string $template, ?string $value, array $attributes = []): ?string

ClipboardTwigExtension::clipboard_target()

public function clipboard_target(Environment $twig, string $template, ?string $target, array $attributes = []): ?string

CommonsTwigExtension class

class CommonsTwigExtension extends AbstractExtension CommonsTwigExtension.php:26

The shared bricks, in a template (docs/40-commons):

embed_url(url) what a page can frame of an address (Base\Service\Embeds) qr_code(data, size) a QR code as an SVG data: URI (Base\Service\Qr\QrCode) opening_hours() Base\Service\OpeningHours; opening_hours(store), opening_hours('store:12'): one place's image|picture(w, h) a stored picture to its URL (an upload through the image resolver at that size, a URL or a public path as it is, anything else under public/assets/)

CommonsTwigExtension::__construct()

public function __construct(protected readonly Embeds $embeds, protected readonly QrCode $qr, protected readonly OpeningHours $hours, protected readonly ?Packages $packages = null, protected readonly ?MediaService $media = null, protected readonly string $publicDir = '')

CommonsTwigExtension::commons()

public function commons(): Commons

The neutral helper behind this extension (the screens' Pictures contract: Base\Bridge\Symfony\MediaPictures).

CommonsTwigExtension::getFunctions()

public function getFunctions(): array

CommonsTwigExtension::getFilters()

public function getFilters(): array

CommonsTwigExtension::picture()

public function picture(?string $image, ?int $width = null, ?int $height = null): ?string

A stored picture to its URL (Base\View\Commons; moved here from the apps' App\Twig\ImageExtension).

DemoTwigExtension class

class DemoTwigExtension extends AbstractExtension DemoTwigExtension.php:26

The demonstration in a template (docs/20-architecture/demo.md): {% if demo_mode() %}...{% endif %} the demo environment, and no other {% for account in demo_accounts() %} the declared accounts a visitor may sign in as @Base/demo/_banner.html.twig and @Base/demo/_accounts.html.twig are what a layout and a sign-in page include; both print nothing outside demo. The banner names the first of these accounts to a visitor who is not signed in. Framework-free: a host that runs no demonstration (Laravel: no demo kernel environment) gives the mode alone - never active, no account.

DemoTwigExtension::__construct()

public function __construct(readonly DemoMode $mode, readonly ?DemoAccountRegistry $registry = null, readonly ?DemoAccountFactory $factory = null)

DemoTwigExtension::getFunctions()

public function getFunctions(): array

DemoTwigExtension::accounts()

public function accounts(): array

The declared accounts a visitor may sign in as (Base\View\Demo).

DeployVersionExtension class

final class DeployVersionExtension extends AbstractExtension DeployVersionExtension.php:34

A value that changes on every real deploy and stays stable otherwise - meant to be fed into a client-side cache key (e.g.

@glitchr/transparent's Transparent.ready({cache_version: deploy_version()})) so a browser tab that cached a page before a deploy doesn't keep replaying it forever.

Reads the app's own git HEAD directly (no shell-out) rather than a Composer/env-var version string, since that's correct regardless of whether the app bumps any version number on release - this app's own deploy model resets the production directory to a specific commit via git fetch && git reset --hard, so HEAD always changes on a real deploy and never otherwise.

ALSO folds in vendor/{glitchr,omnisense,omnibase}/*'s own git HEADs, not just the app's - on this project, those aren't standard immutable Composer installs, they're live git checkouts iterated on directly (see e.g. the base-bundle-admin/base-bundle dev workflow), so a change committed there changes nothing about the APP's own HEAD at all. Without this, every vendor-level fix left every already-open admin tab replaying the pre-fix HTML/CSS/JS indefinitely - reported live, repeatedly, as "no handler" for a control that had genuinely already shipped. Missing/non-git vendor dirs (a normal production Composer install, source-archive not git checkout) just contribute nothing, same as the app dir falling back to 'dev' when it isn't a git checkout either.

DeployVersionExtension::__construct()

public function __construct(readonly string $projectDir)

DeployVersionExtension::getFunctions()

public function getFunctions(): array

DeployVersionExtension::getVersion()

public function getVersion(): string

EnumTwigExtension class

final class EnumTwigExtension extends AbstractExtension EnumTwigExtension.php:27

omnibase's enumerations in a template: enum() (an enumeration by its class or by the name of its DBAL type, "thread_state"), |colorify (the colours a ColorizeInterface gives, an enumeration's by value) and |trans_enum / |trans_enumExists (a value's words, EnumNouns over the Translations contract).

Framework-free (audit "lesringostars face au master plan", R24): Symfony registers it with omnibase's translator, Laravel (omnibridge/laravel) with its catalogues - the same answers from the same code. enum() and colorify were FunctionTwigExtension's, trans_enum TranslatorTwigExtension's, under the same names. A type named by its DBAL name is known once Doctrine has registered it: a host builds this extension after its entity manager.

EnumTwigExtension::__construct()

public function __construct(Translations $translations)

EnumTwigExtension::getFunctions()

public function getFunctions(): array

EnumTwigExtension::getFilters()

public function getFilters(): array

EnumTwigExtension::enum()

public function enum(null|string|array $class): mixed
Returns

an enumeration (an instance of it, as the type was until step F2a), another type, or each of a list (Base\View\Enums)

EnumTwigExtension::colorify()

public function colorify(null|string|array|ColorizeInterface $color, ?string $entry = null): null|string|array

EnumTwigExtension::transEnum()

public function transEnum(?string $value, string $class, null|string|array $options = TranslatorInterface::NOUN_SINGULAR): ?string

EnumTwigExtension::transEnumExists()

public function transEnumExists(string $value, string $class, string|array $options = TranslatorInterface::NOUN_SINGULAR): bool

FormTwigExtension class

final class FormTwigExtension extends AbstractExtension FormTwigExtension.php:11

FormTwigExtension::__construct()

public function __construct(FormProxyInterface $formProxy)

FormTwigExtension::getName()

public function getName()

FormTwigExtension::getFunctions()

public function getFunctions(): array

FormTwigExtension::advancedForm()

public function advancedForm(): bool

FormTwigExtension::getForm()

public function getForm(string $name): ?FormInterface

FormTwigExtension::getView()

public function getView(string $name): ?FormView

FunctionTwigExtension class

final class FunctionTwigExtension extends AbstractExtension FunctionTwigExtension.php:36

omnibase's Twig functions and filters. html_attributes, mb_ucfirst, second, join_if_exists, less_than, at and emoji_only are omnibridge/twig's HelperExtension's (registered beside this one, the same results); str_shorten, highlight and datetime stay here, they do more than its copies (str_shorten's SHORTEN_BACK_SHRINK/EXTEND, highlight's excerpt, datetime's patterns lists, intervals and formats), and win over them.

FunctionTwigExtension::__construct()

public function __construct(TranslatorInterface $translator, AssetExtension $assetExtension, Environment $twig, AdminUrlGeneratorInterface $adminUrlGenerator, string $projectDir, readonly ?AdminRouteRegistry $routeRegistry = null)

FunctionTwigExtension::getFunctions()

public function getFunctions(): array

FunctionTwigExtension::getFilters()

public function getFilters(): array

FunctionTwigExtension::crudify()

public function crudify(?object $entity, array $options = []): string

A link to the entity's edit page in the admin, or nothing when no CRUD manages it. Options: label, icon. The registered controller first (an app's CRUD may sit outside the namespace convention), then the convention.

Throws

LoaderError

Throws

RuntimeError

Throws

SyntaxError

FunctionTwigExtension::mailparseEmail()

public function mailparseEmail(string|EmailRecipientInterface $recipient): ?string

FunctionTwigExtension::mailparseName()

public function mailparseName(string|EmailRecipientInterface $recipient): ?string

FunctionTwigExtension::htmlify()

public function htmlify(?HtmlizeInterface $object, array $options = [], ...$args): ?string

FunctionTwigExtension::email()

public function email(array $context)

FunctionTwigExtension::is_linkable()

public function is_linkable(mixed $value): bool

FunctionTwigExtension::is_callable()

public function is_callable(mixed $value, bool $syntax_only = false, &$callable_name = null): bool

FunctionTwigExtension::nargs()

public function nargs(callable $fn): int

FunctionTwigExtension::call_user_func_with_defaults()

public function call_user_func_with_defaults(callable $fn, ...$args)

FunctionTwigExtension::call_user_func_if_exists()

public function call_user_func_if_exists(Environment $environment, string $fn, array $args)

FunctionTwigExtension::pad()

public function pad(array $array = [], int $length = 0, mixed $value = null): array

FunctionTwigExtension::transforms()

public function transforms(array $array = [], $arrow = null)

FunctionTwigExtension::static_property()

public function static_property($class, $propertyName)
Throws

Exception

FunctionTwigExtension::property_accessor()

public function property_accessor(mixed $object, array|string $propertyName, bool $enableMagicCall = false): mixed

FunctionTwigExtension::color_name()

public function color_name(string $hex)
Throws

Exception

FunctionTwigExtension::is_countable()

public function is_countable($object)

FunctionTwigExtension::get_class()

public function get_class($object, $method)

FunctionTwigExtension::method_exists()

public function method_exists($object, $method)

FunctionTwigExtension::preg_split()

public function preg_split(string $subject, string $pattern, int $limit = -1, int $flags = 0)

FunctionTwigExtension::instanceof()

public function instanceof(mixed $object, string $class): bool

FunctionTwigExtension::joinIfExists()

public function joinIfExists(?array $array, string $separator)

FunctionTwigExtension::static_call()

public function static_call($class, $method, ...$args)
Throws

Exception

FunctionTwigExtension::render_stylesheet()

public function render_stylesheet(string $href, array $attributes = [], bool $keepIfNotFound = true): string

FunctionTwigExtension::render_javascript()

public function render_javascript(string $src, array $attributes = [], bool $keepIfNotFound = true): string

FunctionTwigExtension::datetime()

public function datetime(Environment $env, \DateTime|\DateInterval|int|string|null $datetime, array|string $pattern = 'YYYY-MM-dd HH:mm:ss', ?string $dateFormat = 'medium', ?string $timeFormat = 'medium', $timezone = null, string $calendar = 'gregorian', ?string $locale = null): array|string

A moment as a pattern says it, lowered (Base\View\Dates, in Twig's time zone).

FunctionTwigExtension::isMoment()

public static function isMoment(string $value): bool

Whether a string is a moment in ISO 8601: a date, a time, and a zone or not (Base\View\Dates).

FunctionTwigExtension::pickup()

public function pickup(?array $array, int $i)

FunctionTwigExtension::countdown()

public function countdown(Environment $env, \DateTime|\DateInterval|int|string|null $datetime, array $parameters = []): string

FunctionTwigExtension::progress()

public function progress(Environment $env, \DateTime $start, \DateTime $end, array $parameters = []): string

FunctionTwigExtension::title()

public function title(string $name, array $parameters = [], ?string $domain = 'controllers', ?string $locale = null): string

FunctionTwigExtension::excerpt()

public function excerpt(string $name, array $parameters = [], ?string $domain = 'controllers', ?string $locale = null): string

FunctionTwigExtension::less_than()

public function less_than($date, $diff): bool
Throws

Exception

FunctionTwigExtension::greater_than()

public function greater_than($date, int $diff): bool
Throws

Exception

FunctionTwigExtension::truncate()

public function truncate($string, $maxLength = 30, $replacement = '', $truncAtSpace = false): string

FunctionTwigExtension::highlight()

public function highlight(?string $content, string|array $pattern, $gateLength = -1)
$gateLength

Number of words before and after

FunctionTwigExtension::stringify()

public function stringify($value): string

FunctionTwigExtension::mailto()

public function mailto(string $address, string $label)

HtmlTwigExtension class

final class HtmlTwigExtension extends AbstractExtension HtmlTwigExtension.php:12

HtmlTwigExtension::__construct()

public function __construct(HtmlTagRenderer $htmlTagRenderer, WysiwygEnhancerInterface $wysiwygEnhancer, EditorEnhancerInterface $editorEnhancer)

HtmlTwigExtension::wysiwyg()

public function wysiwyg(): Wysiwyg

The neutral pipeline behind |wysiwyg (the screens' Texts contract: Base\Bridge\Symfony\WysiwygTexts).

HtmlTwigExtension::renderWysiwyg()

public function renderWysiwyg(?string $htmlOrJson, array $options = [])

The pipeline of |wysiwyg (Base\View\Wysiwyg; TextsTwigExtension, through the Texts contract: Base\Bridge\Symfony\WysiwygTexts under Symfony).

HtmlTwigExtension::getTableOfContents()

public function getTableOfContents(?string $htmlOrJson, ?int $maxLevel = null): array

HtmlTwigExtension::getFunctions()

public function getFunctions(): array

HtmlTwigExtension::renderLinkTags()

public function renderLinkTags(): string

HtmlTwigExtension::renderScriptTags()

public function renderScriptTags(): string

HtmlTwigExtension::renderHeadTags()

public function renderHeadTags(): string

HtmlTwigExtension::renderNoscriptTags()

public function renderNoscriptTags(): string

HtmlTwigExtension::renderBodyTags()

public function renderBodyTags(): string

IconTwigExtension class

final class IconTwigExtension extends AbstractExtension IconTwigExtension.php:18

|iconify in a template: omnibase's Icons (an icon's name, a list, an enumeration's or a route's icons, as HTML).

Framework-free (audit "lesringostars face au master plan", R24): Symfony registers it with IconProvider's Icons, Laravel (omnibridge/laravel) with the same adapters and the Routes contract. It was MediaTwigExtension's, under the same name.

IconTwigExtension::__construct()

public function __construct(readonly Icons $icons)

IconTwigExtension::getFilters()

public function getFilters(): array

LinkTwigExtension class

final class LinkTwigExtension extends AbstractExtension LinkTwigExtension.php:20

Links in a template: |urlify (a link to an address or to a linkable record, its label the one given, else the address; marked "highlight" when it is the page's own) and |linkify (a linkable record's address).

Framework-free (audit "lesringostars face au master plan", R24): whether an address is the page's own is the host's answer, a closure - under Symfony omnibase's router (MediaTwigExtension::links()), under Laravel omnibridge/laravel's. They were MediaTwigExtension's, under the same names.

LinkTwigExtension::__construct()

public function __construct(readonly ?\Closure $current = null)

LinkTwigExtension::getFilters()

public function getFilters(): array

LinkTwigExtension::urlify()

public function urlify(LinkableInterface|string|null $urlOrPath, ?string $label = null, array $attributes = [])

LinkTwigExtension::linkify()

public function linkify(mixed $urlOrLinkableObject)

LocalBusinessTwigExtension class

class LocalBusinessTwigExtension extends AbstractExtension LocalBusinessTwigExtension.php:16

schema.org's LocalBusiness in a template (docs/40-commons/local-business.md):

{{ local_business_jsonld() }} the page's <script type="application/ld+json"> {{ local_business_jsonld({priceRange: '€€'}, store) }} properties of its own, one place's hours {% set business = local_business() %} the properties, to merge into a graph of the page's own

LocalBusinessTwigExtension::__construct()

public function __construct(protected readonly LocalBusiness $business)

LocalBusinessTwigExtension::getFunctions()

public function getFunctions(): array

LocalizerTwigExtension class

final class LocalizerTwigExtension extends AbstractExtension LocalizerTwigExtension.php:18

omnibase's locale filters and its timezone, country and currency menus, on its Localizer. The language menu, render_locale(), is MenuTwigExtension's (on the host's Locales contract, the same under Laravel).

LocalizerTwigExtension::__construct()

public function __construct(LocalizerInterface $localizer)

LocalizerTwigExtension::getName()

public function getName()

LocalizerTwigExtension::getFilters()

public function getFilters(): array

LocalizerTwigExtension::getFunctions()

public function getFunctions(): array

LocalizerTwigExtension::renderCountry()

public function renderCountry(Environment $twig, array $options = [], string $template = '@Base/localizer/country_dropdown.html.twig'): ?string

LocalizerTwigExtension::renderTimezone()

public function renderTimezone(Environment $twig, array $options = [], string $template = '@Base/localizer/timezone_dropdown.html.twig'): ?string

LocalizerTwigExtension::renderCurrency()

public function renderCurrency(Environment $twig, array $options = [], string $template = '@Base/localizer/currency_dropdown.html.twig'): ?string

MailTwigExtension class

final class MailTwigExtension extends AbstractExtension MailTwigExtension.php:27

What omnibase's e-mail templates ask of Twig beyond Twig's own extras (inky_to_html, inline_css): embed() - a picture of the site's public folder (or of a Twig path) as the e-mail being written embeds it, its cid: address through the template's email (Symfony's WrappedTemplatedEmail, or InlineImages where omnibase writes the e-mail itself: Base\Notifier\Mail\EmailComposer), else its public path -, |url (an address made whole) and |inline_css_email (the styles inlined in an e-mail). MediaTwigExtension gives them under Symfony (its embed() and inline_css_email() are these lines); this extension gives them to a host whose Twig has no MediaTwigExtension (omnibridge/laravel), for omnibase's e-mails. Its templates find the public folder as @Public.

MailTwigExtension::__construct()

public function __construct(readonly string $projectDir, readonly ?\Closure $url = null)
$url

an address whole: a route's name, a path or an address (AdvancedRouter::getUrl() under Symfony)

MailTwigExtension::getFunctions()

public function getFunctions(): array

MailTwigExtension::getFilters()

public function getFilters(): array

MailTwigExtension::embed()

public function embed(Environment $twig, array $context, string $src, array $options = []): string

MailTwigExtension::url()

public function url(?string $name, array $parameters = []): ?string

MailTwigExtension::inlineCss()

public static function inlineCss(array $context, string $body, string ...$css): string

The styles inlined into an e-mail's HTML (an e-mail being written: its email); a page's HTML as it is.

MailTwigExtension::source()

public static function source(Environment $twig, array $context, string $src, array $options, string $projectDir): string

MathTwigExtension class

final class MathTwigExtension extends AbstractExtension MathTwigExtension.php:8

MathTwigExtension::getFunctions()

public function getFunctions(): array

MathTwigExtension::sqrt()

public function sqrt($value): float

MathTwigExtension::count()

public function count(\Countable|array $value, int $mode = COUNT_NORMAL): int

MathTwigExtension::round()

public function round(int|float $num, int $precision = 0, int $mode = PHP_ROUND_HALF_UP): float

MediaTwigExtension class

final class MediaTwigExtension extends AbstractExtension MediaTwigExtension.php:18

MediaTwigExtension::__construct()

public function __construct(AdvancedRouterInterface $router, MediaService $mediaService, MediaController $mediaController, string $projectDir)

MediaTwigExtension::getFunctions()

public function getFunctions(): array

MediaTwigExtension::getTests()

public function getTests(): array

MediaTwigExtension::getFilters()

public function getFilters(): array

MediaTwigExtension::onDisk()

public function onDisk(string $file): bool
public function links(): LinkTwigExtension

The page's links (|urlify, |linkify): omnibase's router says whether an address is the page's own (the link is then "highlight").

MediaTwigExtension::url()

public function url(array $context, ?string $name, array $parameters = [], int $referenceType = AdvancedRouter::ABSOLUTE_URL)

MediaTwigExtension::inline_css_email()

public function inline_css_email(array $context, string $body, string ...$css): string

MediaTwigExtension::embed()

public function embed(Environment $twig, array $context, string $src, array $options = [])

MenuTwigExtension class

final class MenuTwigExtension extends AbstractExtension MenuTwigExtension.php:27

The visitor's menus of a page: its language, render_locale() (the host's Locales contract: the site's languages and the request's), and its theme, render_theme_modes(), render_theme_filters(), render_theme_widths() (omnibase's ThemizerInterface: the modes, filters and widths the site offers and the visitor chose) - each a template rendered with the choices, the visitor's marked.

Framework-free (plan "omnibase agnostique", step R9 of the audit "lesringostars face au master plan"): Symfony registers it with omnibase's Localizer (Base\Bridge\Symfony\LocalizerLocales) and Themizer, Laravel with omnibridge/laravel's AppLocales and Theme - the same menus from the same code. Formerly in LocalizerTwigExtension and ThemizerTwigExtension, under the same names and defaults.

MenuTwigExtension::__construct()

public function __construct(readonly Locales $locales, readonly ThemizerInterface $themizer)

MenuTwigExtension::getFunctions()

public function getFunctions(): array

MenuTwigExtension::renderLocale()

public function renderLocale(Environment $twig, array $options = [], string $template = '@Base/localizer/locale_dropdown.html.twig'): ?string

MenuTwigExtension::renderModes()

public function renderModes(Environment $twig, array $options = [], string $template = '@Base/themizer/dropdown.html.twig'): ?string

MenuTwigExtension::renderFilters()

public function renderFilters(Environment $twig, array $options = [], string $template = '@Base/themizer/filters/dropdown.html.twig'): ?string

MenuTwigExtension::renderWidths()

public function renderWidths(Environment $twig, array $options = [], string $template = '@Base/themizer/widths/dropdown.html.twig'): ?string

NotificationTwigExtension class

class NotificationTwigExtension extends AbstractExtension NotificationTwigExtension.php:28

What a toolbar needs to draw the bell: the unread count (the red dot), the latest entries (the dropdown), and the two things its script needs - the CSRF token every mutation carries and whether push can be offered at all.

All of it is for the CURRENT user; anonymous visitors get zeros so the templates need no guards of their own.

Framework-free (audit "lesringostars face au master plan", R24): the user signed in is the host's Access contract, the token its Tokens contract (Symfony's security and CSRF manager under Symfony, the guard and the session's token under Laravel); push is offered where WebPushService is configured (none given: never).

NotificationTwigExtension::__construct()

public function __construct(protected readonly Access $access, protected readonly Notifications $repository, protected readonly ?WebPushService $webPush, protected readonly Tokens $tokens, protected readonly ?NotificationLinkerInterface $linker = null)

NotificationTwigExtension::getFunctions()

public function getFunctions(): array

NotificationTwigExtension::unread()

public function unread(): int

NotificationTwigExtension::latest()

public function latest(int $limit = 8): array

NotificationTwigExtension::token()

public function token(): string

NotificationTwigExtension::pushKey()

public function pushKey(): string

NotificationTwigExtension::adminUrl()

public function adminUrl(Notification $notification): ?string

The back-office page of what a notification is about, or null.

NotificationTwigExtension::pushAvailable()

public function pushAvailable(): bool

OAuthTwigExtension class

final class OAuthTwigExtension extends AbstractExtension OAuthTwigExtension.php:16

oauth_available('google'): whether a "continue with ..." button can lead anywhere - the provider is declared in hwi_oauth.resource_owners of some firewall AND has a client id. A site that leaves the id empty (a sandbox, a provider not set up yet) keeps the declaration without showing a button that ends on the provider's error page.

OAuthTwigExtension::__construct()

public function __construct(readonly ?ResourceOwnerMapLocator $locator = null)

OAuthTwigExtension::getFunctions()

public function getFunctions(): array

OAuthTwigExtension::isAvailable()

public function isAvailable(string $name): bool

PaginatorTwigExtension class

final class PaginatorTwigExtension extends AbstractExtension PaginatorTwigExtension.php:12

PaginatorTwigExtension::__construct()

public function __construct(TranslatorInterface $translator)

PaginatorTwigExtension::getName()

public function getName()

PaginatorTwigExtension::getFunctions()

public function getFunctions(): array

PaginatorTwigExtension::getSlidingControl()

public function getSlidingControl(Environment $twig, PaginationInterface $pagination, string $name, array $parameters = []): ?string

The pagination's template, rendered with what Base\View\Pagination gives it.

PaginatorTwigExtension::getRewind()

public function getRewind(PaginationInterface $pagination, string $name, array $parameters = [], ?string $label = null): ?string

PaginatorTwigExtension::getFirst()

public function getFirst(PaginationInterface $pagination, string $name, array $parameters = [], ?string $label = null): ?string

PaginatorTwigExtension::getFirstSeparator()

public function getFirstSeparator(PaginationInterface $pagination, string $separator): ?string

PaginatorTwigExtension::getFirstOnes()

public function getFirstOnes(PaginationInterface $pagination, string $name, array $parameters = [], ?string $label = null): ?array

PaginatorTwigExtension::getPreviousOnes()

public function getPreviousOnes(PaginationInterface $pagination, string $name, array $parameters = [], ?string $label = null): ?array

PaginatorTwigExtension::getPrevious()

public function getPrevious(PaginationInterface $pagination, string $name, array $parameters = [], ?string $label = null): ?string

PaginatorTwigExtension::getCurrent()

public function getCurrent(PaginationInterface $pagination, ?string $label = null): ?string

PaginatorTwigExtension::getNext()

public function getNext(PaginationInterface $pagination, string $name, array $parameters = [], ?string $label = null): ?string

PaginatorTwigExtension::getNextOnes()

public function getNextOnes(PaginationInterface $pagination, string $name, array $parameters = [], ?string $label = null): ?array

PaginatorTwigExtension::getLast()

public function getLast(PaginationInterface $pagination, string $name, array $parameters = [], ?string $label = null): ?string

PaginatorTwigExtension::getLastOnes()

public function getLastOnes(PaginationInterface $pagination, string $name, array $parameters = [], ?string $label = null): ?array

PaginatorTwigExtension::getLastSeparator()

public function getLastSeparator(PaginationInterface $pagination, string $separator): ?string

PaginatorTwigExtension::getFastForward()

public function getFastForward(PaginationInterface $pagination, string $name, array $parameters = [], ?string $label = null): ?string

PictureTwigExtension class

final class PictureTwigExtension extends AbstractExtension PictureTwigExtension.php:33

What a template shows of a stored file through omnibase's media rule (MediaService, Base\Service\FileService): image() and |thumbnail (the image route's obfuscated address of a picture, at a size, in the format the browser takes), |crop, |soundify and |vidify (an audio or video player over the files' addresses), |imagify, imageset(), |mimetype, |extensions, |filesize, |public, |downloadable, |embed_base64, |obfuscate_image, |obfuscate_file, |lightbox.

Framework-free (audit "lesringostars face au master plan", R24): Symfony registers it with its MediaService and FileService services, Laravel (omnibridge/laravel, omnibridge.media on) with the MediaService it builds on its own router - the same addresses from the same code. They were MediaTwigExtension's, under the same names; what needs Symfony's router (url(), asset(), embed(), |inline_css_email...) stays there.

In an e-mail (a context's email being Symfony's WrappedTemplatedEmail) a picture is made at once and never as WebP, as before; a context's warmup is handed on.

PictureTwigExtension::__construct()

public function __construct(readonly MediaService $media, ?FileService $files = null)

PictureTwigExtension::getFunctions()

public function getFunctions(): array

PictureTwigExtension::getFilters()

public function getFilters(): array

PictureTwigExtension::image()

public function image(array $context, array|string|null $path, array $config = [], array $filters = []): array|string|null
$context

the template's

$path

a path, or several

PictureTwigExtension::imageCrop()

public function imageCrop(array $context, array|string|null $path, int $x = 0, int $y = 0, ?int $width = null, ?int $height = null, string $position = 'leftop', array $config = [], array $filters = []): array|string|null
$context

the template's

$path

a path, or several

PictureTwigExtension::thumbnailInset()

public function thumbnailInset(array $context, array|string|null $path, ?int $width = null, ?int $height = null, array $config = [], array $filters = []): array|string|null
$context

the template's

$path

a path, or several

PictureTwigExtension::thumbnailOutbound()

public function thumbnailOutbound(array $context, array|string|null $path, ?int $width = null, ?int $height = null, array $config = [], array $filters = []): array|string|null
$context

the template's

$path

a path, or several

PictureTwigExtension::thumbnailNoclone()

public function thumbnailNoclone(array $context, array|string|null $path, ?int $width = null, ?int $height = null, array $config = [], array $filters = []): array|string|null
$context

the template's

$path

a path, or several

PictureTwigExtension::thumbnailUpscale()

public function thumbnailUpscale(array $context, array|string|null $path, ?int $width = null, ?int $height = null, array $config = [], array $filters = []): array|string|null
$context

the template's

$path

a path, or several

PictureTwigExtension::thumbnail()

public function thumbnail(array $context, array|string|null $path, ?int $width = null, ?int $height = null, array $config = [], array $filters = []): array|string|null
$context

the template's

$path

a path, or several

SecurityPolicyTwigExtension class

class SecurityPolicyTwigExtension extends AbstractExtension implements GlobalsInterface SecurityPolicyTwigExtension.php:19

Exposes the administrator's account-security policy to every template as security_policy.

The account settings page receives the same object as a normal render parameter, but the login page and the layout do not have a controller of their own to pass it from - the login form is rendered by the security bundle - and both need to know whether passkeys are offered before they draw a button for them.

SecurityPolicyTwigExtension::__construct()

public function __construct(SecurityPolicy $securityPolicy)

SecurityPolicyTwigExtension::getGlobals()

public function getGlobals(): array

SemanticTwigExtension class

final class SemanticTwigExtension extends AbstractExtension SemanticTwigExtension.php:10

SemanticTwigExtension::__construct()

public function __construct(SemanticEnhancerInterface $semanticEnhancer)

SemanticTwigExtension::getName()

public function getName()

SemanticTwigExtension::getFilters()

public function getFilters(): array

SharingFilter class

final class SharingFilter extends AbstractExtension SharingFilter.php:10

SharingFilter::__construct()

public function __construct(Sharing $sharing)

SharingFilter::getName()

public function getName()

SharingFilter::getFilters()

public function getFilters(): array

SharingFilter::getFunctions()

public function getFunctions(): array

SharingFilter::generate()

public function generate(LinkableInterface $url, string $identifier, array $options = [], ?string $template = null): ?string

TextsTwigExtension class

final class TextsTwigExtension extends AbstractExtension TextsTwigExtension.php:21

A stored text in a template: |wysiwyg (an Editor.js document or the HTML of an older editor, rendered - mentions, links, media, headings anchored; printed with |raw) and |wysiwyg_toc (its headings), on the Texts contract.

Framework-free (audit "lesringostars face au master plan", R24): Symfony registers it with Base\Bridge\Symfony\WysiwygTexts (HtmlTwigExtension's own pipeline, the HTML of before), Laravel (omnibridge/laravel) with its WysiwygTexts on the page's environment - the same filters, under the same names (they were HtmlTwigExtension's).

TextsTwigExtension::__construct()

public function __construct(readonly Texts $texts)

TextsTwigExtension::getFilters()

public function getFilters(): array

TextsTwigExtension::render()

public function render(?string $htmlOrJson, array $options = []): string
$options

headings, semantics, media, row_attr, hydrate

TextsTwigExtension::toc()

public function toc(?string $htmlOrJson, ?int $maxLevel = null): array

ThemizerTwigExtension class

final class ThemizerTwigExtension extends AbstractExtension ThemizerTwigExtension.php:16

omnibase's theme filters on its Themizer. The theme menus, render_theme_modes(), _filters() and _widths(), are MenuTwigExtension's (framework-free, the same under Laravel).

ThemizerTwigExtension::__construct()

public function __construct(ThemizerInterface $themizer)

ThemizerTwigExtension::getName()

public function getName()

ThemizerTwigExtension::getFilters()

public function getFilters(): array

ThemizerTwigExtension::getFunctions()

public function getFunctions(): array

TradingTwigExtension class

final class TradingTwigExtension extends AbstractExtension TradingTwigExtension.php:11

TradingTwigExtension::__construct()

public function __construct(TradingInterface $tradingMarket)

TradingTwigExtension::getFilters()

public function getFilters(): array

TradingTwigExtension::getFunctions()

public function getFunctions(): array

TradingTwigExtension::formatCurrency()

public function formatCurrency($amount, string $currency, array $attrs = [], ?string $locale = null): string

An amount in the currency the visitor reads (Base\View\Money).

TradingTwigExtension::applyCurrencyRate()

public function applyCurrencyRate($amount, string $currency, array $attrs = [], ?string $locale = null): ?float

An amount converted to the currency the visitor reads, null without a rate (Base\View\Money).

TranslatorTwigExtension class

final class TranslatorTwigExtension extends AbstractExtension TranslatorTwigExtension.php:11

TranslatorTwigExtension::__construct()

public function __construct(LocalizerInterface $localizer)

TranslatorTwigExtension::getName()

public function getName()

TranslatorTwigExtension::getFilters()

public function getFilters(): array

WebpackTwigExtension class

final class WebpackTwigExtension extends AbstractExtension WebpackTwigExtension.php:9

WebpackTwigExtension::getFunctions()

public function getFunctions(): array

WidgetTwigExtension class

final class WidgetTwigExtension extends AbstractExtension WidgetTwigExtension.php:15

WidgetTwigExtension::__construct()

public function __construct(WidgetProviderInterface $widgetProvider)

WidgetTwigExtension::getName()

public function getName()

WidgetTwigExtension::getFunctions()

public function getFunctions(): array

WidgetTwigExtension::render_slot()

public function render_slot(Environment $twig, string $slot, array $options = [], ?string $template = null): string

The widget a slot holds, rendered with what Base\View\Widgets gives it; nothing for an empty slot.

Base\Twig\Loader

FilesystemLoader class

class FilesystemLoader extends FilesystemLoader FilesystemLoader.php:8

FilesystemLoader::__construct()

public function __construct(\Twig\Loader\FilesystemLoader $inner, ParameterBagInterface $parameterBag, string $projectDir)

FilesystemLoader::getSourceContext()

public function getSourceContext(string $name): \Twig\Source

ORDER OF RESOLUTION: 1. custom loader 2. default Symfony loader (and TwigComponent delegated loaders)

FilesystemLoader::exists()

public function exists(string $name): bool

FilesystemLoader::getCacheKey()

public function getCacheKey(string $name): string

FilesystemLoader::isFresh()

public function isFresh(string $name, int $time): bool

Base\Twig\Renderer

AbstractTagRenderer class

abstract class AbstractTagRenderer implements TagRendererInterface AbstractTagRenderer.php:10

AbstractTagRenderer::__construct()

public function __construct(Environment $twig, LocalizerInterface $localizer, SluggerInterface $slugger, ParameterBagInterface $parameterBag)

TagRendererInterface interface

interface TagRendererInterface TagRendererInterface.php:7

TagRendererInterface::render()

public function render(string $name, array $context = []): string

TagRendererInterface::renderFallback()

public function renderFallback(Response $response): Response

Base\Twig\Renderer\Adapter

HtmlTagRenderer class

class HtmlTagRenderer extends AbstractTagRenderer implements ResetInterface HtmlTagRenderer.php:22

Collects the HTML a page's templates add to its locations (html_entry_*), to print them where the layout asks. Reset between two requests (ResetInterface, kernel.reset): in a process that answers several - FrankenPHP's worker, a static export - one page's content (timeline.css...) was printed on every page after it.

HtmlTagRenderer::__construct()

public function __construct(Environment $twig, LocalizerInterface $localizer, SluggerInterface $slugger, ParameterBagInterface $parameterBag, RequestStack $requestStack, AdvancedRouterInterface $router)

HtmlTagRenderer::getAsset()

public function getAsset(string $url): string

HtmlTagRenderer::reset()

public function reset(): void

What the page's templates added, forgotten before the next request.

HtmlTagRenderer::renderHtmlContent()

public function renderHtmlContent(string $location)

HtmlTagRenderer::getHtmlContent()

public function getHtmlContent(string $location)

HtmlTagRenderer::removeHtmlContent()

public function removeHtmlContent(string $location)

HtmlTagRenderer::addHtmlContent()

public function addHtmlContent(string $location, $contentOrArrayOrFile, array $options = [])

HtmlTagRenderer::render()

public function render(string $name, array $context = []): string

HtmlTagRenderer::renderFallback()

public function renderFallback(Response $response): Response

WebpackTagRenderer class

class WebpackTagRenderer extends AbstractTagRenderer implements AbstractLocalCacheInterface WebpackTagRenderer.php:25

WebpackTagRenderer::__construct()

public function __construct(Environment $twig, LocalizerInterface $localizer, SluggerInterface $slugger, ParameterBagInterface $parameterBag, ?EntrypointLookupCollectionInterface $entrypointLookupCollection, Packages $packages, string $publicDir, string $cacheDir, ?string $buildDir = null)

WebpackTagRenderer::getCacheFile()

public function getCacheFile()

WebpackTagRenderer::warmUp()

public function warmUp(string $cacheDir, ?string $buildDir = null): array

WebpackTagRenderer::getMedia()

public function getMedia(string $filename): ?string

WebpackTagRenderer::getBreakpoints()

public function getBreakpoints()

WebpackTagRenderer::addBreakpoint()

public function addBreakpoint(string $name, string $media)

WebpackTagRenderer::removeBreakpoint()

public function removeBreakpoint(string $name)

WebpackTagRenderer::getAlternatives()

public function getAlternatives()

WebpackTagRenderer::addAlternative()

public function addAlternative(string $alternative)

WebpackTagRenderer::removeAlternative()

public function removeAlternative(string $alternative)

WebpackTagRenderer::getEntryLinkTags()

public function getEntryLinkTags(): array

WebpackTagRenderer::getEntryScriptTags()

public function getEntryScriptTags(): array

WebpackTagRenderer::getEntrypoints()

public function getEntrypoints(): array

WebpackTagRenderer::discoverEntrypoints()

public function discoverEntrypoints(?string $appJsonPath, array $breakpoints = []): bool

Reads the entries of the application's build (its entrypoints.json) and of the core's (public/bundles/base/entrypoints.json), the breakpoints and the alternatives (-async, -defer).

Returns

whether both builds were there with entries: a build being written (Encore's watcher empties its output first) is not complete, and what was read of it is never kept beyond the request (see WebpackCacheWarmer::doWarmUp())

WebpackTagRenderer::getEntry()

public function getEntry(string $entrypointName): ?EntrypointLookupInterface

WebpackTagRenderer::addEntrypoint()

public function addEntrypoint(string $value, string $entrypointJsonPath, ?CacheItemPoolInterface $cache = null, ?string $cacheKey = null, bool $strictMode = true)

WebpackTagRenderer::removeEntrypoint()

public function removeEntrypoint(string $value)

WebpackTagRenderer::hasEntry()

public function hasEntry(string $entryName, string $entrypointName = '_default'): bool

WebpackTagRenderer::addTag()

public function addTag(string $value, ?string $packageName = null, ?string $entrypointName = null, ?string $htmlAttributes = null)

WebpackTagRenderer::loadEntry()

public function loadEntry(array|string|null $value)

WebpackTagRenderer::markAsOptional()

public function markAsOptional(array|string|null $value, bool $isOptional = true)

WebpackTagRenderer::isOptional()

public function isOptional(string $value): bool

WebpackTagRenderer::addLinkTag()

public function addLinkTag(string $value, ?string $packageName = null, ?string $entrypointName = null, ?string $htmlAttributes = null)

WebpackTagRenderer::addScriptTag()

public function addScriptTag(string $value, ?string $packageName = null, ?string $entrypointName = null, ?string $htmlAttributes = null)

WebpackTagRenderer::removeTags()

public function removeTags(string $value)

WebpackTagRenderer::removeLinkTag()

public function removeLinkTag(string $entryName)

WebpackTagRenderer::removeScriptTag()

public function removeScriptTag(string $entryName)

WebpackTagRenderer::reset()

public function reset($entrypoints = null)

WebpackTagRenderer::renderOptionalCssSource()

public function renderOptionalCssSource(string $entryName, ?string $packageName = null, ?string $entrypointName = null, ?string $htmlAttributes = null): string

WebpackTagRenderer::renderCssSource()

public function renderCssSource(string|array $entryName, ?string $packageName = null, ?string $entrypointName = null, ?string $htmlAttributes = null): string

WebpackTagRenderer::renderOptionalLinkTags()

public function renderOptionalLinkTags(null|string|array $entryName = null, ?string $packageName = null, ?string $entrypointName = null, array $htmlAttributes = []): string

WebpackTagRenderer::renderLinkTags()

public function renderLinkTags(null|string|array $entryName = null, ?string $packageName = null, ?string $entrypointName = null, array $htmlAttributes = []): string

WebpackTagRenderer::renderOptionalScriptTags()

public function renderOptionalScriptTags(null|string|array $entryName = null, ?string $packageName = null, ?string $entrypointName = null, array $htmlAttributes = []): string

WebpackTagRenderer::scriptAttributes()

public static function scriptAttributes(string $file, array $defaults = []): array

How a script file is loaded: defer for a file named -defer, async for one named -async, the defaults (base.twig.script_attributes) for the others.

Unless the defaults say ordered: false, a file named -async is loaded defer too: deferred scripts run in the order of the page, async ones whenever they arrive. The core's base-async entry is what sets window.jQuery, and a site's entries read it as an external (addExternals({ jquery: 'jQuery' }), its own app-async included): left async, nothing made the core's run first, and the site's threw "jQuery is not defined" when its file came back sooner. The page renders base before the site's entries, so in order the global is always there.

WebpackTagRenderer::renderScriptTags()

public function renderScriptTags(null|string|array $entryName = null, ?string $packageName = null, ?string $entrypointName = null, array $htmlAttributes = []): string

WebpackTagRenderer::render()

public function render(string $name, ?array $context = [], ?string $packageName = null, ?string $entrypointName = null, array $htmlAttributes = []): string

WebpackTagRenderer::renderFallback()

public function renderFallback(Response $response): Response

Base\Twig\Variable

final class AdminLinks AdminLinks.php:18

app.admin where omnibase/admin's generator is not at hand (a host other than Symfony, whose back office stays the Symfony site's): crudify() is a record's back-office edit page, named by omnibase/admin's rule (AdminRouteNames::forEntity()), with the record's id - its address by the host's Urls contract, null when the host's Routes know no such route.

Framework-free (audit "lesringostars face au master plan", R24); under Symfony app.admin is AdminVariable, on omnibase/admin's own registry.

public function __construct(readonly Routes $routes, readonly Urls $urls)
public function crudify(mixed $entity): ?string

AdminVariable class

class AdminVariable extends SiteVariable AdminVariable.php:18

AdminVariable::__construct()

public function __construct(AdvancedRouterInterface $router, SitemapperInterface $sitemapper, TranslatorInterface $translator, LocalizerInterface $localizer, SettingBagInterface $settingBag, MaintenanceProviderInterface $maintenanceProvider, LauncherInterface $launcher, ?KernelInterface $kernel, AdminUrlGeneratorInterface $adminUrlGenerator)

AdminVariable::title()

public function title()

AdminVariable::slogan()

public function slogan()
public function logo()

AdminVariable::crudify()

public function crudify(mixed $entity)

EmailVariable class

class EmailVariable EmailVariable.php:14

The site as an e-mail names it: the e-mail's own title, slogan and logo set in the back office, else the site's. Read from the settings and the router themselves, where it asked BaseService (plan "omnibase agnostique", C9).

EmailVariable::__construct()

public function __construct(protected AdvancedRouterInterface $router, protected SettingBagInterface $settingBag, protected LauncherInterface $launcher)

EmailVariable::homepage()

public function homepage()

EmailVariable::title()

public function title(): ?string

EmailVariable::slogan()

public function slogan(): ?string
public function logo(): ?string

EmailVariable::address()

public function address(?string $locale = null): ?string

EmailVariable::age()

public function age(?string $locale = null): string

RandomVariable class

class RandomVariable RandomVariable.php:8

RandomVariable::uuidv4()

public function uuidv4()

RandomVariable::rand()

public function rand()

SiteVariable class

class SiteVariable SiteVariable.php:15

SiteVariable::__construct()

public function __construct(AdvancedRouterInterface $router, SitemapperInterface $sitemapper, TranslatorInterface $translator, LocalizerInterface $localizer, SettingBagInterface $settingBag, MaintenanceProviderInterface $maintenanceProvider, LauncherInterface $launcher, ?KernelInterface $kernel = null)

SiteVariable::index()

public function index()

SiteVariable::meta()

public function meta(array $meta = [], ?string $locale = null): array

SiteVariable::map()

public function map()

SiteVariable::route()

public function route()

SiteVariable::title()

public function title()

SiteVariable::slogan()

public function slogan()
public function logo()

SiteVariable::scheme()

public function scheme(?string $locale = null): ?string

SiteVariable::host()

public function host(?string $locale = null): ?string

SiteVariable::port()

public function port(?string $locale = null): ?string

SiteVariable::domain()

public function domain(?string $locale = null): ?string

SiteVariable::subdomain()

public function subdomain(?string $locale = null): ?string

SiteVariable::base_dir()

public function base_dir(?string $locale = null): string

SiteVariable::url()

public function url(?string $nameOrUrl = '', array $routeParameters = [], ?string $locale = null): string

SiteVariable::under_maintenance()

public function under_maintenance(): bool

SiteVariable::launchdate()

public function launchdate(?string $locale = null): \DateTime

SiteVariable::is_launchedd()

public function is_launchedd(?string $locale = null): bool

SiteVariable::age()

public function age(?string $locale = null): string

SiteVariable::is_newcomer()

public function is_newcomer(int $within = 0): bool

Whether the visitor has not been seen within the last $within seconds, remembered in the cookie USER/LAST_VISIT - which a visitor who refused the site's own cookies (USER) is not given: such a visitor is a newcomer at each page.

SiteVariable::execution_time()

public function execution_time()

Base\Validator

Constraint class

class Constraint extends Constraint Constraint.php:5

public string $message

Constraint::__construct()

public function __construct(?string $message = null, ?array $groups = null, mixed $payload = null)

ConstraintEntity class

abstract class ConstraintEntity extends Constraint ConstraintEntity.php:5

public array|string $fields
public mixed $entity = null

ConstraintEntity::__construct()

public function __construct(array|string $fields, mixed $entity = null, ?string $message = null, ?array $groups = null, mixed $payload = null)
$fields

Required: the field or combination of fields

$entity

Optional: entity class or name

ConstraintEntity::getRequiredOptions()

public function getRequiredOptions(): array

ConstraintEntity::getDefaultOption()

public function getDefaultOption(): ?string

ConstraintEntity::getTargets()

public function getTargets(): string|array

ConstraintEntityValidator class

abstract class ConstraintEntityValidator extends ConstraintValidator ConstraintEntityValidator.php:18

ConstraintEntityValidator::getOriginalEntity()

public function getOriginalEntity($entity)

ConstraintEntityValidator::getEntityChangeSet()

public function getEntityChangeSet($entity): ?array

ConstraintEntityValidator::getClassMetadata()

public function getClassMetadata($entityName): ClassMetadata

ConstraintEntityValidator::buildViolation()

public function buildViolation(Constraint $constraint, $value = null): ConstraintViolationBuilderInterface

ConstraintEntityValidator::validate()

public function validate($value, Constraint $constraint): void
Throws

Exception

ConstraintValidator class

abstract class ConstraintValidator extends ConstraintValidator ConstraintValidator.php:11

public string $constraintClass

ConstraintValidator::__construct()

public function __construct()

ConstraintValidator::setParameter()

public function setParameter(string $parameterName, ?string $parameterValue = null)

ConstraintValidator::getPropertyName()

public function getPropertyName()

ConstraintValidator::getConstraintType()

public function getConstraintType()

ConstraintValidator::buildViolation()

public function buildViolation(Constraint $constraint, $value = null): ConstraintViolationBuilderInterface

Base\Validator\Constraints

Alphanumeric class

class Alphanumeric extends Constraint Alphanumeric.php:8

public string $message = 'alphanumeric'

AlphanumericPlus class

class AlphanumericPlus extends Constraint AlphanumericPlus.php:7

public string $message = 'alphanumeric_plus'

AlphanumericPlusValidator class

class AlphanumericPlusValidator extends ConstraintValidator AlphanumericPlusValidator.php:10

AlphanumericPlusValidator::validate()

public function validate($value, Constraint $constraint): void

AlphanumericValidator class

class AlphanumericValidator extends ConstraintValidator AlphanumericValidator.php:10

AlphanumericValidator::validate()

public function validate($value, Constraint $constraint): void

File class

class File extends Constraint File.php:8

public string $messageMaxSize = 'file.max_size'
public string $messageMimeType = 'file.mime_type'
public array $mimeTypes = []
public int $maxSize

File::__construct()

public function __construct(int|string|null $max_size = null, array $mime_types = [], ?array $groups = null, mixed $payload = null)
$max_size

A size in bytes (an integer: FileType's ceiling), a human readable string ("2MB", "500KB", etc.), or null (PHP's upload limit)

$mime_types

Array of allowed MIME types

$groups

Validation groups

$payload

Metadata

File::getAllowedMimeTypes()

public function getAllowedMimeTypes(): array

File::getMaxSize()

public function getMaxSize(): int

FileValidator class

class FileValidator extends ConstraintValidator FileValidator.php:11

FileValidator::validate()

public function validate($value, Constraint $constraint): void

Hexcode class

class Hexcode extends Constraint Hexcode.php:7

public string $message = 'hexcode'

HexcodeValidator class

class HexcodeValidator extends ConstraintValidator HexcodeValidator.php:8

HexcodeValidator::validate()

public function validate(mixed $value, Constraint $constraint): void

NotBlank class

class NotBlank extends Constraint NotBlank.php:15

Constraint for the NotBlank validator.

public string $message = '@validators.not_blank'
public bool $allowNull = false
public $normalizer = null

NotBlank::getTargets()

public function getTargets(): string|array

NotBlank::__construct()

public function __construct(?string $message = null, ?bool $allowNull = null, ?callable $normalizer = null, ?array $groups = null, mixed $payload = null)

Symfony 7.4 compliant constructor

NotBlankValidator class

class NotBlankValidator extends ConstraintValidator NotBlankValidator.php:11

NotBlankValidator::validate()

public function validate($value, Constraint $constraint): void

{@inheritdoc}

Password class

class Password extends Constraint Password.php:11

const MIN_LENGTH_FALLBACK = 8
const MIN_STRENGTH_FALLBACK = 0
const MAX_STRENGTH_FALLBACK = 5
public string $messageMinStrength = 'password.min_strength'
public string $messageMinLength = 'password.min_length'
public string $messageUpperCase = 'password.requirements.uppercase'
public string $messageLowerCase = 'password.requirements.lowercase'
public string $messageLength = 'password.requirements.length'
public string $messageNumbers = 'password.requirements.numbers'
public string $messageSpecials = 'password.requirements.specials'

Password::getMinLength()

public function getMinLength(): int

Password::getMinStrength()

public function getMinStrength(): int

Password::getMaxStrength()

public function getMaxStrength(): int

Password::requiresUppercase()

public function requiresUppercase(): bool

Password::requiresLowercase()

public function requiresLowercase(): bool

Password::requiresNumbers()

public function requiresNumbers(): bool

Password::requiresSpecials()

public function requiresSpecials(): bool

Password::requiresLength()

public function requiresLength(): bool

Password::__construct()

public function __construct(bool $uppercase = true, bool $lowercase = true, bool $numbers = true, bool $specials = true, bool $length = true, int $min_strength = self::MIN_STRENGTH_FALLBACK, int $min_length = self::MIN_LENGTH_FALLBACK, ?array $groups = null, mixed $payload = null)

Symfony 7.4+ compliant constructor

PasswordValidator class

class PasswordValidator extends ConstraintValidator PasswordValidator.php:9

PasswordValidator::validate()

public function validate($value, Constraint $constraint): void

StringCaseEntity class

class StringCaseEntity extends ConstraintEntity StringCaseEntity.php:11

Constraint for the StringCase Entity validator.

public string $message = 'string_case'

StringCaseEntityValidator class

class StringCaseEntityValidator extends ConstraintEntityValidator StringCaseEntityValidator.php:10

StringCaseEntityValidator::validate()

public function validate($value, Constraint $constraint): void
Throws

Exception

Unique class

class Unique extends Constraint Unique.php:20

No other record of the class has the same values for these fields (plan "omnibase agnostic", step E1): Symfony's UniqueEntity (symfony/doctrine-bridge) without Doctrine, the lookup asked of the persistence's Repositories (Base\Database\Repository\Repositories, whichever backend answers the unit of work). The same arguments, message, code and violation as UniqueEntity, so an entity that named it says the same; the neutral form layer reads it as omnisense/omnibridge's Unique.

Kept from UniqueEntity: fields, message, entityClass, repositoryMethod (an Entities method taking the criteria, findBy by default, asked for two records at most), errorPath, ignoreNull (a bool, or the fields whose null is ignored), groups, payload. Not kept: em and service (Doctrine's manager and validator service: the unit of work is the host's), identifierFieldNames (a DTO validated as an entity; none of the core's).

const NOT_UNIQUE_ERROR = '23bd9dbf-6b9b-41cd-a99e-4844bcf3077f'
public string $message = 'This value is already used.'
public ?string $entityClass = null
public string $repositoryMethod = 'findBy'
public array|string $fields = []
public ?string $errorPath = null
public bool|string|array $ignoreNull = true

Unique::__construct()

public function __construct(array|string $fields, ?string $message = null, ?string $entityClass = null, ?string $repositoryMethod = null, ?string $errorPath = null, bool|string|array|null $ignoreNull = null, ?array $groups = null, mixed $payload = null)

Unique::getRequiredOptions()

public function getRequiredOptions(): array

Unique::getDefaultOption()

public function getDefaultOption(): ?string

Unique::getTargets()

public function getTargets(): string|array

UniqueEntity class

class UniqueEntity extends ConstraintEntity UniqueEntity.php:14

Constraint for UniqueEntity validation.

const NOT_UNIQUE_ERROR = '23bd9dbf-6b9b-41cd-a99e-4844bcf3077f'
public string $service = 'doctrine.orm.validator.unique'
public ?string $em = null
public ?string $entityClass = null
public string $repositoryMethod = 'findBy'
public string|array $fields = []
public ?string $errorPath = null
public bool $ignoreNull = true

UniqueEntity::__construct()

public function __construct(array|string $fields, ?string $message = null, ?string $service = null, ?string $em = null, ?string $entityClass = null, ?string $repositoryMethod = null, ?string $errorPath = null, ?bool $ignoreNull = null, ?array $groups = null, mixed $payload = null)

Symfony 7.4+ compliant constructor.

UniqueEntityValidator class

class UniqueEntityValidator extends ConstraintEntityValidator UniqueEntityValidator.php:21

UniqueEntityValidator::setUnitOfWork()

public function setUnitOfWork(?UnitOfWork $unitOfWork): void

UniqueEntityValidator::validate()

public function validate($value, Constraint $constraint): void
Throws

Exception

UniqueValidator class

class UniqueValidator extends ConstraintValidator UniqueValidator.php:23

Unique's check (plan "omnibase agnostic", step E1): UniqueEntityValidator's steps, the record looked up through the persistence's Repositories instead of Doctrine's registry. The fields are read from the record's properties (Doctrine's reflection fields read the same values), the lookup is repositoryMethod($criteria) - findBy asked for two at most -, and the violation is the one UniqueEntity built: at errorPath (the first field by default), its value formatted the same way, the code NOT_UNIQUE_ERROR, the records found as its cause.

UniqueValidator::__construct()

public function __construct(readonly ?UnitOfWork $unitOfWork = null, readonly ?Repositories $repositories = null)

UniqueValidator::validate()

public function validate(mixed $value, Constraint $constraint): void

Base\View

AssetPaths interface

interface AssetPaths AssetPaths.php:11

An asset's path as the page links it (plan "omnibase agnostic", step F4): an address as it is, a path under the request's base folder. Under Twig, omnibase's environment answers it (Base\Twig\Environment, through its HTML renderer); a form type that shows a thumbnail asks it without naming the view engine.

AssetPaths::getAsset()

public function getAsset(string $url): string

Bell class

final class Bell Bell.php:22

What a toolbar needs to draw the bell (plan "omnibase agnostic", step F4): the unread count (the red dot), the latest entries (the dropdown), the CSRF token every mutation carries, whether push can be offered and its public key, the back-office page of a notification. All of it for the user signed in (the host's Access contract); anonymous visitors get zeros, so a view needs no guard of its own. NotificationTwigExtension's notifications_*() and push_*() under Twig, the same code for Blade and a React page's props; push is offered where WebPushService is configured (none given: never).

Bell::__construct()

public function __construct(readonly Access $access, readonly Notifications $repository, readonly ?WebPushService $webPush, readonly Tokens $tokens, readonly ?NotificationLinkerInterface $linker = null)

Bell::unread()

public function unread(): int

Bell::latest()

public function latest(int $limit = 8): array

Bell::token()

public function token(): string

Bell::pushKey()

public function pushKey(): string

Bell::adminUrl()

public function adminUrl(Notification $notification): ?string

The back-office page of what a notification is about, or null.

Bell::pushAvailable()

public function pushAvailable(): bool

Captions class

final class Captions Captions.php:12

Words a page shows that its translations give (plan "omnibase agnostic", step F4): a controller's title and excerpt (title(), excerpt()) and a value as text (|stringify) - FunctionTwigExtension's under Twig, the same code for Blade and a React page's props.

Captions::__construct()

public function __construct(readonly TranslatorInterface $translator)

Captions::title()

public function title(string $name, array $parameters = [], ?string $domain = 'controllers', ?string $locale = null): string

"<name>.title" in a domain; "@<domain>.<name>.title" when it is not translated.

Captions::excerpt()

public function excerpt(string $name, array $parameters = [], ?string $domain = 'controllers', ?string $locale = null): string

"<name>.excerpt" in a domain; "@<domain>.<name>.excerpt" when it is not translated.

Captions::stringify()

public function stringify(mixed $value): string

Any value as text: a string as it is, a number, "true"/"false", "Array (n items)", an object as its string or as "<its entity's noun> #<id>" (its uuid, else a short hash of the object).

Commons class

final class Commons implements PicturesContract Commons.php:18

The shared bricks in a page (plan "omnibase agnostic", step F4; docs/40-commons): what a page can frame of an address (Embeds), a QR code as an SVG data: URI, the opening hours (of the site or of one place), and a stored picture to its URL - CommonsTwigExtension's embed_url(), qr_code(), opening_hours() and |picture under Twig, the same code for Blade and a React page's props. The Pictures contract of the screens (Base\Bridge\Symfony\MediaPictures) is its picture().

Commons::__construct()

public function __construct(readonly Embeds $embeds, readonly QrCode $qr, readonly OpeningHours $hours, readonly ?\Closure $asset = null, readonly ?MediaService $media = null, readonly string $publicDir = '')
$asset

an asset's address in the build (symfony/asset's packages under Symfony); "/<path>" without it

$publicDir

the application's public folder, where the uploads' paths start

Commons::embedUrl()

public function embedUrl(?string $url, bool $remote = true): ?array

Commons::qrCode()

public function qrCode(string $data, int $size = 600): string

Commons::openingHours()

public function openingHours(string|object|null $scope = null): OpeningHours

The site's opening hours, or one place's (an object, "store:12").

Commons::picture()

public function picture(?string $image, ?int $width = null, ?int $height = null): ?string

A stored picture to its URL: an upload through the image resolver at that size, a URL or a public path as it is, anything else under public/assets/.

Dates class

final class Dates Dates.php:13

A moment as a pattern says it (plan "omnibase agnostic", step F4): the logic of the |datetime filter, formatted by PHP's intl as Twig's format_datetime() formats it (twig/intl-extra), without Twig - FunctionTwigExtension calls it with Twig's time zone, Blade and a React page's props with the application's.

Dates::__construct()

public function __construct(readonly ?TranslatorInterface $translator = null, readonly \DateTimeZone|string|null $timezone = null)
$translator

the page's locale, when none is given

$timezone

the zone a moment is printed in, when none is given (PHP's default without it)

Dates::isMoment()

public static function isMoment(string $value): bool

Whether a string is a moment in ISO 8601: a date, a time, and a zone or not.

Dates::datetime()

public function datetime(\DateTimeInterface|\DateInterval|int|string|null $datetime, array|string $pattern = 'YYYY-MM-dd HH:mm:ss', ?string $dateFormat = 'medium', ?string $timeFormat = 'medium', \DateTimeZone|string|false|null $timezone = null, string $calendar = 'gregorian', ?string $locale = null, \DateTimeZone|string|null $default = null): array|string

A moment as a pattern says it, lowered. A string in ISO 8601 (a screen's moment, Base\Screen\Shape::moment(): 2026-04-10T18:05:00+00:00) is that moment, printed as the DateTime it came from was; any other string is given back lowered (a word: "présent"); nothing gives the pattern. Several patterns give a list.

$timezone

the zone, null for the default, false to keep UTC

$default

the default zone of this call (a view engine's), over the helper's

Dates::format()

public function format(int $timestamp, ?string $dateFormat, ?string $timeFormat, string $pattern, \DateTimeZone|string|false|null $timezone, ?string $calendar, string $locale, \DateTimeZone|string|null $default = null): string

A timestamp formatted as Twig's format_datetime() formats it: in the zone given (a name or a zone), else the default one; false keeps UTC.

Demo class

final class Demo Demo.php:17

The demonstration in a page (plan "omnibase agnostic", step F4; docs/20-architecture/demo.md): whether it runs (the demo environment, and no other) and the declared accounts a visitor may sign in as - DemoTwigExtension's demo_mode() and demo_accounts() under Twig, the same code for Blade and a React page's props. A host that runs no demonstration gives the mode alone - never active, no account.

Demo::__construct()

public function __construct(readonly DemoMode $mode, readonly ?DemoAccountRegistry $registry = null, readonly ?DemoAccountFactory $factory = null)

Demo::active()

public function active(): bool

Demo::accounts()

public function accounts(): array

The declared accounts that exist and may be signed in as - none outside demo, and never one that opens the back office (base.demo.admin_roles; the super-administrator's roles reach them).

DeployVersion class

final class DeployVersion DeployVersion.php:20

A value that changes on every real deploy and stays stable otherwise (plan "omnibase agnostic", step F4: DeployVersionExtension's deploy_version(), the same for Blade and a React page) - meant to be fed into a client-side cache key (@glitchr/transparent's Transparent.ready({cache_version: deploy_version()})) so a browser tab that cached a page before a deploy does not keep replaying it.

It reads the application's own git HEAD directly (no shell-out), which is right whether or not the application bumps a version on release: its deploy resets the production directory to a commit, so HEAD changes on a real deploy and never otherwise. It also folds in the git HEADs of vendor/{glitchr,omnisense,omnibase}/*, which are live checkouts iterated on in place on these projects: a fix committed there changes nothing of the application's HEAD, and open tabs kept replaying the HTML of before it. Missing or non-git folders (a normal Composer install) give nothing; with no HEAD at all, the version is "dev".

DeployVersion::__construct()

public function __construct(readonly string $projectDir)

DeployVersion::version()

public function version(): string

Enums class

final class Enums Enums.php:18

omnibase's enumerations in a page (plan "omnibase agnostic", step F4): an enumeration by its class or by its column type's name ("thread_state"), the colours a ColorizeInterface gives, a value's words (EnumNouns over the Translations contract) - EnumTwigExtension's enum(), |colorify and |trans_enum under Twig, the same code for Blade and a React page's props.

Enums::__construct()

public function __construct(Translations $translations)

Enums::enum()

public function enum(null|string|array $class): mixed

An enumeration (an instance of it), by its class or by the name of its type; for any other name, the persistence's type of that name where Doctrine is installed and knows it. Each of a list for a list.

Enums::colorify()

public function colorify(null|string|array|ColorizeInterface $color, ?string $entry = null): null|string|array

The colours of a ColorizeInterface (its entry when one is asked), of each of a list merged.

Enums::transEnum()

public function transEnum(?string $value, string $class, null|string|array $options = TranslatorInterface::NOUN_SINGULAR): ?string

Enums::transEnumExists()

public function transEnumExists(string $value, string $class, string|array $options = TranslatorInterface::NOUN_SINGULAR): bool

Formats class

final class Formats Formats.php:19

omnibase's formatting and value helpers, with no view engine (plan "omnibase agnostic", step F4): what the Twig functions and filters of FunctionTwigExtension and ClassTwigExtension compute - |highlight, mailto(), mailparse_email(), |pickup, |color_name, get_short_class()... -, the same code for Twig (the extensions call it), Blade (omnibridge/laravel) and a React page's props.

Pure: no service, no state. What needs a translator is Captions; dates are Dates.

Formats::mailto()

public static function mailto(string $address, string $label): string

A link to write to an address.

Formats::mailparseEmail()

public static function mailparseEmail(string|EmailRecipientInterface $recipient): ?string

The address of a recipient ("Name <address>", an address, a notifier's recipient).

Formats::mailparseName()

public static function mailparseName(string|EmailRecipientInterface $recipient): ?string

The name of a recipient ("Name <address>"), its address when it has none.

Formats::highlight()

public static function highlight(?string $content, string|array $pattern, int $gateLength = -1): ?string

The words of a text that match a pattern (or one of several) marked; with a gate, only the first match and that many words around it, "[..]" where the text goes on. Null when nothing matched within a gate.

Formats::truncate()

public static function truncate(mixed $string, mixed $maxLength = 30, mixed $replacement = '', bool $truncAtSpace = false): string

A string cut to a length, the replacement and ".." at its end; at a space if asked.

Formats::greaterThan()

public static function greaterThan(mixed $date, int $diff): bool

Whether more than that many seconds passed since a moment (a DateTime, a string, a timestamp).

Formats::pickup()

public static function pickup(?array $array, int $i): ?array

That many entries of a list taken at random, their keys kept.

Formats::colorName()

public static function colorName(string $hex): ?string

The nearest CSS colour name of a hexadecimal code.

Formats::pregSplit()

public static function pregSplit(string $subject, string $pattern, int $limit = -1, int $flags = 0): array|false

preg_split() with the subject first, as a filter reads it.

Formats::pad()

public static function pad(array $array = [], int $length = 0, mixed $value = null): array

Formats::transforms()

public static function transforms(array $array = [], mixed $arrow = null): mixed

A list given to a closure, as it is without one.

Formats::nargs()

public static function nargs(callable $fn): int

The number of parameters a callable takes.

Formats::isLinkable()

public static function isLinkable(mixed $value): bool

Formats::methodExists()

public static function methodExists(mixed $object, string $method): bool

Formats::instanceOf()

public static function instanceOf(mixed $object, string $class): bool

Formats::shortClass()

public static function shortClass(object $object): string

An object's class without its namespace, its first letter lowered ("blogPost").

Formats::staticCall()

public static function staticCall(string|object $class, string $method, mixed ...$args): mixed

A static method of a class (or of an object's class) called.

Throws

Exception when the class or the method does not exist

Formats::staticProperty()

public static function staticProperty(string|object $class, string $propertyName): mixed

A static property of a class (or of an object's class).

Throws

Exception when the class or the property does not exist

Formats::propertyAccessor()

public static function propertyAccessor(mixed $object, array|string $propertyName, bool $enableMagicCall = false): mixed

A value read along a property path ("author.name", or the path's parts), null where a step cannot be read.

final class Links Links.php:13

Links (plan "omnibase agnostic", step F4): a link to an address or to a linkable record (|urlify) and a linkable record's address (|linkify) - LinkTwigExtension's under Twig, the same code for Blade and a React page's props. Whether an address is the page's own is the host's answer, a closure (omnibase's router under Symfony, omnibridge/laravel's under Laravel).

public function __construct(readonly ?\Closure $current = null)
$current

whether an address is the page's own; none is without it

public function urlify(LinkableInterface|string|null $urlOrPath, ?string $label = null, array $attributes = []): string

A link, its label the one given, else the record's or the address; "highlight" when it is the page's own. Nothing without an address.

public function linkify(mixed $urlOrLinkableObject): ?string

A linkable record's address, an address as it is.

Throws

LogicException for an object that is not linkable

Menus class

final class Menus Menus.php:17

The visitor's menus of a page as data (plan "omnibase agnostic", step F4): the choices a menu offers and the one the visitor made - its language (the host's Locales contract), its theme's modes, filters and widths (omnibase's Themizer), its time zone and country (omnibase's Localizer). Twig renders them with omnibase's dropdown templates (render_locale(), render_theme_modes()..., MenuTwigExtension and LocalizerTwigExtension); Blade renders the same data, a React page takes it as props.

Menus::__construct()

public function __construct(readonly ?Locales $locales = null, readonly ?ThemizerInterface $themizer = null, readonly ?LocalizerInterface $localizer = null)

Menus::locale()

public function locale(): array

Menus::modes()

public function modes(): array

Menus::filters()

public function filters(): array

Menus::widths()

public function widths(): array

Menus::timezone()

public function timezone(): array

Menus::country()

public function country(): array

Money class

final class Money Money.php:13

An amount in the currency the visitor reads (plan "omnibase agnostic", step F4): the logic of the |format_currency and |apply_currency_rate filters, on the Trading service's rates, formatted by PHP's intl as Twig's format_currency() formats it (twig/intl-extra), without Twig - TradingTwigExtension calls it, Blade and a React page's props the same.

Money::__construct()

public function __construct(readonly TradingInterface $trading)

Money::formatCurrency()

public function formatCurrency(mixed $amount, string $currency, array $attrs = [], ?string $locale = null): string

An amount in minor units (cents: attribute scale, 100 by default) formatted in a currency; converted first to the currency the visitor reads when a rate is known (attribute use_rate, true by default). The other attributes are the number formatter's (fraction_digit...).

Money::applyCurrencyRate()

public function applyCurrencyRate(mixed $amount, string $currency): ?float

An amount converted to the currency the visitor reads; null when no rate is known.

Money::currency()

public static function currency(int|float $amount, string $currency, array $attrs = [], ?string $locale = null): string

An amount formatted in a currency, as twig/intl-extra's format_currency() formats it.

$attrs

the number formatter's attributes, by their names in Twig

Pagination class

final class Pagination Pagination.php:13

A pagination's controls (plan "omnibase agnostic", step F4): the links of the paginator_*() functions and what the sliding control's template is given (paginator()), the same for Twig (PaginatorTwigExtension calls it), Blade and a React page's props.

Pagination::__construct()

public function __construct(readonly TranslatorInterface $translator)

Pagination::slidingControl()

public function slidingControl(PaginationInterface $pagination, string $name, array $parameters = []): array

What the pagination's template (PaginationInterface::getTemplate()) is rendered with.

$parameters

the route's parameters

Pagination::rewind()

public function rewind(PaginationInterface $pagination, string $name, array $parameters = [], ?string $label = null): ?string

Pagination::first()

public function first(PaginationInterface $pagination, string $name, array $parameters = [], ?string $label = null): ?string

Pagination::firstSeparator()

public function firstSeparator(PaginationInterface $pagination, string $separator): ?string

Pagination::firstOnes()

public function firstOnes(PaginationInterface $pagination, string $name, array $parameters = [], ?string $label = null): array

Pagination::previousOnes()

public function previousOnes(PaginationInterface $pagination, string $name, array $parameters = [], ?string $label = null): array

Pagination::previous()

public function previous(PaginationInterface $pagination, string $name, array $parameters = [], ?string $label = null): ?string

Pagination::current()

public function current(PaginationInterface $pagination, ?string $label = null): ?string

Pagination::next()

public function next(PaginationInterface $pagination, string $name, array $parameters = [], ?string $label = null): ?string

Pagination::nextOnes()

public function nextOnes(PaginationInterface $pagination, string $name, array $parameters = [], ?string $label = null): array

Pagination::last()

public function last(PaginationInterface $pagination, string $name, array $parameters = [], ?string $label = null): ?string

Pagination::lastOnes()

public function lastOnes(PaginationInterface $pagination, string $name, array $parameters = [], ?string $label = null): array

Pagination::lastSeparator()

public function lastSeparator(PaginationInterface $pagination, string $separator): ?string

Pagination::fastForward()

public function fastForward(PaginationInterface $pagination, string $name, array $parameters = [], ?string $label = null): ?string

Pictures class

final class Pictures Pictures.php:14

What a page shows of a stored picture through omnibase's media rule (plan "omnibase agnostic", step F4): image(), |crop and the |thumbnail filters of PictureTwigExtension, which call it with the template's context; Blade and a React page's props give theirs. In an e-mail being written (a context's email being Symfony's WrappedTemplatedEmail) a picture is made at once and never as WebP; a context's warmup is handed on.

Pictures::__construct()

public function __construct(readonly MediaService $media)

Pictures::image()

public function image(array|string|null $path, array $config = [], array $filters = [], array $context = []): array|string|null
$path

a path, or several

$context

the view's (its email, its warmup)

Pictures::crop()

public function crop(array|string|null $path, int $x = 0, int $y = 0, ?int $width = null, ?int $height = null, string $position = 'leftop', array $config = [], array $filters = [], array $context = []): array|string|null

Pictures::thumbnail()

public function thumbnail(array|string|null $path, ?int $width = null, ?int $height = null, array $config = [], array $filters = [], array $context = []): array|string|null

A picture's thumbnail at a size; mode in the config (ImageInterface::THUMBNAIL_INSET, OUTBOUND, FLAG_NOCLONE, FLAG_UPSCALE) as the |thumbnail_* filters give it.

Pictures::config()

public static function config(array $context, array $config): array

The config of a picture in a view's context: its warmup handed on; in an e-mail, made at once and never as WebP.

ViewsAdapter class

final class ViewsAdapter ViewsAdapter.php:15

omnibridge's Views from what a constructor was given (plan "omnibase agnostic", step F5a): the core's services render through Views, and still accept Twig's environment, deprecated until 6.0, wrapped in omnibridge/twig's TwigViews. Naming Twig's class in a type loads nothing of Twig.

ViewsAdapter::of()

public static function of(Views|Environment $views): Views

ViewsAdapter::ofNullable()

public static function ofNullable(Views|Environment|null $views): ?Views

Widgets class

final class Widgets Widgets.php:13

A widget slot of a page as data (plan "omnibase agnostic", step F4): the template of the widget a slot holds and what it is rendered with (its row and widget classes, its label) - WidgetTwigExtension's render_slot() renders it under Twig; Blade renders the same, a React page takes it as props.

Widgets::__construct()

public function __construct(readonly WidgetProviderInterface $widgetProvider)

Widgets::slot()

public function slot(string $slot, array $options = [], ?string $template = null): ?array

The slot's widget, its template and its options; null for a slot unknown or empty.

Wysiwyg class

final class Wysiwyg Wysiwyg.php:16

A stored text rendered (plan "omnibase agnostic", step F4): an Editor.js document or the HTML of the older editor, its mentions and links enhanced, its semantics if asked, its media, its headings anchored - the pipeline of |wysiwyg and |wysiwyg_toc (HtmlTwigExtension::renderWysiwyg() under Twig, the Texts contract of the screens: Base\Bridge\Symfony\WysiwygTexts), the same code for Blade and a React page's props.

Wysiwyg::__construct()

public function __construct(readonly WysiwygEnhancerInterface $wysiwygEnhancer, readonly EditorEnhancerInterface $editorEnhancer, readonly ?string $storage = null)
$storage

the storage of the editor's media (base.twig.editor.storage); read from the parameters when none is given

Wysiwyg::render()

public function render(?string $htmlOrJson, array $options = []): mixed
$options

headings (a level, or true), semantics, media (its config, or false), row_attr, hydrate

Throws

RuntimeException for a text neither enhancer supports

Wysiwyg::toc()

public function toc(?string $htmlOrJson, ?int $maxLevel = null): array

The text's headings.