tomatophp/ecommerce-theme-module
A TomatoPHP module that adds ready-made, customizable storefront themes to your Laravel ecommerce app. Switch layouts, colors, and product page templates from the admin panel, with Blade views and assets built for Filament, so you can launch a polished shop fast.
This package adds a contact form endpoint to a Laravel application. The release notes only reference the POST /contact route, so treat the route file and service provider as the source of truth until fuller docs are available.
Minimal steps:
composer require the package (check the README for the exact vendor/name), then confirm the service provider is auto-discovered via php artisan about or bootstrap/providers.php on Laravel 11+.php artisan route:list --path=contact to see the URI, name, middleware, and controller.php artisan vendor:publish --provider="..." (config, views, migrations, translations).First use case: drop the form partial into a page, submit to POST /contact, and verify the happy path plus one validation failure before touching styling or mail configuration.
Note on v1.0.2: the route name changed. In v1.0.1 and earlier it was home.contact; it no longer is. Any Blade/controller/test code using route('home.contact') must be updated — see Gotchas.
Reference the route by name, not by URL. Hardcoding action="/contact" works but silently survives route-name changes and breaks if the package later makes the path configurable. Use route('...') and treat the name as part of the package's public API.
Verify the route name in code, not from memory. After upgrading, run route:list and grep the codebase for the old name:
php artisan route:list --path=contact
grep -rn "home.contact" app resources routes tests
Form integration pattern. Standard Blade form with @csrf, old() repopulation, and @error blocks. If the package ships its own form component or partial, prefer publishing and overriding the view over duplicating markup, so validation messages and field names stay in sync with the controller.
Make route:cache a CI gate. The v1.0.2 fix exists because a duplicate route name broke route caching — a failure that only surfaces in production-style deploys. Add this to CI so regressions are caught before deploy:
php artisan route:cache && php artisan route:clear
Feature-test the endpoint rather than only testing through the browser. A test that posts to the named route catches both route-name changes and validation-rule changes:
$this->post(route('contact.store'), [...])->assertSessionHasNoErrors();
Mail/notification handling. If the package sends mail, keep it queued in production and check whether the recipient is config-driven. Override the config value in config/ rather than editing the vendor file.
Upgrade workflow. Read the changelog, bump the constraint, run composer update, then php artisan route:clear && php artisan config:clear && php artisan view:clear before re-testing. Cached routes and configs are the most common reason an upgrade "doesn't take effect."
The v1.0.2 route-name change is breaking in practice. It ships as a patch, but renaming home.contact breaks any route('home.contact') call at runtime with RouteNotFoundException. Pin the version in composer.json if you can't audit call sites immediately, and grep for the old name as the first step of the upgrade.
The original bug only appeared with cached routes. A duplicate route name is tolerated at runtime but throws during route:cache, so local development and even most test suites won't catch it. If you deploy with route:cache (as Forge/Vapor/Envoyer do), test that path explicitly.
route:clear after every upgrade. Stale bootstrap/cache/routes-*.php will keep serving the old route name and produce confusing "route exists but name doesn't" behavior.
Check middleware before debugging a 419 or redirect. CSRF and throttle middleware on the package route are easy to miss; confirm with route:list -v. A 419 on the contact form is almost always a missing @csrf or a session/cookie domain mismatch, not a package bug.
Watch for route collisions with your own app. The name was presumably changed to avoid a clash — if you have your own home.contact or similar, verify the new name doesn't clash with yours by re-running route:cache after adding app routes.
Extension points to check first: published config (recipient address, middleware, redirect target), published views (form markup and field names), and any events/notifications fired after submission. Prefer these over forking the controller.
Debugging checklist for a failing submission: route:list for the actual name and middleware → route:cache for naming conflicts → config:clear/route:clear → check storage/logs/laravel.log for mail transport errors → confirm the config recipient is set in non-local environments.
How can I help you explore Laravel packages today?