progrupa/edifact-bundle
A Symfony bundle that brings EDIFACT EDI handling to your application, wrapping the progrupa/edifact library so you can parse, read and generate electronic business documents through Symfony services and configuration.
progrupa/edifact-bundle is a Symfony bundle, not a Laravel package — the first thing to internalize is that there is no ExtraServiceProvider / package auto-discovery here. You are adopting a Symfony DI extension inside a Laravel app, so expect to do the wiring yourself.
Minimal steps:
Install and inspect before trusting it.
composer require progrupa/edifact-bundle
Immediately open vendor/progrupa/edifact-bundle/composer.json and DependencyInjection/. You need to know (a) which Symfony components it pins (symfony/dependency-injection, symfony/config, symfony/http-kernel), and (b) what the underlying EDIFACT engine is (almost certainly progrupa/edifact). The bundle is a thin DI/config layer; the real API lives in the base library's README, and that is where you should spend your reading time.
Read the bundle's services.yaml / Configuration.php. This is your source of truth for class names, constructor arguments, and available config keys. There is no Laravel-facing documentation for this package, so the service definitions are the docs.
Skip the bundle's bootstrapping and bind the underlying services directly. In App\Providers\EdifactServiceProvider:
$this->app->singleton(Parser::class, fn () => new Parser(/* separators, charset */));
$this->app->singleton(Serializer::class, fn ($app) => new Serializer($app->make(Parser::class)));
You get the library's behaviour without fighting Symfony's Extension/CompilerPass machinery, which Laravel has no equivalent for.
First use case: ingest, don't emit. Parsing an inbound ORDERS/INVOIC into segments is low-risk and easy to validate against a real partner file. Outbound generation is where separator/qualifier bugs bite hardest — save it for after you have round-trip tests.
A good first concrete goal: read a .edi fixture, walk the segment tree in tinker, and print UNB, BGM, and a couple of LIN segments. If that works, the rest is mapping work.
Wrap, don't leak. The bundle's value is the underlying message model. Expose it behind your own interface so you can swap the engine later (this package has 0 stars and 0 dependents — treat it as replaceable):
interface EdifactReader {
public function read(string $raw): EdifactDocument;
}
Bind the library implementation in a service provider; every caller depends on your interface.
Queue the parse. EDIFACT files are frequently megabytes and full of repeated segment groups. Parsing belongs in a job, not a controller:
final class IngestEdifact implements ShouldQueue
{
public function handle(EdifactReader $reader, EdifactMapper $mapper): void
{
$doc = $reader->read(Storage::get($this->path));
$mapper->toOrder($doc)->save();
}
}
Store the raw payload alongside the parsed result. You will re-parse after a mapper fix, and without the original file you cannot.
Two-stage mapping. Keep segment traversal and domain mapping separate: a SegmentWalker that yields typed segment groups, and a Mapper that turns those into Eloquent models/DTOs. This mirrors how the library itself is layered (reader → segments → serializer) and makes unit tests trivial — you can feed handcrafted segment arrays into the mapper without touching the parser.
Serializer for outbound, with a golden-file test. Build documents from DTOs, then assert byte-for-byte equality against a known-good partner file. Anything less and separator/qualifier drift will pass CI and fail in production:
$this->assertSame(
file_get_contents(base_path('tests/fixtures/orders_out.edi')),
$serializer->serialize($orderDto)
);
Integration tips.
bootstrap/providers.php (Laravel 11+) or config/app.php.config/edifact.php and inject them — never hardcode +, :, '.php artisan.The Symfony coupling is the main risk. Laravel has no bundle registration, no service tags, no compiler passes. If the bundle's services only resolve through a CompilerPass or a tagged iterator, you must replicate that wiring manually in your provider. Budget real time for this — it is the single most common reason people give up on Symfony bundles in Laravel.
Zero stars, zero dependents, zero releases of note. Pin the version explicitly in composer.json and, if you go to production with it, consider composer vendor-style forking into app/Support/Edifact or a private package. There will be no upstream fixes for separator or charset bugs.
Character sets and release characters. UNOA/UNOB/UNOC restrict which characters may appear in data. If a partner sends an ampersand or an accented name and you have not set the release character correctly, the parser will split segments in the wrong place and you will get silently truncated fields rather than an exception. Validate the UNB S001 syntax identifier and reject mismatches loudly.
The UNA segment is optional. When present it redefines the separators for the whole interchange. A parser configured with defaults will produce garbage on files that carry a UNA. Check whether the library honours UNA; if not, parse it yourself and configure accordingly.
Trailing whitespace and line breaks. EDIFACT has no semantic newlines — many real-world files are pretty-printed with \r\n between segments. Most parsers tolerate this, but a strict one will not. Normalize (or preserve) input deliberately and write a test for both.
Decimal notation. UNB/UNS/config may state decimal comma vs. point. Getting this wrong on MOA/PRI amounts is a financial bug that surfaces months later. Assert it in a test.
Debugging approach. When a parse fails, print the raw segment list before mapping, one segment per line, with indices. Nine times out of ten the failure is a mismatched segment count in a repeating group (LIN/PIA/QTY/FTX), not a code bug. Build a small Artisan command, edifact:dump {path}, that emits the segment tree — you will use it constantly.
Extension points to look for in services.yaml: custom segment classes, serializer encoders, and any element/component validators. These are usually the only sanctioned override hooks; subclassing the parser directly tends to break on the next version.
Validate at the boundary. EDIFACT has segment tables (/segments/*.xml in the UNECE directories). If the library does not validate against them, add a lightweight check of mandatory segments and qualifier values in your own layer — a malformed BGM should fail at ingestion, not halfway through writing an order.
How can I help you explore Laravel packages today?