Configuring Doctrine Behaviors

← Configuring Doctrine Behaviors

Ashterix

docs: Doctrine section with Doctrine Behaviors and Doctrine Helper (uk + en)

en/docs/doctrine/doctrine-behaviors/config.md new file +92 āˆ’0

1 + # Configuring Doctrine Behaviors
2 +
3 + The bundle has no configuration section of its own. Its behavior is changed with container parameters and by replacing two providers.
4 +
5 + ## Parameters
6 +
7 + Set the parameters you need in `config/services.yaml` (application values take precedence over the bundle's):
8 +
9 + ```yaml
10 + # config/services.yaml
11 + parameters:
12 + doctrine_behaviors_blameable_user_entity: App\Entity\User
13 + doctrine_behaviors_timestampable_date_field_type: datetimetz
14 + doctrine_behaviors_translatable_fetch_mode: LAZY
15 + doctrine_behaviors_translation_fetch_mode: LAZY
16 + ```
17 +
18 + | Parameter | Default | What it changes |
19 + | --- | --- | --- |
20 + | `doctrine_behaviors_blameable_user_entity` | `null` | The user entity class. If set and the class exists, `createdBy` / `updatedBy` / `deletedBy` are mapped as `ManyToOne` to this entity; otherwise as string columns. See [Blameable](/docs/doctrine/doctrine-behaviors/blameable). |
21 + | `doctrine_behaviors_timestampable_date_field_type` | `datetime` | Doctrine type of `createdAt` / `updatedAt`. See [Timestampable](/docs/doctrine/doctrine-behaviors/timestampable). |
22 + | `doctrine_behaviors_translatable_fetch_mode` | `LAZY` | Fetch strategy of the translatable entity's `translations` collection: `LAZY`, `EAGER`, `EXTRA_LAZY`. |
23 + | `doctrine_behaviors_translation_fetch_mode` | `LAZY` | Fetch strategy of the translation entity's `translatable` relation; same values. |
24 +
25 + Any other fetch mode value is treated as `LAZY`. More in [Translatable](/docs/doctrine/doctrine-behaviors/translatable).
26 +
27 + ## User provider
28 +
29 + Blameable takes the current user from `Ufo\DoctrineBehaviors\Contract\Provider\UserProviderInterface`. The default implementation `Ufo\DoctrineBehaviors\Provider\UserProvider` returns `getUser()` from the Symfony Security token (if `doctrine_behaviors_blameable_user_entity` is set — only an instance of that class), or `null` when there is no token.
30 +
31 + A custom implementation — for example, to store the user identifier as a string:
32 +
33 + ```php
34 + namespace App\Doctrine;
35 +
36 + use Symfony\Bundle\SecurityBundle\Security;
37 + use Ufo\DoctrineBehaviors\Contract\Provider\UserProviderInterface;
38 +
39 + final class UserIdentifierProvider implements UserProviderInterface
40 + {
41 + public function __construct(private Security $security) {}
42 +
43 + public function provideUser(): ?string
44 + {
45 + return $this->security->getUser()?->getUserIdentifier();
46 + }
47 +
48 + public function provideUserEntity(): ?string
49 + {
50 + return null;
51 + }
52 + }
53 + ```
54 +
55 + ```yaml
56 + # config/services.yaml
57 + services:
58 + Ufo\DoctrineBehaviors\Contract\Provider\UserProviderInterface: '@App\Doctrine\UserIdentifierProvider'
59 + ```
60 +
61 + If `provideUser()` returns `null`, Blameable changes nothing.
62 +
63 + ## Locale provider
64 +
65 + Translatable takes locales from `Ufo\DoctrineBehaviors\Contract\Provider\LocaleProviderInterface`:
66 +
67 + * `provideCurrentLocale()` — the current request's locale, `null` without a request; if the request locale is empty — the `TranslatorInterface` locale;
68 + * `provideFallbackLocale()` — the request's default locale; without a request — the `locale` parameter, and if it is missing — `kernel.default_locale`.
69 +
70 + It is replaced the same way as the user provider:
71 +
72 + ```yaml
73 + services:
74 + Ufo\DoctrineBehaviors\Contract\Provider\LocaleProviderInterface: '@App\Doctrine\MyLocaleProvider'
75 + ```
76 +
77 + ## Doctrine listeners
78 +
79 + Each behavior is a separate class in `Ufo\DoctrineBehaviors\EventSubscriber`, registered with the `#[AsDoctrineListener]` attribute with priority `500` for the `default` connection:
80 +
81 + | Listener | Events |
82 + | --- | --- |
83 + | `TimestampableEventSubscriber` | `loadClassMetadata` |
84 + | `BlameableEventSubscriber` | `loadClassMetadata`, `prePersist`, `preUpdate`, `preRemove` |
85 + | `SoftDeletableEventSubscriber` | `loadClassMetadata`, `onFlush` |
86 + | `TranslatableEventSubscriber` | `loadClassMetadata`, `postLoad`, `prePersist` |
87 + | `SluggableEventSubscriber` | `loadClassMetadata`, `prePersist`, `preUpdate` |
88 + | `TreeEventSubscriber` | `loadClassMetadata` |
89 + | `UuidableEventSubscriber` | `loadClassMetadata`, `prePersist` |
90 + | `LoggableEventSubscriber` | `postPersist`, `postUpdate`, `preRemove` |
91 +
92 + The bundle's services are public and autowired, so any listener can be redefined in `config/services.yaml` under the same class id.