Files
esun3d/app/code/Esun/Catalog/Model/CertificationFileUploader.php
T
2026-09-15 10:35:56 +08:00

134 lines
4.5 KiB
PHP

<?php
declare(strict_types=1);
namespace Esun\Catalog\Model;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Filesystem;
use Magento\Framework\UrlInterface;
use Magento\MediaStorage\Model\File\UploaderFactory;
use Magento\Store\Model\StoreManagerInterface;
class CertificationFileUploader
{
private const BASE_TMP_PATH = 'tmp/esun/catalog/certification';
private const BASE_PATH = 'esun/catalog/certification';
private const PRODUCT_BASE_PATH = self::BASE_PATH . '/product';
private const ALLOWED_EXTENSIONS = ['pdf', 'doc', 'docx', 'zip', 'rar', '7z'];
public function __construct(
private readonly UploaderFactory $uploaderFactory,
private readonly Filesystem $filesystem,
private readonly StoreManagerInterface $storeManager
) {
}
public function saveFileToTmpDir(string $fileId): array
{
$mediaDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::MEDIA);
$mediaDirectory->create(self::BASE_TMP_PATH);
$uploader = $this->uploaderFactory->create(['fileId' => $fileId]);
$uploader->setAllowedExtensions(self::ALLOWED_EXTENSIONS);
$uploader->setAllowRenameFiles(true);
$uploader->setFilesDispersion(false);
$result = $uploader->save($mediaDirectory->getAbsolutePath(self::BASE_TMP_PATH));
if (!$result || empty($result['file'])) {
throw new LocalizedException(__('The certification file could not be uploaded.'));
}
$file = ltrim((string)$result['file'], '/');
$relativePath = self::BASE_TMP_PATH . '/' . $file;
$result['file'] = $relativePath;
$result['name'] = (string)($result['name'] ?? basename($file));
$result['url'] = $this->getMediaUrl($relativePath);
return $result;
}
public function moveFileFromTmp(string $file, string $sku = ''): string
{
$file = $this->normalizePath($file);
if ($file === '') {
return '';
}
if (str_starts_with($file, self::BASE_PATH . '/')) {
return $file;
}
$basename = basename($file);
$tmpPath = str_starts_with($file, self::BASE_TMP_PATH . '/')
? $file
: self::BASE_TMP_PATH . '/' . $basename;
$targetDirectory = $this->getTargetDirectory($sku);
$targetPath = $targetDirectory . '/' . $basename;
$mediaDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::MEDIA);
if (!$mediaDirectory->isExist($tmpPath)) {
return $file;
}
$mediaDirectory->create($targetDirectory);
if ($mediaDirectory->isExist($targetPath)) {
$targetPath = $targetDirectory . '/' . $this->getUniqueFilename($targetDirectory, $basename);
}
$mediaDirectory->renameFile($tmpPath, $targetPath);
return $targetPath;
}
public function getAllowedExtensions(): array
{
return self::ALLOWED_EXTENSIONS;
}
private function normalizePath(string $value): string
{
$path = parse_url($value, PHP_URL_PATH) ?: $value;
$marker = '/media/';
$position = strpos($path, $marker);
if ($position !== false) {
$path = substr($path, $position + strlen($marker));
}
return ltrim($path, '/');
}
private function getTargetDirectory(string $sku): string
{
$sku = trim($sku);
if ($sku === '') {
return self::BASE_PATH;
}
$safeSku = preg_replace('/[^A-Za-z0-9._-]+/', '_', $sku) ?: '';
$safeSku = trim($safeSku, '._-');
return $safeSku !== '' ? self::PRODUCT_BASE_PATH . '/' . $safeSku : self::BASE_PATH;
}
private function getUniqueFilename(string $targetDirectory, string $basename): string
{
$mediaDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::MEDIA);
$info = pathinfo($basename);
$filename = $info['filename'] ?? 'certification';
$extension = isset($info['extension']) ? '.' . $info['extension'] : '';
$candidate = $basename;
$index = 1;
while ($mediaDirectory->isExist($targetDirectory . '/' . $candidate)) {
$candidate = $filename . '_' . $index . $extension;
$index++;
}
return $candidate;
}
private function getMediaUrl(string $path): string
{
return $this->storeManager->getStore()->getBaseUrl(UrlInterface::URL_TYPE_MEDIA) . ltrim($path, '/');
}
}