frequence-web/contact-bundle
Contact bundle from Frequence Web for PHP applications. Adds reusable contact form handling so you can capture, store, and manage incoming contact requests through a simple configurable integration. Ideal for adding a ready-made contact workflow to Symfony/PHP projects without building form and pers...
Before writing a line of code, confirm what you are actually installing: frequence-web/contact-bundle is a Symfony bundle, not a Laravel package. There is no service provider, no facade, no config/contact.php publish tag. If you are in a Laravel codebase, "getting started" realistically means one of two paths — extract the pattern (recommended) or bridge the bundle (only if you are on a hybrid/legacy Symfony app).
Minimal steps:
Check the constraints first. Open the repo's composer.json and read the require block. Bundles of this vintage (4 stars, 0 dependents, MIT, "event-based contact bundle") typically pin symfony/symfony to a 2.x/3.x range and PHP to >=5.5. If those ranges don't resolve against your PHP 8.x / Laravel 10–11 stack, stop here and treat the repo as reference source rather than a dependency.
Read the bundle entry point. FrequenceWebContactBundle.php tells you the bundle alias (usually derived from getAlias()), and DependencyInjection/Configuration.php + DependencyInjection/*Extension.php tell you the full config tree. This is the fastest way to learn what is actually configurable versus hard-coded.
Read Resources/config/services.yml. That file is the real API surface — it shows you the dispatcher wiring, the controller/service IDs, and which classes you can override or decorate. Everything else is convention.
Locate the event contract. The whole point of the bundle is the event. Find the events class (commonly ContactEvents.php or similar) and grep for ->dispatch( to see exactly when the event fires relative to persistence and mail sending. That ordering determines almost every integration decision you'll make later.
Install it only if step 1 passes:
composer require frequence-web/contact-bundle
Then, in a Symfony kernel, register the bundle in AppKernel/bundles.php and add a minimal config block using the alias from step 2.
First use case to target: a contact form whose submission dispatches a domain event, so that notification, CRM sync, and spam filtering are listeners rather than controller code. That is the value proposition — thin controller, decoupled reactions. If the bundle's event fires after the entity is flushed, you get the standard "persisted then notified" flow; if it fires before, you get validation/abort hooks. Confirm which before building on it.
For Laravel, the equivalent first step is one Event class carrying a DTO of the contact payload, one Listener for mail, and Event::dispatch() at the end of a ContactController@store. That reproduces ~90% of this bundle's usefulness in ~40 lines.
Listener-per-concern (the core pattern). Never put mail, Slack, or CRM calls in the controller. Register subscribers against the bundle's event and keep each listener single-purpose:
// Symfony side — the shape the bundle expects
class NotifyTeamSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [ContactEvents::CONTACT_CREATED => ['onContact', 10]];
}
public function onContact(ContactEvent $event): void
{
// read $event->getContact(), never re-query it
}
}
Priority ordering matters. A spam-check listener should run at a high priority (e.g. 100) and short-circuit; notification listeners at default priority; analytics/logging at low priority. Symfony's dispatcher honours this; if you port to Laravel, remember Laravel listeners have no priority system — use a single dispatching listener that calls the others in order, or Event::listen with explicit sequencing.
Thin controller, fat event. The bundle's controller is almost certainly a form-render/submit pair. If you need extra fields, extend the form type via a FormTypeExtension (Symfony) rather than editing the bundle. If you need extra behaviour, add a subscriber. Avoid forking the controller unless you've exhausted both.
Persistence bridging. In Symfony, the entity is Doctrine-mapped. In a Laravel app, do not try to make Doctrine and Eloquent share a model. Mirror the field list on an Eloquent Contact model, keep the event payload as a plain DTO, and let the listener translate. The event payload is the stable contract; the ORM is an implementation detail.
Config-driven service overrides. Most bundles of this type expose parameters for recipient address, sender, and template. Set those in config, not code:
frequence_web_contact:
recipient: "%contact_recipient%"
template: "Emails/contact.html.twig"
Then inject %contact_recipient% from an environment-specific parameter file so staging and production don't diverge.
Testing. Assert behaviour at the event boundary, not the HTTP boundary. In Symfony, replace the dispatcher with a spy or assert on a mock's dispatch call. In Laravel, Event::fake() then Event::assertDispatched(ContactSubmitted::class) is the direct analogue and is cheap to keep green.
Integration tips. If you go the bridge route, write a small compiler pass to decorate the bundle's notifier with your own (e.g. swap Swiftmailer calls for Symfony\Component\Mailer or Laravel's Mail). Decoration beats copy-paste because bundle upgrades then flow through.
composer require will install it, but nothing will auto-register. There is no laravel/frequence-web-contact-bundle wrapper, and with 0 dependents you are very likely the first person to attempt the integration.php and symfony/* constraints before anything else. A --ignore-platform-reqs install will "work" and then fatal at runtime — don't do it.flush()-scoped dispatch), a retried POST sends two emails. Add a nonce or check-then-notify.getAlias() exactly, otherwise your settings are silently ignored and defaults are used — a classic "why is it emailing the wrong address" bug. Validate with the container debug command (Symfony) or a startup assertion.Event::fake() in tests plus a Log::info in each listener during local development covers the same ground.Resources/config/services.yml in place.ContactEvents and the controller, then reimplement the pattern natively. The bundle gives you a clean event-driven contact workflow as a template; taking the dependency buys you a version-compatibility fight for roughly the same amount of code you'd write anyway.How can I help you explore Laravel packages today?