. */ namespace SP\Modules\Web\Controllers\AccountFile; use Exception; use JsonException; use SP\Core\Application; use SP\Core\Events\Event; use SP\Core\Events\EventMessage; use SP\Domain\Account\Models\File; use SP\Domain\Account\Ports\AccountFileService; use SP\Domain\Account\Ports\AccountService; use SP\Domain\Core\Exceptions\SPException; use SP\Domain\File\Ports\FileHandlerInterface; use SP\Infrastructure\File\FileException; use SP\Infrastructure\File\FileHandler; use SP\Modules\Web\Controllers\ControllerBase; use SP\Modules\Web\Controllers\Traits\JsonTrait; use SP\Mvc\Controller\WebControllerHelper; /** * Class UploadController * * @package SP\Modules\Web\Controllers */ final class UploadController extends ControllerBase { use JsonTrait; private AccountFileService $accountFileService; private AccountService $accountService; public function __construct( Application $application, WebControllerHelper $webControllerHelper, AccountFileService $accountFileService, AccountService $accountService ) { parent::__construct($application, $webControllerHelper); $this->checkLoggedIn(); $this->accountFileService = $accountFileService; $this->accountService = $accountService; } /** * Upload action * * @param int $accountId * * @return bool * @throws JsonException */ public function uploadAction(int $accountId): bool { try { $file = $this->router->request()->files()->get('inFile'); if ($accountId === 0 || null === $file) { throw new SPException(__u('INVALID QUERY'), SPException::ERROR); } $filesAllowedMime = $this->configData->getFilesAllowedMime(); if (count($filesAllowedMime) === 0) { throw new SPException(__u('There aren\'t any allowed MIME types')); } try { $fileHandler = new FileHandler($file['tmp_name']); $fileData = new File(); $fileData->setAccountId($accountId); $fileData->setName(htmlspecialchars($file['name'], ENT_QUOTES)); $fileData->setSize($file['size']); $fileData->setType($file['type']); $fileData->setExtension(mb_strtoupper(pathinfo($fileData->getName(), PATHINFO_EXTENSION))); if ($fileData->getName() === '') { throw new SPException( __u('Invalid file'), SPException::ERROR, sprintf(__u('File: %s'), $fileData->getName()) ); } $fileHandler->checkFileExists(); $fileData->setType($this->checkAllowedMimeType($fileData, $fileHandler)); $allowedSize = $this->configData->getFilesAllowedSize(); if ($fileData->getSize() > ($allowedSize * 1000)) { throw new SPException( __u('File size exceeded'), SPException::ERROR, sprintf(__u('Maximum size: %d KB'), $fileData->getRoundSize()) ); } $fileData->setContent($fileHandler->readToString()); } catch (FileException $e) { throw new SPException(__u('Internal error while reading the file')); } $this->accountFileService->create($fileData); $account = $this->accountService->getByIdEnriched($accountId)->getAccountVData(); $this->eventDispatcher->notify( 'upload.accountFile', new Event( $this, EventMessage::factory() ->addDescription(__u('File saved')) ->addDetail(__u('File'), $fileData->getName()) ->addDetail(__u('Account'), $account->getName()) ->addDetail(__u('Client'), $account->getClientName()) ->addDetail(__u('Type'), $fileData->getType()) ->addDetail(__u('Size'), $fileData->getRoundSize() . 'KB') ) ); return $this->returnJsonResponse(0, __u('File saved')); } catch (SPException $e) { processException($e); $this->eventDispatcher->notify('exception', new Event($e)); return $this->returnJsonResponse(1, $e->getMessage(), [$e->getHint()]); } catch (Exception $e) { processException($e); $this->eventDispatcher->notify('exception', new Event($e)); return $this->returnJsonResponseException($e); } } /** * @param \SP\Domain\Account\Models\File $fileData * @param FileHandlerInterface $fileHandler * * @return string * @throws SPException * @throws FileException */ private function checkAllowedMimeType(File $fileData, FileHandlerInterface $fileHandler): string { if (in_array($fileData->getType(), $this->configData->getFilesAllowedMime(), true)) { return $fileData->getType(); } if (in_array($fileHandler->getFileType(), $this->configData->getFilesAllowedMime(), true)) { return $fileHandler->getFileType(); } throw new SPException( __u('File type not allowed'), SPException::ERROR, sprintf(__('MIME type: %s'), $fileData->getType()) ); } }