Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
wazum committed Dec 6, 2024
0 parents commit d2358a1
Show file tree
Hide file tree
Showing 11 changed files with 556 additions and 0 deletions.
138 changes: 138 additions & 0 deletions Classes/Controller/RedirectExportController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
<?php

declare(strict_types=1);

namespace Plan2net\RedirectExport\Controller;

use Plan2net\RedirectExport\Repository\Demand;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Backend\Routing\UriBuilder;
use TYPO3\CMS\Backend\Template\Components\ButtonBar;
use TYPO3\CMS\Core\Http\Response;
use TYPO3\CMS\Core\Http\Stream;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Redirects\Controller\ManagementController;
use TYPO3\CMS\Redirects\Repository\RedirectRepository;
use TYPO3\CMS\Core\Imaging\IconFactory;
use TYPO3\CMS\Core\Imaging\Icon;
use TYPO3\CMS\Redirects\Service\UrlService;

final class RedirectExportController extends ManagementController
{
private const CSV_HEADERS = [
'source_host',
'source_path',
'target',
'status_code',
'page_id',
'disabled',
'starttime',
'endtime',
'hitcount',
'last_hit',
'is_regexp'
];

public function handleRequest(ServerRequestInterface $request): ResponseInterface
{
if ($request->getQueryParams()['action'] === 'export') {
return $this->exportAction($request);
}

$this->registerExportButton();

return parent::handleRequest($request);
}

protected function registerExportButton(): void
{
$buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
$iconFactory = GeneralUtility::makeInstance(IconFactory::class);
$uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);

$exportButton = $buttonBar->makeLinkButton()
->setHref(
(string)$uriBuilder->buildUriFromRoute(
'site_redirects',
['action' => 'export']
)
)
->setTitle($this->getLanguageService()->sL(
'LLL:EXT:redirect_export/Resources/Private/Language/locallang.xlf:export.title'
))
->setIcon($iconFactory->getIcon('actions-download', Icon::SIZE_SMALL));

$buttonBar->addButton($exportButton, ButtonBar::BUTTON_POSITION_LEFT, 20);
}

protected function exportAction(ServerRequestInterface $request): ResponseInterface
{
$redirects = $this->fetchRedirectRecords($request);
$csvData = $this->generateCsvData($redirects);

return $this->createCsvResponse($csvData);
}

protected function fetchRedirectRecords(ServerRequestInterface $request): array
{
$demand = Demand::createFromRequest($request);
// Essentially remove the limit to fetch all redirects
$demand->setLimit(999999999);

$redirectRepository = GeneralUtility::makeInstance(RedirectRepository::class, $demand);
return $redirectRepository->findRedirectsByDemand();
}

protected function generateCsvData(array $redirects): string
{
$this->initializeView('Export');
$this->view->assignMultiple([
'redirects' => $redirects,
'defaultUrl' => GeneralUtility::makeInstance(UrlService::class)->getDefaultUrl(),
]);

$output = $this->view->render();
$rows = array_filter(explode("\n", trim($output)));

return $this->convertToCsv($rows);
}

protected function convertToCsv(array $rows): string
{
$csv = fopen('php://temp', 'w+');

fputcsv($csv, self::CSV_HEADERS);
foreach ($rows as $row) {
$data = explode('|', $row);
fputcsv($csv, $data);
}

rewind($csv);
$content = stream_get_contents($csv);
fclose($csv);

return $content;
}

protected function createCsvResponse(string $csvContent): ResponseInterface
{
$response = new Response();
$body = new Stream('php://temp', 'w+');
$body->write($csvContent);

return $response
->withHeader('Content-Type', 'text/csv; charset=utf-8')
->withHeader('Content-Disposition', 'attachment; filename="redirects.csv"')
->withBody($body);
}

protected function initializeView(string $templateName): void
{
parent::initializeView($templateName);
$this->view->setTemplateRootPaths([
'EXT:redirects/Resources/Private/Templates/Management',
'EXT:redirect_export/Resources/Private/Templates/Management'
]);
}
}
31 changes: 31 additions & 0 deletions Classes/Repository/Demand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

declare(strict_types=1);

namespace Plan2net\RedirectExport\Repository;

use Psr\Http\Message\ServerRequestInterface;

class Demand extends \TYPO3\CMS\Redirects\Repository\Demand
{
public static function createFromRequest(ServerRequestInterface $request): \TYPO3\CMS\Redirects\Repository\Demand
{
$page = (int)($request->getQueryParams()['page'] ?? $request->getParsedBody()['page'] ?? 1);
$demand = $request->getQueryParams()['demand'] ?? $request->getParsedBody()['demand'];
if (empty($demand)) {
return new self($page);
}

$sourceHost = $demand['source_host'] ?? '';
$sourcePath = $demand['source_path'] ?? '';
$statusCode = (int)($demand['target_statuscode'] ?? 0);
$target = $demand['target'] ?? '';

return new self($page, $sourceHost, $sourcePath, $target, $statusCode);
}

public function setLimit(int $limit): void
{
$this->limit = $limit;
}
}
Loading

0 comments on commit d2358a1

Please sign in to comment.