Importers

Validation

Validate imported data with per-field rules, type-specific parsing, and inline corrections.

Tapix validates imported data at multiple stages: during column mapping, during the review step, and before saving. Validation errors are surfaced inline so users can fix problems before committing the import.

Per-Field Validation

Define validation rules on each field using the ->rules() method. These accept standard Laravel validation rules as an array.

app/Importers/ContactImporter.php
use Tapix\Core\Fields\ImportField;

ImportField::make('email')
    ->rules(['required', 'email', 'max:255']);

ImportField::make('age')
    ->rules(['required', 'integer', 'min:0', 'max:150']);

ImportField::make('website')
    ->rules(['nullable', 'url']);

The ->required() method is a shorthand that adds the required rule:

app/Importers/ContactImporter.php
ImportField::make('name')->required();
// Equivalent to: ImportField::make('name')->rules(['required']);

The ->nullable() method adds the nullable rule:

app/Importers/ContactImporter.php
ImportField::make('middle_name')->nullable();

FieldType Default Rules

When you assign a FieldType to a field, Tapix automatically applies type-appropriate validation rules. You do not need to manually add these -- they are merged with any custom rules you define.

FieldTypeDefault Rule Applied
Emailemail
Phonephone:AUTO
Urlurl
NumberNumeric parsing/validation
CurrencyNumeric parsing/validation
DateDate format parsing
DateTimeDateTime format parsing
BooleanBoolean value validation
ChoiceValidates against options
MultiChoiceValidates against options
app/Importers/ContactImporter.php
use Tapix\Core\Enums\FieldType;

// The 'email' rule is added automatically by the Email type
ImportField::make('email')
    ->type(FieldType::Email)
    ->rules(['required', 'max:255']);

Type-Specific Parsing and Validation

During the review step, Tapix applies type-aware parsing to handle real-world data formats.

Date Fields

Date values are parsed against the DateFormat enum, which supports multiple common formats:

FormatPatternExample
ISOY-m-d2024-03-15
Europeand/m/Y15/03/2024
Americanm/d/Y03/15/2024

Tapix auto-detects the date format from the imported data and parses all values in the column consistently.

Number Fields

Numeric values are parsed against the NumberFormat enum, handling different locale conventions:

FormatThousandsDecimalExample
Point,.1,000.50
Comma.,1.000,50

Boolean Fields

Boolean fields accept a range of truthy and falsy values:

  • Truthy: true, yes, 1, on
  • Falsy: false, no, 0, off

Values are case-insensitive.

Choice Fields

Choice and MultiChoice fields validate each value against the defined options array. Any value not present in the options list is flagged as a validation error.

app/Importers/ContactImporter.php
ImportField::make('status')
    ->type(FieldType::Choice)
    ->options([
        ['label' => 'Active', 'value' => 'active'],
        ['label' => 'Inactive', 'value' => 'inactive'],
    ]);

Email and Phone Fields

  • Email: Validated using Laravel's built-in email rule.
  • Phone: Validated using the phone:AUTO rule, which auto-detects the country format.

Column-Level Validation

When an import reaches the review step, Tapix runs a ValidateColumnJob for each mapped column. This job validates all cell values in the column against the field's rules and type constraints, then stores the results so users can see which rows have issues.

This validation runs asynchronously as part of the queue-powered processing pipeline.

Corrections

When validation errors are found, users can fix them directly in the review step. The Tapix UI displays each error alongside the original value, allowing users to:

  • Edit the value -- type a corrected value that satisfies the validation rules.
  • Skip the value -- mark an individual cell to be excluded from the import.

Corrections are stored per-row and applied during the final import processing. The original CSV data is never modified.

Custom Validation Rules

Any Laravel validation rule can be used in the ->rules() array, including custom rule classes:

app/Importers/ProductImporter.php
use App\Rules\ValidProductCode;

ImportField::make('product_code')
    ->rules(['required', new ValidProductCode]);

You can also use closure-based rules:

app/Importers/ProductImporter.php
ImportField::make('sku')
    ->rules([
        'required',
        function (string $attribute, mixed $value, Closure $fail) {
            if (! preg_match('/^[A-Z]{3}-\d{4}$/', $value)) {
                $fail("The {$attribute} must match the format ABC-1234.");
            }
        },
    ]);

Full Example

app/Importers/EmployeeImporter.php
use App\Rules\ValidProductCode;
use Tapix\Core\Enums\FieldType;
use Tapix\Core\Fields\ImportField;
use Tapix\Core\Fields\ImportFieldCollection;

public function fields(): ImportFieldCollection
{
    return ImportFieldCollection::make([
        ImportField::id(),
        ImportField::make('name')
            ->required()
            ->rules(['string', 'max:255']),
        ImportField::make('email')
            ->type(FieldType::Email)
            ->required()
            ->rules(['max:255']),
        ImportField::make('phone')
            ->type(FieldType::Phone)
            ->nullable(),
        ImportField::make('hire_date')
            ->type(FieldType::Date)
            ->required(),
        ImportField::make('salary')
            ->type(FieldType::Currency)
            ->rules(['min:0']),
        ImportField::make('is_active')
            ->type(FieldType::Boolean),
        ImportField::make('department')
            ->type(FieldType::Choice)
            ->required()
            ->options([
                ['label' => 'Engineering', 'value' => 'engineering'],
                ['label' => 'Marketing', 'value' => 'marketing'],
                ['label' => 'Sales', 'value' => 'sales'],
                ['label' => 'Support', 'value' => 'support'],
            ]),
        ImportField::make('product_code')
            ->rules(['required', new ValidProductCode]),
    ]);
}
Copyright © 2026