PHP code example of elachagui / laravel-smart-importer

1. Go to this page and download the library: Download elachagui/laravel-smart-importer library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

elachagui / laravel-smart-importer example snippets


return [
    // Models allowed for import (security)
    'allowed_models' => [
        App\Models\User::class,
        App\Models\Product::class,
    ],

    // Default chunk size for processing
    'chunk_size' => 1000,

    // Default duplicate strategy: 'skip', 'update', 'fail'
    'duplicate_strategy' => 'skip',

    // Queue configuration
    'queue' => [
        'enabled' => false,
        'connection' => env('QUEUE_CONNECTION', 'sync'),
        'queue' => 'imports',
    ],

    // Stop on first validation error
    'stop_on_error' => false,

    // Wrap import in database transaction
    'use_transaction' => false,

    // Disable model events during import
    'disable_model_events' => false,

    // File storage configuration
    'storage' => [
        'disk' => 'local',
        'path' => 'imports',
    ],

    // CSV settings
    'csv' => [
        'delimiter' => ',',
        'enclosure' => '"',
        'escape' => '\\',
        'encoding' => 'UTF-8',
    ],

    // Logging
    'logging' => [
        'enabled' => true,
        'channel' => env('LOG_CHANNEL', 'stack'),
    ],
];

use Elachagui\SmartImporter\Facades\SmartImporter;

$import = SmartImporter::make()
    ->model(App\Models\User::class)
    ->file($request->file('file'))
    ->mapping([
        'Full Name' => 'name',
        'Email Address' => 'email',
        'Phone Number' => 'phone',
    ])
    ->import();

$import = SmartImporter::make()
    ->model(App\Models\User::class)
    ->file($request->file('file'))
    ->mapping([
        'Name' => 'name',
        'Email' => 'email',
    ])
    ->duplicateStrategy('update') // or 'skip', 'fail'
    ->import();

// Or use convenience methods
->skipDuplicates()
->updateDuplicates()
->failOnDuplicates()

use Carbon\Carbon;

$import = SmartImporter::make()
    ->model(App\Models\Product::class)
    ->file($request->file('file'))
    ->mapping([
        'Product Name' => 'name',
        'Price' => 'price',
        'Created Date' => 'created_at',
    ])
    ->transform([
        'price' => fn($value) => floatval(str_replace(['$', ','], '', $value)),
        'created_at' => fn($value) => Carbon::parse($value),
    ])
    ->import();

$import = SmartImporter::make()
    ->model(App\Models\User::class)
    ->file($request->file('file'))
    ->mapping([
        'Name' => 'name',
        'Email' => 'email',
    ])
    ->queue() // Use default queue
    // or
    ->queue('redis', 'high-priority') // Custom connection and queue
    ->import();

$import = SmartImporter::make()
    ->model(App\Models\User::class)
    ->file($request->file('file'))
    ->mapping([
        'Name' => 'name',
        'Email' => 'email',
    ])
    ->chunkSize(500)
    ->uniqueBy(['email'])
    ->stopOnError()
    ->withTransaction()
    ->withoutModelEvents()
    ->import();

$preview = SmartImporter::make()
    ->file($request->file('file'))
    ->preview(10);

// Returns:
// [
//     'headers' => ['Name', 'Email', 'Phone'],
//     'rows' => [...],
//     'total_rows' => 100,
// ]

$headers = SmartImporter::make()
    ->file($request->file('file'))
    ->getHeaders();

// Returns: ['Name', 'Email', 'Phone']

use App\Models\Product;
use App\Models\Category;

$import = SmartImporter::make()
    ->model(Product::class)
    ->file($file)
    ->mapping([
        'SKU' => 'sku',
        'Name' => 'name',
        'Price' => 'price',
    ])
    ->relations([
        'category' => [
            'type' => 'belongsTo',
            'model' => Category::class,
            'file_column' => 'Category Name',    // Column in CSV/Excel
            'lookup_by' => 'name',               // Column to search in categories table
            'create_if_missing' => true,         // Create category if not found
            'create_mapping' => [                // Optional: map additional fields when creating
                'Category Name' => 'name',
                'Category Slug' => 'slug',
            ],
            'defaults' => [                      // Optional: default values when creating
                'active' => true,
            ],
            'foreign_key' => 'category_id',      // Optional: explicit foreign key (auto-detected)
            'owner_key' => 'id',                 // Optional: parent's key column (default: 'id')
        ],
    ])
    ->import();

->relations([
    'warehouse' => [
        'type' => 'belongsTo',
        'model' => Warehouse::class,
        'file_columns' => ['Region Code', 'Warehouse Code'],
        'lookup_columns' => ['region_code', 'code'],
    ],
])

use App\Models\Order;
use App\Models\OrderItem;

$import = SmartImporter::make()
    ->model(Order::class)
    ->file($file)
    ->mapping([
        'Order Number' => 'order_number',
        'Total' => 'total',
    ])
    ->relations([
        // HasMany with column mapping
        'items' => [
            'type' => 'hasMany',
            'model' => OrderItem::class,
            'foreign_key' => 'order_id',
            'mapping' => [
                'Item Name' => 'product_name',
                'Quantity' => 'quantity',
                'Unit Price' => 'price',
            ],
        ],
    ])
    ->import();

->relations([
    'variants' => [
        'type' => 'hasMany',
        'model' => ProductVariant::class,
        'foreign_key' => 'product_id',
        'file_column' => 'Sizes',           // e.g., "S,M,L,XL"
        'separator' => ',',
        'mapping' => ['Sizes' => 'size'],
        'defaults' => ['stock' => 0],
    ],
])

->relations([
    'items' => [
        'type' => 'hasMany',
        'model' => OrderItem::class,
        'foreign_key' => 'order_id',
        'file_column' => 'Items JSON',
        // File contains: [{"name":"Widget","qty":2},{"name":"Gadget","qty":1}]
    ],
])

use App\Models\Product;
use App\Models\Tag;

$import = SmartImporter::make()
    ->model(Product::class)
    ->file($file)
    ->mapping([
        'SKU' => 'sku',
        'Name' => 'name',
    ])
    ->relations([
        'tags' => [
            'type' => 'belongsToMany',
            'model' => Tag::class,
            'file_column' => 'Tags',             // e.g., "electronics,featured,sale"
            'lookup_by' => 'name',               // Find tags by name
            'separator' => ',',                  // How values are separated
            'create_if_missing' => true,         // Create tags that don't exist
            'sync_mode' => 'sync',               // 'sync', 'attach', 'toggle', 'syncWithoutDetaching'
            'pivot_data' => [                    // Optional: data for pivot table
                'assigned_by' => 'import',
            ],
            'pivot_columns' => [                 // Optional: map file columns to pivot columns
                'Tag Priority' => 'priority',
            ],
        ],
    ])
    ->import();

use App\Models\Product;
use App\Models\Comment;

$import = SmartImporter::make()
    ->model(Product::class)
    ->file($file)
    ->mapping([
        'SKU' => 'sku',
        'Name' => 'name',
    ])
    ->relations([
        'comments' => [
            'type' => 'morphMany',
            'model' => Comment::class,
            'mapping' => [
                'Review' => 'body',
                'Rating' => 'rating',
            ],
        ],
    ])
    ->import();

use App\Models\Comment;
use App\Models\Product;

$import = SmartImporter::make()
    ->model(Comment::class)
    ->file($file)
    ->mapping([
        'Body' => 'body',
    ])
    ->relations([
        'commentable' => [
            'type' => 'morphTo',
            'model' => Product::class,
            'file_column' => 'Product SKU',
            'lookup_by' => 'sku',
            'morph_name' => 'commentable',       // Optional: morph name
            'create_if_missing' => true,
        ],
    ])
    ->import();

->relations([
    'tags' => [
        'type' => 'morphToMany',
        'model' => Tag::class,
        'file_column' => 'Tags',
        'lookup_by' => 'name',
        'separator' => ',',
        'create_if_missing' => true,
    ],
])

use App\Models\Country;
use App\Models\User;
use App\Models\Post;

$import = SmartImporter::make()
    ->model(Country::class)
    ->file($file)
    ->mapping([
        'Country Name' => 'name',
    ])
    ->relations([
        'posts' => [
            'type' => 'hasManyThrough',
            'model' => Post::class,
            'through_model' => User::class,
            'first_key' => 'country_id',         // Foreign key on User
            'second_key' => 'user_id',           // Foreign key on Post
            'through_mapping' => [               // Create the intermediate User
                'Author Name' => 'name',
                'Author Email' => 'email',
            ],
            'mapping' => [                       // Create the Post
                'Post Title' => 'title',
                'Post Body' => 'body',
            ],
        ],
    ])
    ->import();

use Elachagui\SmartImporter\Contracts\Importable;
use Illuminate\Database\Eloquent\Model;

class Product extends Model implements Importable
{
    public static function importRules(): array
    {
        return [
            'sku' => 'rtRelations(): array
    {
        return [
            'category' => [
                'type' => 'belongsTo',
                'model' => Category::class,
                'file_column' => 'category_name',
                'lookup_by' => 'name',
                'create_if_missing' => true,
            ],
            'tags' => [
                'type' => 'belongsToMany',
                'model' => Tag::class,
                'file_column' => 'tags',
                'lookup_by' => 'name',
                'separator' => ',',
                'create_if_missing' => true,
            ],
        ];
    }
}

$import = SmartImporter::make()
    ->model(Product::class)
    ->file($file)
    ->mapping([
        'SKU' => 'sku',
        'Name' => 'name',
        'Price' => 'price',
    ])
    ->import(); // Relations are auto-loaded from model

$import = SmartImporter::make()
    ->model(Order::class)
    ->file($file)
    ->mapping([
        'Order Number' => 'order_number',
        'Total' => 'total',
    ])
    ->relations([
        // BelongsTo: Set customer_id
        'customer' => [
            'type' => 'belongsTo',
            'model' => Customer::class,
            'file_column' => 'Customer Email',
            'lookup_by' => 'email',
            'create_if_missing' => true,
            'create_mapping' => [
                'Customer Email' => 'email',
                'Customer Name' => 'name',
            ],
        ],
        // HasMany: Create order items
        'items' => [
            'type' => 'hasMany',
            'model' => OrderItem::class,
            'foreign_key' => 'order_id',
            'mapping' => [
                'Product' => 'product_name',
                'Qty' => 'quantity',
                'Price' => 'price',
            ],
        ],
        // BelongsToMany: Sync tags
        'tags' => [
            'type' => 'belongsToMany',
            'model' => Tag::class,
            'file_column' => 'Tags',
            'lookup_by' => 'name',
            'separator' => ',',
            'create_if_missing' => true,
        ],
        // MorphMany: Add comments
        'comments' => [
            'type' => 'morphMany',
            'model' => Comment::class,
            'mapping' => [
                'Note' => 'body',
            ],
        ],
    ])
    ->import();

use Elachagui\SmartImporter\Contracts\Importable;
use Illuminate\Database\Eloquent\Model;

class User extends Model implements Importable
{
    public static function importRules(): array
    {
        return [
            'name' => ' Define relations for import
    public static function importRelations(): array
    {
        return [
            // ... relation definitions
        ];
    }
}

use Elachagui\SmartImporter\Models\Import;

$import = Import::find($id);

// Access import data
$import->model;           // Target model class
$import->file_path;       // Path to imported file
$import->total_rows;      // Total rows in file
$import->processed_rows;  // Rows processed
$import->success_rows;    // Successfully imported
$import->failed_rows;     // Failed rows
$import->skipped_rows;    // Skipped (duplicates)
$import->status;          // pending, processing, completed, failed, cancelled
$import->mapping;         // Column mapping (array)
$import->started_at;      // When import started
$import->finished_at;     // When import finished

// Check status
$import->isPending();
$import->isProcessing();
$import->isCompleted();
$import->isFailed();
$import->isCancelled();

// Get progress
$import->getProgressPercentage(); // Returns 0-100

// Get errors
$import->errors; // HasMany relationship to ImportError

$import = SmartImporter::find($id);

SmartImporter::cancel($import);

use Elachagui\SmartImporter\Events\ImportStarted;
use Elachagui\SmartImporter\Events\ImportCompleted;
use Elachagui\SmartImporter\Events\ImportFailed;
use Elachagui\SmartImporter\Events\RowImported;

// In your EventServiceProvider
protected $listen = [
    ImportStarted::class => [
        SendImportStartedNotification::class,
    ],
    ImportCompleted::class => [
        SendImportCompletedNotification::class,
    ],
    ImportFailed::class => [
        SendImportFailedNotification::class,
    ],
    RowImported::class => [
        ProcessImportedRow::class,
    ],
];

// ImportStarted
public Import $import;

// ImportCompleted
public Import $import;
public function getSummary(): array; // Returns summary data

// ImportFailed
public Import $import;
public Throwable $exception;
public function getErrorMessage(): string;
public function getErrorDetails(): array;

// RowImported
public Import $import;
public int $rowNumber;
public array $data;
public string $action; // 'created' or 'updated'
public function wasCreated(): bool;
public function wasUpdated(): bool;

use Elachagui\SmartImporter\Exceptions\ImportException;

try {
    $import = SmartImporter::make()
        ->model(App\Models\User::class)
        ->file($file)
        ->mapping($mapping)
        ->import();
} catch (ImportException $e) {
    // Handle import-specific errors
    $message = $e->getMessage();
    $rowNumber = $e->getRowNumber();
    $rowData = $e->getRowData();
    $context = $e->getContext();
}



namespace App\Http\Controllers;

use App\Models\Product;
use App\Models\Category;
use App\Models\Tag;
use Elachagui\SmartImporter\Facades\SmartImporter;
use Elachagui\SmartImporter\Exceptions\ImportException;
use Illuminate\Http\Request;

class ProductImportController extends Controller
{
    public function preview(Request $request)
    {
        $request->validate([
            'file' => '          ->model(Product::class)
                ->file($request->file('file'))
                ->mapping([
                    'SKU' => 'sku',
                    'Product Name' => 'name',
                    'Price' => 'price',
                ])
                ->relations([
                    'category' => [
                        'type' => 'belongsTo',
                        'model' => Category::class,
                        'file_column' => 'Category',
                        'lookup_by' => 'name',
                        'create_if_missing' => true,
                    ],
                    'tags' => [
                        'type' => 'belongsToMany',
                        'model' => Tag::class,
                        'file_column' => 'Tags',
                        'lookup_by' => 'name',
                        'separator' => ',',
                        'create_if_missing' => true,
                    ],
                ])
                ->transform([
                    'price' => fn($v) => floatval(str_replace(['$', ','], '', $v)),
                ])
                ->updateDuplicates()
                ->queue()
                ->import();

            return response()->json([
                'message' => 'Import queued successfully',
                'import_id' => $import->id,
            ]);
        } catch (ImportException $e) {
            return response()->json([
                'message' => $e->getMessage(),
            ], 422);
        }
    }

    public function status(int $id)
    {
        $import = SmartImporter::findWithErrors($id);

        if (!$import) {
            return response()->json(['message' => 'Import not found'], 404);
        }

        return response()->json([
            'status' => $import->status,
            'progress' => $import->getProgressPercentage(),
            'total_rows' => $import->total_rows,
            'processed_rows' => $import->processed_rows,
            'success_rows' => $import->success_rows,
            'failed_rows' => $import->failed_rows,
            'skipped_rows' => $import->skipped_rows,
            'errors' => $import->errors->map(fn($e) => [
                'row' => $e->row_number,
                'errors' => $e->errors,
            ]),
        ]);
    }

    public function cancel(int $id)
    {
        $import = SmartImporter::find($id);

        if (!$import) {
            return response()->json(['message' => 'Import not found'], 404);
        }

        $cancelled = SmartImporter::cancel($import);

        return response()->json([
            'cancelled' => $cancelled,
        ]);
    }
}
bash
php artisan vendor:publish --tag=smart-importer-config
bash
php artisan migrate