6d6f5d571a
- Admin panel page at #Admin/dataMigration with two-column layout - Export: filter by case status, skip attachments option, progress + log - Import: select backup, preserve IDs / skip duplicates, dry run support - List/delete existing backups with full manifest details - 5 API endpoints (status, export, import, listBackups, deleteBackup) - BufferedIO adapter to capture CLI output for API responses - Admin-only access on all endpoints - i18n: English + Hebrew (fa_IR) translations Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
54 lines
1.4 KiB
PHP
54 lines
1.4 KiB
PHP
<?php
|
|
|
|
namespace Espo\Modules\DataMigration\Api;
|
|
|
|
use Espo\Core\Api\Action;
|
|
use Espo\Core\Api\Request;
|
|
use Espo\Core\Api\Response;
|
|
use Espo\Core\Api\ResponseComposer;
|
|
use Espo\Core\Exceptions\Forbidden;
|
|
use Espo\Entities\User;
|
|
use Espo\Modules\DataMigration\Services\ExportService;
|
|
use Espo\Modules\DataMigration\Services\BufferedIO;
|
|
|
|
class Export implements Action
|
|
{
|
|
public function __construct(
|
|
private ExportService $exportService,
|
|
private User $user
|
|
) {}
|
|
|
|
public function process(Request $request): Response
|
|
{
|
|
if (!$this->user->isAdmin()) {
|
|
throw new Forbidden();
|
|
}
|
|
|
|
$body = $request->getParsedBody();
|
|
|
|
$caseIds = $body->caseIds ?? null;
|
|
$caseStatus = $body->caseStatus ?? null;
|
|
$noFiles = $body->noFiles ?? false;
|
|
|
|
$timestamp = date('Ymd-His');
|
|
$outputDir = 'data/backups/datamigration-' . $timestamp;
|
|
|
|
$io = new BufferedIO();
|
|
|
|
$this->exportService->export($outputDir, [
|
|
'batchSize' => 500,
|
|
'caseIds' => $caseIds,
|
|
'caseStatus' => is_array($caseStatus) && !empty($caseStatus) ? $caseStatus : null,
|
|
'noFiles' => $noFiles,
|
|
'verbose' => true,
|
|
], $io);
|
|
|
|
return ResponseComposer::json([
|
|
'success' => true,
|
|
'outputDir' => $outputDir,
|
|
'backupName' => 'datamigration-' . $timestamp,
|
|
'log' => $io->getLines(),
|
|
]);
|
|
}
|
|
}
|