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

Polyfill Form Dti Bundle Laravel Package

ruwork/polyfill-form-dti-bundle

Symfony bundle that polyfills the DateTimeImmutable form type for older framework versions, so you can use immutable date and time fields without upgrading Symfony. Drop-in integration for forms and applications.

View on GitHub
Deep Wiki
Context7

Getting Started

ruwork/polyfill-form-dti-bundle is a Symfony bundle that polyfills DateTimeImmutable support in the Form component's date/time types (DateType, TimeType, DateTimeType). Core Symfony form types of that era were hard-wired to produce mutable \DateTime objects, so mapping a form to an entity or DTO with DateTimeImmutable properties failed with errors like "Expected argument of type DateTimeImmutable, DateTime given". This bundle backfills that behavior for Symfony 3.x/early-4.x projects.

Minimal setup:

  1. composer require ruwork/polyfill-form-dti-bundle — expect 2018-era version constraints, so you may need a legacy PHP/Symfony matrix or --with-all-dependencies when resolving conflicts.
  2. Register the bundle:
    • Symfony 3: add new Ruwork\PolyfillFormDTIBundle\RuworkPolyfillFormDTIBundle() to AppKernel::registerBundles().
    • Symfony 4: add it to config/bundles.php.
  3. Clear the cache: bin/console cache:clear. Form type services are cached, so a stale container is the usual reason "nothing happened."
  4. Look first at how it hooks in. Run bin/console debug:form DateTimeType and bin/console debug:container form.type.datetime. There are two possible designs, and they change your usage entirely:
    • Transparent override — the bundle replaces/decorates the core form type services, so existing forms just start returning immutable objects.
    • Explicit types — the bundle ships its own type classes (e.g. under Form/Type) that you must reference in your form builders.
  5. First real use case: an entity with private DateTimeImmutable $startsAt; and a DateTimeType field. Before the bundle the submit fails; after, the form reverse-transforms the submitted string into a DateTimeImmutable.

Implementation Patterns

If the bundle overrides core services (transparent mode): change nothing in your form classes. Verify with debug:form that the data transformer now produces DateTimeImmutable, then add an integration test asserting assertInstanceOf(DateTimeImmutable::class, $form->getData()) so a future dependency bump can't silently regress you back to mutable.

If the bundle ships explicit types (opt-in mode): swap imports only in the form classes that need immutability:

// use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
use Ruwork\PolyfillFormDTIBundle\Form\Type\DateTimeType;

Keep the alias name identical so the diff stays a one-line-per-file change and migration to native Symfony later is a mechanical find-and-replace.

Custom form types: if you already subclass DateType/DateTimeType (very common for date-picker widgets), extend the bundle's type instead of the core type so you inherit the immutable transformer rather than bypassing it.

Per-field vs bundle-wide: if the bundle exposes an input option ('input' => 'datetime_immutable'), prefer setting it per field over relying on a global default — it keeps the immutability contract visible at the call site and limits blast radius.

Doctrine alignment: pair the form change with @ORM\Column(type="datetime_immutable") (Doctrine 2.6+). A DateTimeImmutable property backed by a datetime column is a classic source of conversion errors and confusing hydration behavior.

Validation: Symfony\Component\Validator\Constraints\DateTime accepts both mutable and immutable. But a Type constraint pinned to \DateTime::class will start failing — update those to DateTimeImmutable::class.

DTO / command pattern: this bundle pairs naturally with immutable command objects. Build a DTO with readonly-style DateTimeImmutable properties, let the form hydrate it directly, and skip the "copy mutable DateTime into immutable entity field" glue you'd otherwise write.

Testing workflow: fixtures should use DateTimeImmutable::from.../new DateTimeImmutable(...). In functional tests, submit through KernelBrowser rather than calling the type directly, so you exercise the transformer registered by the bundle.

Exit strategy: treat this as a scaffold, not a dependency. Modern Symfony supports immutable input natively via the input => 'datetime_immutable' option (or the immutable equivalents in later versions), so the migration is: drop the bundle, revert type imports to the core classes, add the input option, delete the bundle registration.

Gotchas and Tips

  • Archived and unmaintained since Feb 2018, 1 star, 0 dependents. There will be no fixes for new PHP or Symfony releases. Pin it, document why it exists in your composer.json, and put a removal ticket in the backlog the day you add it.
  • Mutation assumptions are the #1 runtime bug. $date->modify('+1 day'), ->setTime(...), ->setDate(...) all return new instances on DateTimeImmutable. Any code that ignores the return value silently keeps the old date. Grep for ->modify(, ->setDate(, ->setTime(, ->add(, ->sub( on anything that now flows out of a form.
  • Global blast radius. If the bundle decorates the core form.type.datetime service, every date field in the app changes, including those rendered by third-party bundles (Sonata, EasyAdmin, custom pickers). Those bundles extend the core type and may bring their own mutable transformers back — you can end up with some fields immutable and some mutable in the same form.
  • Doctrine type mismatch. datetime vs datetime_immutable is not cosmetic: the DBAL type controls conversion. Mismatched mappings throw on persist/flush or hydrate the wrong class depending on Doctrine version.
  • empty_data and non-required fields. An empty/blank submission can yield null or a default constructed object. Don't assume every non-null result is immutable — assert both branches in tests.
  • Timezones. The core transformers honor model_timezone and view_timezone. Confirm the polyfill's transformer does too, or you'll get subtly shifted dates that only show up in production with non-UTC users.
  • Debugging checklist: debug:form DateTimeType (which transformer?), debug:container form.type.datetime (which class?), then cache:clear. If the behavior flipped in one environment only, it's almost always a cached container or a different bundle registration order.
  • Extension points: subclass the bundle's types for app-specific behavior, or decorate the core service with a compiler pass — never patch vendor/. The bundle is small enough to fork if you need a long-term fix, but then you own the maintenance you were trying to avoid.
  • Don't start new projects on it. For greenfield Symfony, use the native input => 'datetime_immutable' support; this bundle only makes sense as a shim on a legacy branch you're not ready to upgrade.
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.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings