elasticms/submission-bundle
EMS SubmissionBundle handles form submissions from the EMS FormBundle. It provides the backend workflow for processing submitted data and is documented in the EMS project site, with issues and pull requests managed in the elasticMS monorepo.
Install the Bundle:
composer require elasticms/submission-bundle
Ensure EMSFormBundle is also installed (core dependency).
Configure the Bundle:
Add to config/bundles.php:
return [
// ...
ElasticMS\SubmissionBundle\ElasticMSSubmissionBundle::class => ['all' => true],
];
Define a Submission Configuration:
Create a YAML/JSON config file (e.g., config/submissions/contact.yaml):
name: "contact_form"
handler: "database" # or "api", "event", etc.
rules:
- { field: "email", validator: "required|email" }
Route a Form Submission:
In routes/web.php:
use ElasticMS\SubmissionBundle\Routing\SubmissionRouter;
Route::post('/submit-contact', [SubmissionRouter::class, 'handle'])
->name('ems.submission.handle');
First Submission Test:
Submit a form via EMSFormBundle with the config key (contact_form). Verify the submission appears in the database or triggers the configured handler.
Create a Config:
# config/submissions/newsletter.yaml
name: "newsletter_signup"
handler: "database"
model: "App\Models\NewsletterSubscriber"
fields:
email: "email"
name: "name"
Submit via Form:
Use EMSFormBundle to render a form targeting this config. On submission, the bundle will:
email must be valid).NewsletterSubscriber record.Debugging:
Check Laravel logs (storage/logs/laravel.log) for validation errors or use Tinker to inspect the submitted data:
php artisan tinker
>>> \ElasticMS\SubmissionBundle\Submission::findLatest();
config/submissions/: Default location for submission configs. Override via config/elasticms_submission.yaml.src/Handler/: Core handlers (e.g., DatabaseHandler, ApiHandler). Extend these for custom logic.submission.created, submission.validated, or submission.failed in EventServiceProvider.Define the Config:
# config/submissions/lead_capture.yaml
name: "lead_form"
handler: "api"
api:
url: "https://api.example.com/leads"
method: "POST"
auth: "bearer: {{ env('API_TOKEN') }}"
validation:
- { field: "phone", validator: "digits:10" }
Submit via Form:
// In a controller or EMSFormBundle config
$submission = new \ElasticMS\SubmissionBundle\Submission('lead_form');
$submission->setData($request->all());
$submission->handle();
Extend Handlers:
Create a custom handler (e.g., SlackHandler) by extending AbstractHandler:
namespace App\Handlers;
use ElasticMS\SubmissionBundle\Handler\AbstractHandler;
class SlackHandler extends AbstractHandler
{
public function handle(array $data)
{
// Send to Slack API
Http::post('https://slack.com/api/chat.postMessage', [
'text' => "New lead: {$data['email']}",
]);
}
}
Register it in config/elasticms_submission.yaml:
handlers:
slack: App\Handlers\SlackHandler
Events:
Listen for submission events in EventServiceProvider:
protected $listen = [
'ElasticMS\SubmissionBundle\Events\SubmissionCreated' => [
\App\Listeners\LogSubmission::class,
],
];
Queues: Dispatch async processing:
use ElasticMS\SubmissionBundle\Events\SubmissionProcessed;
SubmissionProcessed::dispatch($submission)
->onQueue('submissions');
Validation: Extend validation rules by creating a custom validator:
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
class CustomRule implements Rule
{
public function passes($attribute, $value) { /* ... */ }
public function message() { /* ... */ }
}
Reference it in config:
validation:
- { field: "custom_field", validator: "custom_rule" }
| Pattern | Implementation |
|---|---|
| Multi-Step Workflow | Chain handlers in config: handlers: ["database", "slack"] |
| Dynamic Routing | Use environment variables in config: url: "{{ env('API_URL') }}/leads" |
| Conditional Logic | Add a conditions key to configs to route based on form data (e.g., if: $data['type'] == 'premium'). |
| File Uploads | Configure a file_handler in the bundle’s YAML to process uploads via League\Flysystem. |
Symfony-Laravel Container Conflicts:
DependencyInjection, which may clash with Laravel’s container.AppServiceProvider:
$this->app->bind(
'elasticms.submission.handler.database',
\ElasticMS\SubmissionBundle\Handler\DatabaseHandler::class
);
Missing EMSFormBundle:
EMSFormBundle is installed. Without it, form submissions won’t trigger the bundle’s routers.Route::post('/submit', function (Request $request) {
$submission = new \ElasticMS\SubmissionBundle\Submission('your_config');
$submission->setData($request->all());
return $submission->handle();
});
Validation Errors:
config(['debug' => true]);
Or extend the validator to throw Laravel-specific exceptions.Handler Order:
try-catch in handlers or configure fail_on_error: false in the bundle’s YAML.Log Submissions: Add a listener to log all submissions:
// app/Listeners/LogSubmission.php
public function handle(SubmissionCreated $event)
{
\Log::info('Submission created', ['data' => $event->getData()]);
}
Validate Configs:
Use the validate command to check YAML syntax:
php artisan elasticms:submission:validate config/submissions/your_config.yaml
Inspect Handlers: Dump handler execution:
$handler = $this->container->get('elasticms.submission.handler.database');
\Log::debug('Handler config:', [$handler->getConfig()]);
Custom Handlers:
AbstractHandler and register in config/elasticms_submission.yaml:
handlers:
custom: App\Handlers\CustomHandler
Dynamic Configs: Load configs from a database or API:
// Override the config loader in a service provider
$this->app->bind('elasticms.submission.config_loader', function () {
return new \App\Services\DynamicConfigLoader();
});
Event Overrides: Publish and override bundle events:
php artisan vendor:publish --tag=elasticms-submission-events
Then extend the published event classes.
Environment Variables: Use double curly braces for nested env vars:
api:
url: "{{ env('APP_URL') }}/api/{{ env('API_VERSION') }}/leads"
Default Values:
Override defaults in config/elasticms_submission.yaml:
default
How can I help you explore Laravel packages today?