Files
VITEC-website/packages/vitec/Classes/Controller/DownloadController.php
2026-05-18 14:46:25 +02:00

445 lines
17 KiB
PHP

<?php
declare(strict_types=1);
namespace Evomedien\Vitec\Controller;
use TYPO3\CMS\Core\Core\Environment;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Database\Connection;
use TYPO3\CMS\Core\Resource\ResourceFactory;
use TYPO3\CMS\Core\Resource\FileRepository;
use TYPO3\CMS\Core\Mail\MailerInterface;
use TYPO3\CMS\Core\Mail\FluidEmail;
use TYPO3\CMS\Core\Http\ResponseFactory;
use TYPO3\CMS\Core\Http\Stream;
use TYPO3\CMS\Extbase\Http\ForwardResponse;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ResponseFactoryInterface;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
use TYPO3\CMS\Core\Imaging\ImageManipulation\CropVariantCollection;
use Evomedien\Vitec\Domain\Repository\DownloadRepository;
use Evomedien\Vitec\Domain\Repository\ProductRepository;
use Evomedien\Vitec\Domain\Model\Download;
/**
* This file is part of the "VITEC" Extension for TYPO3 CMS.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* (c) 2021
*/
/**
* DownloadController
*/
class DownloadController extends ActionController
{
protected DownloadRepository $downloadRepository;
protected ProductRepository $productRepository;
protected MailerInterface $mailer;
protected ResponseFactoryInterface $responseFactory;
public function __construct(
DownloadRepository $downloadRepository,
ProductRepository $productRepository,
MailerInterface $mailer,
ResponseFactoryInterface $responseFactory
) {
$this->downloadRepository = $downloadRepository;
$this->productRepository = $productRepository;
$this->mailer = $mailer;
$this->responseFactory = $responseFactory;
}
/**
* action list
*/
public function listAction(): ResponseInterface
{
$downloads = $this->downloadRepository->findAll();
$this->view->assign('downloads', $downloads);
return $this->htmlResponse();
}
/**
* action show
*/
public function showAction(): ResponseInterface
{
$products = $this->productRepository->findAlphabetically(false, false);
$ps = [];
$used = [];
foreach ($products as $p) {
if (!in_array($p->getUid(), $used)) {
$scat = $p->getProductsubcategory()->toArray();
$cat = $p->getProductcategory()->toArray();
if (!empty($scat)) {
$ps[$scat[0]->getTitle()][] = $p;
} elseif (!empty($cat)) {
$ps[$cat[0]->getTitle()][] = $p;
}
$used[] = $p->getUid();
}
}
ksort($ps);
$this->view->assign('settings', $this->settings);
$this->view->assign('products', $ps);
// $dcs = $this->dcRepository->fetchForWebsite();
// $this->view->assign('dcs', $dcs);
return $this->htmlResponse();
}
/**
* action directdownload
*/
public function directdownloadAction(Download $download): ResponseInterface
{
$json = $download->getForJSON();
$file = Environment::getProjectPath() . $json['file'];
if (!file_exists($file)) {
throw new \Exception('File not found', 404);
}
$response = $this->responseFactory->createResponse()
->withHeader('Content-Type', 'application/pdf')
->withHeader('Content-Disposition', 'inline; filename="' . basename($file) . '"')
->withHeader('Content-Transfer-Encoding', 'binary')
->withHeader('Accept-Ranges', 'bytes')
->withHeader('Content-Length', (string)filesize($file))
->withHeader('Pragma', 'public')
->withHeader('Expires', '0')
->withHeader('Cache-Control', 'must-revalidate');
$stream = new Stream(fopen($file, 'rb'));
return $response->withBody($stream);
}
/**
* action ac
*/
public function acAction(): ResponseInterface
{
$downloads = [];
$request = $this->request;
if (!empty($request->getQueryParams()['dc'])) {
$downloads = $this->downloadRepository->findByCategory($request->getQueryParams()['dc'], 1);
} elseif (!empty($request->getQueryParams()['k'])) {
$downloads = $this->downloadRepository->search($request->getQueryParams()['k'], 1);
} elseif (!empty($request->getQueryParams()['p'])) {
$downloads = $this->downloadRepository->findByProduct($request->getQueryParams()['p'], 1);
$product = $this->productRepository->findByUid($request->getQueryParams()['p']);
$this->view->assign('product', $product);
}
$this->downloadInfo($downloads);
return $this->htmlResponse();
}
private function downloadInfo($downloads): void
{
if (!empty($downloads)) {
$info = [];
foreach ($downloads as $d) {
$file = $d->getFile();
if (!empty($file)) {
$fileResourceReference = GeneralUtility::makeInstance(ResourceFactory::class)
->getFileReferenceObject($file->getUid());
$file = urldecode($fileResourceReference->getOriginalFile()->getPublicUrl());
$i = pathinfo($file);
$i['size'] = $this->human_filesize(filesize($file));
$info[$d->getUid()] = $i;
}
}
$this->view->assign('info', $info);
}
$this->view->assign('downloads', $downloads);
}
private function human_filesize($bytes, $decimals = 2): string
{
$sz = 'BKMGTP';
$factor = floor((strlen(strval($bytes)) - 1) / 3);
return sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . @$sz[$factor];
}
/**
* action download
*/
public function downloadAction(Download $download): ResponseInterface
{
return $this->directdownloadAction($download);
}
public function combineddlAction(string $files): ResponseInterface
{
$ids = explode(',', $files);
$downloads = $this->downloadRepository->findByUids($ids);
$file = $this->createZip(md5($files), $downloads, null);
if ($file !== false) {
$response = $this->responseFactory->createResponse()
->withHeader('Content-disposition', 'attachment; filename=Vitec.zip')
->withHeader('Content-type', 'application/zip')
->withHeader('Content-Length', (string)filesize($file));
$stream = new Stream(fopen($file, 'rb'));
unlink($file);
return $response->withBody($stream);
}
return $this->htmlResponse();
}
/**
* action datasheets
*/
public function datasheetsAction(): ResponseInterface
{
$productso = $this->productRepository->fetchForDatasheets();
$sheets = [];
$faved = [];
$faves = [];
$request = $this->request;
if (!empty($_COOKIE['datasheet-faves'])) {
$faved = json_decode($_COOKIE['datasheet-faves']);
}
if (!empty($request->getParsedBody()['download'])) {
$downloads = $this->downloadRepository->findByUids($faved);
$file = $this->createZip($_COOKIE['datasheet-faves'], $downloads, null);
if ($file !== false) {
$response = $this->responseFactory->createResponse()
->withHeader('Content-disposition', 'attachment; filename=Vitec.zip')
->withHeader('Content-type', 'application/zip')
->withHeader('Content-Length', (string)filesize($file));
$stream = new Stream(fopen($file, 'rb'));
unlink($file);
return $response->withBody($stream);
}
}
if (!empty($productso)) {
foreach ($productso as $p) {
$downloads = $p->getDownload();
foreach ($downloads as $d) {
$isSheet = false;
foreach ($d->getType() as $t) {
// filter download type ids
if ($t->getUid() == 1 || $t->getUid() == 3) {
$isSheet = true;
break;
}
}
if ($isSheet) {
$cat = null;
$maincategorysort = 0;
foreach ($p->getProductcategory() as $c) {
$cat = $c->getTitle();
$maincategorysort = $c->getSort3();
break;
}
$subcat = null;
$subcatsort = 0;
foreach ($p->getProductsubcategory() as $s) {
$subcat = $s->getTitle();
$subcatsort = $s->getSort3();
break;
}
$isFaved = false;
if (in_array($d->getUid(), $faved)) {
$faves[] = [
'product' => $p,
'datasheet' => $d
];
$isFaved = true;
}
$sheets[] = [
'isfaved' => $isFaved,
'category' => $cat,
'sort' => $maincategorysort,
'subcategory' => $subcat,
'subcategorysort' => strval($subcatsort),
'product' => $p,
'datasheet' => $d
];
}
}
}
}
usort($sheets, function ($a, $b) {
if ($a["sort"] === $b["sort"]) {
if ($a["subcategorysort"] === $b["subcategorysort"]) {
return strcmp($a["product"]->getTitle(), $b["product"]->getTitle());
} else {
return strcmp($a["subcategorysort"], $b["subcategorysort"]);
}
}
return strcmp(strval($a["sort"]), strval($b["sort"]));
});
$this->view->assign('sheets', $sheets);
$this->view->assign('faves', $faves);
return $this->htmlResponse();
}
/**
* action index
*/
public function indexAction(): ResponseInterface
{
return $this->htmlResponse();
}
private function createZip($req, $downloads, $stories): string|false
{
$zip = new \ZipArchive();
$tmp_file = '/tmp/' . sha1($req) . '.zip';
if ($zip->open($tmp_file, \ZipArchive::CREATE)) {
if (!empty($downloads)) {
foreach ($downloads as $download) {
$f = $download->getFilepfad();
if ($f !== false) {
$zip->addFile($f, basename($f));
}
}
}
if (!empty($stories)) {
foreach ($stories as $story) {
$f = $story['pdf'];
if ($f !== false) {
$zip->addFile($f, basename($f));
}
}
}
$zip->close();
return $tmp_file;
}
return false;
}
/**
* action collection
*/
public function collectionAction(): ResponseInterface
{
$downloads = [];
$downloadids = [];
$stories = [];
$storyids = [];
$request = $this->request;
$parsedBody = $request->getParsedBody();
if (!empty($parsedBody['downloads'])) {
$ids = explode(',', $parsedBody['downloads']);
foreach ($ids as $id) {
$downloadids[] = intval($id);
}
$downloadids = implode(',', $downloadids);
$downloads = $this->downloadRepository->findByUids($ids);
}
if (!empty($parsedBody['stories'])) {
$ids = explode(',', $parsedBody['stories']);
foreach ($ids as $id) {
$storyids[] = intval($id);
}
$storyids = implode(',', $storyids);
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable('tt_content');
$whereExpressions = [
$queryBuilder->expr()->eq('colPos', $queryBuilder->createNamedParameter(0)),
$queryBuilder->expr()->eq('pid', $queryBuilder->createNamedParameter(18)),
$queryBuilder->expr()->in(
'uid',
$queryBuilder->createNamedParameter(
explode(',', $storyids),
Connection::PARAM_INT_ARRAY
)
),
$queryBuilder->expr()->eq('CType', $queryBuilder->createNamedParameter('mask_use_case')),
$queryBuilder->expr()->eq('tx_mask_app_visible', $queryBuilder->createNamedParameter(1))
];
$result = $queryBuilder->select('tt_content.*')
->from('tt_content')
->where(...$whereExpressions)
->orderBy('tt_content.sorting')
->executeQuery();
$rows = $result->fetchAllAssociative();
$fileRepository = GeneralUtility::makeInstance(FileRepository::class);
foreach ($rows as $content) {
$pdf_url = '';
$filename = '';
if (!empty($content['tx_mask_detail_pdf'])) {
try {
$filename = Environment::getProjectPath() . '/' . $content['tx_mask_detail_pdf'];
$pdf_url = $this->uriBuilder->setTargetPageUid(1)->buildFrontendUri() .
substr(str_replace(Environment::getProjectPath(), '', $filename), 1);
} catch (\Exception $e) {
// Handle exception
}
}
$stories[$content['uid']] = [
'uid' => $content['uid'],
'header' => $content['header'],
'pdf' => $filename,
'detail_pdf' => $pdf_url
];
}
}
if (!empty($parsedBody['email']) &&
filter_var($parsedBody['email'], FILTER_VALIDATE_EMAIL) &&
(!empty($parsedBody['downloads']) || !empty($parsedBody['stories']))) {
$file = $this->createZip($parsedBody['downloads'] . $parsedBody['stories'], $downloads, $stories);
if ($file !== false) {
$email = GeneralUtility::makeInstance(FluidEmail::class);
$email->from('downloads@vitec.com', 'VITEC')
->to($parsedBody['email'])
->subject('VITEC Datasheets download')
->text('Thank you for your interest in VITEC products. Attached, please find your Datasheets ready for download.')
->attachFromPath($file, 'Vitec.zip');
$this->mailer->send($email);
$redirect = $this->uriBuilder->setTargetPageUid(186)->setCreateAbsoluteUri(true)->buildFrontendUri();
return $this->redirectToUri($redirect);
}
} elseif (!empty($parsedBody['downloads']) || !empty($parsedBody['stories'])) {
$file = $this->createZip($parsedBody['downloads'] . $parsedBody['stories'], $downloads, $stories);
if ($file !== false) {
$response = $this->responseFactory->createResponse()
->withHeader('Content-disposition', 'attachment; filename=Vitec.zip')
->withHeader('Content-type', 'application/zip')
->withHeader('Content-Length', (string)filesize($file));
$stream = new Stream(fopen($file, 'rb'));
unlink($file);
return $response->withBody($stream);
}
}
$this->view->assign('downloads', $downloads);
$this->view->assign('downloadids', $downloadids);
$this->view->assign('stories', $stories);
$this->view->assign('storyids', $storyids);
return $this->htmlResponse();
}
}