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

Configuring Doctrine Behaviors

The bundle has no configuration section of its own. Its behavior is changed with container parameters and by replacing two providers.

Parameters

Set the parameters you need in config/services.yaml (application values take precedence over the bundle's):

# config/services.yaml
parameters:
    doctrine_behaviors_blameable_user_entity: App\Entity\User
    doctrine_behaviors_timestampable_date_field_type: datetimetz
    doctrine_behaviors_translatable_fetch_mode: LAZY
    doctrine_behaviors_translation_fetch_mode: LAZY
Parameter Default What it changes
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.
doctrine_behaviors_timestampable_date_field_type datetime Doctrine type of createdAt / updatedAt. See Timestampable.
doctrine_behaviors_translatable_fetch_mode LAZY Fetch strategy of the translatable entity's translations collection: LAZY, EAGER, EXTRA_LAZY.
doctrine_behaviors_translation_fetch_mode LAZY Fetch strategy of the translation entity's translatable relation; same values.

Any other fetch mode value is treated as LAZY. More in Translatable.

User provider

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.

A custom implementation — for example, to store the user identifier as a string:

namespace App\Doctrine;

use Symfony\Bundle\SecurityBundle\Security;
use Ufo\DoctrineBehaviors\Contract\Provider\UserProviderInterface;

final class UserIdentifierProvider implements UserProviderInterface
{
    public function __construct(private Security $security) {}

    public function provideUser(): ?string
    {
        return $this->security->getUser()?->getUserIdentifier();
    }

    public function provideUserEntity(): ?string
    {
        return null;
    }
}
# config/services.yaml
services:
    Ufo\DoctrineBehaviors\Contract\Provider\UserProviderInterface: '@App\Doctrine\UserIdentifierProvider'

If provideUser() returns null, Blameable changes nothing.

Locale provider

Translatable takes locales from Ufo\DoctrineBehaviors\Contract\Provider\LocaleProviderInterface:

  • provideCurrentLocale() — the current request's locale, null without a request; if the request locale is empty — the TranslatorInterface locale;
  • provideFallbackLocale() — the request's default locale; without a request — the locale parameter, and if it is missing — kernel.default_locale.

It is replaced the same way as the user provider:

services:
    Ufo\DoctrineBehaviors\Contract\Provider\LocaleProviderInterface: '@App\Doctrine\MyLocaleProvider'

Doctrine listeners

Each behavior is a separate class in Ufo\DoctrineBehaviors\EventSubscriber, registered with the #[AsDoctrineListener] attribute with priority 500 for the default connection:

Listener Events
TimestampableEventSubscriber loadClassMetadata
BlameableEventSubscriber loadClassMetadata, prePersist, preUpdate, preRemove
SoftDeletableEventSubscriber loadClassMetadata, onFlush
TranslatableEventSubscriber loadClassMetadata, postLoad, prePersist
SluggableEventSubscriber loadClassMetadata, prePersist, preUpdate
TreeEventSubscriber loadClassMetadata
UuidableEventSubscriber loadClassMetadata, prePersist
LoggableEventSubscriber postPersist, postUpdate, preRemove

The bundle's services are public and autowired, so any listener can be redefined in config/services.yaml under the same class id.