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

Contact Bundle Laravel Package

sylius/contact-bundle

Sylius Contact Bundle adds a configurable contact form to your Sylius storefront and lets administrators review and manage submitted contact requests from the admin panel, integrating with Sylius resources, channels, and email notifications.

View on GitHub
Deep Wiki
Context7

Getting Started

Reality check first: this is not a Laravel package. sylius/contact-bundle is a Symfony bundle for Sylius, the Symfony-based e-commerce platform. There is no service provider, config file, facade, migration stub, or Blade view to publish. composer require sylius/contact-bundle in a Laravel app does nothing useful — you will pull in Symfony/Doctrine dependencies that fight with your Laravel stack and gain zero usable code paths.

So your "getting started" depends on which side of the fence you are on:

If you are on Sylius (the only place this runs natively):

  1. Check whether you even need it. The bundle is archived/read-only, and newer Sylius releases folded contact functionality into core. Grep your installed Sylius source for ContactRequest before adding anything — installing the standalone bundle into a version that already has it produces duplicate service IDs and conflicting routes.
  2. If genuinely absent: composer require sylius/contact-bundle, register it in config/bundles.php, and import its routing from Resources/config/routing.yml.
  3. Verify the sylius_contact_request and sylius_contact_topic tables exist via Doctrine migrations or bin/console doctrine:schema:validate.
  4. Read these files first, in order:
    • src/Model/ContactRequest.php, src/Model/ContactTopic.php — the domain
    • src/Form/Type/ — the storefront form and its validation
    • src/Controller/ — storefront submit + admin actions
    • Resources/config/ — routing, services, grid definitions
    • Resources/translations/ — copy and email templates (this is the configuration surface)
  5. First use case: load the storefront contact page, submit a message, confirm a ContactRequest row is created, open it in the admin contact grid, and transition it to handled.

If you are on Laravel (the likely case):

Do not install. Treat the repository as a reference design for a ~200-line feature, then build it natively. Clone it to a scratch directory, read src/Model/ and src/Form/Type/, and treat the two entities plus one form as a spec. Your "getting started" is one afternoon of scaffolding:

  • ContactTopic and ContactRequest Eloquent models (with the belongsTo relation and a status enum)
  • A StoreContactRequest form request with validation
  • A queued Mailable triggered from a model event
  • An admin resource (Filament/Nova) or a simple Livewire inbox

That is the whole bundle, reimplemented idiomatically.

Implementation Patterns

Inside Sylius — the override layers, in order of preference:

  • Resource configuration first. Entities are wired through sylius_resource config, not autodiscovery. To change the model, form, controller, or repository, override the resource entry — never edit the class in place. This is the primary customization seam and the only one that survives upgrades cleanly.
  • Template overrides via bundle inheritance: templates/bundles/SyliusContactBundle/.... This is how you restyle or restructure the storefront form.
  • Form type extensions (AbstractTypeExtension) to add or hide fields without forking the form.
  • Service decoration for controller or repository behavior changes.
  • Container parameters for class swapping when nothing else fits.

Modeling the workflow:

  • ContactTopic is a resource, meaning extra topics (sales, support, legal) are database rows, not code. Seed them in fixtures or a migration rather than hardcoding an enum. If you need per-topic routing, attach metadata to the topic row and resolve the recipient in an event listener.
  • The admin inbox is a SyliusGridBundle grid defined in Resources/config/. Add columns, filters, and bulk actions in the grid config. Status transitions (new → handled) live on the resource workflow, not in the controller — resist the urge to set status in a controller action.
  • Email notifications should hook the sylius.contact_request.pre_create / post_create resource events via a subscriber. Do not inject mailer calls into the controller; the bundle is thin here and you want to swap transport logic later without touching vendor code.

Porting the pattern to Laravel (the recommended path):

// app/Models/ContactRequest.php
class ContactRequest extends Model {
    protected $fillable = ['contact_topic_id','name','email','message','status'];
    protected function casts(): array {
        return ['status' => ContactStatus::class];
    }
    public function topic(): BelongsTo { return $this->belongsTo(ContactTopic::class); }
}

// app/Http/Requests/StoreContactRequest.php
public function rules(): array {
    return [
        'contact_topic_id' => ['required','exists:contact_topics,id'],
        'name'    => ['required','string','max:255'],
        'email'   => ['required','email'],
        'message' => ['required','string','max:5000'],
    ];
}

// Controller: throttle + honeypot, persist, dispatch event
Route::post('/contact', StoreContactController::class)
    ->middleware('throttle:5,1');

Then attach a listener to ContactRequest::created that queues a NewContactRequest mailable to the recipient resolved from the topic, and a Filament resource for admin triage with a status transition. That reproduces 100% of the bundle's behavior with native primitives — queues, rate limiting, and validation are all things Laravel already gives you.

Gotchas and Tips

  • Archived means frozen. No security patches, no PHP 8.x/Symfony 7 compatibility work. Composer will increasingly conflict on symfony/* and doctrine/* constraints. Plan to pin the platform or expect resolution failures on the next bump.
  • Duplicate-functionality trap. As noted above, grep your Sylius version for ContactRequest before installing — many deployments already have it via core, and installing the standalone bundle produces conflicting service IDs and duplicate routes. This is the most common silent failure with this package.
  • Zero dependents, 5 stars, archived is a real signal: almost nobody runs this standalone. Community answers will not exist. When something breaks, your sources are the Sylius core source and the bundle's own tests — nothing else.
  • Overriding the wrong layer is the classic Sylius mistake. Editing vendor/ or copying controllers wholesale breaks on every update. If a class is not exposed as a sylius_resource or a sylius.* parameter, decorate the service instead.
  • Routing cache. After adding or overriding contact routes, run bin/console cache:clear. Stale router caches produce confusing 404s on the contact page that look like a missing route when it is actually cached.
  • Translations are the "config." Labels, email subjects, and flash messages live in translation files. Missing keys render as raw keys rather than throwing, so inspect the rendered page — not the logs — when copy looks wrong.
  • Debugging commands worth memorizing:
    • bin/console debug:container sylius.contact — confirm services
    • bin/console debug:router | grep contact — confirm routes
    • bin/console debug:event-dispatcher — confirm your subscriber is registered on sylius.contact_request.*
    • Sylius grid debug commands for the admin list
  • No modern spam defense out of the box. Beyond Symfony's CSRF defaults, this predates current abuse mitigations. Add throttling at the reverse proxy or via a Symfony rate limiter — the equivalent of Laravel's throttle:5,1 middleware.
  • PII and retention are your problem. Contact messages are unstructured free-text with emails. For a Laravel port, add a retention/pruning job and encrypt at rest; the bundle gives you none of this.
  • If you must stay on Sylius and adopt it, isolate it behind a bounded service, write tests around the submit → persist → notify → status path, and assign explicit ownership for upgrades and security patching. For a commodity feature this small, an in-house Sylius module is usually less work than owning a fork.
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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager