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'; } }