Adminix Documentation Help

Import

ImportModule renders a CSV upload form, server-side preview, optional column mapping, and opt-in queued execution. Adminix reads the uploaded CSV, renders preview rows, preselects configured mappings, and can dispatch a queued handler after a clean preview. It never lets the browser choose target fields, validation rules, datasource, or persistence behavior.

use AlexKudrya\Adminix\AdminixPage; use AlexKudrya\Adminix\Modules\Import\ImportColumn; use App\Admin\Imports\CustomerImportHandler; use App\Adminix\Progress\ImportProgressHandler; use AlexKudrya\Adminix\Modules\Module; AdminixPage::uri('imports') ->name('imports-page') ->addModules( Module::progressBar() ->name('import-progress') ->title('Import progress') ->handler(ImportProgressHandler::class) ->showValues(), Module::import() ->name('customers') ->title('Customer import') ->description('Upload a customer CSV file and review the first rows.') ->maxKilobytes(2048) ->previewRows(10) ->handler(CustomerImportHandler::class) ->queued('Customer import queued.') ->onQueue('imports') ->progressTrigger('import-progress') ->addColumns( ImportColumn::make('name', 'Name')->required(), ImportColumn::make('email', 'Email') ->aliases('E-mail', 'Email Address') ->required() ->rules('email', 'max:255'), ImportColumn::make('status', 'Status')->aliases('State') ) );

Rendered behavior

The module renders:

  • a CSRF-protected POST form to the Adminix import preview endpoint;

  • a real file input named adminix_import_file;

  • hidden page/module names used only to resolve the configured module server-side;

  • preview rows after a successful upload;

  • mapping selects when ImportColumn definitions exist.

  • a server-side row validation report when configured columns are required or declare validation rules.

  • a failed-row CSV download when preview validation finds invalid rows.

  • a Queue import button when queued() and handler() are configured and the preview has no missing required columns or validation issues.

The preview redirect stores parsed preview data in the Laravel session and, only for queued imports, stores a server-owned temporary CSV copy for the later execute request. Adminix does not trust browser-submitted mapping as an import contract and does not write application records during preview.

Module API

  • name() is required and must be unique within the page.

  • title() renders the card heading; by default the module name is shown.

  • description() renders short helper text under the title.

  • maxKilobytes() limits accepted preview upload size. The default is 2048.

  • previewRows() limits rendered preview rows and is clamped to at least 1. The default is 10.

  • delimiter() accepts one character and defaults to ,.

  • addColumn() and addColumns() define optional target columns for mapping.

  • handler() configures an import handler class, object, or callable for queued execution.

  • queued() enables the Queue import action and accepts the success message shown after dispatch.

  • onQueue() and onConnection() set Laravel queue routing for the queued import job.

  • progressTrigger() starts a same-page ProgressBarModule when the clean preview is queued.

ImportColumn supports:

  • field() - stable target field key;

  • label() - visible target label;

  • aliases() - header aliases for automatic matching;

  • required()/optional() - whether a missing header match should be highlighted and mapped preview values must be present;

  • rules() - Laravel validation rules applied to mapped preview values server-side.

Header matching is case-insensitive and ignores punctuation, so email, E-mail, and Email Address can match the same configured target when aliases are declared.

Row validation report

Import preview validates only the rendered preview rows. Adminix builds validation data from the server-resolved ImportModule, resolved header mapping, and parsed CSV rows. The browser cannot submit validation rules or choose target fields.

ImportColumn::make('email', 'Email') ->aliases('E-mail') ->required() ->rules('email', 'max:255');

Result: after upload, Adminix renders a compact validation summary. If issues are found, the report lists CSV row number, target column, submitted value, and Laravel validation message. The preview report checks only preview rows; queued execution reparses the full server-owned temporary CSV and validates every row again before calling the handler.

When preview validation has invalid rows, Adminix renders Download failed rows. The download endpoint verifies the signed import context and current preview session, then returns a CSV containing only failed preview rows. The CSV includes _adminix_csv_row, _adminix_failed_fields, _adminix_errors, and the original CSV columns. The browser cannot submit failed row data, validation messages, or a temporary file path.

Queued execution

Queued import execution is opt-in. Configure both queued() and handler(). The execute form is rendered only after preview and is disabled until required mappings and preview validation pass.

namespace App\Admin\Imports; use AlexKudrya\Adminix\Modules\Import\ImportHandlerInterface; use AlexKudrya\Adminix\Modules\Import\ImportRequest; use AlexKudrya\Adminix\Modules\Import\ImportResult; final class CustomerImportHandler implements ImportHandlerInterface { public function handle(ImportRequest $request): ImportResult { foreach ($request->rows() as $row) { // Persist through application-owned services. } return ImportResult::success('Customers imported.'); } }

ImportRequest::rows() contains mapped rows keyed by configured ImportColumn::field() values. rawRows(), headers(), mappings(), params(), filename(), and validation() expose the server-derived context for application services. If full-file validation fails, Adminix returns ImportResult::validation(...) from the job and does not call the handler. Preview failed-row downloads are available before queueing.

Call progressTrigger('import-progress') to start an existing same-page ProgressBarModule when the Queue import button is clicked. The progress handler remains application-owned: store queued job state in the consuming app and return it from ProgressBarHandlerInterface. The browser trigger only starts polling; it does not make progress data client-authoritative.

Queued workers cannot return an HTTP download response to the original browser request, so generated results are represented as typed metadata:

use Illuminate\Support\Facades\URL; return ImportResult::download( url: URL::signedRoute('admin.imports.result', ['import' => $importId]), label: 'Download import CSV', message: 'Import result ready.' ); return ImportResult::report( title: 'Customer import report', body: 'Created: 120, updated: 14, skipped: 3.', message: 'Import report ready.' );

downloadResult(), reportResult(), and toArray() expose this metadata for application-owned job storage, notifications, or progress handlers. The consuming app owns the generated file/report, authorization, signed URL, retention, and audit rules.

For safe queue usage, make import handlers idempotent. Use an application import/job record or a deterministic idempotency key before writing business data, record processed/failed counters from the queue worker, and let the progress handler read those counters only. Do not rely on the preview session after dispatch; the queued job receives the server-owned CSV copy and reparses it. If a job is retried, the handler should detect rows or batches that were already applied and avoid duplicate writes.

Security

The preview endpoint resolves the page and module through Adminix server-side configuration. It accepts CSV or text files only within the configured size limit and parses the file on the server. The browser cannot choose datasource, writable fields, validation rules, or persistence behavior.

The failed-row download endpoint verifies the same signed import context and exports only rows from the server-owned preview validation report. The execute endpoint verifies a signed import context, requires an existing server-owned preview session, and dispatches RunQueuedImport. The job resolves the current ImportModule, reparses the temporary CSV, resolves mappings from the current module config, validates all rows, and then calls the configured handler. Queued result metadata is returned by the server-side handler; Adminix does not accept result URLs or report bodies from the browser. Application handlers own database writes, idempotency, authorization beyond Adminix access, failed-row storage, and audit rules.

Doctor

php artisan adminix:doctor validates import column configuration:

  • ADMINIX_IMPORT_COLUMNS_INVALID for non-array or non-ImportColumn column values;

  • ADMINIX_IMPORT_COLUMN_FIELD_MISSING for empty target fields;

  • ADMINIX_IMPORT_COLUMN_FIELD_DUPLICATE for duplicate target fields in one module;

  • ADMINIX_IMPORT_COLUMN_RULE_INVALID for invalid row validation rule values;

  • ADMINIX_IMPORT_HANDLER_MISSING when a queued import has no handler;

  • ADMINIX_IMPORT_HANDLER_INVALID when a queued import handler is not a valid class, object, or callable;

  • ADMINIX_IMPORT_PROGRESS_TRIGGER_NOT_FOUND when progressTrigger() does not match a same-page ProgressBarModule.

Last modified: 01 July 2026