Weave Code
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

Timestampable Bundle Laravel Package

andanteproject/timestampable-bundle

Symfony bundle for Doctrine entities that automatically manages createdAt and updatedAt with DateTimeImmutable. Zero config to start, customizable, uses Symfony Clock, no attributes needed, and won’t overwrite timestamps you set manually. Compatible with Symfony 5–8, PHP 8.2.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Symfony/Laravel Hybrid Projects: Ideal for Laravel apps adopting Symfony components (e.g., API Platform, Doctrine ORM) where consistent timestamping is needed. The bundle’s zero-config approach aligns with Laravel’s simplicity while leveraging Symfony’s robustness.
  • Doctrine-Centric Workflows: Fits seamlessly into existing Doctrine entity structures, reducing boilerplate for createdAt/updatedAt fields. The trait-based implementation mirrors Laravel’s HasTimestamps trait, easing migration paths.
  • Symfony Ecosystem: Native support for Symfony Clock (time provider abstraction) ensures compatibility with modern Symfony versions (5–8) and avoids deprecated DateTime pitfalls.

Integration Feasibility

  • Low Friction: No annotations, attributes, or complex setup—just implement TimestampableInterface and use the trait. This mirrors Laravel’s HasTimestamps but with Symfony’s type safety (DateTimeImmutable).
  • Backward Compatibility: Works alongside existing Doctrine entities without requiring schema migrations for non-timestampable fields. Optional configuration allows granular control (e.g., custom column names).
  • Laravel Interop: Can be adapted for Laravel via Symfony’s Bridge (e.g., symfony/clock for time handling) or by wrapping the bundle in a Laravel service provider.

Technical Risk

  • Metadata Cache Warmup: While optional, enabling metadata_cache_warmer_enabled in production may introduce cache invalidation complexity (e.g., post-deploy warmup scripts). Mitigate by testing in staging with cache:clear --no-warmup.
  • PHP 8.2+ Requirement: May block integration with older Laravel versions (pre-9.x). Use runtime checks or polyfills if targeting legacy stacks.
  • Doctrine Event Overrides: The bundle hooks into Doctrine lifecycle events. Potential conflicts with other bundles (e.g., Gedmo\Timestampable) require explicit configuration or disabling one of them.
  • Symfony-Specific Abstractions: Heavy reliance on Symfony Clock and Doctrine’s metadata system could complicate standalone Laravel use. Abstract via interfaces if cross-framework reuse is a goal.

Key Questions

  1. Cross-Framework Strategy:
    • Will this replace Laravel’s HasTimestamps entirely, or coexist in a hybrid app?
    • If Laravel-only, how will Symfony Clock be mocked/abstracted?
  2. Performance Tradeoffs:
    • Is the metadata cache warmup critical for cold-start performance (e.g., serverless), or is the default "lazy warmup" acceptable?
  3. Conflict Resolution:
    • Are other timestamping bundles (e.g., Gedmo) in use? How will overlaps be managed?
  4. Testing Scope:
    • Should the bundle’s Symfony Clock be tested for time-freezing scenarios (e.g., unit tests)?
  5. Future-Proofing:
    • Does the team plan to adopt Symfony 8+ features (e.g., attributes over annotations)? The bundle supports both but may favor attributes long-term.

Integration Approach

Stack Fit

  • Symfony Projects: Native fit for Symfony 5–8 apps using Doctrine ORM. Leverage Symfony Flex for auto-bundle registration.
  • Laravel Adaptation:
    • Option 1: Use as a composer dependency with a custom service provider to bridge Symfony Clock and Doctrine events.
    • Option 2: Reimplement core logic (e.g., DateTimeImmutable handling) in a Laravel package (e.g., spatie/laravel-timestamps alternative).
  • Hybrid PHP Apps: Ideal for monolithic apps with mixed Laravel/Symfony components (e.g., API layer in Symfony, legacy Laravel modules).

Migration Path

  1. Assessment Phase:
    • Audit existing timestamp implementations (e.g., manual created_at fields, Gedmo).
    • Identify entities requiring timestamps and conflicts (e.g., custom setCreatedAt() logic).
  2. Pilot Rollout:
    • Start with non-critical entities (e.g., App\Entity\LogEntry).
    • Test trait vs. interface-only approaches for flexibility.
  3. Incremental Adoption:
    • Phase 1: Add TimestampableTrait to new entities.
    • Phase 2: Migrate legacy entities using optional configuration (e.g., custom column names).
    • Phase 3: Replace custom timestamp logic with bundle hooks.
  4. Doctrine Schema Update:
    • Use migrations (recommended) or schema:update --force for new columns.
    • Example migration:
      // src/Migration/Version20231001000000.php
      public function up(SchemaManager $sm): void
      {
          $sm->addColumn('article', 'created_at', 'datetime_immutable');
          $sm->addColumn('article', 'updated_at', 'datetime_immutable');
      }
      

Compatibility

  • Doctrine ORM: Tested with Symfony’s DoctrineBundle (versions 2.3+). Verify compatibility with custom naming strategies (e.g., snake_case vs. camelCase).
  • Event Listeners: Conflicts with other Doctrine listeners (e.g., Gedmo\Timestampable) require priority configuration or disabling one bundle.
  • Time Zones: Uses Symfony Clock’s time provider, which defaults to UTC. Ensure alignment with Laravel’s config/app.timezone.
  • PHP Extensions: Requires pdo and ctype (standard in PHP 8.2+). No additional extensions needed.

Sequencing

  1. Dependency Installation:
    composer require andanteproject/timestampable-bundle symfony/clock
    
  2. Bundle Registration:
    • For Symfony Flex: Auto-registered.
    • Manual: Add to config/bundles.php.
  3. Entity Integration:
    • Implement TimestampableInterface and add TimestampableTrait.
    • Example:
      use Andante\TimestampableBundle\Timestampable\{TimestampableInterface, TimestampableTrait};
      
      #[ORM\Entity]
      class Article implements TimestampableInterface
      {
          use TimestampableTrait;
          // ...
      }
      
  4. Database Migration:
    • Run migrations or schema update.
  5. Testing:
    • Verify timestamps on create/update operations.
    • Test explicit timestamp overrides (e.g., entity->setCreatedAt(new DateTimeImmutable())).
  6. Optional Optimization:
    • Enable metadata_cache_warmer_enabled in config/packages/andante_timestampable.yaml for production:
      andante_timestampable:
          metadata_cache_warmer_enabled: true
      
    • Warm cache post-deploy:
      php bin/console cache:warmup --env=prod
      

Operational Impact

Maintenance

  • Low Overhead: No manual timestamp updates required. Changes propagate via Doctrine events.
  • Configuration Drift: Centralized config in andante_timestampable.yaml reduces per-entity maintenance.
  • Dependency Updates: Monitor Symfony Clock and Doctrine ORM for breaking changes (e.g., PHP 8.3+ features).

Support

  • Debugging:
    • Use bin/console debug:container Andante\TimestampableBundle to inspect services.
    • Check metadata cache at %kernel.cache_dir%/timestampable_metadata.php for issues.
  • Common Issues:
    • Timestamps not updating: Verify Doctrine events are not overridden (e.g., by prePersist listeners).
    • Metadata cache stale: Clear cache (cache:clear) or enable warmup.
  • Documentation: Bundle’s README is comprehensive, but add internal notes on:
    • Custom column name mappings.
    • Conflict resolution with other bundles.

Scaling

  • Performance:
    • Metadata Cache: Reduces first-request latency by ~50–100ms in cold starts (with warmup enabled).
    • Database Load: Minimal—only writes timestamps on entity changes.
  • Horizontal Scaling: Stateless design works well in distributed environments (e.g., Kubernetes).
  • Edge Cases:
    • High-Write Workloads: Test under load to ensure Doctrine event performance isn’t bottlenecked.
    • Time Synchronization: Ensure all app servers use NTP to avoid timestamp skew.

Failure Modes

Scenario Impact Mitigation
Metadata cache corruption Broken timestamping Disable warmup; rely on lazy build.
Doctrine event conflict Timestamps ignored/overwritten Adjust listener priority.
Database schema mismatch created_at column missing Use migrations; validate schema.
Time provider failure Invalid timestamps (e.g., null) Fallback to new DateTimeImmutable() in custom logic.
PHP 8.2+ requirement Incompatible with older Laravel Use polyfills or target newer stacks.

Ramp-Up

  • **Developer
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.
aimeos/prisma
besmartand-pro/php-quality-config
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor
spatie/laravel-javascript-views