diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index b0dabe5..857e57c 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -1,32 +1,23 @@ name: Unit tests -on: - push: - branches: - - 'master' - tags: - - '*' - pull_request: +on: [push, pull_request] jobs: build: strategy: matrix: - php: ['7.2', '7.3', '7.4'] - typo3: ['^10.4'] + php: ['7.4', '8.0', '8.1'] + typo3: ['^11.5'] runs-on: ubuntu-latest - continue-on-error: ${{ matrix.php == '8.0' }} name: PHP ${{ matrix.php }}, TYPO3 ${{ matrix.typo3 }} steps: - uses: actions/checkout@v1 - - - name: Setup PHP - uses: shivammathur/setup-php@v1 + + - name: Set up PHP Version + uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php }} - extensions: mbstring, intl, json - coverage: pcov tools: composer:v2 - name: Validate composer.json and composer.lock @@ -40,7 +31,7 @@ jobs: run: composer install --prefer-dist --no-progress --no-suggest - name: Run unit tests - run: vendor/bin/phpunit --colors -c vendor/nimut/testing-framework/res/Configuration/UnitTests.xml Tests/Unit/ - + run: .Build/bin/phpunit --colors -c Tests/Build/UnitTests.xml + - name: Run PHP lint - run: find . -name \*.php ! -path "./public/*" ! -path "./vendor/*" | xargs -n1 php -d display_errors=stderr -l + run: find . -name \*.php ! -path "./.Build/*" ! -path "./public/*" ! -path "./vendor/*" | xargs -n1 php -d display_errors=stderr -l diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 815c374..0000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,45 +0,0 @@ -name: Release - -on: - push: - tags: - - '*' - -jobs: - release: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - - name: Setup PHP - uses: shivammathur/setup-php@v1 - with: - php-version: "7.4" - extensions: mbstring, intl, json - coverage: pcov - tools: composer:v2 - - - name: Build extension ZIP - run: | - composer extension-package - - - name: Release ZIP on Github - uses: softprops/action-gh-release@v1 - with: - files: | - web2pdf_*.zip - env: - GITHUB_TOKEN: ${{ secrets.RELEASE_USER_TOKEN }} - - - name: Prepare TER release - run: | - mkdir ter-upload - unzip -d ter-upload ./web2pdf_*.zip - - - name: Release ZIP on TER - uses: mittwald/typo3-publish-ter-action@v1.0.0-beta2 - with: - ter-username: ${{ secrets.TER_USERNAME }} - ter-password: ${{ secrets.TER_PASSWORD }} - extension-key: web2pdf - extension-dir: ./ter-upload diff --git a/.gitignore b/.gitignore index 14f96e4..e806f40 100644 --- a/.gitignore +++ b/.gitignore @@ -2,9 +2,13 @@ .idea # Local files +.Build +.php-cs-fixer.cache +.phpunit.result.cache + /var/ /public/ /vendor/ /Resources/Private/Libraries/vendor data -composer.lock \ No newline at end of file +composer.lock diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php new file mode 100644 index 0000000..0afdf86 --- /dev/null +++ b/.php-cs-fixer.dist.php @@ -0,0 +1,69 @@ +setRiskyAllowed(true) + ->setRules([ + '@DoctrineAnnotation' => true, + '@PSR2' => true, + 'array_syntax' => ['syntax' => 'short'], + 'blank_line_after_opening_tag' => true, + 'braces' => ['allow_single_line_closure' => true], + 'cast_spaces' => ['space' => 'none'], + 'compact_nullable_typehint' => true, + 'concat_space' => ['spacing' => 'one'], + 'declare_equal_normalize' => ['space' => 'none'], + 'dir_constant' => true, + 'function_typehint_space' => true, + 'lowercase_cast' => true, + 'method_argument_space' => ['on_multiline' => 'ensure_fully_multiline'], + 'modernize_types_casting' => true, + 'native_function_casing' => true, + 'new_with_braces' => true, + 'no_alias_functions' => true, + 'no_blank_lines_after_phpdoc' => true, + 'no_empty_phpdoc' => true, + 'no_empty_statement' => true, + 'no_extra_blank_lines' => true, + 'no_leading_import_slash' => true, + 'no_leading_namespace_whitespace' => true, + 'no_null_property_initialization' => true, + 'no_short_bool_cast' => true, + 'no_singleline_whitespace_before_semicolons' => true, + 'no_superfluous_elseif' => true, + 'no_trailing_comma_in_singleline_array' => true, + 'no_unneeded_control_parentheses' => true, + 'no_unused_imports' => true, + 'no_useless_else' => true, + 'no_whitespace_in_blank_line' => true, + 'ordered_imports' => true, + 'php_unit_construct' => ['assertions' => ['assertEquals', 'assertSame', 'assertNotEquals', 'assertNotSame']], + 'php_unit_mock_short_will_return' => true, + 'php_unit_test_case_static_method_calls' => ['call_type' => 'self'], + 'phpdoc_no_access' => true, + 'phpdoc_no_empty_return' => true, + 'phpdoc_no_package' => true, + 'phpdoc_scalar' => true, + 'phpdoc_trim' => true, + 'phpdoc_types' => true, + 'phpdoc_types_order' => ['null_adjustment' => 'always_last', 'sort_algorithm' => 'none'], + 'return_type_declaration' => ['space_before' => 'none'], + 'single_quote' => true, + 'single_line_comment_style' => ['comment_types' => ['hash']], + 'single_trait_insert_per_statement' => true, + 'trailing_comma_in_multiline' => ['elements' => ['arrays']], + 'whitespace_after_comma_in_array' => true, + ]) + ->setFinder( + PhpCsFixer\Finder::create() + ->in(__DIR__) + ->exclude(['.Build', 'Documentation', 'Resources']) + ->notName('ext_emconf.php') + ); diff --git a/Build/package-version.sh b/Build/package-version.sh old mode 100644 new mode 100755 index c1a5c1a..1fd6633 --- a/Build/package-version.sh +++ b/Build/package-version.sh @@ -2,6 +2,8 @@ if [ -n "${VERSION}" ] ; then true # pass +elif [ -n "$1" ] ; then + VERSION="$1" elif [ -n "${GITHUB_REF}" ] ; then VERSION="${GITHUB_REF/refs\/tags\//}" VERSION="${VERSION#v}" @@ -21,7 +23,6 @@ composer install --no-dev popd -sed -i -e "s,[0-9]\.[0-9]-dev,${VERSION},g" ext_emconf.php zip -9 -r \ --exclude=Resources/Private/Libraries/vendor/mpdf/mpdf/ttfonts/* \ web2pdf_${VERSION}.zip \ @@ -33,4 +34,5 @@ zip -9 -r \ ext_icon.png \ ext_localconf.php \ LICENSE.txt \ - README.md \ \ No newline at end of file + README.md \ + composer.json \ \ No newline at end of file diff --git a/Classes/Controller/PdfController.php b/Classes/Controller/PdfController.php index e980ec9..9cc86b1 100644 --- a/Classes/Controller/PdfController.php +++ b/Classes/Controller/PdfController.php @@ -1,9 +1,9 @@ + * (C) Mittwald CM Service GmbH & Co. KG * * All rights reserved * @@ -22,26 +22,17 @@ * GNU General Public License for more details. * * This copyright notice MUST APPEAR in all copies of the script! - * ************************************************************* */ + ***************************************************************/ namespace Mittwald\Web2pdf\Controller; use Mittwald\Web2pdf\Options\ModuleOptions; use TYPO3\CMS\Extbase\Mvc\Controller\ActionController; -/** - * Controller provides partial view for pdf link - * - * @author Kevin Purrmann , Purrmann Websolutions - * @package Mittwald - * @subpackage Web2Pdf\Controller - */ class PdfController extends ActionController { - /** * Method provides link generation - * */ public function generatePdfLinkAction() { diff --git a/Classes/Middleware/PdfHandler.php b/Classes/Middleware/PdfHandler.php index b3a9cb3..9a1ce15 100644 --- a/Classes/Middleware/PdfHandler.php +++ b/Classes/Middleware/PdfHandler.php @@ -1,9 +1,31 @@ + * + * All rights reserved + * + * This script is part of the TYPO3 project. The TYPO3 project is + * free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * The GNU General Public License can be found at + * http://www.gnu.org/copyleft/gpl.html. + * + * This script is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * This copyright notice MUST APPEAR in all copies of the script! + ***************************************************************/ namespace Mittwald\Web2pdf\Middleware; - use Mittwald\Web2pdf\Options\ModuleOptions; use Mittwald\Web2pdf\View\PdfView; use Psr\Http\Message\ResponseInterface; @@ -15,24 +37,10 @@ class PdfHandler implements MiddlewareInterface { - /** - * @var PdfView - */ - private $pdfView; - /** - * @var TypoScriptFrontendController - */ - private $frontendController; - /** - * @var ModuleOptions - */ - private $moduleOptions; + private PdfView $pdfView; + private TypoScriptFrontendController $frontendController; + private ModuleOptions $moduleOptions; - /** - * PdfHandler constructor. - * @param PdfView $pdfView - * @param ModuleOptions $moduleOptions - */ public function __construct(PdfView $pdfView, ModuleOptions $moduleOptions) { $this->pdfView = $pdfView; @@ -61,7 +69,7 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface $response = new Response(); $file = $this->pdfView->renderHtmlOutput($output->getBody(), $this->frontendController->generatePageTitle()); - $destination = ($pdfDestination = $this->moduleOptions->getPdfDestination()) ? $pdfDestination : 'attachment'; + $destination = $this->moduleOptions->getPdfDestination() ?? 'attachment'; $response = $response->withHeader('Content-Transfer-Encoding', 'binary'); $response->getBody()->write(file_get_contents($file)); @@ -70,4 +78,4 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface return $response->withStatus(200); } -} \ No newline at end of file +} diff --git a/Classes/Options/ModuleOptions.php b/Classes/Options/ModuleOptions.php index 121cd73..0aab6ad 100644 --- a/Classes/Options/ModuleOptions.php +++ b/Classes/Options/ModuleOptions.php @@ -1,8 +1,9 @@ + * (C) Mittwald CM Service GmbH & Co. KG * * All rights reserved * @@ -21,58 +22,57 @@ * GNU General Public License for more details. * * This copyright notice MUST APPEAR in all copies of the script! - * ************************************************************* */ + ***************************************************************/ namespace Mittwald\Web2pdf\Options; use Mittwald\Web2pdf\View\PdfView; +use TYPO3\CMS\Core\SingletonInterface; use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface; - -/** - * Class provides access to all typoscript settings - * which are set in Configuration/TypoScript/setup.txt - * - */ -class ModuleOptions implements \TYPO3\CMS\Core\SingletonInterface { - +class ModuleOptions implements SingletonInterface +{ const QUERY_PARAMETER = 'printPage'; - - /** - * @var \TYPO3\CMS\Extbase\Configuration\ConfigurationManager - */ - protected $configurationManager; - - /** - * @var array - */ - protected $options = array(); + protected ConfigurationManagerInterface $configurationManager; + protected array $options = []; /** * Fills typoscript settings into options * * @throws \TYPO3\CMS\Extbase\Configuration\Exception\InvalidConfigurationTypeException */ - public function __construct(ConfigurationManagerInterface $configurationManager) { + public function __construct(ConfigurationManagerInterface $configurationManager) + { $this->configurationManager = $configurationManager; - $configuration = $this->configurationManager->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_FULL_TYPOSCRIPT); + $configuration = $this->configurationManager + ->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_FULL_TYPOSCRIPT); // Check if typoscript is given before, if not ignore if (isset($configuration['plugin.']['tx_web2pdf.']['settings.']) && - isset($configuration['plugin.']['tx_web2pdf.']['view.']) && - ($this->options = array_merge($configuration['plugin.']['tx_web2pdf.']['settings.'], $configuration['plugin.']['tx_web2pdf.']['view.'])) + isset($configuration['plugin.']['tx_web2pdf.']['view.']) && + ($this->options = array_merge( + $configuration['plugin.']['tx_web2pdf.']['settings.'], + $configuration['plugin.']['tx_web2pdf.']['view.'] + )) ) { if (is_array($this->options['pdfPregSearch.']) && is_array($this->options['pdfPregReplace.'])) { - $this->mergeReplaceConfiguration($this->options['pdfPregSearch.'], $this->options['pdfPregReplace.'], PdfView::PREG_REPLACEMENT_KEY); + $this->mergeReplaceConfiguration( + $this->options['pdfPregSearch.'], + $this->options['pdfPregReplace.'], + PdfView::PREG_REPLACEMENT_KEY + ); unset($this->options['pdfPregSearch.'], $this->options['pdfPregReplace.']); } if (is_array($this->options['pdfStrSearch.']) && is_array($this->options['pdfStrReplace.'])) { - $this->mergeReplaceConfiguration($this->options['pdfStrSearch.'], $this->options['pdfStrReplace.'], PdfView::STR_REPLACEMENT_KEY); + $this->mergeReplaceConfiguration( + $this->options['pdfStrSearch.'], + $this->options['pdfStrReplace.'], + PdfView::STR_REPLACEMENT_KEY + ); unset($this->options['pdfStrSearch.'], $this->options['pdfStrReplace.']); } } - } /** @@ -82,14 +82,13 @@ public function __construct(ConfigurationManagerInterface $configurationManager) * @param $replaceArray * @param $newKey */ - private function mergeReplaceConfiguration($searchArray, $replaceArray, $newKey) { - + private function mergeReplaceConfiguration($searchArray, $replaceArray, $newKey) + { foreach ($searchArray as $key => $searchString) { if (isset($replaceArray[$key]) && $searchString !== '' && !empty($replaceArray[$key])) { $this->options[$newKey][$searchString] = $replaceArray[$key]; } } - } /** @@ -100,26 +99,33 @@ private function mergeReplaceConfiguration($searchArray, $replaceArray, $newKey) * @param array $arguments * @return mixed|null */ - public function __call($methodName, $arguments) { + public function __call($methodName, $arguments) + { if (is_array($this->options) && substr($methodName, 0, 3) === 'get' && strlen($methodName) > 5) { $propertyName = lcfirst(substr($methodName, 3)); return $this->getConfigValue($propertyName); } - return NULL; + + return null; } /** * Returns config value if exists * - * @param $index + * @param mixed $index * @return mixed */ - protected function getConfigValue($index) { + protected function getConfigValue($index) + { if (is_array($this->options) && - (array_key_exists($index, $this->options) || (($index = $index . '.') && array_key_exists($index, $this->options))) + ( + array_key_exists($index, $this->options) || + (($index = $index . '.') && array_key_exists($index, $this->options)) + ) ) { return $this->options[$index]; } + return null; } } diff --git a/Classes/Utility/FilenameUtility.php b/Classes/Utility/FilenameUtility.php index b4293d1..ea2e874 100644 --- a/Classes/Utility/FilenameUtility.php +++ b/Classes/Utility/FilenameUtility.php @@ -1,8 +1,9 @@ + * (C) Mittwald CM Service GmbH & Co. KG * * All rights reserved * @@ -21,55 +22,34 @@ * GNU General Public License for more details. * * This copyright notice MUST APPEAR in all copies of the script! - * ************************************************************* */ + ***************************************************************/ namespace Mittwald\Web2pdf\Utility; - -/** - * Class provides functionality to convert strings into appreciable filename - * - * @auto Kevin Purrmann , Purrmann Websolutions - * @package Mittwald - * @subpackage Web2Pdf\Utility - */ class FilenameUtility { - /** * @param string $fileName * @return string - * @throws \InvalidArgumentException */ - public function convert($fileName) + public function convert(string $fileName): string { - - if (!is_string($fileName)) { - throw new \InvalidArgumentException('String needed as argument'); - } - - return preg_replace(array('/\s/', '/\.[\.]+/', '/[^a-zA-Z0-9-_]+/'), array('_', '_', ''), $this->replaceSpecialChars($fileName)); + return preg_replace(['/\s/', '/\.[\.]+/', '/[^a-zA-Z0-9-_]+/'], ['_', '_', ''], $this->replaceSpecialChars($fileName)); } - /** - * @param $string + * @param string $string * @return string */ - protected function replaceSpecialChars($string) + protected function replaceSpecialChars(string $string) { $string = html_entity_decode($string, ENT_COMPAT, 'UTF-8'); $oldLocale = setlocale(LC_CTYPE, '0'); - setlocale(LC_CTYPE, 'en_US.UTF-8'); $string = iconv('UTF-8', 'ASCII//TRANSLIT', $string); - setlocale(LC_CTYPE, $oldLocale); return $string; - } - - } diff --git a/Classes/Utility/PdfLinkUtility.php b/Classes/Utility/PdfLinkUtility.php index 58fafc8..e5282c6 100644 --- a/Classes/Utility/PdfLinkUtility.php +++ b/Classes/Utility/PdfLinkUtility.php @@ -1,8 +1,9 @@ + * (C) Mittwald CM Service GmbH & Co. KG * * All rights reserved * @@ -21,29 +22,24 @@ * GNU General Public License for more details. * * This copyright notice MUST APPEAR in all copies of the script! - * ************************************************************* */ + ***************************************************************/ namespace Mittwald\Web2pdf\Utility; use TYPO3\CMS\Core\Utility\GeneralUtility; - -/** - * Class PdfLinkUtility - * @package Mittwald\Web2pdf\Utility - */ -class PdfLinkUtility { - +class PdfLinkUtility +{ /** * Method removes local absolute url if link section is given * Method keeps external links * Method keeps external links with sections * - * @param $content + * @param string $content * @return string */ - public function replace($content) { - + public function replace(string $content): string + { $tmpSiteUri = $this->getSiteUri(); $currentSiteUri = (preg_match('/^\//', $tmpSiteUri)) ? $tmpSiteUri : '/' . $tmpSiteUri; $currentHost = $this->getHost(); @@ -60,25 +56,22 @@ public function replace($content) { }, $content); return $replacedContent; - } - /** * @return string * @throws \UnexpectedValueException */ - protected function getSiteUri() { - return htmlentities(GeneralUtility::getIndpEnv("TYPO3_SITE_SCRIPT")); + protected function getSiteUri(): string + { + return htmlentities(GeneralUtility::getIndpEnv('TYPO3_SITE_SCRIPT')); } /** * @return string */ - protected function getHost() { - - return ($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : ''; + protected function getHost(): string + { + return $_SERVER['HTTP_HOST'] ?? ''; } - - -} \ No newline at end of file +} diff --git a/Classes/View/PdfView.php b/Classes/View/PdfView.php index 94868bf..6bd9350 100644 --- a/Classes/View/PdfView.php +++ b/Classes/View/PdfView.php @@ -1,8 +1,9 @@ + * (C) Mittwald CM Service GmbH & Co. KG * * All rights reserved * @@ -21,7 +22,7 @@ * GNU General Public License for more details. * * This copyright notice MUST APPEAR in all copies of the script! - * ************************************************************* */ + ***************************************************************/ namespace Mittwald\Web2pdf\View; @@ -32,71 +33,36 @@ use TYPO3\CMS\Core\Core\Environment; use TYPO3\CMS\Core\Utility\ExtensionManagementUtility; use TYPO3\CMS\Core\Utility\GeneralUtility; -use TYPO3\CMS\Extbase\Object\ObjectManagerInterface; use TYPO3\CMS\Fluid\View\StandaloneView; - -/** - * PDFView - * - * @author Kevin Purrmann , Purrmann Websolutions - * @package Mittwald - * @subpackage Web2Pdf\View - */ class PdfView { - const PREG_REPLACEMENT_KEY = 'pregReplacements'; - const STR_REPLACEMENT_KEY = 'strReplacements'; - /** - * @var ModuleOptions - */ - protected $options; - - /** - * @var FilenameUtility - */ - protected $fileNameUtility; - - /** - * @var PdfLinkUtility - */ - protected $pdfLinkUtility; - /** - * @var ObjectManagerInterface - */ - protected $objectManager; + protected ModuleOptions $options; + protected FilenameUtility $fileNameUtility; + protected PdfLinkUtility $pdfLinkUtility; - /** - * PdfView constructor. - * @param ModuleOptions $options - * @param FilenameUtility $fileNameUtility - * @param PdfLinkUtility $pdfLinkUtility - */ public function __construct( ModuleOptions $options, FilenameUtility $fileNameUtility, - PdfLinkUtility $pdfLinkUtility, - ObjectManagerInterface $objectManager + PdfLinkUtility $pdfLinkUtility ) { $this->options = $options; $this->fileNameUtility = $fileNameUtility; $this->pdfLinkUtility = $pdfLinkUtility; - $this->objectManager = $objectManager; } - /** - * Renders the view + * Renders the PDF view * * @param string $content The HTML Code to convert * @param string $pageTitle * @return string $filePath * @throws \Mpdf\MpdfException */ - public function renderHtmlOutput($content, $pageTitle): string + public function renderHtmlOutput(string $content, string $pageTitle): string { $fileName = $this->fileNameUtility->convert($pageTitle) . '.pdf'; $filePath = Environment::getVarPath() . '/web2pdf/' . $fileName; @@ -104,13 +70,13 @@ public function renderHtmlOutput($content, $pageTitle): string $content = $this->replaceStrings($content); $pdf = $this->getPdfObject(); - // Add Header + // Add Header if configured if ($this->options->getUseCustomHeader()) { - $pdf->SetHTMLHeader($this->getPartial('Header', array('title' => $pageTitle))); + $pdf->SetHTMLHeader($this->getPartial('Header', ['title' => $pageTitle])); } - // Add Footer + // Add Footer if configured if ($this->options->getUseCustomFooter()) { - $pdf->SetHTMLFooter($this->getPartial('Footer', array('title' => $pageTitle))); + $pdf->SetHTMLFooter($this->getPartial('Footer', ['title' => $pageTitle])); } $pdf->WriteHTML($content); @@ -122,12 +88,11 @@ public function renderHtmlOutput($content, $pageTitle): string /** * Replacements of configured strings * - * @param $content + * @param string $content * @return string */ - private function replaceStrings($content): string + private function replaceStrings(string $content): string { - if (is_array($this->options->getStrReplacements())) { foreach ($this->options->getStrReplacements() as $searchString => $replacement) { $content = str_replace($searchString, $replacement, $content); @@ -150,34 +115,30 @@ private function replaceStrings($content): string */ protected function getPdfObject(): Mpdf { - // Get options from TypoScript - $pageFormat = ($this->options->getPdfPageFormat()) ? $this->options->getPdfPageFormat() : 'A4'; - $pageOrientation = ($orientation = $this->options->getPdfPageOrientation()) ? $orientation : 'L'; - $leftMargin = ($this->options->getPdfLeftMargin()) ? $this->options->getPdfLeftMargin() : '15'; - $rightMargin = ($this->options->getPdfRightMargin()) ? $this->options->getPdfRightMargin() : '15'; - $bottomMargin = ($this->options->getPdfBottomMargin()) ? $this->options->getPdfBottomMargin() : '15'; - $topMargin = ($this->options->getPdfTopMargin()) ? $this->options->getPdfTopMargin() : '15'; - $styleSheet = ($this->options->getPdfStyleSheet()) ? $this->options->getPdfStyleSheet() : 'print'; - - /* @var $pdf Mpdf */ - $pdf = $this->objectManager->get( - Mpdf::class, [ - 'format' => $pageFormat, - 'default_font_size' => 12, - 'margin_left' => $leftMargin, - 'margin_right' => $rightMargin, - 'margin_top' => $topMargin, - 'margin_bottom' => $bottomMargin, - 'orientation' => $pageOrientation, - 'tempDir' => Environment::getVarPath() . '/web2pdf', - 'fontDir' => ExtensionManagementUtility::extPath('web2pdf') . 'Resources/Public/Fonts', - ] - ); + $pageFormat = $this->options->getPdfPageFormat() ?? 'A4'; + $pageOrientation = $this->options->getPdfPageOrientation() ?? 'L'; + $leftMargin = $this->options->getPdfLeftMargin() ?? '15'; + $rightMargin = $this->options->getPdfRightMargin() ?? '15'; + $bottomMargin = $this->options->getPdfBottomMargin() ?? '15'; + $topMargin = $this->options->getPdfTopMargin() ?? '15'; + $styleSheet = $this->options->getPdfStyleSheet() ?? 'print'; + + $pdf = new Mpdf([ + 'format' => $pageFormat, + 'default_font_size' => 12, + 'margin_left' => $leftMargin, + 'margin_right' => $rightMargin, + 'margin_top' => $topMargin, + 'margin_bottom' => $bottomMargin, + 'orientation' => $pageOrientation, + 'tempDir' => Environment::getVarPath() . '/web2pdf', + 'fontDir' => ExtensionManagementUtility::extPath('web2pdf') . 'Resources/Public/Fonts', + ]); $pdf->SetMargins($leftMargin, $rightMargin, $topMargin); - if ($styleSheet == 'print' || $styleSheet == 'screen') { + if ($styleSheet === 'print' || $styleSheet === 'screen') { $pdf->CSSselectMedia = $styleSheet; } @@ -185,19 +146,23 @@ protected function getPdfObject(): Mpdf } /** - * @param $templateName + * Renders the given templateName. Note, that the template must actually reside in Partials/ folder. + * + * @param string $templateName + * @param array $arguments * @return string */ - protected function getPartial($templateName, $arguments = array()): string + protected function getPartial(string $templateName, array $arguments = []): string { - /* @var $partial \TYPO3\CMS\Fluid\View\StandaloneView */ - $partial = $this->objectManager->get(StandaloneView::class); + $partial = GeneralUtility::makeInstance(StandaloneView::class); $partial->setLayoutRootPaths($this->options->getLayoutRootPaths()); $partial->setPartialRootPaths($this->options->getPartialRootPaths()); - $partial->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName(end($partial->getPartialRootPaths())) . 'Pdf/' . ucfirst($templateName) . '.html'); + $partialsPaths = $partial->getPartialRootPaths(); + $partial->setTemplatePathAndFilename( + GeneralUtility::getFileAbsFileName(end($partialsPaths)) . 'Pdf/' . ucfirst($templateName) . '.html' + ); $partial->assign('data', $arguments); return $partial->render(); } - } diff --git a/Configuration/RequestMiddlewares.php b/Configuration/RequestMiddlewares.php index fdff997..217130e 100644 --- a/Configuration/RequestMiddlewares.php +++ b/Configuration/RequestMiddlewares.php @@ -5,5 +5,5 @@ 'mittwald/web2pdf/pdf-handler' => [ 'target' => \Mittwald\Web2pdf\Middleware\PdfHandler::class, ], - ] + ], ]; diff --git a/Configuration/TCA/Overrides/sys_template.php b/Configuration/TCA/Overrides/sys_template.php index c142ace..3d5e622 100644 --- a/Configuration/TCA/Overrides/sys_template.php +++ b/Configuration/TCA/Overrides/sys_template.php @@ -1,4 +1,5 @@ .tex - - web2pdf - - Kevin Purrmann - latex_elements: - papersize: a4paper - pointsize: 10pt - preamble: \usepackage{typo3} diff --git a/Documentation/ToDoList/Index.rst b/Documentation/ToDoList/Index.rst deleted file mode 100644 index ecbfb53..0000000 --- a/Documentation/ToDoList/Index.rst +++ /dev/null @@ -1,14 +0,0 @@ -.. ================================================== -.. FOR YOUR INFORMATION -.. -------------------------------------------------- -.. -*- coding: utf-8 -*- with BOM. - -.. include:: ../Includes.txt - - -.. _to-do-list: - -To Do List -============== - -* Improve documentation diff --git a/README.md b/README.md index 71730f5..b84f977 100644 --- a/README.md +++ b/README.md @@ -6,5 +6,12 @@ Web2PDF is a fluid and extbase based extension, which provides the functionality to render an PDF File out ouf a HTML Page. Generate a "PDF link" on each page by including the plugin in TypoScript or just on single pages using TYPO3 Backend. - Uses CSS to render PDF Output. CSS with media key "all" is included automatically. You can choose if you want to include "screen" or "print" CSS. + +## TYPO3 Compatibility + +| Version | TYPO3 | PHP | Support/Development | +| ------------------- | ---------- | ----------|---------------------------------------- | +| 3.x | 11.5 | >= 7.4 | Features, Bugfixes, Security Updates | +| 2.x | 10.4 | 7.2 - 7.4 | Features, Bugfixes, Security Updates | +| 1.x | 8.7 - 9.5 | 7.0 - 7.4 | Security Updates | \ No newline at end of file diff --git a/Resources/Private/.htaccess b/Resources/Private/.htaccess new file mode 100644 index 0000000..ce9ec34 --- /dev/null +++ b/Resources/Private/.htaccess @@ -0,0 +1,11 @@ +# Apache < 2.3 + + Order allow,deny + Deny from all + Satisfy All + + +# Apache ≥ 2.3 + + Require all denied + diff --git a/Resources/Private/Language/locallang.xlf b/Resources/Private/Language/locallang.xlf index 07f403d..cbabc1c 100644 --- a/Resources/Private/Language/locallang.xlf +++ b/Resources/Private/Language/locallang.xlf @@ -4,8 +4,8 @@ product-name="web2pdf">
- - Print Current Page + + Download current page as PDF PDF format settings diff --git a/Resources/Private/Templates/Pdf/GeneratePdfLink.html b/Resources/Private/Templates/Pdf/GeneratePdfLink.html index 4fe0b94..99a90c1 100644 --- a/Resources/Private/Templates/Pdf/GeneratePdfLink.html +++ b/Resources/Private/Templates/Pdf/GeneratePdfLink.html @@ -1,5 +1,5 @@

- - + +

\ No newline at end of file diff --git a/ext_icon.png b/Resources/Public/Icons/Extension.png similarity index 100% rename from ext_icon.png rename to Resources/Public/Icons/Extension.png diff --git a/Tests/Build/UnitTests.xml b/Tests/Build/UnitTests.xml new file mode 100644 index 0000000..98f551c --- /dev/null +++ b/Tests/Build/UnitTests.xml @@ -0,0 +1,29 @@ + + + + + ./Classes + + + + + ../Unit/ + + + diff --git a/Tests/Unit/Utility/FilenameUtilityTest.php b/Tests/Unit/Utility/FilenameUtilityTest.php index 16970fb..106c4d5 100644 --- a/Tests/Unit/Utility/FilenameUtilityTest.php +++ b/Tests/Unit/Utility/FilenameUtilityTest.php @@ -26,50 +26,52 @@ namespace Mittwald\Tests\Utility; use Mittwald\Web2pdf\Utility\FilenameUtility; -use Nimut\TestingFramework\TestCase\UnitTestCase; - +use TYPO3\TestingFramework\Core\Unit\UnitTestCase; /** * Class PdfLinkUtilityTest - * @package Mittwald\Tests\Utility */ class FilenameUtilityTest extends UnitTestCase { - /** - * @var FilenameUtility|\PHPUnit_Framework_MockObject_MockObject + * @var FilenameUtility */ - protected $fixture; - + protected $subject; /** - * @dataProvider getTitleData + * Setup */ - public function testConvertMethod($string, $expected) + protected function setUp(): void { - $this->assertEquals($expected, $this->fixture->convert($string)); + $this->subject = new FilenameUtility(); } - /** - * @return array + * Teardown */ - public function getTitleData() + protected function tearDown(): void { - return array( - array('my tést string', 'my_test_string'), - array('mY TeSt', 'mY_TeSt'), - array('my test 123', 'my_test_123'), - array('my tést 123', 'my_test_123') // in case it should be é to e // works but could not find a way to test it - ); + unset($this->subject); } /** - * Set up fixture + * @dataProvider getTitleData */ - protected function setUp() + public function testConvertMethod($string, $expected) { - $this->fixture = new FilenameUtility(); + self::assertEquals($expected, $this->subject->convert($string)); } + /** + * @return array + */ + public function getTitleData() + { + return [ + ['my tést string', 'my_test_string'], + ['mY TeSt', 'mY_TeSt'], + ['my test 123', 'my_test_123'], + ['my tést 123', 'my_test_123'], // in case it should be é to e // works but could not find a way to test it + ]; + } } diff --git a/Tests/Unit/Utility/PdfLinkUtilityTest.php b/Tests/Unit/Utility/PdfLinkUtilityTest.php index be793ae..4b06640 100644 --- a/Tests/Unit/Utility/PdfLinkUtilityTest.php +++ b/Tests/Unit/Utility/PdfLinkUtilityTest.php @@ -1,8 +1,9 @@ + * (C) Mittwald CM Service GmbH & Co. KG * * All rights reserved * @@ -21,76 +22,79 @@ * GNU General Public License for more details. * * This copyright notice MUST APPEAR in all copies of the script! - * ************************************************************* */ + ***************************************************************/ namespace Mittwald\Tests\Utility; use Mittwald\Web2pdf\Utility\PdfLinkUtility; -use Nimut\TestingFramework\TestCase\UnitTestCase; - +use TYPO3\TestingFramework\Core\Unit\UnitTestCase; /** * Class PdfLinkUtilityTest - * @package Mittwald\Tests\Utility */ -class PdfLinkUtilityTest extends UnitTestCase { - +class PdfLinkUtilityTest extends UnitTestCase +{ /** - * @var PdfLinkUtility|\PHPUnit_Framework_MockObject_MockObject + * @var PdfLinkUtility */ protected $fixture; - /** - * + * Set up fixture */ - public function testKeepLinksIfNoSectionGiven() { - $this->fixture->expects($this->once())->method('getSiteUri')->willReturn($this->getSiteUri()); + protected function setUp(): void + { + $this->fixture = $this->getAccessibleMock( + \Mittwald\Web2pdf\Utility\PdfLinkUtility::class, + ['getSiteUri', 'getHost'], + [], + '', + false + ); + $this->fixture->expects(self::once())->method('getHost')->willReturn($this->getDefaultHost()); + } + + public function testKeepLinksIfNoSectionGiven() + { + $this->fixture->expects(self::once())->method('getSiteUri')->willReturn($this->getSiteUri()); $return = $this->fixture->replace($this->getLink($this->getSiteUri())); - $this->assertEquals($this->getLink($this->getSiteUri()), $return); + self::assertEquals($this->getLink($this->getSiteUri()), $return); } - /** - * - */ - public function testLocalAnchorsAreResolvedIfSiteUriContainsSpecialChars() { - $this->fixture->expects($this->once())->method('getSiteUri')->willReturn($this->getSiteUriWithSectionAndSpecialChars()); + public function testLocalAnchorsAreResolvedIfSiteUriContainsSpecialChars() + { + $this->fixture->expects(self::once())->method('getSiteUri')->willReturn($this->getSiteUriWithSectionAndSpecialChars()); $return = $this->fixture->replace($this->getLink($this->getSiteUriWithSectionAndSpecialChars())); - $this->assertEquals('Link Test', $return); + self::assertEquals('Link Test', $return); } - /** - * - */ - public function testLocalAnchorsAreResolvedIfSiteUriContainsHtmlEntities() { - $this->fixture->expects($this->once())->method('getSiteUri')->willReturn(htmlentities($this->getSiteUriWithSectionAndSpecialChars())); + public function testLocalAnchorsAreResolvedIfSiteUriContainsHtmlEntities() + { + $this->fixture->expects(self::once())->method('getSiteUri')->willReturn(htmlentities($this->getSiteUriWithSectionAndSpecialChars())); $return = $this->fixture->replace($this->getLink($this->getSiteUriWithSectionAndSpecialChars())); - $this->assertEquals('Link Test', $return); + self::assertEquals('Link Test', $return); } - /** - * - */ - public function testLocalAnchorsAreResolved() { - $this->fixture->expects($this->once())->method('getSiteUri')->willReturn($this->getSiteUriWithSection()); + public function testLocalAnchorsAreResolved() + { + $this->fixture->expects(self::once())->method('getSiteUri')->willReturn($this->getSiteUriWithSection()); $return = $this->fixture->replace($this->getLink($this->getSiteUriWithSection())); - $this->assertEquals('Link Test', $return); + self::assertEquals('Link Test', $return); } - /** - * - */ - public function testLocalAnchorsOfExternalPageKeptInContent() { - $this->fixture->expects($this->once())->method('getSiteUri')->willReturn($this->getSiteUriWithSection()); + public function testLocalAnchorsOfExternalPageKeptInContent() + { + $this->fixture->expects(self::once())->method('getSiteUri')->willReturn($this->getSiteUriWithSection()); $return = $this->fixture->replace($this->getLink('/external-page#section1', $this->getExternalHost())); - $this->assertEquals('Link Test', $return); + self::assertEquals('Link Test', $return); } /** * @param string $siteUri * @return string */ - protected function getLink($siteUri, $host = null) { + protected function getLink($siteUri, $host = null) + { if (is_null($host)) { $host = $this->getDefaultHost(); } @@ -100,51 +104,40 @@ protected function getLink($siteUri, $host = null) { /** * @return string */ - protected function getSiteUri() { + protected function getSiteUri() + { return '/index.php?id=124'; } /** * @return string */ - protected function getSiteUriWithSection() { + protected function getSiteUriWithSection() + { return '/index.php?id=123#section1'; } /** * @return string */ - protected function getSiteUriWithSectionAndSpecialChars() { + protected function getSiteUriWithSectionAndSpecialChars() + { return '/index.php?id=123&my_ext_pi1[test]=1#section1'; } /** * @return string */ - protected function getDefaultHost() { + protected function getDefaultHost() + { return 'http://www.google.de'; } /** * @return string */ - protected function getExternalHost() { + protected function getExternalHost() + { return 'http://www.external.de'; } - - - /** - * Set up fixture - */ - protected function setUp() { - $this->fixture = $this->getAccessibleMock( - 'Mittwald\Web2pdf\Utility\PdfLinkUtility', - array('getSiteUri', 'getHost'), - array(), - '', - false - ); - $this->fixture->expects($this->once())->method('getHost')->willReturn($this->getDefaultHost()); - } - } diff --git a/composer.json b/composer.json index 128cd6d..66153d6 100644 --- a/composer.json +++ b/composer.json @@ -1,18 +1,19 @@ { "name": "mittwald/web2pdf", "description": "Web2PDF Extension", - "homepage": "http://www.mittwald.de", + "homepage": "https://www.mittwald.de", "license": "GPL-2.0-or-later", "minimum-stability": "dev", "prefer-stable": true, "type": "typo3-cms-extension", "require": { - "typo3/cms-core": "^10.4", + "typo3/cms-core": "^11.5", "mpdf/mpdf": "^8.0", - "php": ">=7.2" + "php": ">=7.4" }, "require-dev": { - "nimut/testing-framework": "*" + "typo3/testing-framework": "^6.9.0", + "friendsofphp/php-cs-fixer": "^3.0" }, "autoload": { "psr-4": { @@ -32,15 +33,20 @@ "scripts": { "extension-package": ["bash -x Build/package-version.sh"], "post-autoload-dump": [ - "mkdir -p public/typo3conf/ext/", - "[ -L public/typo3conf/ext/web2pdf ] || ln -snvf ../../../. public/typo3conf/ext/web2pdf" + "mkdir -p .Build/public/typo3conf/ext/", + "[ -L .Build/public/typo3conf/ext/web2pdf ] || ln -snvf ../../../../. .Build/public/typo3conf/ext/web2pdf" ] }, + "config": { + "vendor-dir": ".Build/vendor", + "bin-dir": ".Build/bin" + }, "extra": { "typo3/cms": { "cms-package-dir": "{$vendor-dir}/typo3/cms", "extension-key": "web2pdf", - "web-dir": "public" + "app-dir": ".Build", + "web-dir": ".Build/public" } } } diff --git a/ext_emconf.php b/ext_emconf.php index 796e71a..0eaf042 100644 --- a/ext_emconf.php +++ b/ext_emconf.php @@ -24,9 +24,9 @@ * This copyright notice MUST APPEAR in all copies of the script! * ************************************************************* */ -$EM_CONF[$_EXTKEY] = array( +$EM_CONF[$_EXTKEY] = [ 'title' => 'Web2PDF', - 'description' => 'This Extension renders the pagecontent to a PDF file. It supports css and uses the library mPDF. This extension is based on the pdf_generator2.', + 'description' => 'This Extension renders the pagecontent to a PDF file. It supports css and uses the library mPDF.', 'category' => 'plugin', 'author' => 'Mittwald CM Service', 'author_company' => 'Mittwald CM Service', @@ -34,16 +34,11 @@ 'dependencies' => 'extbase,fluid', 'state' => 'stable', 'clearCacheOnLoad' => '1', - 'version' => '1.2-dev', - 'constraints' => array( - 'depends' => array( - 'typo3' => '10.4.0-10.4.99', - 'php' => '7.2.0-7.4.99', - ), - ), - 'autoload' => array( - 'psr-4' => array( - 'Mittwald\\Web2pdf\\' => 'Classes', - ), - ), -); + 'version' => '3.0.0', + 'constraints' => [ + 'depends' => [ + 'typo3' => '11.5.0-11.5.99', + 'php' => '7.4.0-8.1.99', + ], + ], +]; diff --git a/ext_localconf.php b/ext_localconf.php index bf09564..5edde9c 100644 --- a/ext_localconf.php +++ b/ext_localconf.php @@ -1,43 +1,20 @@ - * - * All rights reserved - * - * This script is part of the TYPO3 project. The TYPO3 project is - * free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The GNU General Public License can be found at - * http://www.gnu.org/copyleft/gpl.html. - * - * This script is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * This copyright notice MUST APPEAR in all copies of the script! - * ************************************************************* */ +use TYPO3\CMS\Core\Utility\ExtensionManagementUtility; +use TYPO3\CMS\Extbase\Utility\ExtensionUtility; -if (! defined('TYPO3_MODE')) { - die ('Access denied.'); -} +defined('TYPO3') or die(); // Include the Composer autoloader from "Resources/Private/Libraries". This is // only necessary when this extension is installed from TER; when using // Composer, the MPDF dependency is pulled via Composer like any sane person // would. -$mpdfAutoload = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath('web2pdf') . 'Resources/Private/Libraries/vendor/autoload.php'; +$mpdfAutoload = ExtensionManagementUtility::extPath('web2pdf') . 'Resources/Private/Libraries/vendor/autoload.php'; if (file_exists($mpdfAutoload)) { require_once($mpdfAutoload); } -TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin( +ExtensionUtility::configurePlugin( 'web2pdf', 'Pi1', [\Mittwald\Web2pdf\Controller\PdfController::class => 'generatePdfLink'],