Download the PHP package ntoufoudis/hopper without Composer
On this page you can find all versions of the php package ntoufoudis/hopper. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download ntoufoudis/hopper
More information about ntoufoudis/hopper
Files in ntoufoudis/hopper
Package hopper
Short Description A headless, framework-agnostic import engine for Laravel. Hopper owns mapping persistence, preview/diff, idempotent re-runnable imports, and governed audit; parsing is delegated to maatwebsite/excel.
License MIT
Informations about the package hopper
Hopper
⭐ If you find Hopper useful, please consider starring the repository.
A headless, framework-agnostic import engine for Laravel. Hopper owns mapping
persistence, preview/diff, idempotent re-runnable imports, and governed audit.
Parsing is delegated to Laravel Excel
(maatwebsite/excel), so CSV and XLSX/XLS sources work out of the box.
Requirements
- PHP
^8.2 - Laravel
^12or^13
Installation
The service provider is auto-discovered. Publish the config if you need to override defaults:
Hopper's migrations are loaded automatically by the service provider, so run
your usual migration command to create the hopper_* tables:
This creates hopper_runs, hopper_staging, hopper_mapping_templates,
hopper_failed_rows, and hopper_audit. Override any of these names via the
hopper.tables config map.
Quick start
Define an import, point it at a source, auto-map the headers, stage it, preview the diff, then commit:
stage() returns an ImportRun; preview() reads the persisted verdicts only
(it never re-queries the target), so the preview counts are exactly what
commit() will do.
An ImportDefinition declares the target model, resolver, fields, validation
rules, and transformation pipes:
Scaffold one with php artisan make:import CustomerImport (generated under your
application's App\Hopper namespace).
Sources
CsvSource::make($path) and ExcelSource::make($path) both accept a path or an
Illuminate\Http\UploadedFile and stream the file in chunks through Laravel
Excel. They expose ordered headers, header-keyed rows numbered from 1, and a
content-based fingerprint used to keep re-staging idempotent.
Mapping & resolvers
Headers are matched to target fields by a strategy chain - exact, alias
(config-driven synonyms in hopper.mapping.aliases), then fuzzy (Levenshtein
above hopper.mapping.fuzzy_threshold). autoMap() reuses a saved mapping
template for a source signature before falling back to strategies; map()
accepts an explicit ColumnMap.
Resolvers (in Ntoufoudis\Hopper\Resolution) decide each row's verdict
(Insert / Update / Skip):
InsertOnlyResolver- every row inserts (new InsertOnlyResolver).UpsertResolver::by($field)- update on match, else insert.MergeResolver::by($field)- field-level merge (non-blank incoming wins).CallbackResolver- closure escape hatch for custom verdicts.
Validation, pipes & failed rows
Each row runs map -> transform (pipes) -> validate (rules) -> resolve -> stage.
Rows rejected by a pipe (RowRejected) or failing validation are diverted to
hopper_failed_rows with a reason and never staged. Export them as CSV:
The exporter renders the union of payload columns plus a final error column,
and neutralises spreadsheet formula injection by tab-prefixing any cell that
begins with =, +, -, or @.
Audit
Import lifecycle events (run.created, mapping.resolved, row.rejected,
preview.generated, commit.started / commit.completed / commit.failed)
are recorded through the configured AuditDriver.
database(default) - writes each event tohopper_audit.
Select the driver via hopper.audit.driver (or HOPPER_AUDIT_DRIVER):
Configuration
Published to config/hopper.php: queue_connection, default_chunk_size,
audit.driver, mapping.aliases / mapping.fuzzy_threshold, and the
hopper_* table-name map.
Limitations
-
Concurrency. Commit is safe under duplicate/concurrent dispatch - re-entry is refused and uncommitted rows are locked - so a double dispatch cannot double-write.
- Queued-source durability. When staging runs on a queue, the source file must
live on storage the worker can read. A framework temp-upload path
(
$request->file('import')->getRealPath()) belongs to the web request and will not exist on a separate worker. Persist the upload to a durable disk first, then point the source at the stored path:
Versioning
Semantic versioning applies from v1.0.0 onwards.
License
MIT. See LICENSE.
All versions of hopper with dependencies
illuminate/contracts Version ^12.0||^13.0
illuminate/support Version ^12.0||^13.0
illuminate/database Version ^12.0||^13.0
illuminate/bus Version ^12.0||^13.0
illuminate/queue Version ^12.0||^13.0
maatwebsite/excel Version *