Vous lisez la série 4.x ; la série actuelle est 5.x. Lire 5.x
Lue dans les fichiers PHP du paquet au commit 80ca635dac21 : 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
BaseBundleclass14 methods · 1 constant
Base\ApiPlatform\Metadata\Resource\Factory
OverriddenResourceNameCollectionFactoryclassKeeps one API resource per class the application actually uses.
2 methods
AbstractAttributeclass49 methods
AttributeInterfaceinterface15 methods
AttributeReaderclass36 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
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): Doctrine's entity manager - Symfony's, or the one a Laravel host builds by hand on the same mapping -, 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
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
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).
NotifierStubclassThe stubs of App\Notifier\ (see AbstractBaseStub).
RepositoryStubclassThe stubs of App\Repository\ (see AbstractBaseStub).
ConfigurationclassWhat omnibase adds to an entity manager's configuration (plan "omnibase agnostique", C6): the `trash_filter` (soft-deleted rows hidden) and the `vault_filter` (rows of another environment hidden), the DQL functions (RAND, FIELD, JSON_EXTRACT, JSON_SEARCH, JSON_CONTAINS, JSON_ARRAY_POSITION, those whose library is installed), the empty list of tree walkers as the default hint. DoctrineConfigurationPass hands the same lists to DoctrineBundle's configuration service; apply() sets them on a configuration built by hand.
6 methods · 2 constants
DoctrineEntitiesclassBase\Database\Repository\Entities over a plain Doctrine EntityRepository (an entity that names no omnibase repository: the translations, the envelopes...), as ServiceEntityRepository answers it for omnibase's: its finders as they are, the entity manager's unit of work.
9 methods
DoctrineRepositoriesclassBase\Database\Repository\Repositories over Doctrine's entity manager (audit "lesringostars face au master plan", step R28): its repositories as they are when they are omnibase's (Entities already), a plain EntityRepository behind DoctrineEntities otherwise. byIds() and oneById() ask what Base\Field\Type\SelectType asked before: the same queries.
4 methods
Mappingclassomnibase's Doctrine mapping on an entity manager built by hand - no kernel, no container, no DoctrineBundle (plan "omnibase agnostique", C6):
3 methods
MappingDriverclassomnibase's mapping driver: the application's driver (attributes, a chain of them under DoctrineBundle), and around it what omnibase's ClassMetadataFactory did on a patched doctrine/orm (plan "omnibase agnostique", C6):
7 methods
MetadataSnapshotclassWhat an entity manager made of omnibase's mapping, as plain data that can be compared and written to JSON: for each class its ClassMetadata (every public property - table, inheritance, discriminator map and value, fields and their types, associations, cache, callbacks, repository...; the reflection left out, the id generator by its class), what each enabled SQL filter adds to a query of it, and the completor omnibase's attributes filled for it (aliases, hierarchy); then the DBAL types registered, by name.
2 methods
MySQLSchemaManagerclassDBAL's MySQL schema manager, with two things a column read back from the database needs to compare equal to its mapping (plan "omnibase agnostique", C6b; doctrine/dbal as published, without glitchr/doctrine-dc2type):
1 method
Registryclassdoctrine/persistence's ManagerRegistry over one entity manager and its connection, both named "default": what omnibase's repositories (Base\Database\Repository\ServiceEntityRepository) and the ClassMetadataManipulator are built from, where DoctrineBundle's `doctrine` service is not there (Base\Bridge\Doctrine\Mapping).
1 method
RepositoryFactoryclassThe repositories of an entity manager built by hand (Base\Bridge\Doctrine\ Mapping::getRepository(), or the configuration's repository factory when it is set before the entity manager is built): a repository built from the ManagerRegistry - omnibase's ServiceEntityRepository and the applications' repositories over it, `__construct(ManagerRegistry $registry, ?string $entityName = null)` - is given the registry (and the entity's class when it takes one); any other is built as Doctrine builds it, from the entity manager and the metadata. Under Symfony, DoctrineBundle's ContainerRepositoryFactory hands out the services.
4 methods
SchemaManagerFactoryclassThe schema managers of an omnibase connection (plan "omnibase agnostique", C6b): on MySQL and MariaDB, Base\Bridge\Doctrine\MySQLSchemaManager, which reads a SET column with its values and leaves out the "(DC2Type:...)" comments of before; on any other platform, the one the factory it wraps gives (DBAL's DefaultSchemaManagerFactory unless another is given).
2 methods
Typesclassomnibase's column types, registered with DBAL (plan "omnibase agnostique", C6): what BaseBundle::boot() and the bundle's doctrine.dbal.types did, in one place, for Symfony and for an entity manager built by hand.
5 methods
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`, PictureTwigExtension), the providers one may link (`oauth_available()`), web push and the back-office address of a notification (`push_available()`, `push_vapid_key()`, NotificationTwigExtension), 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 extensions without a circular service.
4 methods · 1 constant
ActionArgumentsclassWhat an action written once for every host is given under Symfony beyond its route's parameters (step R27 of the audit "lesringostars face au master plan"): `array $query`, the query string's values, and `array $body` (step R29), what a POST sent - its JSON object, else its form fields -, as omnibridge/laravel's Screen\Responder::action() gives them. A route parameter of either name keeps its own.
2 methods
ActionResultsclassAn action's result answered under Symfony (step R27 of the audit "lesringostars face au master plan"): an action written once for every host - a plain class whose #[Route] Symfony's router reads, as omnibridge/laravel's Routing\ActionRoutes does - returns a View, a Template, Json, a Shell, a File or a Redirect, and the ScreenResponder answers it; null from an action declared to return one of them is no such page (404).
3 methods
AuthListenersclassBase\Auth\'s listeners of omniauth's events, given what they read of a Symfony request (plan "omniauth", step AU7): the captcha's answer the sign-in form posted (GuardSignIn - at the top of the request, where the widget writes it, or under the form, as SignInGuard read it), and whether this browser declined the offer of a second factor (WarnNewDevice).
2 methods
FlysystemFilesclassOmnibridge\Contract\Files under Symfony: omnibase's Flysystem service (its storages from flysystem.yaml) and, for a remote storage, MediaService's image route - what Base\Database\Attribute\Uploader resolves a stored file to: a remote storage's file through the /images route first (no local file to link), a local storage's by its path under public/ (Flysystem::getPublic()); its web address is that path less the public directory, as the editor's uploads give it.
5 methods
LocalizerLocalesclassOmnibridge\Contract\Locales under Symfony: omnibase's Localizer (the request's locale, the site's default and fallbacks from base.yaml), its answers in a list.
4 methods
MediaPicturesclassThe Pictures contract under Symfony (plan "omnibase agnostique", C5): the answers of omnibase's `|picture` filter itself - a stored image's thumbnail by MediaService, an address or a public path as it is, an asset of the build - so a screen's images are those the templates printed.
2 methods
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:
3 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.
RouterRoutesclassThe Routes contract under Symfony (plan "omnibase agnostique", C4b): omnibase's advanced_router - the route collection's path of a route, the name its matcher gives an address (getRouteName()) - and the IconProvider's icons of a route, the answers an entity got through BaseTrait's getRouter() and getIconProvider().
4 methods
ScreenResponderclassAn action's result answered under Symfony: Symfony's adapter of Base\Screen\Negotiation (step R10 of the audit "lesringostars face au master plan" - the negotiation itself, HTML, JSON, omnibridge/react's protocol and its 409, is framework-free there; omnibridge/laravel's Screen\Responder is Laravel's adapter of it). What a controller hands back - a View (a screen of omnibase, plan "omnibase agnostique" C5), a Template, Json, a Shell, a File, or null for no such page - becomes Symfony's response: the request read as a Visit, the template rendered by Twig, the Answer made a Response (a JsonResponse for JSON data, a BinaryFileResponse for a file), its caching set. A Template rendered alone, and a Shell, keep omnibase's tags out of the page (`_omnibase_inject: false`, as a route default says it).
8 methods
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.
ServiceMediaclassThe Media contract under Symfony (plan "omnibase agnostique", C4b): omnibase's MediaService - its extension of a file, its obfuscation of the image route's data, its address of that route - the answers an entity got through BaseTrait's getMediaService(), the same strings.
4 methods
SettingBagWarmerclassThe settings' snapshot compiled at cache:warmup (plan "omnibase agnostique", C9): SettingBag's warmer, HttpKernel's side of it, so that SettingBag itself stands on psr/cache and Doctrine alone. Optional: the snapshot compiles on its first read anyway; an unreachable database warms nothing (SettingBag::warmUp()).
3 methods
SymfonyScreenContextclassThe screens' context under Symfony (plan "omnibase agnostique", C5): what omnibase's kernel.request subscribers and Twig globals gave the templates, asked once for the screen being answered.
4 methods
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.
WysiwygTextsclassThe Texts contract under Symfony (plan "omnibase agnostique", C5): the pipeline of omnibase's `|wysiwyg` and `|wysiwyg_toc` filters itself (mentions, links, media, headings, Editor.js's renderer or the HTML of the older editor), so a screen's text is the HTML the templates printed.
4 methods
AbstractBaseBundleclass27 methods
AbstractBaseConfigurationclass1 method
AbstractBaseExtensionclass3 methods
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
AbstractLocalCacheWarmerclass3 methods
AbstractLocalCacheWarmerInterfaceinterface1 method
CodeCachesClearerclasscache:clear is enough: it empties the pools that remember what the code says - the Doctrine mapping's metadata, the DQL's parsed queries, the router's compiled routes. An application keeps them in pools of its own (filesystem, the default clearer, which cache:clear does not call): a column added to an entity read as missing, a route added was "No valid route found", until cache:pool:clear --all.
2 methods
AttributeCacheWarmerclassIconCacheWarmerclass1 method
LocalizerCacheWarmerclassMetadataCacheWarmerclass1 method
SpreadsheetCacheWarmerclass3 methods
ThemizerCacheWarmerclassWebpackCacheWarmerclassThe entries of the application's build and of the core's, and their tags rendered once, kept in the cache - unless a build was being written when the cache was made (the web container restarted while Encore's watcher rebuilds: entrypoints.json absent, or without entries). What was read then is not kept: it used to stay until cache:pool:clear --all, every page without its stylesheets. The renderer reads the builds again on a request that finds none (WebpackTagRenderer::discoverIfNone()).
2 methods
ApplicationclassCommandclass2 methods
Consoleclass3 methods
ConsoleInterfaceinterface1 method
AutocompleteEntitiesCommandclass1 method
BaseMappingCommandclassCacheClearCommandclass6 methods · 1 property
CacheClearSessionsCommandclass1 method
DemoResetCommandclassThe demonstration back to what the fixtures say: what the `cron` container runs every night in the `demo` environment, and nowhere else.
1 method · 1 constant
DoctrineArrayUpgradeCommandclass1 method
DoctrineDatabaseImportCommandclass2 methods · 6 constants
EntityDiscriminatorCommandclass1 method
IconEntitiesCommandclass1 method
IconEnumsCommandclassMailTrapCommandclassHold outgoing mail during an incident, look at what was held, then throw away the wrong ones and let the rest go.
2 methods
NotifierCommandclassNotifierMailTestCommandclass1 method
ThreadPublishableCommandclass1 method
TimeMachineSnapshotBackupCommandclass1 method
TimeMachineSnapshotCommandclass2 methods
TimeMachineSnapshotRestoreCommandclass1 method
TimeMachineStorageCommandclass2 methods
TranslationCrudCommandclassTranslationEnumsCommandclassTranslationSettingsCommandclass1 method
TrashPurgeCommandclassEmpties the trash of everything past its grace period (`base.extension.empty_trash`, "+7 days" by default).
1 method
UploaderEntitiesCommandclass6 methods
UploaderImagesCommandclass3 methods
UploaderImagesCropCommandclass2 methods
UserCreateCommandclassAn account made from the command line - someone's own to test a site, a colleague's -, verified and approved, with a password it did not choose: generated and shown once (or given with --password), to be changed at its first sign-in (a "change-password" token, PasswordChangeSubscriber) unless --keep-password; e-mailed its username and password unless --no-email. A plain Symfony command (not Base\Console\Command, which wants a ConsoleOutput): it runs from scripts and tests too.
1 method
UserNotificationCommandclassThe notifications kept in the database: counted (an account's with --user, everyone's without), listed with --show, erased with --clear when read and older than base.user.notifications.expiry (or --expiry), with --clear-all when read, whatever their age.
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.
6 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
DemoControllerclassSigning in as a demonstration account in one click: the buttons of the sign-in page's "Demonstration accounts" panel (@Base/demo/_accounts.html.twig).
1 method · 1 constant
ErrorControllerclass3 methods
LocalizerControllerclass3 methods
MainControllerclass2 methods
ProfilerControllerclass3 methods
RescueControllerclassThe admin-firewall login ("rescue") entry point. Self-sufficient: it renders the admin extension's login page when base-bundle-admin is installed (@Admin/security/login.html.twig), and otherwise a fully self-contained fallback bundled here that depends on nothing external - no admin package, no third-party admin UI.
3 methods
SecurityControllerclass18 methods
ShortLinkControllerclass2 methods
SignatureControllerclassA signing provider's callback (glitchr/omnisign: Yousign, DocuSign, DocuSeal...): its signature checked by the gateway, the envelope it names asked again and kept (Base\Service\Signatures::notify()). Without glitchr/omnisign there is nothing to update: 404.
2 methods
SitemapControllerclass1 method
WidgetControllerclass2 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
ThreadControllerclass7 methods
ContactControllerclass2 methods
NotificationControllerclassThe notification center's HTTP surface: the list page, the push subscription registry, and the service worker itself (the bell's payload, read marks and removals: Base\Controller\Action\Notification).
7 methods · 1 constant
ThreadSearchControllerclass2 methods
UserProfileControllerclass3 methods
UserSearchControllerclass2 methods
UserSettingsControllerclass9 methods
AutocompleteControllerclass4 methods
AutovalidateControllerclass4 methods
DropzoneControllerclass5 methods · 4 constants
EditorControllerclass8 methods · 3 constants
MediaControllerclass11 methods
Eventsclass4 constants
AttributeSubscriberclass16 methods
DemoAccountLockSubscriberclassA demonstration account stays what its declaration says, whoever asks and through whichever form (registered in the `demo` environment only): its identifier, its address, its password, its second factor are put back before anything is written, it is not disabled, it is not deleted.
3 methods
IntlSubscriberclass10 methods
InverseCollectionCacheSubscriberclassKeeps the second-level cache's INVERSE collections true.
1 method
TrackingPolicySubscriberclass2 methods
Aliasclass7 methods · 3 properties
Associateclass9 methods · 1 property
BlameableclassClass Blameable package Base\AttributeReader\Abstract\Blameable
6 methods
CacheclassCaching to an entity or a collection.
9 methods · 3 properties · 11 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.
4 methods · 2 properties
OrderColumnclass6 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
Vaultclass17 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\Extension
ExtensionHookInterfaceinterface1 method
ExtensionInlineInterfaceinterfaceExtensionMetadataInterfaceinterface3 methods
ExtensionOptionInterfaceinterface2 methods
Base\Database\Common\Collections
OrderedArrayCollectionclass29 methods
EntityExtensionclass2 methods · 6 constants
EntityExtensionInterfaceinterfaceEntityHydratorclass10 methods · 14 constants
EntityHydratorInterfaceinterface3 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
DoctrineQueryEventArgsclass7 methods
TrashFilterclassHides soft-deleted rows from every read that goes through the ORM.
1 method
VaultFilterclass3 methods
Fieldclass2 methods
JsonArrayPositionclass3 methods · 2 properties · 1 constant
Randclass2 methods
ClassMetadataCompletorclass5 methods
ClassMetadataFactoryclassDoctrine's ClassMetadataFactory, as the applications name it in their doctrine.yaml (class_metadata_factory_name), on doctrine/orm as published: it uses nothing Doctrine keeps private (plan "omnibase agnostique", C6).
3 methods
ClassMetadataManipulatorclass69 methods · 1 constant
NamingStrategyclassomnibase's names for tables and columns: App\Entity\Thread\Tag is threadTag, App\Entity\User\Profile userProfile, Thread::$tags the join table thread_tags (thread_id, threadTag_id), a property its own name.
1 method
PlatformMiddlewareclass1 method
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
ServiceEntityParserclass4 methods · 62 constants
ServiceEntityRepositoryclassA repository of omnibase: Doctrine's EntityRepository, built from the ManagerRegistry contract (doctrine/persistence) as DoctrineBundle's ServiceEntityRepository is - `__construct(ManagerRegistry $registry, ?string $entityName = null)`, the entity's class guessed from the repository's name when not given - plus the finder language (findByStateAndLocale(), cacheOneBySlug(), countByDomain()...).
16 methods
DescriberclassThe description of an omnibase application's data (Omnibridge\Schema\ Description), built without any ORM from the entities' folders: their declarations read by reflection, omnibase's naming, and omnibase's rules in the order Doctrine's listeners run - the discriminators, the vaults, the order columns, the translations, the extensions, the targets resolved (audit "lesringostars face au master plan", R14).
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
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
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
ArrayTypeclassType that maps a PHP array to a clob SQL type.
5 methods
DateTimeTypeUTCclassDoctrine's `datetime` (and `datetimetz`) as omnibase overrides them with base.database.use_custom (BaseBundle::boot()): a \DateTime moved to UTC as it is written, read back as UTC.
EnumTypeclass18 methods
MySQLSetTypeclassA SET column as the database has it, its values in the column's `values` option, as DBAL's own EnumType is to an ENUM column: what Base\Bridge\Doctrine\MySQLSchemaManager reads a SET column as, so that it compares with the declaration of the Base\Database\Type\SetType it maps (SET('A', 'B'), the same values, the same order) and differs from it once the enumeration's values change. A mapping names its SetType, never this.
3 methods · 1 constant
SetTypeclass4 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
UtcDateTimeImmutableTypeclassA moment, written in UTC and read back as UTC (`utc_datetime_immutable`).
1 constant
UtcDateTimeTypeclassUtcDateTimeImmutableType's mutable twin (`utc_datetime`): a \DateTime written in UTC and read back as UTC, whatever zone PHP is in.
1 constant
AaguidclassThe model of a passkey's authenticator (its AAGUID), kept as the RFC 4122 text of a UUID (plan "omniauth", AU1). The column is that of web-auth/webauthn-symfony-bundle's `aaguid` type (a CLOB of length 36, TINYTEXT on MySQL), and so is the text (Symfony's Uuid as a string, lowercase); PHP's value is that text, not a Uuid object, so that Base\Entity\User\Passkey loads nothing of webauthn-lib nor symfony/uid. An object that is a UUID (a Stringable, as Symfony's Uuid) is written as its text.
3 methods · 1 constant
Base64classBytes kept as standard base64 text (plan "omniauth", AU1): a passkey's credential id and its public key (Base\Entity\User\Passkey). The column and the text are those of web-auth/webauthn-symfony-bundle's `base64` type, which wrote the table first (a CLOB, LONGTEXT on MySQL; base64 with its padding, ParagonIE's constant-time encoding giving PHP's own), so a row written by either is read by the other - without the bundle, and under its own name, so that a site keeping the bundle keeps the bundle's type too.
3 methods · 1 constant
TrustPathclassA passkey's attestation trust path, as the JSON it is kept in (plan "omniauth", AU1): `[]` for none (EmptyTrustPath), `{"x5c": [...]}` for a chain of certificates. The column and the text are those of web-auth/webauthn-symfony-bundle's `trust_path` type (a JSON column, what webauthn-lib's normalizer gives, encoded by json_encode() as Doctrine's JSON type encodes it); PHP's value is the decoded array, not a TrustPath object - webauthn-lib's TrustPathDenormalizer makes one of it.
1 constant
CountWalkerclass1 method
GroupByWalkerclass1 method · 1 constant
MysqlWalkerclass1 method · 1 constant
TranslatableWalkerclass3 methods · 4 constants
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
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
BaseConfigurationclass1 method
BaseExtensionclass3 methods
Base\DependencyInjection\Compiler
AbstractPassclassAbstractPass for handling tagged services or entities implementing a specific interface.
6 methods
Base\DependencyInjection\Compiler\Pass
AdminUrlGeneratorPassclassBinds Base\Routing\AdminUrlGeneratorInterface to whatever back-office is installed.
1 method
ApplicationTextsPassclassWhich texts the application wrote itself (its own translations/ directory), for the level of politeness (base.translator.politeness, docs/20-architecture/politeness.md).
2 methods
AttributePassclass4 methods
ContractsPassclassThe locator Base\Contract\Runtime reaches the contracts of the Foundation through (plan "omnibase agnostique", C4), handed to it by BaseBundle::boot() - omnisense/omnibridge's registry since A2, the host's contracts (Omnibridge\Contract\*) with omnibase's own (Nouns, Media, Pictures, Texts, the parameters) and the mailer: each contract by its interface's name, the service the container binds to that name - omnibridge/symfony's adapters and omnibase's (config/services/core.php), the framework's clock, event dispatcher and mailer, or an application's own binding, which wins as any alias does.
1 method · 4 constants
DoctrineConfigurationPassclassomnibase's Doctrine mapping on DoctrineBundle's entity managers, from the same lists and the same driver an entity manager built by hand gets from Base\Bridge\Doctrine\Mapping (plan "omnibase agnostique", C6):
1 method
EntityExtensionPassclass4 methods
FlysystemStoragesPassclassThe storages of Base\Service\Flysystem in a Symfony application without league/flysystem-bundle (plan "omnibase agnostique", C7b). The `flysystem` service reads the services tagged flysystem.storage by their `storage` name, which is what the bundle tags each storage of its configuration with; without the bundle registered, nothing is tagged, and omnibase gives its local storages here, where its demonstration keeps them - the images' cache under var/cache, the uploads and the editor's files under var/storage, each beside its public directory under public/.
1 method · 2 constants
GuardPassclassBase\Service\FormGuard's default captcha is glitchr/omnishield's (omnishield.challenge.gateway) - a parameter that exists only when omnishield's bundle is registered: read here, once every extension has loaded, rather than named in the service's definition. So is glitchr/ux-google's switch, for the sign-in's captcha (SignInGuard).
1 method
IconProviderPassclass4 methods
ObfuscatorCompressionPassclass4 methods
SharingPassclass4 methods
TagRendererPassclass4 methods
TextOverrideCachePassclassThe rewritten texts (Base\Translation\OverridingTranslator) are cached in the application's shared Redis pool when it declares one (cache.redis): the web, the worker and cron then agree after an edit. Otherwise cache.app.
1 method
TradingPassclass4 methods
TwigComponentPassclass1 method
WebauthnDeprecatedAliasPassclassWebauthnExtension (web-auth/webauthn-symfony-bundle 5.3) still aliases the deprecated PublicKeyCredentialSourceRepositoryInterface to the configured credential_repository, next to CredentialRecordRepositoryInterface. Nothing in the bundle or here asks for the deprecated name, but the alias forced PasskeyRepository to keep implementing it (an alias to an interface the class lacks fails `lint:container`), and implementing it raises a deprecation on every boot.
1 method
WebauthnMappingPassclassWebauthnBundle's own Doctrine mapping turned off (plan "omniauth", AU1).
2 methods
WorkflowPassclass5 methods
Base\DependencyInjection\Dumper
CliDumperclass2 methods
HtmlDumperclass
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.
6 methods
AbstractEventDispatcherclass21 methods · 1 constant
EventDispatcherInterfaceinterface6 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
ExtensionSubscriberclass5 methods
SettingSubscriberclassInvalidates SettingBag's compiled snapshot on any Setting/SettingIntl write, not just ones that went through SettingBag::set(). The admin CRUD (EasyAdmin's SettingCrudController / LayoutSettingListType) persists these entities via a plain flush() and never called SettingBag::set() at all, so without this listener an admin edit (e.g. the site logo) would keep serving the stale cached value until the next unrelated cache:clear.
4 methods
ThreadSubscriberclass7 methods
TrasheableSubscriberclassTurns `$em->remove()` into a soft delete for every entity carrying `#[Trasheable]` - Thread and, through it, articles, galleries, comments, guestbook messages, calendars and newsletters.
4 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).
8 methods · 2 constants
VersionableSubscriberclassRecords what changed, for every property carrying `#[Versionable]`.
3 methods
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 glitchr/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 glitchr/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 core's types Base\Database\Type\Passkey\{Base64, Aaguid, TrustPath} 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
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, which Symfony FormType renders it, where it is displayed, and how.
80 methods · 6 constants
FieldInterfaceinterface3 methods
FieldTraittraitFluent configuration surface shared by every field.
50 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
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
TextAlignclass3 constants
ArrayTypeclass8 methods
AssociationFileTypeclass7 methods
AssociationTypeclass7 methods
AttributeTypeclass7 methods
AudioTypeclass4 methods
AvatarTypeclass5 methods
BooleanTypeclass5 methods
ButtonTypeclass4 methods
CodeTypeclassA code of known length - a one-time code, a voucher, a PIN - typed one character per box. The boxes are presentation only: they feed a single hidden input that carries the field's real value, so the type is a plain TextType to the form (validation, data transformers, everything) and degrades to that hidden value when the script is not there.
4 methods
CollectionTypeclass6 methods
ColorPickerTypeclass6 methods · 25 constants
ColorTypeclass6 methods
CountryTypeclass11 methods
CropperTypeclass8 methods
CurrencyTypeclass3 methods · 2 constants
DateTimePickerTypeclass5 methods
DiscriminatorTypeclass6 methods
EditorTypeclass7 methods
EmojiPickerTypeclass5 methods
FileTypeclass7 methods
ForexTypeclass5 methods
GenderTypeclass3 methods
IconTypeclass6 methods · 1 property
ImageTypeclass5 methods
MoneyTypeclass4 methods · 3 constants
NumberTypeclass5 methods
PasswordTypeclass7 methods
QuadrantTypeclass7 methods
RoleTypeclass3 methods
RouteTypeclass4 methods
SelectTypeclass9 methods · 1 constant
SlugTypeclass5 methods
StateTypeclass3 methods
StockTypeclass4 methods
SubmitTypeclass3 methods
TranslatableTypeclass2 methods
TranslationTypeclass9 methods
VideoTypeclass4 methods
WysiwygTypeclass6 methods
FormFactoryclass3 methods
FormFactoryInterfaceinterfaceFormProcessorclass25 methods · 2 properties
FormProcessorInterfaceinterface12 methods
FormProxyclassThe forms of a request, by name. Reset between two requests (kernel.reset): a kernel that serves several - a test client's, a worker's - kept the sign-in form under "form:login", and the sign-up page, which asks for a processor of that name, rendered the sign-in form.
14 methods
FormProxyInterfaceinterface11 methods
AbstractModelclass1 method
AbstractTypeclass1 method
FormModelInterfaceinterface1 method
FormTypeInterfaceinterface1 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
FormTypeBootstrapExtensionclass9 methods
FormTypeCollabExtensionclassThis class activates real-time presence and autosave for any regular field: an input field, a select field, a select2 field, or another field type. This class is not specific to EditorType. This class adds a new `collab` form option, with three possible values: false (the default value), "autosave", or "live".
4 methods
FormTypeCollectionExtensionclass4 methods
FormTypeCsrfExtensionclass3 methods
FormTypeExtensionclass12 methods
FormTypeGuardExtensionclassThe option `guard` of a root form: Base\Service\FormGuard's checks, in their order (docs/20-architecture/guard.md).
5 methods
FormTypeTranslateExtensionclass3 methods
FormTypeWebpackExtensionclass5 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
FormGuessInterfaceinterface6 methods · 4 constants
FormGuessTraittrait9 methods
FormProcessorTraittrait1 method
ScaleNumberTransformerclassTransforms between a number type and a localized number with grouping (each thousand) and comma separators.
3 methods
StrippedNumberToLocalizedStringTransformerclassTransforms between a number type and a localized number with grouping (each thousand) and comma separators.
2 methods
CommentTypeclassThe comment form - small: a name, a message, an e-mail if one wants to be answered - on Base\Form\Model\CommentModel, which omnibase's FormTypeSpamExtension sends to Akismet. On top of it, for the robots that never reach Akismet: a trap field (`url`, hidden from people, filled by robots), the time the form was opened (`opened`), and - when glitchr/ux-google is installed and `recaptcha` is on - Google reCAPTCHA v3. Base\Service\CommentGuard reads the trap and the time.
2 methods
ContactTypeclassThe contact form, usable as it is by every site:
3 methods
LayoutSettingListTypeclass7 methods
LayoutWidgetListTypeclass7 methods
Login2FATypeclassThe six-digit code that confirms a new authenticator app (/settings/2fa): nothing is mapped, the controller checks the code against the pending secret.
2 methods
PrivacyTypeclassThe data-protection notice (GDPR) under a form that collects personal data, and if asked the box to tick before sending - one place for every site and bundle rather than a checkbox and a sentence each:
4 methods · 2 constants
SecurityLoginTokenTypeclass4 methods
SecurityLoginTwoFactorTypeclass2 methods
SecurityLoginTypeclass4 methods
SecurityRegistrationTypeclass3 methods
SecurityResetPasswordConfirmTypeclass1 method
SecurityResetPasswordTypeclass2 methods
ThreadSearchTypeclass2 methods
ThreadSearchbarTypeclass2 methods
UserProfileTypeclass3 methods
UserSearchTypeclassThe members' search (user_search): a name to look for. It had no field at all, so its page could not render the input its template asked for.
2 methods
UserSettingsTypeclass1 method
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
DoctrineDataCollectorclass3 methods
LocalizerDataCollectorclass6 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
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
BaseNotificationInterfaceinterface3 methods
BaseNotifierclass25 methods
BaseNotifierInterfaceinterface14 methods
BrowserPlusChannelclass3 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: Twig and symfony/mime, which every host has (Laravel's mail is Symfony's Mailer).
7 methods · 3 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.
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
ThreadIntlRepositoryclass1 method
ThreadRepositoryclass17 methods
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
UserRepositoryclass14 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
PageViewRepositoryclass7 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
PageVisitRepositoryclass4 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
VisitRepositoryclass6 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
LogRepositoryclassOrderingRepositoryclassRevisionRepositoryclass2 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
TrashBallRepositoryclass4 methods
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
ScopedWeekRepositoryclass4 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
SpecialDayRepositoryclass1 method
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
WeekDayHoursRepositoryclass2 methods
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
AttributeRepositoryclassImageCropRepositoryclass4 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
ImageRepositoryclass1 method
RedirectionRepositoryclass2 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
SemanticRepositoryclass1 method
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
SettingRepositoryclass2 methods
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
ShortLinkRepositoryclassTextOverrideRepositoryclass1 method
TooltipRepositoryclassWidgetRepositoryclass2 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
Base\Repository\Layout\Attribute
HyperlinkRepositoryclass
Base\Repository\Layout\Attribute\Adapter
ArrayAdapterRepositoryclassColorAdapterRepositoryclassCountryAdapterRepositoryclassImageAdapterRepositoryclassMoneyAdapterRepositoryclassNumberAdapterRepositoryclassPercentAdapterRepositoryclassScalarAdapterRepositoryclassScoreAdapterRepositoryclassTextAdapterRepositoryclass
Base\Repository\Layout\Attribute\Common
AbstractActionRepositoryclassAbstractRuleRepositoryclassAbstractScopeRepositoryclass
AttachmentRepositoryclassLinkRepositoryclassPageRepositoryclassRouteRepositoryclassSlotRepositoryclass1 method
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
Base\Repository\Layout\Widget\Set
BookRepositoryclassLinksetRepositoryclassMenuRepositoryclassNetworkRepositoryclassPaperclipRepositoryclass
CommentRepositoryclass5 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.
1 method
LikeRepositoryclass1 method
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
MentionRepositoryclass1 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
TagRepositoryclass4 methods
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
TaxonRepositoryclass
AddressRepositoryclassComplaintRepositoryclass1 method
ConnectionRepositoryclass2 methods
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
GroupRepositoryclassIdentityRepositoryclassThe accounts' identities at providers (Base\Entity\User\Identity, the userIdentity table); omniauth reads them through Base\Auth\UserIdentities.
2 methods
NotificationRepositoryclass2 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
PasskeyRepositoryclassThe passkeys (Base\Entity\User\Passkey), and WebauthnBundle's credential repository (plan "omniauth", AU1).
6 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.
PenaltyRepositoryclassPermissionRepositoryclassPushSubscriptionRepositoryclass1 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
SanctionRepositoryclassTokenRepositoryclass4 methods
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
Base\Repository\User\Attribute
GroupActionRepositoryclassGroupRuleRepositoryclassGroupScopeRepositoryclass
Base\Repository\User\Attribute\Scope
GroupAdapterRepositoryclassUserAdapterRepositoryclass
PdfResponseclassAn HTML page answered as a PDF, rendered by dompdf/dompdf - a suggested package: `composer require dompdf/dompdf`.
5 methods
XmlResponseclass3 methods
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
AdvancedRouterclass65 methods
AdvancedRouterInterfaceinterface52 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
AdvancedUrlGeneratorclass6 methods · 1 property
RouteTranslationsResourceLoaderclassRegisters config/routes_paths.yaml as a tracked resource so Symfony's config-cache rebuilds routes when it changes. Base\Attributes\Attribute\Route reads that file directly (not through Symfony's routing loaders), so without this, editing it alone — without touching any controller file — would leave the compiled route cache stale: AttributeClassLoader's freshness tracking is per-controller-class, not aware of this file at all.
2 methods · 1 constant
AdvancedUrlMatcherclass8 methods · 2 properties
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
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
AccessTokenHandlerclass2 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
LoginFormAuthenticatorclass6 methods · 3 constants
LoginRestrictionInterfaceinterfaceOAuthUserProviderclassBase\Security\UserProvider declared OAuth-aware, for hwi/oauth-bundle's firewalls (an `oauth` provider asks for its interface). The service Base\Security\UserProvider is this class when hwi/oauth-bundle is installed, UserProvider otherwise (config/services/form.php): the sites' security.yaml name the service, not the class.
RescueFormAuthenticatorclass2 constants
SignInCaptchaclassThe 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
SignInGuardclassThe sign-in's captcha, after a few failures (Base\Security\SignInCaptcha), under Symfony. Symfony's login_throttling is the first line (five tries a minute, per identifier and address); this one counts the failures from an address - whatever identifiers they tried - and from base.guard.sign_in_after of them on, the sign-in form carries the captcha (SecurityController::Login) and a sign-in without a valid token is refused before its password is even checked. A success forgets the count.
7 methods
SignOutclassThe sign-out's address, its token in it, for any host.
2 methods · 4 constants
UserCheckerclass3 methods
UserProviderclassThe users of the firewalls, by their identifier, refreshed from their row.
6 methods
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
DynamicSessionStorageclass1 method
DynamicSessionStorageFactoryclass2 methods
AccessVoterclass1 method · 6 constants
AdminVoterclass1 method · 1 constant
ComplaintVoterclassWho reads and answers a complaint (Base\Entity\User\Complaint).
1 method · 2 constants
PermissionVoterclassCustom fine-grained permission names, backed by Base\Entity\User\Permission and granted through group membership (or directly on the user). This is the "customizable by base or app classes" extensibility a plain ROLE_* hierarchy can't offer: base-bundle-admin's own SecurityVoter already delegates every permission string through isGranted(), so registering this voter is all that's needed for Actions::setPermission()/ Crud::setEntityPermission()/MenuItem::setPermission() to accept a custom tag like "ARTICLE.PUBLISH" alongside a plain ROLE_* string - no changes to base-bundle-admin required.
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. It is a lazy service - a ghost of this class until one of its methods reads a property - and the core injects it nowhere on a page's path any more: the core and the bundles ask the contracts (Base\Contract\Runtime) or the services they need.
53 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):
22 methods · 17 constants
GroupManagerclassThe one service that turns a score into an actual capability.
4 methods
HotParameterBagclass`parameter_bag` under Symfony: the container's parameters (Base\Service\ParameterBag) with the settings stored in the database laid over them - Base\Service\HotParameters, the Foundation's overlay, as DependencyInjection's ParameterBagInterface and ContainerBagInterface (plan "omnibase agnostique", C9). It decorates `parameter_bag` over Base\Service\ParameterBag; `parameter_bag`, the autowiring of Base\Service\ParameterBagInterface (and of DependencyInjection's two interfaces) and Runtime::parameters() are this one object.
7 methods
HotParameterBagInterfaceinterfaceThe parameters with the settings stored in the database laid over them, as DependencyInjection's ParameterBagInterface: what `parameter_bag` is under Symfony (Base\Service\HotParameterBag over Base\Service\HotParameters, plan "omnibase agnostique", C9).
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.
9 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.
3 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
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
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
ParameterBagclassThe Symfony adapter of omnibase's Base\Service\ParameterBagInterface: the container's parameters (it decorates `parameter_bag`), read by a dotted path as Base\Service\DottedParameterBag reads any (plan "omnibase agnostique", C9), and DependencyInjection's ParameterBagInterface and ContainerBagInterface as well, for the code that types those.
9 methods
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
Referrerclass8 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 glitchr/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 glitchr/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 · 1 constant
TimeMachineInterfaceinterface5 methods
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.
1 method
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
Paginationclass27 methods
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
AnalyticsSubscriberclass4 methods
DemoBackOfficeSubscriberclassThe back office in a demonstration (registered in the `demo` environment only): open to nobody with a password everyone knows. Two tiers, a secret each:
4 methods
DemoSubscriberclassTwo of the demonstration's safeguards (registered in the `demo` environment only, config/services/demo.php):
4 methods
EntityDispatcherFlushSubscriberclassFlushes what the entity dispatchers' listeners changed (a thread published by its "publishable" event, a user's welcome state...), once the flush that raised those events is completely over: when the response goes out, when a command ends, after each message a worker handles. See AbstractEventDispatcher::$flushPending for why not from postFlush.
3 methods
FlashBagSubscriberclass2 methods
HotParameterBagSubscriberclass3 methods
IntegritySubscriberclassRegistered by no configuration, on purpose: as written it would open a session on every main request, run `bin/console cache:clear` inside a web request on a Doctrine TypeError, and sign the user out (and clear the remember-me cookie) whenever one of its checks fails. A site that wants these checks registers it itself, knowing that.
10 methods · 1 constant
IsGrantedSubscriberclass3 methods
LocalizerSubscriberclass5 methods · 4 constants
MailTrapSubscriberclassStops mail at the last possible moment when the trap is armed.
3 methods
NewDeviceSubscriberclassReacts to an account being signed into from a browser it has not been signed into before: tells the user by email (administrator's switch), and on an account with no second factor, flags the session so the next page offers - once, optionally - to set up a one-time code (SecurityEnrolmentSubscriber, Base\Controller\Action\Settings\Enrolment).
3 methods
NotifierSubscriberclass3 methods
PageViewSubscriberclassRecords one Base\Service\Analytics::track() call per trackable request.
3 methods
PasswordChangeSubscriberclassAn account made with a password it did not choose (user:create) carries a "change-password" token: until its owner has chosen one, every page sends them to security_changePassword.
3 methods · 1 constant
ProfilerSubscriberclass4 methods
RedirectionSubscriberclassA page that is not found is looked up in the redirections (Base\Entity\Layout\Redirection) before the 404 is answered: the old addresses of a site taken over lead to its new pages.
3 methods
ReferrerSubscriberclassWhere a visitor comes back to after signing in: the last page they read.
7 methods
RequestScopedStateSubscriberclassClears static state that is really request-scoped, for processes that outlive a request: FrankenPHP worker mode and messenger consumers.
3 methods · 1 constant
RouterSubscriberclass4 methods
SecondLevelCacheConsoleSubscriberclassDoctrine's second-level cache emptied after a command that rewrites the database behind the ORM's back: doctrine:fixtures:load purges the tables with DELETE / TRUNCATE and numbers the new rows from 1 again, so the cache went on answering yesterday's entity for today's id (a product under another one's name, a deleted page still shown) until it expired.
4 methods · 1 constant
SecurityEnrolmentSubscriberclassSends a signed-in user to the enrolment prompt once, when a second factor is mandatory for this account - the administrator made it so for everyone, or the application requires it of one of the account's roles (base.security.two_factor.required_roles) - and the account has none.
3 methods
SecuritySubscriberclass10 methods
TemplatedEmailSubjectSubscriberclassA TemplatedEmail's subject written in its template:
3 methods
TwigSubscriberclass5 methods · 1 constant
ValidCacheSubscriberclassMarks the bundle cache as valid early in the request cycle. Sole survivor of the former EagerSubscriber: its eager-construction duty is obsolete now that AttributeReader's constructor is metadata-free (the heavy precompute moved to AttributeCacheWarmer) and BaseTrait statics resolve lazily through the base.runtime locator.
2 methods
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.
33 methods
CacheClearTraittraitCacheableTraittrait3 methods
ProxyTraittrait4 methods
SimpleCacheTraittrait9 methods
SingletonTraittrait6 methods
UserInfoTraittrait7 methods · 2 constants
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
Environmentclass11 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):
4 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
HtmlTwigExtensionclass9 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
UniqueEntityclassConstraint for UniqueEntity validation.
1 method · 7 properties · 1 constant
UniqueEntityValidatorclass1 method
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
BaseBundle class
class BaseBundle extends AbstractBaseBundle BaseBundle.php:31
const VERSION = '1.0.0'
BaseBundle::__construct()
public function __construct()BaseBundle::getCacheDir()
public function getCacheDir(): stringBaseBundle::getPublicDir()
public function getPublicDir(): stringBaseBundle::getSourceDir()
public function getSourceDir(): stringBaseBundle::getEnvironment()
public function getEnvironment(): stringBaseBundle::isBooted()
public function isBooted()BaseBundle::isDoctrineReady()
public function isDoctrineReady(): boolBaseBundle::isInvalid()
public function isInvalid(): boolBaseBundle::markCacheAsValid()
public function markCacheAsValid(): voidBaseBundle::warmUp()
public function warmUp()BaseBundle::boot()
public function boot(): voidBaseBundle::shutdown()
public function shutdown(): voidA kernel that shuts down handles no request any more. get_url() reads the main request first, through BaseService's static stack, which outlives the kernel: a request left on it (a test that pushed one and never popped it) was the current address of every call made after the kernel was gone, instead of PHP's globals.
BaseBundle::isBuilt()
public function isBuilt()BaseBundle::build()
public function build(ContainerBuilder $container): voidBase\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:34
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(): ?ClassMetadataManipulatorAbstractAttribute::getClassMetadataCompletor()
public static function getClassMetadataCompletor(mixed $entityOrClassOrMetadata): ?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): array|PersistentCollectionAbstractAttribute::getSerializer()
public static function getSerializer(): ?SerializerAbstractAttribute::isSerializable()
public static function isSerializable(AbstractAttribute $attribute): boolAbstractAttribute::getPropertyOwnerRepository()
public function getPropertyOwnerRepository($entity, string $property): EntityRepository- 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): ?objectAbstractAttribute::getOriginalEntity()
public static function getOriginalEntity($entity): ?object- Throws
MappingException
AbstractAttribute::getOriginalEntityData()
public static function getOriginalEntityData($entity): ?array- Throws
MappingException
AbstractAttribute::getOldEntity()
public static function getOldEntity($entity): ?objectAbstractAttribute::getOldEntityData()
public static function getOldEntityData($entity): ?arrayAbstractAttribute::hasField()
public static function hasField($entity, string $property): boolAbstractAttribute::getFieldValue()
public static function getFieldValue($entity, string $property)- Throws
Exception
AbstractAttribute::setFieldValue()
public static function setFieldValue($entity, string $property, $value): false|ClassMetadataManipulatorAbstractAttribute::hasProperty()
public static function hasProperty($entity, string $property): boolAbstractAttribute::getPropertyValue()
public static function getPropertyValue($entity, string $property)AbstractAttribute::setPropertyValue()
public static function setPropertyValue($entity, string $property, $value): ClassMetadataManipulatorAbstractAttribute::loadClassMetadata()
public function loadClassMetadata(ClassMetadata $classMetadata, string $target, ?string $targetValue = null): voidAbstractAttribute::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)AttributeInterface 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(): 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, 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.
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::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): boolUserAccounts class
class UserAccounts extends UserStore implements Accounts UserAccounts.php:27
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:23
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:19
What omniauth's stores over omnibase's tables share (plan "omniauth", §2.2, step AU4): Doctrine's entity manager - Symfony's, or the one a Laravel host builds by hand on the same mapping -, 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(protected readonly EntityManagerInterface $entityManager)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\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:22
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, protected readonly EntityManagerInterface $entityManager, protected readonly ?Accounts $accounts = null)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:17
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(protected readonly EntityManagerInterface $entityManager)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:20
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(protected readonly EntityManagerInterface $entityManager, protected readonly ?Notifier $notifier = null, protected readonly ?SignInMails $mails = null)$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\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:6
The stubs of App\Form\ (see AbstractBaseStub).
NotifierStub class
final class NotifierStub extends AbstractBaseStub NotifierStub.php:6
The stubs of App\Notifier\ (see AbstractBaseStub).
RepositoryStub class
final class RepositoryStub extends AbstractBaseStub RepositoryStub.php:6
The stubs of App\Repository\ (see AbstractBaseStub).
Base\Bridge\Doctrine
Configuration class
final class Configuration Configuration.php:25
What omnibase adds to an entity manager's configuration (plan "omnibase
agnostique", C6): the trash_filter (soft-deleted rows hidden) and the
vault_filter (rows of another environment hidden), the DQL functions
(RAND, FIELD, JSON_EXTRACT, JSON_SEARCH, JSON_CONTAINS, JSON_ARRAY_POSITION,
those whose library is installed), the empty list of tree walkers as the
default hint. DoctrineConfigurationPass hands the same lists to
DoctrineBundle's configuration service; apply() sets them on a
configuration built by hand.
const TRASH_FILTER = 'trash_filter'const VAULT_FILTER = 'vault_filter'
Configuration::filters()
public static function filters(): arrayConfiguration::numericFunctions()
public static function numericFunctions(): arrayConfiguration::stringFunctions()
public static function stringFunctions(): arrayConfiguration::defaultQueryHints()
public static function defaultQueryHints(): arrayConfiguration::apply()
public static function apply(OrmConfiguration $configuration): voidConfiguration::enableFilters()
public static function enableFilters(EntityManagerInterface $entityManager, string $environment): voidThe two filters on, the vault's for the environment given: what BaseBundle::boot() does.
DoctrineEntities class
final class DoctrineEntities implements Entities DoctrineEntities.php:19
Base\Database\Repository\Entities over a plain Doctrine EntityRepository (an entity that names no omnibase repository: the translations, the envelopes...), as ServiceEntityRepository answers it for omnibase's: its finders as they are, the entity manager's unit of work.
DoctrineEntities::__construct()
public function __construct(readonly EntityManagerInterface $entityManager, readonly EntityRepository $repository)DoctrineEntities::find()
public function find($id): ?objectDoctrineEntities::findAll()
public function findAll(): arrayDoctrineEntities::findBy()
public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null): arrayDoctrineEntities::findOneBy()
public function findOneBy(array $criteria, ?array $orderBy = null): ?objectDoctrineEntities::count()
public function count(array $criteria = []): intDoctrineEntities::persist()
public function persist($entity, bool $flush = false): voidDoctrineEntities::remove()
public function remove($entity, bool $flush = false): voidDoctrineEntities::flush()
public function flush(bool $autoclear = false)DoctrineRepositories class
final class DoctrineRepositories implements Repositories DoctrineRepositories.php:17
Base\Database\Repository\Repositories over Doctrine's entity manager (audit "lesringostars face au master plan", step R28): its repositories as they are when they are omnibase's (Entities already), a plain EntityRepository behind DoctrineEntities otherwise. byIds() and oneById() ask what Base\Field\Type\SelectType asked before: the same queries.
DoctrineRepositories::__construct()
public function __construct(readonly EntityManagerInterface $entityManager)DoctrineRepositories::of()
public function of(string $class): EntitiesDoctrineRepositories::byIds()
public function byIds(string $class, array $ids): arrayDoctrineRepositories::oneById()
public function oneById(string $class, mixed $id): ?objectMapping class
final class Mapping Mapping.php:80
omnibase's Doctrine mapping on an entity manager built by hand - no kernel, no container, no DoctrineBundle (plan "omnibase agnostique", C6):
$entityManager = Omnibridge\Doctrine\EntityManagers::create($connection, $paths, configure: Base\Bridge\Doctrine\Mapping::configure(...)); Base\Bridge\Doctrine\Mapping::register($entityManager, ['project_dir' => ..., 'environment' => 'prod']);
before the first metadata is read. It does what DoctrineBundle and the bundle do under Symfony:
- the class convention (Base\Service\Model\ClassAliases: App\Entity\X is Base\Entity\X where the application has none);
- the column types (Base\Bridge\Doctrine\Types): the core's, the enumerations of the core and of the project (src/Enum), those given;
- the configuration: omnibase's naming strategy, the filters and the DQL
functions (Base\Bridge\Doctrine\Configuration), the mapping driver wrapped
twice (omnibridge/doctrine's DeclarationDriver: the metadata built from the
classes' declarations, Omnibridge\Schema\Declaration, no longer from the
attributes read by Doctrine - audit R14; then Base\Bridge\Doctrine\MappingDriver:
the discriminator maps, the
resolveDiscriminatorevent); - the repositories built from a registry (Base\Bridge\Doctrine\Registry,
RepositoryFactory): configure() sets the factory on the configuration
before the entity manager exists (omnibridge/doctrine's
configure:), and the entity manager's own getRepository() hands them out; - the services the mapping reads through: the ClassMetadataManipulator (the completors: aliases, hierarchies), the AttributeReader (#[Alias], #[DiscriminatorEntry], #[Hierarchify], #[Cache], #[OrderColumn]...) with the parameters given and none of the framework's services;
- the listeners, in the order DoctrineBundle gives them: AttributeSubscriber and IntlSubscriber (the translations' mapping, their discriminators, the walker of a translatable's query), the targets resolved, the entity listeners attached, the tracking policy, the extensions' index, then the soft deletion, the revisions and the inverse collections' cache on flush;
- the trash and vault filters enabled, the vault for the environment.
Options: project_dir (the project's src/Enum and src/Attribute; the current directory by default), environment ("prod"), cache_dir (the reader's and the manipulator's caches; a folder of the system's temporary one by default), parameters (the application's, by full name: base.attributes.use_custom, base.extension.max_revisions...), types (by name, a bundle's enumerations), enumerations (more folders of enumerations), attribute_paths (more folders of attributes: a bundle's src/Attribute), resolve_target_entities (interface => class), entity_listeners (entity class => list of {event, class, method}: what a bundle tags doctrine.orm.entity_listener), localizer (a LocalizerInterface, none by default), flysystem (omnibase's Base\Service\Storages over the host's storages, none by default: the attributes that read a stored file - #[Uploader]'s public address of an upload, an article's audio - read it through the reader's; without it they cannot answer), services (a closure giving the host's service of a type, or null: what a repository takes beside the registry, a site's cache pool - RepositoryFactory::services()), filters (true: enabled).
Mapping::register()
public static function register(EntityManagerInterface $entityManager, array $options = []): selfMapping::configure()
public static function configure(\Doctrine\ORM\Configuration $configuration): voidWhat an entity manager built by hand needs set before it exists: the
repository factory (Doctrine keeps the one its configuration had at
new EntityManager). Given to omnibridge/doctrine's EntityManagers::create()
as its configure: closure; then the entity manager's getRepository()
builds omnibase's ServiceEntityRepository and the applications' over it
from the registry, as the bundle would.
Mapping::getRepository()
public function getRepository(string $className): EntityRepositorysince step C6's follow-up: build the entity manager with configure() (omnibridge/doctrine's `configure:`) and ask its own getRepository() - the same repository. Kept for an entity manager built without it, whose own factory is Doctrine's default.
The repository of an entity as the bundle would hand it out: omnibase's ServiceEntityRepository and the applications' over it are built from the ManagerRegistry (Base\Bridge\Doctrine\Registry).
MappingDriver class
final class MappingDriver implements PersistenceMappingDriver MappingDriver.php:38
omnibase's mapping driver: the application's driver (attributes, a chain of them under DoctrineBundle), and around it what omnibase's ClassMetadataFactory did on a patched doctrine/orm (plan "omnibase agnostique", C6):
- before the driver, the
resolveDiscriminatorevent (Base\Database\Events): IntlSubscriber gives a translation class the inheritance and the discriminator map of its translatable; then the discriminator value of a concrete class is looked up in its map, as the factory did; - the table names checked: two entity classes may not take the same one;
- after the driver, the discriminator map of a root entity that declares an inheritance and no map is generated: the class and every subclass the driver knows, each under its own class name. Doctrine would generate it itself, under the classes' short names - which collide here (App\Entity\ Thread\Tag, Base\Entity\Thread\Tag) - and its getShortName() is private: glitchr/base-plugin made it protected so that the factory could answer the class name. The map is now there before Doctrine looks, its keys those the factory gave, and #[DiscriminatorEntry] (AttributeSubscriber, loadClassMetadata) renames them as before.
Under Symfony the bundle wraps every entity manager's driver with it (DoctrineConfigurationPass); Base\Bridge\Doctrine\Mapping::register() does it for an entity manager built by hand. Doctrine's own ClassMetadataFactory is then enough: nothing here needs a member Doctrine keeps private.
MappingDriver::__construct()
public function __construct(readonly PersistenceMappingDriver $driver, EntityManagerInterface|\Closure|null $entityManager = null)MappingDriver::getDriver()
public function getDriver(): PersistenceMappingDriverMappingDriver::setEntityManager()
public function setEntityManager(EntityManagerInterface $entityManager): voidMappingDriver::loadMetadataForClass()
public function loadMetadataForClass(string $className, PersistenceClassMetadata $metadata): voidMappingDriver::getAllClassNames()
public function getAllClassNames(): arrayThe driver's classes, without the aliases: an attribute driver lists the classes PHP declared from its folders, and PHP lists a class_alias() among them, lower-cased (app\entity\thread\tag for App\Entity\ Thread\Tag, Base\Entity\Thread\Tag's alias). DoctrineBundle's chain dropped them by its namespaces' case; one attribute driver over every folder (an entity manager built by hand) did not.
MappingDriver::isTransient()
public function isTransient(string $className): boolMappingDriver::__call()
public function __call(string $method, array $arguments): mixedWhat else the application's driver answers (MappingDriverChain::getDrivers()...).
MetadataSnapshot class
final class MetadataSnapshot MetadataSnapshot.php:28
What an entity manager made of omnibase's mapping, as plain data that can be compared and written to JSON: for each class its ClassMetadata (every public property - table, inheritance, discriminator map and value, fields and their types, associations, cache, callbacks, repository...; the reflection left out, the id generator by its class), what each enabled SQL filter adds to a query of it, and the completor omnibase's attributes filled for it (aliases, hierarchy); then the DBAL types registered, by name.
A mapping object's properties left null or false are left out (read back from the metadata cache, a field's nullable, unique and index are null where a mapping just built says false); the discriminator map is sorted by its keys, the subclasses by name and the property accessors by property - in a map Doctrine generates, the classes come in the order PHP declared them, which two processes need not share. Two entity managers over the same entities and database - DoctrineBundle's, and one built by hand with Base\Bridge\Doctrine\Mapping - give the same snapshot (tests/Bridge/Doctrine/HandBuiltEntityManagerTest).
MetadataSnapshot::of()
public static function of(EntityManagerInterface $entityManager, ?array $classNames = null): array$classNamesthe classes, those the mapping driver knows when null
MetadataSnapshot::classMetadata()
public static function classMetadata(ClassMetadata $classMetadata, EntityManagerInterface $entityManager): arrayMySQLSchemaManager class
class MySQLSchemaManager extends DbalMySQLSchemaManager MySQLSchemaManager.php:31
DBAL's MySQL schema manager, with two things a column read back from the database needs to compare equal to its mapping (plan "omnibase agnostique", C6b; doctrine/dbal as published, without glitchr/doctrine-dc2type):
- a SET column (Base\Database\Type\SetType: user roles, user states) is read with its values, as DBAL reads an ENUM column since 4.2: its type is Base\Database\Type\MySQLSetType, whose declaration is the SET(...) of the values the database has. DBAL reads SET as simple_array (LONGTEXT), a column every comparison found changed;
- the "(DC2Type:...)" a column's comment holds from before is left out, with the values Base\DatabaseSubscriber\EnumSubscriber wrote after it on an ENUM or SET column ("(DC2Type:user_role) ROLE_ADMIN,ROLE_USER"): DBAL 4 no longer writes these comments, nor does omnibase since 4.0, so they are no part of a column; a database that still has them needs no migration (DBAL 3 left them out on reading as well). Any other comment is kept.
An ENUM or SET column's values come from the database, so a value added to an enumeration (an application's ROLE_PRO) is a column changed: the schema tool and doctrine:migrations:diff alter it.
MySQLSchemaManager::values()
public static function values(string $columnType): array- Returns
the values of "set('a','b')" (or "enum(...)"), as DBAL reads an ENUM's
Registry class
final class Registry extends AbstractManagerRegistry Registry.php:16
doctrine/persistence's ManagerRegistry over one entity manager and its
connection, both named "default": what omnibase's repositories
(Base\Database\Repository\ServiceEntityRepository) and the
ClassMetadataManipulator are built from, where DoctrineBundle's doctrine
service is not there (Base\Bridge\Doctrine\Mapping).
Registry::__construct()
public function __construct(readonly EntityManagerInterface $entityManager)RepositoryFactory class
final class RepositoryFactory implements RepositoryFactoryInterface RepositoryFactory.php:29
The repositories of an entity manager built by hand (Base\Bridge\Doctrine\
Mapping::getRepository(), or the configuration's repository factory when it
is set before the entity manager is built): a repository built from the
ManagerRegistry - omnibase's
ServiceEntityRepository and the applications' repositories over it,
__construct(ManagerRegistry $registry, ?string $entityName = null) - is
given the registry (and the entity's class when it takes one); any other is
built as Doctrine builds it, from the entity manager and the metadata. Under
Symfony, DoctrineBundle's ContainerRepositoryFactory hands out the services.
A repository that takes other services beside the registry (a site's
CommentRepository, its cache pool first: __construct(CacheItemPoolInterface
$cache, ManagerRegistry $doctrine, ?string $entityName = null)) is given
each of them by its type from the host (services(): a closure, the host's
container - Mapping::register()'s option services); a service the host does
not have is null where the parameter allows it, its default where it has
one, else the repository is refused with the service it lacks.
RepositoryFactory::__construct()
public function __construct(readonly ?ManagerRegistry $registry = null)RepositoryFactory::services()
public function services(\Closure $services): void$servicesa service of the host by its type, null when it has none
RepositoryFactory::registryFor()
public function registryFor(EntityManagerInterface $entityManager): ManagerRegistryThe registry a repository of this entity manager is built from.
RepositoryFactory::getRepository()
public function getRepository(EntityManagerInterface $entityManager, string $entityName): EntityRepositorySchemaManagerFactory class
final class SchemaManagerFactory implements SchemaManagerFactoryInterface SchemaManagerFactory.php:24
The schema managers of an omnibase connection (plan "omnibase agnostique", C6b): on MySQL and MariaDB, Base\Bridge\Doctrine\MySQLSchemaManager, which reads a SET column with its values and leaves out the "(DC2Type:...)" comments of before; on any other platform, the one the factory it wraps gives (DBAL's DefaultSchemaManagerFactory unless another is given).
doctrine/dbal as published, no patch: DBAL's own SchemaManagerFactory extension point. Symfony: the core decorates DoctrineBundle's doctrine.dbal.default_schema_manager_factory (config/services/media.php). By hand: $configuration->setSchemaManagerFactory(new SchemaManagerFactory()) on the DBAL Configuration given to DriverManager::getConnection().
SchemaManagerFactory::__construct()
public function __construct(readonly ?SchemaManagerFactoryInterface $inner = null)SchemaManagerFactory::createSchemaManager()
public function createSchemaManager(Connection $connection): AbstractSchemaManagerTypes class
final class Types Types.php:31
omnibase's column types, registered with DBAL (plan "omnibase agnostique", C6): what BaseBundle::boot() and the bundle's doctrine.dbal.types did, in one place, for Symfony and for an entity manager built by hand.
datetimeanddatetimetzare Base\Database\Type\DateTimeTypeUTC (the moment kept in UTC whatever zone PHP was put in),arraythe core's ArrayType (the serialized arrays of before DBAL 4),utc_datetimeandutc_datetime_immutablethe core's UTC types,passkey_base64,passkey_aaguidandpasskey_trust_paththe columns of Base\Entity\User\Passkey (plan "omniauth", AU1: those of web-auth/webauthn-symfony-bundle, without it);- every enumeration (Base\Database\Type\EnumType, SetType) of the folders given, under its getStaticName(), when no type has that name yet;
- the types given by name (a bundle's enumerations), replacing a type of the same name, as DoctrineBundle registers its configured types.
Types::core()
public static function core(): array- Returns
the core's types, by name
Types::passkey()
public static function passkey(): array- Returns
the columns of a passkey (Base\Entity\User\Passkey), by name
Types::enumerations()
public static function enumerations(array $directories): array- Returns
the enumerations the folders hold, by their names
Types::register()
public static function register(array $types = [], array $enumerationDirectories = []): void$typesthe types to register by name, over any of that name
$enumerationDirectoriesthe folders whose enumerations are registered, under names not taken
Types::coreEnumerationDirectory()
public static function coreEnumerationDirectory(): stringThe core's own enumerations (src/Enum).
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)[A-Z]/'The requests ServiceEntityParser::__parse() recognises (find, cache, count, distinctCount, lengthOf), 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, PictureTwigExtension), the providers one may link
(oauth_available()), web push and the back-office address of a
notification (push_available(), push_vapid_key(), NotificationTwigExtension),
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 extensions without a circular service.
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): NotificationsPageActionArguments class
final class ActionArguments implements ValueResolverInterface ActionArguments.php:17
What an action written once for every host is given under Symfony beyond
its route's parameters (step R27 of the audit "lesringostars face au
master plan"): array $query, the query string's values, and array $body
(step R29), what a POST sent - its JSON object, else its form fields -, as
omnibridge/laravel's Screen\Responder::action() gives them. A route
parameter of either name keeps its own.
ActionArguments::resolve()
public function resolve(Request $request, ArgumentMetadata $argument): iterableActionArguments::body()
public static function body(Request $request): arrayWhat a request's body carries: its JSON object (a script's request), else its form fields.
ActionResults class
final class ActionResults ActionResults.php:23
An action's result answered under Symfony (step R27 of the audit "lesringostars face au master plan"): an action written once for every host - a plain class whose #[Route] Symfony's router reads, as omnibridge/laravel's Routing\ActionRoutes does - returns a View, a Template, Json, a Shell, a File or a Redirect, and the ScreenResponder answers it; null from an action declared to return one of them is no such page (404).
A controller that answers a Response itself is left alone.
ActionResults::__construct()
public function __construct(readonly ScreenResponder $responder)ActionResults::__invoke()
public function __invoke(ViewEvent $event): voidActionResults::answers()
public static function answers(mixed $controller): boolWhether a controller ("Class", "Class::method", [Class, method]) is declared to return an action's result.
AuthListeners class
final class AuthListeners AuthListeners.php:22
Base\Auth\'s listeners of omniauth's events, given what they read of a Symfony request (plan "omniauth", step AU7): the captcha's answer the sign-in form posted (GuardSignIn - at the top of the request, where the widget writes it, or under the form, as SignInGuard read it), and whether this browser declined the offer of a second factor (WarnNewDevice).
AuthListeners::guardSignIn()
public static function guardSignIn(SignInGuard $guard, RequestStack $requests, array $firewalls = ['main'], string $form = '_base_security_login'): GuardSignInAuthListeners::warnNewDevice()
public static function warnNewDevice(SecurityPolicy $policy, UserTracker $tracker, Connections $connections, RequestStack $requests, ?State $state = null): WarnNewDeviceFlysystemFiles class
final class FlysystemFiles implements Files FlysystemFiles.php:18
Omnibridge\Contract\Files under Symfony: omnibase's Flysystem service (its storages from flysystem.yaml) and, for a remote storage, MediaService's image route - what Base\Database\Attribute\Uploader resolves a stored file to: a remote storage's file through the /images route first (no local file to link), a local storage's by its path under public/ (Flysystem::getPublic()); its web address is that path less the public directory, as the editor's uploads give it.
FlysystemFiles::__construct()
public function __construct(readonly Storages $flysystem, readonly ?MediaServiceInterface $media = null)FlysystemFiles::publicPath()
public function publicPath(string $path, ?string $storage = null): ?stringFlysystemFiles::publicUrl()
public function publicUrl(string $path, ?string $storage = null): ?stringFlysystemFiles::localPath()
public function localPath(string $path, ?string $storage = null): ?stringFlysystemFiles::isRemote()
public function isRemote(?string $storage = null): boolLocalizerLocales class
final class LocalizerLocales implements Locales LocalizerLocales.php:13
Omnibridge\Contract\Locales under Symfony: omnibase's Localizer (the request's locale, the site's default and fallbacks from base.yaml), its answers in a list.
LocalizerLocales::__construct()
public function __construct(readonly LocalizerInterface $localizer)LocalizerLocales::getLocale()
public function getLocale(): stringLocalizerLocales::getDefaultLocale()
public function getDefaultLocale(): stringLocalizerLocales::getAvailableLocales()
public function getAvailableLocales(): arrayMediaPictures class
final class MediaPictures implements Pictures MediaPictures.php:14
The Pictures contract under Symfony (plan "omnibase agnostique", C5): the
answers of omnibase's |picture filter itself - a stored image's thumbnail
by MediaService, an address or a public path as it is, an asset of the
build - so a screen's images are those the templates printed.
MediaPictures::__construct()
public function __construct(readonly CommonsTwigExtension $commons)MediaPictures::picture()
public function picture(?string $image, ?int $width = null, ?int $height = null): ?stringNotificationMessages class
final class NotificationMessages NotificationMessages.php:39
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, Environment $twig, string $projectDir): EmailMessagePasskeyRecords 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.
RouterRoutes class
final class RouterRoutes implements Routes RouterRoutes.php:16
The Routes contract under Symfony (plan "omnibase agnostique", C4b): omnibase's advanced_router - the route collection's path of a route, the name its matcher gives an address (getRouteName()) - and the IconProvider's icons of a route, the answers an entity got through BaseTrait's getRouter() and getIconProvider().
RouterRoutes::__construct()
public function __construct(readonly AdvancedRouterInterface $router, readonly ?IconProvider $icons = null)RouterRoutes::pattern()
public function pattern(string $name): ?stringRouterRoutes::match()
public function match(string $url): ?stringRouterRoutes::icons()
public function icons(string $name): ?arrayScreenResponder class
class ScreenResponder ScreenResponder.php:38
An action's result answered under Symfony: Symfony's adapter of
Base\Screen\Negotiation (step R10 of the audit "lesringostars face au
master plan" - the negotiation itself, HTML, JSON, omnibridge/react's
protocol and its 409, is framework-free there; omnibridge/laravel's
Screen\Responder is Laravel's adapter of it). What a controller hands back
- a View (a screen of omnibase, plan "omnibase agnostique" C5), a Template,
Json, a Shell, a File, or null for no such page - becomes Symfony's
response: the request read as a Visit, the template rendered by Twig, the
Answer made a Response (a JsonResponse for JSON data, a BinaryFileResponse
for a file), its caching set. A Template rendered alone, and a Shell, keep
omnibase's tags out of the page (_omnibase_inject: false, as a route
default says it).
ScreenResponder::__construct()
public function __construct(readonly Environment $twig, readonly ContextProvider $context, readonly ?string $version = null, readonly ?bool $omnibridge = null)ScreenResponder::respond()
public function respond(Request $request, View|Template|Json|Shell|File|Redirect|null $result, array $legacy = [], ?Frame $frame = null): Response$legacya View's variables of before, for a site's own template
ScreenResponder::visit()
public static function visit(Request $request): VisitWhat the client asked, off Symfony's request.
ScreenResponder::response()
public static function response(Answer $answer): ResponseSymfony's response of an Answer.
ScreenResponder::legacy()
public function legacy(string $template, \Closure $variables, ?string $own = null): arrayThe variables a page had before its view model, given only to a template a site overrides (its templates/ folder, templates/bundles/...): one read from $own (the core's templates by default) reads its screen alone, and the variables - their queries - are not made at all.
ScreenResponder::props()
public function props(Frame $frame, View $view): array- Returns
the frame's props and the screen's, as a front end reads them
ScreenResponder::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.
ScreenResponder::negotiation()
public function negotiation(): NegotiationSecurityUser 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.
ServiceMedia class
final class ServiceMedia implements Media ServiceMedia.php:14
The Media contract under Symfony (plan "omnibase agnostique", C4b): omnibase's MediaService - its extension of a file, its obfuscation of the image route's data, its address of that route - the answers an entity got through BaseTrait's getMediaService(), the same strings.
ServiceMedia::__construct()
public function __construct(readonly MediaService $media)ServiceMedia::extension()
public function extension(?string $path): ?stringServiceMedia::obfuscate()
public function obfuscate(?string $path, array $config = [], array $filters = []): ?stringServiceMedia::link()
public function link(string $route, array $parameters, ?string $path, array $config = []): ?stringSettingBagWarmer class
final class SettingBagWarmer implements CacheWarmerInterface SettingBagWarmer.php:14
The settings' snapshot compiled at cache:warmup (plan "omnibase agnostique", C9): SettingBag's warmer, HttpKernel's side of it, so that SettingBag itself stands on psr/cache and Doctrine alone. Optional: the snapshot compiles on its first read anyway; an unreachable database warms nothing (SettingBag::warmUp()).
SettingBagWarmer::__construct()
public function __construct(readonly SettingBag $settingBag)SettingBagWarmer::isOptional()
public function isOptional(): boolSettingBagWarmer::warmUp()
public function warmUp(string $cacheDir, ?string $buildDir = null): arraySymfonyScreenContext class
class SymfonyScreenContext implements ContextProvider SymfonyScreenContext.php:40
The screens' context under Symfony (plan "omnibase agnostique", C5): what omnibase's kernel.request subscribers and Twig globals gave the templates, asked once for the screen being answered.
- the locale: the request's (what
|transspeaks,app.request.locale); - the host: the scheme, host and base path the page was asked at;
- the site: the host application's Twig global
site(its name, slogan, description: the sites' App\Site\Identity) when it has one, else omnibase's settings (base.settings.title, slogan, logo, meta.description); - the links: home (app_index, else "/"), login, register, logout (with the token the firewall's sign-out asks, Base\Security\SignOut, when someone is signed in), and each language's address (_switch_locale), those whose route exists;
- the viewer: the Access contract's user (the token storage's);
- the theme: the Themizer's colour scheme;
- the flashes: Twig's
app.flashes()itself (read, and so taken).
A site decorates this service (Base\Screen\ContextProvider) to add its own frame fields.
SymfonyScreenContext::__construct()
public function __construct(readonly RequestStack $requests, readonly ?Urls $urls = null, readonly ?Access $access = null, readonly ?Locales $locales = null, readonly ?SettingBagInterface $settings = null, readonly ?ThemizerInterface $themizer = null, readonly ?Environment $twig = null, readonly ?object $app = null, readonly ?Tokens $tokens = null)SymfonyScreenContext::frame()
public function frame(array $extra = []): FrameSymfonyScreenContext::viewer()
public function viewer(): ?ViewerSymfonyScreenContext::flashes()
public function flashes(string $type): arrayTwoFactorUser 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.
WysiwygTexts class
final class WysiwygTexts implements Texts WysiwygTexts.php:15
The Texts contract under Symfony (plan "omnibase agnostique", C5): the
pipeline of omnibase's |wysiwyg and |wysiwyg_toc filters itself
(mentions, links, media, headings, Editor.js's renderer or the HTML of the
older editor), so a screen's text is the HTML the templates printed.
WysiwygTexts::__construct()
public function __construct(readonly HtmlTwigExtension $html, readonly EditorEnhancerInterface $editor)WysiwygTexts::isEditor()
public function isEditor(?string $text): boolWysiwygTexts::render()
public function render(?string $text, array $options = []): stringWysiwygTexts::toc()
public function toc(?string $text, ?int $maxLevel = null): arrayBase\Bundle
AbstractBaseBundle class
abstract class AbstractBaseBundle extends Bundle AbstractBaseBundle.php:14
AbstractBaseBundle::__construct()
public function __construct()AbstractBaseBundle::getBundleDir()
public static function getBundleDir()AbstractBaseBundle::getProjectDir()
public static function getProjectDir(): stringAbstractBaseBundle::getBundles()
public function getBundles()AbstractBaseBundle::hasBundle()
public function hasBundle(string $bundleName)AbstractBaseBundle::getDeclaredClasses()
public function getDeclaredClasses(string $namespace = "", int $level = -1)AbstractBaseBundle::getDeclaredNamespaces()
public function getDeclaredNamespaces(string $namespace = "", int $level = 1)AbstractBaseBundle::setMapping()
public function setMapping(string $path, string $inputNamespace = "", string $outputNamespace = "")AbstractBaseBundle::generateStub()
public function generateStub(string $path, string $inputNamespace = "", string $outputNamespace = ""): voidAbstractBaseBundle::registerAliasAutoloader()
public static function registerAliasAutoloader(): voidA last-resort autoloader for the App\* aliases.
The aliases are declared once per process, from the pool that
BaseBundle::warmUp() reads (or the scan that rebuilds it). A pool that is
stale or incomplete - a concurrent rebuild, cache:clear moving the cache
dir under a process - used to leave one alias out, and whatever first
needed it died: Class "App\Repository\Thread\MentionRepository" not
found from the container, which instantiates the service by that name
(config/services/media.php).
It also covers the window before warmUp() has run at all: see the constructor. Composer is asked first; this only runs for a class nobody else could load. It answers from the known alias lists, then from the convention itself (App\Entity\X is Base\Entity\X, ...), and declares the alias. An alias the lists declare whose Base class is missing is a LogicException.
AbstractBaseBundle::getAlias()
public function getAlias($arrayOrObjectOrClass)AbstractBaseBundle::hasAlias()
public function hasAlias(mixed $objectOrClass): boolAbstractBaseBundle::getAliasRepository()
public function getAliasRepository($aliasRepository)AbstractBaseBundle::getUnloadableClasses()
public static function getUnloadableClasses(): arrayAbstractBaseBundle::declareAlias()
public static function declareAlias(string $class, string $alias, bool $lookup = true): boolDeclares $alias as $class unless something already answers to $alias: a class loaded, or one an autoloader finds a file for - the application's own App\Enum\X, not loaded yet, is never replaced by Base\Enum\X. The stubs written for the classes an application does not define (vendor/composer/omnibridge/stubs/ by omnibridge/composer, glitchr/base-plugin's stubs/ before 4.0) are no definition of its own, should an autoloader ever find one. True when the alias is declared (or already was, to that class).
$lookup false skips the autoloaders' search for a file of the application: for an alias of the pool, which BaseBundle::warmUp() wrote only for names no class answered to when it scanned (setAlias()), in a kernel without debug, whose pool is rebuilt with every cache:clear. That search is a file_exists() missed per alias - 346 of them on each request of lesringostars, 8.7 of its 11 ms of aliases.
AbstractBaseBundle::isStub()
public static function isStub(string $file): boolWhether $file is a stub (omnibridge/composer's, or glitchr/base-plugin's before 4.0), not a class of the application.
AbstractBaseBundle::classLoads()
public static function classLoads(string $class): boolAbstractBaseBundle::isRepositoryService()
public static function isRepositoryService(string $class): boolWhether $class is registered as a Doctrine repository service (tagged
doctrine.repository_service, built with doctrine): a class whose name
ends with "Repository", that can be instantiated and that is a service
repository: omnibase's Base\Database\Repository\ServiceEntityRepository
(built on doctrine/orm's EntityRepository since step C3b of the plan
"omnibase agnostique") or DoctrineBundle's ServiceEntityRepositoryInterface.
Every class of a bundle's src/Repository named so used to be registered, an abstract base repository included - and the container then had a service it could not build. Abstract classes, interfaces and traits are aliased like any class of the bundle, never registered.
AbstractBaseBundle::setAlias()
public function setAlias(array $classes)AbstractBaseBundle::setAliasEntity()
public function setAliasEntity($class)AbstractBaseBundle::getAllClasses()
public static function getAllClasses(string $path, string $prefix = "", int $level = -1): arrayAbstractBaseBundle::getAllNamespaces()
public function getAllNamespaces(string $path, string $prefix = "", int $level = -1): arrayAbstractBaseBundle::getAllNamespacesAndClasses()
public function getAllNamespacesAndClasses(string $path, string $prefix = "", int $level = -1): arrayAbstractBaseBundle::getClassname()
public static function getClassname(string $filename)AbstractBaseBundle::getFullNamespace()
public static function getFullNamespace(string $filename, string $prefix = "")AbstractBaseBundle::getFiles()
public static function getFiles(string $path, int $level = -1)AbstractBaseBundle::getDirectories()
public function getDirectories(string $path, int $level = -1)AbstractBaseConfiguration class
abstract class AbstractBaseConfiguration implements ConfigurationInterface AbstractBaseConfiguration.php:8
AbstractBaseConfiguration::getTreeBuilder()
public function getTreeBuilder(?string $treeName = null): TreeBuilderAbstractBaseExtension class
abstract class AbstractBaseExtension extends Extension AbstractBaseExtension.php:8
AbstractBaseExtension::setConfiguration()
public function setConfiguration(ContainerBuilder $container, array $config, $globalKey = '')AbstractBaseExtension::getBaseNamespace()
public function getBaseNamespace()AbstractBaseExtension::setConfigurationAliases()
public function setConfigurationAliases(ContainerBuilder $container)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()AbstractLocalCacheWarmer class
abstract class AbstractLocalCacheWarmer extends AbstractPhpFileCacheWarmer implements AbstractLocalCacheWarmerInterface AbstractLocalCacheWarmer.php:9
AbstractLocalCacheWarmer::__construct()
public function __construct(AbstractLocalCacheInterface $simpleCache, string $cacheDir)AbstractLocalCacheWarmer::getCache()
public function getCache(): ArrayAdapterAbstractLocalCacheWarmer::isOptional()
public function isOptional(): boolAbstractLocalCacheWarmerInterface interface
interface AbstractLocalCacheWarmerInterface AbstractLocalCacheWarmerInterface.php:7
AbstractLocalCacheWarmerInterface::getCache()
public function getCache(): ArrayAdapterBase\Cache\Clearer
CodeCachesClearer class
final class CodeCachesClearer implements CacheClearerInterface CodeCachesClearer.php:16
cache:clear is enough: it empties the pools that remember what the code says - the Doctrine mapping's metadata, the DQL's parsed queries, the router's compiled routes. An application keeps them in pools of its own (filesystem, the default clearer, which cache:clear does not call): a column added to an entity read as missing, a route added was "No valid route found", until cache:pool:clear --all.
CodeCachesClearer::__construct()
public function __construct(readonly iterable $pools)CodeCachesClearer::clear()
public function clear(string $cacheDir): voidBase\Cache\Warmer
AttributeCacheWarmer class
class AttributeCacheWarmer extends AbstractLocalCacheWarmer AttributeCacheWarmer.php:9
IconCacheWarmer class
class IconCacheWarmer extends AbstractLocalCacheWarmer IconCacheWarmer.php:10
IconCacheWarmer::__construct()
public function __construct(IconProvider $iconProvider, string $cacheDir)LocalizerCacheWarmer class
class LocalizerCacheWarmer extends AbstractLocalCacheWarmer LocalizerCacheWarmer.php:7
MetadataCacheWarmer class
class MetadataCacheWarmer extends AbstractLocalCacheWarmer MetadataCacheWarmer.php:12
MetadataCacheWarmer::__construct()
public function __construct(AbstractLocalCacheInterface $simpleCache, AttributeReader $attributeReader, string $cacheDir)SpreadsheetCacheWarmer class
class SpreadsheetCacheWarmer implements CacheWarmerInterface SpreadsheetCacheWarmer.php:10
SpreadsheetCacheWarmer::__construct()
public function __construct(string $cacheDir)SpreadsheetCacheWarmer::isOptional()
public function isOptional(): boolSpreadsheetCacheWarmer::warmUp()
public function warmUp(string $cacheDir, ?string $buildDir = null): arrayThemizerCacheWarmer class
class ThemizerCacheWarmer extends AbstractLocalCacheWarmer ThemizerCacheWarmer.php:7
WebpackCacheWarmer class
class WebpackCacheWarmer extends AbstractLocalCacheWarmer WebpackCacheWarmer.php:21
The entries of the application's build and of the core's, and their tags rendered once, kept in the cache - unless a build was being written when the cache was made (the web container restarted while Encore's watcher rebuilds: entrypoints.json absent, or without entries). What was read then is not kept: it used to stay until cache:pool:clear --all, every page without its stylesheets. The renderer reads the builds again on a request that finds none (WebpackTagRenderer::discoverIfNone()).
WebpackCacheWarmer::__construct()
public function __construct(ParameterBagInterface $parameterBag, WebpackTagRenderer $webpackTagRenderer, ?EntrypointLookupInterface $entrypointLookup, string $cacheDir, string $publicDir)WebpackCacheWarmer::isComplete()
public function isComplete(): boolBase\Console
Application class
class Application extends Application Application.php:7
Command class
class Command extends SymfonyCommand Command.php:19
Command::__construct()
public function __construct(LocalizerInterface $localizer, TranslatorInterface $translator, EntityManagerInterface $entityManager, ParameterBagInterface $parameterBag)Command::run()
public function run(InputInterface $input, OutputInterface $output): intConsole class
class Console implements ConsoleInterface Console.php:12
Console::__construct()
public function __construct(KernelInterface $kernel, int $verbosity = Output::VERBOSITY_NORMAL)Console::verbosity()
public function verbosity(int $verbosity)Console::exec()
public function exec(string $command, array $parameters = []): ?stringConsoleInterface interface
interface ConsoleInterface ConsoleInterface.php:5
ConsoleInterface::exec()
public function exec(string $command, array $parameters = []): ?stringBase\Console\Command
AutocompleteEntitiesCommand class
class AutocompleteEntitiesCommand extends Command AutocompleteEntitiesCommand.php:23
AutocompleteEntitiesCommand::__construct()
public function __construct(LocalizerInterface $localizer, TranslatorInterface $translator, EntityManagerInterface $entityManager, ParameterBagInterface $parameterBag, ClassMetadataManipulator $classMetadataManipulator)BaseMappingCommand class
class BaseMappingCommand extends Command BaseMappingCommand.php:13
CacheClearCommand class
class CacheClearCommand extends Command CacheClearCommand.php:21
public static string $testFile
CacheClearCommand::__construct()
public function __construct(LocalizerInterface $localizer, TranslatorInterface $translator, EntityManagerInterface $entityManager, ParameterBagInterface $parameterBag, SymfonyCommand $cacheClearCommand, SymfonyCommand $cacheClearSessionsCommand, Flysystem $flysystem, Notifier $notifier, AdvancedRouterInterface $router, string $projectDir, string $cacheDir)CacheClearCommand::getTestFile()
public static function getTestFile(): stringCacheClearCommand::markAsFirstClear()
public static function markAsFirstClear(bool $first = true)CacheClearCommand::applicationNotStarted()
public static function applicationNotStarted(): boolCacheClearCommand::isFirstClear()
public static function isFirstClear(): boolCacheClearCommand::getNClears()
public static function getNClears(): intCacheClearSessionsCommand class
class CacheClearSessionsCommand extends Command CacheClearSessionsCommand.php:15
CacheClearSessionsCommand::__construct()
public function __construct(LocalizerInterface $localizer, TranslatorInterface $translator, EntityManagerInterface $entityManager, ParameterBagInterface $parameterBag, string $projectDir)DemoResetCommand class
class DemoResetCommand extends Command DemoResetCommand.php:44
The demonstration back to what the fixtures say: what the cron container
runs every night in the demo environment, and nowhere else.
1. refuses outside demo, and on what DemoGuard refuses (debug, the
production database);
2. under a lock (symfony/lock): two resets never overlap;
3. empties the directories of base.demo.reset.purge - the files the
visitors sent to a storage of the application's own;
4. reloads the fixtures (doctrine:fixtures:load, the groups of
base.demo.reset.groups when some are named), then creates the declared
demonstration accounts they left out;
5. deletes the uploaded files no row names any more
(uploader:entities --delete-orphans, unless base.demo.reset.orphans is off);
6. empties the caches that would go on answering yesterday's rows: every
cache pool, Doctrine's second-level cache.
Each step is logged; the exit code is not 0 when one failed.
const LOCK = 'base-demo-reset'
DemoResetCommand::__construct()
public function __construct(readonly DemoMode $mode, readonly DemoGuard $guard, readonly DemoAccountFactory $accounts, readonly ?ManagerRegistry $doctrine = null, readonly ?LockFactory $lockFactory = null, readonly ?SecondLevelCacheConsoleSubscriber $secondLevelCache = null, readonly ?LoggerInterface $logger = null, readonly array $purge = [], readonly bool $orphans = true, readonly array $groups = [], readonly ?DemoAccountRegistry $registry = null)$purgedirectories emptied before the fixtures are loaded (base.demo.reset.purge)
$groupsthe fixture groups loaded (base.demo.reset.groups); none: every fixture
DoctrineArrayUpgradeCommand class
class DoctrineArrayUpgradeCommand extends Command DoctrineArrayUpgradeCommand.php:14
DoctrineArrayUpgradeCommand::__construct()
public function __construct(LocalizerInterface $localizer, TranslatorInterface $translator, EntityManagerInterface $entityManager, ParameterBagInterface $parameterBag)DoctrineDatabaseImportCommand class
class DoctrineDatabaseImportCommand extends Command DoctrineDatabaseImportCommand.php:38
const OFFSET = 2const UNKNOWN_STATE = -1const VALID_ENTITY = 0const FIELD_REQUIRED = 1const PARENT_NOT_FOUND = 2const ALREADY_IN_DATABASE = 3
DoctrineDatabaseImportCommand::__construct()
public function __construct(LocalizerInterface $localizer, TranslatorInterface $translator, EntityManagerInterface $entityManager, ParameterBagInterface $parameterBag, EntityHydrator $entityHydrator, ClassMetadataManipulator $classMetadataManipulator, Notifier $notifier)DoctrineDatabaseImportCommand::normalize()
public function normalize($entityName, $entityData)- Throws
Exception
DoctrineSchemaCharsetCommand class
class DoctrineSchemaCharsetCommand extends Command DoctrineSchemaCharsetCommand.php:12
EntityDiscriminatorCommand class
class EntityDiscriminatorCommand extends Command EntityDiscriminatorCommand.php:17
EntityDiscriminatorCommand::__construct()
public function __construct(LocalizerInterface $localizer, TranslatorInterface $translator, EntityManagerInterface $entityManager, ParameterBagInterface $parameterBag, ClassMetadataManipulator $classMetadataManipulator)IconEntitiesCommand class
class IconEntitiesCommand extends Command IconEntitiesCommand.php:22
IconEntitiesCommand::__construct()
public function __construct(LocalizerInterface $localizer, TranslatorInterface $translator, EntityManagerInterface $entityManager, ParameterBagInterface $parameterBag, ClassMetadataManipulator $classMetadataManipulator)IconEnumsCommand class
class IconEnumsCommand extends Command IconEnumsCommand.php:15
MailTrapCommand class
class MailTrapCommand extends Command MailTrapCommand.php:30
Hold outgoing mail during an incident, look at what was held, then throw away the wrong ones and let the rest go.
base:mailer:trap on --reason="hotfix newsletter" nothing leaves from now on base:mailer:trap list who each held mail was for base:mailer:trap show <id> one message in full base:mailer:trap purge <id> | --all delete, never sent base:mailer:trap release <id> | --all send it after all base:mailer:trap off back to normal
on takes effect for mail that is ALREADY queued too, because the trap
sits at send time rather than at queue time - so arming it mid-incident
still catches whatever the worker had not got to yet.
MailTrapCommand::setMailTrap()
public function setMailTrap(MailTrap $trap): staticMailTrapCommand::setMailerTransport()
public function setMailerTransport(TransportInterface $transport): staticNotifierCommand class
class NotifierCommand extends Command NotifierCommand.php:13
NotifierMailTestCommand class
class NotifierMailTestCommand extends Command NotifierMailTestCommand.php:15
NotifierMailTestCommand::__construct()
public function __construct(...$args)ThreadPublishableCommand class
class ThreadPublishableCommand extends Command ThreadPublishableCommand.php:16
ThreadPublishableCommand::setThreads()
public function setThreads(Threads $threads): selfTimeMachineSnapshotBackupCommand class
class TimeMachineSnapshotBackupCommand extends TimeMachineSnapshotCommand TimeMachineSnapshotBackupCommand.php:12
TimeMachineSnapshotBackupCommand::execute()
public function execute(InputInterface $input, OutputInterface $output): intTimeMachineSnapshotCommand class
class TimeMachineSnapshotCommand extends Command TimeMachineSnapshotCommand.php:19
TimeMachineSnapshotCommand::__construct()
public function __construct(LocalizerInterface $localizer, TranslatorInterface $translator, EntityManagerInterface $entityManager, ParameterBagInterface $parameterBag, TimeMachineInterface $timeMachine, Storages $flysystem)TimeMachineSnapshotCommand::execute()
public function execute(InputInterface $input, OutputInterface $output): intTimeMachineSnapshotRestoreCommand class
class TimeMachineSnapshotRestoreCommand extends TimeMachineSnapshotCommand TimeMachineSnapshotRestoreCommand.php:13
TimeMachineSnapshotRestoreCommand::execute()
public function execute(InputInterface $input, OutputInterface $output): intTimeMachineStorageCommand class
class TimeMachineStorageCommand extends Command TimeMachineStorageCommand.php:18
TimeMachineStorageCommand::__construct()
public function __construct(LocalizerInterface $localizer, TranslatorInterface $translator, EntityManagerInterface $entityManager, ParameterBagInterface $parameterBag, TimeMachineInterface $timeMachine, Storages $flysystem)TimeMachineStorageCommand::execute()
public function execute(InputInterface $input, OutputInterface $output): intTranslationControllersCommand class
class TranslationControllersCommand extends Command TranslationControllersCommand.php:13
TranslationCrudCommand class
class TranslationCrudCommand extends Command TranslationCrudCommand.php:16
TranslationEntitiesCommand class
class TranslationEntitiesCommand extends Command TranslationEntitiesCommand.php:17
TranslationEnumsCommand class
class TranslationEnumsCommand extends Command TranslationEnumsCommand.php:16
TranslationSettingsCommand class
class TranslationSettingsCommand extends Command TranslationSettingsCommand.php:18
TranslationSettingsCommand::__construct()
public function __construct(LocalizerInterface $localizer, TranslatorInterface $translator, EntityManagerInterface $entityManager, ParameterBagInterface $parameterBag, SettingBagInterface $settingBag)TrashPurgeCommand class
class TrashPurgeCommand extends Command TrashPurgeCommand.php:21
Empties the trash of everything past its grace period
(base.extension.empty_trash, "+7 days" by default).
Meant for cron. Defaults to a dry run: this is the only thing in the stack that destroys content beyond recovery, so it says what it would do unless told --force.
TrashPurgeCommand::setTrashManager()
public function setTrashManager(TrashManager $trashManager): selfUploaderEntitiesCommand class
class UploaderEntitiesCommand extends Command UploaderEntitiesCommand.php:18
UploaderEntitiesCommand::setRepositories()
public function setRepositories(Repositories $repositories): staticUploaderEntitiesCommand::getEntries()
public function getEntries($class)UploaderEntitiesCommand::getOrphanFiles()
public function getOrphanFiles(string $class, string $field, Uploader $attribute)- Throws
Exception
UploaderEntitiesCommand::deleteOrphanFiles()
public function deleteOrphanFiles(Uploader $attribute, array $fileList)UploaderEntitiesCommand::preProcess()
public function preProcess(mixed $class, string $field, Uploader $attribute)UploaderEntitiesCommand::postProcess()
public function postProcess(mixed $class, string $field, Uploader $attribute, array $fileList)UploaderImagesCommand class
class UploaderImagesCommand extends UploaderEntitiesCommand UploaderImagesCommand.php:18
UploaderImagesCommand::__construct()
public function __construct(LocalizerInterface $localizer, TranslatorInterface $translator, EntityManagerInterface $entityManager, ParameterBagInterface $parameterBag, MediaServiceInterface $mediaService, MediaController $mediaController)UploaderImagesCommand::isCached()
public function isCached($data)UploaderImagesCommand::postProcess()
public function postProcess(mixed $class, string $field, Uploader $attribute, array $fileList)UploaderImagesCropCommand class
class UploaderImagesCropCommand extends UploaderImagesCommand UploaderImagesCropCommand.php:21
UploaderImagesCropCommand::postProcess()
public function postProcess(mixed $class, string $field, Uploader $attribute, array $fileList)UploaderImagesCropCommand::isCached()
public function isCached($data, $imageCrop = null)UserCreateCommand class
class UserCreateCommand extends Command UserCreateCommand.php:27
An account made from the command line - someone's own to test a site, a colleague's -, verified and approved, with a password it did not choose: generated and shown once (or given with --password), to be changed at its first sign-in (a "change-password" token, PasswordChangeSubscriber) unless --keep-password; e-mailed its username and password unless --no-email. A plain Symfony command (not Base\Console\Command, which wants a ConsoleOutput): it runs from scripts and tests too.
UserCreateCommand::__construct()
public function __construct(readonly EntityManagerInterface $entityManager, readonly NotifierInterface $notifier)UserNotificationCommand class
class UserNotificationCommand extends Command UserNotificationCommand.php:22
The notifications kept in the database: counted (an account's with --user, everyone's without), listed with --show, erased with --clear when read and older than base.user.notifications.expiry (or --expiry), with --clear-all when read, whatever their age.
An unread notification is never erased.
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:21
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: a helper over 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): stringMedia 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:38
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() (Base\DependencyInjection\Compiler\Pass\ContractsPass);
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(): MailerInterfaceTexts 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.
Base\Controller
DemoController class
class DemoController extends AbstractController DemoController.php:27
Signing in as a demonstration account in one click: the buttons of the sign-in page's "Demonstration accounts" panel (@Base/demo/_accounts.html.twig).
The route exists in the demo environment only. It is a POST carrying a
CSRF token - never a link: a GET that signs in is followed by a prefetch,
a crawler, a preview. Only a declared account is signed in, and never one
that opens the back office (base.demo.admin_roles) or whose roles reach
ROLE_SUPERADMIN: those sign in with their secret (DemoBackOfficeSubscriber).
const CSRF = 'demo_login'
DemoController::Login()
public function Login(Request $request, DemoMode $demo, DemoAccountRegistry $accounts, UserRepository $users, UserAuthenticatorInterface $userAuthenticator, LoginFormAuthenticator $authenticator): ResponseErrorController class
class ErrorController extends AbstractController ErrorController.php:22
ErrorController::__construct()
public function __construct(HtmlErrorRenderer $htmlErrorRenderer, AdvancedRouterInterface $router, Environment $environment, RequestStack $requestStack, ?Profiler $profiler = null)The Environment contract, where it asked BaseService whether it runs for its developers (plan "omnibase agnostique", C9).
ErrorController::Main()
public function Main(Throwable $exception)- Throws
Exception
ErrorController::Rescue()
public function Rescue(Throwable $exception): ResponseThe debug page of an error, under the error's own status: 403 for a refusal, 422 for a payload that does not validate, 404 for a page that does not exist, 500 for anything that is not an HTTP error.
It answered 404 whatever the error. A response that is already a client error is kept as it is by the kernel, so in debug (dev, and the tests) every refusal and every validation failure of a signed-in user read as "not found" - while production, whose page is rendered with a 200 the kernel then replaces, gave the right one.
LocalizerController class
class LocalizerController extends AbstractController LocalizerController.php:18
LocalizerController::__construct()
public function __construct(LocalizerInterface $localizer, EntityManagerInterface $entityManager, AdvancedRouterInterface $router, ReferrerInterface $referrer, TranslatorInterface $translator)LocalizerController::Locale()
public function Locale(Request $request, ReferrerInterface $referrer, ?string $_locale = null)The visitor's choice of language: remembered (LANG, and a member's own locale), then the page they came from, in that language when it has an address of its own. Without one ("/locale"), the choice is forgotten.
LocalizerController::Timezone()
public function Timezone(Request $request, ReferrerInterface $referrer, ?string $_locale = null)MainController class
class MainController extends AbstractController MainController.php:15
MainController::__construct()
public function __construct(SettingBag $settingBag)MainController::Index()
public function Index(): ResponseController example
ProfilerController class
class ProfilerController extends AbstractController ProfilerController.php:12
ProfilerController::__construct()
public function __construct(NotifierInterface $notifier, UserRepository $userRepository)ProfilerController::Email()
public function Email(): ResponseProfilerController::SendEmail()
public function SendEmail(): ResponseRescueController class
class RescueController extends AbstractController RescueController.php:27
The admin-firewall login ("rescue") entry point. Self-sufficient: it renders the admin extension's login page when base-bundle-admin is installed (@Admin/security/login.html.twig), and otherwise a fully self-contained fallback bundled here that depends on nothing external - no admin package, no third-party admin UI.
RescueController::__construct()
public function __construct(protected RouterInterface $router, protected SettingBagInterface $settingBag, protected Environment $twig, protected TranslatorInterface $translator, protected FormProxyInterface $formProxy)RescueController::LoginRescue()
public function LoginRescue(Request $request, ReferrerInterface $referrer, AuthenticationUtils $authenticationUtils): ResponseLink to this controller to start the "connect" process
RescueController::index()
public function index(): ResponseSecurityController class
class SecurityController extends AbstractController SecurityController.php:54
SecurityController::__construct()
public function __construct(NotifierInterface $notifier, EntityManagerInterface $entityManager, Tokens $tokenRepository, Users $userRepository, AdvancedRouterInterface $router, FormProxy $formProxy, TokenStorageInterface $tokenStorage, TranslatorInterface $translator, ParameterBagInterface $parameterBag)SecurityController::Login()
public function Login(Request $request, ReferrerInterface $referrer, AuthenticationUtils $authenticationUtils, ?SignInGuard $signInGuard = null): ResponseSecurityController::Logout()
public function Logout(Request $request, ReferrerInterface $referrer)SecurityController::LogoutRequest()
public function LogoutRequest()SecurityController::LoginTokenRequest()
public function LoginTokenRequest(Request $request, ReferrerInterface $referrer, AuthenticationUtils $authenticationUtils, LoginFormAuthenticator $authenticator, UserAuthenticatorInterface $userAuthenticator, ?string $token = null, ?\Omniauth\Omniauth $omniauth = null, ?\Omnibridge\Symfony\Auth\Contexts $contexts = null): ResponseSecurityController::Register()
public function Register(Request $request, LoginFormAuthenticator $authenticator, UserAuthenticatorInterface $userAuthenticator): ResponseSecurityController::VerifyEmailRequest()
public function VerifyEmailRequest()SecurityController::VerifyEmailResponse()
public function VerifyEmailResponse(Request $request, UserAuthenticatorInterface $userAuthenticator, LoginFormAuthenticator $authenticator, string $token): ResponseSecurityController::AdminApprovalRequest()
public function AdminApprovalRequest(Request $request)SecurityController::DisableAccountRequest()
public function DisableAccountRequest(Request $request, SecurityPolicy $securityPolicy)SecurityController::EnableAccountRequest()
public function EnableAccountRequest(Request $request, LoginFormAuthenticator $authenticator, UserAuthenticatorInterface $userAuthenticator, ?string $token = null): ResponseSecurityController::ResetPasswordRequest()
public function ResetPasswordRequest(Request $request, SecurityPolicy $securityPolicy): ResponseDisplay & process form to request a password reset.
SecurityController::ResetPasswordResponse()
public function ResetPasswordResponse(Request $request, LoginFormAuthenticator $authenticator, UserAuthenticatorInterface $userAuthenticator, SecurityPolicy $securityPolicy, ?string $token = null): ResponseValidates and process the reset URL that the user clicked in their email.
SecurityController::ChangePassword()
public function ChangePassword(Request $request, LoginFormAuthenticator $authenticator, UserAuthenticatorInterface $userAuthenticator): ResponseA password to choose, before anything else: the account was made with one its owner did not choose (user:create, a "change-password" token; PasswordChangeSubscriber brings them here).
SecurityController::Maintenance()
public function Maintenance(MaintenanceProviderInterface $maintenanceProvider): ResponseLink to this controller to start the maintenance
SecurityController::Launch()
public function Launch(LauncherInterface $launcher): ResponseSecurityController::Pending()
public function Pending(): ResponseSecurityController::PendingForApproval()
public function PendingForApproval(): ResponseShortLinkController class
class ShortLinkController extends AbstractController ShortLinkController.php:11
ShortLinkController::__construct()
public function __construct(AdvancedRouterInterface $router, ShortLinkRepository $shlinkRepository)ShortLinkController::Main()
public function Main(string $slug): ResponseSignatureController class
final class SignatureController SignatureController.php:16
A signing provider's callback (glitchr/omnisign: Yousign, DocuSign, DocuSeal...): its signature checked by the gateway, the envelope it names asked again and kept (Base\Service\Signatures::notify()). Without glitchr/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): JsonResponseSitemapController class
class SitemapController extends AbstractController SitemapController.php:15
SitemapController::Main()
public function Main(string $extension, Request $request, SitemapperInterface $sitemap, EventDispatcherInterface $dispatcher): ResponseWidgetController class
class WidgetController extends AbstractController WidgetController.php:14
WidgetController::__construct()
public function __construct(AttachmentRepository $attachmentRepository)WidgetController::Attachment()
public function Attachment($slug): BinaryFileResponseBase\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\Controller\Api
ThreadController class
class ThreadController extends AbstractController ThreadController.php:21
ThreadController::__construct()
public function __construct(EntityManagerInterface $entityManager, TranslatorInterface $translator, Threads $threadRepository, Likes $likeRepository)ThreadController::Publish()
public function Publish(Request $request, string $slug): ResponseThreadController::Hide()
public function Hide(Request $request, string $slug): ResponseThreadController::Follow()
public function Follow(Request $request, string $slug): ResponseThreadController::Unfollow()
public function Unfollow(Request $request, string $slug): ResponseThreadController::Like()
public function Like(Request $request, string $slug): ResponseThreadController::Unlike()
public function Unlike(Request $request, string $slug): ResponseBase\Controller\Client
ContactController class
class ContactController extends AbstractController ContactController.php:16
ContactController::__construct()
public function __construct(FormProxy $formProxy, Notifier $notifier)ContactController::Contact()
public function Contact(Request $request, array $options = []): ResponseNotificationController class
class NotificationController extends AbstractController NotificationController.php:30
The notification center's HTTP surface: the list page, the push subscription registry, and the service worker itself (the bell's payload, read marks and removals: Base\Controller\Action\Notification).
Every mutation is a JSON POST carrying the "notifications" CSRF token in its body (the toolbar renders it as data-csrf), same-origin only. They answer JSON rather than redirecting because the bell updates in place.
const CSRF = "notifications"
NotificationController::__construct()
public function __construct(protected readonly EntityManagerInterface $entityManager, protected readonly Notifications $notificationRepository, protected readonly WebPushService $webPush, protected readonly CsrfTokenManagerInterface $csrfTokenManager, protected readonly ?NotificationLinkerInterface $linker = null)NotificationController::Index()
public function Index(Request $request, ScreenResponder $responder, AccountScreens $screens): ResponseThe list: its template and its view model
(Base\Screen\Account\NotificationsPage, plan "omnibase agnostique", C5)
to omnibase's ScreenResponder - the days' groups by the screen's clock,
the token in it, the answers stored by no cache; a template the site
overrides gets notifications, unread and unreadOnly as well
(deprecated, gone in 4.0).
NotificationController::PushConfig()
public function PushConfig(): JsonResponseWhat the browser needs before it can subscribe: the VAPID public key, or null when push is off.
NotificationController::PushSubscribe()
public function PushSubscribe(Request $request): JsonResponseBody: {token, subscription: PushSubscriptionJSON}
NotificationController::PushUnsubscribe()
public function PushUnsubscribe(Request $request): JsonResponseBody: {token, endpoint}
NotificationController::ServiceWorker()
public function ServiceWorker(): ResponseThe service worker. Served from the origin root because a worker's scope cannot exceed its own path: registered from /sw.js it covers the whole site, admin included. Served by PHP rather than as a static file so the bundle owns it - the app's public/ never has to carry a copy. no-cache so a new version is picked up on the next check.
NotificationController::serialize()
public function serialize(Notification $n): arrayThreadSearchController class
class ThreadSearchController extends AbstractController ThreadSearchController.php:16
ThreadSearchController::__construct()
public function __construct(FormProxyInterface $formProxy, ThreadTranslations $translations, Repositories $repositories)ThreadSearchController::Main()
public function Main(Request $request)UserProfileController class
class UserProfileController extends AbstractController UserProfileController.php:20
UserProfileController::__construct()
public function __construct(Users $users, FormProxyInterface $formProxy)UserProfileController::Edit()
public function Edit(Request $request, int $id = -1)UserProfileController::Show()
public function Show(Request $request, ScreenResponder $responder, AccountScreens $screens, int $id = -1)A member's profile: its template and its view model
(Base\Screen\Account\ProfilePage, plan "omnibase agnostique", C5) to
omnibase's ScreenResponder - the core's template reads the screen alone,
a front end gets it in JSON; a template the site overrides gets user
as well (deprecated, gone in 4.0).
UserSearchController class
class UserSearchController extends AbstractController UserSearchController.php:14
UserSearchController::__construct()
public function __construct(FormProxyInterface $formProxy, Users $users)UserSearchController::Main()
public function Main(Request $request, ?FormInterface $formSearch = null)UserSettingsController class
class UserSettingsController extends AbstractController UserSettingsController.php:35
UserSettingsController::__construct()
public function __construct(Users $userRepository, SecurityPolicy $securityPolicy, TranslatorInterface $translator)UserSettingsController::displayTotpQrCode()
public function displayTotpQrCode(TotpAuthenticatorInterface $totpAuthenticator, ?TotpSecrets $totpSecrets = null): ResponseUserSettingsController::Settings()
public function Settings(Request $request, Connections $connectionRepository, ScreenResponder $responder, AccountScreens $screens)The account's settings: its template and its view model
(Base\Screen\Account\SettingsPage, plan "omnibase agnostique", C5) to
omnibase's ScreenResponder - each small form an action with its token,
the answers stored by no cache; a template the site overrides gets
user, sessions and policy as well (deprecated, gone in 4.0).
UserSettingsController::RenamePasskey()
public function RenamePasskey(int $id, Request $request, Passkeys $passkeyRepository)UserSettingsController::DeletePasskey()
public function DeletePasskey(int $id, Request $request, Passkeys $passkeyRepository)UserSettingsController::LogoutSession()
public function LogoutSession(int $id, Request $request, Connections $connectionRepository)UserSettingsController::TwoFactorAuthentication()
public function TwoFactorAuthentication(Request $request, TotpAuthenticatorInterface $totpAuthenticator, ?TotpSecrets $totpSecrets = null)UserSettingsController::TwoFactorAuthentication_Disable()
public function TwoFactorAuthentication_Disable(Request $request, UserPasswordHasherInterface $passwordHasher)UserSettingsController::TwoFactorAuthentication_QrCode()
public function TwoFactorAuthentication_QrCode(Request $request, TotpAuthenticatorInterface $totpAuthenticator)Base\Controller\UX
AutocompleteController class
class AutocompleteController extends AbstractController AutocompleteController.php:27
AutocompleteController::__construct()
public function __construct(ObfuscatorInterface $obfuscator, RequestStack $requestStack, TradingInterface $tradingMarket, TranslatorInterface $translator, EntityManagerInterface $entityManager, PaginatorInterface $paginator, ClassMetadataManipulator $classMetadataManipulator, ?MediaServiceInterface $mediaService = null, ?Profiler $profiler = null, ?ManagerRegistry $doctrine = null)AutocompleteController::Main()
public function Main(Request $request, string $data): ResponseAutocompleteController::Forex()
public function Forex(Request $request, string $source, string $target, string $data, ?Profiler $profiler = null): ResponseAutocompleteController::Icons()
public function Icons(Request $request, string $provider, int $pageSize, string $data, ?Profiler $profiler = null): ResponseAutovalidateController class
class AutovalidateController extends AbstractController AutovalidateController.php:16
AutovalidateController::__construct()
public function __construct(TranslatorInterface $translator, EntityManagerInterface $entityManager)AutovalidateController::encode()
public function encode(array $array): stringAutovalidateController::decode()
public function decode(string $hash): arrayAutovalidateController::Main()
public function Main(Request $request, string $hashid): ResponseDropzoneController class
class DropzoneController extends AbstractController DropzoneController.php:19
const CACHE_DURATION = 24 * 3600const STATUS_OK = "OK"const STATUS_BAD = "BAD"const STATUS_NOTOKEN = "NO_TOKEN"
DropzoneController::__construct()
public function __construct(TranslatorInterface $translator, CacheInterface $cache, ObfuscatorInterface $obfuscator, string $cacheDir)DropzoneController::getCacheDir()
public function getCacheDir()DropzoneController::Main()
public function Main(Request $request, $data = null): ResponseController example
DropzoneController::Preview()
public function Preview(string $data, string $uuid): ResponseDropzoneController::Delete()
public function Delete(string $data, string $uuid): ResponseEditorController class
class EditorController extends AbstractController EditorController.php:35
const STATUS_OK = 1const STATUS_BAD = 0const STATUS_NOTOKEN = -1
EditorController::__construct()
public function __construct(ParameterBagInterface $parameterBag, SluggerInterface $slugger, MediaServiceInterface $mediaService, Storages $flysystem, TranslatorInterface $translator, RequestStack $requestStack, PaginatorInterface $paginator, ObfuscatorInterface $obfuscator, UserRepository $userRepository, ThreadRepository $threadRepository, TagRepository $tagRepository, CollabRoomResolver $roomResolver, CollabTicketFactory $ticketFactory, ?Profiler $profiler = null)EditorController::EndpointByUser()
public function EndpointByUser(Request $request, $data = null, array $fields = [], $page = 1): ResponseEditorController::EndpointByKeyword()
public function EndpointByKeyword(Request $request, $data = null, array $fields = ["slug"], $page = 1): ResponseEditorController::EndpointByThread()
public function EndpointByThread(Request $request, $data = null, array $fields = [], $page = 1): ResponseEditorController::UploadByFile()
public function UploadByFile(Request $request, $data = null): ResponseEditorController::UploadByUrl()
public function UploadByUrl(Request $request, $data = null): ResponseEditorController::CollabTicket()
public function CollabTicket(Request $request): JsonResponseThis action creates a short-lived, signed ticket. A browser
presents this ticket to the collab relay. Refer to the relay/
directory of the editorjs-yjs repository for the relay code. This ticket lets a
client join a room's WebSocket connection, for the collab_live
option. This action uses the same CSRF check and session check as
the other actions in this controller. Refer to the Autosave()
method below for the reason: this action adds no separate
per-room check.
EditorController::Autosave()
public function Autosave(Request $request): JsonResponseThis action is an optional, debounced autosave method. This action
serves EditorType fields with the collab_autosave option. This
action also serves regular fields with the collab option. This
action saves one field's value outside a full form submission. This
action uses an optimistic-concurrency version hash. Because of this
hash, a stale client never overwrites a newer saved value silently.
This action, by itself, with no WebSocket relay, is the complete "plain autosave" mode. In "live" collaboration mode, the relay calls this same action. In "live" mode, the browser does not call this action directly.
This action has no separate per-entity permission check, by design. A user can reach this action only through a form or a route that already allowed that user in, through this app's normal firewall and session system. This action also needs the same per-action CSRF token as the other actions in this controller. This action creates no new trust boundary.
This action accepts two callers, through two authentication paths.
A browser sends the usual session-scoped "token" value, for CSRF
protection. A browser uses this path in plain collab_autosave
mode. A browser also uses this path as the fallback path in
collab_live mode. The collab relay itself uses a different path.
The relay saves a collab_live room's content on its own debounced
schedule. The relay has no Symfony session for that call. Because
of this, the relay sends a "serviceToken" value and a "room" value
instead. This action checks these two values through
CollabTicketFactory::verifyServiceToken(). This method uses the
same shared secret as ticket creation.
MediaController class
class MediaController extends AbstractController MediaController.php:21
MediaController::__construct()
public function __construct(RequestStack $requestStack, Flysystem $flysystem, MediaService $mediaService, ImageCrops $imageCropRepository, ?Profiler $profiler = null, ?bool $localCache = null)MediaController::redirectToRoute()
public function redirectToRoute(string $route, array $parameters = [], int $status = 302): RedirectResponseReturns a RedirectResponse to the given route with the given parameters.
MediaController::Serve()
public function Serve($data): ResponseMediaController::ImageCropCacheless()
public function ImageCropCacheless($data, string $identifier, ?string $extension = null): ResponseMediaController::ImageCrop()
public function ImageCrop($data, string $identifier, ?string $extension = null): ResponseMediaController::ImageWebpCacheless()
public function ImageWebpCacheless($data): ResponseMediaController::ImageDebug()
public function ImageDebug($data, ?string $extension = null): ResponseMediaController::ImageCacheless()
public function ImageCacheless($data, ?string $extension = null): ResponseMediaController::ImageWebp()
public function ImageWebp($data): ResponseMediaController::ImageSvg()
public function ImageSvg($data): ResponseMediaController::Image()
public function Image($data, ?string $extension = null, bool $debug = false): ResponseBase\Database
Events class
final class Events Events.php:5
const resolveDiscriminator = 'resolveDiscriminator'const preQuery = 'preQuery'const onQuery = 'onQuery'const postQuery = 'postQuery'
Base\DatabaseSubscriber
AttributeSubscriber class
class AttributeSubscriber AttributeSubscriber.php:18
AttributeSubscriber::__construct()
public function __construct(EntityManagerInterface $entityManager, ClassMetadataManipulator $classMetadataManipulator, AttributeReader $attributeReader)AttributeSubscriber::loadClassMetadata()
public function loadClassMetadata(LoadClassMetadataEventArgs $event)AttributeSubscriber::resolveDiscriminator()
public function resolveDiscriminator(ResolveDiscriminatorEventArgs $event)AttributeSubscriber::preQuery()
public function preQuery(DoctrineQueryEventArgs $event): voidAttributeSubscriber::onQuery()
public function onQuery(DoctrineQueryEventArgs $event)AttributeSubscriber::postQuery()
public function postQuery(DoctrineQueryEventArgs $event)AttributeSubscriber::preFlush()
public function preFlush(PreFlushEventArgs $event)AttributeSubscriber::onFlush()
public function onFlush(OnFlushEventArgs $event)AttributeSubscriber::postFlush()
public function postFlush(PostFlushEventArgs $event)AttributeSubscriber::prePersist()
public function prePersist(LifecycleEventArgs $event)AttributeSubscriber::preUpdate()
public function preUpdate(LifecycleEventArgs $event)AttributeSubscriber::preRemove()
public function preRemove(LifecycleEventArgs $event)AttributeSubscriber::postLoad()
public function postLoad(LifecycleEventArgs $event)AttributeSubscriber::postPersist()
public function postPersist(LifecycleEventArgs $event)AttributeSubscriber::postUpdate()
public function postUpdate(LifecycleEventArgs $event)AttributeSubscriber::postRemove()
public function postRemove(LifecycleEventArgs $event)DemoAccountLockSubscriber class
class DemoAccountLockSubscriber DemoAccountLockSubscriber.php:31
A demonstration account stays what its declaration says, whoever asks and
through whichever form (registered in the demo environment only): its
identifier, its address, its password, its second factor are put back
before anything is written, it is not disabled, it is not deleted.
The pages of omnibase that change these refuse first, with a message (SecurityPolicy::isDemoAccount()); this is what holds for the others - the application's own "my account" page, the back office's users. A visitor signed in as "docteur" who could change that password would lock the next one out until the night's reset.
Only during a request: the fixtures and demo:reset write these accounts
from the console.
DemoAccountLockSubscriber::__construct()
public function __construct(readonly DemoAccountRegistry $accounts, readonly RequestStack $requestStack, readonly PasswordHasherFactoryInterface $hashers, readonly ?TranslatorInterface $translator = null)DemoAccountLockSubscriber::preFlush()
public function preFlush(PreFlushEventArgs $event): voidDemoAccountLockSubscriber::reset()
public function reset(): voidOne message a request: the service lives across requests in a worker.
IntlSubscriber class
class IntlSubscriber IntlSubscriber.php:26
IntlSubscriber::getLocalizer()
public function getLocalizer()IntlSubscriber::__construct()
public function __construct(EntityManagerInterface $entityManager, ?LocalizerInterface $localizer = null)The localizer is the framework's service; an entity manager built by hand maps the translations without it.
IntlSubscriber::onQuery()
public function onQuery(DoctrineQueryEventArgs $args)IntlSubscriber::resolveDiscriminator()
public function resolveDiscriminator(ResolveDiscriminatorEventArgs $resolveDiscriminatorEventArgs)IntlSubscriber::postLoad()
public function postLoad(LifecycleEventArgs $args)IntlSubscriber::upgradeIntl()
public function upgradeIntl($intl)- Throws
Exception
IntlSubscriber::prePersist()
public function prePersist(PrePersistEventArgs $args)The same as preFlush(), for an entity the flush itself finds new through a cascade (it was in no scheduled insertion before).
IntlSubscriber::preFlush()
public function preFlush(PreFlushEventArgs $args)A translation translate() handed out for a locale the entity had none
in is held aside until written in (TranslatableTrait): the written ones
join their entity's collection here, before the unit of work computes
what to insert, so $entity->translate('de')->setTitle(...) then
flush() persists the German title as it always did.
IntlSubscriber::onFlush()
public function onFlush(OnFlushEventArgs $args)IntlSubscriber::loadClassMetadata()
public function loadClassMetadata(LoadClassMetadataEventArgs $loadClassMetadataEventArgs): voidAdds mapping to the translatable and translations.
InverseCollectionCacheSubscriber class
class InverseCollectionCacheSubscriber InverseCollectionCacheSubscriber.php:27
Keeps the second-level cache's INVERSE collections true.
Doctrine refreshes the cached collection of the side that owns an association and leaves the other side's cached collection as it was: a product that drops a feature still shows in Feature::$products (the tag's threads) until the cache expires, so a "still in use" check or a listing reads a relation the database no longer has. On each flush, the inverse collection of every entity that joined or left an owning side - a many-to-many collection, or a many-to-one/one-to-one reference - is evicted, and reloads from the database on next read.
The whole region of that association goes, not the one entry: Doctrine's own Cache::evictCollection() builds its key without the SQL-filter hash its persisters add, so with a filter enabled it evicts nothing, and each set of enabled filters (front, back office) caches its own copy anyway.
InverseCollectionCacheSubscriber::onFlush()
public function onFlush(OnFlushEventArgs $args): voidTrackingPolicySubscriber class
class TrackingPolicySubscriber TrackingPolicySubscriber.php:11
TrackingPolicySubscriber::__construct()
public function __construct(ClassMetadataManipulator $classMetadataManipulator)TrackingPolicySubscriber::loadClassMetadata()
public function loadClassMetadata(LoadClassMetadataEventArgs $args)Base\Database\Attribute
Alias class
class Alias extends AbstractAttribute implements ExtensionOptionInterface Alias.php:15
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::bind()
public function bind($entity, $column, $alias)Alias::postLoad()
public function postLoad(LifecycleEventArgs $event, ClassMetadata $classMetadata, $entity, ?string $property = null)Alias::prePersist()
public function prePersist(LifecycleEventArgs $event, ClassMetadata $classMetadata, mixed $entity, ?string $property = null)Alias::preUpdate()
public function preUpdate(LifecycleEventArgs $event, ClassMetadata $classMetadata, mixed $entity, ?string $property = null)Associate class
class Associate extends AbstractAttribute implements ExtensionOptionInterface Associate.php:20
public string $metadata
Associate::__construct()
public function __construct(string $metadata)Associate::supports()
public function supports(string $target, ?string $targetValue = null, $object = null): boolAssociate::preUpdate()
public function preUpdate(LifecycleEventArgs $event, ClassMetadata $classMetadata, mixed $entity, ?string $property = null)Associate::prePersist()
public function prePersist(LifecycleEventArgs $event, ClassMetadata $classMetadata, mixed $entity, ?string $property = null)Associate::postUpdate()
public function postUpdate(LifecycleEventArgs $event, ClassMetadata $classMetadata, mixed $entity, ?string $property = null)Associate::postPersist()
public function postPersist(LifecycleEventArgs $event, ClassMetadata $classMetadata, mixed $entity, ?string $property = null)Associate::postLoad()
public function postLoad(LifecycleEventArgs $event, ClassMetadata $classMetadata, mixed $entity, ?string $property = null)Associate::preLifecycleEvent()
public function preLifecycleEvent(LifecycleEventArgs $event, ClassMetadata $classMetadata, mixed $entity, ?string $property = null)Associate::postLifecycleEvent()
public function postLifecycleEvent(LifecycleEventArgs $event, ClassMetadata $classMetadata, mixed $entity, ?string $property = null)Blameable class
class Blameable extends AbstractAttribute implements ExtensionOptionInterface Blameable.php:15
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::prePersist()
public function prePersist(LifecycleEventArgs $event, ClassMetadata $classMetadata, $entity, ?string $property = null)Blameable::preUpdate()
public function preUpdate(LifecycleEventArgs $event, ClassMetadata $classMetadata, $entity, ?string $property = null)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 = "ONE_TO_ONE"const TO_ONE = "TO_ONE"const TO_MANY = "TO_MANY"const ALL = "ALL"const NONE = "NONE"
Cache::__construct()
public function __construct(string $usage = 'READ_ONLY', ?string $region = null, ?string $associations = null)Cache::supports()
public function supports(string $target, ?string $targetValue = null, $object = null): boolCache::getRegion()
public function getRegion(ClassMetadata $classMetadata)Cache::getRegionProperty()
public function getRegionProperty(ClassMetadata $classMetadata, string $property)Cache::loadClassMetadata()
public function loadClassMetadata(ClassMetadata $classMetadata, string $target, ?string $targetValue = null): voidCache::payload()
public function payload(BaseLifecycleEventArgs $event, ClassMetadata $classMetadata, mixed $target, ?string $targetValue = null)Cache::prePersist()
public function prePersist(BaseLifecycleEventArgs $event, ClassMetadata $classMetadata, mixed $entity, ?string $property = null)Cache::preUpdate()
public function preUpdate(BaseLifecycleEventArgs $event, ClassMetadata $classMetadata, mixed $entity, ?string $property = null)Cache::preRemove()
public function preRemove(BaseLifecycleEventArgs $event, ClassMetadata $classMetadata, mixed $entity, ?string $property = null)Cascade class
class Cascade extends AbstractAttribute implements ExtensionOptionInterface Cascade.php:11
Cascade::__construct()
public function __construct(string $column = "", array $value = [])Cascade::supports()
public function supports(string $target, ?string $targetValue = null, $object = null): boolCascade::loadClassMetadata()
public function loadClassMetadata(ClassMetadata $classMetadata, string $target, ?string $targetValue = null): voidCountify class
class Countify extends AbstractAttribute implements ExtensionOptionInterface Countify.php:12
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): int- Throws
Exception
Countify::postLoad()
public function postLoad(LifecycleEventArgs $event, ClassMetadata $classMetadata, $entity, ?string $property = null)- Throws
Exception
Countify::prePersist()
public function prePersist(LifecycleEventArgs $event, ClassMetadata $classMetadata, $entity, ?string $property = null)- Throws
Exception
Countify::preUpdate()
public function preUpdate(LifecycleEventArgs $event, ClassMetadata $classMetadata, $entity, ?string $property = null)- 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:19
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::onFlush()
public function onFlush(OnFlushEventArgs $event, ClassMetadata $classMetadata, $entity, ?string $property = null)- Throws
Exception
Hashify class
class Hashify extends AbstractAttribute implements ExtensionOptionInterface Hashify.php:24
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::prePersist()
public function prePersist(LifecycleEventArgs $event, ClassMetadata $classMetadata, $entity, ?string $property = null)Hashify::preUpdate()
public function preUpdate(LifecycleEventArgs $event, ClassMetadata $classMetadata, $entity, ?string $property = null)Hashify::postPersist()
public function postPersist(LifecycleEventArgs $event, ClassMetadata $classMetadata, $entity, ?string $property = null)- Throws
Exception
Hashify::postUpdate()
public function postUpdate(LifecycleEventArgs $event, ClassMetadata $classMetadata, $entity, ?string $property = null)- Throws
Exception
Hierarchify class
class Hierarchify extends AbstractAttribute implements ExtensionOptionInterface Hierarchify.php:16
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::parent_method_exists()
public function parent_method_exists($object, $method)OrderColumn class
class OrderColumn extends AbstractAttribute implements ExtensionInlineInterface OrderColumn.php:21
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::loadClassMetadata()
public function loadClassMetadata(ClassMetadata $classMetadata, string $target, ?string $targetValue = null): voidOrderColumn::prePersist()
public function prePersist(LifecycleEventArgs $event, ClassMetadata $classMetadata, mixed $entity, ?string $property = null)OrderColumn::preUpdate()
public function preUpdate(LifecycleEventArgs $event, ClassMetadata $classMetadata, mixed $entity, ?string $property = null): voidOrderColumn::postLoad()
public function postLoad(LifecycleEventArgs $event, ClassMetadata $classMetadata, mixed $entity, ?string $property = null): voidOrphanRemoval 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:17
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::onFlush()
public function onFlush(OnFlushEventArgs $event, ClassMetadata $classMetadata, $entity, ?string $property = null)- 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)- 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::onFlush()
public function onFlush(OnFlushEventArgs $event, ClassMetadata $classMetadata, $entity, ?string $property = null)- Throws
Exception
Timestamp class
class Timestamp extends AbstractAttribute implements ExtensionOptionInterface Timestamp.php:18
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::prePersist()
public function prePersist(LifecycleEventArgs $event, ClassMetadata $classMetadata, $entity, ?string $property = null)Timestamp::preUpdate()
public function preUpdate(LifecycleEventArgs $event, ClassMetadata $classMetadata, $entity, ?string $property = null)Timezone class
class Timezone extends AbstractAttribute implements ExtensionOptionInterface Timezone.php:17
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::prePersist()
public function prePersist(LifecycleEventArgs $event, ClassMetadata $classMetadata, $entity, ?string $property = null)Timezone::preUpdate()
public function preUpdate(LifecycleEventArgs $event, ClassMetadata $classMetadata, $entity, ?string $property = null)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:32
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::onFlush()
public function onFlush(OnFlushEventArgs $event, ClassMetadata $classMetadata, mixed $entity, ?string $property = null)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::preFlush()
public function preFlush(PreFlushEventArgs $event, ClassMetadata $classMetadata, $entity, ?string $property = null): void- Throws
InvalidMimeTypeException
- Throws
InvalidSizeException
Uploader::preUpdate()
public function preUpdate(LifecycleEventArgs $event, ClassMetadata $classMetadata, $entity, ?string $property = null)- Throws
Exception
Uploader::postRemove()
public function postRemove(LifecycleEventArgs $event, ClassMetadata $classMetadata, $entity, ?string $property = null)Vault class
class Vault extends AbstractAttribute Vault.php:24
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::loadClassMetadata()
public function loadClassMetadata(ClassMetadata $classMetadata, string $target, ?string $targetValue = null): voidVault::preFlush()
public function preFlush(PreFlushEventArgs $event, ClassMetadata $classMetadata, mixed $entity, ?string $property = null): voidVault::preUpdate()
public function preUpdate(LifecycleEventArgs $event, ClassMetadata $classMetadata, mixed $entity, ?string $property = null): voidVault::prePersist()
public function prePersist(LifecycleEventArgs $event, ClassMetadata $classMetadata, mixed $entity, ?string $property = null): voidVault::preLifecycleEvent()
public function preLifecycleEvent($event, ClassMetadata $classMetadata, mixed $entity, ?string $property = null): voidVault::postFlush()
public function postFlush(PostFlushEventArgs $event, ClassMetadata $classMetadata, mixed $entity, ?string $property = null)Vault::postLoad()
public function postLoad(LifecycleEventArgs $event, ClassMetadata $classMetadata, mixed $entity, ?string $property = null)Vault::postLifecycleEvent()
public function postLifecycleEvent($event, ClassMetadata $classMetadata, mixed $entity, ?string $property = null)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\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\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:35
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(EntityManagerInterface $entityManager, ClassMetadataManipulator $classMetadataManipulator)EntityHydrator::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(Proxy $proxy)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)- Throws
Exception
EntityHydrator::getOriginalEntityData()
public function getOriginalEntityData($eventOrEntity)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)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\Event
DoctrineQueryEventArgs class
class DoctrineQueryEventArgs extends EventArgs DoctrineQueryEventArgs.php:11
DoctrineQueryEventArgs::__construct()
public function __construct(ClassMetadata $classMetadata, ?QueryBuilder $queryBuilder, ?Query $query = null)Constructor.
$queryThe Doctrine ORM Query object, or null if not yet created
$dqlThe DQL string associated with the query
DoctrineQueryEventArgs::getClassMetadata()
public function getClassMetadata(): ClassMetadataGet the ClassMetadata associated with the query.
DoctrineQueryEventArgs::getQuery()
public function getQuery(): ?QueryGet the current Doctrine Query object (may be null in preQueryCreate).
DoctrineQueryEventArgs::getEntityName()
public function getEntityName(): stringGet the name of the entity associated with the query.
- Returns
The fully qualified class name of the entity
DoctrineQueryEventArgs::setQuery()
public function setQuery(Query $query): voidSet the current Doctrine Query object.
$queryThe Doctrine ORM Query object
DoctrineQueryEventArgs::getQueryBuilder()
public function getQueryBuilder(): ?QueryBuilderGet the current QueryBuilder object (may be null in preQueryCreate).
DoctrineQueryEventArgs::setQueryBuilder()
public function setQueryBuilder(QueryBuilder $queryBuilder): voidSet the current QueryBuilder object.
$queryBuilderThe Doctrine ORM QueryBuilder object
ResolveDiscriminatorEventArgs class
class ResolveDiscriminatorEventArgs extends LoadClassMetadataEventArgs ResolveDiscriminatorEventArgs.php:7
Base\Database\Filter
TrashFilter class
class TrashFilter extends SQLFilter TrashFilter.php:27
Hides soft-deleted rows from every read that goes through the ORM.
Registered as "trash_filter" by DoctrineConfigurationPass and enabled in
BaseBundle::boot(). Disable it ($em->getFilters()->disable("trash_filter"))
to see the trash - the
trash listing, the restore flow and the purge command all do exactly that.
NB: the previous implementation emitted
deletedAt < <now + 1h> OR deletedAt IS NULLwhich is every row that was ever trashed plus every row that was not, i.e. it hid nothing. That went unnoticed for the same reason nothing else here worked: the filter WAS registered and enabled all along, it just resolved #[Trasheable] with getClassAttributes() on the exact class, which never matches an Article or a Gallery, and returned an empty constraint.
TrashFilter::addFilterConstraint()
public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias): string- Throws
Exception
VaultFilter class
class VaultFilter extends SQLFilter VaultFilter.php:11
VaultFilter::getEnvironment()
public function getEnvironment()VaultFilter::setEnvironment()
public function setEnvironment(string $environment)VaultFilter::addFilterConstraint()
public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias): string- Throws
Exception
Base\Database\Function
Field class
class Field extends FunctionNode Field.php:14
Field::parse()
public function parse(Parser $parser): voidField::getSql()
public function getSql(SqlWalker $sqlWalker): stringJsonArrayPosition class
class JsonArrayPosition extends FunctionNode JsonArrayPosition.php:16
const FUNCTION_NAME = 'JSON_ARRAY_POSITION'public $jsonExprpublic $searchExpr
JsonArrayPosition::__construct()
public function __construct()JsonArrayPosition::parse()
public function parse(Parser $parser): voidJsonArrayPosition::getSql()
public function getSql(SqlWalker $walker): stringRand class
class Rand extends FunctionNode Rand.php:10
Rand::parse()
public function parse(Parser $parser): voidRand::getSql()
public function getSql(SqlWalker $sqlWalker): stringBase\Database\Mapping
ClassMetadataCompletor class
class ClassMetadataCompletor ClassMetadataCompletor.php:5
ClassMetadataCompletor::__construct()
public function __construct(string $className, array $payload = [])ClassMetadataCompletor::getName()
public function getName(): ?stringClassMetadataCompletor::exists()
public function exists($name)ClassMetadataCompletor::__get()
public function __get($name)ClassMetadataCompletor::__set()
public function __set(string $name, mixed $value)ClassMetadataFactory class
class ClassMetadataFactory extends DoctrineClassMetadataFactory ClassMetadataFactory.php:27
Doctrine's ClassMetadataFactory, as the applications name it in their doctrine.yaml (class_metadata_factory_name), on doctrine/orm as published: it uses nothing Doctrine keeps private (plan "omnibase agnostique", C6).
What it did on a doctrine/orm that glitchr/base-plugin patched - the
resolveDiscriminator event before a class is read, the table names
checked, the discriminator maps keyed by class name through an overridden
getShortName() - is Base\Bridge\Doctrine\MappingDriver's, the driver the
bundle wraps every entity manager's with, and which an entity manager built
by hand gets from Base\Bridge\Doctrine\Mapping::register(), on Doctrine's own
factory. Kept here: the naming strategy given back to a ClassMetadata read
from the cache, getAllClassNames() and isEntity().
ClassMetadataFactory::setEntityManager()
public function setEntityManager(EntityManagerInterface $em): voidClassMetadataFactory::getAllClassNames()
public function getAllClassNames()ClassMetadataFactory::isEntity()
public function isEntity($class): bool{@inheritDoc}
ClassMetadataManipulator class
class ClassMetadataManipulator extends AbstractLocalCache ClassMetadataManipulator.php:45
const DEFAULT_TRACKING = 0
ClassMetadataManipulator::__construct()
public function __construct(ManagerRegistry $doctrine, EntityManagerInterface $entityManager, ?string $cacheDir = null, ?string $buildDir = null, array $globalExcludedFields = ['id', 'translatable', 'locale'])ClassMetadataManipulator::getEntityManager()
public function getEntityManager(): EntityManagerInterfaceClassMetadataManipulator::isEntity()
public function isEntity($entityOrClassOrMetadata): bool- Throws
Doctrine\Persistence\Mapping\MappingException
ClassMetadataManipulator::isEnumType()
public function isEnumType($entityOrClassOrMetadata): boolClassMetadataManipulator::isNativeEnum()
public function isNativeEnum(mixed $class): boolA PHP enum (backed or not), as opposed to omnibase's own EnumType / SetType column types.
ClassMetadataManipulator::getEnumClass()
public function getEnumClass(null|string|object $entityOrClassOrMetadata, string $fieldName): ?stringThe PHP enum a column holds: Doctrine's enumType: (which Doctrine also
reads by itself from a property typed with a backed enum), null for any
other column.
ClassMetadataManipulator::getGlobalTrackingPolicy()
public function getGlobalTrackingPolicy()ClassMetadataManipulator::setGlobalTrackingPolicy()
public function setGlobalTrackingPolicy(int $policy)- Throws
Exception
ClassMetadataManipulator::getTrackingPolicy()
public function getTrackingPolicy($className)ClassMetadataManipulator::setTrackingPolicy()
public function setTrackingPolicy($className, int $policy)- Throws
Exception
ClassMetadataManipulator::isSetType()
public function isSetType($entityOrClassOrMetadata): boolClassMetadataManipulator::getDoctrineType()
public function getDoctrineType(?string $type)ClassMetadataManipulator::getPrimaryKey()
public function getPrimaryKey($entity)- Throws
MappingException
ClassMetadataManipulator::getDiscriminatorColumn()
public function getDiscriminatorColumn($entity): ?stringClassMetadataManipulator::getDiscriminatorValue()
public function getDiscriminatorValue($entity): ?stringClassMetadataManipulator::getDiscriminatorMap()
public function getDiscriminatorMap($entity): arrayClassMetadataManipulator::getRootEntityName()
public function getRootEntityName($entity): ?stringClassMetadataManipulator::getRepository()
public function getRepository(null|string|object $entityOrClassOrMetadata)ClassMetadataManipulator::getClassMetadata()
public function getClassMetadata(null|string|object $entityOrClassOrMetadata)ClassMetadataManipulator::getFields()
public function getFields(null|string|object $entityOrClassOrMetadata, array $fields = [], array $excludedFields = []): arrayClassMetadataManipulator::getFieldValue()
public function getFieldValue($entity, string|array $fieldPath): mixed- Throws
Exception
ClassMetadataManipulator::setFieldValue()
public function setFieldValue($entity, string|array $fieldPath, $value)ClassMetadataManipulator::hasField()
public function hasField(null|string|object $entityOrClassOrMetadata, string $fieldName): boolClassMetadataManipulator::hasProperty()
public function hasProperty(null|string|object $entityOrClassOrMetadata, string $fieldName): ?stringClassMetadataManipulator::getPropertyValue()
public function getPropertyValue($entity, string $property)ClassMetadataManipulator::setPropertyValue()
public function setPropertyValue($entity, string $property, $value)ClassMetadataManipulator::getType()
public function getType(null|string|object $entityOrClassOrMetadata, string $property)- Throws
MappingException
ClassMetadataManipulator::getClosestEntity()
public function getClosestEntity(FormInterface|FormEvent $form)ClassMetadataManipulator::getClosestEntityCollection()
public function getClosestEntityCollection(FormInterface|FormEvent $form)ClassMetadataManipulator::isCollectionOwner()
public function isCollectionOwner(object $entityOrForm, ?Collection $collection = null): ?boolClassMetadataManipulator::getDeclaringEntity()
public function getDeclaringEntity(null|string|object $entityOrClassOrMetadata, $fieldPath)- Throws
Exception
ClassMetadataManipulator::getTargetClass()
public function getTargetClass(null|string|object $entityOrClassOrMetadata, $fieldName)- Throws
Exception
ClassMetadataManipulator::getTypeOfField()
public function getTypeOfField(null|string|object $entityOrClassOrMetadata, string $property)- Throws
Exception
ClassMetadataManipulator::getTypeOfAssociation()
public function getTypeOfAssociation(null|string|object $entityOrClassOrMetadata, string $property)- Throws
MappingException
ClassMetadataManipulator::fetchEntityName()
public function fetchEntityName(string $entityName, array|string $fieldPath): ?stringClassMetadataManipulator::fetchEntityMapping()
public function fetchEntityMapping(string $entityName, array|string $fieldPath): null|FieldMapping|AssociationMappingClassMetadataManipulator::isAlias()
public function isAlias(null|object|string $entityOrClassOrMetadata, array|string $fieldPath): boolClassMetadataManipulator::getBackFieldName()
public function getBackFieldName(null|object|string $entityOrClassOrMetadata, array|string $fieldName): ?stringClassMetadataManipulator::getFieldNameMappedBy()
public function getFieldNameMappedBy(null|object|string $entityOrClassOrMetadata, string $mappedBy): ?stringClassMetadataManipulator::getFieldNameInversedBy()
public function getFieldNameInversedBy(null|object|string $entityOrClassOrMetadata, string $inversedBy): ?stringClassMetadataManipulator::getFieldName()
public function getFieldName(null|object|string $entityOrClassOrMetadata, array|string $fieldName): ?stringClassMetadataManipulator::getFieldNames()
public function getFieldNames(null|object|string $entityOrClassOrMetadata): ?arrayClassMetadataManipulator::resolveFieldPath()
public function resolveFieldPath(null|object|string $entityOrClassOrMetadata, array|string $fieldPath): ?stringClassMetadataManipulator::getAssociationTargetClass()
public function getAssociationTargetClass(null|string|object $entityOrClassOrMetadata, string $fieldName): stringClassMetadataManipulator::hasAssociation()
public function hasAssociation(null|string|object $entityOrClassOrMetadata, ?string $fieldName)ClassMetadataManipulator::hasRecursiveAssociation()
public function hasRecursiveAssociation(null|string|object $entityOrClassOrMetadata, ?string $fieldName)ClassMetadataManipulator::getFieldMapping()
public function getFieldMapping(null|string|object $entityOrClassOrMetadata, string $fieldName): null|FieldMapping|AssociationMappingClassMetadataManipulator::getAssociationMapping()
public function getAssociationMapping(null|string|object $entityOrClassOrMetadata, string $fieldName): ?AssociationMappingClassMetadataManipulator::getUniqueKeys()
public function getUniqueKeys(null|string|object $entityOrClassOrMetadata, bool $inherits = false): ?arrayClassMetadataManipulator::hasTranslation()
public function hasTranslation(null|string|object $entityOrClassOrMetadata): boolClassMetadataManipulator::getTranslationMapping()
public function getTranslationMapping(null|string|object $entityOrClassOrMetadata, string $fieldName): ?FieldMappingClassMetadataManipulator::getMapping()
public function getMapping(null|string|object $entityOrClassOrMetadata, string $fieldName): null|FieldMapping|AssociationMappingClassMetadataManipulator::getAssociationMappings()
public function getAssociationMappings(null|string|object $entityOrClassOrMetadata): ?arrayClassMetadataManipulator::isOwningSide()
public function isOwningSide(null|string|object $entityOrClassOrMetadata, string $fieldName): boolClassMetadataManipulator::isInverseSide()
public function isInverseSide(null|string|object $entityOrClassOrMetadata, string $fieldName): boolClassMetadataManipulator::isToOneSide()
public function isToOneSide(null|string|object $entityOrClassOrMetadata, string $fieldName): boolClassMetadataManipulator::isToManySide()
public function isToManySide(null|string|object $entityOrClassOrMetadata, string $fieldName): boolClassMetadataManipulator::isManyToSide()
public function isManyToSide(null|string|object $entityOrClassOrMetadata, string $fieldName): boolClassMetadataManipulator::isOneToSide()
public function isOneToSide(null|string|object $entityOrClassOrMetadata, string $fieldName): boolClassMetadataManipulator::isManyToMany()
public function isManyToMany(null|string|object $entityOrClassOrMetadata, string $fieldName): boolClassMetadataManipulator::isOneToMany()
public function isOneToMany(null|string|object $entityOrClassOrMetadata, string $fieldName): boolClassMetadataManipulator::isManyToOne()
public function isManyToOne(null|string|object $entityOrClassOrMetadata, string $fieldName): boolClassMetadataManipulator::isOneToOne()
public function isOneToOne(null|string|object $entityOrClassOrMetadata, string $fieldName): boolClassMetadataManipulator::getAssociationType()
public function getAssociationType(null|string|object $entityOrClassOrMetadata, string $fieldName)- Throws
MappingException
ClassMetadataManipulator::getAllClassNames()
public function getAllClassNames()ClassMetadataManipulator::getClassMetadataCompletor()
public function getClassMetadataCompletor(null|string|object $entityOrClassOrMetadata): ?ClassMetadataCompletorClassMetadataManipulator::warmUp()
public function warmUp(string $cacheDir, ?string $buildDir = null): arrayClassMetadataManipulator::enrichAndSaveCompletors()
public function enrichAndSaveCompletors(\Base\Attributes\AttributeReader $attributeReader): voidRuns the attribute-driven loadClassMetadata pipeline for every entity so that
completors get their aliasNames, entityHierarchy, etc. fields populated,
then persists the enriched completors to the /Completors cache entry.
Must be called from a context where both this service and the AttributeReader are fully constructed (i.e. a Symfony cache warmer), never from __construct (that would recurse through the AttributeReader -> ClassMetadataManipulator dependency).
ClassMetadataManipulator::saveCompletors()
public function saveCompletors()NamingStrategy class
class NamingStrategy extends NamingStrategy NamingStrategy.php:23
omnibase's names for tables and columns: App\Entity\Thread\Tag is threadTag, App\Entity\User\Profile userProfile, Thread::$tags the join table thread_tags (thread_id, threadTag_id), a property its own name.
The rules are omnibridge/doctrine's NamingStrategy (framework-free, the one another framework reading the same database maps with), which this class extends: one place says how a class becomes a table. What omnibase adds on top is kept here, unchanged: a class may be given as an object, and every attribute of an entity is instantiated and must serialize (the metadata cache stores them) - a mistake said at once, with the attribute's name -, but for the attributes of a package not installed, which PHP itself ignores (audit "lesringostars face au master plan", R4: the core's entities read under Laravel, without API Platform).
NamingStrategy::classToTableName()
public function classToTableName($className): string- Throws
Exception
Base\Database\Middleware
PlatformMiddleware class
class PlatformMiddleware implements Middleware PlatformMiddleware.php:11
PlatformMiddleware::wrap()
public function wrap(Driver $driver): DriverBase\Database\Repository
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().
ServiceEntityParser class
class ServiceEntityParser ServiceEntityParser.php:29
const ALIAS_ENTITY = 'e'const REQUEST_FIND = "find"const REQUEST_CACHE = "cache"const REQUEST_COUNT = "count"const REQUEST_DISTINCT = "distinctCount"const REQUEST_LENGTH = "lengthOf"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"
ServiceEntityParser::__construct()
public function __construct(ServiceEntityRepository $serviceEntity, EntityManager $entityManager, ClassMetadataManipulator $classMetadataManipulator, EntityHydrator $entityHydrator)ServiceEntityParser::parse()
public function parse($method, $arguments): mixed- Throws
MappingException
ServiceEntityParser::getCustomOption()
public function getCustomOption(string $id)ServiceEntityParser::findCustomOption()
public function findCustomOption(string $id, string $option)ServiceEntityRepository class
class ServiceEntityRepository extends EntityRepository implements Entities ServiceEntityRepository.php:40
A repository of omnibase: Doctrine's EntityRepository, built from the
ManagerRegistry contract (doctrine/persistence) as DoctrineBundle's
ServiceEntityRepository is - __construct(ManagerRegistry $registry,
?string $entityName = null), the entity's class guessed from the
repository's name when not given - plus the finder language
(findByStateAndLocale(), cacheOneBySlug(), countByDomain()...).
It no longer extends DoctrineBundle's class (plan "omnibase agnostique",
step C3b): loading a repository loads doctrine/orm and doctrine/persistence,
not the bundle. Under Symfony it is still a repository service: the bundle
tags every service extending this class doctrine.repository_service
(BaseExtension, registerForAutoconfiguration(); AbstractBaseBundle::
isRepositoryService() for the bundles' mapped repositories), and
DoctrineBundle's ContainerRepositoryFactory hands it out as before.
What it answers without the ORM in or out is Entities, the interface the code of an application and of the core is given (audit "lesringostars face au master plan", step R15), with one per entity (Base\Repository\Threads...).
The finder's methods (findBy...(), cacheOneBy...(), countBy...()) are known to PHPStan by Base\Bridge\PHPStan\FinderMethodsExtension (extension.neon).
ServiceEntityRepository::getFqcnEntityName()
public static function getFqcnEntityName()ServiceEntityRepository::__construct()
public function __construct(ManagerRegistry $doctrine, ?string $entityName = null)ServiceEntityRepository::getClassMetadata()
public function getClassMetadata(): ClassMetadataServiceEntityRepository::getClassMetadataCompletor()
public function getClassMetadataCompletor(): ?ClassMetadataCompletorServiceEntityRepository::__call()
public function __call($method, $arguments): mixedServiceEntityRepository::find()
public function find($id, $lockMode = null, $lockVersion = null): ?objectServiceEntityRepository::findAll()
public function findAll(): arrayServiceEntityRepository::findBy()
public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null): arrayServiceEntityRepository::findOneBy()
public function findOneBy(array $criteria, ?array $orderBy = null): ?objectServiceEntityRepository::findByExample()
public function findByExample(object $select, ?array $orderBy = null, $limit = null, $offset = null): arrayQuery-by-Example: build the criteria from the *set* fields of a (usually non-persisted) select entity, then delegate to findBy(). Lets you query with a hydrated object instead of a raw array:
$select = (new Article())->setState('published'); $repo->findByExample($select); // == findBy(['state' => 'published'])
Only mapped scalar fields and to-one associations participate. Uninitialized and null properties are skipped — a select cannot express "IS NULL"; use the finder DSL (e.g. findByStateNull()) for that. Throws when the select yields no criteria, to avoid an accidental whole-table fetch (use findAll() instead).
- Throws
Exception
ServiceEntityRepository::criteriaFromSelect()
public function criteriaFromSelect(object $select): arrayReflect over a select entity and collect its set, mapped fields into a findBy()-compatible criteria array. Shared by findByExample() and by the finder DSL's "Model" clause (e.g. findByModelAndIdGreaterThan($select, 0)).
ServiceEntityRepository::count()
public function count(array $criteria = []): intThe number of rows matching $criteria (all of them for []), as Doctrine's count() promises: an int, never the grouped rows.
ServiceEntityRepository::flush()
public function flush(bool $autoclear = false)Flushes the unit of work - and clears the EntityManager only when asked: cleared by default (as it was), a request's signed-in user and every entity it held were detached for the rest of it, so the next flush touching them duplicated rows or failed on "a new entity was found through the relationship" (as SecuritySubscriber's did). A batch that wants its memory back passes true.
ServiceEntityRepository::clear()
public function clear()ServiceEntityRepository::persist()
public function persist($entity, bool $flush = false): void$entitychecked here: anything else than an entity of the class is refused
- Throws
Exception
ServiceEntityRepository::remove()
public function remove($entity, bool $flush = false): void$entitychecked as persist() checks it
- Throws
Exception
Base\Database\Schema
Describer class
final class Describer Describer.php:42
The description of an omnibase application's data (Omnibridge\Schema\ Description), built without any ORM from the entities' folders: their declarations read by reflection, omnibase's naming, and omnibase's rules in the order Doctrine's listeners run - the discriminators, the vaults, the order columns, the translations, the extensions, the targets resolved (audit "lesringostars face au master plan", R14).
$description = Describer::describe([$vendor.'/omnisense/omnibase/src/Entity', $projectDir.'/src/Entity'], ['project_dir' => $projectDir]);
Options: project_dir (its src/Enum, as Mapping::register()), enumerations (more folders of enumerations), types (by name, a bundle's), resolve_target_entities (interface => class), declarations (a Declarations source in place of the attributes: a set kept as data), rules (more rules, after omnibase's).
Doctrine, on the same classes, gives the same description (omnibridge/doctrine's MetadataDescription: tests/Bridge/Doctrine/SchemaDescriptionTest), and a MySQL database made from it compares equal (mysqlTypes(): the SQL type of each of omnibase's own columns - an ENUM or a SET of the enumeration's values, a long text for the serialized arrays and the passkeys' columns).
Describer::describe()
public static function describe(array $directories, array $options = []): Description$directoriesthe entities' folders
Describer::rules()
public static function rules(array $options = []): arrayomnibase's rules, in the order Doctrine's listeners run.
Describer::types()
public static function types(array $options = []): arrayThe column types by name: the core's, the enumerations of the core and of the project, those given.
Describer::mysqlTypes()
public static function mysqlTypes(array $types): arrayThe SQL type MySQL writes for each of omnibase's own column types (Omnibridge\Schema\Database\MySqlSchema's $types): ENUM or SET of the enumeration's values; for any other type of the family, what the type itself declares for MySQL (a long text for the serialized arrays, a tiny text for a passkey's aaguid, json for its trust path), lower-cased as information_schema writes it.
$typesby name (types())
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
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:31
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).
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:19
#[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\Type
ArrayType class
class ArrayType extends Type ArrayType.php:28
Type that maps a PHP array to a clob SQL type.
ArrayType::getSQLDeclaration()
public function getSQLDeclaration(array $column, AbstractPlatform $platform): string{@inheritDoc}
ArrayType::convertToDatabaseValue()
public function convertToDatabaseValue($value, AbstractPlatform $platform): mixed{@inheritDoc}
ArrayType::convertToPHPValue()
public function convertToPHPValue(mixed $value, AbstractPlatform $platform): mixed{@inheritDoc}
ArrayType::getName()
public function getName(){@inheritDoc}
ArrayType::requiresSQLCommentHint()
public function requiresSQLCommentHint(AbstractPlatform $platform){@inheritDoc}
DateTimeTypeUTC class
class DateTimeTypeUTC extends DateTimeType DateTimeTypeUTC.php:15
Doctrine's datetime (and datetimetz) as omnibase overrides them with
base.database.use_custom (BaseBundle::boot()): a \DateTime moved to UTC as
it is written, read back as UTC.
The conversion is omnibridge/doctrine's DateTimeType, the one another framework reading the same database registers (Omnibridge\Doctrine\Types): one place says how a moment is stored. This name stays the type omnibase registers, for the applications and bundles that name it.
EnumType class
abstract class EnumType extends Type implements SelectInterface EnumType.php:18
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::getSQLDeclaration()
public function getSQLDeclaration(array $column, AbstractPlatform $platform): stringEnumType::declaration()
public static function declaration(array $values, AbstractPlatform $platform, string $keyword = 'SET'): stringENUM('A', 'B') or SET('A', 'B'): written as DBAL writes an ENUM column's declaration, so that the column read back from the database (DBAL's EnumType, or MySQLSetType for a SET) compares equal while its values are the enumeration's.
EnumType::convertToPHPValue()
public function convertToPHPValue($value, AbstractPlatform $platform): mixedEnumType::convertToDatabaseValue()
public function convertToDatabaseValue($value, AbstractPlatform $platform): mixed- Throws
Exception
MySQLSetType class
final class MySQLSetType extends Type MySQLSetType.php:17
A SET column as the database has it, its values in the column's values
option, as DBAL's own EnumType is to an ENUM column: what
Base\Bridge\Doctrine\MySQLSchemaManager reads a SET column as, so that it
compares with the declaration of the Base\Database\Type\SetType it maps
(SET('A', 'B'), the same values, the same order) and differs from it once
the enumeration's values change. A mapping names its SetType, never this.
const NAME = 'omnibase_mysql_set'
MySQLSetType::getSQLDeclaration()
public function getSQLDeclaration(array $column, AbstractPlatform $platform): stringMySQLSetType::convertToPHPValue()
public function convertToPHPValue(mixed $value, AbstractPlatform $platform): arrayMySQLSetType::convertToDatabaseValue()
public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform): ?stringSetType class
abstract class SetType extends EnumType SetType.php:8
SetType::getSQLDeclaration()
public function getSQLDeclaration(array $column, AbstractPlatform $platform): stringSetType::convertToPHPValue()
public function convertToPHPValue($value, AbstractPlatform $platform): mixed- Throws
Exception
SetType::convertToDatabaseValue()
public function convertToDatabaseValue($value, AbstractPlatform $platform): mixed- Throws
Exception
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.
UtcDateTimeImmutableType class
final class UtcDateTimeImmutableType extends UtcDateTimeImmutableType UtcDateTimeImmutableType.php:31
A moment, written in UTC and read back as UTC (utc_datetime_immutable).
omnibase sets PHP's time zone per visitor (BaseBundle::boot(), from the
timezone cookie). Doctrine's own datetime_immutable writes the wall
clock of whatever zone the object carries and reads it back in PHP's
default one: the same instant is stored at different hours by two
requests, and comes back as another moment to a visitor elsewhere.
omnibase's datetime is UTC already (DateTimeTypeUTC); this is its
immutable twin, declared on a column that holds a moment:
#[ORM\Column(type: UtcDateTimeImmutableType::NAME)]
private \DateTimeImmutable $sentAt;The column is the platform's DATETIME, as datetime_immutable's: moving a
column from one type to the other changes no schema, only what its rows
mean (docs/20-architecture/time.md).
What comes back is in UTC; show it with Twig's |date (PHP's zone: the visitor's) or ->setTimezone(). A wall clock that is no moment (a restaurant's reservation at 20:00, an opening hour) is not for this type.
omnibridge/doctrine's UtcDateTimeImmutableType, under omnibase's name: written and read as it writes and reads (in UTC; unreadable, the DBAL's own exception).
const NAME = 'utc_datetime_immutable'
UtcDateTimeType class
final class UtcDateTimeType extends UtcDateTimeType UtcDateTimeType.php:19
UtcDateTimeImmutableType's mutable twin (utc_datetime): a \DateTime
written in UTC and read back as UTC, whatever zone PHP is in.
With base.database.use_custom (the default) omnibase's plain datetime is
UTC already; this type says so by name, and holds without that option. It
leaves the object it is given untouched (DateTimeTypeUTC moves the entity's
own \DateTime to UTC as it writes it).
omnibridge/doctrine's UtcDateTimeType, under omnibase's name: written and read as it writes and reads (in UTC; unreadable, the DBAL's own exception), so a site mapped by omnibase and an application mapped by omnibridge/doctrine read each other's rows.
const NAME = 'utc_datetime'
Base\Database\Type\Passkey
Aaguid class
final class Aaguid extends Type Aaguid.php:19
The model of a passkey's authenticator (its AAGUID), kept as the RFC 4122
text of a UUID (plan "omniauth", AU1). The column is that of
web-auth/webauthn-symfony-bundle's aaguid type (a CLOB of length 36,
TINYTEXT on MySQL), and so is the text (Symfony's Uuid as a string,
lowercase); PHP's value is that text, not a Uuid object, so that
Base\Entity\User\Passkey loads nothing of webauthn-lib nor symfony/uid. An
object that is a UUID (a Stringable, as Symfony's Uuid) is written as its
text.
const NAME = 'passkey_aaguid'
Aaguid::getSQLDeclaration()
public function getSQLDeclaration(array $column, AbstractPlatform $platform): stringAaguid::convertToDatabaseValue()
public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform): ?stringAaguid::convertToPHPValue()
public function convertToPHPValue(mixed $value, AbstractPlatform $platform): ?stringBase64 class
final class Base64 extends Type Base64.php:20
Bytes kept as standard base64 text (plan "omniauth", AU1): a passkey's
credential id and its public key (Base\Entity\User\Passkey). The column and
the text are those of web-auth/webauthn-symfony-bundle's base64 type,
which wrote the table first (a CLOB, LONGTEXT on MySQL; base64 with its
padding, ParagonIE's constant-time encoding giving PHP's own), so a row
written by either is read by the other - without the bundle, and under its
own name, so that a site keeping the bundle keeps the bundle's type too.
PHP's value is the bytes, a string.
const NAME = 'passkey_base64'
Base64::getSQLDeclaration()
public function getSQLDeclaration(array $column, AbstractPlatform $platform): stringBase64::convertToDatabaseValue()
public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform): ?stringBase64::convertToPHPValue()
public function convertToPHPValue(mixed $value, AbstractPlatform $platform): ?stringTrustPath class
final class TrustPath extends JsonType TrustPath.php:16
A passkey's attestation trust path, as the JSON it is kept in (plan
"omniauth", AU1): [] for none (EmptyTrustPath), {"x5c": [...]} for a
chain of certificates. The column and the text are those of
web-auth/webauthn-symfony-bundle's trust_path type (a JSON column, what
webauthn-lib's normalizer gives, encoded by json_encode() as Doctrine's
JSON type encodes it); PHP's value is the decoded array, not a TrustPath
object - webauthn-lib's TrustPathDenormalizer makes one of it.
const NAME = 'passkey_trust_path'
Base\Database\Walker
CountWalker class
class CountWalker extends TreeWalkerAdapter CountWalker.php:11
CountWalker::walkSelectStatement()
public function walkSelectStatement(SelectStatement $AST): voidWalks down a SelectStatement AST node, thereby generating the appropriate SQL.
GroupByWalker class
class GroupByWalker extends TreeWalkerAdapter GroupByWalker.php:11
const HINT_GROUP_ARRAY = "group_by.array"
GroupByWalker::walkSelectStatement()
public function walkSelectStatement(SelectStatement $AST): voidWalks down a SelectStatement AST node, thereby generating the appropriate SQL.
MysqlWalker class
class MysqlWalker extends SqlWalker MysqlWalker.php:7
const HINT_NO_CACHE = "mysql.no_cache"
MysqlWalker::walkSelectClause()
public function walkSelectClause(AST\SelectClause $selectClause): stringWalks down a SelectClause AST node, thereby generating the appropriate SQL.
- Returns
The SQL.
TranslatableWalker class
class TranslatableWalker extends SqlOutputWalker implements OutputWalker TranslatableWalker.php:17
const LOCALE = 'locale'const FOREIGN_KEY = 'translatable_id'const COLUMN_NAME = 'translations'const SALT = "unique_translation"
TranslatableWalker::__construct()
public function __construct($query, $parserResult, array $queryComponents)TranslatableWalker::walkFromClause()
public function walkFromClause($fromClause): stringTranslatableWalker::walkJoinAssociationDeclaration()
public function walkJoinAssociationDeclaration($joinAssociationDeclaration, $joinType = AST\Join::JOIN_TYPE_INNER, $condExpr = null): string- Throws
QueryException
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:22
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.
DemoAccountFactory::__construct()
public function __construct(readonly DemoAccountRegistry $registry, readonly 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.
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:27
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(): boolBase\DependencyInjection
BaseConfiguration class
class BaseConfiguration extends AbstractBaseConfiguration BaseConfiguration.php:13
BaseConfiguration::getConfigTreeBuilder()
public function getConfigTreeBuilder(): TreeBuilderBaseExtension class
class BaseExtension extends AbstractBaseExtension implements PrependExtensionInterface BaseExtension.php:30
BaseExtension::getConfiguration()
public function getConfiguration(array $config, ContainerBuilder $container): ConfigurationInterfaceThe tree of base:, for config:dump-reference and debug:config: Symfony looks for a class named Configuration beside the extension, the core's is BaseConfiguration.
BaseExtension::load()
public function load(array $configs, ContainerBuilder $container): void{@inheritdoc}
BaseExtension::prepend()
public function prepend(ContainerBuilder $builder): voidBase\DependencyInjection\Compiler
AbstractPass class
abstract class AbstractPass implements CompilerPassInterface AbstractPass.php:12
AbstractPass for handling tagged services or entities implementing a specific interface.
AbstractPass::classFqcn()
abstract public function classFqcn(): stringAbstractPass::taggedServiceIds()
abstract public function taggedServiceIds(): ?stringAbstractPass::serviceInterface()
abstract public function serviceInterface(): ?stringAbstractPass::addMethod()
abstract public function addMethod(): stringAbstractPass::addArguments()
public function addArguments(string $className): arrayAbstractPass::process()
public function process(ContainerBuilder $container): voidBase\DependencyInjection\Compiler\Pass
AdminUrlGeneratorPass class
final class AdminUrlGeneratorPass implements CompilerPassInterface AdminUrlGeneratorPass.php:19
Binds Base\Routing\AdminUrlGeneratorInterface to whatever back-office is installed.
base-bundle ships form types and Twig helpers that link back to the admin, but a front-end-only install has no admin at all. Resolving the binding in a compiler pass - rather than by registering competing service ids in two bundles - makes the outcome independent of bundle load order.
AdminUrlGeneratorPass::process()
public function process(ContainerBuilder $container): voidApplicationTextsPass class
final class ApplicationTextsPass implements CompilerPassInterface ApplicationTextsPass.php:23
Which texts the application wrote itself (its own translations/ directory), 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 here, while the container is built, and given to omnibase's translator. Nothing is read when no level is set.
ApplicationTextsPass::process()
public function process(ContainerBuilder $container): voidApplicationTextsPass::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
AttributePass class
class AttributePass extends AbstractPass AttributePass.php:8
AttributePass::serviceInterface()
public function serviceInterface(): ?stringAttributePass::taggedServiceIds()
public function taggedServiceIds(): ?stringAttributePass::classFqcn()
public function classFqcn(): stringAttributePass::addMethod()
public function addMethod(): stringContractsPass class
final class ContractsPass implements CompilerPassInterface ContractsPass.php:43
The locator Base\Contract\Runtime reaches the contracts of the Foundation through (plan "omnibase agnostique", C4), handed to it by BaseBundle::boot() - omnisense/omnibridge's registry since A2, the host's contracts (Omnibridge\Contract\*) with omnibase's own (Nouns, Media, Pictures, Texts, the parameters) and the mailer: each contract by its interface's name, the service the container binds to that name - omnibridge/symfony's adapters and omnibase's (config/services/core.php), the framework's clock, event dispatcher and mailer, or an application's own binding, which wins as any alias does.
The building itself is omnibridge/symfony's since A1 (Omnibridge\Symfony\DependencyInjection\ContractsPass: only the contracts whose service exists are listed, an adapter of omnibridge/symfony whose framework service is missing removed, a locator of closures); this pass gives it omnibase's list, its former names and its service id.
const SERVICE = 'base.contracts'const CONTRACTS = [Urls::class, Routes::class, Environment::class, ParameterBagInterface::class, Translations::class, Nouns::class, Access::class, Sessions::class, Locales::cl…const FORMER = []The former names of the contracts that moved to omnisense/omnibridge (A2): none since omnibase 4's final pass, which removed them (the sites and bundles name Omnibridge\Contract\*). Kept for HostContractsPass's signature, empty.
const SERVICES = [ParameterBagInterface::class => 'parameter_bag']The contracts bound to another service than their interface's name: the parameters are
parameter_bag(HotParameterBag, the settings stored in the database over the container's), what BaseTrait's getParameterBag() gives - the interface's name is the plain Base\Service\ParameterBag.
ContractsPass::process()
public function process(ContainerBuilder $container): voidDoctrineConfigurationPass class
class DoctrineConfigurationPass implements CompilerPassInterface DoctrineConfigurationPass.php:28
omnibase's Doctrine mapping on DoctrineBundle's entity managers, from the same lists and the same driver an entity manager built by hand gets from Base\Bridge\Doctrine\Mapping (plan "omnibase agnostique", C6):
- the filters, the DQL functions and the default hint of
Base\Bridge\Doctrine\Configuration, on
doctrine.orm.configuration; - every entity manager's mapping driver wrapped in omnibridge/doctrine's
DeclarationDriver (the metadata built from the classes' declarations,
Omnibridge\Schema\Declaration: the structure described outside Doctrine,
audit R14), then in Base\Bridge\Doctrine\MappingDriver (the discriminator
maps generated, the
resolveDiscriminatorevent), given its entity manager lazily.
DoctrineConfigurationPass::process()
public function process(ContainerBuilder $container): voidEntityExtensionPass class
class EntityExtensionPass extends AbstractPass EntityExtensionPass.php:10
EntityExtensionPass::serviceInterface()
public function serviceInterface(): ?stringEntityExtensionPass::taggedServiceIds()
public function taggedServiceIds(): ?stringEntityExtensionPass::classFqcn()
public function classFqcn(): stringEntityExtensionPass::addMethod()
public function addMethod(): stringFlysystemStoragesPass class
final class FlysystemStoragesPass implements CompilerPassInterface FlysystemStoragesPass.php:24
The storages of Base\Service\Flysystem in a Symfony application without
league/flysystem-bundle (plan "omnibase agnostique", C7b). The flysystem
service reads the services tagged flysystem.storage by their storage
name, which is what the bundle tags each storage of its configuration
with; without the bundle registered, nothing is tagged, and omnibase gives
its local storages here, where its demonstration keeps them - the images'
cache under var/cache, the uploads and the editor's files under
var/storage, each beside its public directory under public/.
With the bundle registered nothing is added: the application's config/packages/flysystem.yaml names its storages, as before.
const TAG = 'flysystem.storage'const STORAGES = ['local.cache' => '%kernel.project_dir%/var/cache/%kernel.environment%/images', 'local.cache.public' => '%kernel.project_dir%/public/images', 'local.uploads'…
FlysystemStoragesPass::process()
public function process(ContainerBuilder $container): voidGuardPass class
final class GuardPass implements CompilerPassInterface GuardPass.php:15
Base\Service\FormGuard's default captcha is glitchr/omnishield's (omnishield.challenge.gateway) - a parameter that exists only when omnishield's bundle is registered: read here, once every extension has loaded, rather than named in the service's definition. So is glitchr/ux-google's switch, for the sign-in's captcha (SignInGuard).
GuardPass::process()
public function process(ContainerBuilder $container): voidIconProviderPass class
class IconProviderPass extends AbstractPass IconProviderPass.php:8
IconProviderPass::serviceInterface()
public function serviceInterface(): ?stringIconProviderPass::taggedServiceIds()
public function taggedServiceIds(): ?stringIconProviderPass::classFqcn()
public function classFqcn(): stringIconProviderPass::addMethod()
public function addMethod(): stringObfuscatorCompressionPass class
class ObfuscatorCompressionPass extends AbstractPass ObfuscatorCompressionPass.php:8
ObfuscatorCompressionPass::serviceInterface()
public function serviceInterface(): ?stringObfuscatorCompressionPass::taggedServiceIds()
public function taggedServiceIds(): stringObfuscatorCompressionPass::classFqcn()
public function classFqcn(): stringObfuscatorCompressionPass::addMethod()
public function addMethod(): stringSharingPass class
class SharingPass extends AbstractPass SharingPass.php:8
SharingPass::serviceInterface()
public function serviceInterface(): ?stringSharingPass::taggedServiceIds()
public function taggedServiceIds(): ?stringSharingPass::classFqcn()
public function classFqcn(): stringSharingPass::addMethod()
public function addMethod(): stringTagRendererPass class
class TagRendererPass extends AbstractPass TagRendererPass.php:8
TagRendererPass::serviceInterface()
public function serviceInterface(): ?stringTagRendererPass::taggedServiceIds()
public function taggedServiceIds(): ?stringTagRendererPass::classFqcn()
public function classFqcn(): stringTagRendererPass::addMethod()
public function addMethod(): stringTextOverrideCachePass class
final class TextOverrideCachePass implements CompilerPassInterface TextOverrideCachePass.php:13
The rewritten texts (Base\Translation\OverridingTranslator) are cached in the application's shared Redis pool when it declares one (cache.redis): the web, the worker and cron then agree after an edit. Otherwise cache.app.
TextOverrideCachePass::process()
public function process(ContainerBuilder $container): voidTradingPass class
class TradingPass extends AbstractPass TradingPass.php:8
TradingPass::serviceInterface()
public function serviceInterface(): ?stringTradingPass::taggedServiceIds()
public function taggedServiceIds(): ?stringTradingPass::classFqcn()
public function classFqcn(): stringTradingPass::addMethod()
public function addMethod(): stringTwigComponentPass class
class TwigComponentPass implements CompilerPassInterface TwigComponentPass.php:10
TwigComponentPass::process()
public function process(ContainerBuilder $container): voidWebauthnDeprecatedAliasPass class
class WebauthnDeprecatedAliasPass implements CompilerPassInterface WebauthnDeprecatedAliasPass.php:21
WebauthnExtension (web-auth/webauthn-symfony-bundle 5.3) still aliases the
deprecated PublicKeyCredentialSourceRepositoryInterface to the configured
credential_repository, next to CredentialRecordRepositoryInterface. Nothing
in the bundle or here asks for the deprecated name, but the alias forced
PasskeyRepository to keep implementing it (an alias to an interface the
class lacks fails lint:container), and implementing it raises a
deprecation on every boot.
Dropping the alias lets the repository implement only the current contract.
The id is a string on purpose: ::class on a deprecated interface is
harmless, but a string keeps this pass from ever needing it autoloaded.
WebauthnDeprecatedAliasPass::process()
public function process(ContainerBuilder $container): voidWebauthnMappingPass class
class WebauthnMappingPass implements CompilerPassInterface WebauthnMappingPass.php:23
WebauthnBundle's own Doctrine mapping turned off (plan "omniauth", AU1).
The bundle maps, in XML, webauthn-lib's Webauthn\CredentialRecord and two entities of the library as mapped superclasses, for an application's credential entity to inherit (WebauthnBundle::build() adds the driver to every entity manager's chain, under the namespace "Webauthn", whatever the configuration). The core describes the passkeys' table itself since AU1: Base\Entity\User\Passkey declares its 13 fields and no longer extends the record, and no class of a site does (searched). The driver would only list three classes that nothing maps, which Symfony alone would know (the Laravel twin, or an entity manager built by hand, has no bundle) - so it is taken out of the chains, after the bundle's pass. Its DBAL types stay registered (a site's own column might name them); the core's columns use its own.
WebauthnMappingPass::getPriority()
public static function getPriority(): intAfter WebauthnBundle's DoctrineOrmMappingsPass (priority 0, before optimization).
WebauthnMappingPass::process()
public function process(ContainerBuilder $container): voidWorkflowPass class
class WorkflowPass extends AbstractPass WorkflowPass.php:13
WorkflowPass::serviceInterface()
public function serviceInterface(): ?stringWorkflowPass::taggedServiceIds()
public function taggedServiceIds(): ?stringWorkflowPass::classFqcn()
public function classFqcn(): stringWorkflowPass::addMethod()
public function addMethod(): stringWorkflowPass::process()
public function process(ContainerBuilder $container): voidBase\DependencyInjection\Dumper
CliDumper class
class CliDumper extends CliDumper CliDumper.php:8
CliDumper::__construct()
public function __construct($output = null, ?string $charset = null, int $flags = 0)CliDumper::dumpString()
public function dumpString(Cursor $cursor, string $str, bool $bin, int $cut): voidHtmlDumper class
class HtmlDumper extends HtmlDumper HtmlDumper.php:6
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:60
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 AbstractEvent.php:13
NB: Flushing object manager from within listener should be avoided, this is done already in event dispatcher if needed.
AbstractEvent::__construct()
public function __construct(LifecycleEventArgs $eventArgs, ?Request $request)AbstractEvent::getLifecycle()
public function getLifecycle(): LifecycleEventArgsAbstractEvent::getRequest()
public function getRequest(): ?RequestAbstractEvent::getObjectManager()
public function getObjectManager()AbstractEvent::getObjectClass()
public function getObjectClass(): stringAbstractEvent::getObject()
public function getObject(): objectAbstractEventDispatcher class
abstract class AbstractEventDispatcher implements EventDispatcherInterface, ResetInterface AbstractEventDispatcher.php:19
const DISPATCHER_SUFFIX = "Dispatcher"
AbstractEventDispatcher::live()
public static function live(): array- Returns
the dispatchers built in this process
AbstractEventDispatcher::__construct()
public function __construct(SymfonyEventDispatcherInterface $dispatcher, EntityHydratorInterface $entityHydrator, EntityManagerInterface $entityManager, RequestStack $requestStack)AbstractEventDispatcher::getEventClass()
public static function getEventClass()- Throws
Exception
AbstractEventDispatcher::addEvent()
public function addEvent(string $event, mixed $object)AbstractEventDispatcher::dispatchEvents()
public function dispatchEvents(LifecycleEventArgs $event)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()AbstractEventDispatcher::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)AbstractEventDispatcher::preUpdate()
public function preUpdate(LifecycleEventArgs $event)AbstractEventDispatcher::preRemove()
public function preRemove(LifecycleEventArgs $event)AbstractEventDispatcher::postPersist()
public function postPersist(LifecycleEventArgs $event)AbstractEventDispatcher::postUpdate()
public function postUpdate(LifecycleEventArgs $event)AbstractEventDispatcher::postRemove()
public function postRemove(LifecycleEventArgs $event)AbstractEventDispatcher::onPersist()
public function onPersist(LifecycleEventArgs $event)AbstractEventDispatcher::onUpdate()
public function onUpdate(LifecycleEventArgs $event)AbstractEventDispatcher::onRemove()
public function onRemove(LifecycleEventArgs $event)EventDispatcherInterface interface
interface EventDispatcherInterface EventDispatcherInterface.php:10
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::onPersist()
public function onPersist(LifecycleEventArgs $event)ThreadEventDispatcher::onUpdate()
public function onUpdate(LifecycleEventArgs $event)UserEvent class
class UserEvent extends AbstractEvent UserEvent.php:14
The user.* events: UserEventDispatcher dispatches user.register when an account is persisted, and each other one when an update puts the account in that state (approved, verified, enabled, disabled, kicked out, locked, newcomer, banned; user.ghost when it stops being a ghost).
const REGISTER = 'user.register'const VERIFIED = 'user.verified'const APPROVAL = 'user.approval'const DISABLED = 'user.disabled'const ENABLED = 'user.enabled'const KICKED = 'user.kickout'const LOCKED = 'user.locked'const NEWCOMER = 'user.newcomer'const GHOST = 'user.ghost'const BANNED = 'user.banned'
UserEvent::getUser()
public function getUser(): UserUserEventDispatcher class
class UserEventDispatcher extends AbstractEventDispatcher UserEventDispatcher.php:9
UserEventDispatcher::supports()
public function supports(mixed $subject): boolUserEventDispatcher::onPersist()
public function onPersist(LifecycleEventArgs $event)UserEventDispatcher::onUpdate()
public function onUpdate(LifecycleEventArgs $event)Base\EntitySubscriber
ConnectionSubscriber class
class ConnectionSubscriber implements EventSubscriberInterface ConnectionSubscriber.php:19
ConnectionSubscriber::__construct()
public function __construct(UserTracker $userTracker, EntityManagerInterface $entityManager)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)ExtensionSubscriber class
class ExtensionSubscriber HookExtensionSubscriber.php:16
ExtensionSubscriber::__construct()
public function __construct(EntityManagerInterface $entityManager, EntityExtension $entityExtension)ExtensionSubscriber::loadClassMetadata()
public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs)ExtensionSubscriber::onFlush()
public function onFlush(OnFlushEventArgs $event)ExtensionSubscriber::postPersist()
public function postPersist(EventArgs $args)ExtensionSubscriber::payload()
public function payload(string $action, array $entities)- Throws
Exception
SettingSubscriber class
class SettingSubscriber SettingSubscriber.php:20
Invalidates SettingBag's compiled snapshot on any Setting/SettingIntl write, not just ones that went through SettingBag::set(). The admin CRUD (EasyAdmin's SettingCrudController / LayoutSettingListType) persists these entities via a plain flush() and never called SettingBag::set() at all, so without this listener an admin edit (e.g. the site logo) would keep serving the stale cached value until the next unrelated cache:clear.
SettingSubscriber::__construct()
public function __construct(protected \Closure $settingBag)Lazy closure (service_closure in DI config), NOT the SettingBag itself: Doctrine instantiates event listeners during event-manager initialization, and constructing SettingBag there drags in SettingRepository -> getClassMetadata() -> a re-entrant resolveDiscriminator dispatch that corrupts the event manager's partially-initialized listener state. The closure defers all of that to the first actual Setting write.
SettingSubscriber::postPersist()
public function postPersist(PostPersistEventArgs $args): voidSettingSubscriber::postUpdate()
public function postUpdate(PostUpdateEventArgs $args): voidSettingSubscriber::postRemove()
public function postRemove(PostRemoveEventArgs $args): voidThreadSubscriber class
class ThreadSubscriber implements EventSubscriberInterface ThreadSubscriber.php:18
ThreadSubscriber::__construct()
public function __construct(MentionEnhancerInterface $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)ThreadSubscriber::preUpdate()
public function preUpdate(PreUpdateEventArgs $event)ThreadSubscriber::onFlush()
public function onFlush(OnFlushEventArgs $event)TrasheableSubscriber class
class TrasheableSubscriber TrasheableSubscriber.php:59
Turns $em->remove() into a soft delete for every entity carrying
#[Trasheable] - Thread and, through it, articles, galleries, comments,
guestbook messages, calendars and newsletters.
## How the DELETE is cancelled
preRemove cannot veto anything, so the interception happens at onFlush, after computeChangeSets has scheduled everything but before any SQL runs:
- the deletion field is stamped,
persist()on an entity in STATE_REMOVED puts it back to STATE_MANAGED and drops it from the deletion queue - that is what cancels the DELETE,- scheduleExtraUpdate then emits the UPDATE that writes the stamp.
## Why the cascade has to be rescued
Thread::$translations is mapped cascade: [persist, refresh, remove], so by
the time we get here Doctrine has already queued every ThreadIntl row for
deletion. Cancelling only the parent would trash an article and destroy its
title, headline, excerpt and content on the way in - restoring would hand
back an empty shell. So every entity the removal cascaded to is rescued with
it, recursively.
## Hard deletion
An entity whose deletion field is ALREADY stamped is left alone and deleted for real. That is deliberate and is the only escape hatch: emptying the trash, and the "delete permanently" action, both work by removing an already-trashed entity.
## Why the second-level cache has to be evicted
Thread is #[Cache(usage: "NONSTRICT_READ_WRITE")], and the L2 entity
region is keyed by id alone - Doctrine folds the filter hash into query and
collection keys, but not into that one. A copy cached before the trashing
therefore still says deletedAt = null, which broke both directions: find()
kept handing out entities the filter had hidden, and a later remove() read
that stale null and soft-deleted an already-trashed entity instead of
purging it. Evicting on the way out puts the next read back on the database,
where the filter applies.
TrasheableSubscriber::__construct()
public function __construct(string|int $emptyTrash = "+7 days")$emptyTrashbase.extension.empty_trash: a relative date ("+7 days"), or a number of days
TrasheableSubscriber::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.
TrasheableSubscriber::onFlush()
public function onFlush(OnFlushEventArgs $event): voidTrasheableSubscriber::postFlush()
public function postFlush(PostFlushEventArgs $event): voidUserSubscriber class
class UserSubscriber implements EventSubscriberInterface, ResetInterface UserSubscriber.php:22
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 TokenStorageInterface $tokenStorage)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): voidVersionableSubscriber class
class VersionableSubscriber VersionableSubscriber.php:47
Records what changed, for every property carrying #[Versionable].
One Revision per entity per flush, not one per field: a save that retitles an
article and moves it out of draft is one editorial act and reads as one line
of history. entityData is the diff, {"<field>": [old, new]}.
## Translations are folded into their parent
Everything an editor actually types - title, headline, excerpt, content, keywords - lives on ThreadIntl, one row per locale, not on Thread. Left alone, an article's history would be scattered across itself plus N translation rows, none of which the admin has a page for.
So a revision of a TranslationInterface entity is attributed to its translatable parent and its keys are prefixed with the locale:
{"slug": [...], "fr.content": [...], "en.title": [...]}which is also the shape the per-field history badge reads, since the form renders translated fields under their locale too.
## Value normalisation
entityData is a JSON column, so entities and collections are reduced to ids (plus a label kept only for display - restoring reads the ids). Dates go to ATOM. Nothing else survives: an un-normalisable value is dropped from the diff rather than allowed to break the flush.
VersionableSubscriber::__construct()
public function __construct(protected EntityManagerInterface $entityManager, protected int $maxRevisions = 5)VersionableSubscriber::onFlush()
public function onFlush(OnFlushEventArgs $event): voidVersionableSubscriber::postFlush()
public function postFlush(PostFlushEventArgs $event): voidKeep only the newest max_revisions per entity. Done after the flush so
the revision this flush just wrote is counted, and issued as DQL so a
long history is not hydrated to be thrown away.
Base\Entity\Analytics
PageView class
class PageView PageView.php:27
One row per (path, HOUR, source) - an hourly rolling aggregate, not a per-request event log. $views is incremented atomically (see PageViewRepository, which buckets any timestamp down to the top of its hour before writing) on every trackable request; time windows ("24h", "7 days", "all time") are just a SUM over however many of these rows fall in range, and a calendar-day figure (dailyBreakdown()) is itself a SUM over that day's up-to-24 hourly rows rather than its own storage grain - this is what lets "today" plot an hour-by-hour curve instead of the single flat point a pure daily rollup could ever produce.
$source splits that aggregate three ways (see Base\Service\Analytics\ UserAgentClassifier, which is what decides it at track() time) so a dashboard can tell real visitors apart from search/monitoring crawlers (SOURCE_BOT) and AI/LLM crawlers (SOURCE_AI) instead of one number that silently mixes all three. Rows written before this column existed (or by a raw INSERT that omits it, as the test suite's seed data does) default to SOURCE_HUMAN - the historic assumption this table always made.
const SOURCE_HUMAN = "human"const SOURCE_BOT = "bot"const SOURCE_AI = "ai"
PageView::getId()
public function getId(): ?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:16
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:26
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 = UrlGeneratorInterface::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:16
Link::__iconize()
public function __iconize(): ?arrayLink::__iconizeStatic()
public static function __iconizeStatic(): ?arrayLink::__toLink()
public function __toLink(array $routeParameters = [], int $referenceType = UrlGeneratorInterface::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 = UrlGeneratorInterface::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 glitchr/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 glitchr/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:27
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:42
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, Twig and the project's directory this notification reaches through BaseTrait.
Notification::asChatMessage()
public function asChatMessage(RecipientInterface $recipient, ?string $transport = null): ?ChatMessagePasskey class
class Passkey Passkey.php:35
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 core's types Base\Database\Type\Passkey\{Base64, Aaguid, TrustPath}
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 glitchr/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(){}
UploaderAmbiguityException class
class UploaderAmbiguityException extends Exception UploaderAmbiguityException.php:7
UploaderAmbiguityException::getMessageKey()
public function getMessageKey(){}
VaultKeyNotFoundException class
class VaultKeyNotFoundException extends RuntimeException VaultKeyNotFoundException.php:9
A field secured by #[Vault] is about to be stored and the vault has no key pair: the value is refused rather than written in clear.
public readonly string $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:7
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:9
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:12
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:8
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:9
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:9
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:8
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:12
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:8
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:10
ColorField::new()
public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): selfColorPickerField class
final class ColorPickerField implements FieldInterface ColorPickerField.php:9
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:9
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:8
CurrencyField::new()
public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): selfDateField class
class DateField implements FieldInterface DateField.php:8
DateField::new()
public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): selfDateTimeField class
class DateTimeField implements FieldInterface DateTimeField.php:8
DateTimeField::new()
public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): selfDateTimePickerField class
final class DateTimePickerField implements FieldInterface DateTimePickerField.php:9
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:9
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:9
EditorField::new()
public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): selfEmailField class
class EmailField implements FieldInterface EmailField.php:8
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:10
EmojiPickerField::new()
public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): selfFieldDescriptor class
final class FieldDescriptor FieldDescriptor.php:15
Single mutable descriptor carried by every field: what property it maps, which Symfony FormType renders it, where it is displayed, and how.
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::getFormType()
public function getFormType(): ?stringFieldDescriptor::setFormType()
public function setFormType(?string $formTypeFqcn): staticFieldDescriptor::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::setFormType()
public function setFormType(string $formTypeFqcn): staticFieldTrait::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/marki" 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:10
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:9
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:9
GenderField::new()
public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): selfIconField class
class IconField extends SelectField implements FieldInterface IconField.php:10
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:8
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:10
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:8
IntegerField::new()
public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): selfLocaleField class
class LocaleField implements FieldInterface LocaleField.php:11
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:9
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:7
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:8
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:9
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:9
RoleField::new()
public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): selfRouteField class
class RouteField extends SelectField implements FieldInterface RouteField.php:9
RouteField::new()
public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): selfSelectField class
class SelectField implements FieldInterface SelectField.php:9
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:8
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:10
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:7
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:9
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:8
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:10
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:9
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:8
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:11
YearField::new()
public static function new(string $propertyName, TranslatableInterface|string|bool|null $label = null): selfBase\Field\Option
TextAlign class
final class TextAlign TextAlign.php:5
const LEFT = 'left'const CENTER = 'center'const RIGHT = 'right'
Base\Field\Type
ArrayType class
class ArrayType extends CollectionType ArrayType.php:22
ArrayType::__construct()
public function __construct(Environment $twig, TranslatorInterface $translator, AuthorizationChecker $authorizationChecker, AdminUrlGeneratorInterface $adminUrlGenerator, ?\Symfony\Component\HttpFoundation\RequestStack $requestStack = null, ?ClassMetadataManipulator $classMetadataManipulator = null)The service definition inherits CollectionType's args (->parent(...))
and APPENDS its own - so this signature must mirror the parent's
positionally. When the parent gained a RequestStack, this ctor received
it as its 5th argument where it expected the manipulator, and every
form using ArrayType 500'd (caught by the groups/new render test).
ArrayType::getBlockPrefix()
public function getBlockPrefix(): stringArrayType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidArrayType::buildFormArray()
public function buildFormArray(FormBuilderInterface $builder, array $options)ArrayType::buildFormAssociativeArray()
public function buildFormAssociativeArray(FormBuilderInterface $builder, array $options)ArrayType::buildForm()
public function buildForm(FormBuilderInterface $builder, array $options): void{@inheritdoc}
ArrayType::getNumberOfArguments()
public function getNumberOfArguments($pattern): intArrayType::finishView()
public function finishView(FormView $view, FormInterface $form, array $options): voidAssociationFileType class
class AssociationFileType extends AbstractType implements DataMapperInterface AssociationFileType.php:36
AssociationFileType::getBlockPrefix()
public function getBlockPrefix(): stringAssociationFileType::__construct()
public function __construct(FormFactory $formFactory, ClassMetadataManipulator $classMetadataManipulator, EntityHydrator $entityHydrator, MediaService $mediaService, AdminUrlGeneratorInterface $adminUrlGenerator)AssociationFileType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidAssociationFileType::finishView()
public function finishView(FormView $view, FormInterface $form, array $options): voidAssociationFileType::buildForm()
public function buildForm(FormBuilderInterface $builder, array $options): voidAssociationFileType::mapDataToForms()
public function mapDataToForms($viewData, Traversable $forms): voidAssociationFileType::mapFormsToData()
public function mapFormsToData(Traversable $forms, &$viewData): void- Throws
MappingException
AssociationType class
class AssociationType extends AbstractType implements DataMapperInterface AssociationType.php:38
AssociationType::getBlockPrefix()
public function getBlockPrefix(): stringAssociationType::__construct()
public function __construct(FormFactory $formFactory, ClassMetadataManipulator $classMetadataManipulator, EntityHydrator $entityHydrator, TranslatorInterface $translator)AssociationType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidAssociationType::finishView()
public function finishView(FormView $view, FormInterface $form, array $options): voidAssociationType::buildForm()
public function buildForm(FormBuilderInterface $builder, array $options): voidAssociationType::mapDataToForms()
public function mapDataToForms($viewData, Traversable $forms): void- Throws
Exception
AssociationType::mapFormsToData()
public function mapFormsToData(Traversable $forms, &$viewData): void- Throws
MappingException
AttributeType class
class AttributeType extends AbstractType implements DataMapperInterface AttributeType.php:45
AttributeType::getBlockPrefix()
public function getBlockPrefix(): stringAttributeType::__construct()
public function __construct(FormFactory $formFactory, ClassMetadataManipulator $classMetadataManipulator, Environment $twig)AttributeType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidAttributeType::finishView()
public function finishView(FormView $view, FormInterface $form, array $options): voidAttributeType::buildForm()
public function buildForm(FormBuilderInterface $builder, array $options): voidAttributeType::mapDataToForms()
public function mapDataToForms($viewData, Traversable $forms): voidAttributeType::mapFormsToData()
public function mapFormsToData(Traversable $forms, &$viewData): void- Throws
MappingException
AudioType class
class AudioType extends FileType AudioType.php:10
AudioType::getBlockPrefix()
public function getBlockPrefix(): stringAudioType::getParent()
public function getParent(): ?stringAudioType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidAudioType::buildView()
public function buildView(FormView $view, FormInterface $form, array $options): voidAvatarType class
class AvatarType extends ImageType AvatarType.php:12
AvatarType::getBlockPrefix()
public function getBlockPrefix(): stringAvatarType::getParent()
public function getParent(): ?stringAvatarType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidAvatarType::buildForm()
public function buildForm(FormBuilderInterface $builder, array $options): voidAvatarType::buildView()
public function buildView(FormView $view, FormInterface $form, array $options): voidBooleanType class
class BooleanType extends AbstractType BooleanType.php:12
BooleanType::__construct()
public function __construct(Environment $twig)BooleanType::getBlockPrefix()
public function getBlockPrefix(): stringBooleanType::getParent()
public function getParent(): ?stringBooleanType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidBooleanType::buildView()
public function buildView(FormView $view, FormInterface $form, array $options): voidButtonType class
class ButtonType extends BaseType implements SubmitButtonTypeInterface ButtonType.php:11
ButtonType::getParent()
public function getParent(): ?stringButtonType::getBlockPrefix()
public function getBlockPrefix(): stringButtonType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidButtonType::buildView()
public function buildView(FormView $view, FormInterface $form, array $options): voidCodeType class
final class CodeType extends AbstractType CodeType.php:22
A code of known length - a one-time code, a voucher, a PIN - typed one character per box. The boxes are presentation only: they feed a single hidden input that carries the field's real value, so the type is a plain TextType to the form (validation, data transformers, everything) and degrades to that hidden value when the script is not there.
Options: length (6), alphabet ('alnum' | 'digits' | 'alpha'), uppercase (true), submit_on_complete (false: submit the form once every box is filled - what a login code page wants).
CodeType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidCodeType::buildView()
public function buildView(FormView $view, FormInterface $form, array $options): voidCodeType::getParent()
public function getParent(): ?stringCodeType::getBlockPrefix()
public function getBlockPrefix(): stringCollectionType class
class CollectionType extends AbstractType CollectionType.php:23
CollectionType::__construct()
public function __construct(Environment $twig, TranslatorInterface $translator, AuthorizationChecker $authorizationChecker, AdminUrlGeneratorInterface $adminUrlGenerator, readonly ?\Symfony\Component\HttpFoundation\RequestStack $requestStack = null)CollectionType::getBlockPrefix()
public function getBlockPrefix(): stringCollectionType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidCollectionType::buildForm()
public function buildForm(FormBuilderInterface $builder, array $options): void{@inheritdoc}
CollectionType::buildView()
public function buildView(FormView $view, FormInterface $form, array $options): void{@inheritdoc}
CollectionType::finishView()
public function finishView(FormView $view, FormInterface $form, array $options): void{@inheritdoc}
ColorPickerType class
final class ColorPickerType extends AbstractType ColorPickerType.php:16
const THEME_CLASSIC = 'classic'const THEME_MONOLITH = 'monolith'const THEME_NANO = 'nano'const POSITION_TOP = 'top'const POSITION_LEFT = 'left'const POSITION_BOTTOM = 'bottom'const POSITION_RIGHT = 'right'const POSITION_START = 'start'const POSITION_MIDDLE = 'middle'const POSITION_END = 'end'const COLOR_BLUE = '#0074d9'const COLOR_AQUA = '#7fdbff'const COLOR_TEAL = '#39cccc'const COLOR_OLIVE = '#3d9970'const COLOR_GREEN = '#2ecc40'const COLOR_LIME = '#01ff70'const COLOR_YELLOW = '#ffdc00'const COLOR_ORANGE = '#ff851b'const COLOR_RED = '#ff4136'const COLOR_MAROON = '#85144B'const COLOR_FUCHSIA = '#f012be'const COLOR_PURPLE = '#b10dc9'const COLOR_BLACK = '#111111'const COLOR_GRAY = '#AAAAAA'
ColorPickerType::__construct()
public function __construct(TranslatorInterface $translator)ColorPickerType::getParent()
public function getParent(): ?stringColorPickerType::getBlockPrefix()
public function getBlockPrefix(): stringColorPickerType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidColorPickerType::buildForm()
public function buildForm(FormBuilderInterface $builder, array $options): voidColorPickerType::finishView()
public function finishView(FormView $view, FormInterface $form, array $options): voidColorType class
final class ColorType extends AbstractType ColorType.php:20
ColorType::__construct()
public function __construct(Environment $twig, ParameterBagInterface $parameterBag)ColorType::getBlockPrefix()
public function getBlockPrefix(): stringColorType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidColorType::getParent()
public function getParent(): ?stringColorType::buildForm()
public function buildForm(FormBuilderInterface $builder, array $options): voidColorType::buildView()
public function buildView(FormView $view, FormInterface $form, array $options): voidCountryType class
class CountryType extends SelectType implements SelectInterface CountryType.php:12
CountryType::addCountry()
public static function addCountry($code, $country)CountryType::addCountries()
public static function addCountries($array)CountryType::getName()
public static function getName(string $code)CountryType::getNamesWithoutAddons()
public static function getNamesWithoutAddons()CountryType::getNames()
public static function getNames($addons = false)CountryType::getChoices()
public static function getChoices(): arrayCountryType::getIcon()
public static function getIcon(string $id, int $index = -1): ?stringCountryType::getText()
public static function getText(string $id): ?stringCountryType::getHtml()
public static function getHtml(string $id): ?stringCountryType::getData()
public static function getData(string $id): ?arrayCountryType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidCropperType class
class CropperType extends AbstractType implements DataMapperInterface CropperType.php:25
CropperType::getBlockPrefix()
public function getBlockPrefix(): stringCropperType::__construct()
public function __construct(FormFactory $formFactory, EntityManagerInterface $entityManager, ParameterBagInterface $parameterBag, Environment $twig)CropperType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidCropperType::buildForm()
public function buildForm(FormBuilderInterface $builder, array $options): voidCropperType::buildView()
public function buildView(FormView $view, FormInterface $form, array $options): voidCropperType::finishView()
public function finishView(FormView $view, FormInterface $form, array $options): voidCropperType::mapDataToForms()
public function mapDataToForms($viewData, Traversable $forms): voidCropperType::mapFormsToData()
public function mapFormsToData(Traversable $forms, &$viewData): voidCurrencyType class
class CurrencyType extends AbstractType CurrencyType.php:14
const DISPLAY_SYMBOL = "symbol"const DISPLAY_CODE = "code"
CurrencyType::getParent()
public function getParent(): ?stringCurrencyType::getBlockPrefix()
public function getBlockPrefix(): stringCurrencyType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidDateTimePickerType class
class DateTimePickerType extends AbstractType DateTimePickerType.php:17
DateTimePickerType::__construct()
public function __construct(ParameterBagInterface $parameterBag, Environment $twig, LocalizerInterface $localizer)DateTimePickerType::getParent()
public function getParent(): ?stringDateTimePickerType::getBlockPrefix()
public function getBlockPrefix(): stringDateTimePickerType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidDateTimePickerType::buildView()
public function buildView(FormView $view, FormInterface $form, array $options): voidDiscriminatorType class
class DiscriminatorType extends AbstractType DiscriminatorType.php:21
DiscriminatorType::__construct()
public function __construct(FormFactory $formFactory, ClassMetadataManipulator $classMetadataManipulator)DiscriminatorType::getBlockPrefix()
public function getBlockPrefix(): stringDiscriminatorType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidDiscriminatorType::buildForm()
public function buildForm(FormBuilderInterface $builder, array $options): voidDiscriminatorType::getFormattedValues()
public static function getFormattedValues($entry, $class = null, ?TranslatorInterface $translator = null, $format = FORMAT_TITLECASE)DiscriminatorType::buildView()
public function buildView(FormView $view, FormInterface $form, array $options): voidEditorType class
class EditorType extends AbstractType EditorType.php:26
EditorType::__construct()
public function __construct(ParameterBagInterface $parameterBag, TranslatorInterface $translator, Environment $twig, AdvancedRouterInterface $router, CsrfTokenManagerInterface $csrfTokenManager, ObfuscatorInterface $obfuscator, MediaEnhancerInterface $mediaEnhancer, CollabRoomResolver $roomResolver, TokenStorageInterface $tokenStorage, ?CollabTicketFactory $ticketFactory = null)EditorType::getParent()
public function getParent(): ?stringEditorType::getBlockPrefix()
public function getBlockPrefix(): stringEditorType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidEditorType::getFormID()
public function getFormID($view): ?stringEditorType::buildForm()
public function buildForm(FormBuilderInterface $builder, array $options): voidEditorType::buildView()
public function buildView(FormView $view, FormInterface $form, array $options): voidEmojiPickerType class
final class EmojiPickerType extends AbstractType EmojiPickerType.php:13
EmojiPickerType::getBlockPrefix()
public function getBlockPrefix(): stringEmojiPickerType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidEmojiPickerType::getParent()
public function getParent(): ?stringEmojiPickerType::buildForm()
public function buildForm(FormBuilderInterface $builder, array $options): voidEmojiPickerType::buildView()
public function buildView(FormView $view, FormInterface $form, array $options): voidFileType class
class FileType extends AbstractType implements DataMapperInterface FileType.php:36
FileType::__construct()
public function __construct(ParameterBagInterface $parameterBag, TranslatorInterface $translator, Environment $twig, ClassMetadataManipulator $classMetadataManipulator, CsrfTokenManagerInterface $csrfTokenManager, FormFactory $formFactory, AdvancedRouterInterface $router, MediaService $mediaService, ObfuscatorInterface $obfuscator, string $cacheDir)FileType::getBlockPrefix()
public function getBlockPrefix(): string{@inheritdoc}
FileType::configureOptions()
public function configureOptions(OptionsResolver $resolver): void{@inheritdoc}
FileType::buildForm()
public function buildForm(FormBuilderInterface $builder, array $options): voidFileType::buildView()
public function buildView(FormView $view, FormInterface $form, array $options): voidFileType::mapDataToForms()
public function mapDataToForms($viewData, Traversable $forms): voidFileType::mapFormsToData()
public function mapFormsToData(Traversable $forms, &$viewData): voidForexType class
class ForexType extends SelectType implements SelectInterface ForexType.php:11
ForexType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidForexType::getIcon()
public static function getIcon(string $id, int $index = -1): ?stringForexType::getText()
public static function getText(string $id): ?stringForexType::getHtml()
public static function getHtml(string $id): ?stringForexType::getData()
public static function getData(string $id): ?arrayGenderType class
class GenderType extends AbstractType GenderType.php:9
GenderType::getParent()
public function getParent(): ?stringGenderType::getBlockPrefix()
public function getBlockPrefix(): stringGenderType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidIconType class
class IconType extends SelectType implements SelectInterface IconType.php:12
public static mixed $iconProvider = null
IconType::__construct()
public function __construct(...$args)IconType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidIconType::getIcon()
public static function getIcon(string $id, int $index = -1): ?stringIconType::getText()
public static function getText(string $id): ?stringIconType::getHtml()
public static function getHtml(string $id): ?stringIconType::getData()
public static function getData(string $id): ?arrayImageType class
class ImageType extends FileType ImageType.php:12
ImageType::getBlockPrefix()
public function getBlockPrefix(): stringImageType::getParent()
public function getParent(): ?stringImageType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidImageType::buildForm()
public function buildForm(FormBuilderInterface $builder, array $options): voidImageType::buildView()
public function buildView(FormView $view, FormInterface $form, array $options): voidMoneyType class
class MoneyType extends MoneyType MoneyType.php:16
const CODE_ONLY = 0const LABEL_ONLY = 1const LABELCODE_ONLY = 2
MoneyType::__construct()
public function __construct(TradingInterface $tradingMarket)MoneyType::configureOptions()
public function configureOptions(OptionsResolver $resolver): void{@inheritdoc}
MoneyType::finishView()
public function finishView(FormView $view, FormInterface $form, array $options): voidMoneyType::buildForm()
public function buildForm(FormBuilderInterface $builder, array $options): voidNumberType class
class NumberType extends NumberType NumberType.php:14
NumberType::__construct()
public function __construct(Environment $twig)NumberType::getBlockPrefix()
public function getBlockPrefix(): stringNumberType::buildForm()
public function buildForm(FormBuilderInterface $builder, array $options): voidNumberType::buildView()
public function buildView(FormView $view, FormInterface $form, array $options): voidNumberType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidPasswordType class
class PasswordType extends AbstractType implements AutovalidateInterface, DataMapperInterface PasswordType.php:21
PasswordType::__construct()
public function __construct(TranslatorInterface $translator, Environment $twig)PasswordType::getBlockPrefix()
public function getBlockPrefix(): stringPasswordType::buildView()
public function buildView(FormView $view, FormInterface $form, array $options): voidPasswordType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidPasswordType::buildForm()
public function buildForm(FormBuilderInterface $builder, array $options): voidPasswordType::mapDataToForms()
public function mapDataToForms($viewData, Traversable $forms): voidPasswordType::mapFormsToData()
public function mapFormsToData(Traversable $forms, &$viewData): voidQuadrantType class
class QuadrantType extends AbstractType implements DataMapperInterface QuadrantType.php:18
QuadrantType::getBlockPrefix()
public function getBlockPrefix(): stringQuadrantType::__construct()
public function __construct(Environment $twig)QuadrantType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidQuadrantType::buildForm()
public function buildForm(FormBuilderInterface $builder, array $options): voidQuadrantType::buildView()
public function buildView(FormView $view, FormInterface $form, array $options): voidQuadrantType::mapDataToForms()
public function mapDataToForms($viewData, Traversable $forms): voidQuadrantType::mapFormsToData()
public function mapFormsToData(Traversable $forms, &$viewData): voidRoleType class
class RoleType extends AbstractType RoleType.php:10
RoleType::getParent()
public function getParent(): ?stringRoleType::getBlockPrefix()
public function getBlockPrefix(): stringRoleType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidRouteType class
class RouteType extends AbstractType RouteType.php:14
RouteType::getParent()
public function getParent(): ?stringRouteType::getBlockPrefix()
public function getBlockPrefix(): stringRouteType::__construct()
public function __construct(AdvancedRouterInterface $router, LocalizerInterface $localizer)RouteType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidSelectType class
class SelectType extends AbstractType implements DataMapperInterface SelectType.php:55
const REQUIRED_MESSAGE = 'This value should not be blank.'What a required select sent empty answers (Symfony's NotBlank message,
validatorsdomain).
SelectType::__construct()
public function __construct(FormFactory $formFactory, Repositories $repositories, TranslatorInterface $translator, ClassMetadataManipulator $classMetadataManipulator, CsrfTokenManagerInterface $csrfTokenManager, Localizer $localizer, AdminUrlGeneratorInterface $adminUrlGenerator, Environment $twig, AuthorizationChecker $authorizationChecker, ObfuscatorInterface $obfuscator, ParameterBagInterface $parameterBag, RouterInterface $router, ?MediaServiceInterface $mediaService = null)SelectType::getBlockPrefix()
public function getBlockPrefix(): stringSelectType::getIcons()
public static function getIcons(): arraySelectType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidSelectType::buildForm()
public function buildForm(FormBuilderInterface $builder, array $options): voidSelectType::mapDataToForms()
public function mapDataToForms($viewData, Traversable $forms): voidSelectType::mapFormsToData()
public function mapFormsToData(Traversable $forms, &$viewData): void- Throws
MappingException
SelectType::buildView()
public function buildView(FormView $view, FormInterface $form, array $options): voidSelectType::finishView()
public function finishView(FormView $view, FormInterface $form, array $options): voidThe <select> the server prints holds its options and its selection.
The inner choice was drawn empty and filled by select2 alone from data-select2-options: on a page whose script did not run (blocked, failed, not loaded yet) there was nothing to choose, a product's availability arrived null, and a list that did print its options - a choice_loader's, the currencies - printed none of them selected, so the browser sent the first one (AFA) in place of the record's value.
- The entries select2 receives - the choices of a static list, of an enum; the records already chosen of an autocompleted one - are printed as <option>s, groups as <optgroup>s, with the labels select2 shows. select2 empties the select before filling it from its data, as it always did: nothing is listed twice.
- The value of the record is the selected option, for those and for the options a choice_loader gave.
- A select of one value starts with an empty option carrying the placeholder: without it the browser - and select2, which asks for this very option - picks the first choice when the record has none.
SlugType class
final class SlugType extends AbstractType implements AutovalidateInterface SlugType.php:17
SlugType::__construct()
public function __construct(Environment $twig, ClassMetadataManipulator $classMetadataManipulator)SlugType::getParent()
public function getParent(): ?stringSlugType::getBlockPrefix()
public function getBlockPrefix(): stringSlugType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidSlugType::finishView()
public function finishView(FormView $view, FormInterface $form, array $options): voidStateType class
class StateType extends AbstractType StateType.php:9
StateType::getParent()
public function getParent(): ?stringStateType::getBlockPrefix()
public function getBlockPrefix(): stringStateType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidStockType class
class StockType extends NumberType StockType.php:12
StockType::getBlockPrefix()
public function getBlockPrefix(): string{@inheritdoc}
StockType::buildView()
public function buildView(FormView $view, FormInterface $form, array $options): voidStockType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidStockType::finishView()
public function finishView(FormView $view, FormInterface $form, array $options): voidSubmitType class
class SubmitType extends AbstractType implements SubmitButtonTypeInterface SubmitType.php:9
SubmitType::getBlockPrefix()
public function getBlockPrefix(): stringSubmitType::getParent()
public function getParent(): ?stringSubmitType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidTranslatableType class
class TranslatableType extends AbstractType TranslatableType.php:10
TranslatableType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidTranslatableType::buildForm()
public function buildForm(FormBuilderInterface $builder, array $options): voidTranslationType class
class TranslationType extends AbstractType implements DataMapperInterface TranslationType.php:32
TranslationType::__construct()
public function __construct(ClassMetadataManipulator $classMetadataManipulator, LocalizerInterface $localizer, Environment $twig)TranslationType::getBlockPrefix()
public function getBlockPrefix(): stringTranslationType::getDefaultLocale()
public function getDefaultLocale()TranslationType::configureOptions()
public function configureOptions(OptionsResolver $resolver): void{@inheritdoc}
TranslationType::buildForm()
public function buildForm(FormBuilderInterface $builder, array $options): voidTranslationType::buildView()
public function buildView(FormView $view, FormInterface $form, array $options): voidTranslationType::getTranslationFields()
public function getTranslationFields(string $translationClass, array $options): arrayTranslationType::mapDataToForms()
public function mapDataToForms($viewData, Traversable $forms): voidTranslationType::mapFormsToData()
public function mapFormsToData(Traversable $forms, &$viewData): voidVideoType class
class VideoType extends FileType VideoType.php:10
VideoType::getBlockPrefix()
public function getBlockPrefix(): stringVideoType::getParent()
public function getParent(): ?stringVideoType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidVideoType::buildView()
public function buildView(FormView $view, FormInterface $form, array $options): voidWysiwygType class
class WysiwygType extends AbstractType WysiwygType.php:15
WysiwygType::__construct()
public function __construct(ParameterBagInterface $parameterBag, TranslatorInterface $translator, Environment $twig)WysiwygType::getParent()
public function getParent(): ?stringWysiwygType::getBlockPrefix()
public function getBlockPrefix(): stringWysiwygType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidWysiwygType::getFormID()
public function getFormID($view): ?stringWysiwygType::buildView()
public function buildView(FormView $view, FormInterface $form, array $options): voidBase\Form
FormFactory class
class FormFactory extends SymfonyFormFactory implements FormFactoryInterface FormFactory.php:23
FormFactory::__construct()
public function __construct(FormRegistryInterface $registry, ValidatorInterface $validator, ClassMetadataManipulator $classMetadataManipulator, EntityHydratorInterface $entityHydrator)FormFactory::createBuilder()
public function createBuilder(string $type = FormType::class, mixed $data = null, array $options = []): FormBuilderInterfaceFormFactory::create()
public function create(string $type = FormType::class, mixed $data = null, array $options = [], array $listeners = []): FormInterfaceFormFactoryInterface interface
interface FormFactoryInterface extends SymfonyFormFactoryInterface, FormGuessInterface FormFactoryInterface.php:8
FormProcessor class
class FormProcessor implements FormProcessorInterface FormProcessor.php:18
public array $flowSessions = []public array $flowCallbacks = []
FormProcessor::__construct()
public function __construct(FormInterface $form)FormProcessor::getForm()
public function getForm(): FormInterfaceFormProcessor::getFormType()
public function getFormType(): stringFormProcessor::getOption()
public function getOption(string $name): mixedFormProcessor::getOptions()
public function getOptions(): arrayFormProcessor::getData()
public function getData(?string $childName = null): mixedFormProcessor::setData()
public function setData(mixed $data): selfFormProcessor::hydrate()
public function hydrate(mixed $data): mixedFormProcessor::onDefault()
public function onDefault(callable $callback): staticFormProcessor::onInvalid()
public function onInvalid(callable $callback): staticFormProcessor::onSubmit()
public function onSubmit(callable ...$callbacks): staticFormProcessor::hasResponse()
public function hasResponse(): boolFormProcessor::getResponse()
public function getResponse(): ResponseFormProcessor::getDto()
public function getDto(): ?FormModelInterfaceFormProcessor::getEntity()
public function getEntity()FormProcessor::handleRequest()
public function handleRequest(Request $request): staticFormProcessor::reset()
public function reset()FormProcessor::getToken()
public function getToken()FormProcessor::addStep()
public function addStep(callable $callback)FormProcessor::addConfirmStep()
public function addConfirmStep()FormProcessor::getPreviousStep()
public function getPreviousStep()FormProcessor::getStepMax()
public function getStepMax()FormProcessor::getNextStep()
public function getNextStep()FormProcessor::setStep()
public function setStep($step)FormProcessor::getStep()
public function getStep()FormProcessorInterface interface
interface FormProcessorInterface FormProcessorInterface.php:9
FormProcessorInterface::handleRequest()
public function handleRequest(Request $request): staticFormProcessorInterface::hydrate()
public function hydrate(mixed $data): mixedFormProcessorInterface::getForm()
public function getForm(): FormInterfaceFormProcessorInterface::getData()
public function getData(): mixedFormProcessorInterface::setData()
public function setData(mixed $data): selfFormProcessorInterface::getOption()
public function getOption(string $name): mixedFormProcessorInterface::getOptions()
public function getOptions(): arrayFormProcessorInterface::getFormType()
public function getFormType(): stringFormProcessorInterface::onDefault()
public function onDefault(callable $callback): staticFormProcessorInterface::onInvalid()
public function onInvalid(callable $callback): staticFormProcessorInterface::onSubmit()
public function onSubmit(callable ...$callbacks): staticFormProcessorInterface::getResponse()
public function getResponse(): ResponseFormProxy class
class FormProxy implements FormProxyInterface, ResetInterface FormProxy.php:16
The forms of a request, by name. Reset between two requests (kernel.reset): a kernel that serves several - a test client's, a worker's - kept the sign-in form under "form:login", and the sign-up page, which asks for a processor of that name, rendered the sign-in form.
FormProxy::__construct()
public function __construct(FormFactoryInterface $formFactory)FormProxy::all()
public function all()FormProxy::empty()
public function empty(): boolFormProxy::has()
public function has(string $name): boolFormProxy::getData()
public function getData(string $name, ?string $childName = null): mixedFormProxy::setData()
public function setData(string $name, mixed $data): selfFormProxy::get()
public function get(string $name): ?FormInterfaceFormProxy::add()
public function add(string $name, ?FormInterface $form): selfFormProxy::remove()
public function remove(string $name): selfFormProxy::create()
public function create(string $name, string $type = FormType::class, mixed $data = null, array $options = [], array $listeners = []): FormInterfaceFormProxy::submit()
public function submit(string $name, string|array|null $submittedData, bool $clearMissing = true): ?FormInterfaceFormProxy::getProcessor()
public function getProcessor(string $name): ?FormProcessorInterfaceFormProxy::createProcessor()
public function createProcessor(string $name, string $formTypeClass = FormType::class, array $options = [], array $listeners = []): ?FormProcessorInterfaceFormProxy::reset()
public function reset(): voidFormProxyInterface interface
interface FormProxyInterface FormProxyInterface.php:8
FormProxyInterface::all()
public function all()FormProxyInterface::add()
public function add(string $name, ?FormInterface $form): selfFormProxyInterface::remove()
public function remove(string $name): selfFormProxyInterface::has()
public function has(string $name): boolFormProxyInterface::get()
public function get(string $name): ?FormInterfaceFormProxyInterface::getProcessor()
public function getProcessor(string $name): ?FormProcessorInterfaceFormProxyInterface::setData()
public function setData(string $name, mixed $data): selfFormProxyInterface::getData()
public function getData(string $name, ?string $childName): mixedFormProxyInterface::create()
public function create(string $name, string $type = FormType::class, mixed $data = null, array $options = []): ?FormInterfaceFormProxyInterface::createProcessor()
public function createProcessor(string $name, string $formTypeClass = FormType::class, array $options = []): ?FormProcessorInterfaceFormProxyInterface::submit()
public function submit(string $name, string|array|null $submittedData, bool $clearMissing = true): ?FormInterfaceBase\Form\Common
AbstractModel class
class AbstractModel implements FormModelInterface AbstractModel.php:5
AbstractModel::getTypeClass()
public static function getTypeClass(): stringAbstractType class
abstract class AbstractType extends AbstractType implements FormTypeInterface AbstractType.php:5
AbstractType::getModelClass()
public static function getModelClass(): stringFormModelInterface interface
interface FormModelInterface FormModelInterface.php:5
FormModelInterface::getTypeClass()
public static function getTypeClass(): stringFormTypeInterface interface
interface FormTypeInterface extends SymfonyFormTypeInterface FormTypeInterface.php:7
FormTypeInterface::getModelClass()
public static function getModelClass(): 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\Extension
FormTypeBootstrapExtension class
class FormTypeBootstrapExtension extends AbstractTypeExtension FormTypeBootstrapExtension.php:14
FormTypeBootstrapExtension::__construct()
public function __construct(ParameterBagInterface $parameterBag)FormTypeBootstrapExtension::getExtendedTypes()
public static function getExtendedTypes(): iterableFormTypeBootstrapExtension::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidFormTypeBootstrapExtension::finishView()
public function finishView(FormView $view, FormInterface $form, array $options): voidFormTypeBootstrapExtension::browseView()
public function browseView(FormView $view, FormInterface $form, array $options)FormTypeBootstrapExtension::applyBootstrap()
public function applyBootstrap(FormView $view, FormInterface $form, array $options)FormTypeBootstrapExtension::addAttribute()
public static function addAttribute(FormView $view, $name, $value)FormTypeBootstrapExtension::addRowAttribute()
public static function addRowAttribute(FormView $view, $name, $value)FormTypeBootstrapExtension::addLabelAttribute()
public static function addLabelAttribute(FormView $view, $name, $value)FormTypeCollabExtension class
class FormTypeCollabExtension extends AbstractTypeExtension FormTypeCollabExtension.php:38
This class activates real-time presence and autosave for any regular
field: an input field, a select field, a select2 field, or another
field type. This class is not specific to EditorType. This class adds
a new collab form option, with three possible values: false (the
default value), "autosave", or "live".
This class writes plain data-collab-* attributes. This class does not change form_div_layout.html.twig. Twig's own widget_attributes rendering already outputs the content of $view->vars["attr"], set by finishView(). Because of this, every field type receives these attributes automatically, including a field that uses select2_widget's own attribute merge.
The file form-type-collab-presence.js, inside assets/styles/js/forms/, is the client-side code for this feature. This file reuses the ux_editorjs_collabTicket action and the ux_editorjs_autosave action. EditorType uses these same two generic actions. This design follows the "one controller" decision in the collaboration plan.
FormTypeCollabExtension::__construct()
public function __construct(CollabRoomResolver $roomResolver, TokenStorageInterface $tokenStorage, CsrfTokenManagerInterface $csrfTokenManager, AdvancedRouterInterface $router, ?CollabTicketFactory $ticketFactory = null)FormTypeCollabExtension::getExtendedTypes()
public static function getExtendedTypes(): iterableFormTypeCollabExtension::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidFormTypeCollabExtension::finishView()
public function finishView(FormView $view, FormInterface $form, array $options): voidFormTypeCollectionExtension class
class FormTypeCollectionExtension extends AbstractTypeExtension FormTypeCollectionExtension.php:14
FormTypeCollectionExtension::__construct()
public function __construct(ClassMetadataManipulator $classMetadataManipulator)FormTypeCollectionExtension::getExtendedTypes()
public static function getExtendedTypes(): iterable{@inheritdoc}
FormTypeCollectionExtension::finishView()
public function finishView(FormView $view, FormInterface $form, array $options): voidFormTypeCollectionExtension::browseView()
public function browseView(FormView $view, FormInterface $form, array $options)FormTypeCsrfExtension class
class FormTypeCsrfExtension extends AbstractTypeExtension FormTypeCsrfExtension.php:10
FormTypeCsrfExtension::__construct()
public function __construct(bool $defaultEnabled = false)FormTypeCsrfExtension::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidFormTypeCsrfExtension::getExtendedTypes()
public static function getExtendedTypes(): iterable{@inheritdoc}
FormTypeExtension class
class FormTypeExtension extends AbstractTypeExtension FormTypeExtension.php:24
FormTypeExtension::__construct()
public function __construct(AdvancedRouterInterface $router, AuthorizationCheckerInterface $authorizationChecker, ParameterBagInterface $parameterBag, FormFactory $formFactory, FormProxyInterface $formProxy, ClassMetadataManipulator $classMetadataManipulator, VersionManager $versionManager, $translator = null)FormTypeExtension::getExtendedTypes()
public static function getExtendedTypes(): iterable{@inheritdoc}
FormTypeExtension::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidFormTypeExtension::finishView()
public function finishView(FormView $view, FormInterface $form, array $options): voidFormTypeExtension::browseView()
public function browseView(FormView $view, FormInterface $form, array $options)FormTypeExtension::applyForm2()
public function applyForm2(FormView $view)FormTypeExtension::applyEA()
public function applyEA(FormView $view, FormInterface $form)FormTypeExtension::markAsDbColumns()
public function markAsDbColumns(FormView $view, FormInterface $form, array $options)FormTypeExtension::markDbProperties()
public function markDbProperties(FormView $view, FormInterface $form, array $options)FormTypeExtension::markVersionable()
public function markVersionable(FormView $view, FormInterface $form)Hand each versioned field its own history, so form_div_layout can put a badge next to the label of the fields that actually have one.
Runs per form node rather than once at the root: an article's translated fields live on a ThreadIntl sub-form, one per locale, and each of those has to be matched against the locale-prefixed keys of the parent's revisions. VersionManager handles both the anchoring and the memoisation that keeps this from being one query per locale tab.
FormTypeExtension::markOptions()
public function markOptions(FormView $view, FormInterface $form, array $options)FormTypeExtension::buildForm()
public function buildForm(FormBuilderInterface $builder, array $options): voidFormTypeGuardExtension class
class FormTypeGuardExtension extends AbstractTypeExtension FormTypeGuardExtension.php:49
The option guard of a root form: Base\Service\FormGuard's checks, in
their order (docs/20-architecture/guard.md).
$this->createForm(ContactType::class, $model, ['guard' => true]); $this->createForm(ContactType::class, $model, ['guard' => ['action' => 'contact', 'min_delay' => 5]]);
It adds a trap (guard_website), the stamp of the time the form was shown
(guard_opened) and - with glitchr/omnishield and a captcha configured - the
captcha (guard_captcha); after the submission it refuses a trap filled, a
form sent too fast, a sender the lists know. The captcha is checked by the
guard, on its field - shown and asked only once the visitor's tries of this
form were refused captcha_after times (base.guard.captcha_after, 3; 0:
always): a refusal of the guard or an invalid form counts one, a form sent
forgets them (FormGuard::failed(), succeeded()).
Where glitchr/ux-google already guards the form (its option captcha_protection: google.recaptcha.enable), no second captcha is added: the trap, the time, the lists and the classifier stay.
spam_protection - the classifier step, on by default as it always was
outside the back office: a form whose data implement
SpamProtectionInterface is scored (SpamChecker), its callback told, and
blatant spam refused. It runs once the form is otherwise valid: nothing is
sent to the classifier for a form already refused.
FormTypeGuardExtension::__construct()
public function __construct(protected readonly FormGuard $guard, protected readonly SpamCheckerInterface $spamChecker, protected readonly AdvancedRouterInterface $router, protected readonly ?TranslatorInterface $translator = null, protected readonly ?RequestStack $requests = null, protected readonly bool $spamByDefault = true)FormTypeGuardExtension::getExtendedTypes()
public static function getExtendedTypes(): iterableFormTypeGuardExtension::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidFormTypeGuardExtension::buildForm()
public function buildForm(FormBuilderInterface $builder, array $options): voidFormTypeGuardExtension::finishView()
public function finishView(\Symfony\Component\Form\FormView $view, \Symfony\Component\Form\FormInterface $form, array $options): voidThe captcha that waits for consent: its widget kept inert in a <template> until omnibase/consent says yes to the feature CAPTCHA (Consent.use()), the fallback shown meanwhile and after a refusal.
Without omnibase/consent's script on the page, the fallback alone.
FormTypeTranslateExtension class
class FormTypeTranslateExtension extends AbstractTypeExtension FormTypeTranslateExtension.php:10
FormTypeTranslateExtension::__construct()
public function __construct(bool $defaultEnabled = false)FormTypeTranslateExtension::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidFormTypeTranslateExtension::getExtendedTypes()
public static function getExtendedTypes(): iterable{@inheritdoc}
FormTypeWebpackExtension class
class FormTypeWebpackExtension extends AbstractTypeExtension FormTypeWebpackExtension.php:14
FormTypeWebpackExtension::__construct()
public function __construct(FormProxyInterface $formProxy, WebpackTagRenderer $webpackTagRenderer)FormTypeWebpackExtension::getExtendedTypes()
public static function getExtendedTypes(): iterable{@inheritdoc}
FormTypeWebpackExtension::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidFormTypeWebpackExtension::finishView()
public function finishView(FormView $view, FormInterface $form, array $options): voidFormTypeWebpackExtension::browseView()
public function browseView(FormView $view, FormInterface $form, array $options)Base\Form\Model
CommentModel class
class CommentModel implements SpamProtectionInterface CommentModel.php:18
What the comment form (Base\Form\Type\CommentType) edits - not the entity (omnibase's FormFactory refuses an entity as form data): the name, the e-mail, the site, the text. It implements SpamProtectionInterface so omnibase's FormTypeSpamExtension sends it to Akismet; the score lands here, and toComment() carries it onto the Comment to save.
public ?string $name = 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\Form\Traits
FormGuessInterface interface
interface FormGuessInterface FormGuessInterface.php:9
const GUESS_FROM_FORM = "GUESS_FROM_FORM"const GUESS_FROM_PHPDOC = "GUESS_FROM_PHPDOC"const GUESS_FROM_DATA = "GUESS_FROM_DATA"const GUESS_FROM_VIEW = "GUESS_FROM_VIEW"
FormGuessInterface::guessClass()
public function guessClass(FormInterface|FormEvent $form, ?array $options = null): ?stringFormGuessInterface::guessMultiple()
public function guessMultiple(FormInterface|FormEvent|FormBuilderInterface $form, ?array $options = null)FormGuessInterface::guessSortable()
public function guessSortable(FormInterface|FormEvent|FormBuilderInterface $form, ?array $options = null)FormGuessInterface::guessChoices()
public function guessChoices(FormInterface|FormBuilderInterface $form, ?array $options = null)FormGuessInterface::guessChoiceAutocomplete()
public function guessChoiceAutocomplete(FormInterface|FormBuilderInterface $form, ?array $options = null)FormGuessInterface::guessChoiceFilter()
public function guessChoiceFilter(FormInterface|FormBuilderInterface $form, ?array $options = null, $data = null)FormGuessTrait trait
trait FormGuessTrait FormGuessTrait.php:18
FormGuessTrait::guessClass()
public function guessClass(FormInterface|FormEvent $form, ?array $options = null): ?stringFormGuessTrait::guessEnumOfProperty()
public function guessEnumOfProperty(?string $class, string $property): ?stringThe PHP enum a class's property is typed with (private Status $status,
?Status), null for any other property.
FormGuessTrait::guessMultiple()
public function guessMultiple(FormInterface|FormEvent|FormBuilderInterface $form, ?array $options = null)- Throws
MappingException
FormGuessTrait::guessNullable()
public function guessNullable(FormInterface|FormEvent|FormBuilderInterface $form, ?array $options = null)- Throws
MappingException
FormGuessTrait::guessSortable()
public function guessSortable(FormInterface|FormEvent|FormBuilderInterface $form, ?array $options = null)- Throws
Exception
FormGuessTrait::guessOrderDirection()
public function guessOrderDirection(FormInterface|FormEvent|FormBuilderInterface $form, ?array $options = null)Guess the order direction (ASC/DESC) for a sortable field, using OrderColumn or OrderBy mapping.
- Throws
Exception
FormGuessTrait::guessChoices()
public function guessChoices(FormInterface|FormBuilderInterface $form, ?array $options = null)FormGuessTrait::guessChoiceAutocomplete()
public function guessChoiceAutocomplete(FormInterface|FormBuilderInterface $form, ?array $options = null)- Throws
MappingException
FormGuessTrait::guessChoiceFilter()
public function guessChoiceFilter(FormInterface|FormBuilderInterface $form, ?array $options = null, $data = null)FormProcessorTrait trait
trait FormProcessorTrait FormProcessorTrait.php:12
in favor of using Symfony Form Flows
FormProcessorTrait::killSession()
public function killSession(?SessionInterface $session = null)Base\Form\Transformer
ScaleNumberTransformer class
class ScaleNumberTransformer implements DataTransformerInterface ScaleNumberTransformer.php:26
Transforms between a number type and a localized number with grouping (each thousand) and comma separators.
ScaleNumberTransformer::__construct()
public function __construct(float $divisor)ScaleNumberTransformer::transform()
public function transform(mixed $value): float|int|nullTransforms a localized number into an integer or float.
$valueThe localized value
- Throws
TransformationFailedException if the given value is not a string or if the value cannot be transformed
ScaleNumberTransformer::reverseTransform()
public function reverseTransform(mixed $value): int|float|nullTransforms a localized money string into a normalized format.
$valueLocalized money string
- Throws
TransformationFailedException if the given value is not a string or if the value cannot be transformed
StrippedNumberToLocalizedStringTransformer class
class StrippedNumberToLocalizedStringTransformer extends NumberToLocalizedStringTransformer StrippedNumberToLocalizedStringTransformer.php:27
Transforms between a number type and a localized number with grouping (each thousand) and comma separators.
StrippedNumberToLocalizedStringTransformer::__construct()
public function __construct($prefix, $suffix, ...$args)StrippedNumberToLocalizedStringTransformer::reverseTransform()
public function reverseTransform(mixed $value): int|float|nullTransforms a localized number into an integer or float.
$valueThe localized value
- Throws
TransformationFailedException if the given value is not a string or if the value cannot be transformed
Base\Form\Type
CommentType class
class CommentType extends AbstractType CommentType.php:28
The comment form - small: a name, a message, an e-mail if one wants to be
answered - on Base\Form\Model\CommentModel, which omnibase's
FormTypeSpamExtension sends to Akismet. On top of it, for the robots that
never reach Akismet: a trap field (url, hidden from people, filled by
robots), the time the form was opened (opened), and - when
glitchr/ux-google is installed and recaptcha is on - Google reCAPTCHA
v3. Base\Service\CommentGuard reads the trap and the time.
Options: signed_in (no name nor e-mail asked), recaptcha, max_length, placeholders (name, email, content: translation keys), trap_class.
CommentType::buildForm()
public function buildForm(FormBuilderInterface $builder, array $options): voidCommentType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidContactType class
class ContactType extends AbstractType ContactType.php:40
The contact form, usable as it is by every site:
$form = $this->createForm(ContactType::class, $model = new ContactModel(), [ 'phone' => true, 'subject' => false, 'attachments' => false, 'buttons' => false, 'trap' => true, ]); if ($form->isSubmitted() && $form->isValid() && !$model->isRobot()) { ...send... }
Options: phone (off), subject (on), attachments (on), buttons - the
submit and reset buttons (on), trap - the website field robots fill,
off-screen for people (off). Labels: the "forms" domain's contact.fields.*,
or a label given to form_row().
The data-protection notice (Base\Form\Type\PrivacyType, a privacy
child, not mapped): privacy - true for omnibase's notice
(@forms.privacy.notice), a translation key for the site's own, false for
none (default); privacy_consent - the box to tick, the form invalid until
it is (off); privacy_parameters - the notice's parameters, a link to the
privacy page for instance:
['privacy' => '@messages.contact.privacy', 'privacy_parameters' => ['url' => $url], 'privacy_consent' => true]ContactType::getBlockPrefix()
public function getBlockPrefix(): stringContactType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidContactType::buildForm()
public function buildForm(FormBuilderInterface $builder, array $options): voidLayoutSettingListType class
class LayoutSettingListType extends AbstractType implements DataMapperInterface LayoutSettingListType.php:29
LayoutSettingListType::__construct()
public function __construct(SettingBag $settingBag, Localizer $localizer, ClassMetadataManipulator $classMetadataManipulator)LayoutSettingListType::getBlockPrefix()
public function getBlockPrefix(): stringLayoutSettingListType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidLayoutSettingListType::getFormattedData()
public function getFormattedData($data, $from = '.', $to = '-')- Throws
Exception
LayoutSettingListType::buildForm()
public function buildForm(FormBuilderInterface $builder, array $options): voidLayoutSettingListType::mapDataToForms()
public function mapDataToForms($viewData, \Traversable $forms): voidLayoutSettingListType::mapFormsToData()
public function mapFormsToData(\Traversable $forms, &$viewData): void- Throws
Exception
LayoutWidgetListType class
class LayoutWidgetListType extends AbstractType implements DataMapperInterface LayoutWidgetListType.php:21
LayoutWidgetListType::getBlockPrefix()
public function getBlockPrefix(): stringLayoutWidgetListType::__construct()
public function __construct(WidgetProviderInterface $widgetProvider)LayoutWidgetListType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidLayoutWidgetListType::getFormattedData()
public function getFormattedData($data, $from = ".", $to = "-")- Throws
Exception
LayoutWidgetListType::buildForm()
public function buildForm(FormBuilderInterface $builder, array $options): voidLayoutWidgetListType::mapDataToForms()
public function mapDataToForms($viewData, Traversable $forms): voidLayoutWidgetListType::mapFormsToData()
public function mapFormsToData(Traversable $forms, &$viewData): void- Throws
Exception
Login2FAType class
class Login2FAType extends AbstractType Login2FAType.php:15
The six-digit code that confirms a new authenticator app (/settings/2fa): nothing is mapped, the controller checks the code against the pending secret.
Login2FAType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidLogin2FAType::buildForm()
public function buildForm(FormBuilderInterface $builder, array $options): voidPrivacyType class
class PrivacyType extends AbstractType PrivacyType.php:31
The data-protection notice (GDPR) under a form that collects personal data, and if asked the box to tick before sending - one place for every site and bundle rather than a checkbox and a sentence each:
$builder->add('privacy', PrivacyType::class, [ 'notice' => '@forms.privacy.notice', // a translation key, or false: no notice 'notice_parameters' => ['url' => $privacyPageUrl], 'consent' => true, // the box, required (IsTrue) 'consent_label' => '@forms.privacy.consent', ]);
Not mapped: nothing is stored on the model. With consent, the form is
valid only once the box accept is ticked. The notice is a translation
(trusted text: rendered as HTML, so it may link to the privacy page).
ContactType adds it through its privacy options.
const NOTICE = '@forms.privacy.notice'const CONSENT = '@forms.privacy.consent'
PrivacyType::getBlockPrefix()
public function getBlockPrefix(): stringPrivacyType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidPrivacyType::buildForm()
public function buildForm(FormBuilderInterface $builder, array $options): voidPrivacyType::buildView()
public function buildView(FormView $view, FormInterface $form, array $options): voidSecurityLoginTokenType class
class SecurityLoginTokenType extends AbstractType SecurityLoginTokenType.php:16
SecurityLoginTokenType::getBlockPrefix()
public function getBlockPrefix(): stringSecurityLoginTokenType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidSecurityLoginTokenType::buildView()
public function buildView(FormView $view, FormInterface $form, array $options): voidSecurityLoginTokenType::buildForm()
public function buildForm(FormBuilderInterface $builder, array $options): voidSecurityLoginTwoFactorType class
class SecurityLoginTwoFactorType extends AbstractType SecurityLoginTwoFactorType.php:13
SecurityLoginTwoFactorType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidSecurityLoginTwoFactorType::buildForm()
public function buildForm(FormBuilderInterface $builder, array $options): voidSecurityLoginType class
class SecurityLoginType extends AbstractType SecurityLoginType.php:17
SecurityLoginType::getBlockPrefix()
public function getBlockPrefix(): stringSecurityLoginType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidSecurityLoginType::buildView()
public function buildView(FormView $view, FormInterface $form, array $options): voidSecurityLoginType::buildForm()
public function buildForm(FormBuilderInterface $builder, array $options): voidSecurityRegistrationType class
class SecurityRegistrationType extends AbstractType SecurityRegistrationType.php:17
SecurityRegistrationType::getBlockPrefix()
public function getBlockPrefix(): stringSecurityRegistrationType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidSecurityRegistrationType::buildForm()
public function buildForm(FormBuilderInterface $builder, array $options): voidSecurityResetPasswordConfirmType class
class SecurityResetPasswordConfirmType extends AbstractType SecurityResetPasswordConfirmType.php:11
SecurityResetPasswordConfirmType::buildForm()
public function buildForm(FormBuilderInterface $builder, array $options): voidSecurityResetPasswordType class
class SecurityResetPasswordType extends AbstractType SecurityResetPasswordType.php:12
SecurityResetPasswordType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidThe forms' guard (Base\Service\FormGuard): a trap, the time, the captcha - no list: the page answers the same for every address, and asks nothing of the address but where to write.
SecurityResetPasswordType::buildForm()
public function buildForm(FormBuilderInterface $builder, array $options): voidThreadSearchType class
class ThreadSearchType extends AbstractType ThreadSearchType.php:12
ThreadSearchType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidThreadSearchType::buildForm()
public function buildForm(FormBuilderInterface $builder, array $options): voidThreadSearchbarType class
class ThreadSearchbarType extends AbstractType ThreadSearchbarType.php:13
ThreadSearchbarType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidThreadSearchbarType::buildForm()
public function buildForm(FormBuilderInterface $builder, array $options): voidUserProfileType class
class UserProfileType extends AbstractType UserProfileType.php:14
UserProfileType::getBlockPrefix()
public function getBlockPrefix(): stringUserProfileType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidUserProfileType::buildForm()
public function buildForm(FormBuilderInterface $builder, array $options): voidUserSearchType class
class UserSearchType extends AbstractType UserSearchType.php:16
The members' search (user_search): a name to look for. It had no field at all, so its page could not render the input its template asked for.
UserSearchType::buildForm()
public function buildForm(FormBuilderInterface $builder, array $options): voidUserSearchType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidUserSettingsType class
class UserSettingsType extends AbstractType UserSettingsType.php:10
UserSettingsType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidBase\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\Inspector
DoctrineDataCollector class
class DoctrineDataCollector extends DataCollector DoctrineDataCollector.php:9
DoctrineDataCollector::__construct()
public function __construct(DoctrineDataCollector $innerCollector)DoctrineDataCollector::collect()
public function collect(Request $request, Response $response, ?\Throwable $exception = null): voidDoctrineDataCollector::getName()
public function getName(): stringLocalizerDataCollector class
class LocalizerDataCollector extends AbstractDataCollector LocalizerDataCollector.php:12
LocalizerDataCollector::__construct()
public function __construct(LocalizerInterface $localizer)LocalizerDataCollector::getName()
public function getName(): stringLocalizerDataCollector::getTemplate()
public static function getTemplate(): ?stringLocalizerDataCollector::getData()
public function getData(): arrayLocalizerDataCollector::getLocale()
public function getLocale()LocalizerDataCollector::collect()
public function collect(Request $request, Response $response, $exception = null): voidBase\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
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:16
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): ?stringBase\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:47
BaseNotifier::__call()
public function __call($method, $arguments): mixedBaseNotifier::getOptions()
public function getOptions(): arrayBaseNotifier::getTestRecipients()
public function getTestRecipients(): arrayBaseNotifier::getEnvironment()
public function getEnvironment(): EnvironmentBaseNotifier::setUsers()
public function setUsers(Users $users): staticBaseNotifier::__construct()
public function __construct(SymfonyNotifierInterface $notifier, ChannelPolicyInterface $policy, EntityManagerInterface $entityManager, ParameterBagInterface $parameterBag, TranslatorInterface $translator, LocalizerInterface $localizer, AdvancedRouterInterface $router, Environment $twig, SettingBag $settingBag, bool $debug = false)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(): AdvancedRouterInterfaceBaseNotifier::setRouter()
public function setRouter(AdvancedRouterInterface $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:12
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::getEnvironment()
public function getEnvironment(): EnvironmentBaseNotifierInterface::enable()
public function enable()BaseNotifierInterface::disable()
public function disable()Base\Notifier\Channel
BrowserPlusChannel class
final class BrowserPlusChannel implements ChannelInterface BrowserPlusChannel.php:10
BrowserPlusChannel::__construct()
public function __construct(RequestStack $requestStack)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:28
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(protected readonly EntityManagerInterface $entityManager, protected readonly Users $users)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:24
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: Twig and symfony/mime, which every host has (Laravel's mail is Symfony's Mailer).
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 TEST_PREFIX = "Test: "Before the subject of an e-mail to a test address.
EmailComposer::__construct()
public function __construct(readonly Environment $twig, readonly string|\Closure $from, readonly ?\Closure $isTest = null, readonly ?\Closure $trans = null, readonly ?\Closure $globals = null)$fromthe sender: the technical address (the Notifier's getTechnicalRecipient())
$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)
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(Environment $twig, ?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:17
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.
InlineImages::__construct()
public function __construct(readonly Environment $twig, readonly Email $message)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, …
ThreadIntlRepository class
class ThreadIntlRepository extends ServiceEntityRepository implements ThreadTranslations ThreadIntlRepository.php:16
ThreadIntlRepository::search()
public function search(array $terms, array $states = [], Thread|int|string|null $parent = null): arrayThreadRepository class
class ThreadRepository extends ServiceEntityRepository implements Threads ThreadRepository.php:23
ThreadRepository::oneBySlug()
public function oneBySlug(string $slug, bool $cached = true): ?ThreadThreadRepository::oneBySlugAndState()
public function oneBySlugAndState(?string $slug, array|string $states, array $orderBy = []): ?ThreadThreadRepository::oneByState()
public function oneByState(array|string $states, array $orderBy = []): ?ThreadThreadRepository::first()
public function first(array $orderBy): ?ThreadThreadRepository::byState()
public function byState(array|string $states, array $orderBy = []): arrayThreadRepository::byStateUncached()
public function byStateUncached(array|string $states): arrayThreadRepository::byStates()
public function byStates(array $states): arrayThreadRepository::oneByParentAndSlugAndState()
public function oneByParentAndSlugAndState(?Thread $parent, string $slug, array|string $states, array $orderBy = []): ?ThreadThreadRepository::byParentAndState()
public function byParentAndState(?Thread $parent, array|string $states, array $orderBy = [], ?int $limit = null, ?int $offset = null): arrayThreadRepository::byParentAndStatePublishedWithin()
public function byParentAndStatePublishedWithin(?Thread $parent, array|string $states, string $within, array $orderBy = []): arrayThreadRepository::oneByStateAndSlugStartingWith()
public function oneByStateAndSlugStartingWith(array|string $states, string $prefix): ?ThreadThreadRepository::countByStatePublishedYoungerThan()
public function countByStatePublishedYoungerThan(array|string $states, int|string $age): intThreadRepository::previousOne()
public function previousOne(array $at, array|string $states, ?string $class = null): ?ThreadThreadRepository::nextOne()
public function nextOne(array $at, array|string $states, ?string $class = null): ?ThreadThreadRepository::countForChildrenIn()
public function countForChildrenIn($thread)ThreadRepository::cacheByInsensitiveIdentifier()
public function cacheByInsensitiveIdentifier($identifier, array $fields = [])ThreadRepository::findByInsensitiveIdentifier()
public function findByInsensitiveIdentifier($identifier, array $fields = [], $cacheable = false)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).
UserRepository class
class UserRepository extends ServiceEntityRepository implements SecurityUserLoader, SecurityUserProvider, Users UserRepository.php:27
UserRepository::oneByUsername()
public function oneByUsername(string $username, bool $cached = true): ?\Base\Entity\UserUsers (step R15): the account of a username, through the finder's cache.
UserRepository::oneByEmail()
public function oneByEmail(?string $email): ?\Base\Entity\UserUserRepository::byIds()
public function byIds(array $ids): arrayUserRepository::activeWithin()
public function activeWithin(int $seconds, ?int $exceptId = null): arrayUserRepository::oneById()
public function oneById(int $id): ?\Base\Entity\UserUserRepository::byRoles()
public function byRoles(array|string $roles): arrayUserRepository::byUsernameContaining()
public function byUsernameContaining(string $term, int $limit = 50): arrayUserRepository::supportsClass()
public function supportsClass(string $class): boolUserRepository::loadUserByIdentifier()
public function loadUserByIdentifier(string $identifier): UserInterfaceUserRepository::refreshUser()
public function refreshUser(UserInterface $user): UserInterfaceUserRepository::upgradePassword()
public function upgradePassword(PasswordAuthenticatedUserInterface $user, string $newHashedPassword): voidUserRepository::findActiveAdmins()
public function findActiveAdmins(int $onlineDelay, ?int $excludeId = null): arrayOTHER admins (own ROLE_ADMIN/ROLE_SUPERADMIN column, not group- inherited - a LIKE on the raw SET column can't see those without joining group membership, and this is a "who else is around right now" indicator, not a security check) active within the last $onlineDelay seconds, most recently active first. $excludeId is meant to be the current viewer - matches the one pre-existing precedent for this kind of query (the older, currently-inert AnalyticsSubscriber's findByIdNotEqualToAndActiveAtYoungerThan()).
UserRepository::cacheByInsensitiveIdentifier()
public function cacheByInsensitiveIdentifier($identifier, array $fields = [])UserRepository::findByInsensitiveIdentifier()
public function findByInsensitiveIdentifier($identifier, array $fields = [], $cacheable = false)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
PageViewRepository class
class PageViewRepository extends ServiceEntityRepository implements PageViews PageViewRepository.php:13
PageViewRepository::incrementView()
public function incrementView(string $path, \DateTimeImmutable $date, string $source = PageView::SOURCE_HUMAN): voidAtomic increment, not a load-modify-flush cycle - two concurrent requests hitting the same page the same HOUR must both count, not race and silently drop one. Native upsert rather than a Doctrine entity round-trip: ON DUPLICATE KEY UPDATE on MySQL/MariaDB (the applications' database), ON CONFLICT on SQLite and PostgreSQL (the omnibase harness runs on SQLite). $source is part of the unique key now (see PageView's docblock), so human/bot/ai hits on the same page the same hour land in three separate rows rather than one blended count.
$date is bucketed down to the top of its hour here (minutes/seconds zeroed) rather than trusting every caller to already pass an hour-aligned value - Analytics::track() passes the raw "now", not something pre-bucketed, same as it used to pass a raw "today" before PageView moved from daily to hourly grain.
PageViewRepository::countViews()
public function countViews(?string $path = null, ?\DateTimeImmutable $since = null, ?string $source = null): intSums the daily rows in range - $path null means every page (a site-wide total), $since null means all-time (no lower bound), $source null means every source (human + bot + ai combined, the pre-existing "total hits" semantics); pass a PageView::SOURCE_* constant to see just that bucket.
PageViewRepository::earliestDate()
public function earliestDate(): ?\DateTimeImmutableThe earliest recorded DAY, site-wide - what "all time" actually means for dailyBreakdown()'s $days=null case (there's no data before this, so generating a series further back would just be rows of zeroes). Null if nothing has ever been tracked.
Truncated to midnight even though the underlying column is now hour-grained - Analytics::dailyBreakdown()'s "all time" day-count (a plain calendar diff against today) would be thrown off by whatever hour the earliest row happens to carry otherwise.
PageViewRepository::dailyBreakdown()
public function dailyBreakdown(\DateTimeImmutable $since, string|array|null $path = null): array$patha single path (exact match), a list of paths (any-of match - e.g. every Article's own __toLink(), for a whole-class rollup rather than one instance), or null for site-wide
PageViewRepository::dailyBreakdownBySource()
public function dailyBreakdownBySource(\DateTimeImmutable $since, string|array|null $path = null): array$pathsee dailyBreakdown()'s own docblock
PageViewRepository::hourlyBreakdown()
public function hourlyBreakdown(\DateTimeImmutable $since, string|array|null $path = null): array$pathsee dailyBreakdown()'s own docblock
PageViewRepository::hourlyBreakdownBySource()
public function hourlyBreakdownBySource(\DateTimeImmutable $since, string|array|null $path = null): array$pathsee dailyBreakdown()'s own docblock
PageViews interface
interface PageViews extends Entities PageViews.php:15
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): arrayPageVisitRepository class
class PageVisitRepository extends ServiceEntityRepository implements PageVisits PageVisitRepository.php:12
PageVisitRepository::recordPresence()
public function recordPresence(string $path, string $subjectType, string $subjectId, \DateTimeImmutable $date): voidInsert-if-absent, bucketed to the hour - same contract as VisitRepository::recordPresence(), with the page added.
PageVisitRepository::countUnique()
public function countUnique(?\DateTimeImmutable $since = null, string|array|null $path = null): intUnique views over the window: distinct (page, subject) pairs. A reader reloading one page is one unique view; the same reader on two pages is two. Rows are hourly, so this counts DISTINCT pairs, never rows - over a DISTINCT subquery, since COUNT(DISTINCT a, b, c) is MySQL's alone.
PageVisitRepository::dailyBreakdown()
public function dailyBreakdown(\DateTimeImmutable $since, string|array|null $path = null): arrayOne entry per calendar day: distinct (page, subject) pairs seen that day. A reader coming back to the same page on another day counts again on that day - the right answer for a trend line, as with VisitRepository::dailyBreakdown().
- Returns
date (Y-m-d) => unique views
PageVisitRepository::hourlyBreakdown()
public function hourlyBreakdown(\DateTimeImmutable $since, string|array|null $path = null): array- Returns
hour ("Y-m-d H:i:s") => unique views
PageVisits interface
interface PageVisits extends Entities PageVisits.php:15
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): arrayVisitRepository class
class VisitRepository extends ServiceEntityRepository implements Visits VisitRepository.php:12
VisitRepository::recordPresence()
public function recordPresence(string $subjectType, string $subjectId, \DateTimeImmutable $date): voidInsert-if-absent, not insert-or-update: a presence row only ever needs to exist once per (hour, subject) - a second sighting the same hour is a silent no-op, not an update. INSERT IGNORE (rather than a SELECT-then-INSERT round trip) makes that race-safe under concurrent requests from the same subject too.
$date is bucketed down to the top of its hour here, same reasoning as PageViewRepository::incrementView()'s own bucketing.
VisitRepository::insertIgnore()
public static function insertIgnore(\Doctrine\DBAL\Connection $connection, string $into): string"INSERT IGNORE INTO $into" on MySQL/MariaDB; elsewhere (SQLite, the harness's database, and PostgreSQL) the same through ON CONFLICT DO NOTHING - one row per unique key, a duplicate silently skipped.
VisitRepository::countUnique()
public function countUnique(string $subjectType, ?\DateTimeImmutable $since = null): intTrue unique count over the window (not an approximation): each subject contributes at most one row per day it was seen, so COUNT(DISTINCT subject_id) across the date range never double-counts a subject who returned on multiple days within it.
VisitRepository::returning()
public function returning(string $subjectType, \DateTimeImmutable $previousSince, \DateTimeImmutable $currentSince): arrayRetention: of the subjects seen in [$previousSince, $currentSince), how many were seen again from $currentSince on.
Both numbers come from one scan rather than two queries, so they cannot disagree about who "previous" was. A subject first seen in the current window is not in either count - retention is about coming BACK, and a newcomer has nothing to come back to.
VisitRepository::dailyBreakdown()
public function dailyBreakdown(string $subjectType, \DateTimeImmutable $since): arrayOne row per calendar day in range - unlike countUnique() (a single total over the whole window), a subject seen on multiple days within range legitimately contributes to EACH of those days here; that's the correct semantics for "how many distinct subjects were active on day X", which is what a trend chart needs.
Raw SQL, same reason as PageViewRepository::dailyBreakdown(): folding this table's own hourly rows back down to one row per DAY needs DATE(date), which DQL has no built-in function for.
- Returns
date (Y-m-d) => distinct subject count
VisitRepository::hourlyBreakdown()
public function hourlyBreakdown(string $subjectType, \DateTimeImmutable $since): arrayOne row per HOUR in range - the hourly counterpart to dailyBreakdown(), for the one range ("today") an hour-by-hour curve is actually legible for. No zero-fill here, same division of responsibility as PageViewRepository::hourlyBreakdown() vs Analytics::hourlyBreakdown().
- Returns
hour ("Y-m-d H:i:s") => distinct subject count
Visits interface
interface Visits extends Entities Visits.php:15
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
LogRepository class
class LogRepository extends ServiceEntityRepository LogRepository.php:14
OrderingRepository class
class OrderingRepository extends ServiceEntityRepository OrderingRepository.php:14
RevisionRepository class
class RevisionRepository extends ServiceEntityRepository implements Revisions RevisionRepository.php:14
RevisionRepository::history()
public function history(string $entityClass, int $entityId, ?int $limit = null): arrayHistory of one entity, newest first.
Ordered by id, not createdAt: the id is the insertion sequence and is strictly monotonic, whereas two revisions written in the same second are otherwise unorderable - and #[Timestamp] has been seen to hand out timestamps that disagree with insertion order outright.
RevisionRepository::obsoleteIds()
public function obsoleteIds(string $entityClass, int $entityId, int $keep): arrayIds falling outside the newest $keep revisions of an entity.
Returns ids rather than entities so the caller can DELETE them in one statement: trimming runs on every versioned save, and hydrating a history only to discard it would make each save pay for the whole history it is about to shorten.
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
TrashBallRepository class
class TrashBallRepository extends ServiceEntityRepository implements TrashBalls TrashBallRepository.php:16
TrashBallRepository::contents()
public function contents(?string $entityClass = null, ?int $limit = null, int $offset = 0): arrayEverything currently in the trash, newest first.
TrashBallRepository::countContents()
public function countContents(?string $entityClass = null): intTrashBallRepository::expired()
public function expired(?DateTimeInterface $now = null, ?int $limit = null): arrayTrash entries whose grace period has run out - what the purge destroys.
TrashBallRepository::forEntity()
public function forEntity(string $entityClass, int $entityId): ?TrashBallThe trash entry standing for one entity, if it is in the trash.
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\Extension\Abstract
AbstractExtensionRepository class
abstract class AbstractExtensionRepository extends ServiceEntityRepository AbstractExtensionRepository.php:14
Base\Repository\Hours
ScopedWeekRepository class
class ScopedWeekRepository extends ServiceEntityRepository implements ScopedWeeks ScopedWeekRepository.php:12
ScopedWeekRepository::ofScope()
public function ofScope(string $scope): ?ScopedWeekScopedWeekRepository::week()
public function week(string $scope): ?array- Returns
the place's week, all seven days; null: it follows the site's
ScopedWeekRepository::save()
public function save(string $scope, array $week): ScopedWeek$weekISO day => hours
ScopedWeekRepository::forget()
public function forget(string $scope): voidBack to the site's week.
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): voidSpecialDayRepository class
class SpecialDayRepository extends ServiceEntityRepository implements SpecialDays SpecialDayRepository.php:12
SpecialDayRepository::upcoming()
public function upcoming(\DateTimeInterface $from, int $limit = 50, ?string $scope = null): array$scopethe place's own; null: the whole site's
- Returns
those not over by $from, soonest first
SpecialDays interface
interface SpecialDays extends Entities SpecialDays.php:15
The special days (closures, other hours) (audit "lesringostars face au master plan", step R28; see Base\Database\Repository\Entities): SpecialDayRepository answers it with the queries its callers ran by name before.
SpecialDays::upcoming()
public function upcoming(\DateTimeInterface $from, int $limit = 50, ?string $scope = null): array- Returns
from $from on, the nearest first
WeekDayHoursRepository class
class WeekDayHoursRepository extends ServiceEntityRepository implements WeekDays WeekDayHoursRepository.php:12
WeekDayHoursRepository::week()
public function week(): array- Returns
ISO day => hours; empty when never set
WeekDayHoursRepository::save()
public function save(array $week): void$weekall seven days, ISO day => hours
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
AttributeRepository class
class AttributeRepository extends ServiceEntityRepository AttributeRepository.php:16
ImageCropRepository class
class ImageCropRepository extends ServiceEntityRepository implements ImageCrops ImageCropRepository.php:16
ImageCropRepository::oneBySlugOfImage()
public function oneBySlugOfImage(string $slug, string $source): ?ImageCropImageCrops (step R28): ImageRoute's finder.
ImageCropRepository::oneClosestToRatio()
public function oneClosestToRatio(float|int $ratio0, string $source): ?ImageCropImageCropRepository::oneClosestToRatioAndSize()
public function oneClosestToRatioAndSize(float|int $ratio0, float|int $width0, float|int $height0, string $source): ?ImageCropImageCropRepository::__construct()
public function __construct(ManagerRegistry $registry)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).
ImageRepository class
class ImageRepository extends ServiceEntityRepository ImageRepository.php:16
ImageRepository::__construct()
public function __construct(ManagerRegistry $registry)RedirectionRepository class
class RedirectionRepository extends ServiceEntityRepository implements Redirections RedirectionRepository.php:13
RedirectionRepository::forAddress()
public function forAddress(string $address): ?RedirectionThe redirection for an address (Redirection::normalize()): the one written for it with its query, then for its path alone, then the longest prefix ("/a/b/*" before "/a/*") that covers it.
RedirectionRepository::hit()
public function hit(Redirection $redirection): voidOne more visitor carried: counted in the database, whatever else the request holds.
Redirections interface
interface Redirections extends Entities Redirections.php:15
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.
SemanticRepository class
class SemanticRepository extends ServiceEntityRepository implements Semantics SemanticRepository.php:16
SemanticRepository::every()
public function every(): arraySemantics (step R28): SemanticEnhancer's finder.
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.
SettingRepository class
class SettingRepository extends ServiceEntityRepository implements Settings SettingRepository.php:16
SettingRepository::under()
public function under(?string $path, bool $linkedBagOnly = false, bool $cached = true): arraySettings (step R28): the finders SettingBag::getRaw() named by its arguments.
SettingRepository::oneByInsensitivePath()
public function oneByInsensitivePath(string $path): ?SettingSettings 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.
ShortLinkRepository class
class ShortLinkRepository extends ServiceEntityRepository ShortLinkRepository.php:16
TextOverrideRepository class
class TextOverrideRepository extends ServiceEntityRepository TextOverrideRepository.php:12
TextOverrideRepository::map()
public function map(): array- Returns
every rewritten text, by "domain|locale|key"
TooltipRepository class
class TooltipRepository extends ServiceEntityRepository TooltipRepository.php:16
WidgetRepository class
class WidgetRepository extends ServiceEntityRepository implements Widgets WidgetRepository.php:16
WidgetRepository::oneByPath()
public function oneByPath(string $path, bool $cached = true): ?WidgetWidgets (step R28): WidgetProvider's finders, the result cache unless $cached is false.
WidgetRepository::every()
public function every(bool $cached = true): arrayWidgets 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\Attribute
HyperlinkRepository class
class HyperlinkRepository extends AttributeRepository HyperlinkRepository.php:16
Base\Repository\Layout\Attribute\Adapter
ArrayAdapterRepository class
class ArrayAdapterRepository extends AbstractAdapterRepository ArrayAdapterRepository.php:16
ColorAdapterRepository class
class ColorAdapterRepository extends AbstractAdapterRepository ColorAdapterRepository.php:16
CountryAdapterRepository class
class CountryAdapterRepository extends AbstractAdapterRepository CountryAdapterRepository.php:16
DateRangeAdapterRepository class
class DateRangeAdapterRepository extends ServiceEntityRepository DateRangeAdapterRepository.php:14
DateTimeAdapterRepository class
class DateTimeAdapterRepository extends AbstractAdapterRepository DateTimeAdapterRepository.php:16
HyperpatternAdapterRepository class
class HyperpatternAdapterRepository extends AbstractAdapterRepository HyperpatternAdapterRepository.php:16
ImageAdapterRepository class
class ImageAdapterRepository extends AbstractAdapterRepository ImageAdapterRepository.php:16
MoneyAdapterRepository class
class MoneyAdapterRepository extends AbstractAdapterRepository MoneyAdapterRepository.php:16
NumberAdapterRepository class
class NumberAdapterRepository extends AbstractAdapterRepository NumberAdapterRepository.php:16
PercentAdapterRepository class
class PercentAdapterRepository extends AbstractAdapterRepository PercentAdapterRepository.php:16
ScalarAdapterRepository class
class ScalarAdapterRepository extends AbstractAdapterRepository ScalarAdapterRepository.php:16
ScoreAdapterRepository class
class ScoreAdapterRepository extends ServiceEntityRepository ScoreAdapterRepository.php:14
TextAdapterRepository class
class TextAdapterRepository extends AbstractAdapterRepository TextAdapterRepository.php:16
TextareaAdapterRepository class
class TextareaAdapterRepository extends AbstractAdapterRepository TextareaAdapterRepository.php:16
Base\Repository\Layout\Attribute\Adapter\Common
AbstractActionAdapterRepository class
class AbstractActionAdapterRepository extends AbstractAdapterRepository AbstractActionAdapterRepository.php:13
AbstractAdapterRepository class
class AbstractAdapterRepository extends ServiceEntityRepository AbstractAdapterRepository.php:16
AbstractRuleAdapterRepository class
class AbstractRuleAdapterRepository extends AbstractAdapterRepository AbstractRuleAdapterRepository.php:14
AbstractScopeAdapterRepository class
class AbstractScopeAdapterRepository extends AbstractAdapterRepository AbstractScopeAdapterRepository.php:14
Base\Repository\Layout\Attribute\Common
AbstractActionRepository class
class AbstractActionRepository extends ServiceEntityRepository AbstractActionRepository.php:16
AbstractAttributeRepository class
class AbstractAttributeRepository extends ServiceEntityRepository AbstractAttributeRepository.php:16
AbstractRuleRepository class
class AbstractRuleRepository extends ServiceEntityRepository AbstractRuleRepository.php:16
AbstractScopeRepository class
class AbstractScopeRepository extends ServiceEntityRepository AbstractScopeRepository.php:16
Base\Repository\Layout\Widget
AttachmentRepository class
class AttachmentRepository extends WidgetRepository AttachmentRepository.php:16
LinkRepository class
class LinkRepository extends WidgetRepository LinkRepository.php:16
PageRepository class
class PageRepository extends WidgetRepository PageRepository.php:16
RouteRepository class
class RouteRepository extends WidgetRepository RouteRepository.php:16
SlotRepository class
class SlotRepository extends WidgetRepository implements Slots SlotRepository.php:15
SlotRepository::oneByPath()
public function oneByPath(string $path, bool $cached = true): ?SlotSlots (step R28): WidgetProvider's finders, the result cache unless $cached is false.
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\Layout\Widget\Set
BookRepository class
class BookRepository extends WidgetRepository BookRepository.php:16
LinksetRepository class
class LinksetRepository extends WidgetRepository LinksetRepository.php:16
MenuRepository class
class MenuRepository extends WidgetRepository MenuRepository.php:16
NetworkRepository class
class NetworkRepository extends WidgetRepository NetworkRepository.php:16
PaperclipRepository class
class PaperclipRepository extends WidgetRepository PaperclipRepository.php:16
Base\Repository\Thread
CommentRepository class
class CommentRepository extends ServiceEntityRepository implements Comments CommentRepository.php:15
CommentRepository::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()).
CommentRepository::countVisible()
public function countVisible(?Thread $thread): intCommentRepository::countPending()
public function countPending(): intCommentRepository::findPending()
public function findPending(int $limit = 20): arrayCommentRepository::findLastFromIp()
public function findLastFromIp(string $ip): ?CommentThe last comment this address left, to hold the flood interval.
Comments interface
interface Comments extends Entities Comments.php:15
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.
Comments::findLastFromIp()
public function findLastFromIp(string $ip): ?CommentThe newest comment written from an address (FormGuard's flood check).
LikeRepository class
class LikeRepository extends ServiceEntityRepository implements Likes LikeRepository.php:15
LikeRepository::oneByThreadAndUser()
public function oneByThreadAndUser(\Base\Entity\Thread $thread, ?\Base\Entity\User $user): ?\Base\Entity\Thread\LikeLikes (step R28): ThreadController's finder.
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).
MentionRepository class
class MentionRepository extends ServiceEntityRepository implements Mentions MentionRepository.php:14
MentionRepository::byThread()
public function byThread(\Base\Entity\Thread $thread): arrayMentions (step R28): ThreadSubscriber's finder.
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.
TagRepository class
class TagRepository extends ServiceEntityRepository implements Tags TagRepository.php:19
TagRepository::oneBySlug()
public function oneBySlug(string $slug): ?TagTagRepository::bySlugs()
public function bySlugs(array $slugs): arrayTagRepository::cacheByInsensitiveIdentifier()
public function cacheByInsensitiveIdentifier($identifier, array $fields = [])TagRepository::findByInsensitiveIdentifier()
public function findByInsensitiveIdentifier($identifier, array $fields = [], $cacheable = false)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
TaxonRepository class
class TaxonRepository extends ServiceEntityRepository TaxonRepository.php:14
Base\Repository\User
AddressRepository class
class AddressRepository extends ServiceEntityRepository AddressRepository.php:15
ComplaintRepository class
class ComplaintRepository extends ServiceEntityRepository ComplaintRepository.php:14
ComplaintRepository::newest()
public function newest(?string $status = null, ?string $source = null, int $limit = 200): arrayThe newest complaints, of one status (and one source) or all.
ConnectionRepository class
class ConnectionRepository extends ServiceEntityRepository implements Connections ConnectionRepository.php:17
ConnectionRepository::oneByUniqidAndUser()
public function oneByUniqidAndUser(string $uniqid, \Base\Entity\User $user): ?\Base\Entity\User\ConnectionConnections (step R28): ConnectionTracker's finder, its arguments as it gave them.
ConnectionRepository::countFor()
public function countFor(\Base\Entity\User $user): intHow many browsers the account was signed into from, counted by the database.
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.
GroupRepository class
class GroupRepository extends ServiceEntityRepository GroupRepository.php:14
IdentityRepository class
class IdentityRepository extends ServiceEntityRepository IdentityRepository.php:17
The accounts' identities at providers (Base\Entity\User\Identity, the userIdentity table); omniauth reads them through Base\Auth\UserIdentities.
IdentityRepository::findOneBySubject()
public function findOneBySubject(string $provider, string $subject): ?IdentityIdentityRepository::findOfUser()
public function findOfUser(object $user): array- Returns
the account's identities, by provider
NotificationRepository class
class NotificationRepository extends ServiceEntityRepository implements Notifications NotificationRepository.php:15
NotificationRepository::countUnreadFor()
public function countUnreadFor(User $user): intA real COUNT. Not the inherited count()/countBy(): base-bundle's ServiceEntityRepository redefines count() to return an array and countBy() hydrates every row, and this runs on every page for the toolbar badge.
NotificationRepository::findVisibleFor()
public function findVisibleFor(User $user, int $limit = 100, int $offset = 0, bool $unreadOnly = false): arrayThe user's notifications that have something to show, newest first.
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
PasskeyRepository class
class PasskeyRepository extends ServiceEntityRepository implements PasskeyRecords, Passkeys PasskeyRepository.php:39
The passkeys (Base\Entity\User\Passkey), and WebauthnBundle's credential repository (plan "omniauth", AU1).
The bundle's interfaces are declared through Base\Contract\PasskeyRecords (theirs where the bundle is installed, empty elsewhere): the repository loads without the bundle. Since the passkey no longer is a Webauthn\CredentialRecord, the records the bundle asks for are made from the passkeys (credentialRecord()), and what it hands back to save is copied onto the passkey of that credential (fill()), or onto a new one at a registration. This is the one place of the core that speaks webauthn-lib to the passkeys; its methods load the library only when called.
Only the current contract: the deprecated PublicKeyCredentialSourceRepositoryInterface alias that WebauthnExtension still registers is removed by WebauthnDeprecatedAliasPass, so nothing requires it here.
PasskeyRepository::findOneByCredential()
public function findOneByCredential(string $publicKeyCredentialId): ?PasskeyThe passkey of this credential id (bytes), compared as the column keeps it (base64).
Not findOneBy(): omnibase's finder binds a criterion's value as it is, not through the column's type, and the raw id never matched its base64 text - up to AU1 no passkey could sign in ("The credential ID is invalid.").
PasskeyRepository::findAllForUserEntity()
public function findAllForUserEntity(PublicKeyCredentialUserEntity $publicKeyCredentialUserEntity): arrayPasskeyRepository::findOneByCredentialId()
public function findOneByCredentialId(string $publicKeyCredentialId): ?CredentialRecordPasskeyRepository::saveCredentialRecord()
public function saveCredentialRecord(CredentialRecord $credentialRecord): voidWhat the bundle hands back: after a sign-in, the record of a known passkey (its counter and flags moved), copied onto it; at a registration, a plain record made from the attestation, which becomes the passkey of the account its userHandle names (WebauthnUserEntityRepository gives the account's id as its handle).
PasskeyRepository::credentialRecord()
public static function credentialRecord(Passkey $passkey): CredentialRecordwebauthn-lib's record of a passkey: what the bundle verifies a sign-in against.
PasskeyRepository::fill()
public static function fill(Passkey $passkey, CredentialRecord $record): PasskeyThe 13 fields of a record, on the passkey, in the values the passkey keeps: the trust path as
webauthn-lib normalizes it (what the bundle's trust_path type wrote), the AAGUID as its text.
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.
PenaltyRepository class
class PenaltyRepository extends ServiceEntityRepository PenaltyRepository.php:14
PermissionRepository class
class PermissionRepository extends ServiceEntityRepository PermissionRepository.php:14
PushSubscriptionRepository class
class PushSubscriptionRepository extends ServiceEntityRepository implements PushSubscriptions PushSubscriptionRepository.php:14
PushSubscriptionRepository::countDistinctUsers()
public function countDistinctUsers(): intUsers who enabled push in at least one browser.
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.
SanctionRepository class
class SanctionRepository extends ServiceEntityRepository SanctionRepository.php:16
TokenRepository class
class TokenRepository extends ServiceEntityRepository implements Tokens TokenRepository.php:14
TokenRepository::oneByValueAndName()
public function oneByValueAndName(?string $value, string $name): ?TokenTokens (step R28): SecurityController's and AccessTokenHandler's finders.
TokenRepository::oneByValue()
public function oneByValue(?string $value): ?TokenTokenRepository::oneSigningInByNameAndValue()
public function oneSigningInByNameAndValue(string $name, ?string $value): ?TokenTokenRepository::oneSigningInByValue()
public function oneSigningInByValue(?string $value): ?TokenTokens 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\Repository\User\Attribute
GroupActionRepository class
class GroupActionRepository extends ServiceEntityRepository GroupActionRepository.php:14
GroupRuleRepository class
class GroupRuleRepository extends ServiceEntityRepository GroupRuleRepository.php:14
GroupScopeRepository class
class GroupScopeRepository extends ServiceEntityRepository GroupScopeRepository.php:14
Base\Repository\User\Attribute\Action
GrantPermissionAdapterRepository class
class GrantPermissionAdapterRepository extends ServiceEntityRepository GrantPermissionAdapterRepository.php:14
GrantRoleAdapterRepository class
class GrantRoleAdapterRepository extends ServiceEntityRepository GrantRoleAdapterRepository.php:14
Base\Repository\User\Attribute\Scope
GroupAdapterRepository class
class GroupAdapterRepository extends ServiceEntityRepository GroupAdapterRepository.php:14
UserAdapterRepository class
class UserAdapterRepository extends ServiceEntityRepository UserAdapterRepository.php:14
Base\Response
PdfResponse class
class PdfResponse extends Response PdfResponse.php:34
An HTML page answered as a PDF, rendered by dompdf/dompdf - a suggested
package: composer require dompdf/dompdf.
return new PdfResponse($this->renderView('invoice.pdf.twig', [...])); return new PdfResponse($html, 200, [ 'filename' => 'facture-2026-041.pdf', 'stream' => ['Attachment' => true], // downloaded, not shown 'options' => ['isRemoteEnabled' => true], // Dompdf's options ]);
The PDF is the response's content (getContent(), testable, cacheable): nothing is sent before the kernel sends the response.
Remote resources are off by default: an <img>, a stylesheet or a font at
an http(s) address is not fetched - the HTML often carries what a visitor
wrote, and fetching what it names from the server is a request forgery
waiting to happen. Embed images as data: URIs (the embed_base64 filter),
fonts and styles in the page; or turn isRemoteEnabled on, knowingly.
Three keys of $headers are settings, not headers: options (Dompdf's),
stream (Attachment, compress), filename, and debug (true: the
HTML itself is answered, to look at it in a browser).
PdfResponse::__construct()
public function __construct(string|Response|null $data = null, int $status = 200, array $headers = [])PdfResponse::render()
public static function render(string $html, array $options = [], array $output = []): stringThe PDF of an HTML page, as a string.
$optionsDompdf's options, over ours (remote resources off, fonts not subset)
$outputDompdf's output options (
compress)- Throws
LogicException when dompdf/dompdf is not installed
PdfResponse::options()
public static function options(array $options = []): arrayDompdf's options as PdfResponse sets them, under the caller's: remote resources off, fonts embedded whole.
PdfResponse::fromPdfString()
public static function fromPdfString(string $source, int $status = 200, array $headers = []): ResponseThe same, as a factory: an HTML source answered as a PDF.
return PdfResponse::fromPdfString($html)->setSharedMaxAge(300);
PdfResponse::fromPdfFile()
public static function fromPdfFile(string $filename, int $status = 200, array $headers = []): ResponseA PDF that already exists as a file.
XmlResponse class
class XmlResponse extends Response XmlResponse.php:8
XmlResponse::__construct()
public function __construct($data = null, int $status = 200, array $headers = [])XmlResponse::fromXmlString()
public static function fromXmlString(string $source, ?int $options = null, int $status = 200, array $headers = []): ResponseFactory method for chainability.
Example:
return JsonResponse::fromJsonString('{"key": "value"}') ->setSharedMaxAge(300);
$statusThe response status code
$headersAn array of response headers
XmlResponse::fromXmlFile()
public static function fromXmlFile(string $filename, ?int $options = null, int $status = 200, array $headers = []): ResponseBase\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): stringAdvancedRouter class
class AdvancedRouter implements AdvancedRouterInterface, ResetInterface AdvancedRouter.php:33
AdvancedRouter::getLocaleLang()
public function getLocaleLang(?string $lang = null): stringAdvancedRouter::getLocale()
public function getLocale(?string $locale = null): stringAdvancedRouter::getEnvironment()
public function getEnvironment(): stringAdvancedRouter::__construct()
public function __construct(Router $router, RequestStack $requestStack, FirewallMapInterface $firewallMap, ParameterBagInterface $parameterBag, LocalizerInterface $localizer, AssetExtension $assetTwigExtension, CacheInterface $cache, string $debug, string $environment)AdvancedRouter::useAdvancedFeatures()
public function useAdvancedFeatures(): boolAdvancedRouter::useFallbacks()
public function useFallbacks(): boolAdvancedRouter::getCache()
public function getCache(): CacheInterfaceAdvancedRouter::getCacheName()
public function getCacheName(): stringAdvancedRouter::getCacheRoutes()
public function getCacheRoutes()AdvancedRouter::warmUp()
public function warmUp(string $cacheDir, ?string $buildDir = null): arrayAdvancedRouter::isCli()
public function isCli(): boolAdvancedRouter::isDebug()
public function isDebug(): boolAdvancedRouter::isProfiler()
public function isProfiler(mixed $request = null): boolAdvancedRouter::isUX()
public function isUX(mixed $request = null): boolAdvancedRouter::isAPI()
public function isAPI(mixed $request = null): boolAdvancedRouter::isMainApplication()
public function isMainApplication(mixed $request = null): boolAdvancedRouter::isSecured()
public function isSecured(mixed $request = null): boolAdvancedRouter::isWdt()
public function isWdt(mixed $request = null): boolAdvancedRouter::isAdmin()
public function isAdmin(mixed $request = null): boolAdvancedRouter::getUrl()
public function getUrl(?string $nameOrUrl = null, array $parameters = [], int $referenceType = self::ABSOLUTE_PATH): stringAdvancedRouter::getAssetUrl()
public function getAssetUrl(?string $nameOrUrl = null, ?string $packageName = null): stringAdvancedRouter::getContext()
public function getContext(): RequestContextAdvancedRouter::setContext()
public function setContext(RequestContext $context): voidAdvancedRouter::getGenerator()
public function getGenerator(): UrlGeneratorInterfaceAdvancedRouter::generate()
public function generate(string $name, array $parameters = [], int $referenceType = self::ABSOLUTE_PATH): stringAdvancedRouter::match()
public function match(string $pathinfo): arrayAdvancedRouter::matchRequest()
public function matchRequest(Request $request): arrayAdvancedRouter::getMatcher()
public function getMatcher(): UrlMatcherInterfaceAdvancedRouter::getLocalizer()
public function getLocalizer(): LocalizerInterfaceAdvancedRouter::getRouteCollection()
public function getRouteCollection(): RouteCollectionAdvancedRouter::getRequestUri()
public function getRequestUri(): ?stringAdvancedRouter::getRequest()
public function getRequest(): ?RequestAdvancedRouter::getMainRequest()
public function getMainRequest(): ?RequestAdvancedRouter::getRoute()
public function getRoute(?string $routeNameOrUrl = null): ?RouteAdvancedRouter::reset()
public function reset(): voidThe routes read for a request, forgotten before the next one (ResetInterface, kernel.reset).
AdvancedRouter::getScheme()
public function getScheme(?string $locale = null, ?string $environment = null): stringThe scheme of the request being handled: get_url_scheme() of the main request (Request::isSecure(), so a trusted proxy's X-Forwarded-Proto, then HTTPS, USE_HTTPS, REQUEST_SCHEME), the scheme get_url() gives the visited address and the site's routes. A web request not yet on the stack: the same function on PHP's globals. A command, a worker or a test with no request: https, unless the site sets HTTPS (or USE_HTTPS) to a false value - PHP's globals say nothing of the scheme there.
It is the scheme of Symfony's own routes (_profiler, _wdt...), the one the host fallbacks' ports are filtered by (HTTPS_PORT or HTTP_PORT), the IP restriction's redirection and app.site.scheme. docs/decisions/router-scheme.md says why it read REQUEST_SCHEME as a boolean (always https) until 3.x and what following the request moved.
AdvancedRouter::getBaseDir()
public function getBaseDir(?string $locale = null, ?string $environment = null): stringAdvancedRouter::reducesOnFallback()
public function reducesOnFallback(?string $locale = null, ?string $environment = null): boolAdvancedRouter::getHostFallback()
public function getHostFallback(?string $locale = null, ?string $environment = null): stringAdvancedRouter::getHost()
public function getHost(?string $locale = null, ?string $environment = null): stringAdvancedRouter::getPortFallbacks()
public function getPortFallbacks(?string $locale = null, ?string $environment = null): arrayAdvancedRouter::getPortFallback()
public function getPortFallback(?string $locale = null, ?string $environment = null): ?intAdvancedRouter::getPort()
public function getPort(?string $locale = null, ?string $environment = null): ?intAdvancedRouter::getMachineFallbacks()
public function getMachineFallbacks(?string $locale = null, ?string $environment = null): arrayAdvancedRouter::getMachineFallback()
public function getMachineFallback(?string $locale = null, ?string $environment = null): ?stringAdvancedRouter::getMachine()
public function getMachine(?string $locale = null, ?string $environment = null): ?stringAdvancedRouter::getSubdomainFallbacks()
public function getSubdomainFallbacks(?string $locale = null, ?string $environment = null): arrayAdvancedRouter::getSubdomainFallback()
public function getSubdomainFallback(?string $locale = null, ?string $environment = null): ?stringAdvancedRouter::getSubdomain()
public function getSubdomain(?string $locale = null, ?string $environment = null): ?stringAdvancedRouter::getDomainFallbacks()
public function getDomainFallbacks(?string $locale = null, ?string $environment = null): arrayAdvancedRouter::getDomainFallback()
public function getDomainFallback(?string $locale = null, ?string $environment = null): ?stringAdvancedRouter::getDomain()
public function getDomain(?string $locale = null, ?string $environment = null): ?stringThe domain of the site's cookies: CookieDomain's rule (the request's domain when configured, else the first configured).
AdvancedRouter::getRouteIndex()
public function getRouteIndex(): stringAdvancedRouter::getUrlIndex()
public function getUrlIndex(): stringAdvancedRouter::getRouteName()
public function getRouteName(?string $routeUrl = null): ?stringAdvancedRouter::getRouteGroups()
public function getRouteGroups(string $routeNameOrUrl): arrayAdvancedRouter::getRouteMatch()
public function getRouteMatch(?string $routeUrl = null): ?arrayAdvancedRouter::getFirewallMap()
public function getFirewallMap(): FirewallMapInterfaceAdvancedRouter::hasFirewall()
public function hasFirewall(?string $routeUrl = null): ?boolAdvancedRouter::getRouteFirewall()
public function getRouteFirewall(?string $routeUrl = null): ?FirewallConfigAdvancedRouter::getRouteHash()
public function getRouteHash(string $routeNameOrUrl): stringAdvancedRouter::redirect()
public function redirect(string $urlOrRoute, array $routeParameters = [], int $state = 302, array $headers = []): RedirectResponseAdvancedRouter::redirectToRoute()
public function redirectToRoute(string $routeName, array $routeParameters = [], int $state = 302, array $headers = []): RedirectResponseAdvancedRouter::redirectEvent()
public function redirectEvent(Event $event, string $routeName, array $routeParameters = [], int $state = 302, array $headers = []): boolAdvancedRouter::reloadRequest()
public function reloadRequest(?Request $request = null): RedirectResponseAdvancedRouterInterface interface
interface AdvancedRouterInterface extends SymfonyRouterInterface, RequestMatcherInterface, WarmableInterface, MediaRouter AdvancedRouterInterface.php:19
AdvancedRouterInterface::getRouteIndex()
public function getRouteIndex(): stringAdvancedRouterInterface::getUrlIndex()
public function getUrlIndex(): stringAdvancedRouterInterface::useAdvancedFeatures()
public function useAdvancedFeatures(): boolAdvancedRouterInterface::isProfiler()
public function isProfiler(mixed $request = null): boolAdvancedRouterInterface::isUX()
public function isUX(mixed $request = null): boolAdvancedRouterInterface::isAPI()
public function isAPI(mixed $request = null): boolAdvancedRouterInterface::isMainApplication()
public function isMainApplication(mixed $request = null): boolAdvancedRouterInterface::isWdt()
public function isWdt(mixed $request = null): boolAdvancedRouterInterface::isSecured()
public function isSecured(mixed $request = null): boolAdvancedRouterInterface::reducesOnFallback()
public function reducesOnFallback(?string $locale = null, ?string $environment = null): boolAdvancedRouterInterface::getBaseDir()
public function getBaseDir(?string $locale = null, ?string $environment = null): stringAdvancedRouterInterface::getHost()
public function getHost(?string $locale = null, ?string $environment = null): stringAdvancedRouterInterface::getHostFallback()
public function getHostFallback(?string $locale = null, ?string $environment = null): stringAdvancedRouterInterface::getMachine()
public function getMachine(?string $locale = null, ?string $environment = null): ?stringAdvancedRouterInterface::getMachineFallback()
public function getMachineFallback(?string $locale = null, ?string $environment = null): mixedAdvancedRouterInterface::getMachineFallbacks()
public function getMachineFallbacks(?string $locale = null, ?string $environment = null): ?arrayAdvancedRouterInterface::getScheme()
public function getScheme(?string $locale = null, ?string $environment = null): stringAdvancedRouterInterface::getSubdomain()
public function getSubdomain(?string $locale = null, ?string $environment = null): ?stringAdvancedRouterInterface::getSubdomainFallback()
public function getSubdomainFallback(?string $locale = null, ?string $environment = null): mixedAdvancedRouterInterface::getSubdomainFallbacks()
public function getSubdomainFallbacks(?string $locale = null, ?string $environment = null): ?arrayAdvancedRouterInterface::getDomain()
public function getDomain(?string $locale = null, ?string $environment = null): ?stringAdvancedRouterInterface::getDomainFallback()
public function getDomainFallback(?string $locale = null, ?string $environment = null): mixedAdvancedRouterInterface::getDomainFallbacks()
public function getDomainFallbacks(?string $locale = null, ?string $environment = null): ?arrayAdvancedRouterInterface::getPort()
public function getPort(?string $locale = null, ?string $environment = null): ?intAdvancedRouterInterface::getPortFallback()
public function getPortFallback(?string $locale = null, ?string $environment = null): mixedAdvancedRouterInterface::getPortFallbacks()
public function getPortFallbacks(?string $locale = null, ?string $environment = null): ?arrayAdvancedRouterInterface::getUrl()
public function getUrl(?string $nameOrUrl = null, array $parameters = [], int $referenceType = self::ABSOLUTE_PATH): stringAdvancedRouterInterface::getAssetUrl()
public function getAssetUrl(string $nameOrUrl, ?string $packageName = null): stringAdvancedRouterInterface::getRequest()
public function getRequest(): ?RequestAdvancedRouterInterface::getEnvironment()
public function getEnvironment(): stringAdvancedRouterInterface::getLocale()
public function getLocale(?string $locale = null): stringAdvancedRouterInterface::getLocaleLang()
public function getLocaleLang(?string $lang = null): stringAdvancedRouterInterface::getContext()
public function getContext(): RequestContextAdvancedRouterInterface::setContext()
public function setContext(RequestContext $context): voidAdvancedRouterInterface::getGenerator()
public function getGenerator(): UrlGeneratorInterfaceAdvancedRouterInterface::getMatcher()
public function getMatcher(): UrlMatcherInterface|RequestMatcherInterfaceAdvancedRouterInterface::isCli()
public function isCli(): boolAdvancedRouterInterface::isDebug()
public function isDebug(): boolAdvancedRouterInterface::isAdmin()
public function isAdmin(mixed $request = null): boolAdvancedRouterInterface::hasFirewall()
public function hasFirewall(?string $routeUrl = null): ?boolAdvancedRouterInterface::getCache()
public function getCache(): CacheInterfaceAdvancedRouterInterface::getCacheRoutes()
public function getCacheRoutes()AdvancedRouterInterface::getRoute()
public function getRoute(?string $routeNameOrUrl = null): ?RouteAdvancedRouterInterface::getRouteHash()
public function getRouteHash(string $routeNameOrUrl): stringAdvancedRouterInterface::getRouteName()
public function getRouteName(?string $routeUrl = null): ?stringAdvancedRouterInterface::getRouteMatch()
public function getRouteMatch(?string $routeUrl = null): ?arrayAdvancedRouterInterface::getRouteGroups()
public function getRouteGroups(string $routeNameOrUrl): arrayAdvancedRouterInterface::getRouteFirewall()
public function getRouteFirewall(?string $routeUrl = null): ?FirewallConfigAdvancedRouterInterface::redirect()
public function redirect(string $urlOrRoute, array $routeParameters = [], int $state = 302, array $headers = []): RedirectResponseAdvancedRouterInterface::redirectToRoute()
public function redirectToRoute(string $routeName, array $routeParameters = [], int $state = 302, array $headers = []): RedirectResponseAdvancedRouterInterface::redirectEvent()
public function redirectEvent(Event $event, string $routeName, array $routeParameters = [], int $state = 302, array $headers = []): boolAdvancedRouterInterface::reloadRequest()
public function reloadRequest(?Request $request = null): RedirectResponseCookieDomain 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\Routing\Generator
AdvancedUrlGenerator class
class AdvancedUrlGenerator extends CompiledUrlGenerator AdvancedUrlGenerator.php:13
public static $router = null
AdvancedUrlGenerator::getCompiledRoutes()
public function getCompiledRoutes(): arrayAdvancedUrlGenerator::__construct()
public function __construct(array $compiledRoutes, RequestContext $context, ?LoggerInterface $logger = null, ?string $defaultLocale = null)AdvancedUrlGenerator::resolveParameters()
public function resolveParameters(?array $routeParameters = null): ?arrayAdvancedUrlGenerator::generate()
public function generate(string $routeName, array $routeParameters = [], int $referenceType = self::ABSOLUTE_PATH): stringAdvancedUrlGenerator::withoutEmptySegments()
public static function withoutEmptySegments(string $url, int $referenceType = self::ABSOLUTE_PATH): stringThe address without an empty segment in its path ("/boutique//wishlist" is "/boutique/wishlist"); its scheme, host, query and fragment as they were, a path's trailing slash kept. A network path (//host/path, UrlGeneratorInterface::NETWORK_PATH) keeps its leading host.
AdvancedUrlGenerator::groups()
public function groups(?string $routeName): arrayThe routes of a group: the route named before its first dot and its variants ("app_x", "app_x.fr"...), in the compiled order. Read from an index made once, at the first call: it scanned the 575 compiled routes of lesringostars at every call, 2.4 to 3 ms of a page.
Base\Routing\Loader
RouteTranslationsResourceLoader class
class RouteTranslationsResourceLoader extends FileLoader RouteTranslationsResourceLoader.php:22
Registers config/routes_paths.yaml as a tracked resource so Symfony's config-cache rebuilds routes when it changes. Base\Attributes\Attribute\Route reads that file directly (not through Symfony's routing loaders), so without this, editing it alone — without touching any controller file — would leave the compiled route cache stale: AttributeClassLoader's freshness tracking is per-controller-class, not aware of this file at all.
Registers no routes itself; loaded purely for its addResource() side effect. Extends FileLoader (not the bare Loader) specifically to reuse its FileLocator for resolving the resource path the same way YamlFileLoader and friends do (relative to the importing routes.yaml's directory).
const TYPE = "base_route_paths"
RouteTranslationsResourceLoader::load()
public function load(mixed $resource, ?string $type = null): RouteCollectionRouteTranslationsResourceLoader::supports()
public function supports(mixed $resource, ?string $type = null): boolBase\Routing\Matcher
AdvancedUrlMatcher class
class AdvancedUrlMatcher extends CompiledUrlMatcher implements RedirectableUrlMatcherInterface AdvancedUrlMatcher.php:14
public static $router = nullpublic static int $i = 0
AdvancedUrlMatcher::__construct()
public function __construct(array $compiledRoutes, RequestContext $context)AdvancedUrlMatcher::redirect()
public function redirect(string $path, string $route, ?string $scheme = null): arrayAdvancedUrlMatcher::security()
public function security(string $pathinfo): boolAdvancedUrlMatcher::firewall()
public function firewall(string $pathinfo): ?FirewallConfigAdvancedUrlMatcher::getCompiledPath()
public function getCompiledPath(array $compiledRoute): ?stringAdvancedUrlMatcher::getCompiledHost()
public function getCompiledHost(array $compiledRoute): ?stringAdvancedUrlMatcher::getCompiledHostRegex()
public function getCompiledHostRegex(array $compiledRoute): ?stringAdvancedUrlMatcher::match()
public function match(string $pathinfo): arrayBase\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).
Base\Screen\Account
AccountSummary class
final readonly class AccountSummary implements Screen AccountSummary.php:14
An account's security at a glance, on its profile, for its owner or an
administrator: whether it has a second factor (null where two-factor is not
available on the site), how many passkeys (null where passkeys are not -
never 0 for "not counted"), the provider it signs in with (google), its
language and time zone.
public ?bool $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
AccessTokenHandler class
class AccessTokenHandler implements AccessTokenHandlerInterface AccessTokenHandler.php:10
AccessTokenHandler::__construct()
public function __construct(Tokens $tokenRepository)AccessTokenHandler::getUserBadgeFrom()
public function getUserBadgeFrom(string $token): UserBadgeConnectionTracker class
class ConnectionTracker ConnectionTracker.php:20
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(EntityManagerInterface $entityManager, 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
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): boolLoginFormAuthenticator class
class LoginFormAuthenticator extends AbstractLoginFormAuthenticator LoginFormAuthenticator.php:29
const LOGIN_ROUTE = 'security_login'const LOGOUT_ROUTE = 'security_logout'const LOGOUT_REQUEST_ROUTE = 'security_logoutRequest'
LoginFormAuthenticator::__construct()
public function __construct(ReferrerInterface $referrer, Users $users, AdvancedRouterInterface $router, AuthorizationCheckerInterface $authorizationChecker)LoginFormAuthenticator::isSecurityRoute()
public static function isSecurityRoute(Request|string $routeNameOrRequest)LoginFormAuthenticator::start()
public function start(Request $request, ?AuthenticationException $authException = null): ResponseLoginFormAuthenticator::supports()
public function supports(Request $request): boolLoginFormAuthenticator::authenticate()
public function authenticate(Request $request): PassportLoginFormAuthenticator::onAuthenticationSuccess()
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?ResponseLoginRestrictionInterface interface
interface LoginRestrictionInterface LoginRestrictionInterface.php:5
OAuthUserProvider class
class OAuthUserProvider extends UserProvider implements OAuthAwareUserProviderInterface OAuthUserProvider.php:14
Base\Security\UserProvider declared OAuth-aware, for hwi/oauth-bundle's
firewalls (an oauth provider asks for its interface). The service
Base\Security\UserProvider is this class when hwi/oauth-bundle is installed,
UserProvider otherwise (config/services/form.php): the sites' security.yaml
name the service, not the class.
RescueFormAuthenticator class
class RescueFormAuthenticator extends LoginFormAuthenticator RescueFormAuthenticator.php:5
const LOGIN_ROUTE = 'security_rescue'const PENDING_ROUTE = 'security_pending'
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 glitchr/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).
SignInGuard class
class SignInGuard extends SignInCaptcha implements EventSubscriberInterface SignInGuard.php:30
The sign-in's captcha, after a few failures (Base\Security\SignInCaptcha), under Symfony. Symfony's login_throttling is the first line (five tries a minute, per identifier and address); this one counts the failures from an address - whatever identifiers they tried - and from base.guard.sign_in_after of them on, the sign-in form carries the captcha (SecurityController::Login) and a sign-in without a valid token is refused before its password is even checked. A success forgets the count.
Only the site's own sign-in form (security_login): not the rescue door, not the demonstration's one click. Nothing where glitchr/ux-google's reCAPTCHA already guards the sign-in (google.recaptcha.enable), nor without glitchr/omnishield and a captcha.
SignInGuard::__construct()
public function __construct(FormGuard $guard, ?CacheItemPoolInterface $cache = null, bool $google = false, ?LoggerInterface $logger = null, protected readonly ?RequestStack $requests = null)SignInGuard::getSubscribedEvents()
public static function getSubscribedEvents(): arraySignInGuard::required()
public function required(?Request $request): ?stringThe captcha's gateway when a sign-in from this request must pass it; null otherwise.
SignInGuard::onLoginFailure()
public function onLoginFailure(LoginFailureEvent $event): voidSignInGuard::onLoginSuccess()
public function onLoginSuccess(LoginSuccessEvent $event): voidSignInGuard::onCheckPassport()
public function onCheckPassport(CheckPassportEvent $event): voidSignInGuard::byOmniauth()
public static function byOmniauth(?\Symfony\Component\Security\Http\Authenticator\Passport\Passport $passport): boolA sign-in omniauth decided (omnibridge/symfony's OmniauthAuthenticator, plan "omniauth" AU7): its own events were heard, Base\Auth\Listener\GuardSignIn guarded it.
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.
UserChecker class
class UserChecker implements UserCheckerInterface UserChecker.php:14
UserChecker::__construct()
public function __construct(EntityManagerInterface $entityManager, protected ?\Base\Notifier\Notifier $notifier = null)UserChecker::checkPreAuth()
public function checkPreAuth(UserInterface $user): voidUserChecker::checkPostAuth()
public function checkPostAuth(UserInterface $user, ?TokenInterface $token = null): voidUserProvider class
class UserProvider implements UserProviderInterface, PasswordUpgraderInterface UserProvider.php:26
The users of the firewalls, by their identifier, refreshed from their row.
hwi/oauth-bundle is a suggestion of the core since 4.0: this class no longer names its interface, so it loads without it. With it, the service Base\Security\UserProvider is an OAuthUserProvider (the same class, declared OAuth-aware), see config/services/form.php; loadUserByOAuthUserResponse() stays here (a type in a signature loads nothing).
UserProvider::__construct()
public function __construct(UserTracker $userTracker, Users&SecurityUserLoader $userRepository)UserProvider::loadUserByIdentifier()
public function loadUserByIdentifier($identifier): UserInterface{@inheritdoc}
UserProvider::refreshUser()
public function refreshUser(UserInterface $user): UserInterfaceRefreshes the user after being reloaded from the session.
The session holds a serialized copy of the User; what comes back from it is a detached object with the values of the moment it was stored. Re-reading the row is what makes a change made elsewhere (a level or a balance updated by a nightly command, a role changed in the admin) show on the member's next request instead of their next login - and what makes deleting an account actually end its sessions: no row, no user.
A transient user (the OAuth stub of loadUserByOAuthUserResponse(), id 0) has no row to re-read and is returned as it is.
If your firewall is "stateless: true" (for a pure API), this method is not called.
UserProvider::supportsClass()
public function supportsClass(string $class): boolTells Symfony to use this provider for this User class.
UserProvider::upgradePassword()
public function upgradePassword(PasswordAuthenticatedUserInterface $user, string $newHashedPassword): voidUpgrades the encoded password of a user, typically for using a better hash algorithm.
UserProvider::loadUserByOAuthUserResponse()
public function loadUserByOAuthUserResponse(UserResponseInterface $response): UserInterface{@inheritdoc}
UserTracker class
class UserTracker extends ConnectionTracker UserTracker.php:16
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(EntityManagerInterface $entityManager, RequestStack $requestStack, AdvancedRouterInterface $router, Connections $connectionRepository)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\Security\Session
DynamicSessionStorage class
class DynamicSessionStorage extends NativeSessionStorage DynamicSessionStorage.php:7
DynamicSessionStorage::setOptions()
public function setOptions(array $options): voidDynamicSessionStorageFactory class
class DynamicSessionStorageFactory implements SessionStorageFactoryInterface DynamicSessionStorageFactory.php:27
DynamicSessionStorageFactory::__construct()
public function __construct(array $options = [], AbstractProxy|SessionHandlerInterface|null $handler = null, MetadataBag|null $metaBag = null, bool $secure = false)DynamicSessionStorageFactory::createStorage()
public function createStorage(?Request $request): SessionStorageInterfaceBase\Security\Voter
AccessVoter class
class AccessVoter extends Voter AccessVoter.php:17
const LAUNCH_ACCESS = "LAUNCH_ACCESS"const MAINTENANCE_ACCESS = "MAINTENANCE_ACCESS"const EXCEPTION_ACCESS = "EXCEPTION_ACCESS"const ANONYMOUS_ACCESS = "ANONYMOUS_ACCESS"const USER_ACCESS = "USER_ACCESS"const ADMIN_ACCESS = "ADMIN_ACCESS"
AccessVoter::__construct()
public function __construct(RouterInterface $router, ParameterBagInterface $parameterBag, LocalizerInterface $localizer, MaintenanceProviderInterface $maintenanceProvider, LauncherInterface $launcher)AdminVoter class
class AdminVoter extends Voter AdminVoter.php:10
const BACKEND = "BACKEND"
AdminVoter::__construct()
public function __construct(RouterInterface $router)ComplaintVoter class
class ComplaintVoter extends Voter ComplaintVoter.php:27
Who reads and answers a complaint (Base\Entity\User\Complaint).
COMPLAINT_READ / COMPLAINT_HANDLE, with the complaint as subject (or none: may this user read complaints at all). PermissionVoter alone cannot say it - it matches tags and ignores what they are about - so this voter adds the rule that matters:
- to read complaints at all: the reader role (ROLE_MODERATOR by default), or the permission tag COMPLAINT.READ / COMPLAINT.HANDLE given to a user or a group (Permission, GrantPermissionAdapter);
- 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 decides, not a list here) - moderators do not judge a moderator;
- nobody reads a complaint about themselves, except the top role (ROLE_SUPERADMIN by default), which reads them all: somebody has to read the ones about the top.
const READ = "COMPLAINT_READ"const HANDLE = "COMPLAINT_HANDLE"
ComplaintVoter::__construct()
public function __construct(readonly AccessDecisionManagerInterface $decisions, readonly RoleHierarchyInterface $hierarchy, readonly string $readerRole = "ROLE_MODERATOR", readonly string $topRole = "ROLE_SUPERADMIN")PermissionVoter class
class PermissionVoter extends Voter PermissionVoter.php:21
Custom fine-grained permission names, backed by Base\Entity\User\Permission and granted through group membership (or directly on the user). This is the "customizable by base or app classes" extensibility a plain ROLE_* hierarchy can't offer: base-bundle-admin's own SecurityVoter already delegates every permission string through isGranted(), so registering this voter is all that's needed for Actions::setPermission()/ Crud::setEntityPermission()/MenuItem::setPermission() to accept a custom tag like "ARTICLE.PUBLISH" alongside a plain ROLE_* string - no changes to base-bundle-admin required.
Base\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 implements RuntimeExtensionInterface BaseService.php:74
The facade of omnibase's services for an application's code (plan "omnibase agnostique", C9): kept, not deprecated, with BaseTrait. It is a lazy service - a ghost of this class until one of its methods reads a property - and the core injects it nowhere on a page's path any more: the core and the bundles ask the contracts (Base\Contract\Runtime) or the services they need.
What a contract answers, it asks the contract when the registry has it: isDebug(), isDevelopment(), getSecret()/getSalt() (Environment), isGranted() (Access), and BaseTrait's getParameterBag() and getEnvironment(). Those methods read no property of the object: called on the ghost, they build nothing.
BaseService::getContainer()
public function getContainer($name)BaseService::getAvailableServices()
public function getAvailableServices(): arrayBaseService::__construct()
public function __construct(KernelInterface $kernel, RequestStack $requestStack, FirewallMapInterface $firewallMap, Environment $twig, SluggerInterface $slugger, ManagerRegistry $doctrine, AuthorizationCheckerInterface $authorizationChecker, TokenStorageInterface $tokenStorage, CsrfTokenManagerInterface $csrfTokenManager, ParameterBagInterface $parameterBag, NotifierInterface $notifier, FormFactoryInterface $formFactory, LocalizerInterface $localizer, TradingInterface $tradingMarket, Obfuscator $obfuscator, SettingBag $settingBag, MediaService $mediaService, IconProvider $iconProvider, TranslatorInterface $translator, AdvancedRouterInterface $router, EntityHydratorInterface $entityHydrator, ClassMetadataManipulator $classMetadataManipulator, ?Profiler $profiler)BaseService::getRouteIndex()
public function getRouteIndex(): stringBaseService::getSite()
public function getSite()BaseService::getAdmin()
public function getAdmin()BaseService::getEmail()
public function getEmail()BaseService::getMeta()
public function getMeta(?string $locale = null): arrayBaseService::exec()
public function exec(string $command, array $arguments = [])- Throws
Exception
BaseService::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)BaseService::removeSession()
public function removeSession($name)BaseService::getSession()
public function getSession($name = null)BaseService::createForm()
public function createForm($type, $data = null, array $options = []): FormInterfaceBaseService::getLocale()
public function getLocale(?string $locale = null)BaseService::getSalt()
public function getSalt()BaseService::getSecret()
public function getSecret()BaseService::getProfiler()
public function getProfiler(): ?ProfilerBaseService::getProfile()
public function getProfile($response = null)BaseService::getParameter()
public function getParameter(string $name): array|bool|string|int|float|nullBaseService::hasParameter()
public function hasParameter(string $name): boolBaseService::setParameter()
public function setParameter(string $name, array|bool|string|int|float|null $value)BaseService::getAsset()
public function getAsset(string $url): stringBaseService::getRequest()
public function getRequest(): ?RequestBaseService::getCurrentRequest()
public function getCurrentRequest(): ?RequestBaseService::getRoute()
public function getRoute(?string $url): ?RouteBaseService::getCurrentRoute()
public function getCurrentRoute(): ?RouteBaseService::getRouteName()
public function getRouteName(?string $url): ?stringBaseService::getCurrentRouteName()
public function getCurrentRouteName(): ?stringBaseService::generateUrl()
public function generateUrl(string $routeName, array $routeParameters = []): stringBaseService::redirect()
public function redirect(string $urlOrRoute, array $routeParameters = [], int $state = 302, array $headers = []): RedirectResponseBaseService::redirectToRoute()
public function redirectToRoute(string $routeName, array $routeParameters = [], int $state = 302, array $headers = []): ?RedirectResponseBaseService::refresh()
public function refresh(?Request $request = null): RedirectResponseBaseService::isDevelopment()
public function isDevelopment()BaseService::isProduction()
public function isProduction()BaseService::isCli()
public function isCli()BaseService::isDebug()
public function isDebug()BaseService::isAdmin()
public function isAdmin()BaseService::isProfiler()
public function isProfiler()BaseService::setUserIdentifier()
public function setUserIdentifier(string $userIdentifier)Security container related methods
BaseService::isCsrfTokenValid()
public function isCsrfTokenValid(string $id, $tokenOrForm, ?Request $request = null, string $csrfFieldId = "_csrf_token"): bool- Throws
Exception
BaseService::getToken()
public function getToken()- Throws
Exception
BaseService::getUser()
public function getUser()- Throws
Exception
BaseService::isGranted()
public function isGranted($attribute, $subject = null): bool- Throws
Exception
BaseService::inDoctrine()
public function inDoctrine($entity): boolDoctrine related methods
BaseService::inDoctrineStack()
public function inDoctrineStack()BaseService::getOriginalEntityData()
public function getOriginalEntityData($eventOrEntity, bool $inDoctrineStack = false, bool $reopen = false)- Throws
Exception
BaseService::getOriginalEntity()
public function getOriginalEntity($eventOrEntity, bool $inDoctrineStack = false, bool $reopen = false)- 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:13
const USE_SHORT = Obfuscator::USE_SHORT
FileService::__construct()
public function __construct(Environment $twig, MediaRouter $router, ObfuscatorInterface $obfuscator, Storages $flysystem, ParameterBagInterface $parameterBag)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 glitchr/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 glitchr/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: glitchr/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 glitchr/omnishield is installed (GuardPass)
$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 glitchr/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 $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 $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 $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 $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::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 $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:32
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 fr.latoucheoriginale.www 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, protected readonly EntityManagerInterface $entityManager)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.
HotParameterBag class
class HotParameterBag extends HotParameters implements HotParameterBagInterface, ContainerBagInterface HotParameterBag.php:21
parameter_bag under Symfony: the container's parameters (Base\Service\ParameterBag)
with the settings stored in the database laid over them - Base\Service\HotParameters,
the Foundation's overlay, as DependencyInjection's ParameterBagInterface and
ContainerBagInterface (plan "omnibase agnostique", C9). It decorates parameter_bag
over Base\Service\ParameterBag; parameter_bag, the autowiring of
Base\Service\ParameterBagInterface (and of DependencyInjection's two interfaces) and
Runtime::parameters() are this one object.
Like the frozen bag the container's parameters are, it refuses clear() and remove(); add() takes the settings in (HotParameterBagSubscriber), set() writes into the $bag given.
HotParameterBag::__construct()
public function __construct(ParameterBag|Container $config, ?bool $enabled = null)$configthe container's parameters, or the container to read them from
HotParameterBag::clear()
public function clear(): voidHotParameterBag::remove()
public function remove(string $name): voidHotParameterBag::resolve()
public function resolve(): voidThe container's parameters are resolved already.
HotParameterBag::resolveValue()
public function resolveValue(mixed $value): mixedHotParameterBag::escapeValue()
public function escapeValue(mixed $value): mixedHotParameterBag::unescapeValue()
public function unescapeValue(mixed $value): mixedHotParameterBagInterface interface
interface HotParameterBagInterface extends ParameterBagInterface HotParameterBagInterface.php:14
The parameters with the settings stored in the database laid over them, as
DependencyInjection's ParameterBagInterface: what parameter_bag is under
Symfony (Base\Service\HotParameterBag over Base\Service\HotParameters, plan
"omnibase agnostique", C9).
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 ParameterBagInterface HotParameters.php:36
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.
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::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::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:19
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(protected readonly EntityManagerInterface $entityManager, protected readonly string $userClass = 'App\Entity\User')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:13
Launcher::__construct()
public function __construct(AdvancedRouterInterface $router, ParameterBagInterface $parameterBag, SettingBagInterface $settingBag, AuthorizationCheckerInterface $authorizationChecker, TokenStorageInterface $tokenStorage)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): boolLauncherInterface 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): boolLocalBusiness 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 $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:11
MaintenanceProvider::__construct()
public function __construct(AdvancedRouterInterface $router, SettingBagInterface $settingBag, AuthorizationCheckerInterface $authorizationChecker, ParameterBagInterface $parameterBag, LocalizerInterface $localizer, TokenStorageInterface $tokenStorage)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): boolMaintenanceProviderInterface 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:32
MediaService::__construct()
public function __construct(Environment $twig, 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)Obfuscator class
class Obfuscator extends AbstractLocalCache implements ObfuscatorInterface Obfuscator.php:13
Obfuscator::warmUp()
public function warmUp(string $cacheDir, ?string $buildDir = null): arrayObfuscator::__construct()
public function __construct(ParameterBagInterface $parameterBag, string $cacheDir, ?string $buildDir = null)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:10
Paginator::__construct()
public function __construct(RouterInterface $router, ParameterBagInterface $parameterBag)Paginator::paginate()
public function paginate(array|Query $query, int $page = 1, int $pageSize = 0, int $pageRange = 0): ?PaginationPaginatorInterface interface
interface PaginatorInterface PaginatorInterface.php:7
PaginatorInterface::paginate()
public function paginate(Query $query, int $page = 0, int $pageSize = 0, int $pageRange = 0)ParameterBag class
class ParameterBag extends DottedParameterBag implements SymfonyParameterBagInterface, ContainerBagInterface ParameterBag.php:27
The Symfony adapter of omnibase's Base\Service\ParameterBagInterface: the
container's parameters (it decorates parameter_bag), read by a dotted path
as Base\Service\DottedParameterBag reads any (plan "omnibase agnostique", C9),
and DependencyInjection's ParameterBagInterface and ContainerBagInterface as
well, for the code that types those.
It wraps Symfony's ContainerBag rather than extending it (since 4.0, P3):
ContainerBag is a FrozenParameterBag, whose set() and add() return never since
DependencyInjection 7, which PHP refuses against this class's void set(). What
the frozen bag forbade, this one forbids the same way (clear(), add(), remove()
throw its LogicException); what it read, it reads through the wrapped
ContainerBag. The settings stored in the database are laid over it by
Base\Service\HotParameterBag, which parameter_bag is.
ParameterBag::__construct()
public function __construct(Container $container)ParameterBag::set()
public function set(string $path, array|bool|string|int|float|UnitEnum|null $value, ?array &$bag = null): voidWrites into the $bag given; the container's parameters are frozen.
ParameterBag::clear()
public function clear(): voidParameterBag::add()
public function add(array $parameters): voidParameterBag::remove()
public function remove(string $name): voidParameterBag::resolve()
public function resolve(): voidThe container's parameters are resolved already.
ParameterBag::resolveValue()
public function resolveValue(mixed $value): mixedParameterBag::escapeValue()
public function escapeValue(mixed $value): mixedParameterBag::unescapeValue()
public function unescapeValue(mixed $value): mixedParameterBagInterface 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:17
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:11
Referrer::__toString()
public function __toString(): stringReferrer::__construct()
public function __construct(RequestStack $requestStack, AdvancedRouterInterface $router)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:47
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 Symfony's where there is one, else 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, ?RoleHierarchyInterface $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)
$reachableRolesthe roles some roles reach, where the host has no Symfony hierarchy (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:22
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, EntityManagerInterface $entityManager, Settings $settingRepository, LocalizerInterface $localizer, CacheItemPoolInterface $cache, string $environment)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:44
Documents signed through glitchr/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 glitchr/omnisign is installed (its bundle gives the gateways: omnisign.gateways.<name>); the entity is mapped only then too.
Signatures::__construct()
public function __construct(readonly EntityManagerInterface $entityManager, 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)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:16
Sitemapper::__construct()
public function __construct(Environment $twig, AttributeReader $attributeReader, AdvancedRouterInterface $router, LocalizerInterface $localizer, ?LoggerInterface $logger = null)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:38
Is what a visitor wrote spam? The classifier of glitchr/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.
SpamChecker::__construct()
public function __construct(protected RequestStack $requestStack, protected SettingBagInterface $settingBag, protected ParameterBagInterface $parameterBag, protected TranslatorInterface $translator, protected HttpClientInterface $client, protected bool $debug, protected ?FormGuard $guard = null, protected ?AdvancedRouterInterface $router = null, protected ?LoggerInterface $logger = null)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
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.
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:5
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. TradingPass 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:23
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, KernelInterface $kernel, ParameterBagInterface $parameterBag, ?string $politeness = null, array $applicationTexts = [])$applicationTextsthe keys the application wrote in its own translations/ directory, by domain and locale (ApplicationTextsPass; 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:24
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(protected EntityManagerInterface $entityManager, protected TrashBalls $trashBalls)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:24
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(protected EntityManagerInterface $entityManager, protected Revisions $revisions, protected int $maxRevisions = 5)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:13
WysiwygEnhancer::__construct()
public function __construct(Environment $twig, 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:14
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(EntityManagerInterface $entityManager)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 CollabTicketFactory.php:18
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.
Ticket format: base64url(payload) . "." . hex(hmac_sha256(payload, secret)). This format matches the relay's own verifyTicket() method exactly. To confirm this match, read the relay code first. Do not design each side separately.
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 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): arrayColorizeInterface 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
Pagination class
class Pagination implements PaginationInterface, Iterator, Countable Pagination.php:16
Pagination::__construct()
public function __construct(array|Query $arrayOrQuery, RouterInterface $router, ?string $parameterName = "page")Pagination::getCountQuery()
public function getCountQuery(Query $query, bool $bHint = true): QueryPagination::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()Pagination::getQuery()
public function getQuery(): ?QueryPagination::isQuery()
public function isQuery()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:8
AbstractSharingAdapter::__iconize()
public function __iconize(): ?arrayAbstractSharingAdapter::__construct()
public function __construct(Environment $twig)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:9
HeadingEnhancer::__construct()
public function __construct(EntityManagerInterface $entityManager, SluggerInterface $slugger)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.apfelschorlette.fr/... URL sits in the stored content forever, so viewing that same article on beta.m.apfelschorlette.fr (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 "apfelschorlette.fr" + "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:25
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(protected readonly EntityManagerInterface $entityManager, protected readonly PushSubscriptions $repository, protected readonly ?LoggerInterface $logger = null, protected readonly ?string $publicKey = null, protected readonly ?string $privateKey = null, protected readonly ?string $subject = null)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:22
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, protected readonly ?Environment $twig = 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\Subscriber
AnalyticsSubscriber class
class AnalyticsSubscriber implements EventSubscriberInterface AnalyticsSubscriber.php:18
AnalyticsSubscriber::__construct()
public function __construct(TokenStorageInterface $tokenStorage, AdvancedRouterInterface $router, TranslatorInterface $translator, Environment $twig, Users $userRepository, ?GaService $googleAnalyticsService = null)AnalyticsSubscriber::getSubscribedEvents()
public static function getSubscribedEvents(): arrayAnalyticsSubscriber::onUserRequest()
public function onUserRequest(RequestEvent $event)AnalyticsSubscriber::onGoogleAnalyticsRequest()
public function onGoogleAnalyticsRequest(RequestEvent $event)DemoBackOfficeSubscriber class
class DemoBackOfficeSubscriber implements EventSubscriberInterface DemoBackOfficeSubscriber.php:42
The back office in a demonstration (registered in the demo environment
only): open to nobody with a password everyone knows. Two tiers, a secret
each:
- the super-administrator, never a demonstration account, and never signed in with the password the fixtures gave it ("glitchr" / "glitchr"): its password is base.demo.superadmin_password (DEMO_SUPERADMIN_PASSWORD by default);
- an account that opens the back office (base.demo.admin_roles - the shop's, the practice's, declared as a demonstration account or not): its password is base.demo.admin_password (DEMO_ADMIN_PASSWORD by default), the one given to whoever is shown the back office.
What is typed is compared with the secret, the password stored in the database is not looked at. While a tier's secret is not set, its accounts cannot sign in at all, by any means.
And no other account opens the back office, whatever its roles give it elsewhere (the kitchen's ROLE_STAFF reading the orders under /admin): a page of it answers 403 to anyone signed in below base.demo.admin_roles.
DemoBackOfficeSubscriber::__construct()
public function __construct(readonly DemoAccountRegistry $accounts, readonly ?string $password = null, readonly ?string $adminPassword = null, readonly ?AdvancedRouterInterface $router = null, readonly ?TokenStorageInterface $tokens = null)DemoBackOfficeSubscriber::getSubscribedEvents()
public static function getSubscribedEvents(): arrayDemoBackOfficeSubscriber::onRequest()
public function onRequest(RequestEvent $event): voidDemoBackOfficeSubscriber::onCheckPassport()
public function onCheckPassport(CheckPassportEvent $event): voidDemoSubscriber class
class DemoSubscriber implements EventSubscriberInterface DemoSubscriber.php:24
Two of the demonstration's safeguards (registered in the demo
environment only, config/services/demo.php):
- no page of a demonstration is indexed:
X-Robots-Tag: noindex, nofollowon every response; - no e-mail leaves it. Every message is refused where the mailer hands it over - as it is queued and as it is sent - whatever transport MAILER_DSN names: a visitor signed in as "patient" types any address in a form, and a demonstration must not write to it. What would have gone is logged (recipients and subject, not the body).
DemoSubscriber::__construct()
public function __construct(readonly ?LoggerInterface $logger = null)DemoSubscriber::getSubscribedEvents()
public static function getSubscribedEvents(): arrayDemoSubscriber::onResponse()
public function onResponse(ResponseEvent $event): voidDemoSubscriber::onMessage()
public function onMessage(MessageEvent $event): voidEntityDispatcherFlushSubscriber class
final class EntityDispatcherFlushSubscriber implements EventSubscriberInterface EntityDispatcherFlushSubscriber.php:25
Flushes what the entity dispatchers' listeners changed (a thread published by its "publishable" event, a user's welcome state...), once the flush that raised those events is completely over: when the response goes out, when a command ends, after each message a worker handles. See AbstractEventDispatcher::$flushPending for why not from postFlush.
The dispatchers built in this process alone (AbstractEventDispatcher::live()): one never built has nothing pending, and building it then - from the tagged services, at the end of every command - required its file from the container's folder, which bin/console cache:clear had just removed: the command died at console.terminate ("Failed opening required .../getNewsletterEventDispatcherService.php").
EntityDispatcherFlushSubscriber::getSubscribedEvents()
public static function getSubscribedEvents(): arrayEntityDispatcherFlushSubscriber::onResponse()
public function onResponse(ResponseEvent $event): voidEntityDispatcherFlushSubscriber::flush()
public function flush(): voidFlashBagSubscriber class
class FlashBagSubscriber implements EventSubscriberInterface FlashBagSubscriber.php:11
FlashBagSubscriber::getSubscribedEvents()
public static function getSubscribedEvents(): arrayFlashBagSubscriber::onKernelResponse()
public function onKernelResponse(ResponseEvent $event)HotParameterBagSubscriber class
class HotParameterBagSubscriber implements EventSubscriberInterface HotParameterBagSubscriber.php:14
HotParameterBagSubscriber::__construct()
public function __construct($parameterBag, SettingBagInterface $settingBag)HotParameterBagSubscriber::getSubscribedEvents()
public static function getSubscribedEvents(): arrayHotParameterBagSubscriber::onRequest()
public function onRequest($event)IntegritySubscriber class
class IntegritySubscriber implements EventSubscriberInterface IntegritySubscriber.php:42
Registered by no configuration, on purpose: as written it would open a session on every main
request, run bin/console cache:clear inside a web request on a Doctrine TypeError, and sign
the user out (and clear the remember-me cookie) whenever one of its checks fails. A site that
wants these checks registers it itself, knowing that.
const DEFAULT_PRIORITY = 7
IntegritySubscriber::__construct()
public function __construct(TokenStorageInterface $tokenStorage, RequestStack $requestStack, ManagerRegistry $doctrine, AdvancedRouterInterface $router, ReferrerInterface $referrer, string $projectDir, ?string $secret = null)IntegritySubscriber::getSubscribedEvents()
public static function getSubscribedEvents(): arrayIntegritySubscriber::checkCacheReady()
public function checkCacheReady()IntegritySubscriber::onCommand()
public function onCommand(ConsoleEvent $event)IntegritySubscriber::onEarlyKernelRequest()
public function onEarlyKernelRequest()IntegritySubscriber::onException()
public function onException(ExceptionEvent $event)IntegritySubscriber::onKernelRequest()
public function onKernelRequest(RequestEvent $event)IntegritySubscriber::checkUserIntegrity()
public function checkUserIntegrity()IntegritySubscriber::checkDoctrineIntegrity()
public function checkDoctrineIntegrity()IntegritySubscriber::checkSecretIntegrity()
public function checkSecretIntegrity()IsGrantedSubscriber class
class IsGrantedSubscriber implements EventSubscriberInterface IsGrantedSubscriber.php:21
IsGrantedSubscriber::__construct()
public function __construct(AttributeReader $attributeReader, ?AuthorizationCheckerInterface $authorizationChecker = null)IsGrantedSubscriber::onKernelControllerArguments()
public function onKernelControllerArguments(KernelEvent $event)IsGrantedSubscriber::getSubscribedEvents()
public static function getSubscribedEvents(): arrayLocalizerSubscriber class
class LocalizerSubscriber implements EventSubscriberInterface LocalizerSubscriber.php:20
const __LANG_IDENTIFIER__ = "LANG"const __TIMEZONE_IDENTIFIER__ = "TIMEZONE"const DISPLAYED_LOCALE = "_base_displayed_locale"The request attribute holding the language a page was shown in, for the response to remember.
const REQUEST_DEFAULT_LANGUAGE = "en-us,en;q=0.5"What Symfony's Request::create() says when it is told no language.
LocalizerSubscriber::__construct()
public function __construct(LocalizerInterface $localizer, AdvancedRouterInterface $router, TokenStorageInterface $tokenStorage)LocalizerSubscriber::getSubscribedEvents()
public static function getSubscribedEvents(): arrayLocalizerSubscriber::onKernelResponse()
public function onKernelResponse(ResponseEvent $event): voidThe language the page was shown in, remembered for the next one (LANG).
LocalizerSubscriber::onSwitchUser()
public function onSwitchUser(SwitchUserEvent $event): voidLocalizerSubscriber::onKernelRequest()
public function onKernelRequest(RequestEvent $event)The language of a page: its address (a route of one language, "/en/..." or "/datenschutz"), else the visitor's own choice or the language their last page was shown in (the LANG cookie, which the response keeps up to date), else a signed-in member's, else - on a first visit only - the browser's (Accept-Language), else the site's.
The browser's language used to be read on every page from the USER/INFO cookie, which the site's script writes after the first one: a visitor who arrived on a French page, or chose French, was moved to their browser's language from the second page on.
MailTrapSubscriber class
class MailTrapSubscriber implements EventSubscriberInterface MailTrapSubscriber.php:19
Stops mail at the last possible moment when the trap is armed.
MessageEvent fires twice for a queued message: once as it is handed to Messenger (isQueued() true) and again when the worker actually sends it. Only the second one is intercepted, and that is the whole point - trapping at queue time would refuse mail that a released trap should still deliver, while trapping at send time means a message queued before the incident is still caught on its way out.
MailTrapSubscriber::__construct()
public function __construct(readonly MailTrap $trap)MailTrapSubscriber::getSubscribedEvents()
public static function getSubscribedEvents(): arrayMailTrapSubscriber::onMessage()
public function onMessage(MessageEvent $event): voidNewDeviceSubscriber class
class NewDeviceSubscriber implements EventSubscriberInterface NewDeviceSubscriber.php:30
Reacts to an account being signed into from a browser it has not been signed into before: tells the user by email (administrator's switch), and on an account with no second factor, flags the session so the next page offers - once, optionally - to set up a one-time code (SecurityEnrolmentSubscriber, Base\Controller\Action\Settings\Enrolment).
"Browser" here means what UserTracker already means by it: a Connection, keyed by the long-lived id it keeps in a cookie. A sign-in that has to create one is a sign-in from somewhere new. The account's very first sign-in creates one too, and there is nothing useful to warn about then - the person is holding the device in their hand - so the mail goes out only once a second browser appears.
Nothing here blocks the login. This is a notice after the fact, not a challenge; the administrator's switch decides whether it is sent at all.
NewDeviceSubscriber::__construct()
public function __construct(SecurityPolicy $securityPolicy, UserTracker $userTracker, Connections $connectionRepository)NewDeviceSubscriber::getSubscribedEvents()
public static function getSubscribedEvents(): arrayNewDeviceSubscriber::onLoginSuccess()
public function onLoginSuccess(LoginSuccessEvent $event): voidNotifierSubscriber class
class NotifierSubscriber implements EventSubscriberInterface NotifierSubscriber.php:15
NotifierSubscriber::__construct()
public function __construct(Notifier $notifier, AuthorizationCheckerInterface $authorizationChecker, ParameterBagInterface $parameterBag, string $debug)NotifierSubscriber::getSubscribedEvents()
public static function getSubscribedEvents(): arrayNotifierSubscriber::onKernelRequest()
public function onKernelRequest(RequestEvent $event)PageViewSubscriber class
class PageViewSubscriber implements EventSubscriberInterface PageViewSubscriber.php:35
Records one Base\Service\Analytics::track() call per trackable request.
Runs on kernel.terminate (after the response has already been sent) so the counter writes never add latency to what the visitor is waiting on.
Not to be confused with the pre-existing Base\Subscriber\AnalyticsSubscriber (an unrelated, currently-inert - gated behind the now-dead isAdmin() check - "online users" heartbeat + Google Analytics live-stats puller). That one is untouched by this; naming this class PageViewSubscriber specifically to avoid colliding with it.
"Trackable" is deliberately inferred from the RESPONSE rather than matched against a path allow/deny list: a successful, GET, text/html response is a real page render regardless of whether it arrived via a normal navigation or one of transparentJS's AJAX SPA-swap fetches (both return full HTML documents with that content type) - excluding XHR requests outright would have undercounted most of this app's actual navigation, since in-app browsing mostly happens through those swaps, not full page loads. $excludedPrefixes is the one thing that IS explicitly configured (bound in services.php) - keeps admin/API/asset traffic out of what's meant to be public-site analytics.
PageViewSubscriber::__construct()
public function __construct(readonly Analytics $analytics, readonly Security $security, readonly array $excludedPrefixes = ["/admin", "/_", "/api"])PageViewSubscriber::getSubscribedEvents()
public static function getSubscribedEvents(): arrayPageViewSubscriber::onKernelTerminate()
public function onKernelTerminate(TerminateEvent $event): voidPasswordChangeSubscriber class
class PasswordChangeSubscriber implements EventSubscriberInterface PasswordChangeSubscriber.php:21
An account made with a password it did not choose (user:create) carries a "change-password" token: until its owner has chosen one, every page sends them to security_changePassword.
As narrow as SecurityEnrolmentSubscriber, for the same reason: only a plain top-level GET of an HTML page is turned back, never the pages needed to answer - the change itself, logging out, the profiler.
const TOKEN = 'change-password'
PasswordChangeSubscriber::__construct()
public function __construct(Security $security, UrlGeneratorInterface $router)PasswordChangeSubscriber::getSubscribedEvents()
public static function getSubscribedEvents(): arrayPasswordChangeSubscriber::onKernelRequest()
public function onKernelRequest(RequestEvent $event): voidProfilerSubscriber class
class ProfilerSubscriber implements EventSubscriberInterface ProfilerSubscriber.php:13
ProfilerSubscriber::__construct()
public function __construct(AdvancedRouterInterface $router)ProfilerSubscriber::getSubscribedEvents()
public static function getSubscribedEvents(): arrayProfilerSubscriber::onKernelRequest()
public function onKernelRequest(RequestEvent $event)ProfilerSubscriber::onKernelResponse()
public function onKernelResponse(ResponseEvent $event)RedirectionSubscriber class
class RedirectionSubscriber implements EventSubscriberInterface RedirectionSubscriber.php:21
A page that is not found is looked up in the redirections (Base\Entity\Layout\Redirection) before the 404 is answered: the old addresses of a site taken over lead to its new pages.
Only then - no route matched, or a controller found no record: a page the site answers is never redirected, and costs no query. Ahead of the listeners that log and render the error (priority 16), so a redirected address is not reported as an error.
RedirectionSubscriber::__construct()
public function __construct(readonly Redirections $redirections)RedirectionSubscriber::getSubscribedEvents()
public static function getSubscribedEvents(): arrayRedirectionSubscriber::onKernelException()
public function onKernelException(ExceptionEvent $event): voidReferrerSubscriber class
class ReferrerSubscriber implements EventSubscriberInterface ReferrerSubscriber.php:29
Where a visitor comes back to after signing in: the last page they read.
Only a page is remembered - a GET answered 2xx with an HTML document, asked as a document (Sec-Fetch-Dest: document or iframe) or by flowjs's navigation swap (an XHR whose answer is a whole HTML page, as omnibase's PageViewSubscriber counts it). An image, a stylesheet, a feed, a JSON or an HTML fragment fetched by a script is not: an avatar served by a controller used to be the last thing asked before the sign-in, and the sign-in sent the visitor to that SVG (seen on chapaland). Nor is a speculative fetch, a route of base.access_restriction.route_exceptions (the sign-in pages themselves...) or a secured page.
ReferrerSubscriber::__construct()
public function __construct(protected ReferrerInterface $referrer, protected AdvancedRouterInterface $router, protected ParameterBagInterface $parameterBag)ReferrerSubscriber::getSubscribedEvents()
public static function getSubscribedEvents(): arrayReferrerSubscriber::getCurrentRouteName()
public function getCurrentRouteName($event)ReferrerSubscriber::isException()
public function isException(?string $route): boolReferrerSubscriber::isPageNavigation()
public static function isPageNavigation(Request $request, Response $response): boolWhether this request and its answer are a page the visitor read.
ReferrerSubscriber::onKernelRequest()
public function onKernelRequest(RequestEvent $event)ReferrerSubscriber::onKernelResponse()
public function onKernelResponse(ResponseEvent $event): voidRequestScopedStateSubscriber class
class RequestScopedStateSubscriber implements EventSubscriberInterface, ResetInterface RequestScopedStateSubscriber.php:32
Clears static state that is really request-scoped, for processes that outlive a request: FrankenPHP worker mode and messenger consumers.
Under FPM, or FrankenPHP classic mode, statics die with the request anyway and both hooks below are no-ops on already-empty state.
Two hooks, because neither covers every mode on its own:
- kernel.reset (reset()): the services_resetter runs between requests handled by the SAME kernel, and messenger resets services between messages. But under FRANKENPHP_RESET_KERNEL=1 the kernel is cloned after each request: Kernel::__clone() sets resetServices back to false and the clone boots a fresh container, so the resetter never runs at all - while class statics survive the clone untouched.
- kernel.request, main request only, top priority: fires in every mode, cloned kernel included, and ahead of LocalizerSubscriber (priority 8) and anything else that reads this state.
const PRIORITY = 4096
RequestScopedStateSubscriber::getSubscribedEvents()
public static function getSubscribedEvents(): arrayRequestScopedStateSubscriber::onKernelRequest()
public function onKernelRequest(RequestEvent $event): voidRequestScopedStateSubscriber::reset()
public function reset(): voidRouterSubscriber class
class RouterSubscriber implements EventSubscriberInterface RouterSubscriber.php:15
RouterSubscriber::__construct()
public function __construct(AuthorizationCheckerInterface $authorizationChecker, RouterInterface $router, ParameterBagInterface $parameterBag)RouterSubscriber::getSubscribedEvents()
public static function getSubscribedEvents(): arrayRouterSubscriber::onCommand()
public function onCommand(ConsoleEvent $event): voidRouterSubscriber::onKernelRequest()
public function onKernelRequest(RequestEvent $event)SecondLevelCacheConsoleSubscriber class
class SecondLevelCacheConsoleSubscriber implements EventSubscriberInterface SecondLevelCacheConsoleSubscriber.php:18
Doctrine's second-level cache emptied after a command that rewrites the database behind the ORM's back: doctrine:fixtures:load purges the tables with DELETE / TRUNCATE and numbers the new rows from 1 again, so the cache went on answering yesterday's entity for today's id (a product under another one's name, a deleted page still shown) until it expired.
const COMMANDS = ['doctrine:fixtures:load', 'doctrine:schema:drop', 'doctrine:schema:create', 'doctrine:schema:update', 'doctrine:database:drop', 'doctrine:database:import', …The commands after which the cached entities may no longer be the database's.
SecondLevelCacheConsoleSubscriber::__construct()
public function __construct(readonly ?ManagerRegistry $doctrine = null)SecondLevelCacheConsoleSubscriber::getSubscribedEvents()
public static function getSubscribedEvents(): arraySecondLevelCacheConsoleSubscriber::onTerminate()
public function onTerminate(ConsoleTerminateEvent $event): voidSecondLevelCacheConsoleSubscriber::evict()
public function evict(): intEvery region of every entity manager that has a second-level cache; the number of managers emptied.
SecurityEnrolmentSubscriber class
class SecurityEnrolmentSubscriber implements EventSubscriberInterface SecurityEnrolmentSubscriber.php:32
Sends a signed-in user to the enrolment prompt once, when a second factor is mandatory for this account - the administrator made it so for everyone, or the application requires it of one of the account's roles (base.security.two_factor.required_roles) - and the account has none.
The redirect is deliberately narrow. It only ever happens on a plain top-level GET of an HTML page, so nothing in-flight is interrupted: a form post lands where it was going, an XHR gets its JSON, a download downloads. And it never fires on the pages the user needs in order to *answer* it - the settings pages, the login and logout paths, the two-factor check itself. Getting that list wrong would lock the account out of the site with no way back in, so the exemptions err generously.
The rule is Base\Auth\EnrolmentPrompt's, framework-free (step R29 of the audit "lesringostars face au master plan"): omnibridge/laravel's enrolment middleware asks it too.
SecurityEnrolmentSubscriber::__construct()
public function __construct(SecurityPolicy $securityPolicy, Security $security, UrlGeneratorInterface $router)SecurityEnrolmentSubscriber::getSubscribedEvents()
public static function getSubscribedEvents(): arraySecurityEnrolmentSubscriber::onKernelRequest()
public function onKernelRequest(RequestEvent $event): voidSecuritySubscriber class
class SecuritySubscriber implements EventSubscriberInterface SecuritySubscriber.php:40
SecuritySubscriber::__construct()
public function __construct(UserRepository $userRepository, AuthorizationChecker $authorizationChecker, TokenStorageInterface $tokenStorage, RequestStack $requestStack, ReferrerInterface $referrer, SettingBagInterface $settingBag, Localizer $localizer, AdvancedRouterInterface $router, ParameterBagInterface $parameterBag, MaintenanceProviderInterface $maintenanceProvider, LauncherInterface $launcher, ?Profiler $profiler = null, protected ?Tokens $tokens = null)SecuritySubscriber::getSubscribedEvents()
public static function getSubscribedEvents(): arraySecuritySubscriber::onAccessRequest()
public function onAccessRequest(?RequestEvent $event = null): boolSecuritySubscriber::onKernelRequest()
public function onKernelRequest(RequestEvent $event)SecuritySubscriber::onKernelResponse()
public function onKernelResponse(ResponseEvent $event)SecuritySubscriber::onLoginFailure()
public function onLoginFailure(LoginFailureEvent $event)SecuritySubscriber::onLoginSuccess()
public function onLoginSuccess(LoginSuccessEvent $event)SecuritySubscriber::onLogout()
public function onLogout(LogoutEvent $event)SecuritySubscriber::onMaintenanceRequest()
public function onMaintenanceRequest(RequestEvent $event)SecuritySubscriber::onLaunchRequest()
public function onLaunchRequest(RequestEvent $event)TemplatedEmailSubjectSubscriber class
class TemplatedEmailSubjectSubscriber implements EventSubscriberInterface TemplatedEmailSubjectSubscriber.php:26
A TemplatedEmail's subject written in its template:
{% block subject %}{{ 'booking.email.subject'|trans({date: date}) }}{% endblock %}
omnibase's e-mail templates name their subject that way, and a notification reads it. A plain TemplatedEmail sent through Symfony's mailer did not: the block was rendered in the body and the message left without a subject. Here the block is rendered with the e-mail's context and becomes the subject, before the body is rendered.
A subject set in PHP (->subject('...')) is kept: it is also handed to the
template as the subject variable, which omnibase's frame prints instead
of the block.
TemplatedEmailSubjectSubscriber::__construct()
public function __construct(readonly Environment $twig)TemplatedEmailSubjectSubscriber::getSubscribedEvents()
public static function getSubscribedEvents(): arrayTemplatedEmailSubjectSubscriber::onMessage()
public function onMessage(MessageEvent $event): voidTwigSubscriber class
class TwigSubscriber implements EventSubscriberInterface TwigSubscriber.php:18
const INJECT = '_omnibase_inject'The request attribute (a route default) that keeps a response as it was rendered.
TwigSubscriber::__construct()
public function __construct(HtmlTagRenderer $htmlTagRenderer, WebpackTagRenderer $webpackTagRenderer, AuthorizationCheckerInterface $authorizationChecker, ParameterBagInterface $parameterBag, AdvancedRouterInterface $router)TwigSubscriber::getSubscribedEvents()
public static function getSubscribedEvents(): arrayTwigSubscriber::onKernelException()
public function onKernelException(RequestEvent $event)TwigSubscriber::onKernelRequest()
public function onKernelRequest(RequestEvent $event)TwigSubscriber::onKernelResponse()
public function onKernelResponse(ResponseEvent $event)- Throws
Exception
ValidCacheSubscriber class
class ValidCacheSubscriber implements EventSubscriberInterface ValidCacheSubscriber.php:17
Marks the bundle cache as valid early in the request cycle. Sole survivor of the former EagerSubscriber: its eager-construction duty is obsolete now that AttributeReader's constructor is metadata-free (the heavy precompute moved to AttributeCacheWarmer) and BaseTrait statics resolve lazily through the base.runtime locator.
ValidCacheSubscriber::getSubscribedEvents()
public static function getSubscribedEvents(): arrayValidCacheSubscriber::onValidCache()
public function onValidCache(KernelEvent $e)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(?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:54
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).
An accessor whose answer a contract gives asks the contract first, so it
answers wherever the registry is filled, Symfony or not: getParameterBag()
(Runtime::parameters()), getEnvironment() (Runtime::environment()->name()).
The others hand out the framework's services, typed as they always were;
they 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): BaseService, which kept it
before and extends it, is no longer loaded by an accessor.
BaseTrait::getAttributeReader()
public static function getAttributeReader(): ?AttributeReaderBaseTrait::getService()
public static function getService(): ?BaseServiceBaseTrait::getSettingBag()
public static function getSettingBag(): ?SettingBagBaseTrait::getDoctrine()
public static function getDoctrine(): ?ManagerRegistryBaseTrait::getObjectManager()
public static function getObjectManager(mixed $entity): ?ObjectManagerBaseTrait::getEntityManager()
public static function getEntityManager(bool $reopen = false): ?EntityManagerInterfaceBaseTrait::getRepository()
public static function getRepository(mixed $object = null): ?ObjectRepositoryBaseTrait::isEntity()
public static function isEntity(mixed $entityOrClassOrMetadata): ?boolBaseTrait::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::getClassMetadataManipulator()
public static function getClassMetadataManipulator(): ?ClassMetadataManipulatorBaseTrait::getTokenStorage()
public static function getTokenStorage(): ?TokenStorageInterfaceBaseTrait::getRequestStack()
public static function getRequestStack(): ?RequestStackBaseTrait::getEntityHydrator()
public static function getEntityHydrator(): ?EntityHydratorBaseTrait::getMediaService()
public static function getMediaService(): ?MediaServiceBaseTrait::getObfuscator()
public static function getObfuscator(): ?ObfuscatorBaseTrait::getIconProvider()
public static function getIconProvider(): ?IconProviderBaseTrait::getLocalizer()
public static function getLocalizer(): ?LocalizerInterfaceBaseTrait::getRouter()
public static function getRouter(): ?AdvancedRouterInterfaceBaseTrait::getFirewallMap()
public static function getFirewallMap(): ?FirewallMapInterfaceBaseTrait::getTwig()
public static function getTwig(): ?EnvironmentBaseTrait::getNotifier()
public static function getNotifier(): ?BaseNotifierInterfaceBaseTrait::getTranslator()
public static function getTranslator(): ?TranslatorInterfaceBaseTrait::getSlugger()
public static function getSlugger(): ?SluggerInterfaceBaseTrait::getTrading()
public static function getTrading(): ?TradingInterfaceBaseTrait::getParameterBag()
public static function getParameterBag(string $key = "", ?array $bag = null)CacheClearTrait trait
trait CacheClearTrait CacheClearTrait.php:13
CacheableTrait trait
trait CacheableTrait CacheableTrait.php:5
CacheableTrait::__toKey()
public function __toKey(mixed ...$variadic): stringCacheableTrait::__toKeyTTL()
public function __toKeyTTL(): ?intCacheableTrait::__toKeyTags()
public function __toKeyTags(): arrayProxyTrait 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:11
SimpleCacheTrait::__construct()
public function __construct(string $cacheDir, ?string $buildDir = null)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
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 Environment.php:17
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:11
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:25
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::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 (moved here from the apps' App\Twig\ImageExtension).
DemoTwigExtension class
class DemoTwigExtension extends AbstractExtension DemoTwigExtension.php:25
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 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).
DeployVersionExtension class
final class DeployVersionExtension extends AbstractExtension DeployVersionExtension.php:33
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:29
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): null|Type|arrayEnumTwigExtension::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:43
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|RecipientInterface $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. 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.
- Throws
RuntimeError
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.
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:13
HtmlTwigExtension::__construct()
public function __construct(HtmlTagRenderer $htmlTagRenderer, WysiwygEnhancerInterface $wysiwygEnhancer, EditorEnhancerInterface $editorEnhancer)HtmlTwigExtension::renderWysiwyg()
public function renderWysiwyg(?string $htmlOrJson, array $options = [])The pipeline of |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:19
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)$currentwhether an address is the page's own; none is without it
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:17
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:26
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:11
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 = []): ?stringPaginatorTwigExtension::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:32
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:12
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): string- Throws
RuntimeError
TradingTwigExtension::applyCurrencyRate()
public function applyCurrencyRate($amount, string $currency, array $attrs = [], ?string $locale = null): ?floatTranslatorTwigExtension 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:14
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): stringBase\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:17
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(?string $max_size = null, array $mime_types = [], ?array $groups = null, mixed $payload = null)$max_sizeHuman readable string ("2M", "500K", etc.) or null
$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
UniqueEntity class
class UniqueEntity extends ConstraintEntity UniqueEntity.php:14
Constraint for UniqueEntity validation.
const NOT_UNIQUE_ERROR = '23bd9dbf-6b9b-41cd-a99e-4844bcf3077f'public string $service = 'doctrine.orm.validator.unique'public ?string $em = 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:17
UniqueEntityValidator::validate()
public function validate($value, Constraint $constraint): void- Throws
Exception