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

Sonata Importer Bundle Laravel Package

kunicmarko/sonata-importer-bundle

A Symfony bundle that adds configurable data import to Sonata Admin. Define importers for CSV or XML files, map columns to entity fields, and run imports from the admin interface with validation and error handling.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Re-verify compatibility, don't trust the old note. Release 0.1.3 only says "updated dependencies to newest versions" — it does not state a Symfony/Sonata version range. Open composer.json (or composer show kunicmarko/sonata-importer-bundle --all) and read the actual constraints. The prior assumption of a hard 3.4–4.x / Sonata 3.x ceiling may or may not still hold; the release notes are terse enough that you should confirm before planning anything.
  2. Install. composer require kunicmarko/sonata-importer-bundle. 0.1.3 specifically fixes "unable to install correctly when using Symfony Flex", so on a Flex app the bundle should now be registered automatically. If config/bundles.php still doesn't list it after install, you're either not on Flex or hit the old bug — register it by hand and check composer why for a stale lockfile. Non-Flex apps still register manually as before.
  3. Re-check the config footprint. The old assessment assumed "no recipe, probably no config file." Since the Flex path was broken and is now fixed, look for a generated config/packages/*sonata_importer* file before writing your own — and diff it against the README so you don't duplicate settings in the wrong place.
  4. Read in this order: README (still the only usage doc), then src/Importer/ (the interface/abstract class you implement), then the compiler pass that collects tagged importer services, then the admin extension/controller adding the "Import" action. Note the release-note line "dependency used changed how they handle stuff" — something behind the compiler pass or the admin extension changed behaviour upstream, and 0.1.3 is the adaptor. If you're upgrading an existing install, diff src/ between the two tags rather than assuming the architecture is identical.
  5. First use case: an entity you already manage in Sonata Admin that arrives as CSV (products, price lists, customers). One importer service, tagged so it maps to that admin's service id, gives you an "Import" action on the list page that uploads a file and hands it to your importer.

Implementation Patterns

  • One importer per admin. Extend the bundle's AbstractImporter (or implement ImporterInterface), put parsing/persistence in import(), register as a service with the bundle's tag whose alias matches the admin service id. If the alias doesn't resolve, the Import button silently won't appear.
  • Upgrade bundle and lockfile together. Because 0.1.3 is a two-sided fix (bundle code + a changed transitive dependency), a partial upgrade leaves you with half the pair. Bump the bundle, run composer update, and commit composer.lock in the same change; then re-test the "Import" button and the tag resolution on a non-production environment.
  • Let the bundle own the entry point, not the logic. Upload form → file → your importer → flash result. Everything else stays in your class so it's testable and reusable.
  • Reuse the importer from a console command. app:import:products {file} calling the same importer keeps big files and nightly syncs out of a web request.
  • Validate per row, not per file. Iterate rows, validate into a DTO/entity, collect [line => message], continue. Return a summary (created / updated / skipped / failed) instead of throwing on the first bad row.
  • Batch the EntityManager. flush() + clear() every ~100–500 rows. Flushing per row is the usual reason a 20k-line import times out.
  • Upsert on a natural key. Look up by SKU/external id and update-or-create, so re-running the same file is idempotent.
  • Separate parsing from persistence. Wrap file reading in its own service (league/csv, PhpSpreadsheet) with a fixed column map; the importer depends on an array of rows. Swapping CSV→XLSX costs one class.
  • Large files: persist the upload to storage and dispatch a Messenger message with the path; surface status through a field on the admin entity. Don't process a 50MB file in the request.
  • Test with a fixture file. One tests/fixtures/products.csv plus assertions on created/updated counts covers most of the risk; add a functional test that POSTs the import form — that's also your regression net for the 0.1.3 wiring changes.

Gotchas and Tips

  • Stale lockfile defeats the Flex fix. If composer require "succeeds" but the bundle isn't in config/bundles.php and the Import button never appears, clear the Flex cache (rm -rf var/cache/*), confirm the plugin is enabled in composer.json (symfony/flex), and retry on a clean vendor. Don't start hand-wiring services before you've confirmed which of the two paths you're on.
  • The dependency-behaviour fix cuts both ways. If you'd worked around the old transitive behaviour in your own code, 0.1.3 may now double-handle it. Run composer why <suspect-package> / git diff the tag and retest your importer registration and admin extension before deploying.
  • Treat it as low-maintenance, not archived. Earlier releases suggested an abandoned project; 0.1.3 shows it still gets patch releases, but the scope is narrow and the notes are one-liners. Keep the fork/copy plan: this is a handful of classes, so a VCS or path repository in composer.json remains cheap insurance if constraints block your Symfony/Sonata version.
  • Silent no-op when tags don't match. A typo in the importer tag alias vs. the admin service id is still the most common failure. Debug with bin/console debug:container --tag=<bundle tag> and confirm the action is registered on the admin's routes/available actions.
  • Guard the action. Uploaded files are user input: check isGranted('EDIT') (or a dedicated role), enforce a max size, validate extension/MIME. Sonata's ACL doesn't automatically cover a custom action.
  • CSRF and form type. If you swap the file form type, keep the CSRF token and multipart/form-data — a custom template that drops form_enctype is a classic silent failure.
  • CSV quirks bite before your code does: strip the UTF-8 BOM Excel writes, handle Windows-1250/1252, and don't trust that ; vs , matches expectations (Excel uses the OS locale separator). Detect the delimiter or force it in config.
  • Pin columns via a header map, not by index — supplier files reorder columns, and a header-keyed map fails loudly instead of writing prices into the stock column.
  • Memory and time: set_time_limit(0) and a raised memory_limit for CLI/cron paths; keep the web path small or defer it.
  • Cap your error flash. A 5,000-row file with 4,000 failures shouldn't go into a flash message — show the first N, log the rest, or write a downloadable error report.
  • Labels/translations come from the bundle's translation domain; override the "Import" label in your app's translations/ rather than editing vendor files.
  • Extension points worth knowing: the upload form type (swap for XLSX), the abstract importer (override row handling), and the compiler pass (only if you need multiple importers per admin — and the one that just changed its dependency behaviour, so diff it first).
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.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console