134 lines
4.5 KiB
PHP
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, '/');
|
|
}
|
|
}
|