Add asset import/export and local dev server setup
- Configure Vite dev server with localhost binding and public asset proxy - Add npm scripts for concurrent Laravel/Vite development (dev:local, dev:test) - Implement asset import/export in ACP via ZIP file upload/download - Create AssetController for asset management endpoints - Add asset management UI tab in admin panel
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use ZipArchive;
|
||||
|
||||
class AssetController extends Controller
|
||||
{
|
||||
public function export(): \Symfony\Component\HttpFoundation\StreamedResponse
|
||||
{
|
||||
$user = auth()->user();
|
||||
if (!$user || !$user->roles()->where('name', 'ROLE_ADMIN')->exists()) {
|
||||
abort(403, 'Forbidden');
|
||||
}
|
||||
|
||||
$storagePublic = storage_path('app/public');
|
||||
$zip = new ZipArchive();
|
||||
$zipPath = storage_path('exports/assets-'.date('YmdHis').'.zip');
|
||||
|
||||
if (!is_dir(storage_path('exports'))) {
|
||||
mkdir(storage_path('exports'), 0775, true);
|
||||
}
|
||||
|
||||
if ($zip->open($zipPath, ZipArchive::CREATE) === true) {
|
||||
$this->addDirectoryToZip($zip, $storagePublic, '');
|
||||
$zip->close();
|
||||
}
|
||||
|
||||
return response()->download($zipPath)->deleteFileAfterSend(true);
|
||||
}
|
||||
|
||||
public function import(Request $request): JsonResponse
|
||||
{
|
||||
$user = $request->user();
|
||||
if (!$user || !$user->roles()->where('name', 'ROLE_ADMIN')->exists()) {
|
||||
return response()->json(['message' => 'Forbidden'], 403);
|
||||
}
|
||||
|
||||
$data = $request->validate([
|
||||
'file' => ['required', 'file', 'mimes:zip', 'max:104857600'],
|
||||
]);
|
||||
|
||||
$file = $data['file'];
|
||||
$zip = new ZipArchive();
|
||||
$zipPath = $file->getPathname();
|
||||
|
||||
if ($zip->open($zipPath) !== true) {
|
||||
return response()->json(['message' => 'Invalid zip file'], 400);
|
||||
}
|
||||
|
||||
$storagePublic = storage_path('app/public');
|
||||
|
||||
for ($i = 0; $i < $zip->numFiles; $i++) {
|
||||
$filename = $zip->getNameIndex($i);
|
||||
$fileinfo = $zip->statIndex($i);
|
||||
|
||||
if ($fileinfo['crc'] == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$targetPath = $storagePublic.DIRECTORY_SEPARATOR.$filename;
|
||||
$targetDir = dirname($targetPath);
|
||||
|
||||
if (!is_dir($targetDir)) {
|
||||
mkdir($targetDir, 0775, true);
|
||||
}
|
||||
|
||||
copy('zip://'.$zipPath.'#'.$filename, $targetPath);
|
||||
}
|
||||
|
||||
$zip->close();
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Assets imported successfully',
|
||||
]);
|
||||
}
|
||||
|
||||
private function addDirectoryToZip(ZipArchive $zip, string $dir, string $zipPath): void
|
||||
{
|
||||
$files = scandir($dir);
|
||||
|
||||
foreach ($files as $file) {
|
||||
if ($file === '.' || $file === '..') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$path = $dir.DIRECTORY_SEPARATOR.$file;
|
||||
$zipPath = $zipPath === '' ? $file : $zipPath.'/'.$file;
|
||||
|
||||
if (is_dir($path)) {
|
||||
$zip->addEmptyDir($zipPath);
|
||||
$this->addDirectoryToZip($zip, $path, $zipPath);
|
||||
} else {
|
||||
$zip->addFile($path, $zipPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user