Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Doctrine Behaviors Laravel Package

awstudio/doctrine-behaviors

awstudio/doctrine-behaviors provides reusable Doctrine behavior traits for Laravel and PHP applications, helping add common entity features such as timestamps, soft deletes, slugs, blameable users, sorting, and tree support with less boilerplate.

View on GitHub
Deep Wiki
Context7

Getting Started

This package provides Doctrine ORM behavior traits, not Eloquent models. It is only relevant if your Laravel app already uses Doctrine via laravel-doctrine or a direct EntityManager. Treat it as a low-level Doctrine add-on, not a Laravel-first package.

Minimal adoption path:

  1. Confirm your stack and compatibility:

    composer show doctrine/orm
    composer show laravel-doctrine/orm
    composer require awstudio/doctrine-behaviors
    

    Check the installed source in vendor/awstudio/doctrine-behaviors/src before using it. The package is old and small, so verify the actual trait names, required methods, namespaces, and whether event subscribers are included.

  2. Decide whether Laravel Doctrine is already wired correctly. You need a working Doctrine EntityManager, metadata driver, migrations, and cache configuration before behavior traits are useful.

  3. Register the behavior event subscribers with your Doctrine manager. Depending on the package version, these may be Doctrine event subscribers rather than Laravel service providers. In laravel-doctrine, this usually means adding them to the manager's event_subscribers config or registering them from a service provider.

  4. Start with the lowest-risk behavior: timestamps. Add a timestampable trait to one existing entity, map the expected columns explicitly, generate a migration, clear Doctrine metadata cache, then persist and flush:

    $entity = new Post();
    $entity->setTitle('Hello');
    $em->persist($entity);
    $em->flush();
    
  5. Verify the behavior through an integration test against a real Doctrine EntityManager, not a mocked unit test. Traits often depend on lifecycle events and metadata, so isolated mocks hide failures.

First real use case: add createdAt / updatedAt to an existing Doctrine entity and confirm Doctrine lifecycle events set them on insert and update. Once that works, evaluate slugs, soft deletes, blameable, or translatable separately.

Implementation Patterns

Use traits as entity composition, but keep Doctrine mapping explicit. Do not assume the trait alone creates database columns; map the fields in the entity metadata and generate migrations for them.

Typical day-to-day patterns:

  • Service layer around the EntityManager. Keep persist() / flush() out of controllers. Wrap multi-entity writes in transactions:

    $em->wrapInTransaction(function () use ($em, $post) {
        $em->persist($post);
    });
    
  • Timestampable pattern. Use it for audit fields, but set timezone consistently. Prefer immutable date types where the package supports them; otherwise normalize to UTC in the app.

  • Sluggable pattern. Implement whatever required method the trait exposes, map a unique slug column, and enforce uniqueness at the database level. Regenerate slugs only when the source field changes, and handle collisions with a suffix or retry strategy.

  • Soft delete pattern. Confirm how the package filters deleted records. If it uses a Doctrine query filter, ensure it is enabled for the manager. Add repository methods that explicitly include or exclude deleted rows, and test direct DQL separately because filters may not behave the same as entity queries.

  • Blameable pattern. Resolve the current user from Laravel's auth guard, but provide a fallback for console commands, queues, and seeders. A null or system-user fallback is usually better than throwing when no authenticated user exists.

  • Translatable pattern. Treat this as the highest-complexity behavior. Use a separate translation entity, define locale handling explicitly, and fetch translations with joins where possible to avoid N+1 queries. Add serialization rules so API responses do not recurse through translations.

  • Testing pattern. Use an integration test with a real Doctrine setup, ideally the same metadata driver and subscribers as production. SQLite can be useful for speed, but verify date, JSON, and unique-constraint behavior against your production database.

  • Extension pattern. Prefer custom Doctrine event subscribers over editing vendor traits. If a behavior is close but not exact, subclass the subscriber or wrap the service logic. If you must change a trait, fork the package and pin your fork.

Gotchas and Tips

  • Maintenance risk is the biggest issue. The package has 1 star, 0 dependents, and the last release was 2018-05-08. Budget for compatibility work with PHP 8+, Doctrine ORM 2/3, and modern Laravel. Pin the version, test upgrades, and be prepared to fork.

  • It is Doctrine, not Eloquent. There is no save(), no mass assignment, no model events in the Eloquent sense, and no automatic Laravel integration. Developers used to Eloquent will lose time assuming Eloquent behavior.

  • Trait property conflicts are common. If two traits declare the same property or method, use insteadof / as aliases or refactor the entity. Check for duplicate $id, $createdAt, $slug, or $deletedAt fields.

  • Metadata cache will waste your time. After adding traits or changing mappings, clear Doctrine metadata cache. In Laravel Doctrine, that often means the Doctrine cache commands or your app's cache layer, depending on configuration.

  • DQL updates bypass lifecycle events. UPDATE / DELETE DQL and native SQL can skip timestampable, blameable, and soft-delete subscribers. Use entity updates when behavior matters, or handle those paths explicitly.

  • Slug uniqueness needs a database constraint. Application-level checks race under concurrency. Add a unique index and handle duplicate-key exceptions with a retry or suffix strategy.

  • Soft-deleted rows can leak through raw SQL or custom DQL. Verify every repository, report query, and admin export. Also check whether the filter is enabled per EntityManager and whether it is disabled temporarily during maintenance tasks.

  • Blameable breaks in CLI and queues. Auth is often absent there. Use nullable columns or a system user, and make the resolver explicit rather than relying on auth()->user() globally.

  • Translatable behavior causes N+1 and serialization problems. Fetch joins, locale fallback, and API resources need deliberate design. Do not expose Doctrine entities directly without controlling translation loading.

  • Timezone drift is easy. Timestampable fields are only as good as the app's timezone discipline. Store UTC and format at the boundary.

  • No Laravel auto-discovery should be assumed. Check whether a service provider exists in the package. If not, register subscribers manually and document the setup in your app's Doctrine config.

  • Use it selectively. Timestampable and soft delete are reasonable first candidates. Translatable and loggable behaviors are much more invasive; only adopt them if the package's implementation matches your domain model closely.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core
nodisrupt/laravel-agent
sierratecnologia/media-manager