Models Resources

Import / Export

Basics

By default, import and export are enabled for all model resources.
To override this behavior, you need to change the moonshine configuration.

// config/moonshine.php 'model_resources' => [ 'default_with_import' => false, 'default_with_export' => false, ],
// config/moonshine.php
 
'model_resources' => [
'default_with_import' => false,
'default_with_export' => false,
],

You can also disable import and export in a resource; for this, the corresponding methods must return null.

namespace App\MoonShine\Resources; use App\Models\Post; use MoonShine\Resources\ModelResource; class PostResource extends ModelResource { protected string $model = Post::class; protected string $title = 'Posts'; public function import(): ?ImportHandler { return null; } public function export(): ?ExportHandler { return null; } //... }
namespace App\MoonShine\Resources;
 
use App\Models\Post;
use MoonShine\Resources\ModelResource;
 
class PostResource extends ModelResource
{
protected string $model = Post::class;
 
protected string $title = 'Posts';
 
public function import(): ?ImportHandler
{
return null;
}
 
public function export(): ?ExportHandler
{
return null;
}
 
//...
}

Import

You can import data into the MoonShine admin panel.

Fields

The fields that will participate in the import are required in the model resource, add useOnImport() method.

useOnImport(mixed $condition = null, ?Closure $fromRaw = null)
useOnImport(mixed $condition = null, ?Closure $fromRaw = null)
  • $condition - method execution condition,
  • $fromRaw - a closure that returns values from the raw.
namespace App\MoonShine\Resources; use App\Enums\StatusEnum; use App\Models\Post; use MoonShine\Fields\Enum; use MoonShine\Fields\ID; use MoonShine\Resources\ModelResource; class PostResource extends ModelResource { protected string $model = Post::class; protected string $title = 'Posts'; //... public function fields(): array { return [ ID::make() ->useOnImport(), Enum::make('Status') ->attach(StatusEnum::class) ->useOnImport(fromRaw: static fn(string $raw, Enum $ctx) => StatusEnum::tryFrom($raw)), ]; } //... }
namespace App\MoonShine\Resources;
 
use App\Enums\StatusEnum;
use App\Models\Post;
use MoonShine\Fields\Enum;
use MoonShine\Fields\ID;
use MoonShine\Resources\ModelResource;
 
class PostResource extends ModelResource
{
protected string $model = Post::class;
 
protected string $title = 'Posts';
 
//...
 
public function fields(): array
{
return [
ID::make()
->useOnImport(),
 
Enum::make('Status')
->attach(StatusEnum::class)
->useOnImport(fromRaw: static fn(string $raw, Enum $ctx) => StatusEnum::tryFrom($raw)),
];
}
 
//...
}

Be sure to add ID to the import, otherwise, records will only be added without updating existing ones.

Handler

It is also necessary to implement the import() method in the model resource. The method must return an ImportHandler object that implements the data import algorithm.

namespace App\MoonShine\Resources; use App\Models\Post; use MoonShine\Handlers\ImportHandler; use MoonShine\Resources\ModelResource; class PostResource extends ModelResource { protected string $model = Post::class; protected string $title = 'Posts'; //... public function import(): ?ImportHandler { return ImportHandler::make('Import'); } //... }
namespace App\MoonShine\Resources;
 
use App\Models\Post;
use MoonShine\Handlers\ImportHandler;
use MoonShine\Resources\ModelResource;
 
class PostResource extends ModelResource
{
protected string $model = Post::class;
 
protected string $title = 'Posts';
 
//...
 
public function import(): ?ImportHandler
{
return ImportHandler::make('Import');
}
 
//...
}

Methods ImportHandler

Optional methods are available to configure import:

use MoonShine\Handlers\ImportHandler; //... public function import(): ?ImportHandler { return ImportHandler::make('Import') // Specify the ID of the users who will receive a notification about the end of the operation ->notifyUsers(fn() => [auth()->id()]) // Disc selection ->disk('public') // Selecting a directory to save the import file ->dir('/imports') // Delete file after import ->deleteAfter() // Separator for csv ->delimiter(','); } //...
use MoonShine\Handlers\ImportHandler;
 
//...
 
public function import(): ?ImportHandler
{
return ImportHandler::make('Import')
// Specify the ID of the users who will receive a notification about the end of the operation
->notifyUsers(fn() => [auth()->id()])
// Disc selection
->disk('public')
// Selecting a directory to save the import file
->dir('/imports')
// Delete file after import
->deleteAfter()
// Separator for csv
->delimiter(',');
}
 
//...

If the import() method returns NULL, then the import button will not appear on the index page.

Events

To change the import logic, you can use events of the model resource.

// MoonShine\Resources\ModelResource public function beforeImportFilling(array $data): array { return $data; } public function beforeImported(Model $item): Model { return $item; } public function afterImported(Model $item): Model { return $item; }
// MoonShine\Resources\ModelResource
 
public function beforeImportFilling(array $data): array
{
return $data;
}
 
public function beforeImported(Model $item): Model
{
return $item;
}
 
public function afterImported(Model $item): Model
{
return $item;
}

These events are called in ImportHandler

// MoonShine\Handlers\ImportHandler $data = $resource->beforeImportFilling($data); $item->forceFill($data); $item = $resource->beforeImported($item); return tap( $item->save(), fn() => $resource->afterImported($item) );
// MoonShine\Handlers\ImportHandler
 
$data = $resource->beforeImportFilling($data);
 
$item->forceFill($data);
 
$item = $resource->beforeImported($item);
 
return tap(
$item->save(),
fn() => $resource->afterImported($item)
);

Export

In the MoonShine admin panel you can export all data taking into account the current filtering and sorting.

By default, data is exported in xlsx format, but there is an option to change the format to csv globally or through the csv() method of the class ExportHandler.

Global export format

You can change the export format globally in MoonShineServiceProvider:

use MoonShine\Providers\MoonShineApplicationServiceProvider; use MoonShine\Resources\ModelResource; class MoonShineServiceProvider extends MoonShineApplicationServiceProvider { public function boot(): void { parent::boot(); ModelResource::defaultExportToCsv(); } }
use MoonShine\Providers\MoonShineApplicationServiceProvider;
use MoonShine\Resources\ModelResource;
 
class MoonShineServiceProvider extends MoonShineApplicationServiceProvider
{
public function boot(): void
{
parent::boot();
 
ModelResource::defaultExportToCsv();
}
}

Fields

Only those fields that have the showOnExport() method added will participate in the export.

showOnExport(mixed $condition = null, ?Closure $modifyRawValue = null)
showOnExport(mixed $condition = null, ?Closure $modifyRawValue = null)
  • $condition - method execution condition,
  • $modifyRawValue - closure to get the raw value.
namespace App\MoonShine\Resources; use App\Enums\StatusEnum; use App\Models\Post; use MoonShine\Fields\Enum; use MoonShine\Fields\Text; use MoonShine\Resources\ModelResource; class PostResource extends ModelResource { protected string $model = Post::class; protected string $title = 'Posts'; //... public function fields(): array { return [ Text::make('Title', 'title') ->showOnExport(), Enum::make('Status') ->attach(StatusEnum::class) ->showOnExport(modifyRawValue: static fn(StatusEnum $raw, Enum $ctx) => $raw->value), ]; } //... }
namespace App\MoonShine\Resources;
 
use App\Enums\StatusEnum;
use App\Models\Post;
use MoonShine\Fields\Enum;
use MoonShine\Fields\Text;
use MoonShine\Resources\ModelResource;
 
class PostResource extends ModelResource
{
protected string $model = Post::class;
 
protected string $title = 'Posts';
 
//...
 
public function fields(): array
{
return [
Text::make('Title', 'title')
->showOnExport(),
 
Enum::make('Status')
->attach(StatusEnum::class)
->showOnExport(modifyRawValue: static fn(StatusEnum $raw, Enum $ctx) => $raw->value),
];
}
 
//...
}

Handler

It is also necessary to implement the export() method in the model resource. The method must return an ExportHandler object that implements the data export algorithm.

namespace App\MoonShine\Resources; use App\Models\Post; use MoonShine\Handlers\ExportHandler; use MoonShine\Resources\ModelResource; class PostResource extends ModelResource { protected string $model = Post::class; protected string $title = 'Posts'; //... public function export(): ?ExportHandler { return ExportHandler::make('Export'); } //... }
namespace App\MoonShine\Resources;
 
use App\Models\Post;
use MoonShine\Handlers\ExportHandler;
use MoonShine\Resources\ModelResource;
 
class PostResource extends ModelResource
{
protected string $model = Post::class;
 
protected string $title = 'Posts';
 
//...
 
public function export(): ?ExportHandler
{
return ExportHandler::make('Export');
}
 
//...
}

Methods ExportHandler

Optional methods are available to configure export:

use MoonShine\Handlers\ExportHandler; //... public function export(): ?ExportHandler { return ExportHandler::make('Export') // Specify the ID of the users who will receive a notification about the end of the operation ->notifyUsers(fn() => [auth()->id()]) // Disc selection ->disk('public') // File name ->filename(sprintf('export_%s', date('Ymd-His'))) // Selecting the directory for saving the export file ->dir('/exports') // If you need to export in csv format ->csv() // Separator for csv ->delimiter(',') // Export with confirmation ->withConfirm(); } //...
use MoonShine\Handlers\ExportHandler;
 
//...
 
public function export(): ?ExportHandler
{
return ExportHandler::make('Export')
// Specify the ID of the users who will receive a notification about the end of the operation
->notifyUsers(fn() => [auth()->id()])
// Disc selection
->disk('public')
// File name
->filename(sprintf('export_%s', date('Ymd-His')))
// Selecting the directory for saving the export file
->dir('/exports')
// If you need to export in csv format
->csv()
// Separator for csv
->delimiter(',')
// Export with confirmation
->withConfirm();
}
 
//...

If the export() method returns NULL, then the export button will not appear on the index page.

Handler methods

ImportHandler and ExportHandler extend the base class Handler that implements additional methods.

icon

// icon for button icon(string $icon)
// icon for button
icon(string $icon)

queue

// run processes in the background queue()
// run processes in the background
queue()

when

// conditional methods when($value = null, callable $callback = null, callable $default = null)
// conditional methods
when($value = null, callable $callback = null, callable $default = null)

$value - condition,
$callback - callback function that will be executed if the condition is true TRUE,
$default - callback function that will be executed if the condition is true FALSE.

use MoonShine\Handlers\ImportHandler; //... public function import(): ?ImportHandler { return ImportHandler::make('Import') ->when( true, fn($handler) => $handler->delimiter(','), fn($handler) => $handler->delimiter(';') ); } //...
use MoonShine\Handlers\ImportHandler;
 
//...
 
public function import(): ?ImportHandler
{
return ImportHandler::make('Import')
->when(
true,
fn($handler) => $handler->delimiter(','),
fn($handler) => $handler->delimiter(';')
);
}
 
//...

unless

// conditional methods unless($value = null, callable $callback = null, callable $default = null)
// conditional methods
unless($value = null, callable $callback = null, callable $default = null)

$value - condition,
$callback - callback function that will be executed if the condition is true FALSE,
$default - callback function that will be executed if the condition is true TRUE.

The unless() method is the when() method the inverse.

Custom implementation

There may be a situation where you want to change your import or export implementation. To do this, you need to implement your own class extending ImportHandler or ExportHandler.

The class can be generated using the console command:

php artisan moonshine:handler
php artisan moonshine:handler

After executing the command, a base handler class will be created in the app/MoonShine/Handlers directory.