Files
2026-09-15 10:35:56 +08:00

124 lines
3.9 KiB
PHP

<?php
declare(strict_types=1);
namespace Esun\FileManager\Controller\Adminhtml\File;
use Esun\FileManager\Model\UploadService;
use Magento\Backend\App\Action;
use Magento\Framework\App\Action\HttpPostActionInterface;
use Magento\Framework\Controller\Result\JsonFactory;
use Magento\Framework\Exception\LocalizedException;
use Psr\Log\LoggerInterface;
class Upload extends Action implements HttpPostActionInterface
{
public const ADMIN_RESOURCE = 'Esun_FileManager::upload';
public function __construct(
Action\Context $context,
private readonly JsonFactory $jsonFactory,
private readonly UploadService $uploadService,
private readonly LoggerInterface $logger
) {
parent::__construct($context);
}
public function execute()
{
$result = $this->jsonFactory->create();
$uploadedFiles = $this->normalizeFiles((array) $this->getRequest()->getFiles('files'));
if (!$uploadedFiles) {
$contentLength = (int) $this->getRequest()->getServer('CONTENT_LENGTH', 0);
$postMaxSize = $this->getPostMaxSizeBytes();
$message = $postMaxSize > 0 && $contentLength > $postMaxSize
? (string) __(
'The upload request exceeds the server limit of %1 MB.',
round($postMaxSize / 1024 / 1024, 2)
)
: (string) __('Please select at least one file.');
return $result->setData([
'error' => true,
'message' => $message,
'errors' => [],
'files' => [],
]);
}
$saved = [];
$errors = [];
foreach ($uploadedFiles as $uploadedFile) {
try {
$saved[] = $this->uploadService->upload($uploadedFile);
} catch (LocalizedException $exception) {
$errors[] = $exception->getMessage();
} catch (\Throwable $exception) {
$this->logger->critical($exception);
$errors[] = (string) __('The file could not be uploaded.');
}
}
$message = $saved
? (string) __(
'%1 file(s) uploaded successfully.',
count($saved)
)
: (string) __('No files were uploaded.');
return $result->setData([
'error' => !$saved,
'hasErrors' => count($saved) !== count($uploadedFiles),
'message' => $message,
'errors' => $errors,
'files' => $saved,
]);
}
/**
* @return array<int, array<string, mixed>>
*/
private function normalizeFiles(array $files): array
{
if (array_is_list($files)) {
return array_values(array_filter(
$files,
static fn (mixed $file): bool => is_array($file) && array_key_exists('name', $file)
));
}
if (!isset($files['name'])) {
return [];
}
if (!is_array($files['name'])) {
return [$files];
}
$normalized = [];
foreach (array_keys($files['name']) as $index) {
$normalized[] = [
'name' => $files['name'][$index] ?? '',
'type' => $files['type'][$index] ?? '',
'tmp_name' => $files['tmp_name'][$index] ?? '',
'error' => $files['error'][$index] ?? UPLOAD_ERR_NO_FILE,
'size' => $files['size'][$index] ?? 0,
];
}
return $normalized;
}
private function getPostMaxSizeBytes(): int
{
$value = trim((string) ini_get('post_max_size'));
$bytes = (int) $value;
$unit = strtolower(substr($value, -1));
return match ($unit) {
'g' => $bytes * 1024 * 1024 * 1024,
'm' => $bytes * 1024 * 1024,
'k' => $bytes * 1024,
default => $bytes,
};
}
}