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é.
DemoControllerclassA deliberately flat, style-free tour of a few base-bundle features.
1 method
DiscoveryclassWhat 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
OptionsclassThe 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
ServicesclassThe 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
OverriddenResourceNameCollectionFactoryclassKeeps one API resource per class the application actually uses.
2 methods
AbstractAttributeclass60 methods
AttributeInterfaceinterface15 methods
AttributeReaderclass37 methods · 4 constants
HierarchifyTraittrait3 methods
DemoPasswordsclassThe 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
EnrolmentPromptclassWhen 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
NotifierSenderclassomniauth'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
Policyclassomnibase'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
PolicyLinkingclassomniauth'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
RegistrationclassA 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
UserAccountsclassomniauth's accounts: omnibase's users (the `user` table, and the application's own beside it - lesringostars' userProfile, joined).
7 methods · 5 constants
UserBackupCodesclassThe backup codes: user.backupCodes, a JSON list of password_hash()'s, as User::setBackupCodes() writes it.
2 methods
UserEmailCodesclassThe 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
UserIdentitiesclassomniauth'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
UserLinkTokensclassThe 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
UserPasskeysclassomniauth/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
UserPasswordsclassThe 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
UserStoreclassWhat 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
UserTotpSecretsclassThe 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
UserTrustedVersionclassThe trusted devices' version: user.trustedTokenVersion, the "vsn" claim of the trusted_device cookie scheb/2fa wrote and omniauth writes alike.
2 methods
AlreadySignedInclassThe 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
ClosingclassAn 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
DevicesclassThe 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
MemberSearchclassThe 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
OutcomeclassWhere 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
PasswordsclassA 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
ProfileAccessclassWhose 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
RescuePageclassThe 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
SecondFactorclassThe 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
SignInclassThe 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
SignOutPageclassThe 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
VerificationclassAn 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
WaitingPagesclassThe 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
GuardSignInclassBase\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
TrackConnectionsclassThe 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
UpdateAccountclassThe 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
WarnNewDeviceclassA 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
WelcomeBackclassA 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
AccessclassWho 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
AdminclassBACKEND (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
ComplaintclassWho 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
LaunchclassLAUNCH_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
MaintenanceclassMAINTENANCE_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
PageinterfaceThe 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
PermissionclassThe 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
RestrictionclassWhat 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
RestrictionDecisionclassRestriction'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
WelcomeclassThe 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
AbstractBaseStubclassThe 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
EntityStubclassThe stubs of App\Entity\ (see AbstractBaseStub).
EnumStubclassThe stubs of App\Enum\ (see AbstractBaseStub).
FormStubclassThe 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
NotifierStubclassThe stubs of App\Notifier\ (see AbstractBaseStub).
RepositoryStubclassThe 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.
EntityAccessorReflectionclassOne 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
EntityAccessorsExtensionclassThe 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
FinderMethodReflectionclassOne method of the finder language (FinderMethodsExtension): public, any arguments, mixed.
15 methods
FinderMethodsExtensionclassThe 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
AccountScreensclassThe 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
NotificationMessagesclassThe 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
PasskeyRecordsinterfaceBase\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.
PasskeyUsersinterfaceBase\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.
SecurityUserinterfaceBase\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.
SecurityUserLoaderinterfaceBase\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.
SecurityUserProviderinterfaceBase\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.
TwoFactorUserinterfaceBase\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.
SimpleCacheclass10 methods
SimpleCacheInterfaceinterface
AbstractLocalCacheclassAbstractLocalCacheInterfaceinterfaceA 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
AbstractLocalCacheWarmerInterfaceinterface1 method
MemoryItemclassAn 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
MemoryPoolclassA 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
CommandsinterfaceThe 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
ConsoleInterfaceinterface1 method
ReportclassWhat 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
AutocompleteEntitiesclassautocomplete: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
BaseMappingclassbase: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
BaseMappingInputclassbase:mapping's options (plan "omnibase agnostic", step F5e, slice 3).
1 method · 1 property
CacheClearclasscache: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
CacheClearInputclasscache:clear's options and what the host knows of itself (plan "omnibase agnostic", step F5e, slice 3).
2 methods · 8 properties
CacheClearSessionsclasscache: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
CacheClearSessionsInputclasscache:clear:sessions' input (plan "omnibase agnostic", step F5e, slice 3): where the host keeps its session files.
1 method · 2 properties
CacheClearsclassHow 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
DemoResetclassdemo: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
DemoResetInputclassdemo:reset's options and the base.demo.reset.* parameters (plan "omnibase agnostic", step F5e, slice 3).
1 method · 4 properties
EntitiesInputclassicon:entities' and autocomplete:entities' options (plan "omnibase agnostic", step F5e, slice 3).
1 method · 3 properties
EntitiesTaskclassA 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
EntityDiscriminatorclassentity:discriminator (plan "omnibase agnostic", step F5e, slice 3): a class that is no entity refused aloud.
1 method
EntityDiscriminatorInputclassentity:discriminator's argument (plan "omnibase agnostic", step F5e, slice 3).
1 method · 1 property
FoldersclassWhere 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
IconEntitiesclassicon: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
IconEnumsclassicon: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
IconEnumsInputclassicon:enums' options (plan "omnibase agnostic", step F5e, slice 3).
1 method · 2 properties
MailerTrapclassbase: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
MailerTrapInputclassbase:mailer:trap's arguments and options (plan "omnibase agnostic", step F5e, slice 3).
1 method · 4 properties
NotifierMailTestclassnotifier: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
NotifierMailTestInputclassnotifier:mail:test's options (plan "omnibase agnostic", step F5e, slice 3).
1 method · 1 property
NotifierOverviewclassapp: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
NotifierOverviewInputclassapp:notifier's options (plan "omnibase agnostic", step F5e, slice 3).
1 method · 1 property
ThreadPublishableclassthread: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
ThreadPublishableInputclassthread:publishable's options (plan "omnibase agnostic", step F5e, slice 3).
1 method · 1 property
TimeMachineSnapshotclasstimemachine: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
TimeMachineSnapshotBackupInputclasstimemachine:snapshot:backup's options (plan "omnibase agnostic", step F5e, slice 3).
1 method · 2 properties
TimeMachineSnapshotInputclasstimemachine:snapshot's arguments and options, and those of its backup and restore (plan "omnibase agnostic", step F5e, slice 3).
1 method · 4 properties
TimeMachineSnapshotRestoreInputclasstimemachine:snapshot:restore's options (plan "omnibase agnostic", step F5e, slice 3).
1 method · 1 property
TimeMachineStorageclasstimemachine:storage (plan "omnibase agnostic", step F5e, slice 3): the storages a snapshot can be written to.
2 methods
TranslationControllersclasstranslation: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
TranslationControllersInputclasstranslation:controllers' options (plan "omnibase agnostic", step F5e, slice 3).
1 method · 4 properties
TranslationCrudclasstranslation: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
TranslationCrudInputclasstranslation:crud's options (plan "omnibase agnostic", step F5e, slice 3).
1 method · 5 properties
TranslationEntitiesclasstranslation: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
TranslationEntitiesInputclasstranslation:entities' options (plan "omnibase agnostic", step F5e, slice 3).
1 method · 4 properties
TranslationEnumsclasstranslation: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
TranslationEnumsInputclasstranslation:enums' options (plan "omnibase agnostic", step F5e, slice 3).
1 method · 4 properties
TranslationSettingsclasstranslation: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
TranslationSettingsInputclasstranslation:settings' options (plan "omnibase agnostic", step F5e, slice 3).
1 method · 3 properties
TranslationTaskclassWhat 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
TrashPurgeclasstrash: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
TrashPurgeInputclasstrash:purge's options (plan "omnibase agnostic", step F5e, slice 3).
1 method · 2 properties
UploaderEntitiesclassuploader: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
UploaderEntitiesInputclassuploader:entities' options (plan "omnibase agnostic", step F5e, slice 3).
2 methods · 6 properties
UploaderImagesclassuploader: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
UploaderImagesCropclassuploader: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
UploaderImagesCropInputclassuploader:images:crop's options (plan "omnibase agnostic", step F5e, slice 3).
1 method · 2 properties
UploaderImagesInputclassuploader:images' options (plan "omnibase agnostic", step F5e, slice 3).
1 method · 3 properties
UserCreateclassuser: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
UserCreateInputclassuser:create's arguments and options (plan "omnibase agnostic", step F5e, slice 3).
1 method · 6 properties
UserNotificationclassuser: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
UserNotificationInputclassuser:notifications' options (plan "omnibase agnostic", step F5e, slice 3).
1 method · 5 properties
FrameworkclassWhether 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
LinkclassA 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
MediainterfaceThe 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
MediaRouterinterfaceThe 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
NounsinterfaceWhat 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
PicturesinterfaceAn 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
RuntimeclassThe 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
TextsinterfaceA 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
TicketsinterfaceShort-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
SignatureControllerclassA 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
DeleteclassThe 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
LatestclassThe 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
ReadclassThe 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
EmailCodeToggleclassThe 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
EnrolmentclassThe 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
EnrolmentSkipclassThe 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
NoticeclassHow 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
PageclassA 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
Eventsclass4 constants
FormerNamesclassThe 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
UnitOfWorksclassomnisense/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
Aliasclass8 methods · 3 properties
Associateclass7 methods · 1 property
BlameableclassClass Blameable package Base\AttributeReader\Abstract\Blameable
6 methods
CacheclassCaching to an entity or a collection.
7 methods · 3 properties · 15 constants
Cascadeclass3 methods
Countifyclass7 methods · 5 constants
DiscriminatorEntryclass4 methods
GenerateUuidclassClass GenerateUuid package Base\Database\Attribute\GenerateUuid
5 methods · 10 constants
HashifyclassClass Hashify package Base\Database\Attribute\Hashify
10 methods · 14 properties
HierarchifyclassClass Hierarchify package Base\Database\Attribute\Hierarchify.
5 methods · 2 properties
OrderColumnclass5 methods · 2 properties · 2 constants
OrphanRemovalclass3 methods
RandomizeclassClass Randomize package Base\Database\Attribute\Randomize
3 methods
SlugifyclassClass Slugify package Base\Database\Attribute\Slugify
7 methods
TimestampclassClass Timestamp package Base\Database\Attribute\Timestamp
8 methods
TimezoneclassClass Timezone package Base\Database\Attribute\Timezone
6 methods · 1 constant
TrasheableclassMarks 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
UploaderclassClass Uploader package Base\Database\Attribute\Uploader
25 methods · 1 constant
Vaultclass16 methods · 3 properties
VersionableclassMarks 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
BackendsclassThe persistence's part of each behaviour, by unit of work (plan "omnibase agnostic", step F2b).
3 methods
CacheBackendinterface#[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
OrderColumnBackendinterface#[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
SlugifyBackendinterface#[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
VaultBackendinterface#[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
ExtensionHookInterfaceinterface1 method
ExtensionInlineInterfaceinterfaceExtensionMetadataInterfaceinterface3 methods
ExtensionOptionInterfaceinterface2 methods
BulkDeletesinterfaceRows 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
ColumnTypesinterfaceWhat 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
ConditionalUpdatesinterfaceOne 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
EntityCacheinterfaceThe 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
RowLocksinterfaceAn 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
OrderedArrayCollectionclass29 methods
EntityExtensionclass2 methods · 6 constants
EntityExtensionInterfaceinterfaceEntityHydratorclassAn 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
EntityHydratorInterfaceinterface3 methods
EntityValuesclassAn 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
PopulableInterfaceinterface1 method
SerializableInterfaceinterface2 methods
Base\Database\Entity\Extension
AliasInterfaceinterface4 methods
AliasTraittrait4 methods
TranslatableAliasTraittrait4 methods
TranslatableInterfaceinterfaceEach implementation has, by TranslatableTrait, the class of its translations: the schema (Base\Database\Schema\TranslationRule) asks it of the class itself.
5 methods
TranslatableTraittrait12 methods
TranslationInterfaceinterfaceEach implementation has, by TranslationTrait, the class it translates: the schema (Base\Database\Schema\TranslationRule) asks it of the class itself.
5 methods
TranslationTraittrait8 methods
TrasheableInterfaceinterfaceTrasheableTraittrait4 methods
VaultInterfaceinterfaceVaultTraittrait8 methods
Base\Database\Entity\Extension\Type
EntityHookInterfaceinterfaceEntityInlineInterfaceinterface1 method
EntityMetadataInterfaceinterfaceEntityOptionInterfaceinterface1 method
RevisionRecorderclassWhat 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
SettingsInvalidationclassThe 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
ThreadParticipantsclassWho 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
TrashRecorderclassWhat 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
CompletorclassWhat 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
CompletorsclassEach 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
DescriptionShapesclassThe 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
EntityFieldsclassAn 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
EntityShapeclassWhat 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
EntityShapesinterfaceThe entities' shapes (plan "omnibase agnostic", step F2c): from a Description (DescriptionShapes), or from the installed persistence (Base\Bridge\Doctrine\DoctrineShapes on Doctrine).
2 methods
MetadataManipulatorclassWhat 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
BackendOnlyclassA 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
EntitiesinterfaceThe 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
RepositoriesinterfaceThe 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
UnsupportedQueryExceptionclassA 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
CriterionclassOne 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
GroupclassA 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
KeyclassA 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
ParserclassThe 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
QueryclassA 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
SubjectinterfaceWhat 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
DiscriminatorRuleclassomnibase'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
EntitySchemaclassThe 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
ExtensionRuleclassThe 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
OrderColumnRuleclass#[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
TargetRuleclassThe 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
TranslationRuleclassThe translations' mapping, as Base\DatabaseSubscriber\IntlSubscriber gives it to Doctrine, on the description built without it:
3 methods · 4 constants
VaultRuleclass#[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
TrashScopeclassThe 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
VaultScopeclassThe 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
EnumTypeclassAn 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
Enumerationsclassomnibase'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
SetTypeclassAn 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
UtcclassMoments 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
DemoAccountclassA 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
DemoAccountFactoryclassThe 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
DemoAccountLockclassA 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
DemoAccountProviderInterfaceinterfaceDeclares 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
DemoAccountRegistryclassEvery 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
DemoGuardclassWhat the `demo` environment refuses to start on (BaseBundle::boot() asks, for a page as for a command):
3 methods
DemoModeclassWhether 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
DemoSignInclassSigning 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
Threadclass71 methods
ThreadIntlclass10 methods
Userclass156 methods · 1 property · 3 constants
AbstractEventclassNB: Flushing object manager from within listener should be avoided, this is done already in event dispatcher if needed.
9 methods
AbstractEventDispatcherclassAn 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
EventDispatcherInterfaceinterfaceAn 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
EventInterfaceinterface3 methods
ThreadEventclass1 method · 3 constants
ThreadEventDispatcherclass3 methods
UserEventclassThe 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
UserEventDispatcherclass3 methods
ConnectionSubscriberclass6 methods
ThreadSubscriberclassThe 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
UserSubscriberclassWhat 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
PageViewclassOne 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
PageVisitclassAn 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
VisitclassAn 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\Abstract
AbstractExtensionclass16 methods
AbstractExtensionInterfaceinterface
ScopedWeekclassThe 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
SpecialDayclassA 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
WeekDayHoursclassThe 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
Attributeclass5 methods
AttributeIntlclass6 methods
Imageclass23 methods
ImageCropclass40 methods
ImageCropInterfaceinterface16 methods
ImageInterfaceinterface5 methods
RedirectionclassAn 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
Semanticclass15 methods
SemanticIntlclass4 methods
Settingclass14 methods
SettingIntlclass11 methods
ShortLinkclass8 methods
ShortLinkIntlclass4 methods
TextOverrideclassA 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
Tooltipclass14 methods
TooltipIntlclass4 methods
Widgetclass17 methods
WidgetIntlclass8 methods
Hyperlinkclass11 methods
HyperlinkIntlclass3 methods
Base\Entity\Layout\Attribute\Adapter
ArrayAdapterclass7 methods
ColorAdapterclass5 methods
CountryAdapterclass4 methods
DateRangeAdapterclass"Are we inside this window?" - the coupon predicate.
6 methods
DateTimeAdapterclass4 methods
HyperpatternAdapterclass9 methods
HyperpatternAdapterIntlclass2 methods
ImageAdapterclass4 methods
MoneyAdapterclass9 methods
NumberAdapterclass9 methods
PercentAdapterclass9 methods
ScalarAdapterclass11 methods
ScoreAdapterclass"Is this account's score <operation> this number?"
8 methods
TextAdapterclass6 methods
TextareaAdapterclass4 methods
Base\Entity\Layout\Attribute\Adapter\Common
AbstractActionAdapterclass2 methods
AbstractAdapterclass14 methods
AbstractAdapterIntlclass4 methods
AbstractRuleAdapterclass2 methods
AbstractScopeAdapterclass2 methods
ActionAdapterInterfaceinterface1 method
AttributeAdapterInterfaceinterface3 methods
RuleAdapterInterfaceinterface2 methods
ScopeAdapterInterfaceinterface2 methods
Base\Entity\Layout\Attribute\Common
AbstractActionclass6 methods
AbstractAttributeclass10 methods
AbstractRuleclass6 methods
AbstractScopeclass6 methods
ActionInterfaceinterface1 method
AttributeInterfaceinterface8 methods
RuleInterfaceinterface1 method
ScopeInterfaceinterface1 method
AbstractEnvelopeclassWhat 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
CommentclassWhat 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
Likeclass10 methods
Mentionclass11 methods
Tagclass17 methods
TagIntlclass6 methods
Taxonclass23 methods
TaxonIntlclass6 methods
Addressclass28 methods
ComplaintclassA user's complaint about another one (or about something), for the staff to answer.
35 methods · 4 constants
Connectionclass35 methods
GroupclassOpen 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
IdentityclassAn 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
InvitationclassAn 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
NotificationclassA 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
PasskeyclassA 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
PenaltyclassA penalty an administrator has defined, NOT one somebody has received.
21 methods
Permissionclass19 methods
PushSubscriptionclassOne 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
SanctionclassOne penalty, given to one user, once.
19 methods
Tokenclass38 methods · 3 constants
GroupActionclassWhat a group DOES for somebody who qualifies for it.
5 methods
GroupRuleclassA condition a user must satisfy for a group to be open to them.
5 methods
GroupScopeclassWho a group's rules are about in the first place.
5 methods
Base\Entity\User\Attribute\Action
GrantPermissionAdapterclassAwards one or more fine-grained permission tags.
5 methods
GrantRoleAdapterclassAwards one or more roles to whoever qualified.
5 methods
Base\Entity\User\Attribute\Scope
GroupAdapterclassNarrows something to the members of another group.
6 methods
UserAdapterclassNarrows something to named people.
6 methods
AllergenenumThe 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
CommentStateenumWhere 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
ConnectionStateclass2 methods · 4 constants
EntityActionclass2 methods · 3 constants
LogLevelclass2 methods · 4 constants
Operationclass2 methods · 6 constants
SpamApiclass2 methods · 1 constant
SpamScoreclass3 methods · 4 constants
ThreadStateclass4 methods · 7 constants
UploadStateclass2 methods · 3 constants
UserGenderclass2 methods · 4 constants
UserRoleclass3 methods · 4 constants
UserStateclass2 methods · 8 constants
WorkflowStateclass2 methods · 6 constants
Quadrantclass8 methods · 5 constants
Quadrant16class7 methods · 8 constants
Quadrant32class7 methods · 16 constants
Quadrant8class7 methods · 4 constants
BritishImperialUnitsclass2 methods
StandardBaseUnitsclass16 methods · 7 constants
StandardUnitsclass2 methods
UnitedStatesCustomaryUnitsclass2 methods
SignatureEventclassAn 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
SitemapEventclassDispatched while /sitemap.xml is being built, once the routes carrying a Sitemap attribute have been registered.
3 methods · 1 constant
DemoRefusedExceptionclassThe `demo` environment refuses to start, or `demo:reset` to run (Base\Demo\DemoGuard).
InvalidMimeTypeExceptionclass1 method
InvalidPageExceptionclass1 method
InvalidSizeExceptionclass1 method
InvalidUuidExceptionclass1 method
MissingDiscriminatorMapExceptionclass1 method
MissingDiscriminatorValueExceptionclass1 method
MissingLocaleExceptionclass1 method
MissingPublicPathExceptionclass1 method
NotDeletableExceptionclass1 method
NotFoundResourceExceptionclass1 method
NotReadableExceptionclass1 method
NotWritableExceptionclass1 method
OwnerSideExceptionclass1 method
SitemapNotFoundExceptionclass1 method
TranslationAmbiguityExceptionclass1 method
UnsupportedBehaviourExceptionclassA 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).
1 method
UploaderAmbiguityExceptionclass1 method
VaultKeyNotFoundExceptionclassA 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.
1 method · 2 properties
ArrayFieldclass11 methods · 4 constants
AssociationFieldclass25 methods · 18 constants
AssociationFileFieldclass19 methods · 15 constants
AttributeFieldclass17 methods · 14 constants
AudioFieldclass1 method · 1 constant
AvatarFieldclass1 method · 1 constant
BooleanFieldclass4 methods · 4 constants
CodeFieldclassA code of known length, one box per character (Base\Field\Type\CodeType).
4 methods
CollectionFieldclass12 methods · 9 constants
ColorFieldclass1 method
ColorPickerFieldclass1 method
CountryFieldclass1 method
CropperFieldclass1 method · 2 constants
CurrencyFieldclass1 method
DateFieldclass1 method
DateTimeFieldclass1 method
DateTimePickerFieldclass9 methods · 16 constants
DiscriminatorFieldclass4 methods · 4 constants
EditorFieldclass1 method
EmailFieldclass6 methods · 5 constants
EmojiPickerFieldclass1 method
FieldDescriptorclassSingle 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.
88 methods · 6 constants
FieldInterfaceinterface3 methods
FieldTraittraitFluent configuration surface shared by every field.
54 methods
FieldValueResolverclassResolves a field's raw and formatted value for one entity instance: property access, then the field's formatValue() callable if any.
10 methods · 4 constants
FileFieldclass13 methods · 5 constants
ForexFieldclass1 method · 1 constant
GenderFieldclass1 method
IconFieldclass3 methods · 1 constant
IdFieldclass6 methods · 3 constants
ImageFieldclass2 methods · 1 constant
IntegerFieldclass1 method
KindclassWhat 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.
4 methods · 59 constants
KindsclassWhat 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).
10 methods · 1 constant
LocaleFieldclass5 methods · 4 constants
MoneyFieldclass8 methods · 5 constants
NumberFieldclass17 methods · 9 constants
PasswordFieldclass5 methods
QuadrantFieldclass6 methods · 8 constants
RoleFieldclass1 method
RouteFieldclass1 method
SelectFieldclass31 methods · 22 constants
SlugFieldclass7 methods · 3 constants
StateFieldclass1 method · 1 constant
StockFieldclass9 methods · 5 constants
TextFieldclass5 methods · 4 constants
TextareaFieldclass3 methods · 2 constants
TranslationFieldclass12 methods · 3 constants
VideoFieldclass1 method · 1 constant
WysiwygFieldclass4 methods · 5 constants
YearFieldclass1 method
AbstractBehaviourclassA 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
AssociationclassA 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
AssociationFileclassRecords 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
AttributeclassA 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
BehavioursclassThe 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
ChoiceListclassKind::LOCALE: a plain select of the locales Intl names (Symfony's LocaleType), its choices given when the field names none.
1 method
ChoicesclassThe 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
CollectionclassA 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
ColorPickrclassKind::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
CountrySelectclassKind::COUNTRY: a select2 of the countries (Base\Field\Choice\Countries), with their flags (use_html).
1 method
DateTimePickerclassKind::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
EditorclassKind::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
GuessclassWhat 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
IconclassKind::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
JsColorclassKind::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
NumberclassKind::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
PasswordclassKind::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
RecordFieldsclassA 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
SelectclassKind::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
SlugclassKind::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
ToggleclassKind::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
TranslationclassA 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
UploadclassA 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
WysiwygclassKind::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
CountriesclassThe 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
HostinterfaceA 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
OutcomeclassA submission's outcome on a host: the data as bound, the errors by field name ("" for the form's own).
1 method · 2 properties
SampleclassOne 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
SamplesclassA 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
SuiteclassThe 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
EditorJsclassAn 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
TextAlignclass3 constants
AnswerclassWhat 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
ExchangeRateclassA 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
RemoteSearchclassA 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
DropzoneclassA 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
AutovalidateclassA 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
AbstractModelclass1 method
FormModelInterfaceinterface1 method
NativeEnumclassA 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
AccountFormsclassThe 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
BindingclassWhat 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
FormBinderclassData 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
FormDefinitionclassA 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
FormProcessorclassA 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
FormSubmissionclassA 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
FormViewclassA 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
PropertiesclassReads 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
RecordRulesclassA 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
UniqueLookupclassThe 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
CommentModelclassWhat 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
ContactModelclassWhat 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
SecurityLoginModelclass2 properties
SecurityLoginTokenModelclass1 property
SecurityRegistrationModelclass3 properties
SettingModelclass1 property
ThreadSearchModelclass5 properties
UserEditModelclass3 properties
UserProfileModelclass3 properties
UserSearchModelclass1 property
RequestsOfclassThe 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
FilterInterfaceinterface1 method
FormatFilterInterfaceinterface6 methods
SanitizeFilterclass3 methods
BackgroundFilterclass9 methods
CropFilterclass7 methods
DownscaleFilterclass2 methods
FixedFilterclass3 methods
FlipFilterclass3 methods
InterlaceFilterclass3 methods
PasteFilterclass3 methods
ResampleFilterclass3 methods
ResizeFilterclass4 methods
RotateFilterclass3 methods
ScaleFilterclass3 methods
ThumbnailFilterclass7 methods
UpscaleFilterclass2 methods
WatermarkFilterclass3 methods
Base\Imagine\Filter\Basic\Definition
FullHighDefinitionFilterclass2 methods
HighDefinitionFilterclass2 methods
QuadHighDefinitionFilterclass2 methods
StandardDefinitionFilterclass2 methods
UltraHighDefinitionFilterclass2 methods
BitmapFilterclass9 methods
BitmapFilterInterfaceinterfaceSvgFilterclass9 methods
SvgFilterInterfaceinterfaceWebpFilterclass8 methods
MailTrapclassA 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
ContactMessageclassThe 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
NotificationCenterclassThe 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
NotificationLinkerInterfaceinterfaceTurns 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
Notifierclass13 methods
NotifierInterfaceinterface1 method
NullNotificationLinkerclassNo back-office installed: there is no admin page to link to.
1 method
TestRecipientclassWho 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
BaseNotificationInterfaceinterface3 methods
BaseNotifierclass26 methods
BaseNotifierInterfaceinterface14 methods
BrowserPlusChannelclassA 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
EmailPlusChannelclassInAppChannelclassThe "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
PushChannelclassThe "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
EmailComposerclassomnibase'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
InlineImagesclassThe `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
MailVariablesclassWhat 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
SignInMailsclassThe 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
LocaleRecipientInterfaceinterface1 method
LocaleRecipientTraittrait1 method
Recipientclass4 methods
TimezoneRecipientInterfaceinterface1 method
TimezoneRecipientTraittrait1 method
AliasesclassThe 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
ThreadTranslationsinterfaceThe 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
ThreadsinterfaceWhat 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
UsersinterfaceThe 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
PageViewsinterfaceThe 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
PageVisitsinterfaceThe 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
VisitsinterfaceThe 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
RevisionsinterfaceThe 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
TrashBallsinterfaceThe 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
ScopedWeeksinterfaceThe 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
SpecialDaysinterfaceThe 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
WeekDaysinterfaceThe 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
ImageCropsinterfaceThe 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
RedirectionsinterfaceThe 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
SemanticsinterfaceThe 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
SettingsinterfaceThe 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
WidgetsinterfaceThe 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
SlotsinterfaceThe 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
CommentsinterfaceThe 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
LikesinterfaceThe 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
MentionsinterfaceThe 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
TagsinterfaceA 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
ComplaintsinterfaceThe 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
ConnectionsinterfaceThe 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
IdentitiesinterfaceThe 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
NotificationsinterfaceA user's notifications, those with something to show (audit "lesringostars face au master plan", step R15; see Base\Database\Repository\Entities).
2 methods
PasskeysinterfaceThe 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
PushSubscriptionsinterfaceThe 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
TokensinterfaceThe 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
AttachmentDownloadclassA 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
DecisionclassWhat 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
ErrorPageclassWhich 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
LocaleSwitchclassThe 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
PageinterfaceThe 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
RouterPageclassA 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
ShortLinkRedirectclassA 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
SitemapPageclassThe 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
TimezoneSwitchclassThe 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
AccessControlclassThe 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
AccountsclassThe 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
AnalyticsclassThe 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
ApprovalclassAn 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
EntryPointclassA 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
ImpersonationclassThe 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
IntegrityclassThe 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
KickedclassAn 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
LaunchPageclassThe 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
LocaleclassThe 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
MaintenancePageclassThe 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
PresenceclassThe 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
RedirectionclassA 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
VerificationclassAn 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
AdminRouteNamesclassHow 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
AdminUrlGeneratorInterfaceinterfaceContract for building back-office URLs.
7 methods
CookieDomainclassThe 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
NullAdminUrlGeneratorclassStand-in used when omnibase/admin is not installed.
7 methods
AnswerclassAn 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
AuthorclassWho 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
CacheclassHow 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
CardclassA 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
CommentclassA 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
ConfidentialinterfaceA 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.
ContextProviderinterfaceWhat 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
DiscussionclassThe 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
FileclassA 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
FragmentsclassTemplates 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
FrameclassWhat 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
JsonclassData 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
LinkclassAnother 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
NegotiationclassHow 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
RedirectclassWhat 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
ReplyclassAn 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
ScreeninterfaceA 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
ShellclassA 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
SiteclassThe site around every page: its name, its slogan, its logo's address, the year, its description (lesringostars' frame `site`).
3 methods · 5 properties
StoryclassA 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
StoryTextclassA 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
TagclassA 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
TemplateclassA 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
ViewclassWhat 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
ViewerclassThe 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
VisitclassWhat 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
WelcomeclassThe 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
AccountSummaryclassAn 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
ActionclassA 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
MemberclassA 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
NotificationclassA 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
NotificationsPageclassThe 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
PasskeyclassA 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
ProfilePageclassA 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
ProviderclassA 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
SessionclassOne 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
SettingsPageclassThe 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
TwoFactorclassAn 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
AccountsclassThe 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
Storiesclassomnibase'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
ConnectionTrackerclassThe 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
CookieAnswerclassThe 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
LoginRestrictionInterfaceinterfaceSignInCaptchaclassThe 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
SignOutclassThe sign-out's address, its token in it, for any host.
2 methods · 4 constants
UserTrackerclassBase\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
WebauthnUserEntityRepositoryclassThe 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
AcoEncoderclass4 methods · 1 constant
ExcelEncoderclass4 methods · 3 constants
AnalyticsclassSingle 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
ArrayParameterBagclassThe 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
BaseServiceclassThe 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
Breadgrinderclass3 methods
BreadgrinderInterfaceinterface1 method
ColorExtractorclass2 methods
CommentGuardclassThe 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
DottedParameterBagclassThe 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
DownloadLinksclassSigned 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
EditorEnhancerclass8 methods
EditorEnhancerInterfaceinterfaceEmbedsclassAn 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
FileServiceclass20 methods · 1 constant
FileServiceInterfaceinterface7 methods
Flysystemclassomnibase'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
FlysystemInterfaceinterfaceomnibase's storages over Flysystem's types.
20 methods
FormGuardclassWhat stands between a form and a robot, in the order it is asked (docs/20-architecture/guard.md):
23 methods · 17 constants
GroupManagerclassThe one service that turns a score into an actual capability.
4 methods
HotParameterBagInterfaceinterfaceThe 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
HotParametersclassThe 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
IconProviderclass9 methods
Iconsclassomnibase'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
ImageRouteclassomnibase'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
InvitationsclassInvitation 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
Launcherclass7 methods
LauncherInterfaceinterface4 methods
LinksclassA 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
LocalBusinessclassschema.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
Localizerclass41 methods · 3 constants
LocalizerInterfaceinterface28 methods
LocatorclassWhere 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.
MaintenanceProviderclass7 methods
MaintenanceProviderInterfaceinterface6 methods
MediaServiceclass26 methods
MediaServiceInterfaceinterface8 methods
NullTradingclassThe 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
Obfuscatorclass9 methods
ObfuscatorInterfaceinterface2 methods · 2 constants
OpeningHoursclassWhen 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
Paginatorclass2 methods
PaginatorInterfaceinterface1 method
ParameterBagInterfaceinterfaceThe 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
ReadSettingsclassThe 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
RedirectionsclassWhere an address that is not found leads now (Base\Entity\Layout\Redirection).
3 methods
ReferrerclassWhere 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
ReferrerInterfaceinterface4 methods
SecurityPolicyclassThe 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
SettingBagclassThe 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
SettingBagInterfaceinterface6 methods
SettingSnapshotValueclassOpaque 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
Sharingclass5 methods
SharingInterfaceinterface1 method
SignaturesclassDocuments 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
Sitemapperclass10 methods
SitemapperInterfaceinterface6 methods
SpamCheckerclassIs 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
SpamCheckerInterfaceinterface2 methods
SpeculativeRequestclassTells a speculative request - one a client made ahead of any user action, hoping to have the answer ready - from a real one.
1 method
Storagesinterfaceomnibase'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
SystemOfUnitsclass1 method
Themizerclass16 methods
ThemizerInterfaceinterface12 methods
TimeMachineclass32 methods
TimeMachineInterfaceinterfaceThe 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
TimelineEventProviderInterfaceinterfaceA 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
Tradingclass20 methods
TradingInterfaceinterface13 methods
Translatorclassomnibase'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
TranslatorInterfaceinterface12 methods · 3 constants
TrashManagerclassReads and empties what TrasheableSubscriber put aside.
9 methods · 1 constant
VersionManagerclassReads back what VersionableSubscriber wrote.
4 methods
WidgetProviderclassThe 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
WidgetProviderInterfaceinterface4 methods
WysiwygEnhancerclass9 methods
WysiwygEnhancerInterfaceinterface8 methods
UserAgentClassifierclassBuckets 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
CalendarEntryclassOne 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
GoogleCalendarLinkclassThe "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
IcsclassDates 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
CollabRoomResolverclassThis class supplies room-key logic and version-hash logic for the real-time collaboration feature. EditorType uses this class.
5 methods
CollabTicketFactoryclassThis 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
Autocompleteclass3 methods
AutocompleteInterfaceinterface2 methods
Autovalidateclass2 methods
AutovalidateInterfaceinterfaceBreadcrumbclass38 methods
BreadcrumbInterfaceinterfaceCacheableInterfaceinterface3 methods
ClassAliasesclassomnibase'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
ClassFinderclassThe 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
ColorizeInterfaceinterface2 methods
DevelopmentEnvironmentclassWhether 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
DurationclassA 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
EntityNounsclassThe 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
EnumNounsclassThe 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
GraphInterfaceinterface3 methods
HtmlizeInterfaceinterface1 method
IconizeInterfaceinterface2 methods
IntlDateTimeclass3 methods
LinkableInterfaceinterfaceA 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
LocaleNormalizerclassomnibase'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
NounVariantsclassThe 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
PagesinterfaceRows 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
Paginationclass28 methods · 1 constant
PaginationInterfaceinterface8 methods
SaltInterfaceinterface1 method
SelectInterfaceinterface4 methods
SitemapEntryclass15 methods
SpamProtectionInterfaceinterface4 methods
WorkflowInterfaceinterface4 methods
Paletteclass10 methods
ColorsclassColour 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
AbstractCurrencyApiclass6 methods
CurrencyApiInterfaceinterface4 methods
Base\Service\Model\Currency\Api
AbstractApiclass1 method
CurrencyLayerclass2 methods
ExchangeRatesApiclass1 method
Fixerclass1 method
Base\Service\Model\IconProvider
AbstractIconAdapterclass8 methods
IconAdapterInterfaceinterface7 methods
Base\Service\Model\IconProvider\Adapter
BootstrapTwitterAdapterclass13 methods · 2 constants
FontAwesomeAdapterclass17 methods · 7 constants
AbstractCompressionclass9 methods
CompressionInterfaceinterface4 methods
Base\Service\Model\Obfuscator\Compression
DeflateCompressionclass2 methods
GzipCompressionclass2 methods
HashidsCompressionclass4 methods
NullCompressionclass1 method
ZlibCompressionclass2 methods
AbstractSharingAdapterclass4 methods
SharingAdapterInterfaceinterface4 methods
Base\Service\Model\Sharing\Adapter
FacebookAdapterclass3 methods
GooglePlusAdapterclass3 methods
LinkedInAdapterclass3 methods
PinterestAdapterclass3 methods
TumblrAdapterclass3 methods
TwitterAdapterclass3 methods
EditorJsRendererclassEditorJS'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.
1 method
HeadingEnhancerclass3 methods
HeadingEnhancerInterfaceinterface2 methods
LinkEnhancerclass1 method
LinkEnhancerInterfaceinterface1 method
MediaEnhancerclass2 methods
MediaEnhancerInterfaceinterface1 method
MentionEnhancerclass5 methods
MentionEnhancerInterfaceinterface4 methods
SemanticEnhancerclass2 methods
SemanticEnhancerInterfaceinterface1 method
WebPushServiceclassWeb 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
QrCodeclassA 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
QrSheetclassQR 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
TicketSignerclassThe 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
ThreadActionsclassThe 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
ThreadSearchclassThe 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
BagTraittrait2 methods
BaseCommonTraittrait25 methods
BaseTraittraitStatic 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
CacheClearTraittraitCacheableTraittrait3 methods
FrameworkAccessorsTraittraitBaseTrait'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
ProxyTraittrait4 methods
SimpleCacheTraittrait9 methods
SingletonTraittrait6 methods
UserInfoTraittrait7 methods · 2 constants
ApplicationTextsclassWhich texts the application wrote itself (its own translations folder), for the level of politeness (base.translator.politeness, docs/20-architecture/politeness.md).
1 method
OverridingTranslatorclassThe 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
TextOverrideCacheListenerclassA rewritten text saved or deleted: the next page reads them all again.
5 methods
AppVariableclass7 methods · 10 properties
AssetPackageclassThis 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
Environmentclassomnibase'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
Globalsclass2 methods
AccountTwigExtensionclassaccount_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
AnalyticsTwigExtensionclassThin 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
BreadgrinderTwigExtensionclass4 methods
ClassTwigExtensionclass3 methods
ClipboardTwigExtensionclass4 methods
CommonsTwigExtensionclassThe shared bricks, in a template (docs/40-commons):
5 methods
DemoTwigExtensionclassThe 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
DeployVersionExtensionclassA 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
EnumTwigExtensionclassomnibase'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
FormTwigExtensionclass6 methods
FunctionTwigExtensionclassomnibase'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
HtmlTwigExtensionclass10 methods
IconTwigExtensionclass`|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
LinkTwigExtensionclassLinks 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
LocalBusinessTwigExtensionclassschema.org's LocalBusiness in a template (docs/40-commons/local-business.md):
2 methods
LocalizerTwigExtensionclassomnibase'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
MailTwigExtensionclassWhat 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
MathTwigExtensionclass4 methods
MediaTwigExtensionclass9 methods
MenuTwigExtensionclassThe 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
NotificationTwigExtensionclassWhat 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
OAuthTwigExtensionclassoauth_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
PaginatorTwigExtensionclass17 methods
PictureTwigExtensionclassWhat 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
SecurityPolicyTwigExtensionclassExposes the administrator's account-security policy to every template as `security_policy`.
2 methods
SemanticTwigExtensionclass3 methods
SharingFilterclass5 methods
TextsTwigExtensionclassA 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
ThemizerTwigExtensionclassomnibase'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
TradingTwigExtensionclass5 methods
TranslatorTwigExtensionclass3 methods
WebpackTwigExtensionclass1 method
WidgetTwigExtensionclass4 methods
FilesystemLoaderclass5 methods
AbstractTagRendererclass1 method
TagRendererInterfaceinterface2 methods
HtmlTagRendererclassCollects 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
WebpackTagRendererclass37 methods
AdminLinksclass`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
AdminVariableclass5 methods
EmailVariableclassThe 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
RandomVariableclass2 methods
SiteVariableclass21 methods
Constraintclass1 method · 1 property
ConstraintEntityclass4 methods · 2 properties
ConstraintEntityValidatorclass5 methods
ConstraintValidatorclass5 methods · 1 property
Alphanumericclass1 property
AlphanumericPlusclass1 property
AlphanumericPlusValidatorclass1 method
AlphanumericValidatorclass1 method
Fileclass3 methods · 4 properties
FileValidatorclass1 method
Hexcodeclass1 property
HexcodeValidatorclass1 method
NotBlankclassConstraint for the NotBlank validator.
2 methods · 3 properties
NotBlankValidatorclass1 method
Passwordclass9 methods · 7 properties · 3 constants
PasswordValidatorclass1 method
StringCaseEntityclassConstraint for the StringCase Entity validator.
1 property
StringCaseEntityValidatorclass1 method
UniqueclassNo 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
UniqueEntityclassConstraint for UniqueEntity validation.
1 method · 7 properties · 1 constant
UniqueEntityValidatorclass2 methods
UniqueValidatorclassUnique'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
AssetPathsinterfaceAn 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
BellclassWhat 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
CaptionsclassWords 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
CommonsclassThe 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
DatesclassA 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
DemoclassThe 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
DeployVersionclassA 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
Enumsclassomnibase'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
Formatsclassomnibase'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
LinksclassLinks (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
MenusclassThe 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
MoneyclassAn 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
PaginationclassA 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
PicturesclassWhat 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
ViewsAdapterclassomnibridge'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
WidgetsclassA 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
WysiwygclassA 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): ResponseBase
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(): arrayEvery registry, by kind.
Discovery::registry()
public static function registry(string $kind): arrayOne registry.
Discovery::enumerations()
public static function enumerations(string $projectDir, ?string $packageDir = null): arrayThe 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.
$packageDirthe 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 parametersbase.*.
Options::schema()
public static function schema(): arrayThe options' schema: the root's children, in Omnibridge\Options\Processor's node format.
Options::environment()
public static function environment(?string $group = null): arrayThe 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): arrayConfigurations 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(): arrayWhat a configuration that says nothing gives.
Options::parameters()
public static function parameters(?array ...$configs): arrayThe 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(): arrayenvironment()'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 aparent),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());argumentsby position (0, 1,index_Nover 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'spublic,shared,lazy,abstract,autowire,autoconfigure;contracts: the aliases answering it - an interface or a former id, as a list item, or under its name withpublicand 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...): itsargumentsandcallsreplace the ones above there, itsparent,factory,bindanddecoratesare 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(): arrayEvery definition of the core, the groups in their order.
Services::group()
public static function group(string $group): arrayThe definitions of a group, in their order.
Services::applies()
public static function applies(array $definition, ?string $environment = null): boolWhether 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$definitionits
id, its class by default
Services::contracts()
public static function contracts(array $definition): arrayA 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): ?stringA 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(): ResourceNameCollectionBase\Attributes
AbstractAttribute class
abstract class AbstractAttribute implements AttributeInterface AbstractAttribute.php:43
AbstractAttribute::getAttributeReader()
public static function getAttributeReader(): ?AttributeReaderAbstractAttribute::getEnvironment()
public static function getEnvironment(): stringAbstractAttribute::getProjectDir()
public static function getProjectDir(): stringAbstractAttribute::getParameterBag()
public static function getParameterBag(): ParameterBagInterfaceAbstractAttribute::getEntityManager()
public static function getEntityManager(): ?EntityManagerAbstractAttribute::getEntityHydrator()
public static function getEntityHydrator(): EntityHydratorInterfaceAbstractAttribute::getTypeOfField()
public static function getTypeOfField($className, string $property)- Throws
Exception
AbstractAttribute::getClassMetadata()
public static function getClassMetadata($objectOrClass): ?ClassMetadataAbstractAttribute::getClassMetadataManipulator()
public static function getClassMetadataManipulator(): null|MetadataManipulator|\Omnibridge\Doctrine\Omnibase\Database\Mapping\ClassMetadataManipulatorThe 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\ClassMetadataCompletorAbstractAttribute::getFlysystem()
public static function getFlysystem(): StoragesAbstractAttribute::getImpersonator()
public static function getImpersonator(): ?UserAbstractAttribute::getUser()
public static function getUser(): ?UserAbstractAttribute::getRepository()
public static function getRepository($className): EntityRepository|ObjectRepositoryAbstractAttribute::getAsset()
public static function getAsset($url): stringAbstractAttribute::resolveAttributes()
public static function resolveAttributes($entityOrClassNameOrMetadataOrRefl, string $mappingPath, ?string $attributeClass = null): arrayResolve 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): mixedAbstractAttribute::hasAttribute()
public static function hasAttribute($entityOrClassNameOrMetadataOrRefl, string $mapping, string $attributeClass): boolAbstractAttribute::getUnitOfWork()
public static function getUnitOfWork(): UnitOfWorkMinimize 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|PersistentCollectionThe 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(): ?SerializerAbstractAttribute::isSerializable()
public static function isSerializable(AbstractAttribute $attribute): boolAbstractAttribute::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): ?objectAbstractAttribute::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): ?objectAbstractAttribute::getOldEntityData()
public static function getOldEntityData($entity, ?NeutralUnitOfWork $unitOfWork = null): ?arrayAbstractAttribute::hasField()
public static function hasField($entity, string $property): boolAbstractAttribute::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|EntityValuesAbstractAttribute::hasProperty()
public static function hasProperty($entity, string $property): boolAbstractAttribute::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|EntityValuesAbstractAttribute::loadClassMetadata()
public function loadClassMetadata(ClassMetadata $classMetadata, string $target, ?string $targetValue = null): voidAbstractAttribute::complete()
public function complete(Completor $completor, string $target, ?string $targetValue = null): voidWhat 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): voidAbstractAttribute::preQuery()
public function preQuery(DoctrineQueryEventArgs $args): voidAbstractAttribute::onQuery()
public function onQuery(DoctrineQueryEventArgs $args): voidAbstractAttribute::postQuery()
public function postQuery(DoctrineQueryEventArgs $args): voidAbstractAttribute::preFlush()
public function preFlush(PreFlushEventArgs $event, ClassMetadata $classMetadata, mixed $entity, ?string $property = null): voidAbstractAttribute::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): voidAbstractAttribute::onPreUpdate()
public function onPreUpdate(Lifecycle\PreUpdate $event, ?string $property = null): voidAbstractAttribute::onPreRemove()
public function onPreRemove(Lifecycle\PreRemove $event, ?string $property = null): voidAbstractAttribute::onPostLoad()
public function onPostLoad(Lifecycle\PostLoad $event, ?string $property = null): voidAbstractAttribute::onPostPersist()
public function onPostPersist(Lifecycle\PostPersist $event, ?string $property = null): voidAbstractAttribute::onPostUpdate()
public function onPostUpdate(Lifecycle\PostUpdate $event, ?string $property = null): voidAbstractAttribute::onPostRemove()
public function onPostRemove(Lifecycle\PostRemove $event, ?string $property = null): voidAbstractAttribute::onPreFlush()
public function onPreFlush(Lifecycle\PreFlush $event, object $entity, ?string $property = null): voidA flush's moments, for one entity it writes (insertions, updates, deletions).
AbstractAttribute::onOnFlush()
public function onOnFlush(Lifecycle\OnFlush $event, object $entity, ?string $property = null): voidAbstractAttribute::onPostFlush()
public function onPostFlush(Lifecycle\PostFlush $event, object $entity, ?string $property = null): voidAttributeInterface interface
interface AttributeInterface AttributeInterface.php:13
AttributeInterface::supports()
public function supports(string $target, ?string $targetValue = null, mixed $object = null): boolAttributeInterface::loadClassMetadata()
public function loadClassMetadata(ClassMetadata $classMetadata, string $target, ?string $targetValue = null)AttributeInterface::resolveDiscriminator()
public function resolveDiscriminator(ResolveDiscriminatorEventArgs $args): voidAttributeInterface::preQuery()
public function preQuery(DoctrineQueryEventArgs $args): voidAttributeInterface::onQuery()
public function onQuery(DoctrineQueryEventArgs $args): voidAttributeInterface::postQuery()
public function postQuery(DoctrineQueryEventArgs $args): voidAttributeInterface::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): selfAttributeReader::getEntityManager()
public function getEntityManager()AttributeReader::getRepository()
public function getRepository($entity)- Throws
NotSupported
AttributeReader::isEntity()
public function isEntity(mixed $entity): boolAttributeReader::getEntityHydrator()
public function getEntityHydrator(): EntityHydratorInterfaceAttributeReader::getClassMetadataManipulator()
public function getClassMetadataManipulator(): MetadataManipulator|\Omnibridge\Doctrine\Omnibase\Database\Mapping\ClassMetadataManipulatorAttributeReader::getFlysystem()
public function getFlysystem(): ?StoragesAttributeReader::getParameterBag()
public function getParameterBag(): ParameterBagInterfaceAttributeReader::__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(): arrayAttributeReader::addPath()
public function addPath(string $path): selfAttributeReader::configuredPaths()
public static function configuredPaths(ParameterBagInterface $parameterBag): arrayThe 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): stringAttributeReader::getUser()
public function getUser(): ?UserInterfaceAttributeReader::getImpersonator()
public function getImpersonator(): ?UserAttributeReader::getAttributeNames()
public function getAttributeNames(): arrayAttributeReader::addAttributeName()
public function addAttributeName(string $attributeName)AttributeReader::removeAttributeName()
public function removeAttributeName(string $attributeName)AttributeReader::getAttributeTargets()
public function getAttributeTargets(object|string $className): arrayAttributeReader::getParent()
public function getParent(string $className): ?stringEverything related to hierarchy
AttributeReader::getAncestor()
public function getAncestor($className): ?stringAttributeReader::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): arrayA 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 = []): arrayAttributeReader::getMethodAttributes()
public function getMethodAttributes(mixed $classNameOrMetadataOrRefl, mixed $attributeNames = null, array $attributeTargets = []): arrayAttributeReader::getPropertyAttributes()
public function getPropertyAttributes(mixed $classNameOrMetadataOrRefl, mixed $attributeNames = null, array $attributeTargets = []): arrayAttributeReader::getReflClass()
public function getReflClass($classNameOrMetadataOrRefl)AttributeReader::normalizeNames()
public function normalizeNames(mixed $attributeNames, bool $fallbackAttributeNames = true): ?arrayAttributeReader::normalizeTargets()
public function normalizeTargets($attributeTargets, $attributeNames)- Throws
Exception
AttributeReader::warmUp()
public function warmUp(string $cacheDir, ?string $buildDir = null): arrayAttributeReader::precompute()
public function precompute(): voidPrecompute 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): boolIconize::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): boolIsGranted::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): boolBase\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): ?stringDemoPasswords::update()
public function update(object $account, string $hash): voidEnrolmentPrompt 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): boolWhether a request asks for a page the prompt may stand in for.
$acceptablethe content types the client accepts, in order (none: anything)
EnrolmentPrompt::due()
public function due(?object $user, bool $offered, bool $skipped, bool $impersonating): boolWhether the visitor goes to the enrolment page now.
$offeredthe session holds the offer after a new device
$skippedthe session said "not now" (SecurityPolicy::SESSION_ENROLMENT_SKIPPED)
$impersonatingthe visitor impersonates the account (a super-admin's support)
EnrolmentPrompt::forgetsTheOffer()
public function forgetsTheOffer(?object $user, bool $offered): boolWhether 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): ?boolWhat 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): voidPolicy 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
demoenvironment) 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): arrayPolicy::needsEnrolment()
public function needsEnrolment(object $account): boolMust this account set up a second factor before carrying on (signed in, sent to the enrolment)?
Policy::allowsEmailLinking()
public function allowsEmailLinking(object $account): boolMay this account be linked to an identity provider by its address alone (QA3)?
Policy::onRevoking()
public function onRevoking(Revoking $event): voidListens 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): boolRegistration 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): UserThe new account made ready and kept; $signedIn the account already signed in, if any.
Registration::name()
public function name(User $user): voidAn 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): ?objectUserAccounts::byHandle()
public function byHandle(string $handle): ?objectUserAccounts::handle()
public function handle(object $account): stringUserAccounts::identifier()
public function identifier(object $account): stringUserAccounts::displayName()
public function displayName(object $account): stringUserAccounts::email()
public function email(object $account): ?stringUserAccounts::check()
public function check(object $account): voidUserBackupCodes 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): arrayUserBackupCodes::replace()
public function replace(object $account, array $hashes): voidUserEmailCodes 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): boolUserEmailCodes::enable()
public function enable(object $account): voidUserEmailCodes::disable()
public function disable(object $account): voidUserEmailCodes::remember()
public function remember(object $account, string $hash): voidUserEmailCodes::remembered()
public function remembered(object $account): ?stringUserEmailCodes::forget()
public function forget(object $account): voidUserIdentities 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): ?objectUserIdentities::link()
public function link(object $account, string $provider, string $subject, ?string $email = null, bool $emailVerified = false): voidUserIdentities::unlink()
public function unlink(object $account, string $provider): voidUserIdentities::used()
public function used(string $provider, string $subject, \DateTimeImmutable $at): voidUserIdentities::providers()
public function providers(object $account): arrayUserIdentities::of()
public function of(object $account): arrayThe 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): voidUserLinkTokens::consume()
public function consume(string $hash, \DateTimeImmutable $now): ?objectUserLinkTokens::consumePlain()
public function consumePlain(string $value, \DateTimeImmutable $now): ?objectUserPasskeys 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): iterableUserPasskeys::byCredentialId()
public function byCredentialId(string $credentialId): ?PasskeyRecordUserPasskeys::add()
public function add(object $account, PasskeyRecord $record, ?string $label = null): voidUserPasskeys::used()
public function used(PasskeyRecord $record): voidUserPasskeys::record()
public static function record(Passkey $passkey): PasskeyRecordThe record of a passkey, in the values of its columns.
UserPasskeys::fill()
public static function fill(Passkey $passkey, PasskeyRecord $record): PasskeyA 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): ?stringUserPasswords::update()
public function update(object $account, string $hash): voidUserStore 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)$unitOfWorkthe 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): ?stringUserTotpSecrets::enable()
public function enable(object $account, string $secret): voidUserTotpSecrets::disable()
public function disable(object $account): voidUserTrustedVersion 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): intUserTrustedVersion::revokeAll()
public function revokeAll(object $account): voidBase\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(): ?OutcomeClosing 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(): OutcomeClosing::welcomeBack()
public function welcomeBack(?string $value): OutcomeThe 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 = 20How 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): stringDevices::renamePasskey()
public function renamePasskey(int $id, ?string $token, ?string $label): OutcomeA passkey's label (none for an empty one).
Devices::deletePasskey()
public function deletePasskey(int $id, ?string $token): OutcomeDevices::signOut()
public function signOut(int $id, ?string $token): OutcomeOne 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 = 50const TEMPLATE = 'client/user/search.html.twig'
MemberSearch::__construct()
public function __construct(readonly Users $users)MemberSearch::find()
public function find(?string $term): arrayOutcome 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 = []): selfOutcome::url()
public static function url(string $url): selfOutcome::index()
public static function index(): selfOutcome::home()
public static function home(): selfOutcome::back()
public static function back(): selfOutcome::page()
public static function page(Template $page): selfOutcome::signedIn()
public static function signedIn(object $user, bool $remember = false): selfOutcome::denied()
public static function denied(?string $reason = null): selfOutcome::missing()
public static function missing(?string $reason = null): selfOutcome::signingIn()
public function signingIn(object $user, bool $remember = false): selfThe 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_CHANGEThe 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): ?OutcomeAn 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|OutcomeThe 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): OutcomeThe new password chosen: the link used up, the account signed in (remembered), the index.
Passwords::changeToken()
public function changeToken(): Token|OutcomeThe 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): OutcomeThe 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|OutcomeProfileAccess::edit()
public function edit(int $id = -1): User|OutcomeRescuePage 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): ?OutcomeRescuePage::logo()
public function logo(): mixedRescuePage::target()
public function target(string $adminUrl): stringThe 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): ?OutcomeA demonstration account's request refused (null for any other): said so, back to the settings.
SecondFactor::enrolment()
public function enrolment(): ?OutcomeWhether the page that turns it on is shown (null) or where the visitor goes instead.
SecondFactor::pending()
public function pending(\Closure $generate): stringThe 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): UserThe 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): ?OutcomeThe 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(): stringWhat the form says of a wrong code.
SecondFactor::disable()
public function disable(?string $token, ?string $password): OutcomeTurned 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(): ?UserThe account as its application scans it (the secret opened by omniauth's store), null where it has none on.
SecondFactor::waiting()
public function waiting(): ?UserThe account carrying the secret waiting for its first code, null where none waits.
SecondFactor::png()
public static function png(string $content): stringA 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'const LINK_TOKEN = 'login-token'The sign-in link's token: its name, how long it lives, how long before another is sent.
const LINK_LIFETIME = 30 * 24 * 3600const LINK_THROTTLE = 3600
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(): ?OutcomeBefore 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(): boolWhether the site signs in by a link sent by e-mail (base.user.login_with_token).
SignIn::link()
public function link(?string $token, bool $byOmniauth = false): ?OutcomeA 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): OutcomeAn 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): boolWhether 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): voidThe 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): OutcomeWhere 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(): OutcomeA 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): ?TokenThe link's token, the host signing its account in before confirm().
Verification::confirm()
public function confirm(?Token $token): OutcomeThe 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(): OutcomeThe 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(): OutcomeWaitingPages::launch()
public function launch(): OutcomeWaitingPages::pending()
public function pending(): OutcomeWaitingPages::pendingForApproval()
public function pendingForApproval(): OutcomeAn 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'])$answerthe captcha's answer the visitor posted in that field
$firewallsthe sign-ins guarded (Context::$firewall)
GuardSignIn::onVerifying()
public function onVerifying(Verifying $event): voidGuardSignIn::onSignInFailed()
public function onSignInFailed(SignInFailed $event): voidGuardSignIn::onSignedIn()
public function onSignedIn(SignedIn $event): voidGuardSignIn::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)$unitOfWorkthe entity manager is deprecated (until 6.0): adapted by UnitOfWorks
TrackConnections::onSignedIn()
public function onSignedIn(SignedIn $event): voidTrackConnections::onSignInFailed()
public function onSignInFailed(SignInFailed $event): voidTrackConnections::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)$unitOfWorkthe entity manager is deprecated (until 6.0): adapted by UnitOfWorks
UpdateAccount::onSignedIn()
public function onSignedIn(SignedIn $event): voidUpdateAccount::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 = 120A 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)$declinedwhether this browser said "no thanks" (SecurityPolicy::COOKIE_NEW_DEVICE_PROMPT_DISMISSED)
$mailsthe 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): voidWarnNewDevice::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)$unitOfWorkthe entity manager is deprecated (until 6.0): adapted by UnitOfWorks
$notifierits welcome-back e-mail (Notifier::userWelcomeBack()); without it, the same e-mail, bare
$mailsthe e-mail written and sent without Symfony's Notifier (a host without it: omnibridge/laravel)
WelcomeBack::onAccountRefused()
public function onAccountRefused(AccountRefused $event): voidWelcomeBack::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 whileadmin_accessis on; - ANONYMOUS_ACCESS:
public_access, or a signed-in user whileadmin_accessoruser_accessis on; - EXCEPTION_ACCESS: the address is outside the restricted firewalls (
base.access_restriction.firewalls), or matches one ofbase.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)$firewallthe name of the firewall an address belongs to, null for none
$environmentthe environment's name
Access::supports()
public function supports(string $attribute): boolAccess::decide()
public function decide(string $attribute, mixed $subject): boolThe 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): boolWhether 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): boolAdmin::decide()
public function decide(mixed $user): boolComplaint 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): boolComplaint::decide()
public function decide(string $attribute, mixed $subject, mixed $user, \Closure $hasTag): bool$hasTagthe 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): boolMaintenance 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): boolPage 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(): boolA page of the sign-in's own (the rescue door must stay open).
Page::isProfiler()
public function isProfiler(): boolThe profiler's or the debugging toolbar's.
Page::isAdmin()
public function isAdmin(): boolThe back office's.
Page::name()
public function name(): ?stringThe 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): boolPermission::decide()
public function decide(string $attribute, mixed $user): boolRestriction 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)$grantedthe host's decision on an attribute, for the current account or the subject given
Restriction::decide()
public function decide(mixed $user, Page $page): RestrictionDecisionRestrictionDecision 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): selfRestrictionDecision::notFound()
public static function notFound(bool $profiler): selfRestrictionDecision::redirect()
public static function redirect(array $routes): selfWelcome 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.alienwhere the host says it is not authenticated (Symfony's IS_AUTHENTICATED_FULLY/REMEMBERED refused), elselogin.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): ?stringThe 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(): stringEntity 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): iterableNotifierStub 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(): ClassReflectionEntityAccessorReflection::isStatic()
public function isStatic(): boolEntityAccessorReflection::isPrivate()
public function isPrivate(): boolEntityAccessorReflection::isPublic()
public function isPublic(): boolEntityAccessorReflection::getDocComment()
public function getDocComment(): ?stringEntityAccessorReflection::getName()
public function getName(): stringEntityAccessorReflection::getPrototype()
public function getPrototype(): ClassMemberReflectionEntityAccessorReflection::getVariants()
public function getVariants(): arrayEntityAccessorReflection::isDeprecated()
public function isDeprecated(): TrinaryLogicEntityAccessorReflection::getDeprecatedDescription()
public function getDeprecatedDescription(): ?stringEntityAccessorReflection::isFinal()
public function isFinal(): TrinaryLogicEntityAccessorReflection::isInternal()
public function isInternal(): TrinaryLogicEntityAccessorReflection::getThrowType()
public function getThrowType(): ?TypeEntityAccessorReflection::hasSideEffects()
public function hasSideEffects(): TrinaryLogicEntityAccessorsExtension 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
aliasof 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): boolEntityAccessorsExtension::getMethod()
public function getMethod(ClassReflection $classReflection, string $methodName): MethodReflectionFinderMethodReflection 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(): ClassReflectionFinderMethodReflection::isStatic()
public function isStatic(): boolFinderMethodReflection::isPrivate()
public function isPrivate(): boolFinderMethodReflection::isPublic()
public function isPublic(): boolFinderMethodReflection::getDocComment()
public function getDocComment(): ?stringFinderMethodReflection::getName()
public function getName(): stringFinderMethodReflection::getPrototype()
public function getPrototype(): ClassMemberReflectionFinderMethodReflection::getVariants()
public function getVariants(): arrayFinderMethodReflection::isDeprecated()
public function isDeprecated(): TrinaryLogicFinderMethodReflection::getDeprecatedDescription()
public function getDeprecatedDescription(): ?stringFinderMethodReflection::isFinal()
public function isFinal(): TrinaryLogicFinderMethodReflection::isInternal()
public function isInternal(): TrinaryLogicFinderMethodReflection::getThrowType()
public function getThrowType(): ?TypeFinderMethodReflection::hasSideEffects()
public function hasSideEffects(): TrinaryLogicFinderMethodsExtension 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): boolFinderMethodsExtension::getMethod()
public function getMethod(ClassReflection $classReflection, string $methodName): MethodReflectionBase\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 = 128The 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): ProfilePageA member's profile, as the visitor asking sees it.
AccountScreens::settings()
public function settings(?User $user, iterable $sessions = []): SettingsPageAccountScreens::notifications()
public function notifications(iterable $notifications, int $unread, bool $unreadOnly = false): NotificationsPageNotificationMessages 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::FRAMEThe 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|nullThe 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): ResponseNotificationMessages::email()
public static function email(Notification $notification, EmailRecipientInterface $recipient, BaseNotifierInterface $notifier, Views|Environment $views, string $projectDir): EmailMessageNotificationMessages::composed()
public static function composed(Notification $notification, EmailRecipientInterface $recipient, BaseNotifierInterface $notifier, Views|Environment $views): EmailMessageA 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): arraySimpleCache::useSimpleCacheVersion3()
public static function useSimpleCacheVersion3(): boolSimpleCache::get()
public function get(string $key, mixed $default = null): mixedSimpleCache::set()
public function set(string $key, mixed $value, null|int|\DateInterval $ttl = null): boolSimpleCache::delete()
public function delete(string $key): boolSimpleCache::clear()
public function clear(): boolSimpleCache::getMultiple()
public function getMultiple(iterable $keys, mixed $default = null): iterableSimpleCache::setMultiple()
public function setMultiple(iterable $keys, null|int|\DateInterval $ttl = null): boolSimpleCache::deleteMultiple()
public function deleteMultiple(iterable $keys): boolSimpleCache::has()
public function has(string $key): boolSimpleCacheInterface 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): arrayWarms up the cache.
- Returns
A list of classes or files to preload
AbstractLocalCacheInterface::hasCache()
public function hasCache(string $key): boolAbstractLocalCacheInterface::deleteCache()
public function deleteCache(?string $key = null): boolAbstractLocalCacheInterface::getCache()
public function getCache(?string $key = null, mixed $fallback = null, int|\DateInterval|null $ttl = null, $deferred = false): mixedAbstractLocalCacheInterface::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(): ArrayAdapterBase\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(): stringMemoryItem::get()
public function get(): mixedMemoryItem::isHit()
public function isHit(): boolMemoryItem::set()
public function set($value): staticMemoryItem::expiresAt()
public function expiresAt($expiration): staticMemoryItem::expiresAfter()
public function expiresAfter($time): staticMemoryPool 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): CacheItemInterfaceMemoryPool::getItems()
public function getItems(array $keys = []): iterableMemoryPool::hasItem()
public function hasItem($key): boolMemoryPool::clear()
public function clear(): boolMemoryPool::deleteItem()
public function deleteItem($key): boolMemoryPool::deleteItems()
public function deleteItems(array $keys): boolMemoryPool::save()
public function save(CacheItemInterface $item): boolMemoryPool::saveDeferred()
public function saveDeferred(CacheItemInterface $item): boolMemoryPool::commit()
public function commit(): boolBase\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$argumentsthe 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 = []): ?stringReport 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 = 0const FAILURE = 1const INVALID = 2const QUIET = 16The verbosities, Symfony Console's values (OutputInterface::VERBOSITY_*), which artisan shares.
const NORMAL = 32const VERBOSE = 64const VERY_VERBOSE = 128const DEBUG = 256const 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): selfText as it is, its line ended or not.
Report::line()
public function line(string $text = '', int $verbosity = self::NORMAL): selfA line of text.
Report::success()
public function success(string|\Stringable $message): selfReport::table()
public function table(array $headers, array $rows): selfReport::log()
public function log($level, $message, array $context = []): voidA block of the level given (PSR-3), {placeholders} replaced from the context.
Report::fail()
public function fail(int $status = self::FAILURE): selfThe task ends with this status (not 0: failed).
Report::status()
public function status(): intReport::entries()
public function entries(): arrayReport::text()
public function text(int $verbosity = self::NORMAL): stringWhat 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): stringThe 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): ReportBaseMapping 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): ReportBaseMappingInput class
final readonly class BaseMappingInput BaseMappingInput.php:6
base:mapping's options (plan "omnibase agnostic", step F5e, slice 3).
public string $sourcethe application's App\ folder (Symfony: ./src)
BaseMappingInput::__construct()
public function __construct(public string $source = 'src')$sourcethe 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$clearthe host's clear (its status)
$againthe host's second clear, in a process of its own
$sessionsthe 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 $projectDirpublic string $cacheDirpublic bool $checksomnibase's checks around the host's clear (not --no-extension)
public bool $optionalWarmersthe optional cache warmers run (not --no-optional-warmers nor --no-warmup)
public bool $sessionsthe sessions killed after the clear (--sessions)
public ?bool $phpInfopublic/phpinfo.php written (debug: true) or removed (false); null: the host has none
public ?bool $hostFallbackwhether the host's router has a host fallback (null: it has no such router)
public ?bool $customMetadataFactorywhether 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)$checksomnibase's checks around the host's clear (not --no-extension)
$optionalWarmersthe optional cache warmers run (not --no-optional-warmers nor --no-warmup)
$sessionsthe sessions killed after the clear (--sessions)
$phpInfopublic/phpinfo.php written (debug: true) or removed (false); null: the host has none
$hostFallbackwhether the host's router has a host fallback (null: it has no such router)
$customMetadataFactorywhether the persistence's metadata factory is omnibase's (null: not asked)
CacheClearInput::clears()
public function clears(): CacheClearsThe 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): ReportCacheClearSessionsInput 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 $directorypublic string $patternthe session files' names (Symfony's native handler: sess_*)
CacheClearSessionsInput::__construct()
public function __construct(public string $directory, public string $pattern = 'sess_*')$patternthe 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(): intCacheClears::notStarted()
public function notStarted(): boolNo clear yet: the application has not started.
CacheClears::isFirst()
public function isFirst(): boolCacheClears::markFirst()
public function markFirst(bool $first = true): voidThe counter set to none, when $first.
CacheClears::increment()
public function increment(): voidOne 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)$unitOfWorkthe persistence the created accounts are flushed to (a closure: asked only then, as the host's manager may not be made before)
$evictthe host's second-level cache emptied
DemoReset::run()
public function run(DemoResetInput $input, Commands $commands, ?\Closure $sink = null): ReportDemoResetInput 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 $keepFilespublic array $purgefolders emptied before the fixtures are loaded (base.demo.reset.purge)
public bool $orphansthe uploaded files no row names deleted (base.demo.reset.orphans)
public array $groupsthe 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 = [])$purgefolders emptied before the fixtures are loaded (base.demo.reset.purge)
$orphansthe uploaded files no row names deleted (base.demo.reset.orphans)
$groupsthe 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 $sourcethe application's App\ folder (Symfony: ./src)
public ?string $entityone entity's rows (its class), the candidate classes otherwise
public ?string $idone row of it
EntitiesInput::__construct()
public function __construct(public string $source = 'src', public ?string $entity = null, public ?string $id = null)$sourcethe application's App\ folder (Symfony: ./src)
$entityone entity's rows (its class), the candidate classes otherwise
$idone 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): ReportEntityDiscriminatorInput 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(): stringThe core's src/ folder.
Folders::classes()
public static function classes(string $folder, string $prefix = ''): arrayThe 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): ReportIconEnums 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): ReportIconEnumsInput class
final readonly class IconEnumsInput IconEnumsInput.php:6
icon:enums' options (plan "omnibase agnostic", step F5e, slice 3).
public string $sourcethe application's App\ folder (Symfony: ./src)
public string $enumonly the enumerations whose name starts so
IconEnumsInput::__construct()
public function __construct(public string $source = 'src', public string $enum = '')$sourcethe application's App\ folder (Symfony: ./src)
$enumonly 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$sendthe 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 $actionstatus, on (arm), off (disarm), list, show, purge, release
public ?string $idthe held message, for show, purge and release
public bool $allevery held message
public ?string $reasonwhy 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)$actionstatus, on (arm), off (disarm), list, show, purge, release
$idthe held message, for show, purge and release
$allevery held message
$reasonwhy 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): ReportNotifierMailTestInput class
final readonly class NotifierMailTestInput NotifierMailTestInput.php:6
notifier:mail:test's options (plan "omnibase agnostic", step F5e, slice 3).
public ?string $userthe account mailed (its id, e-mail address or username); the technical recipient's otherwise
NotifierMailTestInput::__construct()
public function __construct(public ?string $user = null)$userthe 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): ReportNotifierOverviewInput class
final readonly class NotifierOverviewInput NotifierOverviewInput.php:6
app:notifier's options (plan "omnibase agnostic", step F5e, slice 3).
public string $notifierthe application's notifier (App\Notifier\Notifier, the core's where it has none)
NotifierOverviewInput::__construct()
public function __construct(public string $notifier = 'App\Notifier\Notifier')$notifierthe 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): ReportThreadPublishable::banner()
public static function banner(Report $report, string $style, string $message, bool $around = true): Reportomnibase'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 $publishpublish the threads whose time has come (listed only otherwise)
ThreadPublishableInput::__construct()
public function __construct(public bool $publish = false)$publishpublish 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): ReportTimeMachineSnapshot::backup()
public function backup(TimeMachineSnapshotBackupInput $input, \Closure $confirm, ?\Closure $sink = null): ReportTimeMachineSnapshot::restore()
public function restore(TimeMachineSnapshotRestoreInput $input, \Closure $confirm, ?\Closure $sink = null): ReportTimeMachineSnapshotBackupInput class
final readonly class TimeMachineSnapshotBackupInput extends TimeMachineSnapshotInput TimeMachineSnapshotBackupInput.php:6
timemachine:snapshot:backup's options (plan "omnibase agnostic", step F5e, slice 3).
public bool $batchno confirmation asked
public bool $userlogthe 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)$batchno confirmation asked
$userlogthe 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 $storagesthe storages looked into (written to, read from)
public ?string $databasethe database connection backed up
public ?string $prefixthe snapshots' prefix (Symfony: the environment's name)
public int $cyclethe 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)$storagesthe storages looked into (written to, read from)
$databasethe database connection backed up
$prefixthe snapshots' prefix (Symfony: the environment's name)
$cyclethe 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 $idthe 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)$idthe 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): ReportTranslationControllers 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): ReportTranslationControllersInput class
final readonly class TranslationControllersInput TranslationControllersInput.php:6
translation:controllers' options (plan "omnibase agnostic", step F5e, slice 3).
public array $routesthe host's routes: name => controller ("App\...::action")
public string $controllerpublic string $suffixpublic ?string $locale
TranslationControllersInput::__construct()
public function __construct(public array $routes = [], public string $controller = '', public string $suffix = 'title', public ?string $locale = null)$routesthe 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): ReportTranslationCrudInput class
final readonly class TranslationCrudInput TranslationCrudInput.php:6
translation:crud's options (plan "omnibase agnostic", step F5e, slice 3).
public string $sourcethe application's App\ folder (Symfony: ./src)
public string $crudpublic string $actionpublic string $suffixpublic ?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)$sourcethe 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): ReportTranslationEntitiesInput class
final readonly class TranslationEntitiesInput TranslationEntitiesInput.php:8
translation:entities' options (plan "omnibase agnostic", step F5e, slice 3).
public string $sourcethe application's App\ folder (Symfony: ./src)
public string $entitypublic string $suffixpublic ?string $locale
TranslationEntitiesInput::__construct()
public function __construct(public string $source = 'src', public string $entity = '', public string $suffix = TranslatorInterface::NOUN_SINGULAR, public ?string $locale = null)$sourcethe 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): ReportTranslationEnumsInput class
final readonly class TranslationEnumsInput TranslationEnumsInput.php:8
translation:enums' options (plan "omnibase agnostic", step F5e, slice 3).
public string $sourcethe application's App\ folder (Symfony: ./src)
public string $enumpublic string $suffixpublic ?string $locale
TranslationEnumsInput::__construct()
public function __construct(public string $source = 'src', public string $enum = '', public string $suffix = TranslatorInterface::NOUN_SINGULAR, public ?string $locale = null)$sourcethe 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 $pathpublic bool $rawpublic ?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): ReportTrashPurgeInput class
final readonly class TrashPurgeInput TrashPurgeInput.php:6
trash:purge's options (plan "omnibase agnostic", step F5e, slice 3).
public bool $forcedestroy them (only reported otherwise: a dry run)
public ?int $limitat most this many in this run
TrashPurgeInput::__construct()
public function __construct(public bool $force = false, public ?int $limit = null)$forcedestroy them (only reported otherwise: a dry run)
$limitat 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): ReportUploaderEntitiesInput class
readonly class UploaderEntitiesInput UploaderEntitiesInput.php:6
uploader:entities' options (plan "omnibase agnostic", step F5e, slice 3).
public string $sourcethe application's App\ folder (Symfony: <project>/src)
public ?string $entityan entity's name under App\Entity\ or Base\Entity\ (either prefix taken off), none: all
public ?string $propertypublic ?string $uuidpublic bool $orphanspublic 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)$sourcethe application's App\ folder (Symfony: <project>/src)
$entityan entity's name under App\Entity\ or Base\Entity\ (either prefix taken off), none: all
UploaderEntitiesInput::entityName()
public function entityName(): stringThe 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 = [])$defaultFormatsbase.uploader.formats
UploaderImages::run()
public function run(UploaderEntitiesInput $input, ?\Closure $sink = null): ReportUploaderImages::isCached()
public function isCached(string $data): boolWhether 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)$mediaControllerthe 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$confirmthe host's question to the user (the renormalisation is asked for confirmation); none: refused
UploaderImagesCrop::isCropCached()
public function isCropCached(string $data, ImageCrop $imageCrop): boolWhether 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 $normalizethe crops' coordinates renormalised (x0, y0, width0, height0 from x, y, width, height)
public ?object $maxDefinitionthe 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)$normalizethe crops' coordinates renormalised (x0, y0, width0, height0 from x, y, width, height)
$maxDefinitionthe 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 $warmupthe images and their thumbnails made in the cache
public int $batchat most this many made per run (0: no limit)
public ?string $formatonly 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)$warmupthe images and their thumbnails made in the cache
$batchat most this many made per run (0: no limit)
$formatonly 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): ReportUserCreateInput class
final readonly class UserCreateInput UserCreateInput.php:6
user:create's arguments and options (plan "omnibase agnostic", step F5e, slice 3).
public string $usernamepublic string $emailpublic array $rolesUSER, ADMIN, SUPERADMIN... (ROLE_ optional)
public ?string $passwordits password (generated otherwise)
public bool $keepPasswordnot to be changed at the first sign-in
public bool $noEmailnot 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)$rolesUSER, ADMIN, SUPERADMIN... (ROLE_ optional)
$passwordits password (generated otherwise)
$keepPasswordnot to be changed at the first sign-in
$noEmailnot 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): ReportUserNotificationInput class
final readonly class UserNotificationInput UserNotificationInput.php:6
user:notifications' options (plan "omnibase agnostic", step F5e, slice 3).
public ?string $userthe account (its identifier); every account's without it
public ?string $expirythe age past which a read notification is erased ("+30 days"); base.user.notifications.expiry without it
public bool $showlist them
public bool $clearerase the read ones older than the expiry
public bool $clearAllerase 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)$userthe account (its identifier); every account's without it
$expirythe age past which a read notification is erased ("+30 days"); base.user.notifications.expiry without it
$showlist them
$clearerase the read ones older than the expiry
$clearAllerase 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): boolWhether the interfaces named are to be declared: every one of them is installed (autoloaded here).
Link class
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.
const ABSOLUTE_URL = 0Symfony's UrlGeneratorInterface::ABSOLUTE_URL: scheme, host and path
const ABSOLUTE_PATH = 1Symfony's UrlGeneratorInterface::ABSOLUTE_PATH: the path from the root
const RELATIVE_PATH = 2Symfony's UrlGeneratorInterface::RELATIVE_PATH
const NETWORK_PATH = 3Symfony's UrlGeneratorInterface::NETWORK_PATH: "//host/path"
Link::to()
public static function to(string $name, array $parameters = [], int $referenceType = self::ABSOLUTE_PATH): stringThe 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): ?stringThe 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 = []): ?stringThe image route's data for a stored file: its path, the config
(identifier, salt, webp...) and the filters, obfuscated; null for no
path.
Media::link()
public function link(string $route, array $parameters, ?string $path, array $config = []): ?stringThe 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.
$parametersthe 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): stringThe address of a named route (ux_image, ux_imageExtension...) with its parameters, by its reference type.
MediaRouter::getRouteMatch()
public function getRouteMatch(?string $routeUrl = null): ?arrayWhat 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): ?stringThe name of the route an address matches, null for none.
MediaRouter::getAssetUrl()
public function getAssetUrl(string $nameOrUrl, ?string $packageName = null): stringA 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): stringAn 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): ?stringThe 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): boolWhether 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): ?stringRuntime 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(): ParameterBagInterfaceThe 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(): NounsWhat an entity is called (C4b): its noun, singular or plural, from the "entities" catalogues.
Runtime::media()
public static function media(): MediaThe image route's addresses for a stored image (C4b): its extension, its data, its link.
Runtime::pictures()
public static function pictures(): PicturesRuntime::texts()
public static function texts(): TextsRuntime::mailer()
public static function mailer(): MailerInterfaceRuntime::notifier()
public static function notifier(): BaseNotifierInterfaceomnibase'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(): TranslatorInterfaceomnibase's translator (step E1), the one BaseTrait::getTranslator() answered: a Notification's words.
Runtime::projectDir()
public static function projectDir(): stringThe 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): boolWhether the text is an Editor.js document (rather than HTML).
Texts::render()
public function render(?string $text, array $options = []): stringThe text rendered, '' for none (null).
$optionsthose of
|wysiwyg(headings, media, semantics...)
Texts::toc()
public function toc(?string $text, ?int $maxLevel = null): arrayThe 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(): boolWhether tickets can be given: a secret and the service's public address are both set.
Tickets::getWsUrl()
public function getWsUrl(): stringThe service's public address, where a ticket is presented.
Tickets::verifyServiceToken()
public function verifyServiceToken(string $token, string $room): boolWhether 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): JsonResponseBase\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 = []): JsonLatest 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 = []): JsonLatest::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 = []): JsonRead::account()
public static function account(Access $access, Tokens $tokens, array $body): ?UserThe 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)$noticehow the host tells the account (Notice)
EmailCodeToggle::__invoke()
public function __invoke(array $body = []): RedirectEnrolment 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|RedirectEnrolmentSkip 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)$noticehow the host tells the account (a flash)
EnrolmentSkip::__invoke()
public function __invoke(array $body = []): RedirectNotice 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): voidBase\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): ?TemplateBase\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): ?stringThe former name of a moved class, null for any other.
FormerNames::name()
public static function name(string $class): stringThe 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$managerthe persistence's manager class (an interface matches its implementations)
UnitOfWorks::of()
public static function of(object $persistence): UnitOfWorkThe unit of work itself, or one made from a persistence's manager.
UnitOfWorks::repositories()
public static function repositories(UnitOfWork $unitOfWork): RepositoriesThe repositories of the unit of work's persistence, by entity class.
UnitOfWorks::shapes()
public static function shapes(UnitOfWork $unitOfWork): EntityShapesThe 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 $aliaspublic string $columnpublic ?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): boolAlias::loadClassMetadata()
public function loadClassMetadata(ClassMetadata $classMetadata, string $target, ?string $targetValue = null): voidAlias::complete()
public function complete(Completor $completor, string $target, ?string $targetValue = null): voidThe 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): voidThe neutral hooks (plan "omnibase agnostic", step F2c): the alias bound to its column.
Alias::onPrePersist()
public function onPrePersist(Lifecycle\PrePersist $event, ?string $property = null): voidAlias::onPreUpdate()
public function onPreUpdate(Lifecycle\PreUpdate $event, ?string $property = null): voidAssociate 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): boolAssociate::onPreUpdate()
public function onPreUpdate(Lifecycle\PreUpdate $event, ?string $property = null): voidThe 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): voidAssociate::onPostUpdate()
public function onPostUpdate(Lifecycle\PostUpdate $event, ?string $property = null): voidAssociate::onPostPersist()
public function onPostPersist(Lifecycle\PostPersist $event, ?string $property = null): voidAssociate::onPostLoad()
public function onPostLoad(Lifecycle\PostLoad $event, ?string $property = null): voidBlameable 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(): arrayBlameable::getFields()
public function getFields(): arrayBlameable::supports()
public function supports(string $target, ?string $targetValue = null, $object = null): boolBlameable::onPrePersist()
public function onPrePersist(Lifecycle\PrePersist $event, ?string $property = null): voidThe 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): voidThe 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_ONLYconst READ_ONLY = "READ_ONLY"const NONSTRICT_READ_WRITE = "NONSTRICT_READ_WRITE"const READ_WRITE = "READ_WRITE"public ?string $regionpublic int $associations = 0const 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 = 1The 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 = 2const FLAG_ONE_TO_MANY = 4const FLAG_MANY_TO_MANY = 8const 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): boolCache::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): voidThe 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): voidCache::onPreRemove()
public function onPreRemove(Lifecycle\PreRemove $event, ?string $property = null): voidCascade 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): boolCascade::loadClassMetadata()
public function loadClassMetadata(ClassMetadata $classMetadata, string $target, ?string $targetValue = null): voidCountify 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): boolCountify::getCount()
public function getCount($entity, ?UnitOfWork $unitOfWork = null): int- Throws
Exception
Countify::onPostLoad()
public function onPostLoad(Lifecycle\PostLoad $event, ?string $property = null): voidThe 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): voidThe 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): voidThe 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): stringDiscriminatorEntry::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): voidGenerateUuid class
class GenerateUuid extends AbstractAttribute implements ExtensionOptionInterface GenerateUuid.php:20
Class GenerateUuid package Base\Database\Attribute\GenerateUuid
const V1_MAC = 1const V2_DCE = 2const V3_MD5 = 3const V4_RANDOM = 4const V5_SHA1 = 5const V6_SORTABLE = 6const 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): stringGenerateUuid::supports()
public function supports(string $target, ?string $targetValue = null, $object = null): boolGenerateUuid::onOnFlush()
public function onOnFlush(Lifecycle\OnFlush $event, object $entity, ?string $property = null): voidThe 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 $referenceColumnpublic bool $randompublic string $algorithmpublic string $hashAlgorithmpublic string $plainpublic bool $nullablepublic array $migrateFrompublic int $keyLengthpublic bool $ignoreCasepublic bool $encodeAsBase64public int $iterationspublic ?int $costpublic ?int $memoryCostpublic ?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): boolHashify::isValid()
public static function isValid($entity, $property, $hashedMessage): bool- Throws
Exception
Hashify::supports()
public function supports(string $target, ?string $targetValue = null, $object = null): boolHashify::onPrePersist()
public function onPrePersist(Lifecycle\PrePersist $event, ?string $property = null): voidThe 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): voidThe 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): voidThe 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): voidThe 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 $hierarchypublic ?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): boolHierarchify::loadClassMetadata()
public function loadClassMetadata(ClassMetadata $classMetadata, string $target, ?string $targetValue = null): voidHierarchify::complete()
public function complete(Completor $completor, string $target, ?string $targetValue = null): voidThe 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 $orderBypublic 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): voidThe 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): voidThe 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): voidThe 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): boolOrphanRemoval::loadClassMetadata()
public function loadClassMetadata(ClassMetadata $classMetadata, string $target, ?string $targetValue = null): voidRandomize 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): boolRandomize::onOnFlush()
public function onOnFlush(Lifecycle\OnFlush $event, object $entity, ?string $property = null): voidThe 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 = []): ?stringSlugify::supports()
public function supports(string $target, ?string $targetValue = null, $object = null): boolSlugify::onOnFlush()
public function onOnFlush(Lifecycle\OnFlush $event, object $entity, ?string $property = null): voidThe 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(): arrayTimestamp::getFields()
public function getFields(): arrayTimestamp::isImmutable()
public function isImmutable(): boolTimestamp::getValue()
public function getValue(): DateTimeTimestamp::supports()
public function supports(string $target, ?string $targetValue = null, $object = null): boolTimestamp::onPrePersist()
public function onPrePersist(Lifecycle\PrePersist $event, ?string $property = null): voidThe 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): voidThe 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(): arrayTimezone::getValue()
public function getValue(): stringTimezone::supports()
public function supports(string $target, ?string $targetValue = null, $object = null): boolTimezone::onPrePersist()
public function onPrePersist(Lifecycle\PrePersist $event, ?string $property = null): voidThe 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): voidThe 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 $deletedAtField carrying the deletion date.
public ?string $expiryHow long a trashed entity survives before the purge command may destroy it for good. Null means "use base.extension.empty_trash".
public bool $cascadeWhether 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): ?selfFind 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): boolUploader 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): \SplFileInfoUploader::getFileMimeType()
public static function getFileMimeType(\SplFileInfo $file): ?stringThe 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|floatThe 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): voidThe 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): ?stringUploader::getPublic()
public static function getPublic($entity, $fieldName)- Throws
Exception
Uploader::getMimeTypes()
public static function getMimeTypes($entity, $fieldName): arrayUploader::getMaxFilesize()
public static function getMaxFilesize($entity, $fieldName): intUploader::materializeTemporaryFile()
public static function materializeTemporaryFile(string $index, callable $read): ?\SplFileInfoRemote 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(): voidClose 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): boolUploader::onPreFlush()
public function onPreFlush(Lifecycle\PreFlush $event, object $entity, ?string $property = null): voidThe 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): voidThe 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): voidThe 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 $vaultpublic array $fieldspublic 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): stringWhere 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): arrayThe 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): ?MarshallerInterfaceVault::allowsPlaintext()
public function allowsPlaintext(): boolbase.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): boolWhether 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): stringFails 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): mixedVault::onPreFlush()
public function onPreFlush(Lifecycle\PreFlush $event, object $entity, ?string $property = null): voidThe 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): voidThe 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): voidThe neutral hook (plan "omnibase agnostic", step F2b): the secured fields sealed before the insertion.
Vault::sealFields()
public function sealFields(object $entity): voidEach 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): voidThe 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): voidThe neutral hook (plan "omnibase agnostic", step F2b): the secured fields revealed once read.
Vault::revealFields()
public function revealFields(object $entity): voidEach 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 $restorableWhether 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 $ignoreTop-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): mixedThe 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): boolVersionable::resolve()
public static function resolve(object|string $entityOrClass): arrayVersioned property names for a class, mapped to their attribute.
Versionable::anchor()
public static function anchor(object $entity): arrayWhere 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): boolBase\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$unitOfWorkthe persistence's UnitOfWork class (a subclass matches too)
$behaviourthe backend interface (VaultBackend::class...)
$backendits implementation, built with the unit of work
Backends::has()
public static function has(UnitOfWork $unitOfWork, string $behaviour): boolBackends::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): voidWhat 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): boolWhether the persistence took the ordering of that collection over (it sorts itself when loaded).
$positionsthe 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(): arrayThe entities the running flush inserts, then those it updates, in the order it writes them.
SlugifyBackend::uniqueAlone()
public function uniqueAlone(string $class, string $property): boolWhether 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): voidThe 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(): arrayReturns 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): arrayExtensionMetadataInterface::get()
public static function get(): arrayExtensionMetadataInterface::has()
public static function has(string $className, ?string $property = null): boolExtensionOptionInterface interface
interface ExtensionOptionInterface extends EntityExtensionInterface ExtensionOptionInterface.php:8
ExtensionOptionInterface::supports()
public function supports(string $target, ?string $targetValue = null, mixed $object = null): boolExtensionOptionInterface::loadClassMetadata()
public function loadClassMetadata(ClassMetadata $classMetadata, string $target, ?string $targetValue = null): voidBase\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$classthe entity class (its subclasses' rows too, as the persistence maps them)
$criteriafield => 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): boolWhether 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): boolSets 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(): boolWhether the persistence keeps such a cache (Doctrine: the second-level cache is enabled).
EntityCache::evict()
public function evict(string $class, mixed $id): voidThe entity of that class and identifier forgotten by the cache.
EntityCache::evictClass()
public function evictClass(string $class): voidEvery 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): mixedBegins 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): staticThe 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(): boolWhether 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(): arrayOrderedArrayCollection::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): voidOrderedArrayCollection::getIterator()
public function getIterator(): TraversableOrderedArrayCollection::map()
public function map(Closure $func): staticOrderedArrayCollection::reduce()
public function reduce(Closure $func, $initial = null): mixedOrderedArrayCollection::filter()
public function filter(Closure $p): staticOrderedArrayCollection::findFirst()
public function findFirst(Closure $p): mixedOrderedArrayCollection::forAll()
public function forAll(Closure $p): boolOrderedArrayCollection::partition()
public function partition(Closure $p): arrayOrderedArrayCollection::slice()
public function slice(int $offset, int|null $length = null): arrayOrderedArrayCollection::matching()
public function matching(Criteria $criteria): Collection&SelectableCollection&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(): arrayEntityExtension::addExtension()
public function addExtension(EntityExtensionInterface $extension): selfEntityExtensionInterface 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 = 1const HYDRATE_BY_COLUMN = 2const DEFAULT_AGGREGATE = 0b0Aggregate methods: by default, it is "object properties" by "deep copy" method without fallback, but initializing properties
const CLASS_METHODS = 0b1const OBJECT_PROPERTIES = 0b10const PREVENT_ASSOCIATIONS = 0b100const ARRAY_OBJECT = 0b1000const DEEPCOPY = 0b10000const CONSTRUCT = 0b100000const INITIALIZE = 0b1000000const IGNORE_NULLS = 0b10000000const AUTOTYPE = 0b100000000const OBJECT_INHERITED = 0b1000000000const FETCH_ASSOCIATIONS = 0b10000000000
EntityHydrator::__construct()
public function __construct(UnitOfWork|EntityManagerInterface $unitOfWork, EntityShapes|ClassMetadataManipulator|null $shapes = null)$unitOfWorkthe entity manager deprecated until 6.0
$shapesthe unit of work's persistence's by default (UnitOfWorks::shapes()); the manipulator deprecated until 6.0
EntityHydrator::getUnitOfWork()
public function getUnitOfWork(): UnitOfWorkEntityHydrator::getShapes()
public function getShapes(): EntityShapesEntityHydrator::hydrate()
public function hydrate(mixed $entity, null|array|object $data = [], array $fieldExceptions = [], int $aggregateModel = self::DEFAULT_AGGREGATE, ...$constructArguments): mixedEntityHydrator::dehydrate()
public function dehydrate(mixed $entity, array $fieldExceptions = [], int $aggregateModel = self::CLASS_METHODS | self::OBJECT_PROPERTIES): ?arrayEntityHydrator::fromProxy()
public function fromProxy(object $proxy): objectThe 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): arrayEntityHydrator::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): mixedEntityHydratorInterface::dehydrate()
public function dehydrate(mixed $entity, array $fieldExceptions = []): ?arrayEntityHydratorInterface::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,translationsof 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): selfThe values of the entities of that unit of work, on its persistence's shapes (one per unit of work).
EntityValues::shapes()
public function shapes(): EntityShapesEntityValues::isEntity()
public function isEntity(object|string $entityOrClass): boolWhether the entity's class is one the persistence maps.
EntityValues::isMapped()
public function isMapped(object|string $entityOrClass, string $property): boolWhether the property is a field or an association of the entity's class.
EntityValues::get()
public function get(mixed $entity, string|array $path): mixedThe 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): voidThe 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): mixedA 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): voidA property written through its setter (ClassMetadataManipulator::setPropertyValue()).
EntityValues::declaringClass()
public function declaringClass(object|string $entityOrClass, string $property): ?stringThe 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): ?stringThe 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): ?stringThe 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): voidA 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): arraySerializableInterface::getArrayCopy()
public function getArrayCopy(): arrayBase\Database\Entity\Extension
AliasInterface interface
interface AliasInterface AliasInterface.php:5
AliasInterface::__call()
public function __call(string $method, array $args): mixedAliasInterface::__isset()
public function __isset(string $property): boolAliasInterface::__get()
public function __get(string $property): mixedAliasInterface::__set()
public function __set(string $property, mixed $value): voidAliasTrait 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): voidAliasTrait::__isset()
public function __isset(string $name): boolAliasTrait::__call()
public function __call(string $name, array $arguments): mixedTranslatableAliasTrait trait
trait TranslatableAliasTrait TranslatableAliasTrait.php:7
TranslatableAliasTrait::__call()
public function __call(string $method, array $arguments): mixedTranslatableAliasTrait::__isset()
public function __isset(string $property): boolTranslatableAliasTrait::__get()
public function __get(string $property): mixedTranslatableAliasTrait::__set()
public function __set(string $property, mixed $value): voidTranslatableInterface 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(): stringTranslatableTrait::getTranslationEntityClass()
public static function getTranslationEntityClass(bool $withInheritance = true, bool $selfClass = false): ?stringTranslatableTrait::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): boolTranslationInterface 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(): ?TranslatableInterfaceTranslationInterface::setTranslatable()
public function setTranslatable(?TranslatableInterface $translatable)TranslationInterface::getLocale()
public function getLocale(): ?stringTranslationInterface::setLocale()
public function setLocale(string $locale)TranslationInterface::isEmpty()
public function isEmpty(): boolTranslationTrait trait
trait TranslationTrait TranslationTrait.php:11
TranslationTrait::getId()
public function getId(): ?intTranslationTrait::getEntityFqcn()
public static function getEntityFqcn(): stringTranslatable related methods
TranslationTrait::getTranslatableEntityClass()
public static function getTranslatableEntityClass(): stringTranslationTrait::getTranslatable()
public function getTranslatable(): ?TranslatableInterfaceTranslationTrait::setTranslatable()
public function setTranslatable(?TranslatableInterface $translatable)TranslationTrait::getLocale()
public function getLocale(): ?stringTranslationTrait::setLocale()
public function setLocale(string $locale)TranslationTrait::isEmpty()
public function isEmpty(array $addIgnoredVars = [], ?callable $addConditions = null): boolTrasheableInterface interface
interface TrasheableInterface TrasheableInterface.php:5
TrasheableTrait trait
trait TrasheableTrait TrasheableTrait.php:9
TrasheableTrait::isDeleted()
public function isDeleted()TrasheableTrait::getDeletedAt()
public function getDeletedAt(): ?DateTimeInterfaceTrasheableTrait::setDeletedAt()
public function setDeletedAt(?DateTimeInterface $deletedAt): selfTrasheableTrait::restore()
public function restore(): selfTake 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(): ?stringVaultTrait::setVault()
public function setVault(?string $vault): selfVaultTrait::getPlainVaultBag()
public function getPlainVaultBag(mixed $key): mixedVaultTrait::getSealedVaultBag()
public function getSealedVaultBag(string $key): ?stringVaultTrait::setVaultBag()
public function setVaultBag(?string $key, string $sealedValue, mixed $plainValue): selfVaultTrait::isSecured()
public function isSecured(): boolVaultTrait::getSecure()
public function getSecure(): boolVaultTrait::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(): arrayEntityMetadataInterface 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): boolBase\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): arrayThe versioned properties' diff, keyed by the anchor's prefix and the property.
$changesthe entity's field and to-one changes
$collectionsa changed to-many property => [its snapshot, its items]
RevisionRecorder::revision()
public function revision(string $class, object $target, array $diff): ?RevisionThe 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): mixedA 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)$settingBaglazy: see SettingSubscriber
SettingsInvalidation::onPostPersist()
public function onPostPersist(Lifecycle\PostPersist $event): voidSettingsInvalidation::onPostUpdate()
public function onPostUpdate(Lifecycle\PostUpdate $event): voidSettingsInvalidation::onPostRemove()
public function onPostRemove(Lifecycle\PostRemove $event): voidThreadParticipants 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)$mentionEnhancerlazy: 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): voidThreadParticipants::onFlush()
public function onFlush(Lifecycle\OnFlush $event, iterable $threads): voidThe mentions of the threads whose text this flush writes, made to match their text.
ThreadParticipants::follow()
public function follow(Thread $thread): boolA reply followed by its parent's owners; whether it gained a follower.
ThreadParticipants::mentionees()
public function mentionees(Thread $thread): arrayThe 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')$emptyTrashbase.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'): stringAn 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): boolWhether 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): TrashBallThe 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(): ?stringCompletor::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): CompletorThe completor of a class (an object's class), filled by its attributes' complete() hook.
Completors::payload()
public static function payload(string|object $class): arrayWhat 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): boolDescriptionShapes::classes()
public function classes(): arrayThe 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): EntityShapeEntityFields 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(): EntityShapesEntityFields::aliases()
public static function aliases(string|object $class): arrayThe aliases of a class, alias => the property it is bound to.
EntityFields::names()
public function names(string|object $class): arrayEvery 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): ?stringThe property a name designates (an alias resolved), null for none.
EntityFields::hasAssociation()
public function hasAssociation(string|object $class, ?string $name): boolWhether 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): ?stringA 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): ?stringThe class an association path leads to (ClassMetadataManipulator::fetchEntityName()), null for a field or nothing.
EntityFields::mapped()
public function mapped(string|object $class): boolWhether 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(): stringEntityShape::rootClass()
public function rootClass(): stringThe root of its inheritance, itself without one.
EntityShape::parentClass()
public function parentClass(): ?stringEntityShape::table()
public function table(): ?stringEntityShape::identifier()
public function identifier(): arrayEntityShape::primaryKey()
public function primaryKey(): ?stringThe single identifier's property, null for a composite one or none.
EntityShape::fieldNames()
public function fieldNames(): arrayEntityShape::hasField()
public function hasField(string $property): boolEntityShape::fieldType()
public function fieldType(string $property): ?stringThe field's column type by name ("string", "datetime", an enumeration's...), null for no field.
EntityShape::associationNames()
public function associationNames(): arrayEntityShape::hasAssociation()
public function hasAssociation(string $property): boolEntityShape::associationKind()
public function associationKind(string $property): ?stringRelation::ONE_TO_ONE, MANY_TO_ONE, ONE_TO_MANY or MANY_TO_MANY; null for no association.
EntityShape::targetClass()
public function targetClass(string $property): ?stringEntityShape::isToOne()
public function isToOne(string $property): boolEntityShape::isToMany()
public function isToMany(string $property): boolEntityShape::isOwningSide()
public function isOwningSide(string $property): boolEntityShape::isInverseSide()
public function isInverseSide(string $property): boolEntityShape::mappedBy()
public function mappedBy(string $property): ?stringEntityShape::inversedBy()
public function inversedBy(string $property): ?stringEntityShape::discriminatorColumn()
public function discriminatorColumn(): ?stringEntityShape::discriminatorMap()
public function discriminatorMap(): array- Returns
value => class
EntityShape::discriminatorValue()
public function discriminatorValue(): ?stringEntityShapes 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): boolWhether the class (or the entity's, a proxy seen through) is a mapped entity.
EntityShapes::shape()
public function shape(string|object $class): EntityShapeThe 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(): EntityShapesThe entities' shapes this manipulator reads.
MetadataManipulator::getShape()
public function getShape(null|string|object $entityOrClass): ?EntityShapeThe shape of an entity or an entity class, null for anything else.
MetadataManipulator::isEntity()
public function isEntity($entityOrClassOrMetadata): boolMetadataManipulator::isEnumType()
public function isEnumType($entityOrClassOrMetadata): boolMetadataManipulator::isSetType()
public function isSetType($entityOrClassOrMetadata): boolMetadataManipulator::isNativeEnum()
public function isNativeEnum(mixed $class): boolA 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): ?stringThe 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): ?stringMetadataManipulator::getDiscriminatorValue()
public function getDiscriminatorValue($entity): ?stringMetadataManipulator::getDiscriminatorMap()
public function getDiscriminatorMap($entity): arrayMetadataManipulator::getRootEntityName()
public function getRootEntityName($entity): ?stringMetadataManipulator::getFieldValue()
public function getFieldValue($entity, string|array $fieldPath): mixedMetadataManipulator::setFieldValue()
public function setFieldValue($entity, string|array $fieldPath, $value)MetadataManipulator::hasField()
public function hasField(null|string|object $entityOrClassOrMetadata, string $fieldName): boolMetadataManipulator::hasProperty()
public function hasProperty(null|string|object $entityOrClassOrMetadata, string $fieldName): ?stringMetadataManipulator::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): ?stringMetadataManipulator::isAlias()
public function isAlias(null|object|string $entityOrClassOrMetadata, array|string $fieldPath): boolMetadataManipulator::getFieldName()
public function getFieldName(null|object|string $entityOrClassOrMetadata, array|string $fieldName): ?stringMetadataManipulator::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): ?stringMetadataManipulator::getAssociationTargetClass()
public function getAssociationTargetClass(null|string|object $entityOrClassOrMetadata, string $fieldName): stringMetadataManipulator::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): boolMetadataManipulator::isInverseSide()
public function isInverseSide(null|string|object $entityOrClassOrMetadata, string $fieldName): boolMetadataManipulator::isToOneSide()
public function isToOneSide(null|string|object $entityOrClassOrMetadata, string $fieldName): boolMetadataManipulator::isToManySide()
public function isToManySide(null|string|object $entityOrClassOrMetadata, string $fieldName): boolMetadataManipulator::isManyToSide()
public function isManyToSide(null|string|object $entityOrClassOrMetadata, string $fieldName): boolMetadataManipulator::isOneToSide()
public function isOneToSide(null|string|object $entityOrClassOrMetadata, string $fieldName): boolMetadataManipulator::isManyToMany()
public function isManyToMany(null|string|object $entityOrClassOrMetadata, string $fieldName): boolMetadataManipulator::isOneToMany()
public function isOneToMany(null|string|object $entityOrClassOrMetadata, string $fieldName): boolMetadataManipulator::isManyToOne()
public function isManyToOne(null|string|object $entityOrClassOrMetadata, string $fieldName): boolMetadataManipulator::isOneToOne()
public function isOneToOne(null|string|object $entityOrClassOrMetadata, string $fieldName): boolMetadataManipulator::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): ?CompletorThe completor of a mapped class (its attributes' additions: aliases, hierarchy), null for any other.
MetadataManipulator::warmUp()
public function warmUp(string $cacheDir, ?string $buildDir = null): arrayBase\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 $backendspublic readonly string $reasonwhat the query needs of that backend ("ON DUPLICATE KEY UPDATE")
BackendOnly::__construct()
public function __construct(string|array $backends, public readonly string $reason = '')$reasonwhat the query needs of that backend ("ON DUPLICATE KEY UPDATE")
BackendOnly::of()
public static function of(string $class, string $method): ?selfThe 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): boolWhether $backend runs $class::$method: true for any method not declared backend-only.
BackendOnly::refuse()
public static function refuse(string $class, string $method, string $backend): neverRefuses 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): arrayEvery 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): ?objectEntities::findAll()
public function findAll(): arrayEntities::findBy()
public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null): array$criteriafield => value, a list of values for one of them
$orderByfield => ASC|DESC
Entities::findOneBy()
public function findOneBy(array $criteria, ?array $orderBy = null): ?objectEntities::count()
public function count(array $criteria = []): intEntities::persist()
public function persist($entity, bool $flush = false): void$entitykept at the next flush, at once with $flush
Entities::remove()
public function remove($entity, bool $flush = false): voidEntities::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): EntitiesRepositories::byIds()
public function byIds(string $class, array $ids): arrayThe 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): ?objectThe 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 $fieldpublic readonly ?int $indexpublic readonly mixed $valuepublic 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): selfA 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): boolCriterion::byKey()
public function byKey(): boolWhether 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(): stringThe 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): selfGroup::of()
public static function of(string $separator, Criterion|self ...$members): selfA 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(): boolWhether the group was read (by the Parser, or built from its members).
Group::read()
public function read(Query $query): selfThe same group, read by the parser: findBy<name> with its arguments.
Group::separator()
public function separator(): stringHow the members join: And or Or (Parser::SEPARATOR_*).
Group::criterions()
public function criterions(): arrayThe 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$valuean entity, its identifier, a list of them, or null
Key::isNull()
public function isNull(): boolWhether the key compared is none (IS NULL, IS NOT NULL with NotEqualTo).
Key::isList()
public function isList(): boolWhether 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): stringParser::getSpecials()
public static function getSpecials(): arrayParser::__construct()
public function __construct(readonly Subject $subject, readonly ?\Closure $routeParameters = null)$subjectthe entity the finder is asked of
$routeParametersa 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): QueryReads 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 $methodpublic readonly array $argumentspublic readonly array $criteriapublic readonly array $optionspublic readonly ?string $separatorpublic readonly ?string $columnpublic readonly bool $cacheablepublic readonly array|bool $eagerlypublic readonly string $requestpublic 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(): arrayEvery 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(): arrayThe 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(): stringThe entity's class, the one its mapping names (App\Entity\X where the application has one).
Subject::getFieldNames()
public function getFieldNames(): arrayThe 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): boolWhether the entity has that field or association (a real one wins over a Query-by-Example clause).
Subject::criteriaFromSelect()
public function criteriaFromSelect(object $select): arrayA 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): voidDiscriminatorRule::declared()
public function declared(Draft $class, ClassDeclaration $declaration, Builder $builder): voidDiscriminatorRule::loaded()
public function loaded(Draft $class, ClassDeclaration $declaration, Builder $builder): voidDiscriminatorRule::value()
public static function value(string $className): stringDiscriminatorEntry::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 = []): DescriptionThe description of the entities the folders hold.
$directoriesthe entities' folders (directories())
EntitySchema::rules()
public static function rules(array $options = []): arrayomnibase's rules, in the order Doctrine's listeners run.
EntitySchema::types()
public static function types(array $options = []): arrayThe 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 = []): ColumnTypesomnibase'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 = []): arrayThe 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): stringA 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): voidExtensionRule::declared()
public function declared(Draft $class, ClassDeclaration $declaration, Builder $builder): voidExtensionRule::loaded()
public function loaded(Draft $class, ClassDeclaration $declaration, Builder $builder): voidOrderColumnRule 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 = [])$typesthe column types by name, the sets among them
OrderColumnRule::before()
public function before(Draft $class, ClassDeclaration $declaration, Builder $builder): voidOrderColumnRule::declared()
public function declared(Draft $class, ClassDeclaration $declaration, Builder $builder): voidOrderColumnRule::loaded()
public function loaded(Draft $class, ClassDeclaration $declaration, Builder $builder): voidTargetRule 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 = [])$targetsinterface => class
TargetRule::before()
public function before(Draft $class, ClassDeclaration $declaration, Builder $builder): voidTargetRule::declared()
public function declared(Draft $class, ClassDeclaration $declaration, Builder $builder): voidTargetRule::loaded()
public function loaded(Draft $class, ClassDeclaration $declaration, Builder $builder): voidTranslationRule 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
translationsrelation (one-to-many, mapped bytranslatable, indexed by locale) and a translation thetranslatablerelation (many-to-one, the join column translatable_id deleted in cascade), thelocalecolumn (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): voidTranslationRule::declared()
public function declared(Draft $class, ClassDeclaration $declaration, Builder $builder): voidTranslationRule::loaded()
public function loaded(Draft $class, ClassDeclaration $declaration, Builder $builder): voidVaultRule 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): voidVaultRule::declared()
public function declared(Draft $class, ClassDeclaration $declaration, Builder $builder): voidVaultRule::loaded()
public function loaded(Draft $class, ClassDeclaration $declaration, Builder $builder): voidBase\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(): stringTrashScope::appliesTo()
public function appliesTo(string $class): boolTrashScope::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(): stringVaultScope::appliesTo()
public function appliesTo(string $class): boolVaultScope::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): ?VaultThe 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(): arrayEnumType::getColor()
public static function getColor(string $id): ?stringEnumType::getIcon()
public static function getIcon(string $id, int $index = -1): ?stringEnumType::getText()
public static function getText(string $id, ?TranslatorInterface $translator = null): ?stringEnumType::getHtml()
public static function getHtml(string $id): ?stringEnumType::getData()
public static function getData(string $id): ?arrayEnumType::getName()
public function getName(): stringEnumType::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): arrayEnumType::getPermittedValuesByGroup()
public static function getPermittedValuesByGroup(bool $inheritance = true, bool $preserve_keys = false): arrayEnumType::getPermittedValuesByClass()
public static function getPermittedValuesByClass(bool $preserve_groups = true, bool $preserve_keys = false): arrayEnumType::toDatabaseValue()
public static function toDatabaseValue(mixed $value): mixedA 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): mixedA 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): voidEnumerations::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): mixedThe 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): arrayUtc 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(): \DateTimeZoneThe zone moments are kept in: omnibridge/doctrine's, the one its types (and these) write with.
Utc::now()
public static function now(): \DateTimeImmutableUtc::from()
public static function from(?\DateTimeInterface $moment): ?\DateTimeImmutableAny 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 $identifierwhat the account signs in with (the field the application's User names in $userIdentifier)
public readonly string $labelthe button's text: a translation key ("@health.demo.practitioner.label") or the text itself
public readonly string $descriptionone sentence on what this role sees: a translation key or the text itself
public readonly array $rolesthe account's own roles
public readonly ?string $groupthe name of a Base\Entity\User\Group the account belongs to (it holds the group's roles)
public readonly array $groupRolesthe roles of that group, when the fixtures have to create it
public readonly ?string $passwordnull: the identifier (demonstration accounts are public)
public readonly ?string $emailnull: <identifier>@example.org
public readonly int $positionthe 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)$identifierwhat the account signs in with (the field the application's User names in $userIdentifier)
$labelthe button's text: a translation key ("@health.demo.practitioner.label") or the text itself
$descriptionone sentence on what this role sees: a translation key or the text itself
$rolesthe account's own roles
$groupthe name of a Base\Entity\User\Group the account belongs to (it holds the group's roles)
$groupRolesthe roles of that group, when the fixtures have to create it
$passwordnull: the identifier (demonstration accounts are public)
$emailnull: <identifier>@example.org
$positionthe order on the sign-in page, lowest first
DemoAccount::getPassword()
public function getPassword(): stringDemoAccount::getEmail()
public function getEmail(): stringDemoAccount::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): ?objectThe row of a declared account, null when the database has none.
DemoAccountFactory::account()
public function account(string $identifier, ?ObjectManager $manager = null): objectThe 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): arrayEvery declared account, created when missing.
- Returns
by identifier
DemoAccountFactory::missing()
public function missing(?ObjectManager $manager = null): arrayThe 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): ?DemoAccountThe declaration of this account as the database knows it: by the identifier it was loaded with, not the one just typed.
$originalthe 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): boolPuts back what may not change; true when something had.
$originalthe row as loaded
$fieldsthe columns the account's class maps
$reada column's value on the object
$writea column's value put back on the object
DemoAccountLock::message()
public function message(string $key): stringThe 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(): iterableDemoAccountRegistry 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'])$excludeidentifiers left out (base.demo.exclude)
$adminRolesthe 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(): arrayThe 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): arrayThe 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.
$rolesnull: the constants of the
user_roletype
DemoAccountRegistry::get()
public function get(?string $identifier): ?DemoAccountDemoAccountRegistry::has()
public function has(?string $identifier): boolDemoAccountRegistry::of()
public function of(?object $user): ?DemoAccountThe declaration this account was created from, if it is a demonstration account.
DemoAccountRegistry::reachesSuperAdmin()
public function reachesSuperAdmin(array $roles): boolDo 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): boolDemoAccountRegistry::reachesAdministration()
public function reachesAdministration(array $roles): boolDo 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): boolDemoGuard 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:resetempties 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): ?stringWhere 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(): boolDemoSignIn 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(): boolDemoSignIn::decide()
public function decide(?string $token, ?string $account, \Closure $load): OutcomeThe account to sign in (the host then answers what its sign-in answers, else the index), or the refusal.
$loadthe 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): stringThread::__iconize()
public function __iconize(): ?arrayThread::__iconizeStatic()
public static function __iconizeStatic(): ?arrayThread::__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).
Thread::__toLink()
public function __toLink(array $routeParameters = [], int $referenceType = Link::ABSOLUTE_PATH): ?stringIts 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(): ?intThread::getUuid()
public function getUuid()Thread::getParent()
public function getParent(): ?selfThread::setParent()
public function setParent(?self $parent): selfThread::getChildren()
public function getChildren(): CollectionThread::addChild()
public function addChild(self $child): selfThread::removeChild()
public function removeChild(self $child): selfThread::getConnexes()
public function getConnexes(): CollectionThread::addConnex()
public function addConnex($connex): selfThread::removeConnex()
public function removeConnex($connex): selfThread::getSlug()
public function getSlug(): ?stringThread::setSlug()
public function setSlug(string $slug): selfThread::getState()
public function getState()Thread::setState()
public function setState($state): selfThread::setIsPublished()
public function setIsPublished(bool $newState): selfThread::isFuture()
public function isFuture(): boolThread::isDeleted()
public function isDeleted(): boolThread::isScheduled()
public function isScheduled(): boolThread::isSecret()
public function isSecret(): boolThread::isPublished()
public function isPublished(null|DateTime|string $within = null): boolThread::isVisible()
public function isVisible(): boolAn 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(): boolThread::isApproved()
public function isApproved()Thread::getWorkflow()
public function getWorkflow()Thread::setWorkflow()
public function setWorkflow($workflow): selfThread::getOwner()
public function getOwner(int $i = 0)Thread::getOwners()
public function getOwners(): CollectionThread::addOwner()
public function addOwner(?User $owner): selfThread::removeOwner()
public function removeOwner(?User $owner): selfThread::getFollowers()
public function getFollowers(): CollectionThread::addFollower()
public function addFollower(User $follower): selfThread::removeFollower()
public function removeFollower(User $follower): selfThread::getPrimaryTag()
public function getPrimaryTag()Thread::getSecondaryTags()
public function getSecondaryTags(): arrayThread::getTags()
public function getTags(): CollectionThread::addTag()
public function addTag(Tag $tag): selfThread::removeTag()
public function removeTag(?Tag $tag): selfThread::getTaxa()
public function getTaxa(): CollectionThread::getTaxonomy()
public function getTaxonomy(): CollectionThread::addTaxon()
public function addTaxon($taxon): selfThread::removeTaxon()
public function removeTaxon($taxon): selfThread::getMentions()
public function getMentions(): CollectionThread::addMention()
public function addMention(Mention $mention): selfThread::removeMention()
public function removeMention(Mention $mention): selfThread::getLikes()
public function getLikes(): CollectionThread::addLike()
public function addLike(Like $like): selfThread::removeLike()
public function removeLike(?Like $like): selfThread::isLiked()
public function isLiked(?User $user, ?string $icon = null): boolThread::getCreatedAt()
public function getCreatedAt(): ?DateTimeInterfaceThread::getUpdatedAt()
public function getUpdatedAt(): ?DateTimeInterfaceThread::poke()
public function poke(): selfThread::getPublishedAt()
public function getPublishedAt(): ?DateTimeInterfaceThread::getPublishTime()
public function getPublishTime(): ?intThread::getPublishTimeStr()
public function getPublishTimeStr(): ?stringThread::setPublishedAt()
public function setPublishedAt(?DateTimeInterface $publishedAt): selfThread::getKeywords()
public function getKeywords(?string $locale = null, int $inheritanceDepthIfNotSet = 0): arrayThread::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): ?stringThread::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): ?stringThread::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): ?stringThread::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): ?stringThread::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(): ?stringThreadIntl::setTitle()
public function setTitle(?string $title)ThreadIntl::getHeadline()
public function getHeadline(bool $fallback = false): ?stringThreadIntl::setHeadline()
public function setHeadline(?string $headline)ThreadIntl::getKeywords()
public function getKeywords(): arrayThreadIntl::setKeywords()
public function setKeywords(array $keywords)ThreadIntl::getExcerpt()
public function getExcerpt(): ?stringThreadIntl::setExcerpt()
public function setExcerpt(?string $excerpt)ThreadIntl::getContent()
public function getContent(): ?stringThreadIntl::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 = 6const TOTP_TIMEOUT = 30const 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(): stringUser::__autocompleteData()
public function __autocompleteData(): arrayUser::__toString()
public function __toString()User::nameOf()
public static function nameOf(?self $user): ?stringHow 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(): ?arrayUser::__iconizeStatic()
public static function __iconizeStatic(): ?arrayUser::getUserIdentifierField()
public static function getUserIdentifierField(): stringUser::getUserIdentifier()
public function getUserIdentifier(): stringUser::equals()
public function equals($other): boolUser::__construct()
public function __construct(?string $email = null)- Throws
Exception
User::getRecipient()
public function getRecipient(): RecipientUser::isGranted()
public function isGranted($role): boolWhether 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(): ?intUser::setId()
public function setId($id): selfUser::getTotpSecret()
public function getTotpSecret()User::isTotpAuthenticationEnabled()
public function isTotpAuthenticationEnabled(): boolUser::getTotpAuthenticationUsername()
public function getTotpAuthenticationUsername(): stringUser::getTotpAuthenticationConfiguration()
public function getTotpAuthenticationConfiguration(): ?TotpConfigurationInterfaceUser::setTotpSecret()
public function setTotpSecret($secret): selfUser::isBackupCode()
public function isBackupCode(string $code): boolUser::invalidateBackupCode()
public function invalidateBackupCode(string $code): voidUser::getBackupCodesCount()
public function getBackupCodesCount(): intUser::getBackupCodeHashes()
public function getBackupCodeHashes(): arrayThe 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$hashespassword_hash()'s of the codes, never the codes
User::setBackupCodes()
public function setBackupCodes(array $plainCodes): selfUser::isEmailAuthEnabled()
public function isEmailAuthEnabled(): boolUser::setEmailAuthEnabled()
public function setEmailAuthEnabled(bool $emailAuthEnabled): selfUser::getEmailAuthRecipient()
public function getEmailAuthRecipient(): stringUser::getEmailAuthCode()
public function getEmailAuthCode(): ?stringUser::setEmailAuthCode()
public function setEmailAuthCode(?string $authCode): voidThe 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(): intUser::invalidateTrustedDevices()
public function invalidateTrustedDevices(): selfBump this to invalidate every previously-trusted device for this user (e.g. after disabling 2FA).
User::getEmail()
public function getEmail(): ?stringUser::setEmail()
public function setEmail(string $email): selfUser::getPhone()
public function getPhone(): ?stringUser::setPhone()
public function setPhone(?string $phone): selfUser::getAvatar()
public function getAvatar()- Throws
Exception
User::getAvatarFile()
public function getAvatarFile()- Throws
FilesystemException
User::setAvatar()
public function setAvatar($avatar)User::getColor()
public function getColor(): ?stringUser::setColor()
public function setColor(?string $color): selfUser::getLocale()
public function getLocale(): ?stringUser::setLocale()
public function setLocale(?string $locale = null): selfUser::getPlainPassword()
public function getPlainPassword(): ?stringUser::setPlainPassword()
public function setPlainPassword(?string $password): voidUser::__serialize()
public function __serialize(): arrayUser::erasePlainPassword()
public function erasePlainPassword()User::eraseCredentials()
public function eraseCredentials(): voidUser::getPassword()
public function getPassword(): ?stringUser::setPassword()
public function setPassword(string $password): selfUser::getIdentityProvider()
public function getIdentityProvider(): ?stringUser::setIdentityProvider()
public function setIdentityProvider(?string $identityProvider): selfUser::isFederated()
public function isFederated(): boolUser::isPersistent()
public function isPersistent(): boolUser::getRoles()
public function getRoles(): arrayEffective 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(): arrayOnly this user's own roles - what the roles column stores, what edit forms bind to.
User::setRoles()
public function setRoles(array $roles): selfUser::setOwnRoles()
public function setOwnRoles(array $roles): selfAlias so form binding on 'ownRoles' has a matching setter - writes only the own column, same as setRoles().
User::getGroups()
public function getGroups(): CollectionUser::addGroup()
public function addGroup(Group $group): selfUser::removeGroup()
public function removeGroup(Group $group): selfUser::getPermissions()
public function getPermissions(): CollectionUser::addPermission()
public function addPermission(Permission $permission): selfUser::removePermission()
public function removePermission(Permission $permission): selfUser::getSanctions()
public function getSanctions(): CollectionUser::getActiveSanctions()
public function getActiveSanctions(?DateTimeInterface $at = null): CollectionOnly the ones still standing: not lifted, not lapsed.
User::addSanction()
public function addSanction(Sanction $sanction): selfUser::removeSanction()
public function removeSanction(Sanction $sanction): selfUser::getPenalties()
public function getPenalties(?DateTimeInterface $at = null): arrayThe 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): intWhat 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): intUser::getNotifications()
public function getNotifications()User::addNotification()
public function addNotification(Notification $notification): selfUser::removeNotification()
public function removeNotification(Notification $notification): selfUser::isTester()
public function isTester()User::getExpiredTokens()
public function getExpiredTokens(): CollectionUser::getValidTokens()
public function getValidTokens(): CollectionUser::getTokens()
public function getTokens($type = Token::ALL): CollectionUser::removeExpiredTokens()
public function removeExpiredTokens(): selfUser::getExpiredToken()
public function getExpiredToken(string $name): ?TokenUser::getValidToken()
public function getValidToken(string $name): ?TokenUser::getToken()
public function getToken(string $name, $type = Token::ALL): ?TokenUser::addToken()
public function addToken(Token $token): selfUser::removeTokenByName()
public function removeTokenByName(?string $name): selfUser::removeToken()
public function removeToken(Token $token): selfUser::getThreads()
public function getThreads(): CollectionUser::addThread()
public function addThread(Thread $thread): selfUser::removeThread()
public function removeThread(Thread $thread): selfUser::isFollowing()
public function isFollowing(Thread $followedThread): boolUser::getFollowedThreads()
public function getFollowedThreads(): CollectionUser::addFollowedThread()
public function addFollowedThread(Thread $thread): selfUser::removeFollowedThread()
public function removeFollowedThread(Thread $thread): selfUser::getMentions()
public function getMentions(): CollectionUser::addMentions()
public function addMentions(Mention $mentions): selfUser::removeMentions()
public function removeMentions(Mention $mentions): selfUser::getLikes()
public function getLikes(): CollectionUser::addLike()
public function addLike(Like $like): selfUser::removeLike()
public function removeLike(Like $like): selfUser::getStates()
public function getStates(): arrayUser::setStates()
public function setStates(array $states): selfUser::newcomer()
public function newcomer(bool $newState = true): selfUser::elder()
public function elder(bool $newState = true): selfUser::isNewcomer()
public function isNewcomer(): boolUser::isElder()
public function isElder(): boolUser::setIsNewcomer()
public function setIsNewcomer(bool $newState): selfUser::approve()
public function approve(bool $newState = true): selfUser::disregarded()
public function disregarded(bool $newState = true): selfUser::isApproved()
public function isApproved(): boolUser::isDisregarded()
public function isDisregarded(): boolUser::setIsApproved()
public function setIsApproved(bool $newState): selfUser::verify()
public function verify(bool $newState = true): selfUser::isVerified()
public function isVerified(): boolUser::setIsVerified()
public function setIsVerified(bool $newState)User::enable()
public function enable(bool $newState = true): selfUser::disable()
public function disable(bool $newState = true): selfUser::isEnabled()
public function isEnabled(): boolUser::isDisabled()
public function isDisabled(): boolUser::setIsEnabled()
public function setIsEnabled(bool $newState): selfUser::lock()
public function lock(bool $newState = true): selfUser::unlock()
public function unlock(bool $newState = true): selfUser::isLocked()
public function isLocked(): boolUser::setIsLocked()
public function setIsLocked(bool $newState): selfUser::ban()
public function ban(bool $newState = true): selfUser::unban()
public function unban(bool $newState = true): selfUser::isBanned()
public function isBanned(): boolUser::setIsBanned()
public function setIsBanned(bool $newState = true): selfUser::kick()
public function kick(bool $newState = true): selfUser::unkick()
public function unkick(bool $newState = true): selfUser::isKicked()
public function isKicked(): boolUser::setIsKicked()
public function setIsKicked(bool $newState = true): selfUser::ghost()
public function ghost(bool $newState = true): selfUser::isGhost()
public function isGhost(): boolUser::setIsGhost()
public function setIsGhost(bool $newState): selfUser::getBirthdate()
public function getBirthdate(): ?DateTimeInterfaceUser::setBirthdate()
public function setBirthdate(?DateTimeInterface $birthdate): selfUser::getAge()
public function getAge(): ?intUser::getCreatedAt()
public function getCreatedAt(): ?DateTimeInterfaceUser::getUpdatedAt()
public function getUpdatedAt(): ?DateTimeInterfaceUser::getActiveAt()
public function getActiveAt(): ?DateTimeInterfaceUser::poke()
public function poke(?DateTimeInterface $activeAt): selfUser::getActiveDelay()
public static function getActiveDelay(): intUser::isActive()
public function isActive(): boolUser::getOnlineDelay()
public static function getOnlineDelay(): intUser::isOnline()
public function isOnline(): boolUser::getAddresses()
public function getAddresses(): CollectionUser::getAddress()
public function getAddress(int $i = 0): ?AddressUser::addAddress()
public function addAddress(Address $address): selfUser::removeAddress()
public function removeAddress(Address $address): selfUser::getConnections()
public function getConnections(): CollectionUser::addConnection()
public function addConnection(Connection $connection): selfUser::removeConnection()
public function removeConnection(Connection $connection): selfUser::getPasskeys()
public function getPasskeys(): CollectionUser::addPasskey()
public function addPasskey(Passkey $passkey): selfUser::removePasskey()
public function removePasskey(Passkey $passkey): selfBase\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): staticAbstractEvent::eventName()
public function eventName(): stringAbstractEvent::getLifecycle()
public function getLifecycle(): LifecycleEventArgs|EntityEventThe persistence's arguments of the moment: omnisense/omnibridge's Lifecycle event, or Doctrine's LifecycleEventArgs.
AbstractEvent::getUnitOfWork()
public function getUnitOfWork(): UnitOfWorkThe unit of work the entity was written through, whichever persistence.
AbstractEvent::getRequest()
public function getRequest(): ?RequestAbstractEvent::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(): stringAbstractEvent::getObject()
public function getObject(): objectAbstractEventDispatcher 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)$unitOfWorkthe entity manager is deprecated (until 6.0): adapted by UnitOfWorks
$requestsSymfony'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): voidA 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): arrayThe 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): voidNothing is flushed here any more: see $flushPending.
AbstractEventDispatcher::flushPending()
public function flushPending(): voidWhat 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(): voidKeyed 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(): UnitOfWorkAbstractEventDispatcher::getAssociationChangeSet()
public function getAssociationChangeSet($entity): arrayAbstractEventDispatcher::getAssociationDeleteDiff()
public function getAssociationDeleteDiff($entity, $field): arrayAbstractEventDispatcher::getAssociationInsertDiff()
public function getAssociationInsertDiff($entity, $field): arrayAbstractEventDispatcher::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): voidBefore a supported entity is inserted: the events to dispatch once it is (addEvent()).
AbstractEventDispatcher::updating()
public function updating(Lifecycle\PreUpdate $event): voidBefore a supported entity is updated, its changes in the event (the original entity: EntityHydrator::getOriginalEntity($event)).
AbstractEventDispatcher::removing()
public function removing(Lifecycle\PreRemove $event): voidBefore 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): boolEventDispatcherInterface::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(): stringEventInterface::getObject()
public function getObject(): objectBase\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(): ThreadThreadEventDispatcher class
class ThreadEventDispatcher extends AbstractEventDispatcher ThreadEventDispatcher.php:10
ThreadEventDispatcher::supports()
public function supports(mixed $subject): boolThreadEventDispatcher::persisting()
public function persisting(Lifecycle\PrePersist $event): voidThreadEventDispatcher::updating()
public function updating(Lifecycle\PreUpdate $event): voidUserEvent 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(): UserUserEventDispatcher class
class UserEventDispatcher extends AbstractEventDispatcher UserEventDispatcher.php:9
UserEventDispatcher::supports()
public function supports(mixed $subject): boolUserEventDispatcher::persisting()
public function persisting(Lifecycle\PrePersist $event): voidUserEventDispatcher::updating()
public function updating(Lifecycle\PreUpdate $event): voidBase\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(): arrayConnectionSubscriber::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(): arrayThreadSubscriber::onSchedule()
public function onSchedule(ThreadEvent $event)ThreadSubscriber::onPublishable()
public function onPublishable(ThreadEvent $event)ThreadSubscriber::prePersist()
public function prePersist(PrePersistEventArgs $event): voidA new reply followed by its parent's owners.
ThreadSubscriber::onFlush()
public function onFlush(OnFlushEventArgs $event): voidThe 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 * 3600The 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)$accesswho is signed in (plan "omnibase agnostic", F5c); Symfony's token storage is deprecated (until 6.0)
UserSubscriber::listen()
public function listen(callable $listen): voidThe 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(): voidThe 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(): voidUserSubscriber::getSubscribedEvents()
public static function getSubscribedEvents(): arrayUserSubscriber::onRegistration()
public function onRegistration(UserEvent $event): voidUserSubscriber::onApproval()
public function onApproval(UserEvent $event): voidUserSubscriber::onEnabling()
public function onEnabling(UserEvent $event): voidUserSubscriber::onDisabling()
public function onDisabling(UserEvent $event): voidBase\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(): ?intPageView::getPath()
public function getPath(): ?stringPageView::setPath()
public function setPath(string $path): selfPageView::getDate()
public function getDate(): ?\DateTimeImmutablePageView::setDate()
public function setDate(\DateTimeImmutable $date): selfPageView::getViews()
public function getViews(): intPageView::setViews()
public function setViews(int $views): selfPageView::getSource()
public function getSource(): stringPageView::setSource()
public function setSource(string $source): selfPageVisit 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(): ?intPageVisit::getDate()
public function getDate(): ?\DateTimeImmutablePageVisit::setDate()
public function setDate(\DateTimeImmutable $date): selfPageVisit::getPath()
public function getPath(): ?stringPageVisit::setPath()
public function setPath(string $path): selfPageVisit::getSubjectType()
public function getSubjectType(): ?stringPageVisit::setSubjectType()
public function setSubjectType(string $subjectType): selfPageVisit::getSubjectId()
public function getSubjectId(): ?stringPageVisit::setSubjectId()
public function setSubjectId(string $subjectId): selfVisit 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(): ?intVisit::getDate()
public function getDate(): ?\DateTimeImmutableVisit::setDate()
public function setDate(\DateTimeImmutable $date): selfVisit::getSubjectType()
public function getSubjectType(): ?stringVisit::setSubjectType()
public function setSubjectType(string $subjectType): selfVisit::getSubjectId()
public function getSubjectId(): ?stringVisit::setSubjectId()
public function setSubjectId(string $subjectId): selfBase\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(): ?arrayRevision::__construct()
public function __construct()Revision::getHash()
public function getHash()Revision::getHashShort()
public function getHashShort()Revision::getFields()
public function getFields(): arrayField names this revision touched, with the locale prefix stripped off.
Revision::getPreviousValue()
public function getPreviousValue(string $field): mixedThe value $field held BEFORE this revision - what a restore puts back.
Revision::getNextValue()
public function getNextValue(string $field): mixedRevision::supports()
public function supports(): boolTrashBall class
class TrashBall extends AbstractExtension TrashBall.php:13
TrashBall::__iconizeStatic()
public static function __iconizeStatic(): ?arrayTrashBall::getPermanentAfter()
public function getPermanentAfter(): ?DateTimeInterfaceTrashBall::setPermanentAfter()
public function setPermanentAfter(DateTimeInterface $permanentAfter): selfTrashBall::supports()
public function supports(): boolBase\Entity\Extension\Abstract
AbstractExtension class
abstract class AbstractExtension implements AbstractExtensionInterface, IconizeInterface AbstractExtension.php:17
AbstractExtension::__iconize()
public function __iconize(): ?arrayAbstractExtension::__iconizeStatic()
public static function __iconizeStatic(): ?arrayAbstractExtension::getId()
public function getId()AbstractExtension::getImpersonator()
public function getImpersonator(): ?UserAbstractExtension::getInitiator()
public function getInitiator(): ?UserAbstractExtension::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(): arrayAbstractExtension::setEntityData()
public function setEntityData(array $entityData)AbstractExtension::getCreatedAt()
public function getCreatedAt(): ?DateTimeInterfaceAbstractExtension::setCreatedAt()
public function setCreatedAt(DateTimeInterface $createdAt): selfAbstractExtensionInterface 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(): ?intScopedWeek::getScope()
public function getScope(): stringScopedWeek::getWeek()
public function getWeek(): array- Returns
all seven days
ScopedWeek::setWeek()
public function setWeek(array $week): static$weekISO 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(): ?intSpecialDay::getStartsOn()
public function getStartsOn(): stringSpecialDay::getEndsOn()
public function getEndsOn(): stringSpecialDay::getReason()
public function getReason(): ?stringSpecialDay::setReason()
public function setReason(?string $reason): staticSpecialDay::getCreatedAt()
public function getCreatedAt(): \DateTimeImmutableSpecialDay::getScope()
public function getScope(): ?stringSpecialDay::getHours()
public function getHours(): ?arraySpecialDay::setHours()
public function setHours(?array $hours): staticSpecialDay::isClosed()
public function isClosed(): boolSpecialDay::covers()
public function covers(\DateTimeInterface $day): boolSpecialDay::isOneDay()
public function isOneDay(): boolSpecialDay::from()
public function from(): \DateTimeImmutableSpecialDay::until()
public function until(): \DateTimeImmutableWeekDayHours 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(): intWeekDayHours::getId()
public function getId(): intomnibase's listeners ask every entity for one.
WeekDayHours::getHours()
public function getHours(): arrayWeekDayHours::setHours()
public function setHours(array $hours): static$hoursin 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): mixedAttribute::set()
public function set(...$args): selfAttribute::resolve()
public function resolve(?string $locale = null): mixedAttributeIntl class
class AttributeIntl implements TranslationInterface AttributeIntl.php:16
AttributeIntl::isEmpty()
public function isEmpty(): boolAttributeIntl::getValue()
public function getValue()- Throws
Exception
AttributeIntl::getValueFile()
public function getValueFile()- Throws
FilesystemException
AttributeIntl::setValue()
public function setValue($value)AttributeIntl::getClass()
public function getClass(): ?stringAttributeIntl::setClass()
public function setClass(?string $class)Image class
class Image implements IconizeInterface, ImageInterface, SaltInterface Image.php:27
Image::getSalt()
public function getSalt(): stringImage::__toLink()
public function __toLink(array $routeParameters = [], int $referenceType = Link::ABSOLUTE_PATH): ?stringThe 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(): ?arrayImage::__iconizeStatic()
public static function __iconizeStatic(): ?arrayImage::__toString()
public function __toString()Image::__construct()
public function __construct($src = null)Image::getId()
public function getId(): ?intImage::getSource()
public function getSource()- Throws
Exception
Image::getSourceFile()
public function getSourceFile()- Throws
FilesystemException
Image::setSource()
public function setSource($source): staticImage::getNaturalWidth()
public function getNaturalWidth(): ?intImage::getNaturalHeight()
public function getNaturalHeight(): ?intImage::getSourceMeta()
public function getSourceMeta(): array|null|falseImage::get()
public function get()Image::getFile()
public function getFile()Image::set()
public function set($source): selfImage::getQuadrant()
public function getQuadrant(): stringImage::getQuadrantPosition()
public function getQuadrantPosition(): stringImage::setQuadrant()
public function setQuadrant(string $quadrant): selfImage::getCrops()
public function getCrops(): CollectionImage::getCrop()
public function getCrop(string $identifier): ?ImageCropImage::addCrop()
public function addCrop(ImageCrop $crop): selfImage::removeCrop()
public function removeCrop(ImageCrop $crop): selfImageCrop class
class ImageCrop implements LinkableInterface, SaltInterface ImageCrop.php:16
ImageCrop::getSalt()
public function getSalt(): stringImageCrop::__toLink()
public function __toLink(array $routeParameters = [], int $referenceType = Link::ABSOLUTE_PATH): ?stringThe 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(): ?intImageCrop::getImage()
public function getImage(): ?ImageImageCrop::setImage()
public function setImage(?Image $image): selfImageCrop::getLabel()
public function getLabel(): ?stringImageCrop::setLabel()
public function setLabel(?string $label): selfImageCrop::getSlug()
public function getSlug(): ?stringImageCrop::setSlug()
public function setSlug(?string $slug): selfImageCrop::__construct()
public function __construct(?Image $image = null)ImageCrop::getData()
public function getData(): arrayImageCrop::getX()
public function getX(?int $width = null): ?intImageCrop::getX0()
public function getX0(): ?floatImageCrop::setX0()
public function setX0(float $x0): selfImageCrop::getY()
public function getY(?int $height = null): ?intImageCrop::getY0()
public function getY0(): ?floatImageCrop::setY0()
public function setY0(float $y0): selfImageCrop::getPivotX()
public function getPivotX(?int $width = null)ImageCrop::getXp()
public function getXp(): ?floatImageCrop::setXp()
public function setXp(float $xP): selfImageCrop::getPivotY()
public function getPivotY(?int $height = null)ImageCrop::getYp()
public function getYp(): ?floatImageCrop::setYp()
public function setYp(float $yP): selfImageCrop::getNaturalWidth()
public function getNaturalWidth(): ?intImageCrop::getWidth()
public function getWidth(?int $width = null): ?intImageCrop::getWidth0()
public function getWidth0(): ?floatImageCrop::setWidth0()
public function setWidth0(float $width0): selfImageCrop::getNaturalHeight()
public function getNaturalHeight(): ?intImageCrop::getHeight()
public function getHeight(?int $height = null): ?intImageCrop::getHeight0()
public function getHeight0(): ?floatImageCrop::setHeight0()
public function setHeight0(float $height0): selfImageCrop::getScaleX()
public function getScaleX(): ?floatImageCrop::setScaleX()
public function setScaleX(float $scaleX): selfImageCrop::getScaleY()
public function getScaleY(): ?floatImageCrop::setScaleY()
public function setScaleY(float $scaleY): selfImageCrop::getRotate()
public function getRotate(): ?intImageCrop::setRotate()
public function setRotate(int $rotate): selfImageCropInterface interface
interface ImageCropInterface ImageCropInterface.php:5
ImageCropInterface::getPivotX()
public function getPivotX()ImageCropInterface::getPivotY()
public function getPivotY()ImageCropInterface::getX()
public function getX(): ?intImageCropInterface::setX()
public function setX(int $x): selfImageCropInterface::getY()
public function getY(): ?intImageCropInterface::setY()
public function setY(int $y): selfImageCropInterface::getWidth()
public function getWidth(): ?intImageCropInterface::setWidth()
public function setWidth(int $width): selfImageCropInterface::getHeight()
public function getHeight(): ?intImageCropInterface::setHeight()
public function setHeight(int $height): selfImageCropInterface::getScaleX()
public function getScaleX(): ?floatImageCropInterface::setScaleX()
public function setScaleX(float $scaleX): selfImageCropInterface::getScaleY()
public function getScaleY(): ?floatImageCropInterface::setScaleY()
public function setScaleY(float $scaleY): selfImageCropInterface::getRotate()
public function getRotate(): ?intImageCropInterface::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): staticImageInterface::getNaturalWidth()
public function getNaturalWidth(): ?intImageInterface::getNaturalHeight()
public function getNaturalHeight(): ?intRedirection 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 = 301const TEMPORARY = 302const STATUSES = [self::PERMANENT, self::TEMPORARY]
Redirection::__construct()
public function __construct(string $source = '', string $target = '', int $status = self::PERMANENT)Redirection::__toString()
public function __toString(): stringRedirection::normalize()
public static function normalize(string $address): stringAn 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(): ?intRedirection::getSource()
public function getSource(): stringRedirection::setSource()
public function setSource(string $source): staticRedirection::isPrefix()
public function isPrefix(): boolCovers everything beneath its path ("/categorie-produit/*").
Redirection::getTarget()
public function getTarget(): stringRedirection::setTarget()
public function setTarget(string $target): staticA path of the site ("/savoir-faire/enseigne") or a whole address ("https://...").
Redirection::getStatus()
public function getStatus(): intRedirection::setStatus()
public function setStatus(int $status): staticRedirection::isEnabled()
public function isEnabled(): boolRedirection::setEnabled()
public function setEnabled(bool $enabled): staticRedirection::getHits()
public function getHits(): intRedirection::getLastHitAt()
public function getLastHitAt(): ?\DateTimeImmutableRedirection::getCreatedAt()
public function getCreatedAt(): \DateTimeImmutableRedirection::resolve()
public function resolve(string $address): ?stringWhere 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(): ?arraySemantic::__iconizeStatic()
public static function __iconizeStatic(): ?arraySemantic::__toLink()
public function __toLink(int $referenceType = Link::ABSOLUTE_PATH): ?stringSemantic::__construct()
public function __construct(?string $routeName, array $routeParameters = [], ?string $label = null)Semantic::getId()
public function getId(): ?intSemantic::getRouteName()
public function getRouteName(): ?stringSemantic::setRouteName()
public function setRouteName(?string $routeName): selfSemantic::getRouteParameters()
public function getRouteParameters(): ?arraySemantic::setRouteParameters()
public function setRouteParameters(?array $routeParameters): selfSemantic::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(): ?stringThe 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(): ?stringSemantic::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(): ?stringSemanticIntl::setLabel()
public function setLabel(?string $label)SemanticIntl::getKeywords()
public function getKeywords(): arraySemanticIntl::setKeywords()
public function setKeywords(array $keywords)Setting class
class Setting implements TranslatableInterface, IconizeInterface Setting.php:15
Setting::__iconize()
public function __iconize(): ?arraySetting::__iconizeStatic()
public static function __iconizeStatic(): ?arraySetting::__toString()
public function __toString()Setting::__construct()
public function __construct(string $path, $value = null, $locale = null)- Throws
Exception
Setting::getId()
public function getId(): ?intSetting::getPath()
public function getPath(): stringSetting::setPath()
public function setPath(string $path)Setting::isLocked()
public function isLocked(): boolSetting::getLocked()
public function getLocked(): boolSetting::lock()
public function lock(): selfSetting::unlock()
public function unlock(): selfSetting::setLocked()
public function setLocked(bool $locked)Setting::getBag()
public function getBag(): ?stringSetting::setBag()
public function setBag(?string $bag)SettingIntl class
class SettingIntl implements TranslationInterface SettingIntl.php:16
SettingIntl::isEmpty()
public function isEmpty(): boolSettingIntl::getLabel()
public function getLabel(): ?stringSettingIntl::setLabel()
public function setLabel(?string $label)SettingIntl::getHelp()
public function getHelp(): ?stringSettingIntl::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(): ?stringSettingIntl::setClass()
public function setClass(?string $class)ShortLink class
class ShortLink implements TranslatableInterface, IconizeInterface, LinkableInterface ShortLink.php:19
ShortLink::__iconize()
public function __iconize(): ?arrayShortLink::__iconizeStatic()
public static function __iconizeStatic(): ?arrayShortLink::__toLink()
public function __toLink(array $routeParameters = [], int $referenceType = Link::ABSOLUTE_PATH): ?stringThe short address, through the Urls contract (Base\Contract\Link): the router's own string under Symfony, made where there is no framework too.
ShortLink::__toString()
public function __toString()ShortLink::__construct()
public function __construct(string $url = "", ?string $label = null)ShortLink::getId()
public function getId(): ?intShortLink::getSlug()
public function getSlug(): ?stringShortLink::setSlug()
public function setSlug(?string $slug)ShortLinkIntl class
class ShortLinkIntl implements TranslationInterface ShortLinkIntl.php:12
ShortLinkIntl::getLabel()
public function getLabel(): ?stringShortLinkIntl::setLabel()
public function setLabel(?string $label)ShortLinkIntl::getUrl()
public function getUrl(): ?stringShortLinkIntl::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(): stringTextOverride::getId()
public function getId(): ?intTextOverride::getDomain()
public function getDomain(): stringTextOverride::setDomain()
public function setDomain(string $domain): staticTextOverride::getKey()
public function getKey(): stringTextOverride::setKey()
public function setKey(string $key): staticTextOverride::getLocale()
public function getLocale(): stringTextOverride::setLocale()
public function setLocale(string $locale): staticTextOverride::getValue()
public function getValue(): stringTextOverride::setValue()
public function setValue(string $value): staticTextOverride::getUpdatedAt()
public function getUpdatedAt(): \DateTimeImmutableTooltip class
class Tooltip implements TranslatableInterface, IconizeInterface Tooltip.php:18
Tooltip::__iconize()
public function __iconize(): ?arrayTooltip::__iconizeStatic()
public static function __iconizeStatic(): ?arrayTooltip::__toString()
public function __toString()Tooltip::__construct()
public function __construct(string $url = "", ?string $label = null)Tooltip::getId()
public function getId(): ?intTooltip::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): ?stringTooltip::setContent()
public function setContent(?string $content, ?string $locale = null, int $inheritanceDepthIfNotSet = 0)- Throws
Exception
Tooltip::getCreatedAt()
public function getCreatedAt(): ?DateTimeInterfaceTooltip::getUpdatedAt()
public function getUpdatedAt(): ?DateTimeInterfaceTooltip::getStartedAt()
public function getStartedAt(): ?DateTimeInterfaceTooltip::getEndedAt()
public function getEndedAt(): ?DateTimeInterfaceTooltipIntl class
class TooltipIntl implements TranslationInterface TooltipIntl.php:10
TooltipIntl::getTitle()
public function getTitle(): ?stringTooltipIntl::setTitle()
public function setTitle(?string $title)TooltipIntl::getContent()
public function getContent(): ?stringTooltipIntl::setContent()
public function setContent(?string $content)Widget class
class Widget implements TranslatableInterface, IconizeInterface, CacheableInterface Widget.php:29
Widget::__toKey()
public function __toKey(mixed ...$variadic): stringWidget::__iconize()
public function __iconize(): ?arrayWidget::__iconizeStatic()
public static function __iconizeStatic(): ?arrayWidget::__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(): ?intWidget::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(): CollectionWidget::addConnex()
public function addConnex(Widget $connex): selfWidget::removeConnex()
public function removeConnex(Widget $connex): selfWidget::getCreatedAt()
public function getCreatedAt(): ?DateTimeInterfaceWidget::getUpdatedAt()
public function getUpdatedAt(): ?DateTimeInterfaceWidgetIntl class
class WidgetIntl implements TranslationInterface WidgetIntl.php:10
WidgetIntl::getTitle()
public function getTitle(): ?stringWidgetIntl::setTitle()
public function setTitle(?string $title): selfWidgetIntl::getHeadline()
public function getHeadline(): ?stringWidgetIntl::setHeadline()
public function setHeadline(?string $headline): selfWidgetIntl::getExcerpt()
public function getExcerpt(): ?stringWidgetIntl::setExcerpt()
public function setExcerpt(?string $excerpt): selfWidgetIntl::getContent()
public function getContent(): ?stringWidgetIntl::setContent()
public function setContent(?string $content): selfBase\Entity\Layout\Attribute
Hyperlink class
class Hyperlink extends AbstractAttribute implements TranslatableInterface, IconizeInterface Hyperlink.php:19
Hyperlink::__construct()
public function __construct(AbstractAdapter $adapter, mixed $value = null)Hyperlink::__iconize()
public function __iconize(): ?arrayHyperlink::__iconizeStatic()
public static function __iconizeStatic(): ?arrayHyperlink::__toString()
public function __toString()Hyperlink::getHyperpattern()
public function getHyperpattern(): ?HyperpatternAdapterHyperlink::setHyperpattern()
public function setHyperpattern(?HyperpatternAdapter $hyperpattern): selfHyperlink::generate()
public function generate(?string $locale = null)Hyperlink::getLabel()
public function getLabel(): stringHyperlink::get()
public function get(?string $locale = null): mixedHyperlink::set()
public function set(...$args): selfHyperlink::resolve()
public function resolve(?string $locale = null): mixedHyperlinkIntl class
class HyperlinkIntl implements TranslationInterface HyperlinkIntl.php:9
HyperlinkIntl::isEmpty()
public function isEmpty(): boolHyperlinkIntl::getValue()
public function getValue(): arrayHyperlinkIntl::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(): ?arrayArrayAdapter::__construct()
public function __construct(string $label, ?string $path = null, ?int $length = null)ArrayAdapter::getLength()
public function getLength(): ?intArrayAdapter::setLength()
public function setLength(?int $length)ArrayAdapter::getType()
public static function getType(): stringArrayAdapter::getOptions()
public function getOptions(): arrayArrayAdapter::resolve()
public function resolve(mixed $value): mixedColorAdapter class
class ColorAdapter extends AbstractAdapter ColorAdapter.php:14
ColorAdapter::__iconizeStatic()
public static function __iconizeStatic(): ?arrayColorAdapter::getType()
public static function getType(): stringColorAdapter::getOptions()
public function getOptions(): arrayColorAdapter::resolve()
public function resolve(mixed $value): mixedColorAdapter::getName()
public function getName(?string $locale = null): stringCountryAdapter class
class CountryAdapter extends AbstractAdapter CountryAdapter.php:13
CountryAdapter::__iconizeStatic()
public static function __iconizeStatic(): ?arrayCountryAdapter::getType()
public static function getType(): stringCountryAdapter::getOptions()
public function getOptions(): arrayCountryAdapter::resolve()
public function resolve(mixed $value): mixedDateRangeAdapter 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(): ?arrayDateRangeAdapter::getType()
public static function getType(): stringDateRangeAdapter::getOptions()
public function getOptions(): arrayDateRangeAdapter::resolve()
public function resolve(mixed $value): mixedDateRangeAdapter::supports()
public function supports(mixed $value): boolDateRangeAdapter::compliesWith()
public function compliesWith(mixed $value, mixed $subject): boolDateTimeAdapter class
class DateTimeAdapter extends AbstractAdapter DateTimeAdapter.php:13
DateTimeAdapter::__iconizeStatic()
public static function __iconizeStatic(): ?arrayDateTimeAdapter::getType()
public static function getType(): stringDateTimeAdapter::getOptions()
public function getOptions(): arrayDateTimeAdapter::resolve()
public function resolve(mixed $value): mixedHyperpatternAdapter class
class HyperpatternAdapter extends AbstractAdapter HyperpatternAdapter.php:13
HyperpatternAdapter::__iconizeStatic()
public static function __iconizeStatic(): ?arrayHyperpatternAdapter::getType()
public static function getType(): stringHyperpatternAdapter::resolve()
public function resolve(mixed $value): mixedHyperpatternAdapter::getOptions()
public function getOptions(): arrayHyperpatternAdapter::__construct()
public function __construct(string $label = "", ?string $code = null, ?string $icon = "fa-solid fa-laptop", string $pattern = "https://{0}")HyperpatternAdapter::getPattern()
public function getPattern(): stringHyperpatternAdapter::setPattern()
public function setPattern(string $pattern = "https://{0}")HyperpatternAdapter::getNumberOfArguments()
public function getNumberOfArguments(): intHyperpatternAdapter::generate()
public function generate(...$replace): ?stringHyperpatternAdapterIntl class
class HyperpatternAdapterIntl extends AbstractAdapterIntl HyperpatternAdapterIntl.php:8
HyperpatternAdapterIntl::getPlaceholder()
public function getPlaceholder(): ?arrayHyperpatternAdapterIntl::setPlaceholder()
public function setPlaceholder(?array $placeholder): selfImageAdapter class
class ImageAdapter extends AbstractAdapter ImageAdapter.php:13
ImageAdapter::__iconizeStatic()
public static function __iconizeStatic(): ?arrayImageAdapter::getType()
public static function getType(): stringImageAdapter::getOptions()
public function getOptions(): arrayImageAdapter::resolve()
public function resolve(mixed $value): mixedMoneyAdapter class
class MoneyAdapter extends AbstractAdapter MoneyAdapter.php:13
MoneyAdapter::__iconizeStatic()
public static function __iconizeStatic(): ?arrayMoneyAdapter::getType()
public static function getType(): stringMoneyAdapter::getOptions()
public function getOptions(): arrayMoneyAdapter::resolve()
public function resolve(mixed $value): mixedMoneyAdapter::__construct()
public function __construct(string $label = "", ?string $code = null, ?int $minimum = null, ?int $maximum = null)MoneyAdapter::getMinimum()
public function getMinimum(): ?intMoneyAdapter::setMinimum()
public function setMinimum(?int $minimum)MoneyAdapter::getMaximum()
public function getMaximum(): ?intMoneyAdapter::setMaximum()
public function setMaximum(?int $maximum)NumberAdapter class
class NumberAdapter extends AbstractAdapter NumberAdapter.php:13
NumberAdapter::__iconizeStatic()
public static function __iconizeStatic(): ?arrayNumberAdapter::getType()
public static function getType(): stringNumberAdapter::getOptions()
public function getOptions(): arrayNumberAdapter::resolve()
public function resolve(mixed $value): mixedNumberAdapter::__construct()
public function __construct(string $label = "", ?string $code = null, ?int $minimum = null, ?int $maximum = null)NumberAdapter::getMinimum()
public function getMinimum(): ?intNumberAdapter::setMinimum()
public function setMinimum(?int $minimum)NumberAdapter::getMaximum()
public function getMaximum(): ?intNumberAdapter::setMaximum()
public function setMaximum(?int $maximum)PercentAdapter class
class PercentAdapter extends AbstractAdapter PercentAdapter.php:13
PercentAdapter::__iconizeStatic()
public static function __iconizeStatic(): ?arrayPercentAdapter::getType()
public static function getType(): stringPercentAdapter::getOptions()
public function getOptions(): arrayPercentAdapter::resolve()
public function resolve(mixed $value): mixedPercentAdapter::__construct()
public function __construct(string $label = "", ?string $code = null, int $epsilon = 4, int $scale = 2)PercentAdapter::getPrecision()
public function getPrecision(): intPercentAdapter::setPrecision()
public function setPrecision(int $epsilon)PercentAdapter::getScale()
public function getScale(): intPercentAdapter::setScale()
public function setScale(int $scale)ScalarAdapter class
class ScalarAdapter extends AbstractAdapter ScalarAdapter.php:13
ScalarAdapter::__iconizeStatic()
public static function __iconizeStatic(): ?arrayScalarAdapter::getType()
public static function getType(): stringScalarAdapter::getOptions()
public function getOptions(): arrayScalarAdapter::resolve()
public function resolve(mixed $value): mixedScalarAdapter::__construct()
public function __construct(string $label = "", ?string $code = null, ?int $unit = null, ?int $minimum = null, ?int $maximum = null)ScalarAdapter::getUnit()
public function getUnit(): ?intScalarAdapter::setUnit()
public function setUnit(?int $unit)ScalarAdapter::getMinimum()
public function getMinimum(): ?intScalarAdapter::setMinimum()
public function setMinimum(?int $minimum)ScalarAdapter::getMaximum()
public function getMaximum(): ?intScalarAdapter::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(): ?arrayScoreAdapter::getType()
public static function getType(): stringScoreAdapter::getOptions()
public function getOptions(): arrayScoreAdapter::resolve()
public function resolve(mixed $value): mixedScoreAdapter::supports()
public function supports(mixed $value): boolScoreAdapter::compliesWith()
public function compliesWith(mixed $value, mixed $subject): boolScoreAdapter::getOperation()
public function getOperation()ScoreAdapter::setOperation()
public function setOperation($operation): selfTextAdapter class
class TextAdapter extends AbstractAdapter TextAdapter.php:13
TextAdapter::__iconizeStatic()
public static function __iconizeStatic(): ?arrayTextAdapter::getType()
public static function getType(): stringTextAdapter::getOptions()
public function getOptions(): arrayTextAdapter::resolve()
public function resolve(mixed $value): mixedTextAdapter::getLength()
public function getLength(): ?intTextAdapter::setLength()
public function setLength(?int $length)TextareaAdapter class
class TextareaAdapter extends AbstractAdapter TextareaAdapter.php:13
TextareaAdapter::__iconizeStatic()
public static function __iconizeStatic(): ?arrayTextareaAdapter::getType()
public static function getType(): stringTextareaAdapter::getOptions()
public function getOptions(): arrayTextareaAdapter::resolve()
public function resolve(mixed $value): mixedBase\Entity\Layout\Attribute\Adapter\Common
AbstractActionAdapter class
abstract class AbstractActionAdapter extends AbstractAdapter implements ActionAdapterInterface AbstractActionAdapter.php:11
AbstractActionAdapter::__iconizeStatic()
public static function __iconizeStatic(): ?arrayAbstractActionAdapter::apply()
public function apply(mixed $value, mixed $subject): mixedAbstractAdapter class
abstract class AbstractAdapter implements AttributeAdapterInterface, AutocompleteInterface, TranslatableInterface, IconizeInterface AbstractAdapter.php:22
AbstractAdapter::__iconize()
public function __iconize(): ?arrayAbstractAdapter::__iconizeStatic()
public static function __iconizeStatic(): ?arrayAbstractAdapter::__toString()
public function __toString()AbstractAdapter::__autocomplete()
public function __autocomplete(): ?stringAbstractAdapter::__autocompleteData()
public function __autocompleteData(): arrayAbstractAdapter::__construct()
public function __construct(string $label = "", ?string $code = null)AbstractAdapter::getId()
public function getId(): ?intAbstractAdapter::getAttributes()
public function getAttributes(): CollectionAbstractAdapter::addAttribute()
public function addAttribute(AttributeInterface $attribute): selfAbstractAdapter::removeAttribute()
public function removeAttribute(AttributeInterface $attribute): selfAbstractAdapter::getCode()
public function getCode(): ?stringAbstractAdapter::setCode()
public function setCode(?string $code): selfAbstractAdapter::getIcon()
public function getIcon(): ?stringAbstractAdapter::setIcon()
public function setIcon(?string $icon): staticAbstractAdapterIntl class
class AbstractAdapterIntl implements TranslationInterface AbstractAdapterIntl.php:10
AbstractAdapterIntl::getLabel()
public function getLabel(): ?stringAbstractAdapterIntl::setLabel()
public function setLabel(?string $label): staticAbstractAdapterIntl::getHelp()
public function getHelp(): ?stringAbstractAdapterIntl::setHelp()
public function setHelp(?string $help): staticAbstractRuleAdapter class
abstract class AbstractRuleAdapter extends AbstractAdapter implements RuleAdapterInterface AbstractRuleAdapter.php:12
AbstractRuleAdapter::__iconizeStatic()
public static function __iconizeStatic(): ?arrayAbstractRuleAdapter::compliesWith()
public function compliesWith(mixed $value, mixed $subject): boolAbstractScopeAdapter class
abstract class AbstractScopeAdapter extends AbstractAdapter implements ScopeAdapterInterface AbstractScopeAdapter.php:12
AbstractScopeAdapter::__iconizeStatic()
public static function __iconizeStatic(): ?arrayAbstractScopeAdapter::contains()
public function contains(mixed $value, mixed $subject): boolActionAdapterInterface interface
interface ActionAdapterInterface extends AttributeAdapterInterface ActionAdapterInterface.php:5
ActionAdapterInterface::apply()
public function apply(mixed $value, mixed $subject): mixedAttributeAdapterInterface interface
interface AttributeAdapterInterface AttributeAdapterInterface.php:5
AttributeAdapterInterface::getType()
public static function getType(): stringAttributeAdapterInterface::getOptions()
public function getOptions(): arrayAttributeAdapterInterface::resolve()
public function resolve(mixed $value): mixedRuleAdapterInterface interface
interface RuleAdapterInterface extends AttributeAdapterInterface RuleAdapterInterface.php:5
RuleAdapterInterface::supports()
public function supports(mixed $value): boolRuleAdapterInterface::compliesWith()
public function compliesWith(mixed $value, mixed $subject): boolScopeAdapterInterface interface
interface ScopeAdapterInterface extends AttributeAdapterInterface ScopeAdapterInterface.php:5
ScopeAdapterInterface::supports()
public function supports(mixed $value): boolScopeAdapterInterface::contains()
public function contains(mixed $value, mixed $subject): boolBase\Entity\Layout\Attribute\Common
AbstractAction class
abstract class AbstractAction extends AbstractAttribute implements ActionInterface AbstractAction.php:13
AbstractAction::__iconizeStatic()
public static function __iconizeStatic(): ?arrayAbstractAction::apply()
public function apply(mixed $subject): mixedAbstractAction::getValue()
public function getValue()AbstractAction::setValue()
public function setValue($value): staticAbstractAction::getClass()
public function getClass(): ?stringAbstractAction::setClass()
public function setClass(?string $class): staticAbstractAttribute class
abstract class AbstractAttribute implements IconizeInterface, AttributeInterface AbstractAttribute.php:13
AbstractAttribute::__iconize()
public function __iconize(): ?arrayAbstractAttribute::__iconizeStatic()
public static function __iconizeStatic(): ?arrayAbstractAttribute::__toString()
public function __toString()AbstractAttribute::__construct()
public function __construct(AbstractAdapter $adapter)AbstractAttribute::getId()
public function getId(): ?intAbstractAttribute::getAdapter()
public function getAdapter(): ?AbstractAdapterAbstractAttribute::setAdapter()
public function setAdapter(?AbstractAdapter $adapter): selfAbstractAttribute::getCode()
public function getCode(): ?stringAbstractAttribute::getType()
public function getType(): ?stringAbstractAttribute::getOptions()
public function getOptions(): arrayAbstractRule class
abstract class AbstractRule extends AbstractAttribute implements RuleInterface AbstractRule.php:12
AbstractRule::__iconizeStatic()
public static function __iconizeStatic(): ?arrayAbstractRule::compliesWith()
public function compliesWith(mixed $subject): boolAbstractRule::getValue()
public function getValue()AbstractRule::setValue()
public function setValue($value)AbstractRule::getClass()
public function getClass(): ?stringAbstractRule::setClass()
public function setClass(?string $class)AbstractScope class
abstract class AbstractScope extends AbstractAttribute implements ScopeInterface AbstractScope.php:12
AbstractScope::__iconizeStatic()
public static function __iconizeStatic(): ?arrayAbstractScope::contains()
public function contains(mixed $subject): boolAbstractScope::getValue()
public function getValue()AbstractScope::setValue()
public function setValue($value)AbstractScope::getClass()
public function getClass(): ?stringAbstractScope::setClass()
public function setClass(?string $class)ActionInterface interface
interface ActionInterface extends AttributeInterface ActionInterface.php:5
ActionInterface::apply()
public function apply(mixed $subject): mixedAttributeInterface interface
interface AttributeInterface AttributeInterface.php:7
AttributeInterface::get()
public function get(?string $locale = null): mixedAttributeInterface::set()
public function set(...$args): selfAttributeInterface::resolve()
public function resolve(?string $locale = null): mixedAttributeInterface::getAdapter()
public function getAdapter()AttributeInterface::setAdapter()
public function setAdapter(?AbstractAdapter $adapter): selfAttributeInterface::getCode()
public function getCode(): ?stringAttributeInterface::getType()
public function getType(): ?stringAttributeInterface::getOptions()
public function getOptions(): arrayRuleInterface interface
interface RuleInterface extends AttributeInterface RuleInterface.php:5
RuleInterface::compliesWith()
public function compliesWith(mixed $subject): boolScopeInterface interface
interface ScopeInterface extends AttributeInterface ScopeInterface.php:5
ScopeInterface::contains()
public function contains(mixed $subject): boolBase\Entity\Layout\Widget
Attachment class
class Attachment extends Widget implements IconizeInterface, LinkableInterface Attachment.php:21
Attachment::__iconize()
public function __iconize(): ?arrayAttachment::__iconizeStatic()
public static function __iconizeStatic(): ?arrayAttachment::__toLink()
public function __toLink(array $routeParameters = [], int $referenceType = Link::ABSOLUTE_PATH): ?stringAttachment::__toString()
public function __toString()Attachment::getSlug()
public function getSlug(): ?stringAttachment::setSlug()
public function setSlug(string $slug): selfAttachment::getDownload()
public function getDownload()- Throws
Exception
Attachment::getDownloadFile()
public function getDownloadFile()- Throws
FilesystemException
Attachment::setDownload()
public function setDownload($file)Link class
class Link extends Widget implements IconizeInterface, LinkableInterface Link.php:15
Link::__iconize()
public function __iconize(): ?arrayLink::__iconizeStatic()
public static function __iconizeStatic(): ?arrayLink::__toLink()
public function __toLink(array $routeParameters = [], int $referenceType = \Base\Contract\Link::ABSOLUTE_PATH): ?stringLink::__toString()
public function __toString()Link::__construct()
public function __construct(?Hyperlink $hyperlink = null)Link::getHyperlink()
public function getHyperlink(): ?HyperlinkLink::setHyperlink()
public function setHyperlink(Hyperlink $hyperlink)LinkIntl class
class LinkIntl extends WidgetIntl LinkIntl.php:9
LinkIntl::getTitle()
public function getTitle(): ?stringPage class
class Page extends Widget implements IconizeInterface, LinkableInterface Page.php:19
Page::__iconize()
public function __iconize(): ?arrayPage::__iconizeStatic()
public static function __iconizeStatic(): ?arrayPage::__toLink()
public function __toLink(array $routeParameters = [], int $referenceType = Link::ABSOLUTE_PATH): ?stringPage::__toString()
public function __toString()Page::__construct()
public function __construct(?string $title = null, ?string $slug = null)Page::getSlug()
public function getSlug(): ?stringPage::setSlug()
public function setSlug(?string $slug): selfPage::getBook()
public function getBook(): ?BookPage::setBook()
public function setBook(?Book $book): selfRoute class
class Route extends Widget implements IconizeInterface, LinkableInterface Route.php:17
Route::__iconize()
public function __iconize(): ?arrayRoute::__iconizeStatic()
public static function __iconizeStatic(): ?arrayRoute::__toLink()
public function __toLink(array $routeParameters = [], int $referenceType = Link::ABSOLUTE_PATH): ?stringRoute::__toString()
public function __toString()Route::__construct()
public function __construct(?string $title = null, ?string $routeName = null, array $routeParameters = [])Route::getRouteName()
public function getRouteName(): ?stringRoute::setRouteName()
public function setRouteName(?string $routeName): selfRoute::getRouteParameters()
public function getRouteParameters(): ?arrayRoute::setRouteParameters()
public function setRouteParameters(?array $routeParameters): selfRoute::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(): ?stringThe 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(): ?stringRoute::generate()
public function generate(int $referenceType = Link::ABSOLUTE_PATH): ?stringIts 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(): ?arraySlot::__iconizeStatic()
public static function __iconizeStatic(): ?arraySlot::__toString()
public function __toString()Slot::__construct()
public function __construct(string $path, ?string $label = null, ?string $help = null)Slot::getPath()
public function getPath(): stringSlot::setPath()
public function setPath(string $path): selfSlot::getWidget()
public function getWidget(): ?WidgetSlot::setWidget()
public function setWidget(?Widget $widget): selfSlotIntl class
class SlotIntl extends WidgetIntl SlotIntl.php:10
SlotIntl::getLabel()
public function getLabel(): ?stringSlotIntl::setLabel()
public function setLabel(?string $label): selfSlotIntl::getHelp()
public function getHelp(): ?stringSlotIntl::setHelp()
public function setHelp(?string $help): selfBase\Entity\Layout\Widget\Set
Book class
class Book extends Widget implements IconizeInterface, SetInterface Book.php:18
Book::__iconize()
public function __iconize(): ?arrayBook::__iconizeStatic()
public static function __iconizeStatic(): ?arrayBook::__construct()
public function __construct(?string $title = null, array $pages = [])Book::getPages()
public function getPages(): CollectionBook::addPage()
public function addPage(Page $page): selfBook::removePage()
public function removePage(Page $page): selfLinkset class
class Linkset extends Widget implements IconizeInterface, SetInterface Linkset.php:19
Linkset::__iconize()
public function __iconize(): ?arrayLinkset::__iconizeStatic()
public static function __iconizeStatic(): ?arrayLinkset::__construct()
public function __construct(?string $title = null, array $hyperlinks = [])Linkset::getHyperlinks()
public function getHyperlinks(): CollectionLinkset::addHyperlink()
public function addHyperlink(Hyperlink $hyperlink): selfLinkset::removeHyperlink()
public function removeHyperlink(Hyperlink $hyperlink): selfMenu class
class Menu extends Widget implements IconizeInterface, SetInterface Menu.php:18
Menu::__iconize()
public function __iconize(): ?arrayMenu::__iconizeStatic()
public static function __iconizeStatic(): ?arrayMenu::__construct()
public function __construct(?string $title = null)Menu::getItems()
public function getItems(): CollectionMenu::addItem()
public function addItem(Widget $item): selfMenu::removeItem()
public function removeItem(Widget $item): selfNetwork class
class Network extends Widget implements IconizeInterface, SetInterface Network.php:19
Network::__iconize()
public function __iconize(): ?arrayNetwork::__iconizeStatic()
public static function __iconizeStatic(): ?arrayNetwork::__construct()
public function __construct(?string $title = null, array $routes = [])Network::getRoutes()
public function getRoutes(): CollectionNetwork::addRoute()
public function addRoute(Route $route): selfNetwork::removeRoute()
public function removeRoute(Route $route): selfPaperclip class
class Paperclip extends Widget implements IconizeInterface Paperclip.php:19
Paperclip::__iconize()
public function __iconize(): ?arrayPaperclip::__iconizeStatic()
public static function __iconizeStatic(): ?arrayPaperclip::__construct()
public function __construct(?string $title = null, array $attachments = [])Paperclip::getAttachments()
public function getAttachments(): CollectionPaperclip::addAttachment()
public function addAttachment(Attachment $attachment): selfPaperclip::removeAttachment()
public function removeAttachment(Attachment $attachment): selfSetInterface 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(): ?intAbstractEnvelope::getSubjectClass()
public function getSubjectClass(): stringAbstractEnvelope::getSubjectId()
public function getSubjectId(): stringAbstractEnvelope::getTitle()
public function getTitle(): stringAbstractEnvelope::getGateway()
public function getGateway(): stringAbstractEnvelope::getReference()
public function getReference(): ?stringAbstractEnvelope::getStatus()
public function getStatus(): stringAbstractEnvelope::isCompleted()
public function isCompleted(): boolAbstractEnvelope::isOver()
public function isOver(): boolOver: nothing more will happen to it (completed, declined, expired, canceled).
AbstractEnvelope::getEnvelope()
public function getEnvelope(): arrayAbstractEnvelope::getSigners()
public function getSigners(): arrayAbstractEnvelope::update()
public function update(?string $reference, string $status, array $envelope, ?\DateTimeImmutable $completedAt = null): staticWhere it stands, as the gateway answered.
AbstractEnvelope::getSignedFile()
public function getSignedFile(): ?stringAbstractEnvelope::getEvidenceFile()
public function getEvidenceFile(): ?stringAbstractEnvelope::keep()
public function keep(?string $signedFile, ?string $evidenceFile): staticThe signed document and its evidence, kept: their paths in the private storage.
AbstractEnvelope::getCreatedAt()
public function getCreatedAt(): \DateTimeImmutableAbstractEnvelope::getUpdatedAt()
public function getUpdatedAt(): \DateTimeImmutableAbstractEnvelope::getCompletedAt()
public function getCompletedAt(): ?\DateTimeImmutableBase\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 = trueSet 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(): stringComment::getId()
public function getId(): ?intComment::getThread()
public function getThread(): ?ThreadComment::setThread()
public function setThread(?Thread $thread): staticComment::getAuthor()
public function getAuthor(): ?UserComment::setAuthor()
public function setAuthor(?User $author): staticComment::getName()
public function getName(): ?stringComment::setName()
public function setName(?string $name): staticComment::getEmail()
public function getEmail(): ?stringComment::setEmail()
public function setEmail(?string $email): staticComment::getWebsite()
public function getWebsite(): ?stringComment::setWebsite()
public function setWebsite(?string $website): staticComment::getContent()
public function getContent(): ?stringComment::setContent()
public function setContent(?string $content): staticComment::getParent()
public function getParent(): ?CommentComment::setParent()
public function setParent(?Comment $parent): staticComment::getReplies()
public function getReplies(): CollectionComment::getVisibleReplies()
public function getVisibleReplies(): array- Returns
the replies online
Comment::getState()
public function getState(): CommentStateComment::setState()
public function setState(CommentState $state): staticComment::isVisible()
public function isVisible(): boolComment::isPending()
public function isPending(): boolComment::approve()
public function approve(): staticComment::markAsSpam()
public function markAsSpam(): staticComment::trash()
public function trash(): staticComment::getSpamScore()
public function getSpamScore(): ?intComment::getIp()
public function getIp(): ?stringComment::setIp()
public function setIp(?string $ip): staticComment::getUserAgent()
public function getUserAgent(): ?stringComment::setUserAgent()
public function setUserAgent(?string $userAgent): staticComment::getCreatedAt()
public function getCreatedAt(): ?\DateTimeInterfaceComment::setCreatedAt()
public function setCreatedAt(?\DateTimeInterface $createdAt): staticComment::getModeratedAt()
public function getModeratedAt(): ?\DateTimeInterfaceComment::getDisplayName()
public function getDisplayName(): stringHow the comment is signed: the account's name, or the name typed.
Comment::getSpamBlameable()
public function getSpamBlameable(): ?UserComment::getSpamText()
public function getSpamText(): ?stringComment::getSpamDate()
public function getSpamDate(): \DateTimeComment::getSpamCallback()
public function getSpamCallback(int $score): voidThe 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(): ?arrayLike::__iconizeStatic()
public static function __iconizeStatic(): ?arrayLike::__construct()
public function __construct(?User $user = null)Like::getId()
public function getId(): ?intLike::getUser()
public function getUser(): ?UserLike::setUser()
public function setUser(?User $user): selfLike::getThread()
public function getThread(): ?ThreadLike::setThread()
public function setThread(?Thread $thread): selfLike::getIcon()
public function getIcon(): ?stringLike::setIcon()
public function setIcon(string $icon): selfMention class
class Mention implements IconizeInterface Mention.php:16
Mention::__iconize()
public function __iconize(): ?arrayMention::__iconizeStatic()
public static function __iconizeStatic(): ?arrayMention::__construct()
public function __construct(?User $mentionee = null, ?Thread $thread = null)Mention::getId()
public function getId(): ?intMention::getMentionee()
public function getMentionee(): ?UserMention::setMentionee()
public function setMentionee(?User $mentionee): selfMention::getMentioners()
public function getMentioners(): CollectionMention::addMentioner()
public function addMentioner(User $mentioner): selfMention::removeMentioner()
public function removeMentioner(User $mentioner): selfMention::getThread()
public function getThread(): ?ThreadMention::setThread()
public function setThread(?Thread $thread): selfTag class
class Tag implements TranslatableInterface, IconizeInterface, AliasInterface Tag.php:26
Tag::__toString()
public function __toString()Tag::__iconize()
public function __iconize(): ?arrayTag::__iconizeStatic()
public static function __iconizeStatic(): ?arrayTag::__construct()
public function __construct(?string $label = null, ?string $slug = null)Tag::getId()
public function getId(): ?intTag::getSlug()
public function getSlug(): ?stringTag::setSlug()
public function setSlug(?string $slug): selfTag::getColor()
public function getColor(): ?stringTag::setColor()
public function setColor(?string $color): selfTag::getPriority()
public function getPriority(): ?intTag::setPriority()
public function setPriority(?int $priority): selfTag::getIcon()
public function getIcon()- Throws
Exception
Tag::getIconFile()
public function getIconFile()- Throws
FilesystemException
Tag::setIcon()
public function setIcon($icon)Tag::getThreads()
public function getThreads(): CollectionTag::addThread()
public function addThread(Thread $thread): selfTag::removeThread()
public function removeThread(Thread $thread): selfTagIntl class
class TagIntl implements TranslationInterface TagIntl.php:11
TagIntl::getLabel()
public function getLabel(): ?stringTagIntl::setLabel()
public function setLabel(?string $label): selfTagIntl::getKeywords()
public function getKeywords(): arrayTagIntl::setKeywords()
public function setKeywords(array $keywords)TagIntl::getDescription()
public function getDescription(): ?stringTagIntl::setDescription()
public function setDescription(?string $description): selfTaxon class
class Taxon implements TranslatableInterface, IconizeInterface, GraphInterface Taxon.php:26
Taxon::__iconize()
public function __iconize(): ?arrayTaxon::__iconizeStatic()
public static function __iconizeStatic(): ?arrayTaxon::__toString()
public function __toString()Taxon::__construct()
public function __construct(?string $label = null, ?string $slug = null)Taxon::validateLabel()
public function validateLabel(ExecutionContextInterface $context): voidA 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(): ?intTaxon::getSlug()
public function getSlug(): ?stringTaxon::setSlug()
public function setSlug(?string $slug): selfTaxon::getIcon()
public function getIcon()- Throws
Exception
Taxon::getIconFile()
public function getIconFile()- Throws
FilesystemException
Taxon::setIcon()
public function setIcon($icon)Taxon::getParent()
public function getParent(): ?selfTaxon::setParent()
public function setParent(?self $parent): selfTaxon::removeParent()
public function removeParent(self $parent): selfTaxon::getChildren()
public function getChildren(): CollectionTaxon::addChild()
public function addChild(self $child): selfTaxon::removeChild()
public function removeChild(self $child): selfTaxon::getThreads()
public function getThreads(): CollectionTaxon::addThread()
public function addThread(Thread $thread): selfTaxon::removeThread()
public function removeThread(Thread $thread): selfTaxon::getConnexes()
public function getConnexes(): CollectionTaxon::addConnex()
public function addConnex(self $connex): selfTaxon::removeConnex()
public function removeConnex(self $connex): selfTaxonIntl class
class TaxonIntl implements TranslationInterface TaxonIntl.php:11
TaxonIntl::getLabel()
public function getLabel(): ?stringTaxonIntl::setLabel()
public function setLabel(?string $label): selfTaxonIntl::getDescription()
public function getDescription(): ?stringTaxonIntl::setDescription()
public function setDescription(?string $description): selfTaxonIntl::getKeywords()
public function getKeywords(): arrayTaxonIntl::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): ?stringAddress::__toString()
public function __toString()Address::__iconize()
public function __iconize(): ?arrayAddress::__iconizeStatic()
public static function __iconizeStatic(): ?arrayAddress::__construct()
public function __construct(?string $name = null, ?Address $address = null)Address::getId()
public function getId()Address::getName()
public function getName(): ?stringAddress::setName()
public function setName(string $name): selfAddress::getCountry()
public function getCountry(): ?stringAddress::setCountry()
public function setCountry(string $country): selfAddress::getState()
public function getState(): ?stringAddress::setState()
public function setState(?string $state): selfAddress::getCity()
public function getCity(): ?stringAddress::setCity()
public function setCity(string $city): selfAddress::getZipCode()
public function getZipCode(): ?stringAddress::setZipCode()
public function setZipCode(string $zipCode): selfAddress::getStreetAddress()
public function getStreetAddress(): ?stringAddress::setStreetAddress()
public function setStreetAddress(?string $streetAddress): selfAddress::getAffix()
public function getAffix(): ?stringAddress::setAffix()
public function setAffix(?string $affix): selfAddress::getPhone()
public function getPhone(): ?stringAddress::setPhone()
public function setPhone(?string $phone): selfAddress::getFax()
public function getFax(): ?stringAddress::setFax()
public function setFax(?string $fax): selfAddress::getAdditional()
public function getAdditional(): ?stringAddress::setAdditional()
public function setAdditional(?string $additional): selfAddress::getUser()
public function getUser(): ?UserAddress::setUser()
public function setUser(?User $user): selfComplaint 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(): ?arrayComplaint::__iconizeStatic()
public static function __iconizeStatic(): ?arrayComplaint::getId()
public function getId(): ?intComplaint::getCreatedAt()
public function getCreatedAt(): DateTimeComplaint::setCreatedAt()
public function setCreatedAt(DateTime $at): selfComplaint::getComplainant()
public function getComplainant(): ?UserComplaint::setComplainant()
public function setComplainant(?User $user): selfComplaint::getComplainantName()
public function getComplainantName(): stringComplaint::setComplainantName()
public function setComplainantName(string $name): selfComplaint::getTarget()
public function getTarget(): ?UserComplaint::setTarget()
public function setTarget(?User $user): selfComplaint::getTargetName()
public function getTargetName(): ?stringComplaint::setTargetName()
public function setTargetName(?string $name): selfComplaint::getTargetStatus()
public function getTargetStatus(): ?stringComplaint::setTargetStatus()
public function setTargetStatus(?string $status): selfComplaint::getSource()
public function getSource(): ?stringComplaint::setSource()
public function setSource(?string $source): selfComplaint::getLocation()
public function getLocation(): ?stringComplaint::setLocation()
public function setLocation(?string $location): selfComplaint::getLocationName()
public function getLocationName(): ?stringComplaint::setLocationName()
public function setLocationName(?string $name): selfComplaint::getText()
public function getText(): stringComplaint::setText()
public function setText(string $text): selfComplaint::getContext()
public function getContext(): arrayComplaint::setContext()
public function setContext(array $context): selfComplaint::getStatus()
public function getStatus(): stringComplaint::getStatusLabel()
public function getStatusLabel(): stringComplaint::isOpen()
public function isOpen(): boolComplaint::getHandledBy()
public function getHandledBy(): ?UserComplaint::getHandledAt()
public function getHandledAt(): ?DateTimeComplaint::getAnswer()
public function getAnswer(): ?stringComplaint::getSanction()
public function getSanction(): ?SanctionComplaint::setSanction()
public function setSanction(?Sanction $sanction): selfComplaint::settle()
public function settle(string $status, ?User $by, ?string $answer = null): selfHandled or dismissed (or opened again), by whom, with what answer.
Connection class
class Connection implements IconizeInterface Connection.php:14
Connection::__iconize()
public function __iconize(): ?arrayConnection::__iconizeStatic()
public static function __iconizeStatic(): ?arrayConnection::__construct()
public function __construct(string $uniqid = "", ?User $user = null)Connection::getId()
public function getId(): ?intConnection::getUniqid()
public function getUniqid(): ?stringConnection::setUniqid()
public function setUniqid(string $uniqid): selfConnection::getUser()
public function getUser(): ?UserConnection::setUser()
public function setUser(?User $user): selfConnection::getImpersonator()
public function getImpersonator(): ?UserConnection::setImpersonator()
public function setImpersonator(?User $impersonator): selfConnection::getLoginAttempts()
public function getLoginAttempts(): ?stringConnection::setLoginAttempts()
public function setLoginAttempts(int $loginAttempts): selfConnection::getState()
public function getState(): ?stringConnection::isValid()
public function isValid(): boolConnection::markAsSucceeded()
public function markAsSucceeded(): selfConnection::markAsFailed()
public function markAsFailed(): selfConnection::markAsLogout()
public function markAsLogout(): selfConnection::getIpList()
public function getIpList(): ?arrayConnection::addIp()
public function addIp(string $ip): selfConnection::removeIp()
public function removeIp(string $ip): selfConnection::getAgent()
public function getAgent(): ?stringConnection::setAgent()
public function setAgent(string $agent): selfConnection::getAgentLabel()
public function getAgentLabel(): ?stringA 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(): ?stringConnection::setLocale()
public function setLocale(string $locale): selfConnection::getTimezones()
public function getTimezones(): ?arrayConnection::addTimezone()
public function addTimezone(?string $timezone): selfConnection::removeTimezone()
public function removeTimezone(?string $timezone): selfConnection::getHostnames()
public function getHostnames(): ?arrayConnection::addHostname()
public function addHostname(?string $hostname): selfConnection::removeHostname()
public function removeHostname(?string $hostname): selfConnection::getCreatedAt()
public function getCreatedAt(): ?\DateTimeInterfaceConnection::setCreatedAt()
public function setCreatedAt(\DateTimeInterface $createdAt): selfConnection::getUpdatedAt()
public function getUpdatedAt(): ?\DateTimeInterfaceConnection::setUpdatedAt()
public function setUpdatedAt(\DateTimeInterface $updatedAt): selfGroup 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(): ?arrayGroup::__iconizeStatic()
public static function __iconizeStatic(): ?arrayGroup::__toString()
public function __toString(): stringIts 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(): ?intGroup::getRoles()
public function getRoles(): arrayGroup::setRoles()
public function setRoles(array $roles): selfGroup::getName()
public function getName(): ?stringGroup::setName()
public function setName(string $name): selfGroup::getMembers()
public function getMembers(): CollectionGroup::addMember()
public function addMember(User $member): selfGroup::removeMember()
public function removeMember(User $member): selfGroup::getCreatedAt()
public function getCreatedAt(): ?DateTimeInterfaceGroup::setCreatedAt()
public function setCreatedAt(DateTimeInterface $createdAt): selfGroup::getPermissions()
public function getPermissions(): CollectionGroup::addPermission()
public function addPermission(Permission $permission): selfGroup::removePermission()
public function removePermission(Permission $permission): selfGroup::getRules()
public function getRules(): CollectionGroup::addRule()
public function addRule(GroupRule $rule): selfGroup::removeRule()
public function removeRule(GroupRule $rule): selfGroup::getScopes()
public function getScopes(): CollectionGroup::addScope()
public function addScope(GroupScope $scope): selfGroup::removeScope()
public function removeScope(GroupScope $scope): selfGroup::getActions()
public function getActions(): CollectionGroup::addAction()
public function addAction(GroupAction $action): selfGroup::removeAction()
public function removeAction(GroupAction $action): selfGroup::awardsFor()
public function awardsFor(mixed $subject): arrayEverything 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): boolWhether 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(): intWhat 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(): CollectionGroup::addPenalty()
public function addPenalty(Penalty $penalty): selfGroup::removePenalty()
public function removePenalty(Penalty $penalty): selfGroup::getColor()
public function getColor(): ?stringGroup::setColor()
public function setColor(?string $color): selfGroup::getIcon()
public function getIcon(): ?stringGroup::setIcon()
public function setIcon(?string $icon): selfIdentity 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(): ?intIdentity::getUser()
public function getUser(): ?UserIdentity::getProvider()
public function getProvider(): stringIdentity::getSubject()
public function getSubject(): stringIdentity::getEmail()
public function getEmail(): ?stringIdentity::isEmailVerified()
public function isEmailVerified(): boolIdentity::getCreatedAt()
public function getCreatedAt(): ?DateTimeInterfaceIdentity::getLastUsedAt()
public function getLastUsedAt(): ?DateTimeInterfaceIdentity::markUsed()
public function markUsed(DateTimeInterface $at): selfInvitation 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(): ?intInvitation::__toString()
public function __toString(): stringInvitation::getEmail()
public function getEmail(): stringInvitation::getName()
public function getName(): stringInvitation::getTokenHash()
public function getTokenHash(): stringInvitation::getCreatedAt()
public function getCreatedAt(): \DateTimeImmutableInvitation::getExpiresAt()
public function getExpiresAt(): \DateTimeImmutableInvitation::getAcceptedAt()
public function getAcceptedAt(): ?\DateTimeImmutableInvitation::accept()
public function accept(): staticInvitation::getInvitedBy()
public function getInvitedBy(): ?UserInvitation::setInvitedBy()
public function setInvitedBy(?User $invitedBy): staticInvitation::isOpen()
public function isOpen(): boolNotification 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): SymfonyNotificationNotification::__iconize()
public function __iconize(): ?arrayNotification::__iconizeStatic()
public static function __iconizeStatic(): ?arrayNotification::getId()
public function getId(): ?intNotification::getUser()
public function getUser(): ?UserNotification::setUser()
public function setUser(?User $user): selfNotification::getAttachments()
public function getAttachments(): arrayNotification::addAttachment()
public function addAttachment(\SplFileInfo $attachment): selfAn 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): selfNotification::getRecipients()
public function getRecipients(): arrayNotification::addRecipient()
public function addRecipient(RecipientInterface $recipient): selfNotification::removeRecipient()
public function removeRecipient(RecipientInterface $recipient): selfNotification::getChannels()
public function getChannels(?RecipientInterface $recipient = null): arrayNotification::setChannels()
public function setChannels(array $channels): selfNotification::getImportance()
public function getImportance(): stringNotification::setImportance()
public function setImportance(?string $importance): selfNotification::getSubject()
public function getSubject(): stringNotification::setSubject()
public function setSubject(string $subject): selfNotification::getContent()
public function getContent(): stringNotification::setContent()
public function setContent(string $content): selfNotification::getUrl()
public function getUrl(): ?stringNotification::setUrl()
public function setUrl(?string $url): selfNotification::getTargetClass()
public function getTargetClass(): ?stringNotification::getTargetId()
public function getTargetId(): ?stringNotification::setTarget()
public function setTarget(?object $entity): selfNotification::getTitle()
public function getTitle(): stringNotification::setTitle()
public function setTitle(string $title): selfNotification::isRead()
public function isRead(): boolNotification::setIsRead()
public function setIsRead(bool $isRead): selfNotification::markAsRead()
public function markAsRead(bool $isRead)Notification::markAsReadIfNeeded()
public function markAsReadIfNeeded(array $channels = [])Notification::getSentAt()
public function getSentAt(): ?DateTimeInterfaceNotification::setSentAt()
public function setSentAt(?DateTimeInterface $sentAt): selfNotification::getBacktrace()
public function getBacktrace(): stringNotification::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): selfNotification::addContext()
public function addContext(array $context = []): selfNotification::setContext()
public function setContext(array $context): selfNotification::removeContextKey()
public function removeContextKey(string $key): selfNotification::getHtmlTemplate()
public function getHtmlTemplate()Notification::setHtmlTemplate()
public function setHtmlTemplate(?string $htmlTemplate, array $htmlParameters = [])Notification::getHtmlParameters()
public function getHtmlParameters(): arrayNotification::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(): stringThe 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): ?SmsMessageNotification::asEmailMessage()
public function asEmailMessage(EmailRecipientInterface $recipient, ?string $transport = null): ?EmailMessageThe 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): ?ChatMessagePasskey 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 $publicKeyCredentialIdThe 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 $credentialPublicKeyThe public key, COSE-encoded bytes.
public string $userHandleThe account's handle (its id, as text).
public int $counter = 0The signature counter the authenticator last gave.
public ?array $otherUI = nullpublic ?bool $backupEligible = nullpublic ?bool $backupStatus = nullpublic ?bool $uvInitialized = null
Passkey::getId()
public function getId(): ?intPasskey::getUser()
public function getUser(): ?UserPasskey::setUser()
public function setUser(?User $user): selfPasskey::getLabel()
public function getLabel(): ?stringPasskey::setLabel()
public function setLabel(?string $label): selfPasskey::getCreatedAt()
public function getCreatedAt(): ?DateTimeInterfacePasskey::getLastUsedAt()
public function getLastUsedAt(): ?DateTimeInterfacePasskey::touch()
public function touch(): selfPasskey::createFromCredentialRecord()
public static function createFromCredentialRecord(\Webauthn\CredentialRecord $record, User $user, ?string $label = null): selfA 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(): ?arrayPenalty::__iconizeStatic()
public static function __iconizeStatic(): ?arrayPenalty::__toString()
public function __toString(): stringPenalty::getId()
public function getId(): ?intPenalty::getFormType()
public function getFormType(): ?stringPenalty::getType()
public function getType(): ?stringPenalty::setType()
public function setType(string $type): selfPenalty::getWeight()
public function getWeight(): intPenalty::setWeight()
public function setWeight(int $weight): selfPenalty::getDurationDays()
public function getDurationDays(): ?intPenalty::setDurationDays()
public function setDurationDays(?int $durationDays): selfPenalty::expiresFrom()
public function expiresFrom(?DateTimeInterface $from = null): ?DateTimeWhen 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(): ?stringPenalty::setExtra()
public function setExtra(string $extra): selfPenalty::getCreatedAt()
public function getCreatedAt(): ?DateTimeInterfacePenalty::setCreatedAt()
public function setCreatedAt(DateTimeInterface $createdAt): selfPenalty::getSanctions()
public function getSanctions(): CollectionPenalty::getGid()
public function getGid(): CollectionPenalty::addGid()
public function addGid(Group $gid): selfPenalty::removeGid()
public function removeGid(Group $gid): selfPermission class
class Permission implements IconizeInterface Permission.php:14
Permission::__iconize()
public function __iconize(): ?arrayPermission::__iconizeStatic()
public static function __iconizeStatic(): ?arrayPermission::__construct()
public function __construct()Permission::getId()
public function getId(): ?intPermission::__toString()
public function __toString(): stringIts tag, wherever a permission is shown as one line (a group's permissions picker).
Permission::getTag()
public function getTag(): ?stringPermission::setTag()
public function setTag(string $tag): selfPermission::getDescription()
public function getDescription(): ?stringPermission::setDescription()
public function setDescription(string $description): selfPermission::getEmpoweredRoles()
public function getEmpoweredRoles(): arrayPermission::setEmpoweredRoles()
public function setEmpoweredRoles(array $empower): selfPermission::getUid()
public function getUid(): CollectionPermission::addUid()
public function addUid(User $uid): selfPermission::removeUid()
public function removeUid(User $uid): selfPermission::getGid()
public function getGid(): CollectionPermission::addGid()
public function addGid(Group $gid): selfPermission::removeGid()
public function removeGid(Group $gid): selfPermission::getIcon()
public function getIcon(): ?stringPermission::setIcon()
public function setIcon(?string $icon): selfPushSubscription 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(): ?intPushSubscription::getUser()
public function getUser(): ?UserPushSubscription::setUser()
public function setUser(?User $user): selfPushSubscription::getEndpoint()
public function getEndpoint(): stringPushSubscription::setEndpoint()
public function setEndpoint(string $endpoint): selfPushSubscription::getEndpointHash()
public function getEndpointHash(): stringPushSubscription::getP256dh()
public function getP256dh(): stringPushSubscription::setP256dh()
public function setP256dh(string $p256dh): selfPushSubscription::getAuth()
public function getAuth(): stringPushSubscription::setAuth()
public function setAuth(string $auth): selfPushSubscription::getUserAgent()
public function getUserAgent(): ?stringPushSubscription::setUserAgent()
public function setUserAgent(?string $userAgent): selfPushSubscription::getCreatedAt()
public function getCreatedAt(): DateTimeInterfacePushSubscription::getLastUsedAt()
public function getLastUsedAt(): ?DateTimeInterfacePushSubscription::touch()
public function touch(): selfPushSubscription::__construct()
public function __construct()PushSubscription::toArray()
public function toArray(): arrayThe 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(): ?arraySanction::__iconizeStatic()
public static function __iconizeStatic(): ?arraySanction::getId()
public function getId(): ?intSanction::getUser()
public function getUser(): ?UserSanction::setUser()
public function setUser(?User $user): selfSanction::getPenalty()
public function getPenalty(): ?PenaltySanction::setPenalty()
public function setPenalty(?Penalty $penalty): selfSanction::getModerator()
public function getModerator(): ?UserSanction::setModerator()
public function setModerator(?User $moderator): selfSanction::getReason()
public function getReason(): ?stringSanction::setReason()
public function setReason(?string $reason): selfSanction::getCreatedAt()
public function getCreatedAt(): ?DateTimeInterfaceSanction::getExpiresAt()
public function getExpiresAt(): ?DateTimeInterfaceSanction::setExpiresAt()
public function setExpiresAt(?DateTimeInterface $expiresAt): selfSanction::getLiftedAt()
public function getLiftedAt(): ?DateTimeInterfaceSanction::lift()
public function lift(?DateTimeInterface $at = null): selfSanction::isActive()
public function isActive(?DateTimeInterface $at = null): boolSanction::getWeight()
public function getWeight(?DateTimeInterface $at = null): intWhat 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(): ?arrayToken::__iconizeStatic()
public static function __iconizeStatic(): ?arrayToken::__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(): ?intToken::getUser()
public function getUser(): ?UserToken::setUser()
public function setUser(?User $user): selfToken::getName()
public function getName(): ?stringToken::setName()
public function setName(string $name): selfToken::get()
public function get(): ?stringToken::getValue()
public function getValue(): ?stringToken::setValue()
public function setValue(string $value): selfKeeps 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): selfToken::getCreatedAt()
public function getCreatedAt(): ?DateTimeInterfaceToken::setCreatedAt()
public function setCreatedAt(DateTimeInterface $createdAt): selfToken::getExpireAt()
public function getExpireAt(): ?DateTimeInterfaceToken::setExpireAt()
public function setExpireAt(DateTimeInterface $expireAt): selfToken::getExpiry()
public function getExpiry(): ?DateTimeInterfaceToken::setExpiry()
public function setExpiry(DateTimeInterface $expireAt): selfToken::isValid()
public function isValid(): boolToken::getElapsedTime()
public function getElapsedTime(): intToken::getLifetime()
public function getLifetime(): intToken::getRemainingTime()
public function getRemainingTime(): intToken::getRemainingTimeStr()
public function getRemainingTimeStr(): stringToken::getAllowAt()
public function getAllowAt(): ?DateTimeInterfaceToken::setAllowAt()
public function setAllowAt(DateTimeInterface $allowAt): selfToken::hasVeto()
public function hasVeto(): boolToken::getThrottleTime()
public function getThrottleTime(): intToken::getThrottleTimeStr()
public function getThrottleTimeStr(): stringToken::setThrottleTime()
public function setThrottleTime(DateTimeInterface $allowAt): selfToken::isThrottled()
public function isThrottled(): boolToken::revoke()
public function revoke(): selfToken::isRevoked()
public function isRevoked(): boolToken::markAsRevoked()
public function markAsRevoked(): selfToken::isLogginable()
public function isLogginable(): boolToken::markAsLogginable()
public function markAsLogginable(bool $isLogginable = true): selfBase\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): mixedGroupAction::set()
public function set(...$args): selfGroupAction::resolve()
public function resolve(?string $locale = null): mixedGroupAction::getGroup()
public function getGroup(): ?GroupGroupAction::setGroup()
public function setGroup(?Group $group): selfGroupRule 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): mixedGroupRule::set()
public function set(...$args): selfGroupRule::resolve()
public function resolve(?string $locale = null): mixedGroupRule::getGroup()
public function getGroup(): ?GroupGroupRule::setGroup()
public function setGroup(?Group $group): selfGroupScope 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): mixedGroupScope::set()
public function set(...$args): selfGroupScope::resolve()
public function resolve(?string $locale = null): mixedGroupScope::getGroup()
public function getGroup(): ?GroupGroupScope::setGroup()
public function setGroup(?Group $group): selfBase\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 yesso 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(): ?arrayGrantPermissionAdapter::getType()
public static function getType(): stringGrantPermissionAdapter::getOptions()
public function getOptions(): arrayGrantPermissionAdapter::resolve()
public function resolve(mixed $value): mixedGrantPermissionAdapter::apply()
public function apply(mixed $value, mixed $subject): mixedGrantRoleAdapter 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(): ?arrayGrantRoleAdapter::getType()
public static function getType(): stringGrantRoleAdapter::getOptions()
public function getOptions(): arrayGrantRoleAdapter::resolve()
public function resolve(mixed $value): mixedGrantRoleAdapter::apply()
public function apply(mixed $value, mixed $subject): mixedBase\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(): ?arrayGroupAdapter::getType()
public static function getType(): stringGroupAdapter::getOptions()
public function getOptions(): arrayGroupAdapter::resolve()
public function resolve(mixed $value): mixedGroupAdapter::supports()
public function supports(mixed $value): boolGroupAdapter::contains()
public function contains(mixed $value, mixed $subject): boolUserAdapter 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(): ?arrayUserAdapter::getType()
public static function getType(): stringUserAdapter::getOptions()
public function getOptions(): arrayUserAdapter::resolve()
public function resolve(mixed $value): mixedUserAdapter::supports()
public function supports(mixed $value): boolUserAdapter::contains()
public function contains(mixed $value, mixed $subject): boolBase\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(): intIts number in Annex II (1 to 14), as menus often print it.
Allergen::trans()
public function trans(): stringThe translation key of its name, in the "enums" domain.
Allergen::fromList()
public static function fromList(iterable $values): arrayStored 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(): boolConnectionState 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(): ?arrayConnectionState::__iconizeStatic()
public static function __iconizeStatic(): ?arrayEntityAction 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(): ?arrayEntityAction::__iconizeStatic()
public static function __iconizeStatic(): ?arrayLogLevel 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(): ?arrayLogLevel::__iconizeStatic()
public static function __iconizeStatic(): ?arrayOperation 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(): ?arrayOperation::__iconizeStatic()
public static function __iconizeStatic(): ?arraySpamApi 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
SpamApi::__iconize()
public function __iconize(): ?arraySpamApi::__iconizeStatic()
public static function __iconizeStatic(): ?arraySpamScore 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(): ?arraySpamScore::__iconizeStatic()
public static function __iconizeStatic(): ?arraySpamScore::__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(): ?arrayThreadState::__iconizeStatic()
public static function __iconizeStatic(): ?arrayThreadState::__colorize()
public function __colorize(): ?arrayThreadState::__colorizeStatic()
public static function __colorizeStatic(): ?arrayUploadState 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(): ?arrayUploadState::__iconizeStatic()
public static function __iconizeStatic(): ?arrayUserGender 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(): ?arrayUserGender::__iconizeStatic()
public static function __iconizeStatic(): ?arrayUserRole 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(): ?arrayUserRole::__iconizeStatic()
public static function __iconizeStatic(): ?arrayUserRole::getCrudController()
public static function getCrudController(string $role): ?stringThe 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(): ?arrayUserState::__iconizeStatic()
public static function __iconizeStatic(): ?arrayWorkflowState 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(): ?arrayWorkflowState::__iconizeStatic()
public static function __iconizeStatic(): ?arrayBase\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(): ?arrayQuadrant::__iconizeStatic()
public static function __iconizeStatic(): ?arrayQuadrant::getDefault()
public static function getDefault()Quadrant::getTheta()
public static function getTheta()Quadrant::getRotation()
public static function getRotation(string $quadrant): ?floatQuadrant::getRotations()
public static function getRotations(): arrayQuadrant::getPosition()
public static function getPosition(string $quadrant): stringQuadrant::getPositions()
public static function getPositions(): arrayQuadrant16 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(): ?arrayQuadrant16::__iconizeStatic()
public static function __iconizeStatic(): ?arrayQuadrant16::getTheta()
public static function getTheta()Quadrant16::getRotation()
public static function getRotation(string $quadrant): ?floatQuadrant16::getRotations()
public static function getRotations(): arrayQuadrant16::getPosition()
public static function getPosition(string $quadrant): stringQuadrant16::getPositions()
public static function getPositions(): arrayQuadrant32 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(): ?arrayQuadrant32::__iconizeStatic()
public static function __iconizeStatic(): ?arrayQuadrant32::getTheta()
public static function getTheta()Quadrant32::getRotation()
public static function getRotation(string $quadrant): ?floatQuadrant32::getRotations()
public static function getRotations(): arrayQuadrant32::getPosition()
public static function getPosition(string $quadrant): stringQuadrant32::getPositions()
public static function getPositions(): arrayQuadrant8 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(): ?arrayQuadrant8::__iconizeStatic()
public static function __iconizeStatic(): ?arrayQuadrant8::getTheta()
public static function getTheta()Quadrant8::getRotation()
public static function getRotation(string $quadrant): ?floatQuadrant8::getRotations()
public static function getRotations(): arrayQuadrant8::getPosition()
public static function getPosition(string $quadrant): stringQuadrant8::getPositions()
public static function getPositions(): arrayBase\Enum\SystemOfUnits
BritishImperialUnits class
class BritishImperialUnits extends EnumType implements IconizeInterface BritishImperialUnits.php:8
BritishImperialUnits::__iconize()
public function __iconize(): ?arrayBritishImperialUnits::__iconizeStatic()
public static function __iconizeStatic(): ?arrayStandardBaseUnits 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(): ?arrayStandardBaseUnits::__iconizeStatic()
public static function __iconizeStatic(): ?arrayStandardBaseUnits::__colorize()
public function __colorize(): ?arrayStandardBaseUnits::__colorizeStatic()
public static function __colorizeStatic(): ?arrayStandardBaseUnits::getBaseUnit()
public static function getBaseUnit(string $name): ?stringStandardBaseUnits::getBaseUnits()
public static function getBaseUnits(): ?arrayStandardBaseUnits::getBaseUnitName()
public static function getBaseUnitName(string $name): ?stringStandardBaseUnits::getBaseUnitNames()
public static function getBaseUnitNames(): ?arrayStandardBaseUnits::getConstant()
public static function getConstant(string $name): ?stringStandardBaseUnits::getConstants()
public static function getConstants(): ?arrayStandardBaseUnits::getConstantSymbol()
public static function getConstantSymbol(string $name): ?stringStandardBaseUnits::getConstantSymbols()
public static function getConstantSymbols(): ?arrayStandardBaseUnits::getConstantUnit()
public static function getConstantUnit(string $name): ?stringStandardBaseUnits::getConstantUnits()
public static function getConstantUnits(): ?arrayStandardBaseUnits::getConstantName()
public static function getConstantName(string $name): ?stringStandardBaseUnits::getConstantNames()
public static function getConstantNames(): ?arrayStandardUnits class
class StandardUnits extends StandardBaseUnits implements IconizeInterface StandardUnits.php:7
StandardUnits::__iconize()
public function __iconize(): ?arrayStandardUnits::__iconizeStatic()
public static function __iconizeStatic(): ?arrayUnitedStatesCustomaryUnits class
class UnitedStatesCustomaryUnits extends EnumType implements IconizeInterface UnitedStatesCustomaryUnits.php:8
UnitedStatesCustomaryUnits::__iconize()
public function __iconize(): ?arrayUnitedStatesCustomaryUnits::__iconizeStatic()
public static function __iconizeStatic(): ?arrayBase\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(): EnvelopeSignatureEvent::getSubject()
public function getSubject(): ?objectThe entity it is about, when it still exists.
SignatureEvent::getSigner()
public function getSigner(): ?stringFor 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(): SitemapperInterfaceSitemapEvent::getHostname()
public function getHostname(): stringBase\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): selfUploaderAmbiguityException 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 $vaultpublic 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): selfArrayField::useAssociativeKeys()
public function useAssociativeKeys(bool $use_associative = true): selfArrayField::setPlaceholder()
public function setPlaceholder(array $placeholder): selfArrayField::setPatternFieldName()
public function setPatternFieldName(string $fieldName): selfArrayField::allowAdd()
public function allowAdd(bool $allow = true): selfArrayField::allowDelete()
public function allowDelete(bool $allow = true): selfArrayField::setEntryIsComplex()
public function setEntryIsComplex(bool $isComplex): selfSet 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): selfArrayField::setEntryOptions()
public function setEntryOptions(array $entryOptions): selfArrayField::renderExpanded()
public function renderExpanded(bool $renderExpanded = true): selfArrayField::setLength()
public function setLength(string|int $length): selfAssociationField 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 = 0const SHOW_NAME_ONLY = 1const SHOW_ICON_ONLY = 2const SHOW_ALL = 3const 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): selfAssociationField::embed()
public function embed(bool $embed = true): selfThe 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(): selfAssociationField::autoload()
public function autoload($autoload = true): selfAssociationField::setFields()
public function setFields(array $fields): selfAssociationField::allowAdd()
public function allowAdd(bool $allowAdd = true): selfAssociationField::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)$modeone 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): selfAssociationField::showEmbedded()
public function showEmbedded($embed = true): selfAssociationField::showEmbeddedRow()
public function showEmbeddedRow($embed = true): selfAssociationField::showCollapsed()
public function showCollapsed($collapsed = true): selfAssociationFileField 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 = 0const SHOW_NAME_ONLY = 1const SHOW_ICON_ONLY = 2const SHOW_ALL = 3
AssociationFileField::new()
public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): selfAssociationFileField::setClass()
public function setClass(?string $class = null)AssociationFileField::renderAsText()
public function renderAsText(): selfAssociationFileField::renderAsCount()
public function renderAsCount(): selfAssociationFileField::renderAsImage()
public function renderAsImage(): selfAssociationFileField::renderAsAvatar()
public function renderAsAvatar(): selfAssociationFileField::setFieldFile()
public function setFieldFile(string $fieldFile): selfAssociationFileField::setFieldData()
public function setFieldData(array|callable $data): selfAssociationFileField::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 = 0const SHOW_NAME_ONLY = 1const SHOW_ICON_ONLY = 2const SHOW_ALL = 3const OPTION_FILTER_CODE = 'filter_code'
AttributeField::new()
public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): selfAttributeField::setFilterCode()
public function setFilterCode(?string $filter = null): selfAttributeField::setClass()
public function setClass(?string $class = null)AttributeField::allowDelete()
public function allowDelete(bool $allowDelete = true): selfAttributeField::allowAdd()
public function allowAdd(bool $allowAdd = true): selfAttributeField::setFields()
public function setFields(array $fields): selfAttributeField::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): selfAvatarField 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): selfBooleanField 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): selfBooleanField::renderAsSwitch()
public function renderAsSwitch(bool $isASwitch = true): selfBooleanField::showInline()
public function showInline(bool $inline = true): selfBooleanField::withConfirmation()
public function withConfirmation(bool $onCheck = true, bool $onUncheck = true): selfCodeField 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): staticCodeField::setAlphabet()
public function setAlphabet(string $alphabet): static'alnum' (default), 'digits' or 'alpha'.
CodeField::setUppercase()
public function setUppercase(bool $uppercase = true): staticCollectionField 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): selfCollectionField::allowAdd()
public function allowAdd(bool $allow = true): selfCollectionField::allowObject()
public function allowObject(bool $allow = true): selfCollectionField::allowDelete()
public function allowDelete(bool $allow = true): selfCollectionField::setEntryType()
public function setEntryType(string $entryType): selfCollectionField::setEntryOptions()
public function setEntryOptions(array $entryOptions): selfCollectionField::setEntryLabel()
public function setEntryLabel($entryLabel): selfCollectionField::renderExpanded()
public function renderExpanded(bool $renderExpanded = true): selfCollectionField::setLength()
public function setLength(int $length): selfCollectionField::showEmbedded()
public function showEmbedded($embed = true): selfCollectionField::showEmbeddedRow()
public function showEmbeddedRow($embed = true): selfCollectionField::showCollapsed()
public function showCollapsed($collapsed = true): selfColorField class
final class ColorField implements FieldInterface ColorField.php:9
ColorField::new()
public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): selfColorPickerField class
final class ColorPickerField implements FieldInterface ColorPickerField.php:8
ColorPickerField::new()
public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): selfCountryField class
class CountryField extends SelectField implements FieldInterface CountryField.php:8
CountryField::new()
public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): selfCropperField 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): selfCurrencyField class
class CurrencyField extends SelectField implements FieldInterface CurrencyField.php:7
CurrencyField::new()
public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): selfDateField class
class DateField implements FieldInterface DateField.php:7
DateField::new()
public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): selfDateTimeField class
class DateTimeField implements FieldInterface DateTimeField.php:7
DateTimeField::new()
public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): selfDateTimePickerField 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): selfDateTimePickerField::setDebug()
public function setDebug(bool $debug = true): selfDateTimePickerField::setTimezone()
public function setTimezone(string $timezoneId): self$timezoneIdA valid PHP timezone ID
DateTimePickerField::setFormat()
public function setFormat(string $dateFormatOrPattern, string $timeFormat = self::FORMAT_NONE): self$dateFormatOrPatternA format name ('none', 'short', 'medium', 'long', 'full') or a valid ICU Datetime Pattern (see http://userguide.icu-project.org/formatparse/datetime)
$timeFormatA format name ('none', 'short', 'medium', 'long', 'full')
DateTimePickerField::renderAsNativeWidget()
public function renderAsNativeWidget(bool $asNative = true): selfUses native HTML5 widgets when rendering this field in forms.
DateTimePickerField::renderAsChoice()
public function renderAsChoice(bool $asChoice = true): selfUses <select> lists when rendering this field in forms.
DateTimePickerField::renderAsText()
public function renderAsText(bool $asText = true): selfUses <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): selfDiscriminatorField::showColumnLabel()
public function showColumnLabel(bool $show = true): selfDiscriminatorField::showInline()
public function showInline(bool $inline = true): selfDiscriminatorField::showLeaf()
public function showLeaf(bool $show = true): selfEditorField class
final class EditorField implements FieldInterface EditorField.php:8
EditorField::new()
public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): selfEmailField 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): selfEmailField::new()
public static function new(string $propertyName, $label = null): selfEmailField::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): selfFieldDescriptor 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(): stringFieldDescriptor::setUniqueId()
public function setUniqueId(string $uniqueId): staticFieldDescriptor::getFieldFqcn()
public function getFieldFqcn(): ?stringFieldDescriptor::setFieldFqcn()
public function setFieldFqcn(?string $fieldFqcn): staticFieldDescriptor::getProperty()
public function getProperty(): ?stringFieldDescriptor::setProperty()
public function setProperty(?string $propertyName): staticFieldDescriptor::getPropertySuffix()
public function getPropertySuffix(): ?stringFieldDescriptor::setPropertySuffix()
public function setPropertySuffix(?string $propertyNameSuffix): staticFieldDescriptor::getPropertyWithSuffix()
public function getPropertyWithSuffix(): ?stringFieldDescriptor::getValue()
public function getValue(): mixedFieldDescriptor::setValue()
public function setValue(mixed $value): staticFieldDescriptor::getFormattedValue()
public function getFormattedValue(): mixedFieldDescriptor::setFormattedValue()
public function setFormattedValue(mixed $formattedValue): staticFieldDescriptor::getFormatValueCallable()
public function getFormatValueCallable(): ?callableFieldDescriptor::setFormatValueCallable()
public function setFormatValueCallable(?callable $callable): staticFieldDescriptor::getLabel()
public function getLabel(): TranslatableInterface|string|bool|nullFieldDescriptor::setLabel()
public function setLabel(TranslatableInterface|string|bool|null $label): staticFieldDescriptor::getHelp()
public function getHelp(): TranslatableInterface|string|nullFieldDescriptor::setHelp()
public function setHelp(TranslatableInterface|string|null $help): staticFieldDescriptor::getTranslationParameters()
public function getTranslationParameters(): arrayFieldDescriptor::setTranslationParameters()
public function setTranslationParameters(array $translationParameters): staticFieldDescriptor::getKind()
public function getKind(): ?stringThe 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): staticFieldDescriptor::getFormType()
public function getFormType(): ?stringThe 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): staticNames 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(): boolWhether the Symfony type was named directly rather than by the kind.
FieldDescriptor::getConstraints()
public function getConstraints(): arrayThe 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): staticFieldDescriptor::addConstraint()
public function addConstraint(object ...$constraints): staticFieldDescriptor::getOptions()
public function getOptions(): arrayThe field's options as plain data: what getFormTypeOptions() answers, by its neutral name.
FieldDescriptor::getOption()
public function getOption(string $optionName, mixed $default = null): mixedOne option, "." paths supported ("attr.autofocus").
FieldDescriptor::getFormTypeOptions()
public function getFormTypeOptions(): arrayFieldDescriptor::setFormTypeOptions()
public function setFormTypeOptions(array $formTypeOptions): staticFieldDescriptor::getFormTypeOption()
public function getFormTypeOption(string $optionName, mixed $default = null): mixedOption names support "." paths, e.g. "attr.autofocus".
FieldDescriptor::setFormTypeOption()
public function setFormTypeOption(string $optionName, mixed $optionValue): staticFieldDescriptor::setFormTypeOptionIfNotSet()
public function setFormTypeOptionIfNotSet(string $optionName, mixed $optionValue): staticFieldDescriptor::isSortable()
public function isSortable(): ?boolFieldDescriptor::setSortable()
public function setSortable(?bool $sortable): staticFieldDescriptor::isVirtual()
public function isVirtual(): ?boolFieldDescriptor::setVirtual()
public function setVirtual(?bool $virtual): staticFieldDescriptor::isDisabled()
public function isDisabled(): ?boolFieldDescriptor::setDisabled()
public function setDisabled(?bool $disabled): staticFieldDescriptor::isRequired()
public function isRequired(): ?boolFieldDescriptor::setRequired()
public function setRequired(?bool $required): staticFieldDescriptor::getEmptyData()
public function getEmptyData(): mixedFieldDescriptor::setEmptyData()
public function setEmptyData(mixed $emptyData): staticFieldDescriptor::getPermission()
public function getPermission(): string|Expression|nullFieldDescriptor::setPermission()
public function setPermission(string|Expression|null $permission): staticFieldDescriptor::getTextAlign()
public function getTextAlign(): ?stringFieldDescriptor::setTextAlign()
public function setTextAlign(?string $textAlign): staticFieldDescriptor::getCssClass()
public function getCssClass(): stringFieldDescriptor::setCssClass()
public function setCssClass(string $cssClass): staticFieldDescriptor::addCssClass()
public function addCssClass(string $cssClass): staticFieldDescriptor::getHtmlAttributes()
public function getHtmlAttributes(): arrayFieldDescriptor::setHtmlAttributes()
public function setHtmlAttributes(array $htmlAttributes): staticFieldDescriptor::setHtmlAttribute()
public function setHtmlAttribute(string $attributeName, mixed $attributeValue): staticFieldDescriptor::getColumns()
public function getColumns(): null|int|stringFieldDescriptor::setColumns()
public function setColumns(null|int|string $columns): staticFieldDescriptor::getDefaultColumns()
public function getDefaultColumns(): null|int|stringFieldDescriptor::setDefaultColumns()
public function setDefaultColumns(null|int|string $defaultColumns): staticFieldDescriptor::getTemplateName()
public function getTemplateName(): ?stringFieldDescriptor::setTemplateName()
public function setTemplateName(?string $templateName): staticFieldDescriptor::getTemplatePath()
public function getTemplatePath(): ?stringFieldDescriptor::setTemplatePath()
public function setTemplatePath(?string $templatePath): staticFieldDescriptor::getFormThemes()
public function getFormThemes(): arrayFieldDescriptor::addFormTheme()
public function addFormTheme(string ...$formThemePaths): staticFieldDescriptor::getCssAssets()
public function getCssAssets(): arrayFieldDescriptor::addCssAsset()
public function addCssAsset(string $asset): staticFieldDescriptor::getJsAssets()
public function getJsAssets(): arrayFieldDescriptor::addJsAsset()
public function addJsAsset(string $asset): staticFieldDescriptor::getWebpackEncoreEntries()
public function getWebpackEncoreEntries(): arrayFieldDescriptor::addWebpackEncoreEntry()
public function addWebpackEncoreEntry(string $entry): staticFieldDescriptor::getHeadContents()
public function getHeadContents(): arrayFieldDescriptor::addHtmlContentToHead()
public function addHtmlContentToHead(string $content): staticFieldDescriptor::getBodyContents()
public function getBodyContents(): arrayFieldDescriptor::addHtmlContentToBody()
public function addHtmlContentToBody(string $content): staticFieldDescriptor::getCustomOptions()
public function getCustomOptions(): arrayFieldDescriptor::setCustomOptions()
public function setCustomOptions(array $customOptions): staticFieldDescriptor::getCustomOption()
public function getCustomOption(string $optionName, mixed $default = null): mixedFieldDescriptor::setCustomOption()
public function setCustomOption(string $optionName, mixed $optionValue): staticFieldDescriptor::getDoctrineMetadata()
public function getDoctrineMetadata(): arrayFieldDescriptor::setDoctrineMetadata()
public function setDoctrineMetadata(array $doctrineMetadata): staticFieldDescriptor::getDisplayedOn()
public function getDisplayedOn(): arrayFieldDescriptor::setDisplayedOn()
public function setDisplayedOn(array $pages): staticFieldDescriptor::displayOn()
public function displayOn(string ...$pages): staticFieldDescriptor::hideOn()
public function hideOn(string ...$pages): staticFieldDescriptor::isDisplayedOn()
public function isDisplayedOn(string $page): boolFieldInterface 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(): FieldDescriptorFieldInterface::__clone()
public function __clone(): voidFieldTrait 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(): voidFieldTrait::setFieldFqcn()
public function setFieldFqcn(string $fieldFqcn): staticFieldTrait::setProperty()
public function setProperty(string $propertyName): staticFieldTrait::setPropertySuffix()
public function setPropertySuffix(string $propertyNameSuffix): staticFieldTrait::setLabel()
public function setLabel(TranslatableInterface|string|bool|null $label): staticFieldTrait::setValue()
public function setValue(mixed $value): staticFieldTrait::setFormattedValue()
public function setFormattedValue(mixed $value): staticFieldTrait::formatValue()
public function formatValue(?callable $callable): staticFieldTrait::setVirtual()
public function setVirtual(bool $isVirtual): staticFieldTrait::setDisabled()
public function setDisabled(bool $disabled = true): staticFieldTrait::setRequired()
public function setRequired(bool $isRequired): staticFieldTrait::setEmptyData()
public function setEmptyData(mixed $emptyData = null): staticFieldTrait::setKind()
public function setKind(string $kind): staticThe field's neutral kind (Kind::TEXT, Kind::CHOICE...): what every host renders it by.
FieldTrait::addConstraint()
public function addConstraint(object ...$constraints): staticConstraints the field's value is checked against, beside those of the data's class.
FieldTrait::setOptions()
public function setOptions(array $options): staticOptions as plain data, "." paths supported: setFormTypeOptions() by its neutral name.
FieldTrait::setOption()
public function setOption(string $optionName, mixed $optionValue): staticFieldTrait::setFormType()
public function setFormType(string $formTypeFqcn): staticNames a Symfony form type directly (Symfony only, the escape hatch): a field no kind describes. Prefer setKind().
FieldTrait::setFormTypeOptions()
public function setFormTypeOptions(array $options): staticFieldTrait::setFormTypeOption()
public function setFormTypeOption(string $optionName, mixed $optionValue): staticFieldTrait::setFormTypeOptionIfNotSet()
public function setFormTypeOptionIfNotSet(string $optionName, mixed $optionValue): staticFieldTrait::setHtmlAttribute()
public function setHtmlAttribute(string $attributeName, mixed $attributeValue): staticFieldTrait::setHtmlAttributes()
public function setHtmlAttributes(array $attributes): staticFieldTrait::setSortable()
public function setSortable(bool $isSortable): staticFieldTrait::setPermission()
public function setPermission(string|Expression $permission): staticFieldTrait::setTextAlign()
public function setTextAlign(string $textAlign): static$textAlignone of "left", "center", "right"
FieldTrait::setHelp()
public function setHelp(TranslatableInterface|string $help): staticFieldTrait::addCssClass()
public function addCssClass(string $cssClass): staticFieldTrait::setCssClass()
public function setCssClass(string $cssClass): staticFieldTrait::setTranslationParameters()
public function setTranslationParameters(array $parameters): staticFieldTrait::setTemplateName()
public function setTemplateName(string $name): staticFieldTrait::setTemplatePath()
public function setTemplatePath(string $path): staticFieldTrait::addFormTheme()
public function addFormTheme(string ...$formThemePaths): staticFieldTrait::addWebpackEncoreEntries()
public function addWebpackEncoreEntries(string ...$entryNames): staticFieldTrait::addCssFiles()
public function addCssFiles(string ...$paths): staticFieldTrait::addJsFiles()
public function addJsFiles(string ...$paths): staticFieldTrait::addHtmlContentsToHead()
public function addHtmlContentsToHead(string ...$contents): staticFieldTrait::addHtmlContentsToBody()
public function addHtmlContentsToBody(string ...$contents): staticFieldTrait::setCustomOption()
public function setCustomOption(string $optionName, mixed $optionValue): staticFieldTrait::setCustomOptions()
public function setCustomOptions(array $options): staticFieldTrait::hideOnDetail()
public function hideOnDetail(): staticFieldTrait::hideOnForm()
public function hideOnForm(): staticFieldTrait::hideWhenCreating()
public function hideWhenCreating(): staticFieldTrait::hideWhenUpdating()
public function hideWhenUpdating(): staticFieldTrait::hideOnIndex()
public function hideOnIndex(): staticFieldTrait::showOnIndex()
public function showOnIndex(bool $show = true): staticFieldTrait::showOnDetail()
public function showOnDetail(bool $show = true): staticFieldTrait::onlyOnDetail()
public function onlyOnDetail(): staticFieldTrait::onlyOnForms()
public function onlyOnForms(): staticFieldTrait::onlyOnIndex()
public function onlyOnIndex(): staticFieldTrait::onlyWhenCreating()
public function onlyWhenCreating(): staticFieldTrait::onlyWhenUpdating()
public function onlyWhenUpdating(): staticFieldTrait::setColumns()
public function setColumns(int|string $cols): static$colsan integer 1..12 or a responsive spec like "col-md-6 col-xxl-3"
FieldTrait::setDefaultColumns()
public function setDefaultColumns(int|string $cols): staticFieldTrait::getAsDto()
public function getAsDto(): FieldDescriptorFieldValueResolver 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)$identifierFieldsnull = DEFAULT_IDENTIFIER_FIELDS
$identifierFieldsByEntityper-class overrides
$lowercaseIdentifierssee $this->lowercaseIdentifiers
$doctrinesays which identifier fields are columns, see isStoredField()
FieldValueResolver::resolve()
public function resolve(FieldDescriptor $descriptor, object $entity): FieldDescriptorFieldValueResolver::formatValue()
public function formatValue(mixed $value): mixedDefault 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): mixedThe 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): arrayThe 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): arrayEvery 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|nullThe 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): ?stringThe 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): ?stringThe 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): arrayFileField 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): selfFileField::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): selfFileField::downloadable()
public function downloadable(bool $allowDownload = true): selfFileField::noReupload()
public function noReupload(bool $noReupload = true): selfFileField::setPreferredDownloadName()
public function setPreferredDownloadName(string $targetName): selfFileField::setMultipleFiles()
public function setMultipleFiles(bool $multipleFiles = true): selfFileField::renderAsText()
public function renderAsText(): selfFileField::renderAsCount()
public function renderAsCount(): selfFileField::renderAsImage()
public function renderAsImage(): selfFileField::showFirst()
public function showFirst(bool $show = true): selfForexField 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): selfGenderField class
class GenderField extends SelectField implements FieldInterface GenderField.php:8
GenderField::new()
public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): selfIconField 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): selfIconField::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_ADD_LINK = 'addLink'const OPTION_IMPERSONATE = 'impersonate'
IdField::new()
public static function new(string $propertyName = 'id', TranslatableInterface|string|bool|null $label = null): selfIdField::setMaxLength()
public function setMaxLength(int $length): selfSet maxLength to -1 to define an unlimited max length.
IdField::enableImpersonation()
public function enableImpersonation()IdField::disableImpersonation()
public function disableImpersonation()IdField::enableLink()
public function enableLink()IdField::disableLink()
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): selfImageField::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): selfKind 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 SEARCH = 'search'const SLUG = 'slug'const CODE = 'code'const EDITOR = 'editor'const WYSIWYG = 'wysiwyg'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
typeis the kind of the two inputs, first_options and second_options theirs.const TRANSLATION = 'translation'const DISCRIMINATOR = 'discriminator'const SUBMIT = 'submit'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(): arrayEvery 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): ?stringThe HTML input type of a kind printed as an input, null for any other widget.
Kind::isChoice()
public static function isChoice(?string $kind): boolKind::isFile()
public static function isFile(?string $kind): boolKinds 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 = []): voidRegisters (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.
$mapkind => type
$aliasestype => kind
Kinds::type()
public static function type(?string $kind, string $host = 'symfony'): ?stringThe 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'): ?stringThe 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): voidDeclares 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): arrayWhat 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): ?stringA kind's declaration on a host; null when it declares none.
Kinds::known()
public static function known(): arrayEvery 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): arrayWhat is wrong with a host's coverage: a kind left undeclared, a declaration without its reason (Coverage::verify()).
Kinds::reset()
public static function reset(): voidForgets 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): selfMoneyField::useSwap()
public function useSwap(bool $swap = true): selfMoneyField::setCurrency()
public function setCurrency(string $currencyCode): selfMoneyField::setCurrencyPropertyPath()
public function setCurrencyPropertyPath(string $propertyPath): selfMoneyField::showCurrencyCode()
public function showCurrencyCode(bool $show = true): selfMoneyField::setCurrencyList()
public function setCurrencyList(array $moneyList = []): selfMoneyField::setNumDecimals()
public function setNumDecimals(int $num): selfMoneyField::setStoredAsCents()
public function setStoredAsCents(bool $asCents = true): selfNumberField 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): selfNumberField::percentage()
public function percentage(int $min, int $max): selfNumberField::setDivisor()
public function setDivisor(float $num): selfNumberField::setThrottle()
public function setThrottle(int $num): selfNumberField::setNumDecimals()
public function setNumDecimals(int $num): selfNumberField::setMinimum()
public function setMinimum(int $num): selfNumberField::setMaximum()
public function setMaximum(int $num): selfNumberField::setSuffix()
public function setSuffix(string $suffix): selfNumberField::setPrefix()
public function setPrefix(int $prefix): selfNumberField::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): selfNumberField::setStoredAsString()
public function setStoredAsString(bool $asString = true): selfPasswordField class
final class PasswordField implements FieldInterface PasswordField.php:7
PasswordField::new()
public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): selfPasswordField::setRevealer()
public function setRevealer(bool $revealer): selfPasswordField::secure()
public function secure(bool $secure = true): selfPasswordField::setRepeater()
public function setRepeater(bool $repeater): selfPasswordField::showInline()
public function showInline(bool $inline = true): selfQuadrantField 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 = 0const SHOW_NAME_ONLY = 1const SHOW_ICON_ONLY = 2const SHOW_ALL = 3
QuadrantField::new()
public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): selfQuadrantField::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): selfRouteField class
class RouteField extends SelectField implements FieldInterface RouteField.php:8
RouteField::new()
public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): selfSelectField class
class SelectField implements FieldInterface SelectField.php:8
const OPTION_CONFIRMATION_MODAL_ON_CHECK = 'confirmationModalOnCheck'const OPTION_CONFIRMATION_MODAL_ON_UNCHECK = 'confirmationModalOnUncheck'const OPTION_CRUD_LINK = 'href'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 = 0const SHOW_NAME_ONLY = 1const SHOW_ICON_ONLY = 2const SHOW_ALL = 3
SelectField::new()
public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): selfSelectField::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)SelectField::allowCrudLink()
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)$modeone 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): selfSlugField 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): selfSlugField::setTargetFieldName()
public function setTargetFieldName(string $fieldName): selfSlugField::setSeparator()
public function setSeparator(string $separator): selfSlugField::keep()
public function keep(string $keep): selfSlugField::uppercase()
public function uppercase(bool $upper = true): selfSlugField::setUnlockConfirmationMessage()
public function setUnlockConfirmationMessage(string $message): selfSlugField::showLeadingHash()
public function showLeadingHash(bool $show = true): selfStateField 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): selfStockField 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): selfStockField::setTargetFieldName()
public function setTargetFieldName(string $fieldName): selfStockField::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): selfStockField::setAllowInfinity()
public function setAllowInfinity(bool $nullable = true)StockField::setRoundingMode()
public function setRoundingMode(int $mode): selfStockField::setStoredAsString()
public function setStoredAsString(bool $asString = true): selfTextField 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'
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): selfTextareaField::setMaxLength()
public function setMaxLength(int $length): selfTextareaField::setNumOfRows()
public function setNumOfRows(int $rows): selfTranslationField class
class TranslationField implements FieldInterface TranslationField.php:9
const OPTION_MAX_LENGTH = 'maxLength'const OPTION_RENDER_AS_HTML = 'renderAsHtml'
TranslationField::new()
public static function new(?string $propertyName = null, TranslatableInterface|string|bool|null $label = null): selfTranslationField::setMaxLength()
public function setMaxLength(int $length): selfTranslationField::autoload()
public function autoload($autoload = true): selfTranslationField::renderAsHtml()
public function renderAsHtml(bool $asHtml = true): selfTranslationField::stripTags()
public function stripTags(bool $stripTags = true): selfTranslationField::setFields()
public function setFields(array $fields): selfTranslationField::showOnIndex()
public function showOnIndex(?string $field = null): selfTranslationField::setRequired()
public function setRequired(bool $isRequired = true)TranslationField::setExcludedFields()
public function setExcludedFields($excludedFields): selfTranslationField::setTranslationClass()
public function setTranslationClass($translationClass): selfTranslationField::setDefaultLocale()
public function setDefaultLocale(string $defaultLocale): selfTranslationField::renderSingleLocale()
public function renderSingleLocale(?string $singleLocale = null): selfVideoField 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): selfWysiwygField 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_RENDER_AS_BOOLEAN = 'renderAsBoolean'
WysiwygField::new()
public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): selfWysiwygField::renderAsBoolean()
public function renderAsBoolean(bool $asBool = true)WysiwygField::shorten()
public function shorten(int $length = 100, int $position = SHORTEN_BACK, string $separator = ' [..] '): selfWysiwygField::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): selfBase\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): arrayAbstractBehaviour::vars()
public function vars(array $options, mixed $shown, string $id): arrayAbstractBehaviour::transform()
public function transform(mixed $data, array $options): mixedAbstractBehaviour::reverse()
public function reverse(mixed $submitted, array $options): mixedAbstractBehaviour::assets()
public function assets(array $options): FieldAssetsAbstractBehaviour::endpoints()
public function endpoints(array $options): arrayAssociation 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): arrayAssociation::collection()
public static function collection(array $options): arrayWhat the collection of several records' forms is given (AssociationType's _collection): its
entries this type, each one record's form (entry()).
$optionsthe association's, its class and multiplicity known
Association::entry()
public static function entry(array $options): arrayAssociation::targetClass()
public static function targetClass(array $options, ?string $ownerClass, string $property): ?stringThe related records' class: the field's, else its association's target.
Association::property()
public static function property(?string $ownerClass, string $property): stringThe 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): boolSeveral records: the field's word, else its association's (FormFactory::guessMultiple()).
Association::fields()
public static function fields(string $class, array $options, ?string $formName = null): arrayOne 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): arrayWhat 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.
$submittedthe
_collectionpart$optionsthe association's, its class known
$fieldsone 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_filerequired,form_typean 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): arrayThe 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): stringThe 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): stringThe upload kind its file is drawn with (Kind::FILE, IMAGE, AVATAR).
@param array<string, mixed> $options
AssociationFile::child()
public static function child(array $options): stringThe 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): stringThe file's path in a related record (entity_file).
@param array<string, mixed> $options
AssociationFile::list()
public static function list(mixed $records): arrayThe related records as a list: the collection's, the record itself, none.
AssociationFile::files()
public static function files(mixed $records, array $options): arrayThe 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): stringEach 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): arrayThe 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|nullWhat 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.
$fileswhat the upload field reads (Upload::reverse()): a file, a name, a list of them
$existingthe records held before
AssociationFile::bind()
public static function bind(object $owner, string $property, array|object|null $records, array $options): voidThe 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.
$recordsrecords() answer
AssociationFile::required()
public static function required(?string $dataClass, string $property): boolWhether 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): ?boolWhether 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): arrayAttribute::classes()
public static function classes(array $options, ?string $guessed = null): arrayThe attribute's class and its adapters', as AttributeType settles them before building its parts.
Attribute::choice()
public static function choice(array $options, ?object $record): arrayIts select of adapters (SelectType's options, as AttributeType gives them).
$optionsthe 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): stringAn attribute's part's name: its adapter's code and its id.
Attribute::translated()
public static function translated(AbstractAttribute $attribute): boolAttribute::value()
public static function value(AbstractAttribute $attribute): FieldDescriptorThe 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): voidWhat 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.
$optionsthe attribute's, its classes known
$chosenthe 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): voidBehaviours::of()
public static function of(?string $kind): ?FieldBehaviourThe behaviour of a kind; null for a plain one.
Behaviours::ofField()
public static function ofField(FieldDescriptor $field): ?FieldBehaviourThe behaviour of a field: its kind's, none when its host type was named directly.
Behaviours::complete()
public static function complete(FieldDescriptor $field): FieldDescriptorA 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(): voidForgets 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): ?arraylabel => 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(): arrayCollection 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
_renderedinput); - 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;
_renderedleft 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): arrayCollection::length()
public static function length(array $options): int|stringCollection::window()
public static function window(array $entries, array $options): arrayThe 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
_renderedinput
Collection::empty()
public static function empty(): stringcollection2_empty: what a page shows of a collection without an entry.
Collection::entries()
public static function entries(mixed $submitted, array $options): arrayWhat 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): arrayA 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): arrayColorPickr::transform()
public function transform(mixed $data, array $options): mixedColorPickr::reverse()
public function reverse(mixed $submitted, array $options): mixedCountrySelect 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): arrayIts 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): arrayThe picker's settings: the given ones over the defaults, key by key.
DateTimePicker::options()
public function options(array $given): arrayDateTimePicker::vars()
public function vars(array $options, mixed $shown, string $id): arrayDateTimePicker::transform()
public function transform(mixed $data, array $options): mixedA date written in the field's format, as Symfony's DateTimeType writes it (IntlDateFormatter).
DateTimePicker::reverse()
public function reverse(mixed $submitted, array $options): mixedWhat 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): arrayEditor::reverse()
public function reverse(mixed $submitted, array $options): mixedAn empty document (no block) is no text.
Editor::endpoints()
public function endpoints(array $options): arrayGuess 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): FieldDescriptorThe 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): arrayIcon::entry()
public function entry(array $entry, array $options): arrayIconType::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): arrayJsColor::transform()
public function transform(mixed $data, array $options): mixedJsColor::reverse()
public function reverse(mixed $submitted, array $options): mixedNumber 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): arrayNumber::transform()
public function transform(mixed $data, array $options): mixedNumber::reverse()
public function reverse(mixed $submitted, array $options): mixedWhat 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): arrayPassword::vars()
public function vars(array $options, mixed $shown, string $id): arrayPassword::reverse()
public function reverse(mixed $submitted, array $options): mixedThe typed password, from its two inputs; refused when they differ.
Password::transform()
public function transform(mixed $data, array $options): mixedA 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$fieldsname => options (a host type's name alone, or [])
- Returns
name => options, with
kindorform_type
RecordFields::descriptor()
public static function descriptor(string $class, string $name, array $field): ?FieldDescriptorOne 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): stringThe 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 = [])$defaultsa kind's own over the select's (the role's enum, the state's)
Select::options()
public function options(array $given): arrayThe 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): arraySelectType'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 = []): arrayselect2's settings, as SelectType hands them to its script
(data-select2-options): the given select2 completed by the options.
$optionsresolved
$multiplewhat the field is, once guessed
$searchthe remote search's address; null without one
$languageselect2's language, fr
$placeholderthe placeholder in the page's words; translated here when null
$entriesthe entries select2 starts with (data)
$selectedthe values chosen
Select::vars()
public function vars(array $options, mixed $shown, string $id): arrayThe 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): arrayOne 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): mixedA 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): arrayThe 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): arraySlug::vars()
public function vars(array $options, mixed $shown, string $id): arraykeep, 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): arrayTranslation 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_optionsapplied (or the field left out where they say display: false); - required(): a field's
requiredgiven 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): arrayThe 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): arrayTranslationType's normalizer: the required languages among those offered.
Translation::locales()
public static function locales(array $options, array $recordLocales): arrayThe 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.
$optionscompleted (options())
$recordLocalesthe 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): ?boolWhether 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.
$optionscompleted (options())
Translation::perLocale()
public static function perLocale(array $fields, array $locales): arrayEach 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.
$fieldsname => options
$localesthe offered languages
- Returns
locale => name => options
Translation::required()
public static function required(array $field, bool $entryRequired, string $locale, array $options): arrayA 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): ?stringThe 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 = []): arrayEach 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).
$optionscompleted (options())
- Returns
locale => name => descriptor
Translation::recordLocales()
public static function recordLocales(mixed $translations): arrayThe 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): arrayA record's translations as each language's values, read by each field's kind.
$fieldslocale => 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): arrayWhat 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).
$submittedlocale => name => raw
$fieldslocale => 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): ?stringThe 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(): boolUpload::options()
public function options(array $given): arrayUpload::endpoints()
public function endpoints(array $options): arrayUpload::vars()
public function vars(array $options, mixed $shown, string $id): arrayWhat 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): mixedWhat 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): ?arrayThe 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).
$optionsthe 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): arrayThe 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(): stringsymfony, laravel: the host's name in Base\Field\Kinds.
Host::render()
public function render(FormDefinition $form, mixed $data): stringThe form's markup, as a page of this host prints it.
Host::submit()
public function submit(FormDefinition $form, array $submitted, mixed $data): OutcomeWhat 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 $datapublic 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 $kindpublic \Closure $fieldpublic mixed $datapublic mixed $shownpublic mixed $submittedpublic mixed $boundpublic mixed $invalidpublic bool $drawnpublic ?string $dataClasspublic string $namepublic 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(): FieldDescriptorSample::submits()
public function submits(): boolSamples 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 = []): \ClosureSuite 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): FormDefinitionSuite::data()
public static function data(Sample $sample): mixedThe 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): mixedA 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 = 1const STATUS_BAD = 0const 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(): stringWhat an editor hands its routes (their data): the visitor's token.
EditorJs::addresses()
public function addresses(): arrayThe five addresses the widget reads (ADDRESSES), with data(); an address is null where the host has no such route.
EditorJs::rooms()
public function rooms(): CollabRoomResolverThe room's routes (autosave, ticket), the collaboration's rooms and tickets.
EditorJs::tickets()
public function tickets(): ?CollabTicketFactoryEditorJs::roomToken()
public function roomToken(string $room): stringThe token of one room (one record's one field), which its autosave and its ticket check.
EditorJs::author()
public function author(): ?arrayThe account signed in, as the collaboration shows it; null for no one.
@return array<string, mixed>|null
EditorJs::picture()
public function picture(string $origin): mixedA 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): ?stringA 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 = []): AnswerThe accounts whose identifier holds the query (@someone), among $fields where given.
$bodythe request's JSON body: query, page
$fieldsthe 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']): AnswerThe 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 = []): AnswerThe 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): AnswerA 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): AnswerA picture fetched from the address the JSON body gives (url), stored as uploadByFile() stores one.
EditorJs::ticket()
public function ticket(array $body): AnswerA 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.
$bodythe request's JSON body: room, token
EditorJs::autosave()
public function autosave(array $body): AnswerOne 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).
$bodythe request's JSON body: fqcn, id, field, locale, value, baseVersion, token or serviceToken and room
EditorJs::who()
public static function who(User $user): arrayAn 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'
Base\Field\Search
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 $statuspublic 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): selfAnswer::refused()
public static function refused(string $reason, int $status = 500): selfExchangeRate 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): JsonRemoteSearch 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): stringWhat a select hands its search (the route's data), as SelectType built it.
$fieldsthe columns the term is compared with
$filtersthe classes the records are instances of; none for every one
RemoteSearch::filters()
public static function filters(array $options): arrayThe 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): AnswerA page of records, or of an enumeration's values.
$querythe request's query string
$bodythe request's body
$repositorythe 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 = []): AnswerA page of an icon adapter's icons.
$providerthe adapter, or its name (fa, bi) among the host's Icons
RemoteSearch::adapter()
public function adapter(string $idOrClass): ?IconAdapterInterfaceThe 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
filekept 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(): stringThe folder the uploads wait in until their form is sent.
Dropzone::data()
public function data(array $settings): stringWhat a dropzone hands its address (the route's data): its settings and the visitor's token.
$settingsDropzone's options (maxFilesize in MB, acceptedFiles...)
Dropzone::store()
public function store(string $data, ?\SplFileInfo $file, int $error = \UPLOAD_ERR_OK, ?\Closure $moved = null): AnswerThe 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|nullA 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): AnswerA kept file removed.
Dropzone::files()
public static function files(string $submitted, string $directory, bool $multiple): array|\SplFileInfo|string|nullWhat 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): stringAutovalidate::decode()
public function decode(string $hash): arrayAutovalidate::answer()
public function answer(string $hash, string $method): JsonBase\Form\Common
AbstractModel class
class AbstractModel implements FormModelInterface AbstractModel.php:5
AbstractModel::getTypeClass()
public static function getTypeClass(): stringFormModelInterface interface
interface FormModelInterface FormModelInterface.php:5
FormModelInterface::getTypeClass()
public static function getTypeClass(): stringNativeEnum 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): boolNativeEnum::id()
public static function id(\UnitEnum $case): stringWhat the select holds for a case: the backed value, else the case's name.
NativeEnum::of()
public static function of(string $class, mixed $id): ?\UnitEnumThe case a select's value names; null for anything else.
NativeEnum::ids()
public static function ids(string $class): arrayNativeEnum::key()
public static function key(\UnitEnum $case): stringThe 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): stringA 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'): FormDefinitionThe sign-in: its fields, posted to whatever answers it (the firewall's authenticator).
$identifierwhat was typed before, shown again
AccountForms::signInLink()
public static function signInLink(?string $email = null, string $name = '_base_security_login_token'): FormDefinitionThe 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'): FormDefinitionThe 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'): FormDefinitionThe 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 $datapublic readonly array $valuesby field name
public readonly array $violations
Binding::__construct()
public function __construct(public readonly mixed $data, public readonly array $values, public readonly array $violations = [])$valuesby 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): selfA 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): arrayThe 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): BindingBinds 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.
$submittedthe form's part of the request (its name's key), files merged in
FormBinder::reverse()
public function reverse(mixed $raw, FieldDescriptor $field): mixedThe 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): mixedThe data's value of one field as the form shows it.
FormBinder::choices()
public static function choices(FieldDescriptor $field): ?iterableA 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): arrayThe 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): selfFormDefinition::field()
public static function field(string $name, string $kind, ?string $label = null): FieldDescriptorA 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): selfThe form of the fields a page shows (a CRUD controller's configureFields()): those displayed on that page, in order.
FormDefinition::getName()
public function getName(): stringFormDefinition::add()
public function add(FieldInterface|FieldDescriptor $field, ?string $group = null): selfAdds 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): selfFormDefinition::only()
public function only(array $names): selfA 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): boolFormDefinition::get()
public function get(string $name): FieldDescriptorFormDefinition::getFields()
public function getFields(): array- Returns
by name, in order
FormDefinition::addGroup()
public function addGroup(string $name, ?string $label = null): selfA group of fields (a fieldset, a tab), its label a translatable key.
FormDefinition::getGroups()
public function getGroups(): arrayFormDefinition::addAction()
public function addAction(string $name, ?string $label = null, string $kind = Kind::SUBMIT, array $attr = [], array $options = []): selfA 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(): arrayFormDefinition::getMethod()
public function getMethod(): stringFormDefinition::setMethod()
public function setMethod(string $method): selfFormDefinition::getTarget()
public function getTarget(): ?stringWhere the form is sent (its action attribute); null for the page itself.
FormDefinition::setTarget()
public function setTarget(?string $url): selfFormDefinition::getIntent()
public function getIntent(): stringThe intent its token is made for (Omnibridge\Contract\Tokens): the form's name unless set.
FormDefinition::hasIntent()
public function hasIntent(): boolWhether 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): selfFormDefinition::hasCsrf()
public function hasCsrf(): boolFormDefinition::setCsrf()
public function setCsrf(bool $csrf): selfFormDefinition::getDataClass()
public function getDataClass(): ?stringThe class of the data the form edits (an entity, a DTO); null for an array.
FormDefinition::setDataClass()
public function setDataClass(?string $dataClass): selfFormDefinition::getTranslationDomain()
public function getTranslationDomain(): ?stringThe 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): selfFormDefinition::setGuard()
public function setGuard(array|bool $guard): selfBase\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|falseFormDefinition::addRewrite()
public function addRewrite(callable $rewrite): selfWhat 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): arrayFormDefinition::getValidationGroups()
public function getValidationGroups(): ?array- Returns
the groups the form validates, the host's default when null
FormDefinition::setValidationGroups()
public function setValidationGroups(?array $groups): selfFormDefinition::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$errorFieldsthe fields whose refusal is said under them; the others' is the form's own
FormDefinition::getEntityErrorFields()
public function getEntityErrorFields(): arrayFormDefinition::getAttr()
public function getAttr(): array- Returns
the <form> element's attributes
FormDefinition::setAttr()
public function setAttr(array $attr): selfFormDefinition::getHostOptions()
public function getHostOptions(string $host = 'symfony'): arrayOptions 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'): selfFormProcessor 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(): voidomnibase's own rules, read as the kept constraints wherever a class declares them.
FormProcessor::createView()
public function createView(FormDefinition $form, mixed $data = null): FormViewThe 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): FormSubmissionHandles a request's part for the form: null (or nothing under the form's name) is a form not submitted.
$submittedthe values under the form's name, files merged in
$groupsvalidation groups, the form's when null
$addressthe 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 $formpublic readonly bool $submittedpublic readonly mixed $datapublic readonly array $valuesthe values the form shows again, by field name
public readonly array $violationspublic readonly ?string $clickedpublic readonly bool $persistedpublic 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)$valuesthe values the form shows again, by field name
FormSubmission::isSubmitted()
public function isSubmitted(): boolFormSubmission::isValid()
public function isValid(): boolFormSubmission::getClicked()
public function getClicked(): ?stringThe action (FormDefinition::addAction()) whose button sent the form, null for none named.
FormSubmission::getErrors()
public function getErrors(): arrayThe 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): boolWhether the record's rules refused this field's value as already taken.
FormSubmission::withError()
public function withError(string $message, string $field = ''): selfThe 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): FormViewThe 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 $varspublic array $children = []public bool $rendered = falsepublic 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): selfThe view of a definition: one child per field (with the values shown and their errors), one per action, the token's hidden child.
$valuesby field name (FormBinder::read() or Binding::$values)
$errorsby field name, "" for the form's own
$datathe data the form edits: a file field shows the record's stored files
FormView::add()
public function add(string $name, array $vars = []): selfFormView::createView()
public function createView(): selfWhat omnibase's FormProxy hands: a form whose view is made on demand.
FormView::isSelected()
public function isSelected(string $value): boolWhether a choice value is selected by the view's value.
FormView::toArray()
public function toArray(): arrayThe view as plain data (a React page's props): vars and children, recursively.
FormView::jsonSerialize()
public function jsonSerialize(): arrayFormView::offsetExists()
public function offsetExists(mixed $offset): boolFormView::offsetGet()
public function offsetGet(mixed $offset): FormViewFormView::offsetSet()
public function offsetSet(mixed $offset, mixed $value): voidFormView::offsetUnset()
public function offsetUnset(mixed $offset): voidFormView::getIterator()
public function getIterator(): \ArrayIteratorFormView::count()
public function count(): intProperties 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): boolProperties::get()
public static function get(mixed $data, string $path): mixedThe 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): voidWrites 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): arrayUniqueLookup 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): boolBase\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 = nullpublic ?string $email = nullpublic ?string $website = nullpublic ?string $content = nullpublic ?int $spamScore = null
CommentModel::forUser()
public static function forUser(?User $user): staticCommentModel::getSpamBlameable()
public function getSpamBlameable(): ?UserCommentModel::getSpamText()
public function getSpamText(): ?stringCommentModel::getSpamDate()
public function getSpamDate(): \DateTimeCommentModel::getSpamCallback()
public function getSpamCallback(int $score): voidCommentModel::toComment()
public function toComment(?Thread $thread, bool $autoApprove, string $class = Comment::class): CommentThe entity to save, Akismet's score applied (the state follows from it and from $autoApprove).
$classa 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 = nullpublic ?string $email = nullpublic ?string $phone = nullpublic ?string $subject = nullpublic ?string $message = nullpublic ?string $website = nullLeft empty by people; filled by the robots that fill every field.
public array $attachments = []
ContactModel::getRecipient()
public function getRecipient(): ?RecipientContactModel::setAttachments()
public function setAttachments(?array $attachments): voidA 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(): boolThe trap was filled: thank it all the same, and send nothing.
SecurityLoginModel class
class SecurityLoginModel extends AbstractModel SecurityLoginModel.php:11
public $identifierpublic $password
SecurityLoginTokenModel class
class SecurityLoginTokenModel extends AbstractModel SecurityLoginTokenModel.php:11
public $email
SecurityRegistrationModel class
class SecurityRegistrationModel extends AbstractModel SecurityRegistrationModel.php:13
public $emailpublic $plainPasswordpublic 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_idpublic $genericpublic $titlepublic $excerptpublic $content
UserEditModel class
class UserEditModel UserEditModel.php:10
public $avatarpublic $usernamepublic $email
UserProfileModel class
class UserProfileModel extends AbstractModel UserProfileModel.php:11
public $emailpublic $plainPasswordpublic $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): ?RequestsBase\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(): stringFormatFilterInterface::getPath()
public function getPath(): ?stringFormatFilterInterface::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): ImageInterfaceBase\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): ImageInterfaceBase\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): stringBackgroundFilter::getAlpha()
public function getAlpha(): floatBackgroundFilter::getRGBA()
public function getRGBA($hashtag = true): stringBackgroundFilter::getPosition()
public function getPosition(): stringBackgroundFilter::getSize()
public function getSize(): ?arrayBackgroundFilter::getXY()
public function getXY(ImageInterface $image): arrayBackgroundFilter::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(): boolCropFilter::getPosition()
public function getPosition(): stringCropFilter::getSize()
public function getSize(?ImageInterface $image = null): arrayCropFilter::getXY()
public function getXY(?ImageInterface $image = null): arrayCropFilter::apply()
public function apply(ImageInterface $image): ImageInterfaceDownscaleFilter 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): ImageInterfaceFlipFilter 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): ImageInterfaceInterlaceFilter 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): ImageInterfacePasteFilter 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): ImageInterfaceResampleFilter 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): ImageInterfaceResizeFilter 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(): arrayResizeFilter::apply()
public function apply(ImageInterface $image): ImageInterfaceRotateFilter 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): ImageInterfaceScaleFilter 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): ImageInterfaceThumbnailFilter 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): ImageInterfaceThumbnailFilter::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): ImageInterfaceBase\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(): stringBitmapFilter::__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(): ?stringBitmapFilter::setPath()
public function setPath(?string $path)BitmapFilter::getExtension()
public function getExtension()BitmapFilter::apply()
public function apply(ImageInterface $image): ImageInterfaceBitmapFilterInterface interface
interface BitmapFilterInterface extends FormatFilterInterface BitmapFilterInterface.php:7
SvgFilter class
class SvgFilter implements SvgFilterInterface SvgFilter.php:11
SvgFilter::getStandardExtension()
public static function getStandardExtension(): stringSvgFilter::__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(): ?stringSvgFilter::setPath()
public function setPath(?string $path)SvgFilter::getExtension()
public function getExtension()SvgFilter::apply()
public function apply(ImageInterface $image): ImageInterfaceSvgFilterInterface 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(): stringWebpFilter::__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(): ?stringWebpFilter::setPath()
public function setPath(?string $path)WebpFilter::apply()
public function apply(ImageInterface $image): ImageInterfaceBase\Imagine\Svg
Box class
class Box implements ImageBoxInterface Box.php:11
const TYPE_ABSOLUTE = 0const TYPE_ASPECT_RATIO = 1const TYPE_NONE = 2
Box::__construct()
public function __construct(int $width, int $height, int $type = self::TYPE_ABSOLUTE)Box::__toString()
public function __toString(): stringBox::createTypeAbsolute()
public static function createTypeAbsolute(int $width, int $height): selfBox::createTypeAspectRatio()
public static function createTypeAspectRatio(int $width, int $height): selfBox::createTypeNone()
public static function createTypeNone(): selfBox::getType()
public function getType(): int- Returns
one of the SvgImageBox::TYPE_* constants
Box::getWidth()
public function getWidth(): intBox::getHeight()
public function getHeight(): intBox::scale()
public function scale($ratio): selfBox::increase()
public function increase($size): selfBox::contains()
public function contains(ImageBoxInterface $box, PointInterface $start = null): boolBox::square()
public function square(): intBox::widen()
public function widen($width): selfBox::heighten()
public function heighten($height): selfEffects class
class Effects implements EffectsInterface Effects.php:16
Effects::__construct()
public function __construct(DOMDocument $document)Effects::gamma()
public function gamma($correction): selfEffects::negative()
public function negative(): selfEffects::grayscale()
public function grayscale(): selfEffects::colorize()
public function colorize(ColorInterface $color): selfEffects::sharpen()
public function sharpen(): selfEffects::blur()
public function blur($sigma = 1): selfEffects::brightness()
public function brightness($brightness): selfEffects::convolve()
public function convolve(Matrix $matrix): selfImage 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(): stringImage::__clone()
public function __clone()Assures the DOM document instance will be cloned too.
Image::getDomDocument()
public function getDomDocument(): DOMDocumentReturns the DOM document.
Image::copy()
public function copy(): selfImage::crop()
public function crop(PointInterface $start, BoxInterface $size): selfImage::paste()
public function paste(ImageInterface $image, PointInterface $start, $alpha = 100): selfImage::sanitize()
public function sanitize()Image::resize()
public function resize(BoxInterface $size, $filter = ImageInterface::FILTER_UNDEFINED): selfImage::thumbnail()
public function thumbnail(BoxInterface $size, $settings = ImageInterface::THUMBNAIL_INSET, $filter = ImageInterface::FILTER_UNDEFINED): selfImage::rotate()
public function rotate($angle, ColorInterface $background = null): selfImage::save()
public function save($path = null, array $options = []): selfImage::show()
public function show($format, array $options = []): selfImage::get()
public function get($format, array $options = []): stringImage::flipHorizontally()
public function flipHorizontally(): selfImage::flipVertically()
public function flipVertically(): selfImage::strip()
public function strip(): selfImage::draw()
public function draw(): DrawerInterfaceImage::effects()
public function effects(): EffectsImage::getSize()
public function getSize(): BoxImage::applyMask()
public function applyMask(ImageInterface $mask): selfImage::fill()
public function fill(FillInterface $fill): selfImage::mask()
public function mask(): selfImage::histogram()
public function histogram(): arrayImage::getColorAt()
public function getColorAt(PointInterface $point): ColorInterfaceImage::layers()
public function layers(): LayersInterfaceImage::interlace()
public function interlace($scheme): selfImage::palette()
public function palette(): PaletteInterfaceImage::profile()
public function profile(ProfileInterface $profile): selfImage::usePalette()
public function usePalette(PaletteInterface $palette): selfImagine class
class Imagine extends AbstractImagine Imagine.php:17
Imagine::create()
public function create(ImageBoxInterface $size, ?ColorInterface $color = null): ImageImagine::open()
public function open($path): ImageImagine::load()
public function load($string): ImageImagine::read()
public function read($resource): ImageImagine::font()
public function font($file, $size, ColorInterface $color): FontInterfaceBase\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(): boolMailTrap::bypass()
public function bypass(callable $send): mixedMailTrap::isArmed()
public function isArmed(): boolMailTrap::armedDetails()
public function armedDetails(): ?arrayMailTrap::arm()
public function arm(?string $reason = null): voidMailTrap::disarm()
public function disarm(): voidMailTrap::capture()
public function capture(RawMessage $message, Envelope $envelope): stringWrites 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(): arrayMailTrap::read()
public function read(string $id): ?arrayThe held message, rebuilt as a transport can send it.
MailTrap::forget()
public function forget(string $id): boolMailTrap::getDirectory()
public function getDirectory(): stringBase\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)$notifierthe notifier whose contactEmail() and contactEmailConfirmation() make both
ContactMessage::send()
public function send(ContactModel $message): TemplateNotificationCenter 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 = 100const 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|arrayThe page's notifications and the unread count, or where a visitor goes.
NotificationCenter::pushConfig()
public function pushConfig(): JsonWhat 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): arrayA request's body: its JSON, else its form fields.
NotificationCenter::serviceWorker()
public static function serviceWorker(): stringThe 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): ?stringNotifier class
class Notifier extends BaseNotifier implements NotifierInterface Notifier.php:15
Notifier::testEmail()
public function testEmail(User $user): NotificationNotifier::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)Notifier::loginLink()
public function loginLink(User $user, string $token, \DateTimeInterface $until): NotificationThe 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): NotificationThe 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): NotificationNullNotificationLinker 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): ?stringTestRecipient 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(): objectBase\Notifier\Abstract
BaseNotificationInterface interface
interface BaseNotificationInterface BaseNotificationInterface.php:8
BaseNotificationInterface::__toPrune()
public function __toPrune(?RecipientInterface $recipient = null): SymfonyNotificationBaseNotificationInterface::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): mixedBaseNotifier::getOptions()
public function getOptions(): arrayBaseNotifier::getTestRecipients()
public function getTestRecipients(): arrayBaseNotifier::getViews()
public function getViews(): ViewsBaseNotifier::getEnvironment()
public function getEnvironment(): Environmentsince omnisense/omnibase 4.x, removed at 6.0: getViews()
BaseNotifier::setUsers()
public function setUsers(Users $users): staticBaseNotifier::__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)$unitOfWorkthe entity manager is deprecated (until 6.0): adapted by UnitOfWorks
$viewsTwig's environment is deprecated (until 6.0): wrapped in omnibridge/twig's TwigViews
BaseNotifier::getPolicy()
public function getPolicy(): ChannelPolicyInterfaceBaseNotifier::hasLoopback()
public function hasLoopback(): boolBaseNotifier::isTest()
public function isTest(Recipient $recipient): boolBaseNotifier::getAdminRecipient()
public function getAdminRecipient($i = 0): ?RecipientInterfaceBaseNotifier::getAdminRecipients()
public function getAdminRecipients(): arrayBaseNotifier::getTechnicalRecipient()
public function getTechnicalRecipient(): RecipientBaseNotifier::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(): TranslatorInterfaceBaseNotifier::setTranslator()
public function setTranslator(TranslatorInterface $translator)BaseNotifier::getRouter()
public function getRouter(): AdvancedRouterInterface|UrlsBaseNotifier::setRouter()
public function setRouter(AdvancedRouterInterface|Urls $router)BaseNotifier::getDefaultChannels()
public function getDefaultChannels(string $importance)BaseNotifier::send()
public function send(SymfonyNotification $notification, RecipientInterface ...$recipients): voidBaseNotifier::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(): arrayBaseNotifierInterface::getAdminRecipients()
public function getAdminRecipients(): arrayBaseNotifierInterface::getTechnicalRecipient()
public function getTechnicalRecipient(): ?RecipientBaseNotifierInterface::hasLoopback()
public function hasLoopback(): boolBaseNotifierInterface::isTest()
public function isTest(Recipient $recipient): boolBaseNotifierInterface::getPolicy()
public function getPolicy(): ChannelPolicyInterfaceBaseNotifierInterface::getOptions()
public function getOptions(): arrayBaseNotifierInterface::getTranslator()
public function getTranslator(): TranslatorInterfaceBaseNotifierInterface::getViews()
public function getViews(): \Omnibridge\Contract\ViewsThe 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)$requestsSymfony's RequestStack is deprecated (until 6.0)
BrowserPlusChannel::supports()
public function supports(Notification $notification, RecipientInterface $recipient): boolBrowserPlusChannel::notify()
public function notify(Notification $notification, RecipientInterface $recipient, ?string $transportName = null): voidEmailPlusChannel 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)$unitOfWorkthe entity manager is deprecated (until 6.0): adapted by UnitOfWorks
InAppChannel::supports()
public function supports(SymfonyNotification $notification, RecipientInterface $recipient): boolAlways 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): voidInAppChannel::userOf()
public function userOf(RecipientInterface $recipient): ?UserPushChannel 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): boolAlways 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): voidBase\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)$fromthe 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
$isTestwhether an e-mail to that address goes to the technical address instead (the Notifier's isTest(): base.notifier.technical_loopback, test_recipients)
$transthe words of a test e-mail (@emails.fake_test.*)
$globalswhat the templates read as globals where the host's Twig has none of omnibase's (
app: MailVariables)$viewsthe views; Twig's environment is deprecated (until 6.0), wrapped in omnibridge/twig's TwigViews
EmailComposer::views()
public static function views(Views|Environment $views): ViewsThe views, Twig's environment (deprecated) wrapped in omnibridge/twig's TwigViews.
EmailComposer::text()
public static function text(string $subject, string $content): stringThe 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): stringWho 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): stringA 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): stringThe 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): arrayThe 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): stringThe 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): EmailAn 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.
$parametersthe 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)$viewsTwig's environment is deprecated (until 6.0)
InlineImages::image()
public function image(string $image, ?string $contentType = null, ?string $name = null): stringInlineImages::getSubject()
public function getSubject(): ?stringMailVariables 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 $sitepublic readonly object $email
MailVariables::__construct()
public function __construct(SettingBagInterface $settings, \Closure $domain, ?\Closure $homepage = null)$domainthe request's domain (AdvancedRouter::getDomain()), null outside a request
$homepagethe 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 LINK_TEMPLATE = 'email.html.twig'const NEW_DEVICE_TEMPLATE = '@Base/client/email/security_newDevice.html.twig'const LINK_ROUTE = 'security_loginWithToken'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): arrayThe sign-in link's template parameters (Notifier::loginLink()).
$durationa duration spelled (Translator::transTime())
SignInMails::emailCodeParameters()
public static function emailCodeParameters(\Closure $trans, \Closure $duration, string $code, \DateTimeInterface $until): arrayThe 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): arrayThe new device's template parameters (WarnNewDevice).
SignInMails::loginLink()
public function loginLink(User $user, string $token, \DateTimeInterface $until): voidSignInMails::emailCode()
public function emailCode(User $user, string $code, \DateTimeInterface $until): voidSignInMails::welcomeBack()
public function welcomeBack(User $user, Token $token): voidSignInMails::newDevice()
public function newDevice(User $user, Connection $connection): voidBase\Notifier\Recipient
LocaleRecipientInterface interface
interface LocaleRecipientInterface extends RecipientInterface LocaleRecipientInterface.php:7
LocaleRecipientInterface::getLocale()
public function getLocale(): stringLocaleRecipientTrait trait
trait LocaleRecipientTrait LocaleRecipientTrait.php:5
LocaleRecipientTrait::getLocale()
public function getLocale(): stringRecipient 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): selfRecipient::timezone()
public function timezone(string $timezone): selfTimezoneRecipientInterface interface
interface TimezoneRecipientInterface extends RecipientInterface TimezoneRecipientInterface.php:7
TimezoneRecipientInterface::getTimezone()
public function getTimezone(): stringTimezoneRecipientTrait trait
trait TimezoneRecipientTrait TimezoneRecipientTrait.php:5
TimezoneRecipientTrait::getTimezone()
public function getTimezone(): stringBase\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.
ThreadTranslations::search()
public function search(array $terms, array $states = [], Thread|int|string|null $parent = null): arrayThe 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).
$termsfield (title, excerpt, content) => term; empty or non-text terms are left out
$parentthe 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 = []): ?ThreadThe 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 = []): ?ThreadThreads::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 = []): arrayThreads::byStates()
public function byStates(array $states): arrayEvery 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): arrayThe 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 = []): ?ThreadThreads::byParentAndState()
public function byParentAndState(?Thread $parent, array|string $states, array $orderBy = [], ?int $limit = null, ?int $offset = null): arrayThreads::byParentAndStatePublishedWithin()
public function byParentAndStatePublishedWithin(?Thread $parent, array|string $states, string $within, array $orderBy = []): arrayThose published within $within of now (a relative date: "+8 days").
Threads::oneByStateAndSlugStartingWith()
public function oneByStateAndSlugStartingWith(array|string $states, string $prefix): ?ThreadThreads::countByStatePublishedYoungerThan()
public function countByStatePublishedYoungerThan(array|string $states, int|string $age): intHow 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): ?ThreadThe 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): ?ThreadThreads::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): ?UserThe account of a username, through the finder's cache unless $cached is false.
Users::oneByEmail()
public function oneByEmail(?string $email): ?UserThe account of an address, read from the database (step R28: sign-in, links, OAuth).
Users::byIds()
public function byIds(array $ids): arrayThe accounts of these ids, through the finder's cache (step R28: the mentions).
Users::activeWithin()
public function activeWithin(int $seconds, ?int $exceptId = null): arrayThe 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): ?UserThe account of an id, through the finder's cache (step R28: the profile pages).
Users::byRoles()
public function byRoles(array|string $roles): arrayThe 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): arrayThe 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): arrayOther 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): voidPageViews::countViews()
public function countViews(?string $path = null, ?\DateTimeImmutable $since = null, ?string $source = null): intPageViews::earliestDate()
public function earliestDate(): ?\DateTimeImmutablePageViews::dailyBreakdown()
public function dailyBreakdown(\DateTimeImmutable $since, string|array|null $path = null): arrayPageViews::dailyBreakdownBySource()
public function dailyBreakdownBySource(\DateTimeImmutable $since, string|array|null $path = null): arrayPageViews::hourlyBreakdown()
public function hourlyBreakdown(\DateTimeImmutable $since, string|array|null $path = null): arrayPageViews::hourlyBreakdownBySource()
public function hourlyBreakdownBySource(\DateTimeImmutable $since, string|array|null $path = null): arrayPageVisits 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): voidPageVisits::countUnique()
public function countUnique(?\DateTimeImmutable $since = null, string|array|null $path = null): intPageVisits::dailyBreakdown()
public function dailyBreakdown(\DateTimeImmutable $since, string|array|null $path = null): arrayPageVisits::hourlyBreakdown()
public function hourlyBreakdown(\DateTimeImmutable $since, string|array|null $path = null): arrayVisits 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): voidVisits::countUnique()
public function countUnique(string $subjectType, ?\DateTimeImmutable $since = null): intVisits::returning()
public function returning(string $subjectType, \DateTimeImmutable $previousSince, \DateTimeImmutable $currentSince): arrayVisits::dailyBreakdown()
public function dailyBreakdown(string $subjectType, \DateTimeImmutable $since): arrayVisits::hourlyBreakdown()
public function hourlyBreakdown(string $subjectType, \DateTimeImmutable $since): arrayBase\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): intTrashBalls::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): ?ScopedWeekScopedWeeks::week()
public function week(string $scope): ?arrayScopedWeeks::save()
public function save(string $scope, array $week): ScopedWeekScopedWeeks::forget()
public function forget(string $scope): voidSpecialDays 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(): arrayWeekDays::save()
public function save(array $week): voidBase\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): ?ImageCropThe 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): ?ImageCropThe 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): ?ImageCropThe 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): ?RedirectionThe redirection that answers this address, if any.
Redirections::hit()
public function hit(Redirection $redirection): voidCounts 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(): arrayEvery 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): arrayThe 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): ?SettingThe 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): ?WidgetWidgets::every()
public function every(bool $cached = true): arrayBase\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): ?SlotSlots::every()
public function every(bool $cached = true): arrayBase\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): ?CommentThe newest comment written from an address (FormGuard's flood check).
Comments::findVisible()
public function findVisible(?Thread $thread, int $limit = 200): arrayThe 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): intHow many comments are online under a thread, replies included (the visitors' book for null).
Comments::countPending()
public function countPending(): intHow many comments wait for moderation.
Comments::findPending()
public function findPending(int $limit = 20): arrayThe 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): ?LikeA 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): arrayA 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): ?TagTags::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): arrayThe 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): intHow many connections an account has.
Connections::oneByUniqidAndUser()
public function oneByUniqidAndUser(string $uniqid, User $user): ?ConnectionThe 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): ?IdentityIdentities::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): intNotifications::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): ?PasskeyThe 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(): intHow 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): ?TokenTokens::oneByValue()
public function oneByValue(?string $value): ?TokenTokens::oneSigningInByNameAndValue()
public function oneSigningInByNameAndValue(string $name, ?string $value): ?TokenA token of this name and value that signs in (isLogginable).
Tokens::oneSigningInByValue()
public function oneSigningInByValue(?string $value): ?TokenA 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): ?FileAttachmentDownload::type()
public static function type(string $path): stringWhat 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(): selfDecision::final()
public static function final(): selfThe page served as it is, no rule after this one.
Decision::redirect()
public static function redirect(string $route, array $parameters = [], int $status = 302): selfDecision::redirectTo()
public static function redirectTo(string $url, int $status = 302): selfDecision::deny()
public static function deny(int $status = 403): selfDecision::withNotice()
public function withNotice(string $key, array $parameters = [], string $importance = 'info'): selfDecision::withCookie()
public function withCookie(string $name, ?string $value): selfDecision::withSignOut()
public function withSignOut(): selfDecision::withRemember()
public function withRemember(string $url): selfThe address the visitor comes back to after signing in again.
Decision::withoutProfiler()
public function withoutProfiler(): selfDecision::isContinue()
public function isContinue(): boolDecision::then()
public function then(self $next): selfThis 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(): arrayA 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): ?stringThe 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): stringThe 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): ?stringThe 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): arrayThe 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.
$matchthe 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(): boolA route of the account's own pages, "security_*" (omnibridge/symfony's AdvancedRouter::isSecured()).
Page::isUx()
public function isUx(): boolA route of the widgets' endpoints, "ux_*".
Page::uri()
public function uri(): stringThe 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(): boolRouterPage::isProfiler()
public function isProfiler(): boolRouterPage::isAdmin()
public function isAdmin(): boolRouterPage::isUx()
public function isUx(): boolRouterPage::isSecured()
public function isSecured(): boolRouterPage::name()
public function name(): ?stringRouterPage::redirectsOnDeny()
public function redirectsOnDeny(): arrayRouterPage::uri()
public function uri(): stringShortLinkRedirect 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): OutcomeSitemapPage 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): SitemapperInterfaceSitemapPage::template()
public static function template(string $extension): stringTimezoneSwitch 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): ?stringThe zone chosen, or null when PHP knows no such zone.
TimezoneSwitch::remember()
public function remember(string $timezone): voidThe zone kept as a member's own (not while impersonating).
TimezoneSwitch::back()
public static function back(?string $referer, string $host): ?stringWhere 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)$entriesas security.yaml writes them (
^/profile, ROLE_USER)
AccessControl::decide()
public function decide(string $path, bool $signedIn, \Closure $granted, ?string $uri = null): Decision$grantedthe 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$administratorwhether the account is an administrator (the approval asks it)
Accounts::response()
public function response(mixed $user): voidOn 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): boolAnalytics::users()
public function users(?object $user, int $delay, array $globals): array$globalsthe views' globals as they are
Analytics::google()
public function google(array $basics, array $globals): array$basicsGoogle Analytics' (users, users_1day, views, views_1day, sessions, bounces_1day)
$globalsthe views' globals as they are
- Returns
user_analyticswith itsgoogleentries
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$administratorwhether 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): DecisionImpersonation 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): DecisionIntegrity 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(): mixedThe secret as the session keeps it.
Integrity::secretIntact()
public function secretIntact(mixed $sealed): boolIntegrity::checksum()
public static function checksum(array $parameters): string$parametersthe connection's (driver, user, host, port, dbname, charset)
Integrity::databaseIntact()
public static function databaseIntact(bool $signedIn, ?string $kept, string $checksum): boolIntegrity::decide()
public function decide(bool $intact, ?object $user, ?string $route): DecisionKicked 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): DecisionLaunchPage 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$grantedthe 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 $languagesthe 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)$languagesthe languages the site speaks (fr, en), its own first: Accept-Language's ties go to it
$normalizea 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): stringLocale::available()
public function available(?string $locale, bool $declared = false): ?stringA locale of this site's ("de", "fr_FR", "fr-FR"), normalized; null for any other.
Locale::browser()
public function browser(?string $acceptLanguage, \Closure $preferred): ?stringThe browser's language among the site's, null when it says nothing.
$preferredthe 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): stringThe page's locale, normalized.
Locale::remember()
public static function remember(string $displayed, ?string $cookie, bool $setByPage): DecisionThe 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): arrayThe 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$grantedthe 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): boolWhether 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 = ''): DecisionVerification 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): DecisionBase\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): stringA controller's slug: "articles/comment-replies".
AdminRouteNames::pluralize()
public static function pluralize(string $kebab): stringThe 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'): stringA slug's route for an action: admin_crud_articles_comments_edit.
AdminRouteNames::forEntity()
public static function forEntity(string $entityFqcn, string $action = 'index'): ?stringThe 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): staticAdminUrlGeneratorInterface::setAction()
public function setAction(string $action): staticAdminUrlGeneratorInterface::setEntityId()
public function setEntityId(mixed $entityId): staticAdminUrlGeneratorInterface::set()
public function set(string $paramName, mixed $paramValue): staticAdminUrlGeneratorInterface::unset()
public function unset(string $paramName): staticAdminUrlGeneratorInterface::unsetAll()
public function unsetAll(): staticAdminUrlGeneratorInterface::generateUrl()
public function generateUrl(int $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH): stringCookieDomain 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$urlthe address asked (its domain is read as omnibase's parse_url2() reads it: "symfony.test" of "lesringostars.symfony.test")
$configuredthe configured domains (domains())
CookieDomain::domains()
public static function domains(bool $useFallbacks, array $hostFallbacks, array $locales): arrayThe 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.
$hostFallbacksbase.router.host_fallbacks
$localesthe 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): staticNullAdminUrlGenerator::setAction()
public function setAction(string $action): staticNullAdminUrlGenerator::setEntityId()
public function setEntityId(mixed $entityId): staticNullAdminUrlGenerator::set()
public function set(string $paramName, mixed $paramValue): staticNullAdminUrlGenerator::unset()
public function unset(string $paramName): staticNullAdminUrlGenerator::unsetAll()
public function unsetAll(): staticNullAdminUrlGenerator::generateUrl()
public function generateUrl(int $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH): stringBase\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 $statuspublic string $bodypublic array $headerspublic Cache $cachepublic bool $jsonpublic ?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.
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(): arrayAuthor::jsonSerialize()
public function jsonSerialize(): arrayCache 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.
true: public, false: private, null: the host's default
public ?int $maxAgepublic bool $mustRevalidatepublic bool $noStorepublic 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 = [])$sharedtrue: public, false: private, null: the host's default
Cache::private()
public static function private(): selfKept by the visitor's browser alone.
Cache::public()
public static function public(int $maxAge, bool $mustRevalidate = false): selfKept by any cache, that long.
Cache::with()
public function with(array $vary = [], bool $private = false, bool $noStore = false): selfA 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 $slugpublic string $titlepublic string $urlpublic ?string $excerptpublic bool $hasContentpublic ?string $publishedAtpublic int $readingMinutespublic ?int $likespublic ?string $likeUrlpublic ?int $commentspublic ?string $headlinepublic ?string $coverpublic array $taxapublic 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(): arrayCard::jsonSerialize()
public function jsonSerialize(): arrayComment 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 $idpublic ?string $uuidpublic ?string $slugpublic ?string $publishedAtpublic ?string $contentpublic ?string $followUrlpublic array $repliespublic 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(): arrayComment::jsonSerialize()
public function jsonSerialize(): arrayConfidential 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 = []): FrameThe frame of the page being answered; $extra the site's own fields.
ContextProvider::viewer()
public function viewer(): ?ViewerThe visitor signed in, null for nobody.
ContextProvider::flashes()
public function flashes(string $type): arrayThe 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 $commentspublic bool $hasMorepublic bool $openpublic bool $canReplypublic ?string $signInpublic 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(): arrayDiscussion::jsonSerialize()
public function jsonSerialize(): arrayFile 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 $pathpublic ?string $typepublic 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 $localepublic Site $sitepublic array $linksby name;
localesthe address of each languagepublic ?Viewer $viewerpublic array $themepublic array $extrathe 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 = '')$linksby name;
localesthe address of each language$extrathe site's own fields
Frame::with()
public function with(array $extra): selfA copy with the site's own fields added (a site's provider decorating the core's).
Frame::toArray()
public function toArray(): arrayFrame::jsonSerialize()
public function jsonSerialize(): arrayJson 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 $datapublic int $statuspublic Cache $cache
Json::__construct()
public function __construct(public mixed $data, public int $status = 200, public Cache $cache = new Cache())Link class
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 string $titlepublic string $urlpublic string $statepublic ?string $publishedAt
Link::__construct()
public function __construct(public string $title, public string $url, public string $state, public ?string $publishedAt = null)Link::toArray()
public function toArray(): arrayLink::jsonSerialize()
public function jsonSerialize(): arrayNegotiation 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
frameandscreen(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_QUOTHow 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)$renderthe host's Twig; $as one of PAGE, PART, ALONE
$omnibridgewhether 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$legacya 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): voidA 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): stringData in JSON, as Symfony's JsonResponse writes them.
Negotiation::omnibridge()
public function omnibridge(): boolWhether 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 $urlpublic int $statuspublic Cache $cachepublic 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 $idpublic ?string $uuidpublic ?string $publishedAtpublic ?string $contentpublic bool $deletedpublic 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(): arrayReply::jsonSerialize()
public function jsonSerialize(): arrayScreen 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 $componentpublic array $propspublic string $templatepublic array $datathe 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)$datathe 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 $titlepublic ?string $sloganpublic ?string $logopublic string $agepublic ?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(): arraySite::jsonSerialize()
public function jsonSerialize(): arrayStory 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 $idpublic string $slugpublic string $titlepublic string $urlpublic string $statepublic ?string $headlinepublic ?string $excerptpublic StoryText $textpublic ?string $publishedAtpublic int $readingMinutespublic array $audiopublic ?int $likespublic ?string $likeUrlpublic bool $commentablepublic ?int $commentspublic ?string $coverpublic array $taxapublic 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(): stringThe text's HTML (Twig: story.html, as the props say it).
Story::isEditor()
public function isEditor(): boolStory::getToc()
public function getToc(): arrayStory::hasContent()
public function hasContent(): boolStory::toArray()
public function toArray(): arrayStory::jsonSerialize()
public function jsonSerialize(): arrayStoryText 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 $htmlpublic bool $editorpublic array $toc
StoryText::__construct()
public function __construct(public string $html = '', public bool $editor = false, public array $toc = [])StoryText::toArray()
public function toArray(): arrayStoryText::jsonSerialize()
public function jsonSerialize(): arrayTag 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 $slugpublic string $labelpublic string $urlpublic ?string $colorpublic ?string $iconpublic ?int $countpublic ?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(): arrayTag::jsonSerialize()
public function jsonSerialize(): arrayTemplate 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 $templatepublic array $datapublic int $statuspublic bool $jsonpublic bool $alonepublic 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): selfA 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 $templatepublic Screen $screenpublic ?string $componentpublic 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 $idpublic string $namepublic ?string $avatar
Viewer::__construct()
public function __construct(public ?int $id, public string $name, public ?string $avatar = null)Viewer::toArray()
public function toArray(): arrayViewer::jsonSerialize()
public function jsonSerialize(): arrayVisit 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 $uripublic string $acceptpublic ?string $frontEndpublic ?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(): arrayThe types of Accept, the preferred first: by quality, then in their order (Symfony's AcceptHeader), without their parameters.
Visit::prefersJson()
public function prefersJson(): boolThe 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(): boolThe 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 = 404const TEMPLATE = __DIR__ . '/../../templates/welcome.html.php'
Welcome::html()
public static function html(string $version, string $projectDir, string $baseVersion): stringBase\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 $twoFactorpublic ?int $passkeyspublic ?string $identityProviderpublic ?string $localepublic ?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(): arrayAccountSummary::jsonSerialize()
public function jsonSerialize(): arrayAction 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 $urlpublic string $token
Action::__construct()
public function __construct(public string $url, public string $token)Action::toArray()
public function toArray(): arrayAction::jsonSerialize()
public function jsonSerialize(): arrayMember 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 $idpublic string $namepublic ?string $avatarpublic ?string $avatarHtmlpublic array $rolespublic bool $onlinepublic bool $activepublic ?string $registeredAtpublic ?string $lastSeenAtpublic int $threadspublic 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(): arrayMember::jsonSerialize()
public function jsonSerialize(): arrayNotification 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 $idpublic string $titlepublic ?string $contentpublic ?string $urlpublic ?string $adminUrlpublic ?string $importancepublic bool $isReadpublic ?string $sentAtpublic 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(): arrayNotification::jsonSerialize()
public function jsonSerialize(): arrayNotificationsPage 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 $notificationspublic int $unreadpublic bool $unreadOnlypublic string $allUrlpublic string $tokenpublic string $readUrlpublic string $latestUrlpublic string $deleteUrlpublic string $subscribeUrlpublic string $unsubscribeUrlpublic bool $pushpublic ?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(): arrayNotificationsPage::jsonSerialize()
public function jsonSerialize(): arrayPasskey 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 $idpublic Action $renamepublic Action $deletepublic ?string $labelpublic ?string $addedAtpublic ?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(): arrayPasskey::jsonSerialize()
public function jsonSerialize(): arrayProfilePage 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 $memberpublic bool $ownpublic array $recentpublic ?AccountSummary $accountpublic ?string $editUrlpublic ?string $settingsUrlpublic ?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(): arrayProfilePage::jsonSerialize()
public function jsonSerialize(): arrayProvider 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 $namepublic string $labelpublic bool $connectedpublic ?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(): arrayProvider::jsonSerialize()
public function jsonSerialize(): arraySession 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 $idpublic ?string $agentpublic ?string $labelpublic array $ipspublic ?string $updatedAtpublic bool $validpublic ?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(): arraySession::jsonSerialize()
public function jsonSerialize(): arraySettingsPage 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 $namepublic bool $demopublic ?TwoFactor $twoFactorpublic ?array $passkeyspublic ?string $identifierpublic array $providerspublic array $sessionspublic ?string $languagepublic ?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(): arraySettingsPage::jsonSerialize()
public function jsonSerialize(): arrayTwoFactor 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 $mandatorypublic bool $enrolmentRequiredpublic bool $totppublic ?string $totpEnablepublic ?Action $totpDisablepublic bool $emailpublic bool $emailLockedpublic ?Action $emailTogglepublic ?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(): arrayTwoFactor::jsonSerialize()
public function jsonSerialize(): arrayBase\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 = 5How 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): MemberA member as their profile shows them.
$avatarthe 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): ProfilePageA member's profile.
$ownthe viewer is that member
$adminthe 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): AccountSummaryAn account's security at a glance, for its owner or an administrator.
Accounts::settings()
public function settings(?User $user, iterable $sessions = [], array $available = []): SettingsPageThe account's settings; for nobody signed in, its title alone.
$sessionsthe sessions listed, newest first
$availablewhether 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): NotificationsPageThe member's notifications.
$notificationsnewest first
$adminUrlthe back-office address of what one is about
$timezonethe 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): NotificationAccounts::group()
public function group(?string $moment, ?\DateTimeZone $timezone = null): stringThe 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): CardA thread on a list.
$tagUrlthe address listing a tag's stories
$taxonUrlthe address listing a taxon's
$coverthe 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): StoryA thread on its own page: its card's fields, its text through Texts.
$textOptionsthe options of
|wysiwyg$audioits sounds' addresses
Stories::link()
public function link(?Thread $thread, ?string $url): ?LinkA thread pointed to (the one before, after, to read as well); null for none.
Stories::text()
public function text(?string $content, array $options = []): StoryTextA stored text as its page shows it, through the Texts contract.
$optionsthe options of
|wysiwyg
Stories::tags()
public function tags(iterable $tags, \Closure $url, ?string $current = null, bool $marked = false): arrayTags or taxa (any entity with a slug and a label: Base\Entity\Thread\Tag, Taxon).
$currentthe 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): arrayComments 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): boolWhether 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)$uniqidthe browser's PHPUSERID (made and kept by the host when it has none)
$hostthe host the request reached
$unitOfWorkthe entity manager is deprecated (until 6.0): adapted by UnitOfWorks
ConnectionTracker::getUniqid()
public function getUniqid(): stringConnectionTracker::getCurrentConnection()
public function getCurrentConnection(?User $user = NULL, bool $allowNewConnection = true): ?ConnectionConnectionTracker::createNewConnection()
public function createNewConnection(User $user): ConnectionConnectionTracker::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): ?booltrue or false, null when the visitor has not answered for this category - or the answer is not in this cookie.
$cookiesthe request's; PHP's own by default
CookieAnswer::refused()
public static function refused(string $category, ?array $cookies = null): boolLoginRestrictionInterface 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): ?stringThe captcha's gateway when a sign-in from this address must pass it; null otherwise.
SignInCaptcha::failures()
public function failures(string $ip): intSignInCaptcha::failed()
public function failed(string $ip): voidOne more failure from this address, remembered WINDOW seconds.
SignInCaptcha::forget()
public function forget(string $ip): voidThe failures counted from an address forgotten: a success does it; a test that starts afresh too.
SignInCaptcha::field()
public function field(string $gateway): stringThe 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): stringThe 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): boolDoes 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): stringThe 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)$unitOfWorkthe entity manager is deprecated (until 6.0): adapted by UnitOfWorks
UserTracker::getUniqid()
public function getUniqid(): stringWebauthnUserEntityRepository 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): ?PublicKeyCredentialUserEntityWebauthnUserEntityRepository::findOneByUserHandle()
public function findOneByUserHandle(string $userHandle): ?PublicKeyCredentialUserEntityBase\Serializer
Aco class
class Aco Aco.php:13
const BYTE_SIZE = 8const VERSION_V1 = 1const VERSION_V2 = 2const RGB = 0const HSB = 1const CMYK = 2const LAB = 7const GRAYSCALE = 8const WideCMYK = 9
Aco::parseFile()
public static function parseFile(string $filename, int $flags = self::VERSION_V2): arrayAco::parse()
public static function parse($handle, int $flags = self::VERSION_V2): array- Throws
Exception
Aco::dump()
public static function dump($input, int $flags = 0): stringAco::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_KEYconst 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(): stringExcel::extension()
public static function extension(string $path)Excel::parseFile()
public static function parseFile(string $filename, array $context = []): mixedExcel::parse()
public static function parse(string $data, string $format, array $context = []): mixedBase\Serializer\Encoder
AcoEncoder class
class AcoEncoder implements EncoderInterface, DecoderInterface AcoEncoder.php:9
const FORMAT = 'aco'
AcoEncoder::supportsEncoding()
public function supportsEncoding(string $format, array $context = []): boolAcoEncoder::encode()
public function encode(mixed $data, string $format, array $context = []): stringAcoEncoder::supportsDecoding()
public function supportsDecoding(string $format, array $context = []): boolAcoEncoder::decode()
public function decode(string $data, string $format, array $context = []): mixedExcelEncoder 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 = []): boolExcelEncoder::encode()
public function encode(mixed $data, string $format, array $context = []): stringExcelEncoder::supportsDecoding()
public function supportsDecoding(string $format, array $context = []): boolExcelEncoder::decode()
public function decode(string $data, string $format, array $context = []): mixedBase\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): voidCall 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): intTotal 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): intDistinct anonymous (cookie-consented) visitors.
Analytics::uniqueViews()
public function uniqueViews(?string $window = null, ?string $path = null): intUnique 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): arrayRetention 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): intDistinct authenticated user accounts active in the window.
Analytics::summary()
public function summary(): arrayThe 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): arrayDay-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): arrayHour-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): arrayThis $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(): arrayAnalytics::displayBucket()
public static function displayBucket(string $bucket): \DateTimeImmutableA 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): voidBaseService 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)$environmentwhat the application runs as (its name kept for BaseTrait's getEnvironment())
$parameterBagthe parameters (kept for BaseTrait's getParameterBag(); base.user.identifier read)
$projectDirthe application's folder
$startTimewhen 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): arrayBaseService::settings()
public function settings()BaseService::getExecutionTime()
public function getExecutionTime(): floatBaseService::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|nullA parameter of the application, from its parameters (the host's facade reads its container's).
BaseService::hasParameter()
public function hasParameter(string $name): boolBaseService::getAsset()
public function getAsset(string $url): stringAn asset's address (Urls::asset()).
BaseService::getCurrentRouteName()
public function getCurrentRouteName(): ?stringThe route of the request being answered (Requests::route()), null outside one.
BaseService::generateUrl()
public function generateUrl(string $routeName, array $routeParameters = []): stringA 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"): boolWhether 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): boolWhether the visitor is granted that attribute (Access::isGranted()).
BaseService::inDoctrine()
public function inDoctrine($entity): boolWhether 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.
$reopenthe 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): boolBreadgrinder::grind()
public function grind(string $name, array $options = [], ?string $template = null): BreadcrumbBreadgrinderInterface interface
interface BreadgrinderInterface BreadgrinderInterface.php:7
BreadgrinderInterface::grind()
public function grind(string $name): BreadcrumbColorExtractor class
class ColorExtractor ColorExtractor.php:9
ColorExtractor::__construct()
public function __construct(Palette $palette)ColorExtractor::extract()
public function extract(int $colorCount = 1): arrayCommentGuard 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::TRAPPEDconst TOO_FAST = FormGuard::TOO_FASTconst 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): ?stringnull 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(): arrayDottedParameterBag::get()
public function get(string $key = "", ?array $bag = null): array|bool|string|int|float|UnitEnum|nullDottedParameterBag::has()
public function has(string $path, ?array $bag = null): boolDownloadLinks class
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(); }
DownloadLinks::__construct()
public function __construct(protected readonly UriSigner $signer, protected readonly UrlGeneratorInterface $router, protected readonly int $ttl = 600)DownloadLinks::sign()
public function sign(string $route, array $parameters = [], ?int $ttl = null): string$parametersthe route's parameters, and who the link was issued to
DownloadLinks::verify()
public function verify(Request $request): boolThe request's URL is one this site signed, and it has not run out.
DownloadLinks::ttl()
public function ttl(): intEditorEnhancer class
class EditorEnhancer extends WysiwygEnhancer implements EditorEnhancerInterface EditorEnhancer.php:8
EditorEnhancer::supports()
public function supports(mixed $json): boolEditorEnhancer::render()
public function render(mixed $json, array $options = []): stringEditorEnhancer::getTableOfContents()
public function getTableOfContents(mixed $json, ?int $maxLevel = null): arrayEditorEnhancer::enhanceHeadings()
public function enhanceHeadings(mixed $json, ?int $maxLevel = null, array $attrs = []): mixedEditorEnhancer::enhanceSemantics()
public function enhanceSemantics(mixed $json, null|array|string $words = null, array $attrs = []): mixedEditorEnhancer::enhanceMentions()
public function enhanceMentions(mixed $json, array $attrs = []): mixedEditorEnhancer::enhanceLinks()
public function enhanceLinks(mixed $json, array $attrs = []): mixedEditorEnhancer::enhanceMedia()
public function enhanceMedia(mixed $json, array $config = [], FilterInterface|array $filters = [], array $attrs = []): mixedEditorEnhancerInterface 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): ?arrayEmbeds::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)$viewsTwig's environment is deprecated (until 6.0)
FileService::getRouter()
public function getRouter(): MediaRouterThe 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): ?stringFileService::getExtensions()
public function getExtensions(null|string|array $fileOrMimetypeOrArray): arrayFileService::getMimeType()
public function getMimeType(null|string|array $fileOrContentsOrArray): null|string|arrayFileService::linkable()
public function linkable(array|string|null $path, array $config = []): array|string|nullFileService::downloadable()
public function downloadable(array|string|null $path, array $config = []): array|string|nullFileService::public()
public function public(array|string|null $path, ?string $storage = null): array|string|nullFileService::asset()
public function asset(string $path, ?string $packageName = null): ?stringFileService::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): stringFileService::obfuscate()
public function obfuscate(string|null $path, array $config = []): ?stringFileService::generate()
public function generate(string $proxyRoute, array $proxyRouteParameters = [], ?string $path = null, array $config = []): ?stringFileService::resolve()
public function resolve(string $data): ?arrayFileService::serve()
public function serve(?string $path, int $status = 200, array $headers = []): ?ResponseFileService::serveContents()
public function serveContents(?string $contents, int $status = 200, array $headers = []): ?ResponseFileServiceInterface interface
interface FileServiceInterface FileServiceInterface.php:7
FileServiceInterface::getExtension()
public function getExtension(null|string|array $fileOrMimetypeOrArray): ?stringFileServiceInterface::getExtensions()
public function getExtensions(null|string|array $fileOrMimetypeOrArray): null|string|arrayFileServiceInterface::getMimeType()
public function getMimeType(null|string|array $fileOrContentsOrArray): null|string|arrayFileServiceInterface::generate()
public function generate(string $proxyRoute, array $proxyRouteParameters, ?string $path, array $config = []): ?stringFileServiceInterface::resolve()
public function resolve(string $data): ?arrayFileServiceInterface::serve()
public function serve(?string $path, int $status = 200, array $headers = []): null|bool|ResponseFileServiceInterface::serveContents()
public function serveContents(?string $contents, int $status = 200, array $headers = []): null|bool|ResponseFlysystem 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(): DrivesThe storages, as omnidrive's drives.
Flysystem::getDrive()
public function getDrive(FilesystemOperator|string|null $storage = null): DriveA storage as an omnidrive drive: by its name, the default one when null.
Flysystem::createStorage()
public function createStorage(string $source, ?string $storageName = null): FilesystemOperatorsince omnibase 4.0, the operator behind a drive: getDrive()
Flysystem::hasStorage()
public function hasStorage(string $storageName): boolFlysystem::getStorageNames()
public function getStorageNames(bool $public = true): arrayFlysystem::getDefaultStorage()
public function getDefaultStorage(): FilesystemOperatorsince 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): FilesystemOperatorsince omnibase 4.0, Flysystem's operator behind a storage: getDrive() reads and writes it
Flysystem::getAdapter()
public function getAdapter(FilesystemOperator|string|null $operator = null): FilesystemAdaptersince omnibase 4.0, Flysystem's adapter behind a storage
Flysystem::getConnectionOptions()
public function getConnectionOptions(FilesystemOperator|string|null $operator = null): ?arrayFlysystem::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): ?stringFlysystem::write()
public function write(string $path, string $contents, FilesystemOperator|string|null $operator = null, array $config = []): boolFlysystem::delete()
public function delete(string $path, FilesystemOperator|string|null $operator = null): boolFlysystem::fileExists()
public function fileExists(string $path, FilesystemOperator|string|null $operator = null): boolFlysystem::mkdir()
public function mkdir(string $path, FilesystemOperator|string|null $operator = null, array $config = []): boolFlysystem::mimeType()
public function mimeType(string $path, FilesystemOperator|string|null $operator = null): ?stringFlysystem::get()
public function get(mixed $path, FilesystemOperator|string|null $operator = null)Flysystem::getPublicRoot()
public function getPublicRoot(FilesystemOperator|string|null $operator = null): ?stringFlysystem::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): boolFlysystemInterface::getStorageNames()
public function getStorageNames(bool $public = true): arrayFlysystemInterface::getDefaultStorage()
public function getDefaultStorage(): FilesystemOperatorFlysystemInterface::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): ?stringFlysystemInterface::getOperator()
public function getOperator(FilesystemOperator|string|null $operator = null): FilesystemOperatorFlysystemInterface::getAdapter()
public function getAdapter(FilesystemOperator|string|null $operator = null): FilesystemAdapterFlysystemInterface::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): ?stringFlysystemInterface::write()
public function write(string $path, string $contents, FilesystemOperator|string|null $operator = null, array $config = []): boolFlysystemInterface::delete()
public function delete(string $path, FilesystemOperator|string|null $operator = null): boolFlysystemInterface::fileExists()
public function fileExists(string $path, FilesystemOperator|string|null $operator = null): boolFlysystemInterface::isRemote()
public function isRemote(FilesystemOperator|string|null $operator = null)FlysystemInterface::mkdir()
public function mkdir(string $path, FilesystemOperator|string|null $operator = null, array $config = []): boolFlysystemInterface::mimeType()
public function mimeType(string $path, FilesystemOperator|string|null $operator = null): ?stringFlysystemInterface::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
guardadds 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 = 900Seconds 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)$configbase.guard
$defaultChallengeomnishield.challenge.gateway, when omnisense/omnishield is installed (Base\Discovery's
arguments)$cachewhere a form's refused tries are counted; without it, the captcha is always asked
$clockwhat "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(): intNow, 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(): boolWhether omnisense/omnishield is here, with its gateways.
FormGuard::getRegistry()
public function getRegistry(): ?RegistryFormGuard::minDelay()
public function minDelay(): intFormGuard::signInAfter()
public function signInAfter(): intFailed sign-ins from an address before the sign-in form asks the captcha. 0: never.
FormGuard::captchaAfter()
public function captchaAfter(): intRefused 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): boolWhether 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): ?intThe 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): voidOne 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): voidA form sent: its tries are forgotten.
FormGuard::challengeGateway()
public function challengeGateway(bool $field = true): ?stringThe 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(): ?stringThe 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(): ?stringFormGuard::rejectsUnreachable()
public function rejectsUnreachable(): boolFormGuard::stamp()
public function stamp(?int $time = null): stringWhen the form was shown, signed: "<time>.<signature>".
FormGuard::elapsed()
public function elapsed(?string $stamp): ?intSeconds 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): ?arrayThe 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): ?arrayinspect() 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): ?stringWhat 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): ?stringThe 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): ?stringThe 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)$unitOfWorkthe entity manager is deprecated (until 6.0): adapted by UnitOfWorks
GroupManager::getEligibleGroups()
public function getEligibleGroups(User $user): arrayEvery 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): arrayWhat those groups would award, merged across all of them.
GroupManager::synchronize()
public function synchronize(User $user, bool $join = true): arrayBring 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): voidThe 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|nullHotParameterBagInterface::has()
public function has(string $path, ?array $bag = null, bool $useHotBag = true): boolHotParameterBagInterface::markAsReady()
public function markAsReady(bool $ready = true)HotParameterBagInterface::isReady()
public function isReady(): boolHotParameters 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(): boolWhether 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): voidThe settings given, over those given before (a value of null takes one back).
HotParameters::all()
public function all(): arrayHotParameters::get()
public function get(string $path = "", ?array $bag = null, bool $useHotBag = true): array|bool|string|int|float|UnitEnum|nullHotParameters::has()
public function has(string $path, ?array $bag = null, bool $useHotBag = true): boolHotParameters::set()
public function set(string $path, array|bool|string|int|float|UnitEnum|null $value, ?array &$bag = null): voidWrites into the $bag given, as the configuration's set() does.
HotParameters::warm()
public function warm(SettingBagInterface|callable $settings): boolThe 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(): boolHotParameters::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): arrayIconProvider::getRouteIcons()
public function getRouteIcons(?string $route = null)IconProvider::getAdapters()
public function getAdapters()IconProvider::getAdapter()
public function getAdapter(string $idOrClass): ?IconAdapterInterfaceIconProvider::addAdapter()
public function addAdapter(IconAdapterInterface $provider): selfIconProvider::removeAdapter()
public function removeAdapter(IconAdapterInterface $provider): selfIconProvider::icons()
public function icons(): IconsThe 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|arrayIcons 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)$routeIconsa route's icons, null for none
Icons::getAdapters()
public function getAdapters(): iterableIcons::adapter()
public function adapter(string $idOrClass): ?IconAdapterInterfaceThe 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|arrayImageRoute 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): staticThe 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(): staticThe same route without the local cache: the cacheless routes.
ImageRoute::redirectToRoute()
public function redirectToRoute(string $route, array $parameters = [], int $status = 302): RedirectResponseA 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): ResponseA 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): ResponseImageRoute::imageWebp()
public function imageWebp($data): ResponseImageRoute::imageSvg()
public function imageSvg($data): ResponseImageRoute::image()
public function image($data, ?string $extension = null, bool $debug = false): ResponseInvitations 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')$unitOfWorkthe entity manager is deprecated (until 6.0): adapted by UnitOfWorks
Invitations::token()
public static function token(): stringA new token: 48 hexadecimal characters.
Invitations::hash()
public static function hash(string $token): stringInvitations::expiry()
public static function expiry(int $days): \DateTimeImmutableInvitations::save()
public function save(Invitation $invitation): InvitationSaved, its token's hash only.
Invitations::findOpen()
public function findOpen(string $class, string $token): ?InvitationThe open invitation a token belongs to; null once accepted or run out.
Invitations::markAccepted()
public function markAccepted(Invitation $invitation): voidMarked accepted. What it opens is the extending bundle's business.
Invitations::createUser()
public function createUser(Invitation $invitation, string $username, string $plainPassword): UserA new account for an invitation's e-mail, verified: the link proved the address.
Invitations::existingUser()
public function existingUser(Invitation $invitation): ?UserThe 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): ?DateTimeLauncher::date()
public static function date(mixed $launchdate): ?DateTimeA 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): stringThe site's years ("2019-2026", "2026"), since a launch date (since()).
Launcher::isLaunched()
public function isLaunched(?string $locale = null): ?boolLauncher::since()
public function since(?string $locale = null): stringLauncher::redirectOnDeny()
public function redirectOnDeny(?RequestEvent $event = null, ?string $locale = null): boolThe 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): ?DateTimeLauncherInterface::isLaunched()
public function isLaunched(?string $locale = null): ?boolLauncherInterface::since()
public function since(?string $locale = null): stringLauncherInterface::redirectOnDeny()
public function redirectOnDeny(?RequestEvent $event = null): boolLinks class
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.
Links::__construct()
public function __construct(readonly Urls $urls)Links::to()
public function to(string $name, array $parameters = [], int $referenceType = Link::ABSOLUTE_PATH): stringLocalBusiness 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 = [])$configbase.local_business
LocalBusiness::schema()
public function schema(array $overrides = [], string|object|null $scope = null): array$overridesschema.org properties that win over everything (null removes one)
$scopeone place's hours (OpeningHours::for()); null: the site's
LocalBusiness::jsonLd()
public function jsonLd(array $overrides = [], string|object|null $scope = null): stringThe <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 = 256Upper bound for the normalizeLocale() memo; see the check in that method.
Localizer::isLate()
public static function isLate(): boolLocalizer::markAsLate()
public static function markAsLate(?string $location = null)Localizer::forgetRequestState()
public static function forgetRequestState(): voidisLate 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): arrayLocalizer::__toLocale()
public static function __toLocale(string $locale, ?string $separator = self::SEPARATOR): stringLocalizer::__toLocaleLang()
public static function __toLocaleLang(string $locale): stringLocalizer::__toLocaleCountry()
public static function __toLocaleCountry(string $locale): stringLocalizer::getLocales()
public static function getLocales()Localizer::compatibleLocale()
public function compatibleLocale(string $locale, string $preferredLocale, ?array $availableLocales = null): boolLocalizer::getLocale()
public function getLocale(?string $locale = null): stringLocalizer::setLocale()
public function setLocale(string $locale, ?Request $request = null)- Throws
Exception
Localizer::setDefaultLocale()
public function setDefaultLocale(?string $defaultLocale)Localizer::getDefaultLocale()
public static function getDefaultLocale(): ?stringLocalizer::getFallbackLocales()
public static function getFallbackLocales(): arrayLocalizer::getAvailableLocales()
public static function getAvailableLocales(): arrayLocalizer::getDefaultLocaleLang()
public static function getDefaultLocaleLang(): ?stringLocalizer::getFallbackLocaleLangs()
public static function getFallbackLocaleLangs(): arrayLocalizer::getAvailableLocaleLangs()
public static function getAvailableLocaleLangs(): arrayLocalizer::getDefaultLocaleCountry()
public static function getDefaultLocaleCountry(): ?stringLocalizer::getFallbackLocaleCountries()
public static function getFallbackLocaleCountries(): arrayLocalizer::getAvailableLocaleCountries()
public static function getAvailableLocaleCountries(): arrayLocalizer::getLocaleLangName()
public function getLocaleLangName(?string $locale = null): ?stringLocalizer::getLocaleLang()
public function getLocaleLang(?string $locale = null): stringLocalizer::getLocaleCountryName()
public function getLocaleCountryName(?string $locale = null): stringLocalizer::getLocaleCountry()
public function getLocaleCountry(?string $locale = null): stringLocalizer::normalizeLocale()
public static function normalizeLocale(string|array $locale, string $separator = self::SEPARATOR): string|arrayLocalizer::getTimezone()
public function getTimezone(): stringLocalizer::setTimezone()
public function setTimezone(string $timezone): selfLocalizer::getDefaultTimezone()
public static function getDefaultTimezone(): stringLocalizer::getAvailableTimezones()
public static function getAvailableTimezones(): arrayLocalizer::__toGMT()
public static function __toGMT(string $timezone): stringLocalizer::__toTimezone()
public static function __toTimezone(string $countryCode)Localizer::getCountry()
public function getCountry(): stringLocalizer::getCountryName()
public function getCountryName(?string $countryCode, ?string $displayLocale = null): stringA 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): selfLocalizer::__toSymbol()
public static function __toSymbol(string $currency)Localizer::getCurrency()
public function getCurrency(): stringLocalizer::setCurrency()
public function setCurrency(string $currency): selfLocalizerInterface interface
interface LocalizerInterface LocalizerInterface.php:5
LocalizerInterface::__toLocale()
public static function __toLocale(string $locale, ?string $separator = Localizer::SEPARATOR): stringLocalizerInterface::__toLocaleLang()
public static function __toLocaleLang(string $locale): stringLocalizerInterface::__toLocaleCountry()
public static function __toLocaleCountry(string $locale): stringLocalizerInterface::normalizeLocale()
public static function normalizeLocale(string|array $locale, string $separator = Localizer::SEPARATOR): string|arrayLocalizerInterface::getDefaultLocale()
public static function getDefaultLocale(): ?stringLocalizerInterface::getDefaultLocaleLang()
public static function getDefaultLocaleLang(): ?stringLocalizerInterface::getDefaultLocaleCountry()
public static function getDefaultLocaleCountry(): ?stringLocalizerInterface::getFallbackLocales()
public static function getFallbackLocales(): arrayLocalizerInterface::getFallbackLocaleLangs()
public static function getFallbackLocaleLangs(): arrayLocalizerInterface::getFallbackLocaleCountries()
public static function getFallbackLocaleCountries(): arrayLocalizerInterface::getAvailableLocaleLangs()
public static function getAvailableLocaleLangs(): arrayLocalizerInterface::getAvailableLocaleCountries()
public static function getAvailableLocaleCountries(): arrayLocalizerInterface::getAvailableLocales()
public static function getAvailableLocales(): arrayLocalizerInterface::markAsLate()
public static function markAsLate()LocalizerInterface::markAsChanged()
public function markAsChanged()LocalizerInterface::setCountry()
public function setCountry(string $countryCode): selfLocalizerInterface::setTimezone()
public function setTimezone(string $timezone): selfLocalizerInterface::getLocale()
public function getLocale(?string $locale = null): stringLocalizerInterface::setLocale()
public function setLocale(string $locale)LocalizerInterface::compatibleLocale()
public function compatibleLocale(string $locale, string $preferredLocale, ?array $availableLocales = null): boolLocalizerInterface::getLocaleLang()
public function getLocaleLang(?string $locale = null): stringLocalizerInterface::getLocaleLangName()
public function getLocaleLangName(?string $locale = null): ?stringLocalizerInterface::getLocaleCountry()
public function getLocaleCountry(?string $locale = null): stringLocalizerInterface::getLocaleCountryName()
public function getLocaleCountryName(?string $locale = null): stringLocalizerInterface::getCountryName()
public function getCountryName(?string $countryCode, ?string $displayLocale = null): stringLocalizerInterface::getDefaultTimezone()
public static function getDefaultTimezone(): stringLocalizerInterface::getAvailableTimezones()
public static function getAvailableTimezones(): arrayLocalizerInterface::getTimezone()
public function getTimezone(): stringLocator 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(): intMaintenanceProvider::getPercentage()
public function getPercentage(): intMaintenanceProvider::getDowntime()
public function getDowntime(): intMaintenanceProvider::getUptime()
public function getUptime(): intMaintenanceProvider::isUnderMaintenance()
public function isUnderMaintenance(): boolMaintenanceProvider::redirectOnDeny()
public function redirectOnDeny(?RequestEvent $event = null): boolThe 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(): intMaintenanceProviderInterface::getPercentage()
public function getPercentage(): intMaintenanceProviderInterface::getDowntime()
public function getDowntime(): intMaintenanceProviderInterface::getUptime()
public function getUptime(): intMaintenanceProviderInterface::isUnderMaintenance()
public function isUnderMaintenance(): boolMaintenanceProviderInterface::redirectOnDeny()
public function redirectOnDeny(?RequestEvent $event = null): boolMediaService 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|nullMediaService::video()
public function video(array|string|null $path, array $config = [], FilterInterface|array $filters = []): array|string|nullMediaService::soundify()
public function soundify(null|array|string $path, array $attributes = []): ?stringMediaService::vidify()
public function vidify(null|array|string $path, array $attributes = []): ?stringMediaService::image()
public function image(array|string|null $path, array $config = [], FilterInterface|array $filters = []): array|string|nullMediaService::imageBase64()
public function imageBase64(null|array|string $path): null|array|stringMediaService::imageSet()
public function imageSet(null|array|string $path, ...$srcset): null|array|stringMediaService::imagify()
public function imagify(null|array|string $path, array $attributes = [], ...$srcset): null|array|stringMediaService::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|nullMediaService::thumbnailInset()
public function thumbnailInset(array|string|null $path, ?int $width = null, ?int $height = null, array $config = [], FilterInterface|array $filters = []): array|string|nullMediaService::thumbnailOutbound()
public function thumbnailOutbound(array|string|null $path, ?int $width = null, ?int $height = null, array $config = [], FilterInterface|array $filters = []): array|string|nullMediaService::thumbnailNoclone()
public function thumbnailNoclone(array|string|null $path, ?int $width = null, ?int $height = null, array $config = [], FilterInterface|array $filters = []): array|string|nullMediaService::thumbnailUpscale()
public function thumbnailUpscale(array|string|null $path, ?int $width = null, ?int $height = null, array $config = [], FilterInterface|array $filters = []): array|string|nullMediaService::thumbnail()
public function thumbnail(array|string|null $path, ?int $width = null, ?int $height = null, array $config = [], FilterInterface|array $filters = []): array|string|nullMediaService::obfuscate()
public function obfuscate(string|null $path, array $config = [], FilterInterface|array $filters = []): ?stringMediaService::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|stringMediaService::generate()
public function generate(string $proxyRoute, array $proxyRouteParameters = [], ?string $path = null, array $config = []): ?stringMediaService::resolve()
public function resolve(string $data, FilterInterface|array $filters = []): arrayMediaService::serve()
public function serve(?string $file, int $status = 200, array $headers = []): ?ResponseMediaService::isCached()
public function isCached(?string $path, array $config = [], FilterInterface|array $filters = []): boolMediaService::filter()
public function filter(?string $path, array $config = [], FilterInterface|array $filters = []): ?stringMediaService::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 = []): boolMediaServiceInterface::resolve()
public function resolve(string $data): arrayMediaServiceInterface::image()
public function image(array|string|null $path, array $config = [], FilterInterface|array $filters = []): array|string|nullMediaServiceInterface::filter()
public function filter(?string $path, array $config = [], FilterInterface|array $filters = []): ?stringMediaServiceInterface::thumbnail()
public function thumbnail(array|string|null $path, ?int $width = null, ?int $height = null, array $config = [], FilterInterface|array $filters = []): array|string|nullMediaServiceInterface::audio()
public function audio(array|string|null $path, array $config = [], FilterInterface|array $filters = []): array|string|nullMediaServiceInterface::video()
public function video(array|string|null $path, array $config = [], FilterInterface|array $filters = []): array|string|nullMediaServiceInterface::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): ?ExchangeRateNullTrading::get()
public function get(string $from, string $to, array $options = []): ?ExchangeRateNullTrading::getFallback()
public function getFallback(string $source, ?string $target = null): ExchangeRate|array|nullNullTrading::getLatest()
public function getLatest(string $source, string $target, array $options = []): ?ExchangeRateNullTrading::isLive()
public function isLive(): boolNullTrading::setLive()
public function setLive(bool $live): staticNullTrading::convert()
public function convert(string|float $cash, string $source, string $target, array $options = [], string $timeAgo = 'now'): ?floatThe 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 = []): ?floatNullTrading::convertFallback()
public function convertFallback(string|float $cash, string $source, string $target): ?floatNullTrading::getRenderedCurrency()
public function getRenderedCurrency(): ?stringNullTrading::setRenderedCurrency()
public function setRenderedCurrency(?string $renderedCurrency)NullTrading::addFallback()
public function addFallback(string $source, string $target, mixed $value, null|string|int|DateTime $date = 'now'): selfNullTrading::removeFallback()
public function removeFallback(string $source, string $target): selfObfuscator class
class Obfuscator extends AbstractLocalCache implements ObfuscatorInterface Obfuscator.php:12
Obfuscator::warmUp()
public function warmUp(string $cacheDir, ?string $buildDir = null): arrayObfuscator::__construct()
public function __construct(ParameterBagInterface $parameterBag, string $cacheDir, ?string $buildDir = null, iterable $compressions = [])$compressionsthe 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): selfObfuscator::removeCompression()
public function removeCompression(CompressionInterface $compression): selfObfuscator::getCompressions()
public function getCompressions(): arrayObfuscator::getCompression()
public function getCompression(string $idOrClass): ?CompressionInterfaceObfuscator::getUuid()
public function getUuid(string $name): ?UuidV5Obfuscator::encode()
public function encode(array $value, bool $short = Obfuscator::NO_SHORT): stringObfuscator::decode()
public function decode(string $hash, bool $short = Obfuscator::NO_SHORT): ?arrayObfuscatorInterface interface
interface ObfuscatorInterface ObfuscatorInterface.php:5
const NO_SHORT = falseconst USE_SHORT = true
ObfuscatorInterface::encode()
public function encode(array $value, bool $short = Obfuscator::NO_SHORT): stringObfuscatorInterface::decode()
public function decode(string $hash, bool $short = Obfuscator::NO_SHORT): ?arrayOpeningHours 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)$defaultWeekISO day => hours, until a week is saved
OpeningHours::for()
public function for(string|object|null $scope): staticThe 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(): ?stringThe place this instance answers for; null: the whole site.
OpeningHours::scopeOf()
public static function scopeOf(object $place): stringAn entity as a scope key: its class and its id ("App\Entity\Store:12").
OpeningHours::reset()
public function reset(): voidA worker serves many requests: each reads the hours again.
OpeningHours::timezone()
public function timezone(): \DateTimeZoneOpeningHours::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): ?SpecialDayOpeningHours::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): arrayThe special days visitors should hear about: running today, or starting within $days.
OpeningHours::schema()
public function schema(): arrayschema.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(): arrayThe 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): boolOpeningHours::isOpenAt()
public function isOpenAt(?\DateTimeInterface $at = null): boolOpeningHours::nextOpenDay()
public function nextOpenDay(\DateTimeInterface $day): ?\DateTimeImmutableThe next day the place opens, $day itself when it does. Null: closed for a year.
OpeningHours::orderDay()
public function orderDay(?\DateTimeInterface $at = null): \DateTimeImmutableThe 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): arrayWindows 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$querythe 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|nullParameterBagInterface::set()
public function set(string $path, array|bool|string|int|float|UnitEnum|null $value, ?array &$bag = null): voidParameterBagInterface::has()
public function has(string $path, ?array $bag = null): boolParameterBagInterface::all()
public function all(): arrayEvery 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)$reada setting's value, null when none is stored
ReadSettings::clearAll()
public function clearAll()ReadSettings::all()
public function all(?string $locale = null): arrayReadSettings::get()
public function get(null|string|array $path = null, ?string $locale = null): arrayReadSettings::getScalar()
public function getScalar(null|string|array $path, ?string $locale = null): mixedReadSettings::getBagParameters()
public function getBagParameters(): arrayReadSettings::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): ?RedirectResponseRedirections::add()
public function add(string $source, string $target, int $status = Redirection::PERMANENT, bool $flush = true): RedirectionAdds 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(): stringReferrer::__construct()
public function __construct(Requests|RequestStack|null $requests, AdvancedRouterInterface $router)$requestsSymfony's RequestStack is deprecated (until 6.0)
Referrer::redirect()
public function redirect(array $headers = []): RedirectResponseReferrer::isVetoed()
public function isVetoed(?string $routeName)Referrer::clear()
public function clear()Referrer::setUrl()
public function setUrl(?string $url)Referrer::sameSite()
public function sameSite(): boolReferrer::getUrl()
public function getUrl(): ?stringReferrerInterface interface
interface ReferrerInterface ReferrerInterface.php:5
ReferrerInterface::getUrl()
public function getUrl(): ?stringReferrerInterface::setUrl()
public function setUrl(?string $url)ReferrerInterface::clear()
public function clear()ReferrerInterface::sameSite()
public function sameSite(): boolSecurityPolicy 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)$requiredRolesroles whose holders must have a second factor (base.security.two_factor.required_roles)
$postponewhether the enrolment prompt offers a "not now" (base.security.two_factor.postpone)
$roleHierarchythe host's hierarchy; Security's RoleHierarchyInterface is deprecated (until 6.0)
$reachableRolesthe 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): boolIs 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): boolMay 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(): boolIs two-factor authentication offered to users at all?
SecurityPolicy::isTwoFactorMandatory()
public function isTwoFactorMandatory(?object $user = null): boolMust 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): boolDoes 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): boolDoes 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(): boolAre passkeys offered as a login method?
SecurityPolicy::isNewDeviceEmailEnabled()
public function isNewDeviceEmailEnabled(): boolShould signing in from an unrecognised browser send a confirmation email?
SecurityPolicy::hasSecondFactor()
public function hasSecondFactor(?object $user): boolDoes 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): boolMay 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): boolMay this user still enrol - i.e. is the feature switched on for them? (Never a demonstration account.)
SecurityPolicy::isNewDevicePromptEnabled()
public function isNewDevicePromptEnabled(): boolShould 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): boolShould 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): boolDoes 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): boolMay 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): arrayCompile 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(): boolThe 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)$unitOfWorkthe entity manager is deprecated (until 6.0): adapted by UnitOfWorks
SettingBag::invalidate()
public function invalidate(): voidDrop 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(): arrayFlat [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): arraySettingBag::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(): ?stringSettingBag::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): SettingSettingBag::getRawScalar()
public function getRawScalar(null|string|array $path = null, bool $useCache = true)SettingBag::getScalar()
public function getScalar(null|string|array $path, ?string $locale = null): mixedSettingBag::get()
public function get(null|string|array $path = null, ?string $locale = null, ?bool $useCache = true): arraySettingBag::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): arraySettingBagInterface::get()
public function get(null|string|array $path = null, ?string $locale = null): arraySettingBagInterface::getScalar()
public function getScalar(null|string|array $path, ?string $locale = null): mixedSettingBagInterface::getBagParameters()
public function getBagParameters(): arrayFlat [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 $valueslocale => 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)$valueslocale => 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): ?SharingAdapterInterfaceSharing::addAdapter()
public function addAdapter(SharingAdapterInterface $adapter): selfSharing::removeAdapter()
public function removeAdapter(SharingAdapterInterface $adapter): selfSharing::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)$unitOfWorkthe entity manager is deprecated (until 6.0): adapted by UnitOfWorks
Signatures::gateway()
public function gateway(?string $name = null): ?stringThe gateway envelopes go through by default: base.signatures.gateway, or the only one configured.
Signatures::isEnabled()
public function isEnabled(?string $name = null): boolSignatures::send()
public function send(object $subject, Request $request, ?string $gateway = null): EnvelopeSent 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): stringWhere $signer signs in the site's page; asked again each time (the providers' links expire).
Signatures::refresh()
public function refresh(Envelope $envelope): EnvelopeAsks the provider where it stands; kept, its events dispatched, its files kept once completed.
Signatures::remind()
public function remind(Envelope $envelope, ?string $signer = null): voidSignatures::cancel()
public function cancel(Envelope $envelope, ?string $reason = null): EnvelopeSignatures::notify()
public function notify(string $gateway, string $body, array $headers): Envelope|false|nullA 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): ?stringThe signed document, once completed and kept; null before.
Signatures::evidence()
public function evidence(Envelope $envelope): ?stringThe evidence of its signing (an audit trail, a certificate), once kept.
Signatures::subject()
public function subject(Envelope $envelope): ?objectThe 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)$viewsTwig's environment is deprecated (until 6.0)
Sitemapper::getSitemap()
public function getSitemap(Route $route): ?SitemapSitemapper::getHostname()
public function getHostname(): stringSitemapper::setHostname()
public function setHostname(string $hostname): selfSitemapper::register()
public function register(string|Route $routeOrName, array $routeParameters = [], ?string $lastMod = null): selfOne 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): selfSitemapper::registerAttributes()
public function registerAttributes(): selfSitemapper::get()
public function get(SitemapEntry|string|null $sitemapOrRouteName = null): ?SitemapEntrySitemapper::getAlternates()
public function getAlternates(SitemapEntry|string|null $sitemapOrRouteName = null)Sitemapper::serve()
public function serve(string $name, array $context = []): ResponseSitemapperInterface interface
interface SitemapperInterface SitemapperInterface.php:8
SitemapperInterface::getHostname()
public function getHostname(): stringSitemapperInterface::setHostname()
public function setHostname(string $hostname): selfSitemapperInterface::register()
public function register(string|Route $routeOrName, array $routeParameters = [], ?string $lastMod = null): selfSitemapperInterface::registerUrl()
public function registerUrl(string $url, ?string $lastMod = null): selfSitemapperInterface::registerAttributes()
public function registerAttributes(): selfSitemapperInterface::serve()
public function serve(string $name, array $context = []): ResponseSpamChecker 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)$requestsSymfony's RequestStack is deprecated (until 6.0)
$routerthe home page's address
SpamChecker::getLang()
public function getLang(): ?stringSpamChecker::getUrl()
public function getUrl(): ?stringThe 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(): ?ClassifierInterfaceThe classifier asked, or null when there is none.
SpamChecker::submission()
public function submission(SpamProtectionInterface $candidate, array $context = []): SubmissionWhat the classifier is told of a candidate.
$contextwhat 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): intSpamChecker::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): boolTeach 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): intSpamCheckerInterface::score()
public function score(SpamProtectionInterface $candidate, array $context = [], $api = SpamApi::AKISMET): intSpeculativeRequest 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): boolStorages 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(): DrivesThe storages, as omnidrive's drives.
Storages::getDrive()
public function getDrive(?string $storage = null): DriveA storage as an omnidrive drive: by its name, the default one when null.
Storages::hasStorage()
public function hasStorage(string $storageName): boolStorages::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): ?stringStorages::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): ?stringThe contents, null when there is no such file.
Storages::write()
public function write(string $path, string $contents, ?string $storage = null, array $config = []): boolWrites a new file: false when one is there already.
Storages::delete()
public function delete(string $path, ?string $storage = null): boolDeletes a file: false when there is none.
Storages::fileExists()
public function fileExists(string $path, ?string $storage = null): boolStorages::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 = []): boolStorages::mimeType()
public function mimeType(string $path, ?string $storage = null): ?stringStorages::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): stringThemizer::warmUp()
public function warmUp(string $cacheDir, ?string $buildDir = null): arrayThemizer::detectLayouts()
public function detectLayouts()Themizer::getAvailableModes()
public function getAvailableModes(): arrayThemizer::color_scheme()
public function color_scheme(): stringThemizer::getMode()
public function getMode(): ?arrayThemizer::getAvailableFilters()
public function getAvailableFilters(): arrayThemizer::getFilter()
public function getFilter(): ?arrayThemizer::getAudienceCategories()
public function getAudienceCategories(): arrayThemizer::getAudience()
public function getAudience(): ?arrayThemizer::getAvailableWidths()
public function getAvailableWidths(): arrayThemizer::width()
public function width(): ?arrayThemizer::getWidth()
public function getWidth(): ?arrayThemizer::getAvailableEvents()
public function getAvailableEvents(): arrayReturns the list of candidate themes (events) that are currently active.
Themizer::getEvent()
public function getEvent(): ?arrayThemizerInterface interface
interface ThemizerInterface ThemizerInterface.php:5
ThemizerInterface::getAvailableFilters()
public function getAvailableFilters(): arrayThemizerInterface::getFilter()
public function getFilter(): ?arrayThemizerInterface::getAvailableEvents()
public function getAvailableEvents(): arrayThemizerInterface::getEvent()
public function getEvent(): ?arrayThemizerInterface::getAvailableModes()
public function getAvailableModes(): arrayThemizerInterface::getMode()
public function getMode(): ?arrayThemizerInterface::color_scheme()
public function color_scheme(): stringThemizerInterface::getAvailableWidths()
public function getAvailableWidths(): arrayThemizerInterface::getWidth()
public function getWidth(): ?arrayThemizerInterface::width()
public function width(): ?arrayThemizerInterface::getAudienceCategories()
public function getAudienceCategories(): arrayThemizerInterface::getAudience()
public function getAudience(): ?arrayTimeMachine 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(): arrayTimeMachine::setExcludes()
public function setExcludes(array $excludes)TimeMachine::getSnapshotDir()
public function getSnapshotDir(): ?stringTimeMachine::setSnapshotDir()
public function setSnapshotDir(?string $snapshotDir)TimeMachine::assertEnoughFreeSpace()
public function assertEnoughFreeSpace(string $directory, array $excludes = [], float $factor = 2.2): voidRefuse 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 = []): ?intApparent 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(): ?intTimeMachine::setMaxCycle()
public function setMaxCycle(int $maxCycle)TimeMachine::getTimeLimit()
public function getTimeLimit(): ?DateTimeTimeMachine::setTimeLimit()
public function setTimeLimit(null|string|DateTime|int $timeLimit)TimeMachine::getCompression()
public function getCompression(): ?stringTimeMachine::setCompression()
public function setCompression(?string $compression)TimeMachine::getDatabase()
public function getDatabase(string $name): DatabaseTimeMachine::getDatabaseConfiguration()
public function getDatabaseConfiguration(string $name): DatabaseTimeMachine::getDatabaseList()
public function getDatabaseList(): arrayTimeMachine::getStorage()
public function getStorage(string $name): FilesystemTimeMachine::getStorageList()
public function getStorageList(): arrayTimeMachine::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): arrayTimeMachine::findByCycle()
public function findByCycle(int|array $storageNames = [], ?string $prefix = null, $cycle = -1): arrayTimeMachine::getLastCycle()
public function getLastCycle(array $files, ?string $prefix = null): intTimeMachine::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): ?stringTimeMachine::openArchive()
public function openArchive(string $output, bool $compression = false): ?stringTimeMachine::buildCompressedArchive()
public function buildCompressedArchive(string $output, string $directory, array $excludes = [], bool $verbose = true): ?stringTimeMachine::extractUserInfo()
public function extractUserInfo(string $output): ?stringTimeMachine::buildArchive()
public function buildArchive(string $output, string $directory, array $excludes = [], bool $compression = false, bool $verbose = true): ?stringTimeMachineInterface 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(): arrayThe database connections a backup can take, by name (since 5.0, for the console tasks: Base\Console\Task\TimeMachineSnapshot).
TimeMachineInterface::getStorageList()
public function getStorageList(): arrayThe 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$untilnull = 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)$livewhether 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): ?CurrencyApiInterfaceTrading::getRenderedCurrency()
public function getRenderedCurrency(): ?stringTrading::setRenderedCurrency()
public function setRenderedCurrency(?string $renderedCurrency)Trading::normalize()
public function normalize(string $source, string $target, mixed $value, null|string|int|DateTime $datetime): ?ExchangeRateTrading::getFallback()
public function getFallback(string $source, ?string $target = null): ExchangeRate|array|nullTrading::addFallback()
public function addFallback(string $source, string $target, mixed $value, null|string|int|DateTime $date = "now"): selfTrading::removeFallback()
public function removeFallback(string $source, string $target): selfTrading::addProvider()
public function addProvider(CurrencyApiInterface $provider): selfTrading::removeProvider()
public function removeProvider(CurrencyApiInterface $provider): selfTrading::setCacheTTL()
public function setCacheTTL(int $ttl)Trading::isLive()
public function isLive(): boolTrading::setLive()
public function setLive(bool $live): staticTrading::getLatest()
public function getLatest(string $source, string $target, array $options = []): ?ExchangeRateTrading::get()
public function get(string $from, string $to, array $options = [], string $timeAgo = "now"): ?ExchangeRateTrading::convert()
public function convert(string|float $cash, string $source, string $target, array $options = [], string $timeAgo = "now"): ?floatTrading::convertLatest()
public function convertLatest(string|float $cash, string $source, string $target, array $options = []): ?floatTrading::convertFallback()
public function convertFallback(string|float $cash, string $source, string $target): ?floatTradingInterface interface
interface TradingInterface TradingInterface.php:8
TradingInterface::normalize()
public function normalize(string $source, string $target, mixed $value, null|string|int|DateTime $datetime): ?ExchangeRateTradingInterface::get()
public function get(string $from, string $to, array $options = []): ?ExchangeRateTradingInterface::getFallback()
public function getFallback(string $source, ?string $target = null): ExchangeRate|array|nullTradingInterface::getLatest()
public function getLatest(string $source, string $target, array $options = []): ?ExchangeRateTradingInterface::isLive()
public function isLive(): boolWhether get()/getLatest() ask the providers when the options do not say ("use_swap").
TradingInterface::setLive()
public function setLive(bool $live): staticTradingInterface::convert()
public function convert(string|float $cash, string $source, string $target, array $options = [], string $timeAgo = "now"): ?floatTradingInterface::convertLatest()
public function convertLatest(string|float $cash, string $source, string $target, array $options = []): ?floatTradingInterface::convertFallback()
public function convertFallback(string|float $cash, string $source, string $target): ?floatTradingInterface::getRenderedCurrency()
public function getRenderedCurrency(): ?stringTradingInterface::setRenderedCurrency()
public function setRenderedCurrency(?string $renderedCurrency)TradingInterface::addFallback()
public function addFallback(string $source, string $target, mixed $value, null|string|int|DateTime $date): selfTradingInterface::removeFallback()
public function removeFallback(string $source, string $target): selfTranslator 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 = [])$applicationTextsthe 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(): ?stringThe 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): ?stringA 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): arrayThe 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): MessageCatalogueInterfaceTranslator::getCatalogues()
public function getCatalogues(): arrayTranslator::getLocale()
public function getLocale(): stringTranslator::setLocale()
public function setLocale(string $locale)Translator::getFallbackLocales()
public function getFallbackLocales(): arrayTranslator::transQuiet()
public function transQuiet(TranslatableMessage|string $id, array $parameters = array(), ?string $domain = null, ?string $locale = null, bool $recursive = true, bool $nullable = true): ?stringTranslator::trans()
public function trans(TranslatableMessage|string $id, array $parameters = array(), ?string $domain = null, ?string $locale = null, bool $recursive = true): stringTranslator::parseClass()
public function parseClass($class, string $parseBy = self::PARSE_NAMESPACE): stringTranslator::transExists()
public function transExists(TranslatableMessage|string $id, ?string $domain = null, ?string $locale = null, bool $localeCountry = true): boolTranslator::transRoute()
public function transRoute(string $routeName, ?string $domain = null): ?stringTranslator::transRouteExists()
public function transRouteExists(string $routeName, ?string $domain = null): boolTranslator::transEnum()
public function transEnum(?string $value, string $class, null|string|array $options = self::NOUN_SINGULAR): ?stringThe 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): boolTranslator::getEnumNouns()
public function getEnumNouns(): EnumNounsThe enumerations' words over this translator (EnumNouns).
Translator::transEntity()
public function transEntity(mixed $entityOrClassName, ?string $property = null, string|array $options = self::NOUN_SINGULAR): ?stringTranslator::transEntityExists()
public function transEntityExists(mixed $entityOrClassName, ?string $property = null, string|array $options = self::NOUN_SINGULAR): boolTranslator::exists()
public function exists(string $id, ?string $domain = null, ?string $locale = null): boolThe Translations contract's question (Omnibridge\Contract\Translations): whether the catalogue holds the key, as transExists() answers.
Translator::getEntityNouns()
public function getEntityNouns(): EntityNounsThe 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): stringA 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(): arrayTranslatorInterface::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): stringTranslatorInterface::transQuiet()
public function transQuiet(TranslatableMessage|string $id, array $parameters = [], ?string $domain = null, ?string $locale = null, bool $recursive = true): ?stringTranslatorInterface::transExists()
public function transExists(TranslatableMessage|string $id, ?string $domain = null, ?string $locale = null): boolTranslatorInterface::transTime()
public function transTime(int $time): stringTranslatorInterface::transEnum()
public function transEnum(?string $value, string $class, string|array $options = self::NOUN_SINGULAR): ?stringTranslatorInterface::transEnumExists()
public function transEnumExists(string $value, string $class, string|array $options = self::NOUN_SINGULAR): boolTranslatorInterface::transEntity()
public function transEntity(mixed $entityOrClassName, ?string $property = null, string|array $options = self::NOUN_SINGULAR): ?stringTranslatorInterface::transEntityExists()
public function transEntityExists(mixed $entityOrClassName, ?string $property = null, string|array $options = self::NOUN_SINGULAR): boolTranslatorInterface::transRoute()
public function transRoute(string $routeName, ?string $domain = null): ?stringTranslatorInterface::transRouteExists()
public function transRouteExists(string $routeName, ?string $domain = null): boolTrashManager 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)$unitOfWorkthe entity manager is deprecated (until 6.0): adapted by UnitOfWorks
TrashManager::expired()
public function expired(?DateTimeInterface $now = null, ?int $limit = null): arrayThe entries past their grace period at $now (now when null), the oldest first: what purge() destroys.
TrashManager::withTrash()
public function withTrash(Closure $callable): mixedRun something with trashed entities visible.
TrashManager::contents()
public function contents(?string $entityClass = null, ?int $limit = null, int $offset = 0): arrayTrashManager::count()
public function count(?string $entityClass = null): intTrashManager::entity()
public function entity(TrashBall $trashBall): ?objectThe 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): boolPut 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): boolDestroy 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): intDestroy 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)$unitOfWorkthe entity manager is deprecated (until 6.0): adapted by UnitOfWorks
VersionManager::history()
public function history(object $entity): arrayRevisions 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): arrayThe 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): stringA 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): ?WidgetWidgetProvider::getWidget()
public function getWidget(string $widgetName, bool $useCache = true): ?WidgetWidgetProvider::all()
public function all(bool $useCache = true): arrayWidgetProvider::allSlots()
public function allSlots(bool $useCache = true): arrayWidgetProvider::getSlot()
public function getSlot(string $widgetSlotName, bool $useCache = true): ?SlotWidgetProvider::getWidgetSlot()
public function getWidgetSlot(string $path, bool $useCache = true): ?SlotWidgetProviderInterface interface
interface WidgetProviderInterface WidgetProviderInterface.php:8
WidgetProviderInterface::all()
public function all(): arrayWidgetProviderInterface::allSlots()
public function allSlots(): arrayWidgetProviderInterface::get()
public function get(string $widgetName): ?WidgetWidgetProviderInterface::getSlot()
public function getSlot(string $widgetSlotName): ?SlotWysiwygEnhancer 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): boolWysiwygEnhancer::render()
public function render(mixed $html, array $options = []): stringWysiwygEnhancer::getTableOfContents()
public function getTableOfContents(mixed $html, ?int $maxLevel = null): arrayWysiwygEnhancer::enhanceHeadings()
public function enhanceHeadings(mixed $html, ?int $maxLevel = null, array $attrs = []): mixedWysiwygEnhancer::enhanceSemantics()
public function enhanceSemantics(mixed $html, null|array|string $words = null, array $attrs = []): mixedWysiwygEnhancer::enhanceMentions()
public function enhanceMentions(mixed $html, array $attrs = []): mixedWysiwygEnhancer::enhanceLinks()
public function enhanceLinks(mixed $html, array $attrs = []): mixedWysiwygEnhancer::enhanceMedia()
public function enhanceMedia(mixed $html, array $config = [], FilterInterface|array $filters = [], array $attrs = []): mixedWysiwygEnhancerInterface interface
interface WysiwygEnhancerInterface WysiwygEnhancerInterface.php:7
WysiwygEnhancerInterface::supports()
public function supports(mixed $json): boolWysiwygEnhancerInterface::render()
public function render(mixed $json, array $options = []): stringWysiwygEnhancerInterface::getTableOfContents()
public function getTableOfContents(mixed $json, ?int $maxLevel = null): mixedWysiwygEnhancerInterface::enhanceMentions()
public function enhanceMentions(mixed $html, array $attrs = []): mixedWysiwygEnhancerInterface::enhanceLinks()
public function enhanceLinks(mixed $html, array $attrs = []): mixedWysiwygEnhancerInterface::enhanceMedia()
public function enhanceMedia(mixed $html, array $config = [], FilterInterface|array $filters = [], array $attrs = []): mixedWysiwygEnhancerInterface::enhanceHeadings()
public function enhanceHeadings(mixed $json, ?int $maxLevel = null, array $attr = []): mixedWysiwygEnhancerInterface::enhanceSemantics()
public function enhanceSemantics(mixed $json, null|array|string $words = null, array $attr = []): mixedBase\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): stringBase\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 $uidpublic readonly string $titlepublic readonly \DateTimeImmutable $startpublic readonly ?\DateTimeImmutable $endpublic readonly bool $allDaypublic readonly string $descriptionpublic readonly ?string $locationpublic readonly ?float $latitudepublic readonly ?float $longitudepublic readonly ?string $urlpublic readonly bool $cancelledpublic readonly ?\DateTimeInterface $updatedAtpublic 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(): \DateTimeZoneCalendarEntry::effectiveEnd()
public function effectiveEnd(): \DateTimeImmutableThe end a calendar should show: the one given, else the start plus the default duration (a whole day: that day).
GoogleCalendarLink class
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.
const ENDPOINT = 'https://calendar.google.com/calendar/render'
GoogleCalendarLink::for()
public function for(CalendarEntry $entry): stringIcs 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): stringIcs::event()
public function event(CalendarEntry $entry): stringOne date as a VEVENT block, to put in a VCALENDAR.
Ics::escape()
public static function escape(string $text): stringA text value: backslash, semicolon, comma and line break escaped.
Ics::fold()
public static function fold(string $line): stringA 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): arrayLines 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)$unitOfWorkthe 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): stringThe 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): stringThe 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): ?objectThe 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): stringThis 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(): boolAn 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(): stringCollabTicketFactory::mint()
public function mint(string $room, array $user): ?stringCollabTicketFactory::verifyServiceToken()
public function verifyServiceToken(string $token, string $room): boolThis 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(): ?stringAutocompleteInterface::__autocompleteData()
public function __autocompleteData(): arrayAutovalidate class
class Autovalidate Autovalidate.php:8
Autovalidate::__construct()
public function __construct(TranslatorInterface $translator = null)Autovalidate::validate()
public function validate($value, Constraint ...$constraints): boolAutovalidateInterface 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): boolBreadcrumb::offsetUnset()
public function offsetUnset(mixed $offset): voidBreadcrumb::offsetGet()
public function offsetGet(mixed $offset): mixedBreadcrumb::offsetSet()
public function offsetSet(mixed $offset, mixed $value = []): voidBreadcrumb::count()
public function count(): intBreadcrumb::rewind()
public function rewind(): voidBreadcrumb::next()
public function next(): voidBreadcrumb::key()
public function key(): mixedBreadcrumb::valid()
public function valid(): boolBreadcrumb::current()
public function current(): mixedBreadcrumb::__construct()
public function __construct(AdvancedRouterInterface $router, TranslatorInterface $translator, array $options = [], ?string $template = null)Breadcrumb::getRequest()
public function getRequest(): ?RequestBreadcrumb::setRequest()
public function setRequest(Request $request): selfBreadcrumb::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): stringBreadcrumb::getController()
public function getController(?string $url = null): stringBreadcrumb::getRouter()
public function getRouter(): AdvancedRouterInterfaceBreadcrumb::setRouter()
public function setRouter(AdvancedRouterInterface $router)Breadcrumb::getTranslator()
public function getTranslator(): TranslatorInterfaceBreadcrumb::setTranslator()
public function setTranslator(TranslatorInterface $translator)Breadcrumb::getTemplate()
public function getTemplate(): stringBreadcrumb::setTemplate()
public function setTemplate(string $template)Breadcrumb::getOptions()
public function getOptions(): arrayBreadcrumb::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): stringCacheableInterface::__toKeyTTL()
public function __toKeyTTL(): ?intCacheableInterface::__toKeyTags()
public function __toKeyTags(): arrayClassAliases 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): ?stringThe Base class an App class is by convention, null for any other.
ClassAliases::register()
public static function register(): voidThe 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): arrayClassFinder::listed()
public static function listed(string $path): arrayThe 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): arrayThe 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(): ?arrayColorizeInterface::__colorizeStatic()
public static function __colorizeStatic(): ?arrayDevelopmentEnvironment 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): boolDevelopmentEnvironment::named()
public static function named(string $name, bool $debug = false): boolDuration 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): stringEntityNouns 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_ENTITYconst 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 = [])$namespacesthe bundles' entity namespaces and their prefixes (namespacesOf())
EntityNouns::namespacesOf()
public static function namespacesOf(iterable $bundles): arrayThe 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): stringThe 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): ?stringEntityNouns::entityExists()
public function entityExists(object|string $entityOrClass, ?string $property = null, string|array $options = TranslatorInterface::NOUN_SINGULAR): boolEnumNouns 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): ?stringThe 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): boolWhether 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): stringA 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(): CollectionGraphInterface::getConnexes()
public function getConnexes(): CollectionHtmlizeInterface interface
interface HtmlizeInterface HtmlizeInterface.php:5
HtmlizeInterface::__toHtml()
public function __toHtml(array $options = [], ...$args): ?stringIconizeInterface interface
interface IconizeInterface IconizeInterface.php:5
IconizeInterface::__iconize()
public function __iconize(): ?arrayIconizeInterface::__iconizeStatic()
public static function __iconizeStatic(): ?arrayIntlDateTime 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): stringIntlDateTime::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()LinkableInterface::__toLink()
public function __toLink(array $routeParameters = [], int $referenceType = Link::ABSOLUTE_PATH): ?stringLocaleNormalizer 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(): arrayEvery 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$availableLocalesthe default first, in omnibase's form
$localesevery language and its countries; intl's when null
LocaleNormalizer::lang()
public static function lang(string $locale, ?string $defaultLocale, ?array $locales = null): stringThe language of a locale: its first two letters when intl knows them, else the default locale's.
$localesevery language and its countries; intl's when null
LocaleNormalizer::here()
public static function here(string $locale): stringnormalize() 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): arrayThe 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(): intHow many rows in all.
Pages::slice()
public function slice(int $offset, int $limit): arrayThe 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")$arrayOrQuerythe rows: an array, or a query's Pages (a Doctrine Query is adapted)
Pagination::pages()
public static function pages(object $query): PagesThe 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): Querysince step F2e of the plan "omnibase agnostic": Base\Bridge\Doctrine\QueryPages::countQuery()
Pagination::rewind()
public function rewind(): voidPagination::next()
public function next(): voidPagination::count()
public function count(): intPagination::key()
public function key(): mixedPagination::valid()
public function valid(): boolPagination::current()
public function current(): mixedPagination::getBookmark()
public function getBookmark(): mixedPagination::get()
public function get()- Returns
the rows: the array, or the query's Pages
Pagination::getQuery()
public function getQuery(): ?QueryThe 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(): stringSelectInterface interface
interface SelectInterface SelectInterface.php:5
SelectInterface::getIcon()
public static function getIcon(string $id, int $index = -1): ?stringSelectInterface::getText()
public static function getText(string $id): ?stringSelectInterface::getHtml()
public static function getHtml(string $id): ?stringSelectInterface::getData()
public static function getData(string $id): ?arraySitemapEntry class
class SitemapEntry SitemapEntry.php:5
SitemapEntry::getLoc()
public function getLoc(): ?stringSitemapEntry::getLocale()
public function getLocale(): ?stringSitemapEntry::setLocale()
public function setLocale(string $locale): selfSitemapEntry::getPriority()
public function getPriority(): ?floatSitemapEntry::setPriority()
public function setPriority(float $priority): selfSitemapEntry::getLastMod()
public function getLastMod(): ?stringSitemapEntry::setLastMod()
public function setLastMod(string $lastMod): selfSitemapEntry::getChangeFreq()
public function getChangeFreq(): ?stringSitemapEntry::setChangeFreq()
public function setChangeFreq(string $changeFreq): selfSitemapEntry::hasAlternate()
public function hasAlternate(SitemapEntry $entry)SitemapEntry::getAlternates()
public function getAlternates(): arraySitemapEntry::addAlternate()
public function addAlternate(SitemapEntry $entry): selfSitemapEntry::removeAlternate()
public function removeAlternate(SitemapEntry $entry): selfSitemapEntry::__construct()
public function __construct($loc)SitemapEntry::toArray()
public function toArray(): arraySpamProtectionInterface interface
interface SpamProtectionInterface SpamProtectionInterface.php:8
SpamProtectionInterface::getSpamBlameable()
public function getSpamBlameable(): ?UserSpamProtectionInterface::getSpamText()
public function getSpamText(): ?stringSpamProtectionInterface::getSpamDate()
public function getSpamDate(): DateTimeSpamProtectionInterface::getSpamCallback()
public function getSpamCallback(int $score)WorkflowInterface interface
interface WorkflowInterface extends WorkflowInterface WorkflowInterface.php:5
WorkflowInterface::getWorkflowName()
public static function getWorkflowName(): stringWorkflowInterface::getWorkflowType()
public static function getWorkflowType(): stringWorkflowInterface::supports()
public static function supports(): arrayWorkflowInterface::supportStrategy()
public static function supportStrategy(): ?stringBase\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(): intPalette::getIterator()
public function getIterator(): ArrayIteratorPalette::getCount()
public function getCount(int $color): intPalette::getDominantColors()
public function getDominantColors(?int $limit = null): arrayPalette::fromFilename()
public static function fromFilename(string $filename, int|null $colorKey = null): selfPalette::fromGD()
public static function fromGD(GdImage $image, int|null $colorKey = null): selfPalette::load()
public function load($filenameOrImage, int|null $colorKey = null): PalettePalette::loadResource()
public function loadResource(GdImage|false $resource, int|null $colorKey = null): PaletteBase\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): boolA CSS colour name, or a "#RRGGBB" code.
Colors::getName()
public static function getName(string $color, ?string $displayLocale = null): stringA 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): arrayColors::getRGB()
public static function getRGB(string $color): arrayColors::getHexCode()
public static function getHexCode(string $color): stringA 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(): stringAbstractCurrencyApi::supports()
public function supports(string $key): boolAbstractCurrencyApi::getPriority()
public function getPriority(): intAbstractCurrencyApi::getOptions()
public function getOptions(): arrayAbstractCurrencyApi::getKey()
public function getKey(): ?stringCurrencyApiInterface interface
interface CurrencyApiInterface CurrencyApiInterface.php:5
CurrencyApiInterface::supports()
public function supports(string $key): boolCurrencyApiInterface::getPriority()
public function getPriority(): intCurrencyApiInterface::getOptions()
public function getOptions(): arrayCurrencyApiInterface::getKey()
public function getKey(): ?stringBase\Service\Model\Currency\Api
AbstractApi class
class AbstractApi extends AbstractCurrencyApi AbstractApi.php:9
AbstractApi::getOptions()
public function getOptions(): arrayCurrencyLayer class
class CurrencyLayer extends AbstractCurrencyApi CurrencyLayer.php:10
CurrencyLayer::__construct()
public function __construct(SettingBagInterface $settings, bool $enterprise = false)CurrencyLayer::getOptions()
public function getOptions(): arrayExchangeRatesApi class
class ExchangeRatesApi extends AbstractCurrencyApi ExchangeRatesApi.php:9
ExchangeRatesApi::getOptions()
public function getOptions(): arrayFixer class
class Fixer extends AbstractCurrencyApi Fixer.php:9
Fixer::getOptions()
public function getOptions(): arrayBase\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): arrayAbstractIconAdapter::getVersion()
public function getVersion(): stringAbstractIconAdapter::getContents()
public function getContents()AbstractIconAdapter::getMetadata()
public function getMetadata()AbstractIconAdapter::getEntries()
public function getEntries()AbstractIconAdapter::getEntry()
public function getEntry(?string $value = null): stringAbstractIconAdapter::iconify()
public function iconify(IconizeInterface|string $icon, array $attributes = []): stringIconAdapterInterface interface
interface IconAdapterInterface IconAdapterInterface.php:7
IconAdapterInterface::supports()
public function supports(IconizeInterface|string|null $icon): boolIconAdapterInterface::iconify()
public function iconify(IconizeInterface|string $icon, array $attributes): stringIconAdapterInterface::getName()
public static function getName(): stringIconAdapterInterface::getOptions()
public static function getOptions(): arrayIconAdapterInterface::getVersion()
public function getVersion(): stringIconAdapterInterface::getAssets()
public function getAssets(): arrayIconAdapterInterface::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(): stringBootstrapTwitterAdapter::getOptions()
public static function getOptions(): arrayBootstrapTwitterAdapter::__construct()
public function __construct(string $metadata, string $cacheDir, ?string $buildDir = null, ?string $stylesheet = null)BootstrapTwitterAdapter::getAssets()
public function getAssets(): arrayBootstrapTwitterAdapter::supports()
public function supports(IconizeInterface|string|null $icon): boolBootstrapTwitterAdapter::warmUp()
public function warmUp(string $cacheDir, ?string $buildDir = null): arrayBootstrapTwitterAdapter::getChoices()
public function getChoices(string $term = ""): arrayBootstrapTwitterAdapter::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(): stringFontAwesomeAdapter::getOptions()
public static function getOptions(): arrayFontAwesomeAdapter::getAssets()
public function getAssets(): arrayFontAwesomeAdapter::warmUp()
public function warmUp(string $cacheDir, ?string $buildDir = null): arrayFontAwesomeAdapter::supports()
public function supports(IconizeInterface|string|null $icon): boolFontAwesomeAdapter::getClass()
public function getClass(string $style): ?stringFontAwesomeAdapter::getChoices()
public function getChoices(string $term = ""): arrayFontAwesomeAdapter::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): boolAbstractCompression::getLevel()
public function getLevel(): intAbstractCompression::setLevel()
public function setLevel(int $level): staticAbstractCompression::getEncoding()
public function getEncoding(): ?stringAbstractCompression::setEncoding()
public function setEncoding(?string $encoding): staticAbstractCompression::getMaxLength()
public function getMaxLength(): intAbstractCompression::setMaxLength()
public function setMaxLength(int $maxLength): staticAbstractCompression::encode()
public function encode(string $data): ?stringAbstractCompression::decode()
public function decode(string $hex): ?stringCompressionInterface interface
interface CompressionInterface CompressionInterface.php:5
CompressionInterface::getName()
public function getName(): stringCompressionInterface::supports()
public function supports(string $name): boolCompressionInterface::encode()
public function encode(string $data): ?stringCompressionInterface::decode()
public function decode(string $hex): ?stringBase\Service\Model\Obfuscator\Compression
DeflateCompression class
class DeflateCompression extends AbstractCompression DeflateCompression.php:7
DeflateCompression::getName()
public function getName(): stringDeflateCompression::getEncoding()
public function getEncoding(): ?stringGzipCompression class
class GzipCompression extends AbstractCompression GzipCompression.php:7
GzipCompression::getName()
public function getName(): stringGzipCompression::getEncoding()
public function getEncoding(): ?stringHashidsCompression class
class HashidsCompression extends AbstractCompression HashidsCompression.php:8
HashidsCompression::__construct()
public function __construct(string $secret)HashidsCompression::getName()
public function getName(): stringHashidsCompression::getEncoding()
public function getEncoding(): ?stringHashidsCompression::isValid()
public function isValid(string $hash): boolNullCompression class
class NullCompression extends AbstractCompression NullCompression.php:7
NullCompression::getName()
public function getName(): stringZlibCompression class
class ZlibCompression extends AbstractCompression ZlibCompression.php:7
ZlibCompression::getName()
public function getName(): stringZlibCompression::getEncoding()
public function getEncoding(): ?stringBase\Service\Model\Sharing
AbstractSharingAdapter class
abstract class AbstractSharingAdapter implements SharingAdapterInterface, IconizeInterface AbstractSharingAdapter.php:10
AbstractSharingAdapter::__iconize()
public function __iconize(): ?arrayAbstractSharingAdapter::__construct()
public function __construct(Views|Environment $views)$viewsTwig's environment is deprecated (until 6.0)
AbstractSharingAdapter::getTemplate()
public function getTemplate(): stringAbstractSharingAdapter::generate()
public function generate(array $options, ?string $template = null): stringSharingAdapterInterface interface
interface SharingAdapterInterface SharingAdapterInterface.php:5
SharingAdapterInterface::getIdentifier()
public function getIdentifier(): stringSharingAdapterInterface::getUrl()
public function getUrl(): stringSharingAdapterInterface::getTemplate()
public function getTemplate(): stringSharingAdapterInterface::generate()
public function generate(array $options, ?string $template = null): stringBase\Service\Model\Sharing\Adapter
FacebookAdapter class
class FacebookAdapter extends AbstractSharingAdapter FacebookAdapter.php:7
FacebookAdapter::getIdentifier()
public function getIdentifier(): stringFacebookAdapter::getUrl()
public function getUrl(): stringFacebookAdapter::__iconizeStatic()
public static function __iconizeStatic(): ?arrayGooglePlusAdapter class
class GooglePlusAdapter extends AbstractSharingAdapter GooglePlusAdapter.php:7
GooglePlusAdapter::getIdentifier()
public function getIdentifier(): stringGooglePlusAdapter::getUrl()
public function getUrl(): stringGooglePlusAdapter::__iconizeStatic()
public static function __iconizeStatic(): ?arrayLinkedInAdapter class
class LinkedInAdapter extends AbstractSharingAdapter LinkedInAdapter.php:7
LinkedInAdapter::getIdentifier()
public function getIdentifier(): stringLinkedInAdapter::getUrl()
public function getUrl(): stringLinkedInAdapter::__iconizeStatic()
public static function __iconizeStatic(): ?arrayPinterestAdapter class
class PinterestAdapter extends AbstractSharingAdapter PinterestAdapter.php:7
PinterestAdapter::getIdentifier()
public function getIdentifier(): stringPinterestAdapter::getUrl()
public function getUrl(): stringPinterestAdapter::__iconizeStatic()
public static function __iconizeStatic(): ?arrayTumblrAdapter class
class TumblrAdapter extends AbstractSharingAdapter TumblrAdapter.php:7
TumblrAdapter::getIdentifier()
public function getIdentifier(): stringTumblrAdapter::getUrl()
public function getUrl(): stringTumblrAdapter::__iconizeStatic()
public static function __iconizeStatic(): ?arrayTwitterAdapter class
class TwitterAdapter extends AbstractSharingAdapter TwitterAdapter.php:7
TwitterAdapter::getIdentifier()
public function getIdentifier(): stringTwitterAdapter::getUrl()
public function getUrl(): stringTwitterAdapter::__iconizeStatic()
public static function __iconizeStatic(): ?arrayBase\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): stringHeadingEnhancer class
class HeadingEnhancer implements HeadingEnhancerInterface HeadingEnhancer.php:11
HeadingEnhancer::__construct()
public function __construct(UnitOfWork|EntityManagerInterface $unitOfWork, SluggerInterface $slugger)$unitOfWorkthe entity manager is deprecated (until 6.0): adapted by UnitOfWorks
HeadingEnhancer::toc()
public function toc(mixed $html, ?int $maxLevel = null): arrayHeadingEnhancer::enhance()
public function enhance(mixed $html, ?int $maxLevel = null, array $attrs = []): mixedHeadingEnhancerInterface interface
interface HeadingEnhancerInterface HeadingEnhancerInterface.php:5
HeadingEnhancerInterface::enhance()
public function enhance(string|array|null $strOrArray, ?int $maxLevel, array $attributes = []): mixedHeadingEnhancerInterface::toc()
public function toc(mixed $strOrArray, ?int $maxLevel): arrayLinkEnhancer class
class LinkEnhancer implements LinkEnhancerInterface LinkEnhancer.php:7
LinkEnhancer::enhance()
public function enhance(string|array|null $strOrArray, array $attributes = []): string|array|nullRewrites 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|nullMediaEnhancer 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|nullMediaEnhancerInterface interface
interface MediaEnhancerInterface MediaEnhancerInterface.php:7
MediaEnhancerInterface::enhance()
public function enhance(string|array|null $strOrArray, array $config = [], FilterInterface|array $filters = [], array $attributes = []): string|array|nullMentionEnhancer 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(): MentionsMentionEnhancer::getRepository()
public function getRepository(): Mentionssince omnibase 4.0 (step R28), the mentions by their interface: mentions()
MentionEnhancer::extractMentionees()
public function extractMentionees(string|array|null $strOrArray, array $attributes = []): arrayMentionEnhancer::enhance()
public function enhance(string|array|null $strOrArray, array $attributes = []): string|array|nullMentionEnhancerInterface interface
interface MentionEnhancerInterface MentionEnhancerInterface.php:7
MentionEnhancerInterface::mentions()
public function mentions(): MentionsThe mentions, by their interface (step R28).
MentionEnhancerInterface::getRepository()
public function getRepository(): Mentionssince omnibase 4.0 (step R28): mentions()
MentionEnhancerInterface::extractMentionees()
public function extractMentionees(string|array|null $strOrArray, array $attributes = []): arrayMentionEnhancerInterface::enhance()
public function enhance(string|array|null $strOrArray, array $attributes = []): string|array|nullSemanticEnhancer 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|nullSemanticEnhancerInterface interface
interface SemanticEnhancerInterface SemanticEnhancerInterface.php:5
SemanticEnhancerInterface::enhance()
public function enhance(string|array|null $strOrArray, null|array|string $words = null, array $attributes = []): string|array|nullBase\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)$unitOfWorkthe entity manager is deprecated (until 6.0): adapted by UnitOfWorks
WebPushService::isConfigured()
public function isConfigured(): boolWebPushService::getPublicKey()
public function getPublicKey(): ?stringWebPushService::createKeys()
public static function createKeys(): arrayWebPushService::countReachableUsers()
public function countReachableUsers(): intHow 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): arrayWebPushService::subscribe()
public function subscribe(User $user, array $subscription, ?string $userAgent = null): PushSubscriptionRegisters (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): boolWebPushService::sendToUsers()
public function sendToUsers(iterable $users, array $payload): intSends 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): stringThe SVG markup.
QrCode::dataUri()
public function dataUri(string $data, int $size = 600, int $margin = 0, string $format = 'svg'): stringA 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): arrayQrSheet::pages()
public function pages(iterable $items, string $layout = 'a4', int $skip = 0): arrayThe 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): stringThe 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): stringTicketSigner::verify()
public static function verify(string $token, string $secret, string $room): ?arrayA 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): ?JsonThe refusal of a request without the token, null with it.
ThreadActions::publish()
public function publish(string $slug, ?string $token): ?JsonThreadActions::hide()
public function hide(string $slug, ?string $token): ?JsonThreadActions::follow()
public function follow(string $slug, ?string $token): ?JsonThreadActions::unfollow()
public function unfollow(string $slug, ?string $token): ?JsonThreadActions::like()
public function like(string $slug, ?string $token): ?JsonThreadActions::unlike()
public function unlike(string $slug, ?string $token): ?JsonThreadSearch 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): arrayThe 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): voidInstalling 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(): ?AttributeReaderBaseTrait::getAttributeReader()
public static function getAttributeReader(): AttributeReaderBaseTrait::findSettingBag()
public static function findSettingBag(): ?SettingBagBaseTrait::getSettingBag()
public static function getSettingBag(): SettingBagBaseTrait::isEntity()
public static function isEntity(mixed $entityOrClassOrMetadata): boolWhether 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(): stringBaseTrait::getEnvironment()
public static function getEnvironment(): stringThe Environment contract's name when the registry has it (C9), else the kernel's, seeded at boot.
BaseTrait::getPublicDir()
public static function getPublicDir(): stringBaseTrait::getTemplateDir()
public static function getTemplateDir(): stringBaseTrait::getTranslationDir()
public static function getTranslationDir(): stringBaseTrait::getCacheDir()
public static function getCacheDir(): stringBaseTrait::getLogDir()
public static function getLogDir(): stringBaseTrait::getDataDir()
public static function getDataDir(): stringBaseTrait::getFixtureDir()
public static function getFixtureDir(): stringBaseTrait::findEntityHydrator()
public static function findEntityHydrator(): ?EntityHydratorInterfaceBaseTrait::getEntityHydrator()
public static function getEntityHydrator(): EntityHydratorInterfaceBaseTrait::findMediaService()
public static function findMediaService(): ?MediaServiceBaseTrait::getMediaService()
public static function getMediaService(): MediaServiceBaseTrait::findObfuscator()
public static function findObfuscator(): ?ObfuscatorBaseTrait::getObfuscator()
public static function getObfuscator(): ObfuscatorBaseTrait::findIconProvider()
public static function findIconProvider(): ?IconProviderBaseTrait::getIconProvider()
public static function getIconProvider(): IconProviderBaseTrait::findLocalizer()
public static function findLocalizer(): ?LocalizerInterfaceBaseTrait::getLocalizer()
public static function getLocalizer(): LocalizerInterfaceBaseTrait::findNotifier()
public static function findNotifier(): ?BaseNotifierInterfaceBaseTrait::getNotifier()
public static function getNotifier(): BaseNotifierInterfaceBaseTrait::findTranslator()
public static function findTranslator(): ?TranslatorInterfaceBaseTrait::getTranslator()
public static function getTranslator(): TranslatorInterfaceBaseTrait::findTrading()
public static function findTrading(): ?TradingInterfaceBaseTrait::getTrading()
public static function getTrading(): TradingInterfaceBaseTrait::findParameterBag()
public static function findParameterBag(): ?ParameterBagInterfaceThe 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): stringCacheableTrait::__toKeyTTL()
public function __toKeyTTL(): ?intCacheableTrait::__toKeyTags()
public function __toKeyTags(): arrayFrameworkAccessorsTrait 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(): ?BaseServicesince omnisense/omnibase 4.0: the contracts the facade answered
FrameworkAccessorsTrait::getDoctrine()
public static function getDoctrine(): ?ManagerRegistrysince omnisense/omnibase 4.0: the unit of work, the repositories
FrameworkAccessorsTrait::getObjectManager()
public static function getObjectManager(mixed $entity): ?ObjectManagersince omnisense/omnibase 4.0: the unit of work
FrameworkAccessorsTrait::getEntityManager()
public static function getEntityManager(bool $reopen = false): ?EntityManagerInterfacesince omnisense/omnibase 4.0: the unit of work
FrameworkAccessorsTrait::getRepository()
public static function getRepository(mixed $object = null): ?ObjectRepositorysince omnisense/omnibase 4.0: the repository by its interface, or UnitOfWorks::repositories()
FrameworkAccessorsTrait::getClassMetadataManipulator()
public static function getClassMetadataManipulator(): ?ClassMetadataManipulatorsince omnisense/omnibase 4.0: UnitOfWorks::shapes(), BaseTrait::isEntity()
FrameworkAccessorsTrait::getTokenStorage()
public static function getTokenStorage(): ?TokenStorageInterfacesince omnisense/omnibase 4.0: Runtime::access()
FrameworkAccessorsTrait::getRequestStack()
public static function getRequestStack(): ?RequestStacksince omnisense/omnibase 4.0: Runtime::sessions(), Runtime::locales()
FrameworkAccessorsTrait::getFirewallMap()
public static function getFirewallMap(): ?FirewallMapInterfacesince omnisense/omnibase 4.0: Runtime::routes()
FrameworkAccessorsTrait::getTwig()
public static function getTwig(): ?Environmentsince omnisense/omnibase 4.0: Omnibridge\Contract\Views (Runtime::views())
FrameworkAccessorsTrait::getSlugger()
public static function getSlugger(): ?SluggerInterfacesince omnisense/omnibase 4.0: symfony/string's AsciiSlugger, or an injected slugger
FrameworkAccessorsTrait::getRouter()
public static function getRouter(): ?AdvancedRouterInterfacesince omnisense/omnibase 4.0: Base\Contract\Link::to(), Runtime::urls()
ProxyTrait trait
trait ProxyTrait ProxyTrait.php:8
ProxyTrait::hasProxy()
public function hasProxy(): boolProxyTrait::getProxy()
public function getProxy(): ?objectProxyTrait::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): boolSimpleCacheTrait::deleteCache()
public function deleteCache(?string $key = null): boolSimpleCacheTrait::getCacheAdapter()
public function getCacheAdapter(): mixedSimpleCacheTrait::invalidateCache()
public function invalidateCache(?string $key = null): selfSimpleCacheTrait::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): mixedSingletonTrait 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): ?selfSingletonTrait::__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(): ?stringUserInfoTrait::getIp()
public static function getIp(): ?stringUserInfoTrait::getCountryCode()
public function getCountryCode(): ?stringUserInfoTrait::getTimezone()
public function getTimezone(): stringUserInfoTrait::setTimezone()
public function setTimezone(?string $timezone = null): selfBase\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): arrayThe 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): stringOverridingTranslator::isRewritten()
public function isRewritten(string $id, ?string $domain = null, ?string $locale = null): boolWhether 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): MessageCatalogueInterfaceOverridingTranslator::getCatalogues()
public function getCatalogues(): arrayOverridingTranslator::setLocale()
public function setLocale(string $locale): voidOverridingTranslator::getLocale()
public function getLocale(): stringOverridingTranslator::getFallbackLocales()
public function getFallbackLocales(): arrayThe 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): mixedWhat the inner translator offers beyond the interfaces.
OverridingTranslator::reset()
public function reset(): voidOverridingTranslator::invalidate()
public function invalidate(): voidForget 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)$translatorlazy: a Doctrine listener is built while Doctrine starts
TextOverrideCacheListener::postPersist()
public function postPersist(LifecycleEventArgs $args): voidTextOverrideCacheListener::postUpdate()
public function postUpdate(LifecycleEventArgs $args): voidTextOverrideCacheListener::postRemove()
public function postRemove(LifecycleEventArgs $args): voidTextOverrideCacheListener::postFlush()
public function postFlush(PostFlushEventArgs $args): voidBase\Twig
AppVariable class
class AppVariable AppVariable.php:21
public ReferrerInterface $referrerpublic Environment $twigpublic SettingBagInterface $settingBagpublic ParameterBagInterface $parameterBagpublic SiteVariable $sitepublic RandomVariable $randompublic EmailVariable $emailpublic AdminVariable $adminpublic LocalizerInterface $localizerpublic 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(): stringAssetPackage::stripPrefix()
public function stripPrefix(string $path): stringAssetPackage::getUrl()
public function getUrl(string $path): stringAssetPackage::getVersion()
public function getVersion(string $path): stringEnvironment 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): boolEnvironment::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): ?TagRendererInterfaceEnvironment::getAsset()
public function getAsset(string $url): stringEnvironment::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(): arrayBase\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(): arrayAnalyticsTwigExtension 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(): arrayAnalyticsTwigExtension::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(): arrayBreadgrinderTwigExtension::renderBreadcrumb()
public function renderBreadcrumb(Environment $twig, string $name, Request $request, array $options = []): ?stringClassTwigExtension class
final class ClassTwigExtension extends AbstractExtension ClassTwigExtension.php:12
ClassTwigExtension::getFunctions()
public function getFunctions(): arrayClassTwigExtension::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(): arrayClipboardTwigExtension::clipboard()
public function clipboard(Environment $twig, string $template, ?string $value, array $attributes = []): ?stringClipboardTwigExtension::clipboard_target()
public function clipboard_target(Environment $twig, string $template, ?string $target, array $attributes = []): ?stringCommonsTwigExtension 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(): CommonsThe neutral helper behind this extension (the screens' Pictures contract: Base\Bridge\Symfony\MediaPictures).
CommonsTwigExtension::getFunctions()
public function getFunctions(): arrayCommonsTwigExtension::getFilters()
public function getFilters(): arrayCommonsTwigExtension::picture()
public function picture(?string $image, ?int $width = null, ?int $height = null): ?stringA 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(): arrayDemoTwigExtension::accounts()
public function accounts(): arrayThe 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(): arrayDeployVersionExtension::getVersion()
public function getVersion(): stringEnumTwigExtension 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(): arrayEnumTwigExtension::getFilters()
public function getFilters(): arrayEnumTwigExtension::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|arrayEnumTwigExtension::transEnum()
public function transEnum(?string $value, string $class, null|string|array $options = TranslatorInterface::NOUN_SINGULAR): ?stringEnumTwigExtension::transEnumExists()
public function transEnumExists(string $value, string $class, string|array $options = TranslatorInterface::NOUN_SINGULAR): boolFormTwigExtension 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(): arrayFormTwigExtension::advancedForm()
public function advancedForm(): boolFormTwigExtension::getForm()
public function getForm(string $name): ?FormInterfaceFormTwigExtension::getView()
public function getView(string $name): ?FormViewFunctionTwigExtension 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(): arrayFunctionTwigExtension::getFilters()
public function getFilters(): arrayFunctionTwigExtension::crudify()
public function crudify(?object $entity, array $options = []): stringA 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): ?stringFunctionTwigExtension::mailparseName()
public function mailparseName(string|EmailRecipientInterface $recipient): ?stringFunctionTwigExtension::htmlify()
public function htmlify(?HtmlizeInterface $object, array $options = [], ...$args): ?stringFunctionTwigExtension::email()
public function email(array $context)FunctionTwigExtension::is_linkable()
public function is_linkable(mixed $value): boolFunctionTwigExtension::is_callable()
public function is_callable(mixed $value, bool $syntax_only = false, &$callable_name = null): boolFunctionTwigExtension::nargs()
public function nargs(callable $fn): intFunctionTwigExtension::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): arrayFunctionTwigExtension::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): mixedFunctionTwigExtension::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): boolFunctionTwigExtension::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): stringFunctionTwigExtension::render_javascript()
public function render_javascript(string $src, array $attributes = [], bool $keepIfNotFound = true): stringFunctionTwigExtension::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|stringA moment as a pattern says it, lowered (Base\View\Dates, in Twig's time zone).
FunctionTwigExtension::isMoment()
public static function isMoment(string $value): boolWhether 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 = []): stringFunctionTwigExtension::progress()
public function progress(Environment $env, \DateTime $start, \DateTime $end, array $parameters = []): stringFunctionTwigExtension::title()
public function title(string $name, array $parameters = [], ?string $domain = 'controllers', ?string $locale = null): stringFunctionTwigExtension::excerpt()
public function excerpt(string $name, array $parameters = [], ?string $domain = 'controllers', ?string $locale = null): stringFunctionTwigExtension::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): stringFunctionTwigExtension::highlight()
public function highlight(?string $content, string|array $pattern, $gateLength = -1)$gateLengthNumber of words before and after
FunctionTwigExtension::stringify()
public function stringify($value): stringFunctionTwigExtension::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(): WysiwygThe 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): arrayHtmlTwigExtension::getFunctions()
public function getFunctions(): arrayHtmlTwigExtension::renderLinkTags()
public function renderLinkTags(): stringHtmlTwigExtension::renderScriptTags()
public function renderScriptTags(): stringHtmlTwigExtension::renderHeadTags()
public function renderHeadTags(): stringHtmlTwigExtension::renderNoscriptTags()
public function renderNoscriptTags(): stringHtmlTwigExtension::renderBodyTags()
public function renderBodyTags(): stringIconTwigExtension 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(): arrayLinkTwigExtension 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(): arrayLinkTwigExtension::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(): arrayLocalizerTwigExtension 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(): arrayLocalizerTwigExtension::getFunctions()
public function getFunctions(): arrayLocalizerTwigExtension::renderCountry()
public function renderCountry(Environment $twig, array $options = [], string $template = '@Base/localizer/country_dropdown.html.twig'): ?stringLocalizerTwigExtension::renderTimezone()
public function renderTimezone(Environment $twig, array $options = [], string $template = '@Base/localizer/timezone_dropdown.html.twig'): ?stringLocalizerTwigExtension::renderCurrency()
public function renderCurrency(Environment $twig, array $options = [], string $template = '@Base/localizer/currency_dropdown.html.twig'): ?stringMailTwigExtension 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)$urlan address whole: a route's name, a path or an address (AdvancedRouter::getUrl() under Symfony)
MailTwigExtension::getFunctions()
public function getFunctions(): arrayMailTwigExtension::getFilters()
public function getFilters(): arrayMailTwigExtension::embed()
public function embed(Environment $twig, array $context, string $src, array $options = []): stringMailTwigExtension::url()
public function url(?string $name, array $parameters = []): ?stringMailTwigExtension::inlineCss()
public static function inlineCss(array $context, string $body, string ...$css): stringThe 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): stringMathTwigExtension class
final class MathTwigExtension extends AbstractExtension MathTwigExtension.php:8
MathTwigExtension::getFunctions()
public function getFunctions(): arrayMathTwigExtension::sqrt()
public function sqrt($value): floatMathTwigExtension::count()
public function count(\Countable|array $value, int $mode = COUNT_NORMAL): intMathTwigExtension::round()
public function round(int|float $num, int $precision = 0, int $mode = PHP_ROUND_HALF_UP): floatMediaTwigExtension 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(): arrayMediaTwigExtension::getTests()
public function getTests(): arrayMediaTwigExtension::getFilters()
public function getFilters(): arrayMediaTwigExtension::onDisk()
public function onDisk(string $file): boolMediaTwigExtension::links()
public function links(): LinkTwigExtensionThe 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): stringMediaTwigExtension::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(): arrayMenuTwigExtension::renderLocale()
public function renderLocale(Environment $twig, array $options = [], string $template = '@Base/localizer/locale_dropdown.html.twig'): ?stringMenuTwigExtension::renderModes()
public function renderModes(Environment $twig, array $options = [], string $template = '@Base/themizer/dropdown.html.twig'): ?stringMenuTwigExtension::renderFilters()
public function renderFilters(Environment $twig, array $options = [], string $template = '@Base/themizer/filters/dropdown.html.twig'): ?stringMenuTwigExtension::renderWidths()
public function renderWidths(Environment $twig, array $options = [], string $template = '@Base/themizer/widths/dropdown.html.twig'): ?stringNotificationTwigExtension 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(): arrayNotificationTwigExtension::unread()
public function unread(): intNotificationTwigExtension::latest()
public function latest(int $limit = 8): arrayNotificationTwigExtension::token()
public function token(): stringNotificationTwigExtension::pushKey()
public function pushKey(): stringNotificationTwigExtension::adminUrl()
public function adminUrl(Notification $notification): ?stringThe back-office page of what a notification is about, or null.
NotificationTwigExtension::pushAvailable()
public function pushAvailable(): boolOAuthTwigExtension 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(): arrayOAuthTwigExtension::isAvailable()
public function isAvailable(string $name): boolPaginatorTwigExtension 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(): arrayPaginatorTwigExtension::getSlidingControl()
public function getSlidingControl(Environment $twig, PaginationInterface $pagination, string $name, array $parameters = []): ?stringThe 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): ?stringPaginatorTwigExtension::getFirst()
public function getFirst(PaginationInterface $pagination, string $name, array $parameters = [], ?string $label = null): ?stringPaginatorTwigExtension::getFirstSeparator()
public function getFirstSeparator(PaginationInterface $pagination, string $separator): ?stringPaginatorTwigExtension::getFirstOnes()
public function getFirstOnes(PaginationInterface $pagination, string $name, array $parameters = [], ?string $label = null): ?arrayPaginatorTwigExtension::getPreviousOnes()
public function getPreviousOnes(PaginationInterface $pagination, string $name, array $parameters = [], ?string $label = null): ?arrayPaginatorTwigExtension::getPrevious()
public function getPrevious(PaginationInterface $pagination, string $name, array $parameters = [], ?string $label = null): ?stringPaginatorTwigExtension::getCurrent()
public function getCurrent(PaginationInterface $pagination, ?string $label = null): ?stringPaginatorTwigExtension::getNext()
public function getNext(PaginationInterface $pagination, string $name, array $parameters = [], ?string $label = null): ?stringPaginatorTwigExtension::getNextOnes()
public function getNextOnes(PaginationInterface $pagination, string $name, array $parameters = [], ?string $label = null): ?arrayPaginatorTwigExtension::getLast()
public function getLast(PaginationInterface $pagination, string $name, array $parameters = [], ?string $label = null): ?stringPaginatorTwigExtension::getLastOnes()
public function getLastOnes(PaginationInterface $pagination, string $name, array $parameters = [], ?string $label = null): ?arrayPaginatorTwigExtension::getLastSeparator()
public function getLastSeparator(PaginationInterface $pagination, string $separator): ?stringPaginatorTwigExtension::getFastForward()
public function getFastForward(PaginationInterface $pagination, string $name, array $parameters = [], ?string $label = null): ?stringPictureTwigExtension 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(): arrayPictureTwigExtension::getFilters()
public function getFilters(): arrayPictureTwigExtension::image()
public function image(array $context, array|string|null $path, array $config = [], array $filters = []): array|string|null$contextthe template's
$patha 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$contextthe template's
$patha 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$contextthe template's
$patha 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$contextthe template's
$patha 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$contextthe template's
$patha 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$contextthe template's
$patha 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$contextthe template's
$patha 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(): arraySemanticTwigExtension 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(): arraySharingFilter 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(): arraySharingFilter::getFunctions()
public function getFunctions(): arraySharingFilter::generate()
public function generate(LinkableInterface $url, string $identifier, array $options = [], ?string $template = null): ?stringTextsTwigExtension 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(): arrayTextsTwigExtension::render()
public function render(?string $htmlOrJson, array $options = []): string$optionsheadings, semantics, media, row_attr, hydrate
TextsTwigExtension::toc()
public function toc(?string $htmlOrJson, ?int $maxLevel = null): arrayThemizerTwigExtension 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(): arrayThemizerTwigExtension::getFunctions()
public function getFunctions(): arrayTradingTwigExtension class
final class TradingTwigExtension extends AbstractExtension TradingTwigExtension.php:11
TradingTwigExtension::__construct()
public function __construct(TradingInterface $tradingMarket)TradingTwigExtension::getFilters()
public function getFilters(): arrayTradingTwigExtension::getFunctions()
public function getFunctions(): arrayTradingTwigExtension::formatCurrency()
public function formatCurrency($amount, string $currency, array $attrs = [], ?string $locale = null): stringAn amount in the currency the visitor reads (Base\View\Money).
TradingTwigExtension::applyCurrencyRate()
public function applyCurrencyRate($amount, string $currency, array $attrs = [], ?string $locale = null): ?floatAn 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(): arrayWebpackTwigExtension class
final class WebpackTwigExtension extends AbstractExtension WebpackTwigExtension.php:9
WebpackTwigExtension::getFunctions()
public function getFunctions(): arrayWidgetTwigExtension 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(): arrayWidgetTwigExtension::render_slot()
public function render_slot(Environment $twig, string $slot, array $options = [], ?string $template = null): stringThe 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\SourceORDER OF RESOLUTION: 1. custom loader 2. default Symfony loader (and TwigComponent delegated loaders)
FilesystemLoader::exists()
public function exists(string $name): boolFilesystemLoader::getCacheKey()
public function getCacheKey(string $name): stringFilesystemLoader::isFresh()
public function isFresh(string $name, int $time): boolBase\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 = []): stringTagRendererInterface::renderFallback()
public function renderFallback(Response $response): ResponseBase\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): stringHtmlTagRenderer::reset()
public function reset(): voidWhat 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 = []): stringHtmlTagRenderer::renderFallback()
public function renderFallback(Response $response): ResponseWebpackTagRenderer 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): arrayWebpackTagRenderer::getMedia()
public function getMedia(string $filename): ?stringWebpackTagRenderer::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(): arrayWebpackTagRenderer::getEntryScriptTags()
public function getEntryScriptTags(): arrayWebpackTagRenderer::getEntrypoints()
public function getEntrypoints(): arrayWebpackTagRenderer::discoverEntrypoints()
public function discoverEntrypoints(?string $appJsonPath, array $breakpoints = []): boolReads 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): ?EntrypointLookupInterfaceWebpackTagRenderer::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'): boolWebpackTagRenderer::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): boolWebpackTagRenderer::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): stringWebpackTagRenderer::renderCssSource()
public function renderCssSource(string|array $entryName, ?string $packageName = null, ?string $entrypointName = null, ?string $htmlAttributes = null): stringWebpackTagRenderer::renderOptionalLinkTags()
public function renderOptionalLinkTags(null|string|array $entryName = null, ?string $packageName = null, ?string $entrypointName = null, array $htmlAttributes = []): stringWebpackTagRenderer::renderLinkTags()
public function renderLinkTags(null|string|array $entryName = null, ?string $packageName = null, ?string $entrypointName = null, array $htmlAttributes = []): stringWebpackTagRenderer::renderOptionalScriptTags()
public function renderOptionalScriptTags(null|string|array $entryName = null, ?string $packageName = null, ?string $entrypointName = null, array $htmlAttributes = []): stringWebpackTagRenderer::scriptAttributes()
public static function scriptAttributes(string $file, array $defaults = []): arrayHow 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 = []): stringWebpackTagRenderer::render()
public function render(string $name, ?array $context = [], ?string $packageName = null, ?string $entrypointName = null, array $htmlAttributes = []): stringWebpackTagRenderer::renderFallback()
public function renderFallback(Response $response): ResponseBase\Twig\Variable
AdminLinks class
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.
AdminLinks::__construct()
public function __construct(readonly Routes $routes, readonly Urls $urls)AdminLinks::crudify()
public function crudify(mixed $entity): ?stringAdminVariable 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()AdminVariable::logo()
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(): ?stringEmailVariable::slogan()
public function slogan(): ?stringEmailVariable::logo()
public function logo(): ?stringEmailVariable::address()
public function address(?string $locale = null): ?stringEmailVariable::age()
public function age(?string $locale = null): stringRandomVariable 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): arraySiteVariable::map()
public function map()SiteVariable::route()
public function route()SiteVariable::title()
public function title()SiteVariable::slogan()
public function slogan()SiteVariable::logo()
public function logo()SiteVariable::scheme()
public function scheme(?string $locale = null): ?stringSiteVariable::host()
public function host(?string $locale = null): ?stringSiteVariable::port()
public function port(?string $locale = null): ?stringSiteVariable::domain()
public function domain(?string $locale = null): ?stringSiteVariable::subdomain()
public function subdomain(?string $locale = null): ?stringSiteVariable::base_dir()
public function base_dir(?string $locale = null): stringSiteVariable::url()
public function url(?string $nameOrUrl = '', array $routeParameters = [], ?string $locale = null): stringSiteVariable::under_maintenance()
public function under_maintenance(): boolSiteVariable::launchdate()
public function launchdate(?string $locale = null): \DateTimeSiteVariable::is_launchedd()
public function is_launchedd(?string $locale = null): boolSiteVariable::age()
public function age(?string $locale = null): stringSiteVariable::is_newcomer()
public function is_newcomer(int $within = 0): boolWhether 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 $fieldspublic mixed $entity = null
ConstraintEntity::__construct()
public function __construct(array|string $fields, mixed $entity = null, ?string $message = null, ?array $groups = null, mixed $payload = null)$fieldsRequired: the field or combination of fields
$entityOptional: entity class or name
ConstraintEntity::getRequiredOptions()
public function getRequiredOptions(): arrayConstraintEntity::getDefaultOption()
public function getDefaultOption(): ?stringConstraintEntity::getTargets()
public function getTargets(): string|arrayConstraintEntityValidator class
abstract class ConstraintEntityValidator extends ConstraintValidator ConstraintEntityValidator.php:18
ConstraintEntityValidator::getOriginalEntity()
public function getOriginalEntity($entity)ConstraintEntityValidator::getEntityChangeSet()
public function getEntityChangeSet($entity): ?arrayConstraintEntityValidator::getClassMetadata()
public function getClassMetadata($entityName): ClassMetadataConstraintEntityValidator::buildViolation()
public function buildViolation(Constraint $constraint, $value = null): ConstraintViolationBuilderInterfaceConstraintEntityValidator::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): ConstraintViolationBuilderInterfaceBase\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): voidAlphanumericValidator class
class AlphanumericValidator extends ConstraintValidator AlphanumericValidator.php:10
AlphanumericValidator::validate()
public function validate($value, Constraint $constraint): voidFile 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_sizeA size in bytes (an integer: FileType's ceiling), a human readable string ("2MB", "500KB", etc.), or null (PHP's upload limit)
$mime_typesArray of allowed MIME types
$groupsValidation groups
$payloadMetadata
File::getAllowedMimeTypes()
public function getAllowedMimeTypes(): arrayFile::getMaxSize()
public function getMaxSize(): intFileValidator class
class FileValidator extends ConstraintValidator FileValidator.php:11
FileValidator::validate()
public function validate($value, Constraint $constraint): voidHexcode 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): voidNotBlank class
class NotBlank extends Constraint NotBlank.php:15
Constraint for the NotBlank validator.
public string $message = '@validators.not_blank'public bool $allowNull = falsepublic $normalizer = null
NotBlank::getTargets()
public function getTargets(): string|arrayNotBlank::__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 = 8const MIN_STRENGTH_FALLBACK = 0const MAX_STRENGTH_FALLBACK = 5public 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(): intPassword::getMinStrength()
public function getMinStrength(): intPassword::getMaxStrength()
public function getMaxStrength(): intPassword::requiresUppercase()
public function requiresUppercase(): boolPassword::requiresLowercase()
public function requiresLowercase(): boolPassword::requiresNumbers()
public function requiresNumbers(): boolPassword::requiresSpecials()
public function requiresSpecials(): boolPassword::requiresLength()
public function requiresLength(): boolPassword::__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): voidStringCaseEntity 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 = nullpublic string $repositoryMethod = 'findBy'public array|string $fields = []public ?string $errorPath = nullpublic 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(): arrayUnique::getDefaultOption()
public function getDefaultOption(): ?stringUnique::getTargets()
public function getTargets(): string|arrayUniqueEntity 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 = nullpublic ?string $entityClass = nullpublic string $repositoryMethod = 'findBy'public string|array $fields = []public ?string $errorPath = nullpublic 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): voidUniqueEntityValidator::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): voidBase\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): stringBell 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(): intBell::latest()
public function latest(int $limit = 8): arrayBell::token()
public function token(): stringBell::pushKey()
public function pushKey(): stringBell::adminUrl()
public function adminUrl(Notification $notification): ?stringThe back-office page of what a notification is about, or null.
Bell::pushAvailable()
public function pushAvailable(): boolCaptions 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): stringAny 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 = '')$assetan asset's address in the build (symfony/asset's packages under Symfony); "/<path>" without it
$publicDirthe application's public folder, where the uploads' paths start
Commons::embedUrl()
public function embedUrl(?string $url, bool $remote = true): ?arrayCommons::qrCode()
public function qrCode(string $data, int $size = 600): stringCommons::openingHours()
public function openingHours(string|object|null $scope = null): OpeningHoursThe 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): ?stringA 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)$translatorthe page's locale, when none is given
$timezonethe zone a moment is printed in, when none is given (PHP's default without it)
Dates::isMoment()
public static function isMoment(string $value): boolWhether 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|stringA 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.
$timezonethe zone, null for the default, false to keep UTC
$defaultthe 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): stringA 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(): boolDemo::accounts()
public function accounts(): arrayThe 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(): stringEnums 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): mixedAn 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|arrayThe 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): ?stringEnums::transEnumExists()
public function transEnumExists(string $value, string $class, string|array $options = TranslatorInterface::NOUN_SINGULAR): boolFormats 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): stringA link to write to an address.
Formats::mailparseEmail()
public static function mailparseEmail(string|EmailRecipientInterface $recipient): ?stringThe address of a recipient ("Name <address>", an address, a notifier's recipient).
Formats::mailparseName()
public static function mailparseName(string|EmailRecipientInterface $recipient): ?stringThe 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): ?stringThe 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): stringA 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): boolWhether 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): ?arrayThat many entries of a list taken at random, their keys kept.
Formats::colorName()
public static function colorName(string $hex): ?stringThe 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|falsepreg_split() with the subject first, as a filter reads it.
Formats::pad()
public static function pad(array $array = [], int $length = 0, mixed $value = null): arrayFormats::transforms()
public static function transforms(array $array = [], mixed $arrow = null): mixedA list given to a closure, as it is without one.
Formats::nargs()
public static function nargs(callable $fn): intThe number of parameters a callable takes.
Formats::isLinkable()
public static function isLinkable(mixed $value): boolFormats::methodExists()
public static function methodExists(mixed $object, string $method): boolFormats::instanceOf()
public static function instanceOf(mixed $object, string $class): boolFormats::shortClass()
public static function shortClass(object $object): stringAn object's class without its namespace, its first letter lowered ("blogPost").
Formats::staticCall()
public static function staticCall(string|object $class, string $method, mixed ...$args): mixedA 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): mixedA 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): mixedA value read along a property path ("author.name", or the path's parts), null where a step cannot be read.
Links class
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).
Links::__construct()
public function __construct(readonly ?\Closure $current = null)$currentwhether an address is the page's own; none is without it
Links::urlify()
public function urlify(LinkableInterface|string|null $urlOrPath, ?string $label = null, array $attributes = []): stringA 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.
Links::linkify()
public function linkify(mixed $urlOrLinkableObject): ?stringA 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(): arrayMenus::modes()
public function modes(): arrayMenus::filters()
public function filters(): arrayMenus::widths()
public function widths(): arrayMenus::timezone()
public function timezone(): arrayMenus::country()
public function country(): arrayMoney 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): stringAn 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): ?floatAn 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): stringAn amount formatted in a currency, as twig/intl-extra's format_currency() formats it.
$attrsthe 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 = []): arrayWhat the pagination's template (PaginationInterface::getTemplate()) is rendered with.
$parametersthe route's parameters
Pagination::rewind()
public function rewind(PaginationInterface $pagination, string $name, array $parameters = [], ?string $label = null): ?stringPagination::first()
public function first(PaginationInterface $pagination, string $name, array $parameters = [], ?string $label = null): ?stringPagination::firstSeparator()
public function firstSeparator(PaginationInterface $pagination, string $separator): ?stringPagination::firstOnes()
public function firstOnes(PaginationInterface $pagination, string $name, array $parameters = [], ?string $label = null): arrayPagination::previousOnes()
public function previousOnes(PaginationInterface $pagination, string $name, array $parameters = [], ?string $label = null): arrayPagination::previous()
public function previous(PaginationInterface $pagination, string $name, array $parameters = [], ?string $label = null): ?stringPagination::current()
public function current(PaginationInterface $pagination, ?string $label = null): ?stringPagination::next()
public function next(PaginationInterface $pagination, string $name, array $parameters = [], ?string $label = null): ?stringPagination::nextOnes()
public function nextOnes(PaginationInterface $pagination, string $name, array $parameters = [], ?string $label = null): arrayPagination::last()
public function last(PaginationInterface $pagination, string $name, array $parameters = [], ?string $label = null): ?stringPagination::lastOnes()
public function lastOnes(PaginationInterface $pagination, string $name, array $parameters = [], ?string $label = null): arrayPagination::lastSeparator()
public function lastSeparator(PaginationInterface $pagination, string $separator): ?stringPagination::fastForward()
public function fastForward(PaginationInterface $pagination, string $name, array $parameters = [], ?string $label = null): ?stringPictures 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$patha path, or several
$contextthe view's (its
email, itswarmup)
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|nullPictures::thumbnail()
public function thumbnail(array|string|null $path, ?int $width = null, ?int $height = null, array $config = [], array $filters = [], array $context = []): array|string|nullA 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): arrayThe 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): ViewsViewsAdapter::ofNullable()
public static function ofNullable(Views|Environment|null $views): ?ViewsWidgets 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): ?arrayThe 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)$storagethe 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$optionsheadings (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): arrayThe text's headings.