167 lines
5.6 KiB
PHP
167 lines
5.6 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace Esun\Catalog\Model;
|
|
|
|
use Magento\Framework\App\Filesystem\DirectoryList;
|
|
use Magento\Framework\App\Request\Http;
|
|
use Magento\Framework\Exception\LocalizedException;
|
|
use Magento\Framework\Filesystem;
|
|
use Magento\MediaStorage\Model\File\UploaderFactory;
|
|
|
|
class SpecificationMedia
|
|
{
|
|
public const LOGO_PATH = 'esun/catalog/specifications/brand-logo';
|
|
public const ARCHIVE_PATH = 'esun/catalog/specifications/archive';
|
|
public const FILE_PATH = 'esun/catalog/specifications/file';
|
|
|
|
public function __construct(
|
|
private readonly UploaderFactory $uploaderFactory,
|
|
private readonly Filesystem $filesystem,
|
|
private readonly Http $request
|
|
) {
|
|
}
|
|
|
|
public function saveLogo(string $field): ?string
|
|
{
|
|
return $this->saveUpload($field, self::LOGO_PATH, ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg']);
|
|
}
|
|
|
|
public function saveArchive(string $field, int $brandId): ?string
|
|
{
|
|
return $this->saveUpload($field, self::ARCHIVE_PATH . '/' . $brandId, ['zip']);
|
|
}
|
|
|
|
public function hasUpload(string $field): bool
|
|
{
|
|
$file = $this->request->getFiles($field);
|
|
|
|
return is_array($file)
|
|
&& !empty($file['tmp_name'])
|
|
&& (int)($file['error'] ?? UPLOAD_ERR_NO_FILE) !== UPLOAD_ERR_NO_FILE;
|
|
}
|
|
|
|
public function writeSpecificationFile(int $brandId, string $modelName, string $fileName, string $contents): string
|
|
{
|
|
$relativeDirectory = self::FILE_PATH . '/' . $brandId . '/' . $this->sanitizePathSegment($modelName);
|
|
$relativePath = $relativeDirectory . '/' . $this->sanitizeFilename($fileName);
|
|
$media = $this->filesystem->getDirectoryWrite(DirectoryList::MEDIA);
|
|
$media->create($relativeDirectory);
|
|
$media->writeFile($relativePath, $contents);
|
|
|
|
return $relativePath;
|
|
}
|
|
|
|
public function deleteBrandFiles(int $brandId): void
|
|
{
|
|
$media = $this->filesystem->getDirectoryWrite(DirectoryList::MEDIA);
|
|
foreach ([self::ARCHIVE_PATH . '/' . $brandId, self::FILE_PATH . '/' . $brandId] as $path) {
|
|
if ($media->isExist($path)) {
|
|
$media->delete($path);
|
|
}
|
|
}
|
|
}
|
|
|
|
public function deleteBrandParsedFiles(int $brandId): void
|
|
{
|
|
$path = self::FILE_PATH . '/' . $brandId;
|
|
$media = $this->filesystem->getDirectoryWrite(DirectoryList::MEDIA);
|
|
if ($media->isExist($path)) {
|
|
$media->delete($path);
|
|
}
|
|
}
|
|
|
|
public function deleteBrandArchiveFiles(int $brandId): void
|
|
{
|
|
$path = self::ARCHIVE_PATH . '/' . $brandId;
|
|
$media = $this->filesystem->getDirectoryWrite(DirectoryList::MEDIA);
|
|
if ($media->isExist($path)) {
|
|
$media->delete($path);
|
|
}
|
|
}
|
|
|
|
public function delete(string $path): void
|
|
{
|
|
$path = ltrim($path, '/');
|
|
if ($path === '' || !str_starts_with($path, 'esun/catalog/specifications/')) {
|
|
return;
|
|
}
|
|
|
|
$media = $this->filesystem->getDirectoryWrite(DirectoryList::MEDIA);
|
|
if ($media->isExist($path)) {
|
|
$media->delete($path);
|
|
}
|
|
}
|
|
|
|
public function getAbsolutePath(string $path): string
|
|
{
|
|
return $this->filesystem->getDirectoryRead(DirectoryList::MEDIA)->getAbsolutePath(ltrim($path, '/'));
|
|
}
|
|
|
|
public function exists(string $path): bool
|
|
{
|
|
$path = ltrim($path, '/');
|
|
|
|
return $path !== ''
|
|
&& $this->filesystem->getDirectoryRead(DirectoryList::MEDIA)->isExist($path);
|
|
}
|
|
|
|
public function getFileSize(string $path): int
|
|
{
|
|
$path = ltrim($path, '/');
|
|
if ($path === '' || !$this->exists($path)) {
|
|
return 0;
|
|
}
|
|
|
|
$stat = $this->filesystem->getDirectoryRead(DirectoryList::MEDIA)->stat($path);
|
|
|
|
return is_array($stat) ? (int)($stat['size'] ?? 0) : 0;
|
|
}
|
|
|
|
public function sanitizePathSegment(string $value): string
|
|
{
|
|
$value = trim($value);
|
|
$value = preg_replace('/[^A-Za-z0-9._-]+/', '_', $value) ?: '';
|
|
$value = trim($value, '._-');
|
|
|
|
return $value !== '' ? $value : 'model';
|
|
}
|
|
|
|
private function saveUpload(string $field, string $relativeDirectory, array $extensions): ?string
|
|
{
|
|
$file = $this->request->getFiles($field);
|
|
if (!is_array($file)
|
|
|| empty($file['tmp_name'])
|
|
|| (int)($file['error'] ?? UPLOAD_ERR_NO_FILE) === UPLOAD_ERR_NO_FILE
|
|
) {
|
|
return null;
|
|
}
|
|
if ((int)($file['error'] ?? UPLOAD_ERR_NO_FILE) !== UPLOAD_ERR_OK) {
|
|
throw new LocalizedException(__('The %1 file could not be uploaded.', $field));
|
|
}
|
|
|
|
$media = $this->filesystem->getDirectoryWrite(DirectoryList::MEDIA);
|
|
$media->create($relativeDirectory);
|
|
$uploader = $this->uploaderFactory->create(['fileId' => $field]);
|
|
$uploader->setAllowedExtensions($extensions);
|
|
$uploader->setAllowRenameFiles(true);
|
|
$uploader->setFilesDispersion(false);
|
|
$saved = $uploader->save($media->getAbsolutePath($relativeDirectory));
|
|
if (!is_array($saved) || empty($saved['file'])) {
|
|
throw new LocalizedException(__('Unable to save the %1 file.', $field));
|
|
}
|
|
|
|
return trim($relativeDirectory . '/' . ltrim((string)$saved['file'], '/'), '/');
|
|
}
|
|
|
|
private function sanitizeFilename(string $value): string
|
|
{
|
|
$value = strtolower(trim($value));
|
|
$value = preg_replace('/[^a-z0-9._+ -]+/', '_', $value) ?: '';
|
|
$value = preg_replace('/\\s+/', ' ', $value) ?: '';
|
|
$value = trim($value, ' ._-');
|
|
|
|
return $value !== '' ? $value : 'specification';
|
|
}
|
|
}
|