Импорт / Экспорт

# Основы

По умолчанию импорт и экспорт включены во всех ресурсах модели.
Для того чтобы переопределить это поведение, необходимо изменить конфигурацию moonshine.

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

Так же можно отключить импорт и экспорт в ресурсе, для этого соответствующие методы должны возвращать 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

В админ-панель MoonShine можно импортировать данные.

Поля

Необходимо в ресурсе модели полям, которые будут участвовать в импорте, добавить метод useOnImport().

useOnImport(mixed $condition = null, ?Closure $fromRaw = null)
  • $condition - условие выполнения метода,
  • $fromRaw - замыкание возвращающее значения из исходного.
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)),
];
}
 
//...
}

Обязательно добавляйте в импорт ID, иначе записи будут только добавляться, без обновления существующих.

Handler

Так же необходимо в ресурсе модели реализовать метод import(). Метод должен вернуть объект ImportHandler, реализующий алгоритм импорта данных.

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');
}
 
//...
}
Методы ImportHandler

Для настройки импорта доступны опциональные методы:

use MoonShine\Handlers\ImportHandler;
 
//...
 
public function import(): ?ImportHandler
{
return ImportHandler::make('Import')
// Указать id пользователей, которые получат уведомление об окончании операции
->notifyUsers(fn() => [auth()->id()])
// Выбор диска
->disk('public')
// Выбор директории для сохранения файла импорта
->dir('/imports')
// Удалять файл после импорта
->deleteAfter()
// Разделитель для csv
->delimiter(',');
}
 
//...

Если метод import() вернет NULL, то кнопка импорта не будет отображаться на индексной странице.

События

Для изменения логики работы импорта можно воспользоваться событиями ресурса модели.

// 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;
}

Данные события вызываются в ImportHandler

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

# Export

В админ-панели MoonShine можно реализовать экспорт всех данных с учетом текущей фильтрации и сортировки.

По умолчанию данные экспортируются в формате xlsx, но существует возможность изменить формат на csv глобально или через метод csv() класса ExportHandler.

Глобальный формат экспорта

Изменить формат экспорта глобально можно в MoonShineServiceProvider:

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

В экспорте будут участвовать только те поля у которых добавлен метод showOnExport().

showOnExport(mixed $condition = null, ?Closure $modifyRawValue = null)
  • $condition - условие выполнения метода,
  • $modifyRawValue - замыкание для получения необработанного значения.
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

Так же необходимо в ресурсе модели реализовать метод export(). Метод должен вернуть объект ExportHandler, реализующий алгоритм экспорта данных.

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');
}
 
//...
}
Методы ExportHandler

Для настройки экспорта доступны опциональные методы:

use MoonShine\Handlers\ExportHandler;
 
//...
 
public function export(): ?ExportHandler
{
return ExportHandler::make('Export')
// Указать id пользователей, которые получат уведомление об окончании операции
->notifyUsers(fn() => [auth()->id()])
// Выбор диска
->disk('public')
// Наименование файла
->filename(sprintf('export_%s', date('Ymd-His')))
// Выбор директории сохранения файла экспорта
->dir('/exports')
// Если необходимо экспортировать в формате csv
->csv()
// Разделитель для csv
->delimiter(',')
// Экспорт с подтверждением
->withConfirm();
}
 
//...

Если метод export() вернет NULL, то кнопка экспорта не будет отображаться на индексной странице.

# Handler методы

ImportHandler и ExportHandler расширяют базовый класс Handler который реализует дополнительные методы.

icon
// иконка для кнопки
icon(string $icon)
queue
// запускать процессы в фоне
queue()
when
// методы по условию
when($value = null, callable $callback = null, callable $default = null)

$value - условие,
$callback - callback функция, которая будет выполнена, если условие имеет значение TRUE,
$default - callback функция, которая будет выполнена, если условие имеет значение FALSE.

use MoonShine\Handlers\ImportHandler;
 
//...
 
public function import(): ?ImportHandler
{
return ImportHandler::make('Import')
->when(
true,
fn($handler) => $handler->delimiter(','),
fn($handler) => $handler->delimiter(';')
);
}
 
//...
unless
// методы по условию
unless($value = null, callable $callback = null, callable $default = null)

$value - условие,
$callback - callback функция, которая будет выполнена, если условие имеет значение FALSE,
$default - callback функция, которая будет выполнена, если условие имеет значение TRUE.

Метод unless() является обратным методу when().

# Кастомная реализация

Может возникнуть ситуация, когда вы захотите изменить реализацию импорта или экспорта. Для этого необходимо реализовать свой класс расширяющий ImportHandler или ExportHandler.

Класс можно сгенерировать, воспользовавшись консольной командой:

php artisan moonshine:handler

После выполнения команды будет создан базовый класс handler в директории app/MoonShine/Handlers.