124 lines
3.9 KiB
PHP
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,
|
|
};
|
|
}
|
|
}
|