From 23726e34124566b58642eca213204e95cd628936 Mon Sep 17 00:00:00 2001 From: Roman Schilter Date: Thu, 16 Sep 2021 16:56:58 +0200 Subject: [PATCH 01/20] [BUGFIX] Replace the deprecated TYPO3_OS constant usage with the new Environment API (resolves #168) Fixes: #168 Ported-From: #169 --- Classes/Utility/ShellUtility.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Classes/Utility/ShellUtility.php b/Classes/Utility/ShellUtility.php index cade7b2c0..0ec45f681 100644 --- a/Classes/Utility/ShellUtility.php +++ b/Classes/Utility/ShellUtility.php @@ -1,6 +1,8 @@ Date: Thu, 23 Sep 2021 16:57:49 +0200 Subject: [PATCH 02/20] [TASK] Replace badges from travis to github actions --- .github/workflows/ci.yml | 10 +++++----- README.md | 32 ++++++++++++++++++-------------- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6374a361d..cdd4d7900 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,12 +1,12 @@ -name: EXT:tika Github Actions +name: build on: push: - branches: [ master ] + branches: [ master, release-10.0.x ] tags: - "**" pull_request: - branches: [ master ] + branches: [ master, release-10.0.x ] env: TIKA_VERSION: '1.24.1' @@ -124,9 +124,9 @@ jobs: - name: Get comment id: get-comment run: | - readonly local comment=$(git tag -n10 -l ${{ steps.get-version.outputs.version }} | sed "s/^[0-9.]*[ ]*//g") + readonly local comment=$(git tag -n99 -l ${{ steps.get-version.outputs.version }} | sed "s/^[0-9.]*[ ]*//g") if [[ -z "${comment// }" ]]; then - echo ::set-output name=comment::Released version ${{ steps.get-version.outputs.version }} of tailor_ext + echo ::set-output name=comment::Released version ${{ steps.get-version.outputs.version }} of EXT:tika else echo ::set-output name=comment::$comment fi diff --git a/README.md b/README.md index b81bfef42..b5ec4d4dc 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,9 @@ # Apache Tika for TYPO3 -[![Build Status](https://travis-ci.org/TYPO3-Solr/ext-tika.svg?branch=master)](https://travis-ci.org/TYPO3-Solr/ext-tika) -[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/TYPO3-Solr/ext-tika/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/TYPO3-Solr/ext-tika/?branch=master) -[![Code Coverage](https://scrutinizer-ci.com/g/TYPO3-Solr/ext-tika/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/TYPO3-Solr/ext-tika/?branch=master) +[![Build Status](https://github.com/TYPO3-Solr/ext-tika/actions/workflows/ci.yml/badge.svg?branch=release-10.0.x)](https://github.com/TYPO3-Solr/ext-tika/actions?query=branch:release-10.0.x) +[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/TYPO3-Solr/ext-tika/badges/quality-score.png?b=release-10.0.x)](https://scrutinizer-ci.com/g/TYPO3-Solr/ext-tika/?branch=release-10.0.x) +[![Code Coverage](https://scrutinizer-ci.com/g/TYPO3-Solr/ext-tika/badges/coverage.png?b=release-10.0.x)](https://scrutinizer-ci.com/g/TYPO3-Solr/ext-tika/?branch=release-10.0.x) [![Latest Stable Version](https://poser.pugx.org/apache-solr-for-typo3/tika/v/stable)](https://packagist.org/packages/apache-solr-for-typo3/tika) -[![Latest Unstable Version](https://poser.pugx.org/apache-solr-for-typo3/tika/v/unstable)](https://packagist.org/packages/apache-solr-for-typo3/tika) [![License](https://poser.pugx.org/apache-solr-for-typo3/tika/license)](https://packagist.org/packages/apache-solr-for-typo3/tika) [![Monthly Downloads](https://poser.pugx.org/apache-solr-for-typo3/tika/d/monthly)](https://packagist.org/packages/apache-solr-for-typo3/tika) @@ -23,16 +22,21 @@ Please find further information regarding Apache Tika on the [project's homepage ## Continuous Integration -We use travis ci for continuous integration. To run the whole test suite locally for one TYPO3 & Tika Version -do the following: +We use GitHub Actions for continuous integration. -```bash -export TIKA_VERSION="1.11" -export TIKA_PATH="/tmp/tika" -export TYPO3_VERSION="dev-master" -chmod +x ./Build/Test/*.sh -./Build/Test/bootstrap.sh -./Build/Test/cibuild.sh +To run the test suite locally, please use our DDEV docker environment https://github.com/TYPO3-Solr/solr-ddev-site. + +**Note**: + This requires a proper combination of branches: +* solr-ddev-site on release-11.1.x branch + * packages/ext-solr on release-11.1.x + * packages/ext-tika on release-10.0.x +* Please refer to [version matrix](https://raw.githubusercontent.com/TYPO3-Solr/ext-solr/master/Documentation/Appendix/VersionMatrix.rst) for proper combination of branches + +```shell +ddev enable tika +ddev tests-unit-tika +ddev tests-integration-tika ``` ## Contributions @@ -50,4 +54,4 @@ chmod +x ./Build/Test/*.sh 2. git fetch upstream 3. git checkout master 4. git merge upstream/master -5. git push origin master \ No newline at end of file +5. git push origin master From 8d3a5940d49880e59781c9fd7682eb97b6ffc5b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20K=C3=A4hm?= Date: Wed, 15 Dec 2021 15:48:50 +0100 Subject: [PATCH 03/20] [TASK] make actions runnable against main, release-10.0.x, release-6.0.x Due of switching to GitHub Actions and renaming branches, the adjustment of Actions setting is wanted. --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cdd4d7900..8c2eca0ca 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,11 +2,11 @@ name: build on: push: - branches: [ master, release-10.0.x ] + branches: [ main, release-10.0.x, release-6.0.x ] tags: - "**" pull_request: - branches: [ master, release-10.0.x ] + branches: [ main, release-10.0.x, release-6.0.x ] env: TIKA_VERSION: '1.24.1' From dc52912da48a8343b13ed7bba18c776db8143adb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Tue, 14 Dec 2021 16:10:39 +0100 Subject: [PATCH 04/20] [FEATURE:BP:10] Allow definition of additional Java command options This commit introduces the ability to provide additional command options. They are passed to the Java command when using the tika app. For safety reasons, only a small subset of command options can be configured: -Dfoo=bar -Dfoo='hello world' -Dfoo="hello world" --- Classes/Service/Tika/AppService.php | 47 ++++++++++++++++++- .../Service/Tika/AppServiceTest.php | 10 ++++ .../Tika/ServiceIntegrationTestCase.php | 1 + ext_conf_template.txt | 3 ++ 4 files changed, 60 insertions(+), 1 deletion(-) diff --git a/Classes/Service/Tika/AppService.php b/Classes/Service/Tika/AppService.php index 99f4724ba..0ef18b9ed 100644 --- a/Classes/Service/Tika/AppService.php +++ b/Classes/Service/Tika/AppService.php @@ -28,6 +28,8 @@ */ class AppService extends AbstractService { + protected const JAVA_COMMAND_OPTIONS_REGEX = '/-D(?P[\w.]+)=(?P"[^"]+"|\'[^\']+\'|[^\\s\'"]+)/'; + /** * @var array */ @@ -62,6 +64,7 @@ public function getTikaVersion() { $tikaCommand = CommandUtility::getCommand('java') . ' -Dfile.encoding=UTF8' // forces UTF8 output + . $this->getAdditionalCommandOptions() . ' -jar ' . escapeshellarg(FileUtility::getAbsoluteFilePath($this->configuration['tikaPath'])) . ' -V'; @@ -80,6 +83,7 @@ public function extractText(FileInterface $file) $tikaCommand = ShellUtility::getLanguagePrefix() . CommandUtility::getCommand('java') . ' -Dfile.encoding=UTF8' // forces UTF8 output + . $this->getAdditionalCommandOptions() . ' -jar ' . escapeshellarg(FileUtility::getAbsoluteFilePath($this->configuration['tikaPath'])) . ' -t' . ' ' . ShellUtility::escapeShellArgument($localTempFilePath); @@ -110,6 +114,7 @@ public function extractMetaData(FileInterface $file) $tikaCommand = ShellUtility::getLanguagePrefix() . CommandUtility::getCommand('java') . ' -Dfile.encoding=UTF8' + . $this->getAdditionalCommandOptions() . ' -jar ' . escapeshellarg(FileUtility::getAbsoluteFilePath($this->configuration['tikaPath'])) . ' -m' . ' ' . ShellUtility::escapeShellArgument($localTempFilePath); @@ -175,6 +180,7 @@ protected function detectLanguageFromLocalFile($localFilePath) $tikaCommand = ShellUtility::getLanguagePrefix() . CommandUtility::getCommand('java') . ' -Dfile.encoding=UTF8' + . $this->getAdditionalCommandOptions() . ' -jar ' . escapeshellarg(FileUtility::getAbsoluteFilePath($this->configuration['tikaPath'])) . ' -l' . ' ' . ShellUtility::escapeShellArgument($localFilePath); @@ -310,7 +316,46 @@ public function isAvailable() */ protected function getMimeTypeOutputFromTikaJar(): string { - $tikaCommand = ShellUtility::getLanguagePrefix() . CommandUtility::getCommand('java') . ' -Dfile.encoding=UTF8' . ' -jar ' . escapeshellarg(FileUtility::getAbsoluteFilePath($this->configuration['tikaPath'])) . ' --list-supported-types'; + $tikaCommand = ShellUtility::getLanguagePrefix() + . CommandUtility::getCommand('java') + . ' -Dfile.encoding=UTF8' + . $this->getAdditionalCommandOptions() + . ' -jar ' . escapeshellarg(FileUtility::getAbsoluteFilePath($this->configuration['tikaPath'])) + . ' --list-supported-types'; + return trim(shell_exec($tikaCommand)); } + + /** + * Parse additional Java command options. + * + * Reads the configuration value `javaCommandOptions` and tries to parse it to a + * safe argument string. For safety reasons, only the following variants are + * allowed (multiple separated by space): + * + * -Dfoo=bar + * -Dfoo='hello world' + * -Dfoo="hello world" + * + * @return string Parsed additional Java command options + */ + protected function getAdditionalCommandOptions(): string + { + $commandOptions = trim((string)($this->configuration['javaCommandOptions'] ?? '')); + + // Early return if no additional command options are configured + // or configuration does not match required pattern (only -D parameter is supported) + if ('' === $commandOptions || !preg_match_all(self::JAVA_COMMAND_OPTIONS_REGEX, $commandOptions, $matches)) { + return ''; + } + + // Combine matched command options with escaped argument value + $commandOptionsString = ''; + foreach (array_combine($matches['property'], $matches['value']) as $property => $unescapedValue) { + $escapedValue = CommandUtility::escapeShellArgument(trim($unescapedValue, '"\'')); + $commandOptionsString .= sprintf(' -D%s=%s', $property, $escapedValue); + } + + return $commandOptionsString; + } } diff --git a/Tests/Integration/Service/Tika/AppServiceTest.php b/Tests/Integration/Service/Tika/AppServiceTest.php index 93fab4c63..1f97bef0c 100644 --- a/Tests/Integration/Service/Tika/AppServiceTest.php +++ b/Tests/Integration/Service/Tika/AppServiceTest.php @@ -149,5 +149,15 @@ public function canParseMimeList() $this->assertContains('gzip/document', $supportedMimeTypes, 'Mimetype from alias was not found'); } + /** + * @test + */ + public function includesAdditionalCommandOptions() + { + $service = new AppService($this->getConfiguration()); + $service->setLogger(new NullLogger()); + $service->getTikaVersion(); + $this->assertContains('-Dlog4j2.formatMsgNoLookups=\'true\'', ExecRecorder::$execCommand); + } } diff --git a/Tests/Integration/Service/Tika/ServiceIntegrationTestCase.php b/Tests/Integration/Service/Tika/ServiceIntegrationTestCase.php index 28479b296..0862c6921 100644 --- a/Tests/Integration/Service/Tika/ServiceIntegrationTestCase.php +++ b/Tests/Integration/Service/Tika/ServiceIntegrationTestCase.php @@ -295,6 +295,7 @@ protected function getConfiguration() 'logging' => 0, 'tikaPath' => getenv($envVarNamePrefix . 'APP_JAR_PATH') ?: "$tikaPath/tika-app-$tikaVersion.jar", + 'javaCommandOptions' => '-Dlog4j2.formatMsgNoLookups=true', 'tikaServerPath' => getenv($envVarNamePrefix . 'SERVER_JAR_PATH') ?: "$tikaPath/tika-server-$tikaVersion.jar", 'tikaServerScheme' => getenv($envVarNamePrefix . 'SERVER_SCHEME') ?: 'http', diff --git a/ext_conf_template.txt b/ext_conf_template.txt index 03d7cb9d3..c5e540dd3 100644 --- a/ext_conf_template.txt +++ b/ext_conf_template.txt @@ -21,6 +21,9 @@ fileSizeLimit = 500 # cat=jar//10; type=string; label=Tika App Jar Path: The absolute path to your Apache Tika app jar file (tika-app-x.x.jar) tikaPath = +# cat=jar//20; type=string; label=Java command options: Additional command options passed to the java executable (only -D parameter is supported). Separate multiple parameters with a space. +javaCommandOptions = + # cat=server//10; type=string; label=Tika Server Jar Path: [Optional] The absolute path to your Apache Tika server jar file (tika-server-x.x.jar). When set you can use the backend module to start and stop the Tika server from the TYPO3 backend. Otherwise the host and port settings will be used. tikaServerPath = From 1b024b76cd3d2c80c7c78e24795b54acdf139d4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20K=C3=A4hm?= Date: Fri, 17 Dec 2021 13:04:41 +0100 Subject: [PATCH 05/20] Release 10.0.1 **Important**: This version contains CVE-2021-44228 fixes for users, who starting the Tika Server-daemons within TYPO3 BE or using Tika app modes. All users using dedicated Tika server or Apache Solr Tika cell connections do not benefit from the update and should harden the Solr Servers and/or Tika Servers with official CVE-2021-44228 patches manually. Relates: #172 --- Documentation/Index.rst | 2 +- Documentation/Releases/10_0.rst | 10 ++++++++++ Documentation/Settings.yml | 4 ++-- Documentation/conf.py | 2 +- ext_emconf.php | 2 +- 5 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Documentation/Index.rst b/Documentation/Index.rst index b6198573a..acd5e31c5 100644 --- a/Documentation/Index.rst +++ b/Documentation/Index.rst @@ -18,7 +18,7 @@ Apache Tika for TYPO3 tika :Version: - 10.0.0 + 10.0.1 :Language: en diff --git a/Documentation/Releases/10_0.rst b/Documentation/Releases/10_0.rst index 6f7b0955a..228ad22e4 100644 --- a/Documentation/Releases/10_0.rst +++ b/Documentation/Releases/10_0.rst @@ -1,3 +1,13 @@ +========================================================== +Apache Solr for TYPO3 - Tika Addon version 10.0.1 released +========================================================== + +**Important**: +This version contains CVE-2021-44228 fixes for users, who starting +the Tika Server-daemons within TYPO3 BE or using Tika app modes. +All users using dedicated Tika server or Apache Solr Tika cell connections do not benefit from the update +and should harden the Solr Servers and/or Tika Servers with official CVE-2021-44228 patches manually. + ========================================================== Apache Solr for TYPO3 - Tika Addon version 10.0.0 released ========================================================== diff --git a/Documentation/Settings.yml b/Documentation/Settings.yml index 8407dd7a2..f5e40de35 100644 --- a/Documentation/Settings.yml +++ b/Documentation/Settings.yml @@ -6,8 +6,8 @@ conf.py: copyright: 2009-2021 project: Apache Tika for TYPO3 - version: 10.0.0 - release: 10.0.0 + version: 10.0.1 + release: 10.0.1 latex_documents: - - Index - tika.tex diff --git a/Documentation/conf.py b/Documentation/conf.py index fc8b94362..cf3012713 100644 --- a/Documentation/conf.py +++ b/Documentation/conf.py @@ -64,7 +64,7 @@ # The short X.Y version. version = '10.0' # The full version, including alpha/beta/rc tags. -release = '10.0.0' +release = '10.0.1' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/ext_emconf.php b/ext_emconf.php index a898dbc56..d501397fa 100644 --- a/ext_emconf.php +++ b/ext_emconf.php @@ -2,7 +2,7 @@ $EM_CONF[$_EXTKEY] = [ 'title' => 'Apache Tika for TYPO3', 'description' => 'Provides Tika services for TYPO3 to detect a document\'s language, extract meta data, and extract content from files. Can either use a stand alone Tika executable or Tika integrated in a Solr server with an activated extracting request handler.', - 'version' => '10.0.0', + 'version' => '10.0.1', 'state' => 'stable', 'category' => 'services', 'author' => 'Ingo Renner, Timo Hund, Markus Friedrich', From 4ad61723ea19b6380532b68bb6d7273c5fab8ba5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Fri, 17 Dec 2021 15:58:54 +0100 Subject: [PATCH 06/20] [BUGFIX:BP:10] Handle custom java command options for server module as well Related: #174 --- Classes/Service/Tika/AbstractService.php | 36 ++++++++++++++++++++++++ Classes/Service/Tika/AppService.php | 35 ----------------------- Classes/Service/Tika/ServerService.php | 2 ++ 3 files changed, 38 insertions(+), 35 deletions(-) diff --git a/Classes/Service/Tika/AbstractService.php b/Classes/Service/Tika/AbstractService.php index 8662fdf51..0550a048c 100644 --- a/Classes/Service/Tika/AbstractService.php +++ b/Classes/Service/Tika/AbstractService.php @@ -17,6 +17,7 @@ use Psr\Log\LoggerAwareInterface; use Psr\Log\LoggerAwareTrait; use Psr\Log\LogLevel; +use TYPO3\CMS\Core\Utility\CommandUtility; /** * Abstract Tika service implementing shared methods @@ -26,6 +27,8 @@ */ abstract class AbstractService implements ServiceInterface, LoggerAwareInterface { + protected const JAVA_COMMAND_OPTIONS_REGEX = '/-D(?P[\w.]+)=(?P"[^"]+"|\'[^\']+\'|[^\\s\'"]+)/'; + use LoggerAwareTrait; /** @@ -80,4 +83,37 @@ protected function log(string $message, array $data = [], $severity = LogLevel:: public function getSupportedMimeTypes() { return []; } + + /** + * Parse additional Java command options. + * + * Reads the configuration value `javaCommandOptions` and tries to parse it to a + * safe argument string. For safety reasons, only the following variants are + * allowed (multiple separated by space): + * + * -Dfoo=bar + * -Dfoo='hello world' + * -Dfoo="hello world" + * + * @return string Parsed additional Java command options + */ + protected function getAdditionalCommandOptions(): string + { + $commandOptions = trim((string)($this->configuration['javaCommandOptions'] ?? '')); + + // Early return if no additional command options are configured + // or configuration does not match required pattern (only -D parameter is supported) + if ('' === $commandOptions || !preg_match_all(self::JAVA_COMMAND_OPTIONS_REGEX, $commandOptions, $matches)) { + return ''; + } + + // Combine matched command options with escaped argument value + $commandOptionsString = ''; + foreach (array_combine($matches['property'], $matches['value']) as $property => $unescapedValue) { + $escapedValue = CommandUtility::escapeShellArgument(trim($unescapedValue, '"\'')); + $commandOptionsString .= sprintf(' -D%s=%s', $property, $escapedValue); + } + + return $commandOptionsString; + } } diff --git a/Classes/Service/Tika/AppService.php b/Classes/Service/Tika/AppService.php index 0ef18b9ed..b22d55f72 100644 --- a/Classes/Service/Tika/AppService.php +++ b/Classes/Service/Tika/AppService.php @@ -28,8 +28,6 @@ */ class AppService extends AbstractService { - protected const JAVA_COMMAND_OPTIONS_REGEX = '/-D(?P[\w.]+)=(?P"[^"]+"|\'[^\']+\'|[^\\s\'"]+)/'; - /** * @var array */ @@ -325,37 +323,4 @@ protected function getMimeTypeOutputFromTikaJar(): string return trim(shell_exec($tikaCommand)); } - - /** - * Parse additional Java command options. - * - * Reads the configuration value `javaCommandOptions` and tries to parse it to a - * safe argument string. For safety reasons, only the following variants are - * allowed (multiple separated by space): - * - * -Dfoo=bar - * -Dfoo='hello world' - * -Dfoo="hello world" - * - * @return string Parsed additional Java command options - */ - protected function getAdditionalCommandOptions(): string - { - $commandOptions = trim((string)($this->configuration['javaCommandOptions'] ?? '')); - - // Early return if no additional command options are configured - // or configuration does not match required pattern (only -D parameter is supported) - if ('' === $commandOptions || !preg_match_all(self::JAVA_COMMAND_OPTIONS_REGEX, $commandOptions, $matches)) { - return ''; - } - - // Combine matched command options with escaped argument value - $commandOptionsString = ''; - foreach (array_combine($matches['property'], $matches['value']) as $property => $unescapedValue) { - $escapedValue = CommandUtility::escapeShellArgument(trim($unescapedValue, '"\'')); - $commandOptionsString .= sprintf(' -D%s=%s', $property, $escapedValue); - } - - return $commandOptionsString; - } } diff --git a/Classes/Service/Tika/ServerService.php b/Classes/Service/Tika/ServerService.php index 054a12478..43f76a699 100644 --- a/Classes/Service/Tika/ServerService.php +++ b/Classes/Service/Tika/ServerService.php @@ -94,6 +94,8 @@ protected function initializeService(): void */ protected function getProcess($arguments = ''): Process { + $arguments = trim($this->getAdditionalCommandOptions() . ' ' . $arguments); + return GeneralUtility::makeInstance(Process::class, CommandUtility::getCommand('java'), $arguments); } From 655dc9af0e9985ab74783de5ebeb0b1f17fe2094 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20K=C3=A4hm?= Date: Fri, 17 Dec 2021 16:40:38 +0100 Subject: [PATCH 07/20] Release 10.0.2(CVE-2021-44228) Please read the release notes before updating: https://github.com/TYPO3-Solr/ext-tika/releases/tag/10.0.2 --- Documentation/Index.rst | 2 +- Documentation/Releases/10_0.rst | 29 +++++++++++++++++++++++++ Documentation/Releases/6_0.rst | 38 +++++++++++++++++++++++++++++++++ Documentation/Settings.yml | 4 ++-- Documentation/conf.py | 2 +- ext_emconf.php | 2 +- 6 files changed, 72 insertions(+), 5 deletions(-) diff --git a/Documentation/Index.rst b/Documentation/Index.rst index acd5e31c5..5bb4c004d 100644 --- a/Documentation/Index.rst +++ b/Documentation/Index.rst @@ -18,7 +18,7 @@ Apache Tika for TYPO3 tika :Version: - 10.0.1 + 10.0.2 :Language: en diff --git a/Documentation/Releases/10_0.rst b/Documentation/Releases/10_0.rst index 228ad22e4..e6716b66b 100644 --- a/Documentation/Releases/10_0.rst +++ b/Documentation/Releases/10_0.rst @@ -1,3 +1,32 @@ +========================================================== +Apache Solr for TYPO3 - Tika Addon version 10.0.2 released +========================================================== + +**Important**: +This version contains CVE-2021-44228 fixes for users, who starting +the Tika Server-daemons within TYPO3 BE or using Tika app modes. +All users using dedicated Tika server or Apache Solr Tika cell connections do not benefit from the update +and should harden the Solr Servers and/or Tika Servers with official CVE-2021-44228 patches manually. + +Manual action required for Tika App or enabled Tika Server module + +Please note that the release does not automatically include security measures against CVE-2021-44228. Rather, it is +now possible to specify additional parameters that can be passed when the java binary is executed. +The parameters can be set using the extension configuration javaCommandOptions. +Example: + +.. code-block:: + + # LocalConfiguration.php + return [ + 'EXTENSIONS' => [ + 'tika' => [ + 'javaCommandOptions' => '-Dlog4j2.formatMsgNoLookups=true', + ], + ], + ]; + + ========================================================== Apache Solr for TYPO3 - Tika Addon version 10.0.1 released ========================================================== diff --git a/Documentation/Releases/6_0.rst b/Documentation/Releases/6_0.rst index 6b3532e3c..9aeb89c56 100644 --- a/Documentation/Releases/6_0.rst +++ b/Documentation/Releases/6_0.rst @@ -1,3 +1,41 @@ +========================================================== +Apache Solr for TYPO3 - Tika Addon version 6.0.2 released +========================================================== + +**Important**: +This version contains CVE-2021-44228 fixes for users, who starting +the Tika Server-daemons within TYPO3 BE or using Tika app modes. +All users using dedicated Tika server or Apache Solr Tika cell connections do not benefit from the update +and should harden the Solr Servers and/or Tika Servers with official CVE-2021-44228 patches manually. + +Manual action required for Tika App or enabled Tika Server module + +Please note that the release does not automatically include security measures against CVE-2021-44228. Rather, it is +now possible to specify additional parameters that can be passed when the java binary is executed. +The parameters can be set using the extension configuration javaCommandOptions. +Example: + +.. code-block:: + + # LocalConfiguration.php + return [ + 'EXTENSIONS' => [ + 'tika' => [ + 'javaCommandOptions' => '-Dlog4j2.formatMsgNoLookups=true', + ], + ], + ]; + +========================================================== +Apache Solr for TYPO3 - Tika Addon version 6.0.1 released +========================================================== + +**Important**: +This version contains CVE-2021-44228 fixes for users, who starting +the Tika Server-daemons within TYPO3 BE or using Tika app modes. +All users using dedicated Tika server or Apache Solr Tika cell connections do not benefit from the update +and should harden the Solr Servers and/or Tika Servers with official CVE-2021-44228 patches manually. + ========================================================= Apache Solr for TYPO3 - Tika Addon version 6.0.0 released ========================================================= diff --git a/Documentation/Settings.yml b/Documentation/Settings.yml index f5e40de35..4fd37f9f6 100644 --- a/Documentation/Settings.yml +++ b/Documentation/Settings.yml @@ -6,8 +6,8 @@ conf.py: copyright: 2009-2021 project: Apache Tika for TYPO3 - version: 10.0.1 - release: 10.0.1 + version: 10.0.2 + release: 10.0.2 latex_documents: - - Index - tika.tex diff --git a/Documentation/conf.py b/Documentation/conf.py index cf3012713..bda40d328 100644 --- a/Documentation/conf.py +++ b/Documentation/conf.py @@ -64,7 +64,7 @@ # The short X.Y version. version = '10.0' # The full version, including alpha/beta/rc tags. -release = '10.0.1' +release = '10.0.2' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/ext_emconf.php b/ext_emconf.php index d501397fa..bc0365e0a 100644 --- a/ext_emconf.php +++ b/ext_emconf.php @@ -2,7 +2,7 @@ $EM_CONF[$_EXTKEY] = [ 'title' => 'Apache Tika for TYPO3', 'description' => 'Provides Tika services for TYPO3 to detect a document\'s language, extract meta data, and extract content from files. Can either use a stand alone Tika executable or Tika integrated in a Solr server with an activated extracting request handler.', - 'version' => '10.0.1', + 'version' => '10.0.2', 'state' => 'stable', 'category' => 'services', 'author' => 'Ingo Renner, Timo Hund, Markus Friedrich', From 910681daf3fb812cb7447d89ac85c6841a8495d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20K=C3=A4hm?= Date: Fri, 28 Jan 2022 15:19:40 +0100 Subject: [PATCH 08/20] [TASK] Prepare releases for TYPO3 11 LTS --- Documentation/Index.rst | 2 +- Documentation/Releases/11_0.rst | 27 +++++++++++++++++++++++++++ Documentation/Settings.yml | 4 ++-- Documentation/conf.py | 2 +- composer.json | 2 +- ext_emconf.php | 2 +- 6 files changed, 33 insertions(+), 6 deletions(-) create mode 100644 Documentation/Releases/11_0.rst diff --git a/Documentation/Index.rst b/Documentation/Index.rst index 5bb4c004d..96068427a 100644 --- a/Documentation/Index.rst +++ b/Documentation/Index.rst @@ -18,7 +18,7 @@ Apache Tika for TYPO3 tika :Version: - 10.0.2 + 11.0.0 :Language: en diff --git a/Documentation/Releases/11_0.rst b/Documentation/Releases/11_0.rst new file mode 100644 index 000000000..45c9157f7 --- /dev/null +++ b/Documentation/Releases/11_0.rst @@ -0,0 +1,27 @@ +========================================================== +Apache Solr for TYPO3 - Tika Addon version 11.0.0 released +========================================================== + +**Important**: +This version contains CVE-2021-44228 fixes for users, who starting +the Tika Server-daemons within TYPO3 BE or using Tika app modes. +All users using dedicated Tika server or Apache Solr Tika cell connections do not benefit from the update +and should harden the Solr Servers and/or Tika Servers with official CVE-2021-44228 patches manually. + +Manual action required for Tika App or enabled Tika Server module + +Please note that the release does not automatically include security measures against CVE-2021-44228. Rather, it is +now possible to specify additional parameters that can be passed when the java binary is executed. +The parameters can be set using the extension configuration javaCommandOptions. +Example: + +.. code-block:: + + # LocalConfiguration.php + return [ + 'EXTENSIONS' => [ + 'tika' => [ + 'javaCommandOptions' => '-Dlog4j2.formatMsgNoLookups=true', + ], + ], + ]; diff --git a/Documentation/Settings.yml b/Documentation/Settings.yml index 4fd37f9f6..10a5fd5c8 100644 --- a/Documentation/Settings.yml +++ b/Documentation/Settings.yml @@ -6,8 +6,8 @@ conf.py: copyright: 2009-2021 project: Apache Tika for TYPO3 - version: 10.0.2 - release: 10.0.2 + version: 11.0.0 + release: 11.0.0 latex_documents: - - Index - tika.tex diff --git a/Documentation/conf.py b/Documentation/conf.py index bda40d328..61ab3c24b 100644 --- a/Documentation/conf.py +++ b/Documentation/conf.py @@ -64,7 +64,7 @@ # The short X.Y version. version = '10.0' # The full version, including alpha/beta/rc tags. -release = '10.0.2' +release = '11.0.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/composer.json b/composer.json index 91ab513b4..2d265cd6e 100644 --- a/composer.json +++ b/composer.json @@ -63,7 +63,7 @@ }, "extra": { "branch-alias": { - "dev-master": "10.0.x-dev" + "dev-main": "11.0.x-dev" }, "typo3/cms": { "extension-key": "tika", diff --git a/ext_emconf.php b/ext_emconf.php index bc0365e0a..7454d8499 100644 --- a/ext_emconf.php +++ b/ext_emconf.php @@ -2,7 +2,7 @@ $EM_CONF[$_EXTKEY] = [ 'title' => 'Apache Tika for TYPO3', 'description' => 'Provides Tika services for TYPO3 to detect a document\'s language, extract meta data, and extract content from files. Can either use a stand alone Tika executable or Tika integrated in a Solr server with an activated extracting request handler.', - 'version' => '10.0.2', + 'version' => '11.0.0', 'state' => 'stable', 'category' => 'services', 'author' => 'Ingo Renner, Timo Hund, Markus Friedrich', From 24aa731108b2e9087d6015bfa691ac989f97f8b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20K=C3=A4hm?= Date: Fri, 27 Aug 2021 19:05:20 +0200 Subject: [PATCH 09/20] [TASK] Fix issues recognized by scrutinizer --- .github/workflows/ci.yml | 11 +++++++++- .scrutinizer.yml | 20 +++++++++++++++---- .../TikaControlPanelModuleController.php | 14 ++++++------- Classes/Service/Tika/ServerService.php | 4 ++-- composer.json | 4 +++- ext_tables.php | 6 ++---- 6 files changed, 40 insertions(+), 19 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8c2eca0ca..c7aebb41b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,7 +37,14 @@ jobs: name: TYPO3 ${{ matrix.TYPO3 }} on PHP ${{ matrix.PHP }} steps: - - name: Checkout current state + # Workaround for issue with actions/checkout@v2 wrong PR commit checkout: See https://github.com/actions/checkout/issues/299#issuecomment-677674415 + - name: Checkout current state of Pull Request + if: github.event_name == 'pull_request' + uses: actions/checkout@v2 + with: + ref: ${{ github.event.pull_request.head.sha }} + - name: Checkout current state of Branch + if: github.event_name == 'push' uses: actions/checkout@v2 - name: Cache Apache Tika Binaries @@ -111,6 +118,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v2 + with: + ref: ${{ github.event.pull_request.head.sha }} - name: Check tag run: | diff --git a/.scrutinizer.yml b/.scrutinizer.yml index 6ca5e57f9..f0a6bcf73 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -5,6 +5,8 @@ filter: - 'Resources/Public/JavaScript/*' paths: - 'Classes/*' + dependency_paths: + - ".Build/vendor" tools: php_cpd: @@ -41,10 +43,20 @@ checks: - typo3/cms-install avoid_superglobals: false - build: + environment: + # We want to test with the smallest supported by TYPO3 PHP version + php: 7.2 + dependencies: + override: + - composer install --dev --no-interaction --no-scripts nodes: analysis: - tests: - override: - - php-scrutinizer-run \ No newline at end of file + dependencies: + after: + - composer require --dev squizlabs/php_codesniffer:^3.6 +# tests: +# override: +# - php-scrutinizer-run +# - command: phpcs-run +# use_website_config: false diff --git a/Classes/Controller/Backend/SolrModule/TikaControlPanelModuleController.php b/Classes/Controller/Backend/SolrModule/TikaControlPanelModuleController.php index d436d59af..a710e9856 100644 --- a/Classes/Controller/Backend/SolrModule/TikaControlPanelModuleController.php +++ b/Classes/Controller/Backend/SolrModule/TikaControlPanelModuleController.php @@ -134,12 +134,12 @@ public function indexAction() */ public function startServerAction() { - $this->tikaService->startServer(); + $this->tikaService->/** @scrutinizer ignore-call */startServer(); // give it some time to start sleep(2); - if ($this->tikaService->isServerRunning()) { + if ($this->tikaService->/** @scrutinizer ignore-call */isServerRunning()) { $this->addFlashMessage( 'Tika server started.', FlashMessage::OK @@ -157,7 +157,7 @@ public function startServerAction() */ public function stopServerAction() { - $this->tikaService->stopServer(); + $this->tikaService->/** @scrutinizer ignore-call */stopServer(); // give it some time to stop sleep(2); @@ -202,7 +202,7 @@ protected function isTikaServerRunning() */ protected function getTikaServerPid() { - return $this->tikaService->getServerPid(); + return $this->tikaService->/** @scrutinizer ignore-call */getServerPid(); } /** @@ -263,15 +263,15 @@ protected function isTikaServerControllable(): bool */ protected function checkTikaServerConnection() { - if ($this->tikaService->ping()) { + if ($this->tikaService->/** @scrutinizer ignore-call */ping()) { $this->addFlashMessage( - 'Tika host contacted at: ' . $this->tikaService->getTikaServerUrl(), + 'Tika host contacted at: ' . $this->tikaService->/** @scrutinizer ignore-call */getTikaServerUrl(), 'Your Apache Tika server has been contacted.', FlashMessage::OK ); } else { $this->addFlashMessage( - 'Could not connect to Tika at: ' . $this->tikaService->getTikaServerUrl(), + 'Could not connect to Tika at: ' . $this->tikaService->/** @scrutinizer ignore-call */getTikaServerUrl(), 'Unable to contact Apache Tika server.', FlashMessage::ERROR ); diff --git a/Classes/Service/Tika/ServerService.php b/Classes/Service/Tika/ServerService.php index 43f76a699..839162d03 100644 --- a/Classes/Service/Tika/ServerService.php +++ b/Classes/Service/Tika/ServerService.php @@ -306,7 +306,7 @@ public function extractText(FileInterface $file): string $response = $this->queryTika($request); - if ($response === false) { + if (empty($response)) { $this->log( 'Text Extraction using Tika Server failed', $this->getLogData($file, $response), @@ -374,7 +374,7 @@ public function detectLanguageFromFile(FileInterface $file): string $response = $this->queryTika($request); - if ($response === false) { + if (empty($response)) { $this->log( 'Language Detection using Tika Server failed', $this->getLogData($file, $response), diff --git a/composer.json b/composer.json index 2d265cd6e..a6ac39d6f 100644 --- a/composer.json +++ b/composer.json @@ -34,7 +34,9 @@ }, "require-dev": { "phpunit/phpunit": "^7.5.6 || ^8", - "nimut/testing-framework": "^5.0.0" + "nimut/testing-framework": "^5.0.0", + "apache-solr-for-typo3/solr": "dev-release-11.1.x", + "psr/log": "*" }, "suggest": { "apache-solr-for-typo3/solr": "Allows to use Solr Cell - Apache Tika embedded in Apache Solr." diff --git a/ext_tables.php b/ext_tables.php index 28bb582a2..5450a5e32 100644 --- a/ext_tables.php +++ b/ext_tables.php @@ -22,8 +22,6 @@ ['source' => $extIconPath . 'module-tika.svg'] ); - - if (\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('solr')) { $tikaExtensionConfiguration = \ApacheSolrForTypo3\Tika\Util::getTikaExtensionConfiguration(); $isSolrModuleEnabled = (is_array($tikaExtensionConfiguration) @@ -37,7 +35,7 @@ 'TikaControlPanel', 'bottom', [ - 'Backend\\SolrModule\\TikaControlPanelModule' => 'index, startServer, stopServer' + \ApacheSolrForTypo3\Tika\Controller\Backend\SolrModule\TikaControlPanelModuleController::class => 'index, startServer, stopServer' ], [ 'access' => 'user,group', @@ -47,4 +45,4 @@ ); } -} \ No newline at end of file +} From 24208882fb707b17bdf9df7e50b96167f73ac2ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Tue, 14 Dec 2021 16:10:39 +0100 Subject: [PATCH 10/20] [FEATURE] Allow definition of additional Java command options This commit introduces the ability to provide additional command options. They are passed to the Java command when using the tika app. For safety reasons, only a small subset of command options can be configured: -Dfoo=bar -Dfoo='hello world' -Dfoo="hello world" --- Classes/Service/Tika/AppService.php | 35 +++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/Classes/Service/Tika/AppService.php b/Classes/Service/Tika/AppService.php index b22d55f72..0ef18b9ed 100644 --- a/Classes/Service/Tika/AppService.php +++ b/Classes/Service/Tika/AppService.php @@ -28,6 +28,8 @@ */ class AppService extends AbstractService { + protected const JAVA_COMMAND_OPTIONS_REGEX = '/-D(?P[\w.]+)=(?P"[^"]+"|\'[^\']+\'|[^\\s\'"]+)/'; + /** * @var array */ @@ -323,4 +325,37 @@ protected function getMimeTypeOutputFromTikaJar(): string return trim(shell_exec($tikaCommand)); } + + /** + * Parse additional Java command options. + * + * Reads the configuration value `javaCommandOptions` and tries to parse it to a + * safe argument string. For safety reasons, only the following variants are + * allowed (multiple separated by space): + * + * -Dfoo=bar + * -Dfoo='hello world' + * -Dfoo="hello world" + * + * @return string Parsed additional Java command options + */ + protected function getAdditionalCommandOptions(): string + { + $commandOptions = trim((string)($this->configuration['javaCommandOptions'] ?? '')); + + // Early return if no additional command options are configured + // or configuration does not match required pattern (only -D parameter is supported) + if ('' === $commandOptions || !preg_match_all(self::JAVA_COMMAND_OPTIONS_REGEX, $commandOptions, $matches)) { + return ''; + } + + // Combine matched command options with escaped argument value + $commandOptionsString = ''; + foreach (array_combine($matches['property'], $matches['value']) as $property => $unescapedValue) { + $escapedValue = CommandUtility::escapeShellArgument(trim($unescapedValue, '"\'')); + $commandOptionsString .= sprintf(' -D%s=%s', $property, $escapedValue); + } + + return $commandOptionsString; + } } From 1ec312e196150e7db18cdab1012916fdd3a3cd17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Fri, 17 Dec 2021 15:58:54 +0100 Subject: [PATCH 11/20] [BUGFIX] Handle custom java command options for server module as well Related: #172 --- Classes/Service/Tika/AppService.php | 35 ----------------------------- 1 file changed, 35 deletions(-) diff --git a/Classes/Service/Tika/AppService.php b/Classes/Service/Tika/AppService.php index 0ef18b9ed..b22d55f72 100644 --- a/Classes/Service/Tika/AppService.php +++ b/Classes/Service/Tika/AppService.php @@ -28,8 +28,6 @@ */ class AppService extends AbstractService { - protected const JAVA_COMMAND_OPTIONS_REGEX = '/-D(?P[\w.]+)=(?P"[^"]+"|\'[^\']+\'|[^\\s\'"]+)/'; - /** * @var array */ @@ -325,37 +323,4 @@ protected function getMimeTypeOutputFromTikaJar(): string return trim(shell_exec($tikaCommand)); } - - /** - * Parse additional Java command options. - * - * Reads the configuration value `javaCommandOptions` and tries to parse it to a - * safe argument string. For safety reasons, only the following variants are - * allowed (multiple separated by space): - * - * -Dfoo=bar - * -Dfoo='hello world' - * -Dfoo="hello world" - * - * @return string Parsed additional Java command options - */ - protected function getAdditionalCommandOptions(): string - { - $commandOptions = trim((string)($this->configuration['javaCommandOptions'] ?? '')); - - // Early return if no additional command options are configured - // or configuration does not match required pattern (only -D parameter is supported) - if ('' === $commandOptions || !preg_match_all(self::JAVA_COMMAND_OPTIONS_REGEX, $commandOptions, $matches)) { - return ''; - } - - // Combine matched command options with escaped argument value - $commandOptionsString = ''; - foreach (array_combine($matches['property'], $matches['value']) as $property => $unescapedValue) { - $escapedValue = CommandUtility::escapeShellArgument(trim($unescapedValue, '"\'')); - $commandOptionsString .= sprintf(' -D%s=%s', $property, $escapedValue); - } - - return $commandOptionsString; - } } From 38ca19baa81d708db490fed789c5ea0e6e9d87a3 Mon Sep 17 00:00:00 2001 From: Georg Ringer Date: Wed, 26 Jan 2022 15:39:57 +0100 Subject: [PATCH 12/20] [TASK] Let php-cs-fixer fix some CGL --- Build/Release/pre_upload_check.php | 7 +- Classes/ContextMenu/Preview.php | 10 +- .../Controller/Backend/PreviewController.php | 10 +- .../TikaControlPanelModuleController.php | 45 +++--- Classes/Hooks/BackendControllerHook.php | 7 +- Classes/Process.php | 23 ++- Classes/Report/TikaStatus.php | 34 +++-- .../Service/Extractor/AbstractExtractor.php | 14 +- .../Service/Extractor/LanguageDetector.php | 13 +- .../Service/Extractor/MetaDataExtractor.php | 21 +-- Classes/Service/Extractor/TextExtractor.php | 7 +- Classes/Service/File/SizeValidator.php | 12 +- Classes/Service/Tika/AbstractService.php | 15 +- Classes/Service/Tika/AppService.php | 27 ++-- Classes/Service/Tika/ServerService.php | 14 +- Classes/Service/Tika/ServiceFactory.php | 2 + Classes/Service/Tika/ServiceInterface.php | 8 +- Classes/Service/Tika/SolrCellService.php | 38 +++-- .../Tika/UnsupportedOperationException.php | 5 +- Classes/Util.php | 8 +- Classes/Utility/FileUtility.php | 10 +- Classes/Utility/ShellUtility.php | 8 +- Configuration/Backend/Routes.php | 4 +- .../Service/Tika/AppServiceTest.php | 51 ++++--- .../Tika/Fixtures/ServerServiceFixture.php | 2 + .../Service/Tika/ServerServiceTest.php | 132 +++++++++--------- .../Service/Tika/ServiceFactoryTest.php | 39 +++--- .../Tika/ServiceIntegrationTestCase.php | 70 +++++----- .../Service/Tika/SolrCellServiceTest.php | 49 +++---- Tests/Unit/Backend/PreviewControllerTest.php | 36 ++--- .../TikaControlPanelModuleControllerTest.php | 20 +-- Tests/Unit/ExecMockFunctions.php | 4 +- Tests/Unit/ExecRecorder.php | 10 +- Tests/Unit/ProcessTest.php | 50 ++++--- .../Extractor/MetaDataExtractorTest.php | 91 ++++++------ .../Unit/Service/Tika/AbstractServiceTest.php | 11 +- Tests/Unit/UnitTestCase.php | 7 +- ext_emconf.php | 8 +- ext_localconf.php | 4 +- ext_tables.php | 8 +- 40 files changed, 480 insertions(+), 454 deletions(-) diff --git a/Build/Release/pre_upload_check.php b/Build/Release/pre_upload_check.php index afa291ebd..bd204e6e3 100644 --- a/Build/Release/pre_upload_check.php +++ b/Build/Release/pre_upload_check.php @@ -1,6 +1,8 @@ 0) { echo 'Version was a valid release version: ' . $version . PHP_EOL; exit(0); -} else { +} echo 'Version was NOT a valid release version: ' . $version . PHP_EOL; exit(1); -} \ No newline at end of file diff --git a/Classes/ContextMenu/Preview.php b/Classes/ContextMenu/Preview.php index 427e7fee8..9220c7d63 100644 --- a/Classes/ContextMenu/Preview.php +++ b/Classes/ContextMenu/Preview.php @@ -1,4 +1,6 @@ [ 'type' => 'item', 'label' => 'Tika Preview', // you can use "LLL:" syntax here 'iconIdentifier' => 'actions-document-view', - 'callbackAction' => 'tikaPreview' - ] + 'callbackAction' => 'tikaPreview', + ], ]; /** @@ -39,7 +40,7 @@ public function canHandle(): bool $item = $resourceFactory->retrieveFileOrFolderObject($this->identifier); // we only handle files, no folders - return ($item instanceof File); + return $item instanceof File; } /** @@ -81,7 +82,6 @@ protected function getAdditionalAttributes(string $itemName): array */ public function addItems(array $items): array { - $this->initDisabledItems(); $localItems = $this->prepareItems($this->itemsConfiguration); $items = $items + $localItems; diff --git a/Classes/Controller/Backend/PreviewController.php b/Classes/Controller/Backend/PreviewController.php index 6800878ba..f5d7c553a 100644 --- a/Classes/Controller/Backend/PreviewController.php +++ b/Classes/Controller/Backend/PreviewController.php @@ -1,4 +1,6 @@ isAdmin(); } -} \ No newline at end of file +} diff --git a/Classes/Controller/Backend/SolrModule/TikaControlPanelModuleController.php b/Classes/Controller/Backend/SolrModule/TikaControlPanelModuleController.php index a710e9856..252f2b564 100644 --- a/Classes/Controller/Backend/SolrModule/TikaControlPanelModuleController.php +++ b/Classes/Controller/Backend/SolrModule/TikaControlPanelModuleController.php @@ -1,4 +1,6 @@ */ class TikaControlPanelModuleController extends AbstractModuleController @@ -56,14 +57,14 @@ class TikaControlPanelModuleController extends AbstractModuleController /** * @var AppService|ServerService|SolrCellService */ - protected $tikaService = null; + protected $tikaService; /** * Can be used in the test context to force a view. * * @param ViewInterface $view */ - public function overwriteView(ViewInterface $view) + public function overwriteView(ViewInterface $view): void { $this->view = $view; } @@ -71,17 +72,15 @@ public function overwriteView(ViewInterface $view) /** * @param AbstractService $tikaService */ - public function setTikaService(AbstractService $tikaService) + public function setTikaService(AbstractService $tikaService): void { $this->tikaService = $tikaService; } /** * Initializes resources commonly needed for several actions. - * - * @return void */ - protected function initializeAction() + protected function initializeAction(): void { parent::initializeAction(); @@ -93,7 +92,7 @@ protected function initializeAction() /** * @param array $tikaConfiguration */ - public function setTikaConfiguration(array $tikaConfiguration) + public function setTikaConfiguration(array $tikaConfiguration): void { $this->tikaConfiguration = $tikaConfiguration; } @@ -101,14 +100,15 @@ public function setTikaConfiguration(array $tikaConfiguration) /** * Index action * - * @return void * @throws Exception */ - public function indexAction() + public function indexAction(): void { $this->view->assign('configuration', $this->tikaConfiguration); - $this->view->assign('extractor', - ucfirst($this->tikaConfiguration['extractor'])); + $this->view->assign( + 'extractor', + ucfirst($this->tikaConfiguration['extractor']) + ); if ($this->tikaConfiguration['extractor'] == 'server') { $this->checkTikaServerConnection(); @@ -120,7 +120,7 @@ public function indexAction() 'isRunning' => $this->isTikaServerRunning(), 'isControllable' => $this->isTikaServerControllable(), 'pid' => $this->getTikaServerPid(), - 'version' => $this->getTikaServerVersion() + 'version' => $this->getTikaServerVersion(), ] ); } @@ -129,10 +129,9 @@ public function indexAction() /** * Starts the Tika server * - * @return void * @throws StopActionException */ - public function startServerAction() + public function startServerAction(): void { $this->tikaService->/** @scrutinizer ignore-call */startServer(); @@ -152,10 +151,9 @@ public function startServerAction() /** * Stops the Tika server * - * @return void * @throws StopActionException */ - public function stopServerAction() + public function stopServerAction(): void { $this->tikaService->/** @scrutinizer ignore-call */stopServer(); @@ -198,7 +196,7 @@ protected function isTikaServerRunning() * Returns the pid if the Tika server has been started through the backend * module. * - * @return integer|null Tika Server pid or null if not found + * @return int|null Tika Server pid or null if not found */ protected function getTikaServerPid() { @@ -215,7 +213,7 @@ protected function isTikaServerJarAvailable() $serverJarSet = !empty($this->tikaConfiguration['tikaServerPath']); $serverJarExists = file_exists($this->tikaConfiguration['tikaServerPath']); - return ($serverJarSet && $serverJarExists); + return $serverJarSet && $serverJarExists; } /** @@ -230,8 +228,10 @@ protected function isTikaServerControllable(): bool { $disabledFunctions = ini_get('disable_functions') . ',' . ini_get('suhosin.executor.func.blacklist'); - $disabledFunctions = GeneralUtility::trimExplode(',', - $disabledFunctions); + $disabledFunctions = GeneralUtility::trimExplode( + ',', + $disabledFunctions + ); if (in_array('exec', $disabledFunctions)) { return false; } @@ -258,10 +258,9 @@ protected function isTikaServerControllable(): bool * Checks whether the configured Tika server can be reached and provides a * flash message according to the result of the check. * - * @return void * @throws Exception */ - protected function checkTikaServerConnection() + protected function checkTikaServerConnection(): void { if ($this->tikaService->/** @scrutinizer ignore-call */ping()) { $this->addFlashMessage( diff --git a/Classes/Hooks/BackendControllerHook.php b/Classes/Hooks/BackendControllerHook.php index 0227b4a03..5da24704e 100644 --- a/Classes/Hooks/BackendControllerHook.php +++ b/Classes/Hooks/BackendControllerHook.php @@ -1,4 +1,6 @@ getPageRenderer()->addInlineSetting( 'TikaPreview', 'moduleUrl', - (string)$this->getBackendUriBuilder()->buildUriFromRoute('tika_preview')); + (string)$this->getBackendUriBuilder()->buildUriFromRoute('tika_preview') + ); } /** diff --git a/Classes/Process.php b/Classes/Process.php index 2460748d9..e2dda897c 100644 --- a/Classes/Process.php +++ b/Classes/Process.php @@ -1,4 +1,6 @@ arguments = $arguments; } @@ -110,10 +108,9 @@ public function getPid() /** * Sets the process ID * - * @param integer $pid - * @return void + * @param int $pid */ - public function setPid($pid) + public function setPid($pid): void { $this->pid = (int)$pid; } @@ -135,7 +132,7 @@ public function findPid() exec($ps, $output); foreach ($output as $line) { - list($pid, $command) = explode(' ', trim($line), 2); + [$pid, $command] = explode(' ', trim($line), 2); $command = $this->escapePsOutputCommand($command); if ($command == $processCommand) { return (int)$pid; @@ -183,10 +180,8 @@ public function start() /** * Executes the command - * - * @return void */ - protected function runCommand() + protected function runCommand(): void { $command = 'nohup ' . $this->executable; if (!empty($this->arguments)) { diff --git a/Classes/Report/TikaStatus.php b/Classes/Report/TikaStatus.php index 15aa3ce2d..98b52919e 100644 --- a/Classes/Report/TikaStatus.php +++ b/Classes/Report/TikaStatus.php @@ -1,4 +1,6 @@ isJavaInstalled()) { - $status = GeneralUtility::makeInstance(Status::class, + $status = GeneralUtility::makeInstance( + Status::class, 'Apache Tika', 'Java Not Found', '

Please install Java.

', @@ -136,7 +141,8 @@ protected function getAppConfigurationStatus() { $status = $this->getOkStatus(); if (!$this->isFilePresent($this->tikaConfiguration['tikaPath'])) { - $status = GeneralUtility::makeInstance(Status::class, + $status = GeneralUtility::makeInstance( + Status::class, 'Apache Tika', 'Configuration Incomplete', '

Could not find Tika app jar.

', @@ -159,7 +165,8 @@ protected function getServerConfigurationStatus() $tikaServer = $this->getTikaServiceFromTikaConfiguration(); if (!$tikaServer->isAvailable()) { - $status = GeneralUtility::makeInstance(Status::class, + $status = GeneralUtility::makeInstance( + Status::class, 'Apache Tika', 'Configuration Incomplete', '

Could not connect to Tika server.

', @@ -190,7 +197,7 @@ protected function getSolrCellConfigurationStatus() $query->setFile(ExtensionManagementUtility::extPath('tika', 'ext_emconf.php')); $query->addParam('extractFormat', 'text'); - list($extractedContent, $extractedMetadata) = $solr->getWriteService()->extractByQuery($query); + [$extractedContent, $extractedMetadata] = $solr->getWriteService()->extractByQuery($query); if (!is_null($extractedContent) && !empty($extractedMetadata)) { $solrCellConfigurationOk = true; @@ -207,7 +214,8 @@ protected function getSolrCellConfigurationStatus() } if (!$solrCellConfigurationOk) { - $status = GeneralUtility::makeInstance(Status::class, + $status = GeneralUtility::makeInstance( + Status::class, 'Apache Tika', 'Configuration Incomplete', '

Could not extract file contents with Solr Cell.

', @@ -227,12 +235,12 @@ protected function getSolrConnectionFromTikaConfiguration() 'host' => $this->tikaConfiguration['solrHost'], 'port' => $this->tikaConfiguration['solrPort'], 'path' => $this->tikaConfiguration['solrPath'], - 'scheme' => $this->tikaConfiguration['solrScheme'] + 'scheme' => $this->tikaConfiguration['solrScheme'], ]; $config = [ 'read' => $solrConfig, - 'write' => $solrConfig + 'write' => $solrConfig, ]; return GeneralUtility::makeInstance(ConnectionManager::class)->getConnectionFromConfiguration($config); } @@ -277,13 +285,13 @@ protected function isFilePresent($fileName) * @param string $extKey extension key * @param array $data data */ - protected function writeDevLog(string $message, string $extKey, array $data = []) + protected function writeDevLog(string $message, string $extKey, array $data = []): void { $this->logger->debug( $message, [ 'extension' => $extKey, - 'data' => $data + 'data' => $data, ] ); } diff --git a/Classes/Service/Extractor/AbstractExtractor.php b/Classes/Service/Extractor/AbstractExtractor.php index 8cf125797..8796382e2 100644 --- a/Classes/Service/Extractor/AbstractExtractor.php +++ b/Classes/Service/Extractor/AbstractExtractor.php @@ -1,4 +1,6 @@ */ abstract class AbstractExtractor implements ExtractorInterface, LoggerAwareInterface @@ -41,7 +41,7 @@ abstract class AbstractExtractor implements ExtractorInterface, LoggerAwareInter /** * Priority in handling extraction * - * @var integer + * @var int */ protected $priority = 0; @@ -87,7 +87,7 @@ public function getDriverRestrictions() /** * Returns the data priority of the extraction Service. * - * @return integer + * @return int */ public function getPriority() { @@ -97,7 +97,7 @@ public function getPriority() /** * Returns the execution priority of the extraction Service * - * @return integer + * @return int */ public function getExecutionPriority() { @@ -109,9 +109,8 @@ public function getExecutionPriority() * * @param string $message Log message * @param array $data Optional data - * @return void */ - protected function log(string $message, array $data = []) + protected function log(string $message, array $data = []): void { if (!$this->configuration['logging']) { return; @@ -122,5 +121,4 @@ protected function log(string $message, array $data = []) $data ); } - } diff --git a/Classes/Service/Extractor/LanguageDetector.php b/Classes/Service/Extractor/LanguageDetector.php index 4500efa0b..f8d248915 100644 --- a/Classes/Service/Extractor/LanguageDetector.php +++ b/Classes/Service/Extractor/LanguageDetector.php @@ -1,4 +1,6 @@ - * @package ApacheSolrForTypo3\Tika\Service\Extractor */ class LanguageDetector extends AbstractExtractor { - protected $supportedFileTypes = [ 'doc', 'docx', @@ -54,20 +53,19 @@ class LanguageDetector extends AbstractExtractor 'sxw', 'txt', 'xls', - 'xlsx' + 'xlsx', ]; /** - * @var integer + * @var int */ protected $priority = 98; - /** * Checks if the given file can be processed by this Extractor * * @param File $file - * @return boolean + * @return bool */ public function canProcess(File $file) { @@ -96,5 +94,4 @@ public function extractMetaData( return $metaData; } - } diff --git a/Classes/Service/Extractor/MetaDataExtractor.php b/Classes/Service/Extractor/MetaDataExtractor.php index 556252866..08f276380 100644 --- a/Classes/Service/Extractor/MetaDataExtractor.php +++ b/Classes/Service/Extractor/MetaDataExtractor.php @@ -1,4 +1,6 @@ configuration['extractor']); } @@ -97,7 +99,8 @@ protected function getExtractor() { * @return array * @throws Exception */ - public function extractMetaData(File $file, array $previousExtractedData = []) { + public function extractMetaData(File $file, array $previousExtractedData = []) + { $extractedMetaData = $this->getExtractedMetaDataFromTikaService($file); return $this->normalizeMetaData($extractedMetaData); } @@ -153,14 +156,14 @@ protected function normalizeMetaData(array $metaData) $metaDataCleaned['height'] = $value; break; case 'Exif Image Height': - list($height) = explode(' ', $value, 2); + [$height] = explode(' ', $value, 2); $metaDataCleaned['height'] = $height; break; case 'width': $metaDataCleaned['width'] = $value; break; case 'Exif Image Width': - list($width) = explode(' ', $value, 2); + [$width] = explode(' ', $value, 2); $metaDataCleaned['width'] = $width; break; case 'Color space': @@ -220,7 +223,7 @@ protected function normalizeMetaData(array $metaData) * exiftags: 2002:09:07 15:29:52 * * @param string $date An exif date string - * @return integer Unix timestamp + * @return int Unix timestamp */ protected function exifDateToTimestamp($date) { diff --git a/Classes/Service/Extractor/TextExtractor.php b/Classes/Service/Extractor/TextExtractor.php index ddc8bdb1e..6dd77656f 100644 --- a/Classes/Service/Extractor/TextExtractor.php +++ b/Classes/Service/Extractor/TextExtractor.php @@ -1,4 +1,6 @@ - * @package ApacheSolrForTypo3\Tika\Service\Extractor */ class TextExtractor implements TextExtractorInterface { @@ -70,7 +70,7 @@ class TextExtractor implements TextExtractorInterface 'txt', 'xls', 'xlsx', - 'zip' + 'zip', ]; /** @@ -78,7 +78,6 @@ class TextExtractor implements TextExtractorInterface */ private $fileSizeValidator; - /** * Constructor */ diff --git a/Classes/Service/File/SizeValidator.php b/Classes/Service/File/SizeValidator.php index b53ce482e..6fb424d24 100644 --- a/Classes/Service/File/SizeValidator.php +++ b/Classes/Service/File/SizeValidator.php @@ -1,5 +1,7 @@ getSize() < $this->getFileSizeLimit(); } @@ -77,6 +81,6 @@ protected function getFileSizeLimit() */ protected function getConfigurationOrDefaultValue($key, $defaultValue) { - return isset($this->configuration[$key]) ? $this->configuration[$key] : $defaultValue; + return $this->configuration[$key] ?? $defaultValue; } -} \ No newline at end of file +} diff --git a/Classes/Service/Tika/AbstractService.php b/Classes/Service/Tika/AbstractService.php index 0550a048c..f09f4f167 100644 --- a/Classes/Service/Tika/AbstractService.php +++ b/Classes/Service/Tika/AbstractService.php @@ -1,4 +1,6 @@ */ abstract class AbstractService implements ServiceInterface, LoggerAwareInterface @@ -49,10 +50,8 @@ public function __construct(array $configuration) /** * Service initialization - * - * @return void */ - protected function initializeService() + protected function initializeService(): void { } @@ -61,11 +60,10 @@ protected function initializeService() * * @param string $message Log message * @param array $data Optional data - * @param integer|string $severity Use constants from class LogLevel - * @return void + * @param int|string $severity Use constants from class LogLevel * @see LogLevel For supported log levels */ - protected function log(string $message, array $data = [], $severity = LogLevel::DEBUG) + protected function log(string $message, array $data = [], $severity = LogLevel::DEBUG): void { if (!$this->configuration['logging']) { return; @@ -80,7 +78,8 @@ protected function log(string $message, array $data = [], $severity = LogLevel:: /** * @return mixed */ - public function getSupportedMimeTypes() { + public function getSupportedMimeTypes() + { return []; } diff --git a/Classes/Service/Tika/AppService.php b/Classes/Service/Tika/AppService.php index b22d55f72..0c000d755 100644 --- a/Classes/Service/Tika/AppService.php +++ b/Classes/Service/Tika/AppService.php @@ -1,4 +1,6 @@ configuration['tikaPath'])) ) { @@ -93,7 +93,7 @@ public function extractText(FileInterface $file) [ 'file' => $file, 'tika command' => $tikaCommand, - 'shell output' => $extractedText + 'shell output' => $extractedText, ] ); @@ -127,7 +127,7 @@ public function extractMetaData(FileInterface $file) 'file' => $file, 'tika command' => $tikaCommand, 'shell output' => $shellOutput, - 'meta data' => $metaData + 'meta data' => $metaData, ] ); @@ -190,7 +190,7 @@ protected function detectLanguageFromLocalFile($localFilePath) [ 'file' => $localFilePath, 'tika command' => $tikaCommand, - 'shell output' => $language + 'shell output' => $language, ] ); @@ -202,7 +202,7 @@ protected function detectLanguageFromLocalFile($localFilePath) */ public function getSupportedMimeTypes() { - if(is_array(self::$supportedMimeTypes) && count(self::$supportedMimeTypes) > 0) { + if (is_array(self::$supportedMimeTypes) && count(self::$supportedMimeTypes) > 0) { return self::$supportedMimeTypes; } @@ -224,8 +224,8 @@ public function buildSupportedMimeTypes() preg_match_all('/^[\s]*alias:[\s]*.*/im', $mimeTypeOutput, $aliasTypes); $supportedTypes = $coreTypes[0]; - foreach($aliasTypes[0] as $aliasType) { - $supportedTypes[] = trim(str_replace('alias:','', $aliasType)); + foreach ($aliasTypes[0] as $aliasType) { + $supportedTypes[] = trim(str_replace('alias:', '', $aliasType)); } $supportedTypes = array_filter($supportedTypes); @@ -233,7 +233,6 @@ public function buildSupportedMimeTypes() return $supportedTypes; } - /** * Takes shell output from exec() and turns it into an array of key => value * pairs. @@ -246,7 +245,7 @@ protected function shellOutputToArray(array $shellOutput) $metaData = []; foreach ($shellOutput as $line) { - list($key, $value) = explode(':', $line, 2); + [$key, $value] = explode(':', $line, 2); $value = trim($value); if (in_array($key, [ @@ -256,11 +255,11 @@ protected function shellOutputToArray(array $shellOutput) 'tiff', 'xmp', 'xmpTPg', - 'xmpDM' + 'xmpDM', ])) { // Dublin Core metadata and co $keyPrefix = $key; - list($key, $value) = explode(':', $value, 2); + [$key, $value] = explode(':', $value, 2); $key = $keyPrefix . ':' . $key; $value = trim($value); @@ -292,7 +291,7 @@ protected function shellOutputToArray(array $shellOutput) /** * The app is available when the jar can be opened * - * @return boolean + * @return bool */ public function isAvailable() { diff --git a/Classes/Service/Tika/ServerService.php b/Classes/Service/Tika/ServerService.php index 839162d03..595b6571e 100644 --- a/Classes/Service/Tika/ServerService.php +++ b/Classes/Service/Tika/ServerService.php @@ -1,4 +1,6 @@ getProcess($this->getStartCommand()); $process->start(); @@ -133,10 +133,8 @@ public function startServer() /** * Stops the Tika server - * - * @return void */ - public function stopServer() + public function stopServer(): void { $pid = $this->getServerPid(); @@ -560,7 +558,7 @@ protected function getLogData(FileInterface $file, string $response): array 'file' => $file->getName(), 'file_path' => $file->getPublicUrl(), 'tika_url' => $this->getTikaServerUrl(), - 'response' => $response + 'response' => $response, ]; } } diff --git a/Classes/Service/Tika/ServiceFactory.php b/Classes/Service/Tika/ServiceFactory.php index 21a1af469..b6413757d 100644 --- a/Classes/Service/Tika/ServiceFactory.php +++ b/Classes/Service/Tika/ServiceFactory.php @@ -1,4 +1,6 @@ $this->configuration['solrHost'], 'port' => $this->configuration['solrPort'], 'path' => $this->configuration['solrPath'], - 'scheme' => $this->configuration['solrScheme'] + 'scheme' => $this->configuration['solrScheme'], ]; $writeNode = $readNode; $this->solrConnection = $connectionManager->getSolrConnectionForNodes($readNode, $writeNode); @@ -76,7 +74,7 @@ protected function initializeService() */ protected function getConfigurationOrDefaultValue($key, $defaultValue) { - return isset($this->configuration[$key]) ? $this->configuration[$key] : $defaultValue; + return $this->configuration[$key] ?? $defaultValue; } /** @@ -88,7 +86,7 @@ protected function getConfigurationOrDefaultValue($key, $defaultValue) public function extractText(FileInterface $file) { $localTempFilePath = $file->getForLocalProcessing(false); - /** @var Query $query */ + /** @var Query $query */ $query = GeneralUtility::makeInstance(Query::class); $query->setFile($localTempFilePath); $query->setExtractOnly(true); @@ -101,7 +99,7 @@ public function extractText(FileInterface $file) 'file' => $file, 'solr connection' => (array)$writer, 'query' => (array)$query, - 'response' => $response + 'response' => $response, ]); return $response[0]; @@ -124,7 +122,7 @@ public function extractMetaData(FileInterface $file) $writer = $this->solrConnection->getWriteService(); $response = $writer->extractByQuery($query); - + $metaData = []; if (isset($response[1]) && is_array($response[1])) { $metaData = $this->solrResponseToArray($response[1]); @@ -135,7 +133,7 @@ public function extractMetaData(FileInterface $file) 'solr connection' => (array)$writer, 'query' => (array)$query, 'response' => $response, - 'meta data' => $metaData + 'meta data' => $metaData, ]); return $metaData; @@ -183,7 +181,7 @@ protected function solrResponseToArray(array $metaDataResponse = []) $cleanedData = []; foreach ($metaDataResponse as $dataName => $dataArray) { - if(!($dataName % 2) == 0) { + if (!($dataName % 2) == 0) { continue; } $fieldName = $dataArray; @@ -216,7 +214,7 @@ public function getSupportedMimeTypes() { $mapping = [ 'application/epub+zip' => ['epub'], - 'application/gzip' => ['gz','tgz'], + 'application/gzip' => ['gz', 'tgz'], 'application/msword' => ['doc'], 'application/pdf' => ['pdf'], 'application/rtf' => ['rtf'], @@ -231,7 +229,7 @@ public function getSupportedMimeTypes() 'application/zip' => ['zip'], 'application/x-midi' => ['mid'], 'application/xml' => ['xml'], - 'audio/aiff' => ['aif','aiff'], + 'audio/aiff' => ['aif', 'aiff'], 'audio/basic' => ['au'], 'audio/midi' => ['mid'], 'audio/mpeg3' => ['mp3'], @@ -241,15 +239,15 @@ public function getSupportedMimeTypes() 'audio/x-wav' => ['wav'], 'image/bmp' => ['bmp'], 'image/gif' => ['gif'], - 'image/jpeg' => ['jpg','jpeg'], + 'image/jpeg' => ['jpg', 'jpeg'], 'image/png' => ['png'], 'image/svg+xml' => ['svg'], - 'image/tiff' => ['tif','tiff'], - 'text/html' => ['html','htm'], + 'image/tiff' => ['tif', 'tiff'], + 'text/html' => ['html', 'htm'], 'text/plain' => ['txt'], 'text/xml' => ['xml'], 'video/mpeg' => ['mp3'], - 'video/x-mpeg' => ['mp3'] + 'video/x-mpeg' => ['mp3'], ]; return array_keys($mapping); diff --git a/Classes/Service/Tika/UnsupportedOperationException.php b/Classes/Service/Tika/UnsupportedOperationException.php index 4bcc4f5e6..0896b7587 100644 --- a/Classes/Service/Tika/UnsupportedOperationException.php +++ b/Classes/Service/Tika/UnsupportedOperationException.php @@ -1,4 +1,6 @@ [ 'path' => '/tika/preview', - 'target' => \ApacheSolrForTypo3\Tika\Controller\Backend\PreviewController::class . '::previewAction' + 'target' => \ApacheSolrForTypo3\Tika\Controller\Backend\PreviewController::class . '::previewAction', ], ]; diff --git a/Tests/Integration/Service/Tika/AppServiceTest.php b/Tests/Integration/Service/Tika/AppServiceTest.php index 1f97bef0c..50ccfc001 100644 --- a/Tests/Integration/Service/Tika/AppServiceTest.php +++ b/Tests/Integration/Service/Tika/AppServiceTest.php @@ -1,4 +1,6 @@ getConfiguration()); $service->setLogger(new NullLogger()); $service->getTikaVersion(); - $this->assertContains('-V', ExecRecorder::$execCommand); + self::assertContains('-V', ExecRecorder::$execCommand); } /** * @test */ - public function extractTextUsesTParameter() + public function extractTextUsesTParameter(): void { $file = new File( [ 'identifier' => 'testWORD.doc', - 'name' => 'testWORD.doc' + 'name' => 'testWORD.doc', ], $this->documentsStorageMock ); @@ -63,19 +63,19 @@ public function extractTextUsesTParameter() $service->setLogger(new NullLogger()); $service->extractText($file); - $this->assertContains('-t', ExecRecorder::$execCommand); + self::assertContains('-t', ExecRecorder::$execCommand); } /** * @test */ - public function extractMetaDataUsesMParameter() + public function extractMetaDataUsesMParameter(): void { ExecRecorder::setReturnExecOutput(['foo']); $file = new File( [ 'identifier' => 'testWORD.doc', - 'name' => 'testWORD.doc' + 'name' => 'testWORD.doc', ], $this->documentsStorageMock ); @@ -84,18 +84,18 @@ public function extractMetaDataUsesMParameter() $service->setLogger(new NullLogger()); $service->extractMetaData($file); - $this->assertContains('-m', ExecRecorder::$execCommand); + self::assertContains('-m', ExecRecorder::$execCommand); } /** * @test */ - public function detectLanguageFromFileUsesLParameter() + public function detectLanguageFromFileUsesLParameter(): void { $file = new File( [ 'identifier' => 'testWORD.doc', - 'name' => 'testWORD.doc' + 'name' => 'testWORD.doc', ], $this->documentsStorageMock ); @@ -104,60 +104,59 @@ public function detectLanguageFromFileUsesLParameter() $service->setLogger(new NullLogger()); $service->detectLanguageFromFile($file); - $this->assertContains('-l', ExecRecorder::$execCommand); + self::assertContains('-l', ExecRecorder::$execCommand); } /** * @test */ - public function detectLanguageFromStringUsesLParameter() + public function detectLanguageFromStringUsesLParameter(): void { $service = new AppService($this->getConfiguration()); $service->setLogger(new NullLogger()); $service->detectLanguageFromString('foo'); - $this->assertContains('-l', ExecRecorder::$execCommand); + self::assertContains('-l', ExecRecorder::$execCommand); } /** * @test */ - public function callsTikaAppCorrectlyToGetMimeList() + public function callsTikaAppCorrectlyToGetMimeList(): void { $service = new AppService($this->getConfiguration()); $service->setLogger(new NullLogger()); $service->getSupportedMimeTypes(); - $this->assertContains('--list-supported-types', ExecRecorder::$execCommand); + self::assertContains('--list-supported-types', ExecRecorder::$execCommand); } /** * @test */ - public function canParseMimeList() + public function canParseMimeList(): void { - $fixtureContent = file_get_contents(dirname(__FILE__) . '/Fixtures/mimeOut'); + $fixtureContent = file_get_contents(__DIR__ . '/Fixtures/mimeOut'); /** @var $service AppService */ $service = $this->getMockBuilder(AppService::class) ->disableOriginalConstructor() ->setMethods(['getMimeTypeOutputFromTikaJar'])->getMock(); - $service->expects($this->once())->method('getMimeTypeOutputFromTikaJar')->will($this->returnValue($fixtureContent)); + $service->expects(self::once())->method('getMimeTypeOutputFromTikaJar')->willReturn($fixtureContent); $supportedMimeTypes = $service->getSupportedMimeTypes(); - $this->assertContains('application/gzip', $supportedMimeTypes, 'Mimetype from listing was not found'); - $this->assertContains('gzip/document', $supportedMimeTypes, 'Mimetype from alias was not found'); + self::assertContains('application/gzip', $supportedMimeTypes, 'Mimetype from listing was not found'); + self::assertContains('gzip/document', $supportedMimeTypes, 'Mimetype from alias was not found'); } /** * @test */ - public function includesAdditionalCommandOptions() + public function includesAdditionalCommandOptions(): void { $service = new AppService($this->getConfiguration()); $service->setLogger(new NullLogger()); $service->getTikaVersion(); - $this->assertContains('-Dlog4j2.formatMsgNoLookups=\'true\'', ExecRecorder::$execCommand); + self::assertContains('-Dlog4j2.formatMsgNoLookups=\'true\'', ExecRecorder::$execCommand); } } - diff --git a/Tests/Integration/Service/Tika/Fixtures/ServerServiceFixture.php b/Tests/Integration/Service/Tika/Fixtures/ServerServiceFixture.php index ac3e413a6..4db5839a2 100644 --- a/Tests/Integration/Service/Tika/Fixtures/ServerServiceFixture.php +++ b/Tests/Integration/Service/Tika/Fixtures/ServerServiceFixture.php @@ -1,4 +1,6 @@ startServer(); // test - $registryMock->set('tx_tika', 'server.pid', + $registryMock->set( + 'tx_tika', + 'server.pid', Argument::that(function ($arg) { - return (is_int($arg) && $arg == 1000); - }))->shouldHaveBeenCalled(); + return is_int($arg) && $arg == 1000; + }) + )->shouldHaveBeenCalled(); } /** * @test */ - public function stopServerRemovesPidFromRegistry() + public function stopServerRemovesPidFromRegistry(): void { // prepare $registryMock = $this->prophesize(Registry::class); @@ -91,7 +95,7 @@ public function stopServerRemovesPidFromRegistry() /** * @test */ - public function getServerPidGetsPidFromRegistry() + public function getServerPidGetsPidFromRegistry(): void { $registryMock = $this->prophesize(Registry::class); $registryMock->get('tx_tika', 'server.pid')->willReturn(1000); @@ -101,13 +105,13 @@ public function getServerPidGetsPidFromRegistry() $service->setLogger(new NullLogger()); $pid = $service->getServerPid(); - $this->assertEquals(1000, $pid); + self::assertEquals(1000, $pid); } /** * @test */ - public function getServerPidFallsBackToProcess() + public function getServerPidFallsBackToProcess(): void { $registryMock = $this->prophesize(Registry::class); $registryMock->get('tx_tika', 'server.pid')->willReturn(''); @@ -121,13 +125,13 @@ public function getServerPidFallsBackToProcess() $service->setLogger(new NullLogger()); $pid = $service->getServerPid(); - $this->assertEquals(1000, $pid); + self::assertEquals(1000, $pid); } /** * @test */ - public function isServerRunningReturnsTrueForRunningServerFromRegistry() + public function isServerRunningReturnsTrueForRunningServerFromRegistry(): void { $registryMock = $this->prophesize(Registry::class); $registryMock->get('tx_tika', 'server.pid')->willReturn(1000); @@ -135,13 +139,13 @@ public function isServerRunningReturnsTrueForRunningServerFromRegistry() $service = new ServerService($this->getConfiguration()); $service->setLogger(new NullLogger()); - $this->assertTrue($service->isServerRunning()); + self::assertTrue($service->isServerRunning()); } /** * @test */ - public function isServerRunningReturnsTrueForRunningServerFromProcess() + public function isServerRunningReturnsTrueForRunningServerFromProcess(): void { $registryMock = $this->prophesize(Registry::class); $registryMock->get('tx_tika', 'server.pid')->willReturn(''); @@ -153,13 +157,13 @@ public function isServerRunningReturnsTrueForRunningServerFromProcess() $service = new ServerService($this->getConfiguration()); $service->setLogger(new NullLogger()); - $this->assertTrue($service->isServerRunning()); + self::assertTrue($service->isServerRunning()); } /** * @test */ - public function isServerRunningReturnsFalseForStoppedServer() + public function isServerRunningReturnsFalseForStoppedServer(): void { $registryMock = $this->prophesize(Registry::class); $registryMock->get('tx_tika', 'server.pid')->willReturn(''); @@ -171,13 +175,13 @@ public function isServerRunningReturnsFalseForStoppedServer() $service = new ServerService($this->getConfiguration()); $service->setLogger(new NullLogger()); - $this->assertFalse($service->isServerRunning()); + self::assertFalse($service->isServerRunning()); } /** * @test */ - public function getTikaUrlBuildsUrlFromConfiguration() + public function getTikaUrlBuildsUrlFromConfiguration(): void { $tikaExtensionConfiguration = $this->getConfiguration(); $service = new ServerService($tikaExtensionConfiguration); @@ -191,56 +195,58 @@ public function getTikaUrlBuildsUrlFromConfiguration() $tikaExtensionConfiguration['tikaServerPort'], ] ); - $this->assertEquals($expectedTikaAuthority, $service->getTikaServerUrl()); + self::assertEquals($expectedTikaAuthority, $service->getTikaServerUrl()); } /** * @test */ - public function extractTextQueriesTikaEndpoint() + public function extractTextQueriesTikaEndpoint(): void { $service = new ServerServiceFixture($this->getConfiguration()); $service->setLogger(new NullLogger()); $service->extractText($this->getMockedFileInstanceForTestWordDotDocFile()); - $this->assertEquals('/tika', $service->getRecordedEndpoint()); + self::assertEquals('/tika', $service->getRecordedEndpoint()); } /** * @test */ - public function extractMetaDataQueriesMetaEndpoint() + public function extractMetaDataQueriesMetaEndpoint(): void { $service = new ServerServiceFixture($this->getConfiguration()); $service->setLogger(new NullLogger()); $service->extractMetaData($this->getMockedFileInstanceForTestWordDotDocFile()); - $this->assertEquals('/meta', $service->getRecordedEndpoint()); + self::assertEquals('/meta', $service->getRecordedEndpoint()); } /** * @test */ - public function detectLanguageFromFileQueriesLanguageStreamEndpoint() + public function detectLanguageFromFileQueriesLanguageStreamEndpoint(): void { $service = new ServerServiceFixture($this->getConfiguration()); $service->setLogger(new NullLogger()); $service->detectLanguageFromFile($this->getMockedFileInstanceForTestWordDotDocFile()); - $this->assertEquals('/language/stream', - $service->getRecordedEndpoint()); + self::assertEquals( + '/language/stream', + $service->getRecordedEndpoint() + ); } /** * @test */ - public function detectLanguageFromStringQueriesLanguageStringEndpoint() + public function detectLanguageFromStringQueriesLanguageStringEndpoint(): void { $service = new ServerServiceFixture($this->getConfiguration()); $service->setLogger(new NullLogger()); $service->detectLanguageFromString('foo'); - $this->assertEquals( + self::assertEquals( '/language/string', $service->getRecordedEndpoint() ); @@ -258,57 +264,57 @@ protected function getTikaServerConfiguration() return [ 'tikaServerScheme' => getenv($envVarNamePrefix . 'SERVER_SCHEME') ?: 'http', 'tikaServerHost' => getenv($envVarNamePrefix . 'SERVER_HOST') ?: 'localhost', - 'tikaServerPort' => getenv($envVarNamePrefix . 'SERVER_PORT') ?: '9998' + 'tikaServerPort' => getenv($envVarNamePrefix . 'SERVER_PORT') ?: '9998', ]; } /** * @test */ - public function extractsMetaDataFromDocFile() + public function extractsMetaDataFromDocFile(): void { $service = new ServerService($this->getTikaServerConfiguration()); $service->setLogger(new NullLogger()); $metaData = $service->extractMetaData($this->getMockedFileInstanceForTestWordDotDocFile()); - $this->assertEquals('application/msword', $metaData['Content-Type']); - $this->assertEquals('Microsoft Office Word', $metaData['Application-Name']); - $this->assertEquals('Keith Bennett', $metaData['Author']); - $this->assertEquals('', $metaData['Company']); - $this->assertEquals('2010-11-12T16:22:00Z', $metaData['Creation-Date']); - $this->assertEquals('Nick Burch', $metaData['Last-Author']); - $this->assertEquals('2010-11-12T16:22:00Z', $metaData['Last-Save-Date']); - $this->assertEquals('2', $metaData['Page-Count']); - $this->assertEquals('2', $metaData['Revision-Number']); - $this->assertEquals('Normal.dotm', $metaData['Template']); - $this->assertEquals('Sample Word Document', $metaData['title']); + self::assertEquals('application/msword', $metaData['Content-Type']); + self::assertEquals('Microsoft Office Word', $metaData['Application-Name']); + self::assertEquals('Keith Bennett', $metaData['Author']); + self::assertEquals('', $metaData['Company']); + self::assertEquals('2010-11-12T16:22:00Z', $metaData['Creation-Date']); + self::assertEquals('Nick Burch', $metaData['Last-Author']); + self::assertEquals('2010-11-12T16:22:00Z', $metaData['Last-Save-Date']); + self::assertEquals('2', $metaData['Page-Count']); + self::assertEquals('2', $metaData['Revision-Number']); + self::assertEquals('Normal.dotm', $metaData['Template']); + self::assertEquals('Sample Word Document', $metaData['title']); } /** * @test */ - public function extractsMetaDataFromMp3File() + public function extractsMetaDataFromMp3File(): void { $service = new ServerService($this->getTikaServerConfiguration()); $service->setLogger(new NullLogger()); $fileMock = $this->getMockedFileInstance( [ 'identifier' => 'testMP3.mp3', - 'name' => 'testMP3.mp3' + 'name' => 'testMP3.mp3', ] ); $metaData = $service->extractMetaData($fileMock); - $this->assertEquals('audio/mpeg', $metaData['Content-Type']); - $this->assertEquals('Test Title', $metaData['title']); + self::assertEquals('audio/mpeg', $metaData['Content-Type']); + self::assertEquals('Test Title', $metaData['title']); } /** * @test */ - public function extractsTextFromDocFile() + public function extractsTextFromDocFile(): void { $service = new ServerService($this->getTikaServerConfiguration()); $service->setLogger(new NullLogger()); @@ -316,13 +322,13 @@ public function extractsTextFromDocFile() $expectedText = 'Sample Word Document'; $extractedText = $service->extractText($this->getMockedFileInstanceForTestWordDotDocFile()); - $this->assertContains($expectedText, $extractedText); + self::assertContains($expectedText, $extractedText); } /** * @test */ - public function extractsTextFromZipFile() + public function extractsTextFromZipFile(): void { $service = new ServerService($this->getTikaServerConfiguration()); $service->setLogger(new NullLogger()); @@ -331,13 +337,13 @@ public function extractsTextFromZipFile() $extractedText = $service->extractText($this->getMockedFileInstance( [ 'identifier' => 'test-documents.zip', - 'name' => 'test-documents.zip' + 'name' => 'test-documents.zip', ] )); $expectedTextFromPDF= 'Tika - Content Analysis Toolkit'; - $this->assertContains($expectedTextFromWord, $extractedText); - $this->assertContains($expectedTextFromPDF, $extractedText); + self::assertContains($expectedTextFromWord, $extractedText); + self::assertContains($expectedTextFromPDF, $extractedText); } /** @@ -360,7 +366,7 @@ public function languageFileDataProvider() 'lithuanian' => ['lt'], 'dutch' => ['nl'], 'portuguese' => ['pt'], - 'swedish' => ['sv'] + 'swedish' => ['sv'], ]; } @@ -368,7 +374,7 @@ public function languageFileDataProvider() * @test * @dataProvider languageFileDataProvider */ - public function detectsLanguageFromFile($language) + public function detectsLanguageFromFile($language): void { $service = new ServerService($this->getTikaServerConfiguration()); $service->setLogger(new NullLogger()); @@ -377,20 +383,20 @@ public function detectsLanguageFromFile($language) $this->getMockedFileInstance( [ 'identifier' => $language . '.test', - 'name' => $language . '.test' + 'name' => $language . '.test', ], $this->languagesStorageMock ) ); - $this->assertSame($language, $detectedLanguage); + self::assertSame($language, $detectedLanguage); } /** * @test * @dataProvider languageFileDataProvider */ - public function detectsLanguageFromString($language) + public function detectsLanguageFromString($language): void { $service = new ServerService($this->getTikaServerConfiguration()); $service->setLogger(new NullLogger()); @@ -400,31 +406,31 @@ public function detectsLanguageFromString($language) $detectedLanguage = $service->detectLanguageFromString($languageString); - $this->assertSame($language, $detectedLanguage); + self::assertSame($language, $detectedLanguage); } /** * @test */ - public function canGetMimeTypesFromServerAndParseThem() + public function canGetMimeTypesFromServerAndParseThem(): void { $service = new ServerService($this->getTikaServerConfiguration()); $service->setLogger(new NullLogger()); $mimeTypes = $service->getSupportedMimeTypes(); - $this->assertContains('application/pdf', $mimeTypes, 'Server did not indicate to support pdf documents'); - $this->assertContains('application/vnd.openxmlformats-officedocument.wordprocessingml.document', $mimeTypes, 'Server did not indicate to support docx documents'); + self::assertContains('application/pdf', $mimeTypes, 'Server did not indicate to support pdf documents'); + self::assertContains('application/vnd.openxmlformats-officedocument.wordprocessingml.document', $mimeTypes, 'Server did not indicate to support docx documents'); } /** * @test */ - public function canPing() + public function canPing(): void { $service = new ServerService($this->getTikaServerConfiguration()); $service->setLogger(new NullLogger()); $pingResult = $service->ping(); - $this->assertTrue($pingResult, 'Could not ping tika server'); + self::assertTrue($pingResult, 'Could not ping tika server'); } /** @@ -435,7 +441,7 @@ protected function getMockedFileInstanceForTestWordDotDocFile() return $this->getMockedFileInstance( [ 'identifier' => 'testWORD.doc', - 'name' => 'testWORD.doc' + 'name' => 'testWORD.doc', ] ); } diff --git a/Tests/Integration/Service/Tika/ServiceFactoryTest.php b/Tests/Integration/Service/Tika/ServiceFactoryTest.php index be87ea540..fc9aa1773 100644 --- a/Tests/Integration/Service/Tika/ServiceFactoryTest.php +++ b/Tests/Integration/Service/Tika/ServiceFactoryTest.php @@ -1,4 +1,6 @@ getConfiguration()); - $this->assertInstanceOf(AppService::class, $extractor); + self::assertInstanceOf(AppService::class, $extractor); } /** * @test */ - public function getTikaReturnsAppServiceForTikaExtractor() + public function getTikaReturnsAppServiceForTikaExtractor(): void { $extractor = ServiceFactory::getTika('tika', $this->getConfiguration()); - $this->assertInstanceOf(AppService::class, $extractor); + self::assertInstanceOf(AppService::class, $extractor); } /** * @test */ - public function getTikaReturnsServerServiceForServerExtractor() + public function getTikaReturnsServerServiceForServerExtractor(): void { $extractor = ServiceFactory::getTika('server', $this->getConfiguration()); - $this->assertInstanceOf(ServerService::class, $extractor); + self::assertInstanceOf(ServerService::class, $extractor); } /** * @test */ - public function getTikaReturnsSolrCellServiceForSolrExtractor() + public function getTikaReturnsSolrCellServiceForSolrExtractor(): void { if (!ExtensionManagementUtility::isLoaded('solr')) { - $this->markTestSkipped('EXT:solr is required for this test, but is not loaded.'); + self::markTestSkipped('EXT:solr is required for this test, but is not loaded.'); } $extractor = ServiceFactory::getTika('solr', $this->getConfiguration()); - $this->assertInstanceOf(SolrCellService::class, $extractor); - $this->assertInstanceOf(SolrCellService::class, $extractor); + self::assertInstanceOf(SolrCellService::class, $extractor); + self::assertInstanceOf(SolrCellService::class, $extractor); } /** * @test * @expectedException \InvalidArgumentException */ - public function getTikaThrowsExceptionForInvalidExtractor() + public function getTikaThrowsExceptionForInvalidExtractor(): void { ServiceFactory::getTika('foo', $this->getConfiguration()); } - protected function setUp() + protected function setUp(): void { parent::setUp(); $this->globalsBackup = [ @@ -105,22 +105,21 @@ protected function setUp() GeneralUtility::makeInstance(CacheManager::class)->setCacheConfigurations([ 'cache_hash' => [ 'frontend' => \TYPO3\CMS\Core\Cache\Frontend\VariableFrontend::class, - 'backend' => \TYPO3\CMS\Core\Cache\Backend\TransientMemoryBackend::class + 'backend' => \TYPO3\CMS\Core\Cache\Backend\TransientMemoryBackend::class, ], 'cache_runtime' => [ 'frontend' => \TYPO3\CMS\Core\Cache\Frontend\VariableFrontend::class, - 'backend' => \TYPO3\CMS\Core\Cache\Backend\TransientMemoryBackend::class - ] + 'backend' => \TYPO3\CMS\Core\Cache\Backend\TransientMemoryBackend::class, + ], ]); unset($GLOBALS['TYPO3_CONF_VARS']); } - protected function tearDown() + protected function tearDown(): void { foreach ($this->globalsBackup as $key => $data) { $GLOBALS[$key] = $data; } unset($this->globalsBackup); } - } diff --git a/Tests/Integration/Service/Tika/ServiceIntegrationTestCase.php b/Tests/Integration/Service/Tika/ServiceIntegrationTestCase.php index 0862c6921..4b0191407 100644 --- a/Tests/Integration/Service/Tika/ServiceIntegrationTestCase.php +++ b/Tests/Integration/Service/Tika/ServiceIntegrationTestCase.php @@ -1,4 +1,6 @@ [ - 'exceptionalErrors' => E_WARNING | E_RECOVERABLE_ERROR | E_DEPRECATED | E_USER_DEPRECATED - ] + 'exceptionalErrors' => E_WARNING | E_RECOVERABLE_ERROR | E_DEPRECATED | E_USER_DEPRECATED, + ], ]; /** @@ -96,7 +96,7 @@ abstract class ServiceIntegrationTestCase extends FunctionalTestCase */ protected $testExtensionsToLoad = [ 'typo3conf/ext/solr', - 'typo3conf/ext/tika' + 'typo3conf/ext/tika', ]; /** @@ -114,7 +114,7 @@ public function __sleep() return $objectVars; } - protected function setUp() + protected function setUp(): void { parent::setUp(); $this->singletonInstances = GeneralUtility::getSingletonInstances(); @@ -123,12 +123,12 @@ protected function setUp() GeneralUtility::makeInstance(CacheManager::class)->setCacheConfigurations([ 'cache_hash' => [ 'frontend' => VariableFrontend::class, - 'backend' => TransientMemoryBackend::class + 'backend' => TransientMemoryBackend::class, ], 'cache_runtime' => [ 'frontend' => VariableFrontend::class, - 'backend' => TransientMemoryBackend::class - ] + 'backend' => TransientMemoryBackend::class, + ], ]); $this->setUpDocumentsStorageMock(); @@ -139,7 +139,7 @@ protected function setUp() if (Util::getIsTYPO3VersionAbove9()) { /** @noinspection PhpFullyQualifiedNameUsageInspection */ $metaDataRepositoryConstructorArgs = [ - GeneralUtility::makeInstance(\TYPO3\CMS\Core\EventDispatcher\EventDispatcher::class) + GeneralUtility::makeInstance(\TYPO3\CMS\Core\EventDispatcher\EventDispatcher::class), ]; } @@ -150,18 +150,18 @@ protected function setUp() $mockedMetaDataRepository ->expects(self::any()) ->method('findByFile') - ->will($this->returnValue(['file' => 1])); + ->willReturn(['file' => 1]); GeneralUtility::setSingletonInstance(MetaDataRepository::class, $mockedMetaDataRepository); } - protected function setUpDocumentsStorageMock() + protected function setUpDocumentsStorageMock(): void { $this->testDocumentsPath = ExtensionManagementUtility::extPath('tika') . 'Tests/TestDocuments/'; $documentsDriver = $this->createDriverFixture([ 'basePath' => $this->testDocumentsPath, - 'caseSensitive' => true + 'caseSensitive' => true, ]); $documentsStorageRecord = [ @@ -173,8 +173,8 @@ protected function setUpDocumentsStorageMock() 'configuration' => $this->convertConfigurationArrayToFlexformXml([ 'basePath' => $this->testDocumentsPath, 'pathType' => 'absolute', - 'caseSensitive' => '1' - ]) + 'caseSensitive' => '1', + ]), ]; $this->documentsStorageMock = $this->getMockBuilder(ResourceStorage::class) @@ -184,19 +184,19 @@ protected function setUpDocumentsStorageMock() $this->documentsStorageMock ->expects(self::any())->method('getUid') - ->will( - $this->returnValue($this->documentsStorageUid) + ->willReturn( + $this->documentsStorageUid ); } - protected function setUpLanguagesStorageMock() + protected function setUpLanguagesStorageMock(): void { $this->testLanguagesPath = ExtensionManagementUtility::extPath('tika') . 'Tests/TestLanguages/'; $languagesDriver = $this->createDriverFixture([ 'basePath' => $this->testLanguagesPath, - 'caseSensitive' => true + 'caseSensitive' => true, ]); $languagesStorageRecord = [ @@ -208,8 +208,8 @@ protected function setUpLanguagesStorageMock() 'configuration' => $this->convertConfigurationArrayToFlexformXml([ 'basePath' => $this->testLanguagesPath, 'pathType' => 'absolute', - 'caseSensitive' => '1' - ]) + 'caseSensitive' => '1', + ]), ]; $this->languagesStorageMock = $this->getMockBuilder(ResourceStorage::class) @@ -218,10 +218,10 @@ protected function setUpLanguagesStorageMock() ->getMock(); $this->languagesStorageMock->expects(self::any()) ->method('getUid') - ->will($this->returnValue($this->languagesStorageUid)); + ->willReturn($this->languagesStorageUid); } - protected function tearDown() + protected function tearDown(): void { GeneralUtility::resetSingletonInstances($this->singletonInstances); parent::tearDown(); @@ -240,12 +240,15 @@ protected function createDriverFixture( ) { /** @var LocalDriver $driver */ $mockedDriverMethods[] = 'isPathValid'; - $driver = $this->getAccessibleMock(LocalDriver::class, - $mockedDriverMethods, [$driverConfiguration]); + $driver = $this->getAccessibleMock( + LocalDriver::class, + $mockedDriverMethods, + [$driverConfiguration] + ); $driver->expects(self::any()) ->method('isPathValid') - ->will( - $this->returnValue(true) + ->willReturn( + true ); $driver->setStorageUid($this->documentsStorageUid); @@ -267,9 +270,9 @@ protected function convertConfigurationArrayToFlexformXml( $flexformArray = [ 'data' => [ 'sDEF' => [ - 'lDEF' => [] - ] - ] + 'lDEF' => [], + ], + ], ]; foreach ($configuration as $key => $value) { $flexformArray['data']['sDEF']['lDEF'][$key] = ['vDEF' => $value]; @@ -305,7 +308,7 @@ protected function getConfiguration() 'solrScheme' => getenv('TESTING_SOLR_SCHEME') ?: 'http', 'solrHost' => getenv('TESTING_SOLR_HOST') ?: 'localhost', 'solrPort' => getenv('TESTING_SOLR_PORT') ?: 8999, - 'solrPath' => getenv('TESTING_SOLR_PATH') ?: '/solr/core_en' + 'solrPath' => getenv('TESTING_SOLR_PATH') ?: '/solr/core_en', ]; } @@ -328,7 +331,7 @@ protected function getMockedFileInstance( ->setConstructorArgs([ $fileData, $storage ?? $this->documentsStorageMock, - $metaData + $metaData, ]) ->setMethods(['getMetaData']) ->getMock(); @@ -343,5 +346,4 @@ protected function getMockedFileInstance( return $fileMock; } - } diff --git a/Tests/Integration/Service/Tika/SolrCellServiceTest.php b/Tests/Integration/Service/Tika/SolrCellServiceTest.php index f7d16e86b..3660b6980 100644 --- a/Tests/Integration/Service/Tika/SolrCellServiceTest.php +++ b/Tests/Integration/Service/Tika/SolrCellServiceTest.php @@ -1,4 +1,6 @@ markTestSkipped('EXT:solr is required for this test, but is not loaded.'); + self::markTestSkipped('EXT:solr is required for this test, but is not loaded.'); } } /** * @test */ - public function newInstancesAreInitializedWithASolrConnection() + public function newInstancesAreInitializedWithASolrConnection(): void { $service = new SolrCellService($this->getConfiguration()); $service->setLogger(new NullLogger()); - $this->assertAttributeInstanceOf(SolrConnection::class, 'solrConnection', $service); + self::assertAttributeInstanceOf(SolrConnection::class, 'solrConnection', $service); } /** * @test */ - public function extractByQueryTextReturnsTextElementFromResponse() + public function extractByQueryTextReturnsTextElementFromResponse(): void { $expectedValue = 'extracted text element'; @@ -66,7 +66,7 @@ public function extractByQueryTextReturnsTextElementFromResponse() $solrWriter->extractByQuery(Argument::type(Query::class)) ->willReturn([ $expectedValue, // extracted text is index 0 - 'meta data element' // meta data is index 1 + 'meta data element', // meta data is index 1 ]); $connectionMock = $this->prophesize(SolrConnection::class); @@ -79,19 +79,19 @@ public function extractByQueryTextReturnsTextElementFromResponse() $file = new File( [ 'identifier' => 'testWORD.doc', - 'name' => 'testWORD.doc' + 'name' => 'testWORD.doc', ], $this->documentsStorageMock ); $actualValue = $service->extractText($file); - $this->assertEquals($expectedValue, $actualValue); + self::assertEquals($expectedValue, $actualValue); } /** * @test */ - public function extractByQueryTextUsesSolariumExtractQuery() + public function extractByQueryTextUsesSolariumExtractQuery(): void { $solrWriter = $this->prophesize(SolrWriteService::class); $solrWriter->extractByQuery(Argument::type(Query::class))->shouldBeCalled(); @@ -103,9 +103,10 @@ public function extractByQueryTextUsesSolariumExtractQuery() $service->setLogger(new NullLogger()); $this->inject($service, 'solrConnection', $connectionMock->reveal()); - $file = new File([ + $file = new File( + [ 'identifier' => 'testWORD.doc', - 'name' => 'testWORD.doc' + 'name' => 'testWORD.doc', ], $this->documentsStorageMock ); @@ -113,19 +114,20 @@ public function extractByQueryTextUsesSolariumExtractQuery() $service->extractText($file); } - #TODO test return value, conversion of response to array + //TODO test return value, conversion of response to array /** * @test */ - public function extractMetaDataUsesSolariumExtractQuery() + public function extractMetaDataUsesSolariumExtractQuery(): void { $solrWriter = $this->prophesize(SolrWriteService::class); $solrWriter->extractByQuery(Argument::type(Query::class)) ->shouldBeCalled() - ->willReturn([ + ->willReturn( + [ 'foo', // extracted text is index 0 - ['bar'] // meta data is index 1 + ['bar'], // meta data is index 1 ] ); @@ -139,7 +141,7 @@ public function extractMetaDataUsesSolariumExtractQuery() $file = new File( [ 'identifier' => 'testWORD.doc', - 'name' => 'testWORD.doc' + 'name' => 'testWORD.doc', ], $this->documentsStorageMock ); @@ -150,20 +152,19 @@ public function extractMetaDataUsesSolariumExtractQuery() /** * @test */ - public function extractsMetaDataFromMp3File() + public function extractsMetaDataFromMp3File(): void { $service = new SolrCellService($this->getConfiguration()); $service->setLogger(new NullLogger()); $mockedFile = $this->getMockedFileInstance( [ 'identifier' => 'testMP3.mp3', - 'name' => 'testMP3.mp3' + 'name' => 'testMP3.mp3', ] ); - $this->assertTrue(in_array($mockedFile->getMimeType(), $service->getSupportedMimeTypes())); + self::assertTrue(in_array($mockedFile->getMimeType(), $service->getSupportedMimeTypes())); $metaData = $service->extractMetaData($mockedFile); - $this->assertEquals('audio/mpeg', $metaData['Content-Type']); - $this->assertEquals('Test Title', $metaData['title']); + self::assertEquals('audio/mpeg', $metaData['Content-Type']); + self::assertEquals('Test Title', $metaData['title']); } - } diff --git a/Tests/Unit/Backend/PreviewControllerTest.php b/Tests/Unit/Backend/PreviewControllerTest.php index 13aa31294..b4d952144 100644 --- a/Tests/Unit/Backend/PreviewControllerTest.php +++ b/Tests/Unit/Backend/PreviewControllerTest.php @@ -1,5 +1,7 @@ getMockBuilder(PreviewController::class)->setMethods([ 'getFileResourceFactory', 'getInitializedPreviewView', 'getConfiguredTikaService', - 'getIsAdmin' + 'getIsAdmin', ])->getMock(); $fileMock = $this->getMockBuilder(FileInterface::class)->getMock(); $fileResourceFactoryMock = $this->getMockBuilder(ResourceFactory::class)->disableOriginalConstructor()->getMock(); - $fileResourceFactoryMock->expects($this->once())->method('getFileObjectFromCombinedIdentifier')->willReturn($fileMock); - $controller->expects($this->once())->method('getFileResourceFactory')->willReturn($fileResourceFactoryMock); + $fileResourceFactoryMock->expects(self::once())->method('getFileObjectFromCombinedIdentifier')->willReturn($fileMock); + $controller->expects(self::once())->method('getFileResourceFactory')->willReturn($fileResourceFactoryMock); $serviceMock = $this->getMockBuilder(ServerService::class)->disableOriginalConstructor()->getMock(); - $serviceMock->expects($this->once())->method('extractText')->with($fileMock)->willReturn('Extracted Text'); - $serviceMock->expects($this->once())->method('extractMetaData')->with($fileMock)->willReturn(['metaKey' => 'metaValue']); - $serviceMock->expects($this->once())->method('detectLanguageFromFile')->with($fileMock)->willReturn('de'); - - $controller->expects($this->once())->method('getIsAdmin')->willReturn(true); - $controller->expects($this->once())->method('getConfiguredTikaService')->willReturn($serviceMock); + $serviceMock->expects(self::once())->method('extractText')->with($fileMock)->willReturn('Extracted Text'); + $serviceMock->expects(self::once())->method('extractMetaData')->with($fileMock)->willReturn(['metaKey' => 'metaValue']); + $serviceMock->expects(self::once())->method('detectLanguageFromFile')->with($fileMock)->willReturn('de'); + $controller->expects(self::once())->method('getIsAdmin')->willReturn(true); + $controller->expects(self::once())->method('getConfiguredTikaService')->willReturn($serviceMock); $request = $this->getMockBuilder(ServerRequestInterface::class)->getMock(); $controller->previewAction($request); @@ -70,22 +72,22 @@ public function previewActionTriggersTikaServices() /** * @test */ - public function previewActionShowsErrorWhenNoAdmin() + public function previewActionShowsErrorWhenNoAdmin(): void { /** @var $controller PreviewController */ $controller = $this->getMockBuilder(PreviewController::class)->setMethods([ 'getFileResourceFactory', 'getInitializedPreviewView', 'getConfiguredTikaService', - 'getIsAdmin' + 'getIsAdmin', ])->getMock(); - $controller->expects($this->once())->method('getIsAdmin')->willReturn(false); + $controller->expects(self::once())->method('getIsAdmin')->willReturn(false); $request = $this->getMockBuilder(ServerRequestInterface::class)->getMock(); /* @var Response $response */ $response = $controller->previewAction($request); - $this->assertEquals(403, $response->getStatusCode(), 'Non admin BE users do not get 403.'); - $this->assertEquals('Only admins can see the tika preview', $response->getBody(), 'Non admin user do not get proper forbidden message.'); + self::assertEquals(403, $response->getStatusCode(), 'Non admin BE users do not get 403.'); + self::assertEquals('Only admins can see the tika preview', $response->getBody(), 'Non admin user do not get proper forbidden message.'); } -} \ No newline at end of file +} diff --git a/Tests/Unit/Backend/SolrModule/TikaControlPanelModuleControllerTest.php b/Tests/Unit/Backend/SolrModule/TikaControlPanelModuleControllerTest.php index 97b01740b..cad7618a7 100644 --- a/Tests/Unit/Backend/SolrModule/TikaControlPanelModuleControllerTest.php +++ b/Tests/Unit/Backend/SolrModule/TikaControlPanelModuleControllerTest.php @@ -1,6 +1,7 @@ viewMock = $this->getDumbMock(ViewInterface::class); $this->controller = $this->getMockBuilder(TikaControlPanelModuleController::class) @@ -59,27 +59,27 @@ public function setUp() * * @test */ - public function canShowInformationFromStandaloneTikaServer() + public function canShowInformationFromStandaloneTikaServer(): void { $tikaServerService = $this->getDumbMock(ServerService::class); - $tikaServerService->expects($this->atLeastOnce())->method('isServerRunning')->will($this->returnValue(true)); - $tikaServerService->expects($this->atLeastOnce())->method('getServerPid')->will($this->returnValue(4711)); - $tikaServerService->expects($this->atLeastOnce())->method('getTikaVersion')->will($this->returnValue("1.11")); + $tikaServerService->expects(self::atLeastOnce())->method('isServerRunning')->willReturn(true); + $tikaServerService->expects(self::atLeastOnce())->method('getServerPid')->willReturn(4711); + $tikaServerService->expects(self::atLeastOnce())->method('getTikaVersion')->willReturn('1.11'); $this->controller->setTikaService($tikaServerService); $this->controller->setTikaConfiguration([ 'extractor' => 'server', - 'tikaServerPath' => $this->getFixturePath('fake-server-jar.jar') + 'tikaServerPath' => $this->getFixturePath('fake-server-jar.jar'), ]); - $this->viewMock->expects($this->at(2))->method('assign')->with( + $this->viewMock->expects(self::at(2))->method('assign')->with( 'server', [ 'jarAvailable' => true, 'isRunning' => true, 'isControllable' => true, 'pid' => 4711, - 'version' => "1.11" + 'version' => '1.11', ] ); diff --git a/Tests/Unit/ExecMockFunctions.php b/Tests/Unit/ExecMockFunctions.php index e973f427a..bdf1476ca 100644 --- a/Tests/Unit/ExecMockFunctions.php +++ b/Tests/Unit/ExecMockFunctions.php @@ -1,5 +1,7 @@ assertEquals('foo', $process->getExecutable()); - $this->assertEquals('-bar', $process->getArguments()); + self::assertEquals('foo', $process->getExecutable()); + self::assertEquals('-bar', $process->getArguments()); } /** * @test */ - public function findPidUsesExecutableBasename() + public function findPidUsesExecutableBasename(): void { $process = new Process('/usr/bin/foo', '-bar'); ExecRecorder::setReturnExecOutput(['foo']); $process->findPid(); - $this->assertTrue((bool)ExecRecorder::$execCalled); - $this->assertContains('foo', ExecRecorder::$execCommand); - $this->assertNotContains('/usr/bin', ExecRecorder::$execCommand); + self::assertTrue((bool)ExecRecorder::$execCalled); + self::assertContains('foo', ExecRecorder::$execCommand); + self::assertNotContains('/usr/bin', ExecRecorder::$execCommand); } /** * @test */ - public function isRunningUsesPid() + public function isRunningUsesPid(): void { $process = new Process('/usr/bin/foo', '-bar'); $process->setPid(1337); $process->isRunning(); - $this->assertTrue((bool)ExecRecorder::$execCalled); - $this->assertContains('1337', ExecRecorder::$execCommand); + self::assertTrue((bool)ExecRecorder::$execCalled); + self::assertContains('1337', ExecRecorder::$execCommand); } /** * @test */ - public function isRunningReturnsTrueForRunningProcess() + public function isRunningReturnsTrueForRunningProcess(): void { $process = new Process('/usr/bin/foo', '-bar'); $process->setPid(1337); @@ -86,61 +85,60 @@ public function isRunningReturnsTrueForRunningProcess() $running = $process->isRunning(); - $this->assertTrue($running); + self::assertTrue($running); } /** * @test */ - public function isRunningReturnsFalseForStoppedProcess() + public function isRunningReturnsFalseForStoppedProcess(): void { $process = new Process('/usr/bin/foo', '-bar'); $running = $process->isRunning(); - $this->assertFalse($running); + self::assertFalse($running); } /** * @test */ - public function startStartsProcess() + public function startStartsProcess(): void { $process = new Process('/usr/bin/foo', '-bar'); ExecRecorder::setReturnExecOutput(['foo']); $running = $process->isRunning(); - $this->assertFalse($running); + self::assertFalse($running); ExecRecorder::setReturnExecOutput(['1337']); // runCommand() return pid of started process = 1337 ExecRecorder::setReturnExecOutput(['1337 /usr/bin/foo -bar']); // isRunning() $running = $process->start(); - $this->assertTrue($running); + self::assertTrue($running); } /** * @test */ - public function stopStopsProcess() + public function stopStopsProcess(): void { $process = new Process('/usr/bin/foo', '-bar'); $process->setPid(1337); ExecRecorder::setReturnExecOutput(['1337 /usr/bin/foo -bar']); $running = $process->isRunning(); - $this->assertTrue($running); + self::assertTrue($running); $stopped = $process->stop(); - $this->assertTrue($stopped); + self::assertTrue($stopped); $running = $process->isRunning(); - $this->assertFalse($running); + self::assertFalse($running); } - protected function setUp() + protected function setUp(): void { ExecRecorder::reset(); } - } diff --git a/Tests/Unit/Service/Extractor/MetaDataExtractorTest.php b/Tests/Unit/Service/Extractor/MetaDataExtractorTest.php index 2563c5e5e..f3c5c0fac 100644 --- a/Tests/Unit/Service/Extractor/MetaDataExtractorTest.php +++ b/Tests/Unit/Service/Extractor/MetaDataExtractorTest.php @@ -1,4 +1,6 @@ "Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership.", - 'Component 1' => "Y component: Quantization table 0, Sampling factors 1 horiz/1 vert", - 'Component 2' => "Cb component: Quantization table 1, Sampling factors 1 horiz/1 vert", - 'Component 3' => "Cr component: Quantization table 1, Sampling factors 1 horiz/1 vert", - 'Compression Type' => "Baseline", - 'Content-Length' => "7686", - 'Content-Type' => "image/jpeg", - 'Data Precision' => "8 bits", - 'File Modified Date' => "Fri Nov 13 11:32:04 CET 2015", - 'File Name' => "testJPEG.jpg", - 'File Size' => "7686 bytes", - 'Image Height' => "75 pixels", - 'Image Width' => "100 pixels", - 'Exif Image Height' => "75 pixels", - 'Exif Image Width' => "100 pixels", - 'JPEG Comment' => "Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership.", - 'Number of Components' => "3", - 'Resolution Units' => "inch", - 'X Resolution' => "72 dots", - 'X-Parsed-By' => ["org.apache.tika.parser.DefaultParser", "org.apache.tika.parser.jpeg.JpegParser"], - 'Y Resolution' => "72 dots", - 'comment' => "Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership.", - 'resourceName' => "testJPEG.jpg", - 'tiff:BitsPerSample' => "8", - 'tiff:ImageLength' => "75", - 'tiff:ImageWidth' => "100", - 'w' => "comments: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership." + 'Comments' => 'Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership.', + 'Component 1' => 'Y component: Quantization table 0, Sampling factors 1 horiz/1 vert', + 'Component 2' => 'Cb component: Quantization table 1, Sampling factors 1 horiz/1 vert', + 'Component 3' => 'Cr component: Quantization table 1, Sampling factors 1 horiz/1 vert', + 'Compression Type' => 'Baseline', + 'Content-Length' => '7686', + 'Content-Type' => 'image/jpeg', + 'Data Precision' => '8 bits', + 'File Modified Date' => 'Fri Nov 13 11:32:04 CET 2015', + 'File Name' => 'testJPEG.jpg', + 'File Size' => '7686 bytes', + 'Image Height' => '75 pixels', + 'Image Width' => '100 pixels', + 'Exif Image Height' => '75 pixels', + 'Exif Image Width' => '100 pixels', + 'JPEG Comment' => 'Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership.', + 'Number of Components' => '3', + 'Resolution Units' => 'inch', + 'X Resolution' => '72 dots', + 'X-Parsed-By' => ['org.apache.tika.parser.DefaultParser', 'org.apache.tika.parser.jpeg.JpegParser'], + 'Y Resolution' => '72 dots', + 'comment' => 'Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership.', + 'resourceName' => 'testJPEG.jpg', + 'tiff:BitsPerSample' => '8', + 'tiff:ImageLength' => '75', + 'tiff:ImageWidth' => '100', + 'w' => 'comments: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership.', ]; } /** * @test */ - public function extractMetaDataReturnsNormalizedMetaData() + public function extractMetaDataReturnsNormalizedMetaData(): void { $fakedTikaExtractResponse = $this->getFakedExtratorResponseForJGEPImage(); @@ -86,55 +87,55 @@ public function extractMetaDataReturnsNormalizedMetaData() ->setConstructorArgs([[]]) ->setMethods(['getExtractedMetaDataFromTikaService']) ->getMock(); - $metaDataExtractor->expects($this->once())->method('getExtractedMetaDataFromTikaService')->will($this->returnValue( + $metaDataExtractor->expects(self::once())->method('getExtractedMetaDataFromTikaService')->willReturn( $fakedTikaExtractResponse - )); + ); $fileMock = $this->getDumbMock(File::class); $metaData = $metaDataExtractor->extractMetaData($fileMock); //@todo wrong data type should be int? - $this->assertSame($metaData['width'], "100", 'Could not extract width from meta data'); - $this->assertSame($metaData['height'], "75", 'Could not extract height from meta data'); + self::assertSame($metaData['width'], '100', 'Could not extract width from meta data'); + self::assertSame($metaData['height'], '75', 'Could not extract height from meta data'); } /** * @test */ - public function canProcessReturnsFalseForExeFile() + public function canProcessReturnsFalseForExeFile(): void { $tikaAppServiceMock = $this->getDumbMock(AppService::class); - $tikaAppServiceMock->expects($this->once())->method('getSupportedMimeTypes')->will($this->returnValue( + $tikaAppServiceMock->expects(self::once())->method('getSupportedMimeTypes')->willReturn( ['application/vnd.sun.xml.writer'] - )); + ); $exeFileMock = $this->getDumbMock(File::class); - $exeFileMock->expects($this->any())->method('getMimeType')->will($this->returnValue('exe')); + $exeFileMock->expects(self::any())->method('getMimeType')->willReturn('exe'); $metaDataExtractor = $this->getMockBuilder(MetaDataExtractor::class) ->setConstructorArgs([[]]) ->setMethods(['getExtractor'])->getMock(); - $metaDataExtractor->expects($this->once())->method('getExtractor')->will($this->returnValue($tikaAppServiceMock)); - $this->assertFalse($metaDataExtractor->canProcess($exeFileMock)); + $metaDataExtractor->expects(self::once())->method('getExtractor')->willReturn($tikaAppServiceMock); + self::assertFalse($metaDataExtractor->canProcess($exeFileMock)); } /** * @test */ - public function canProcessReturnsTrueForSxwFile() + public function canProcessReturnsTrueForSxwFile(): void { $tikaAppServiceMock = $this->getDumbMock(AppService::class); - $tikaAppServiceMock->expects($this->once())->method('getSupportedMimeTypes')->will($this->returnValue( + $tikaAppServiceMock->expects(self::once())->method('getSupportedMimeTypes')->willReturn( ['application/vnd.sun.xml.writer'] - )); + ); $exeFileMock = $this->getDumbMock(File::class); - $exeFileMock->expects($this->any())->method('getMimeType')->will($this->returnValue('application/vnd.sun.xml.writer')); + $exeFileMock->expects(self::any())->method('getMimeType')->willReturn('application/vnd.sun.xml.writer'); $metaDataExtractor = $this->getMockBuilder(MetaDataExtractor::class) ->setConstructorArgs([[]]) ->setMethods(['getExtractor'])->getMock(); - $metaDataExtractor->expects($this->once())->method('getExtractor')->will($this->returnValue($tikaAppServiceMock)); - $this->assertTrue($metaDataExtractor->canProcess($exeFileMock)); + $metaDataExtractor->expects(self::once())->method('getExtractor')->willReturn($tikaAppServiceMock); + self::assertTrue($metaDataExtractor->canProcess($exeFileMock)); } } diff --git a/Tests/Unit/Service/Tika/AbstractServiceTest.php b/Tests/Unit/Service/Tika/AbstractServiceTest.php index 899e3c715..863053bc3 100644 --- a/Tests/Unit/Service/Tika/AbstractServiceTest.php +++ b/Tests/Unit/Service/Tika/AbstractServiceTest.php @@ -1,7 +1,9 @@ getMockBuilder(AbstractService::class) ->setMethods(['initializeService']) ->disableOriginalConstructor() ->getMockForAbstractClass(); - $service->expects($this->once()) + $service->expects(self::once()) ->method('initializeService'); $service->__construct([]); } - } diff --git a/Tests/Unit/UnitTestCase.php b/Tests/Unit/UnitTestCase.php index c33c09021..4bc8b5123 100644 --- a/Tests/Unit/UnitTestCase.php +++ b/Tests/Unit/UnitTestCase.php @@ -1,4 +1,6 @@ - * @package TYPO3 - * @subpackage tika */ class UnitTestCase extends TYPO3UnitTestCase { @@ -68,7 +68,7 @@ protected function getConfiguration() * @see \ApacheSolrForTypo3\Tika\Tests\Integration\Service\Tika\ServiceIntegrationTestCase::getConfiguration */ 'solrPort' => getenv('TESTING_SOLR_PORT') ?: 8080, - 'solrPath' => getenv('TESTING_SOLR_PATH') ?: '/solr/' + 'solrPath' => getenv('TESTING_SOLR_PATH') ?: '/solr/', ]; } @@ -107,5 +107,4 @@ protected function getRuntimeDirectory() $rc = new ReflectionClass(get_class($this)); return dirname($rc->getFileName()); } - } diff --git a/ext_emconf.php b/ext_emconf.php index 7454d8499..4b27fbd45 100644 --- a/ext_emconf.php +++ b/ext_emconf.php @@ -1,4 +1,6 @@ 'Apache Tika for TYPO3', 'description' => 'Provides Tika services for TYPO3 to detect a document\'s language, extract meta data, and extract content from files. Can either use a stand alone Tika executable or Tika integrated in a Solr server with an activated extracting request handler.', @@ -16,12 +18,12 @@ 'constraints' => [ 'depends' => [ 'typo3' => '10.4.10-10.4.99', - 'filemetadata' => '' + 'filemetadata' => '', ], 'conflicts' => [], 'suggests' => [ - 'solr' => '11.1.0-0.0.0' + 'solr' => '11.1.0-0.0.0', ], ], - '_md5_values_when_last_written' => '' + '_md5_values_when_last_written' => '', ]; diff --git a/ext_localconf.php b/ext_localconf.php index cc3887e01..62161e050 100644 --- a/ext_localconf.php +++ b/ext_localconf.php @@ -1,4 +1,6 @@ addJavaScript'; \ No newline at end of file +$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/backend.php']['constructPostProcess'][] = \ApacheSolrForTypo3\Tika\Hooks\BackendControllerHook::class . '->addJavaScript'; diff --git a/ext_tables.php b/ext_tables.php index 5450a5e32..a7cd262e4 100644 --- a/ext_tables.php +++ b/ext_tables.php @@ -1,4 +1,6 @@ 'index, startServer, stopServer' + \ApacheSolrForTypo3\Tika\Controller\Backend\SolrModule\TikaControlPanelModuleController::class => 'index, startServer, stopServer', ], [ 'access' => 'user,group', 'icon' => 'EXT:tika/Resources/Public/Images/Icons/module-tika.svg', - 'labels' => 'LLL:EXT:tika/Resources/Private/Language/locallang.xlf:solr.backend.tika.label' + 'labels' => 'LLL:EXT:tika/Resources/Private/Language/locallang.xlf:solr.backend.tika.label', ] ); } - } From 4cffbd78da03512e9677c6d1c034ad304edccfc5 Mon Sep 17 00:00:00 2001 From: Georg Ringer Date: Wed, 26 Jan 2022 15:41:36 +0100 Subject: [PATCH 13/20] [TASK] Move ext icon --- .../Public/Icons/Extension.gif | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename ext_icon.gif => Resources/Public/Icons/Extension.gif (100%) diff --git a/ext_icon.gif b/Resources/Public/Icons/Extension.gif similarity index 100% rename from ext_icon.gif rename to Resources/Public/Icons/Extension.gif From f763ebb6bb8c5749ba3a4c4868ab5cff90578099 Mon Sep 17 00:00:00 2001 From: Georg Ringer Date: Wed, 26 Jan 2022 15:55:07 +0100 Subject: [PATCH 14/20] [BUGFIX] Force variable as string --- Classes/Process.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/Process.php b/Classes/Process.php index e2dda897c..add89ce1d 100644 --- a/Classes/Process.php +++ b/Classes/Process.php @@ -61,7 +61,7 @@ class Process */ public function __construct($executable, $arguments = '') { - $this->executable = $executable; + $this->executable = (string)$executable; $this->arguments = $arguments; } From 897b12cbe0c2331291132dfd0f526925998d0bd0 Mon Sep 17 00:00:00 2001 From: Georg Ringer Date: Wed, 26 Jan 2022 15:55:24 +0100 Subject: [PATCH 15/20] [TASK] Allow installation of 11.5 --- composer.json | 2 +- ext_emconf.php | 8 ++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/composer.json b/composer.json index a6ac39d6f..dfe6fe5c9 100644 --- a/composer.json +++ b/composer.json @@ -26,7 +26,7 @@ "ext-json": "*", "ext-pdo": "*", - "typo3/cms-core": "^10.4.10", + "typo3/cms-core": "^10.4.10 || ^11.5", "typo3/cms-backend": "*", "typo3/cms-extbase": "*", "typo3/cms-reports": "*", diff --git a/ext_emconf.php b/ext_emconf.php index 4b27fbd45..124e784d3 100644 --- a/ext_emconf.php +++ b/ext_emconf.php @@ -10,14 +10,10 @@ 'author' => 'Ingo Renner, Timo Hund, Markus Friedrich', 'author_email' => 'ingo@typo3.org', 'author_company' => 'dkd Internet Service GmbH', - 'module' => '', - 'uploadfolder' => 0, - 'createDirs' => '', - 'modify_tables' => '', - 'clearCacheOnLoad' => 1, + 'clearCacheOnLoad' => true, 'constraints' => [ 'depends' => [ - 'typo3' => '10.4.10-10.4.99', + 'typo3' => '10.4.10-11.5.99', 'filemetadata' => '', ], 'conflicts' => [], From 5c8976c105c577598a3693db7a357bac1b43a792 Mon Sep 17 00:00:00 2001 From: Georg Ringer Date: Thu, 27 Jan 2022 07:21:34 +0100 Subject: [PATCH 16/20] [BUGFIX] Use correct controller code --- .../Backend/SolrModule/TikaControlPanelModuleController.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Classes/Controller/Backend/SolrModule/TikaControlPanelModuleController.php b/Classes/Controller/Backend/SolrModule/TikaControlPanelModuleController.php index 252f2b564..f4308a47e 100644 --- a/Classes/Controller/Backend/SolrModule/TikaControlPanelModuleController.php +++ b/Classes/Controller/Backend/SolrModule/TikaControlPanelModuleController.php @@ -102,7 +102,7 @@ public function setTikaConfiguration(array $tikaConfiguration): void * * @throws Exception */ - public function indexAction(): void + public function indexAction() { $this->view->assign('configuration', $this->tikaConfiguration); $this->view->assign( @@ -124,6 +124,7 @@ public function indexAction(): void ] ); } + return $this->getModuleTemplateResponse(); } /** From eaad00e63125626c13963f814ab4fc1cc89b15b1 Mon Sep 17 00:00:00 2001 From: Georg Ringer Date: Thu, 27 Jan 2022 11:23:49 +0100 Subject: [PATCH 17/20] [TASK] update ci pipeline --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c7aebb41b..cf1610274 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,7 +11,7 @@ on: env: TIKA_VERSION: '1.24.1' TIKA_PATH: /ramfs/data-tika-binaries - EXT_SOLR_VERSION: 'dev-release-11.1.x' + EXT_SOLR_VERSION: 'dev-release-11.5.x' TYPO3_DATABASE_NAME: 'typo3_ci' TYPO3_DATABASE_HOST: '127.0.0.1' TYPO3_DATABASE_USERNAME: 'root' @@ -30,8 +30,8 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - PHP: [ '7.2', '7.3', '7.4' ] - TYPO3: [ '^10.4', '10.4.x-dev' ] + PHP: [ '7.4' ] + TYPO3: [ '^11.5'] env: TYPO3_VERSION: ${{ matrix.TYPO3 }} From ed160cd00ef501515ee6953e806744ee76e40183 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20K=C3=A4hm?= Date: Fri, 28 Jan 2022 09:44:28 +0100 Subject: [PATCH 18/20] [TASK] TYPO3 11 LTS and PHP 8.1 compatibility --- .editorconfig | 40 ++++- .github/ISSUE_TEMPLATE/bug_report.md | 8 +- .github/workflows/ci.yml | 143 ++++++++-------- .php-cs-fixer.php | 11 ++ .scrutinizer.yml | 40 +++-- Build/Release/pre_upload_check.php | 16 -- Build/Release/ter_tag_uploader.sh | 41 ----- Build/Test/IntegrationTests.xml | 14 +- Build/Test/IntegrationTestsBootstrap.php | 23 +++ Build/Test/UnitTests.xml | 21 +-- Build/Test/UnitTestsBootstrap.php | 78 +++++++++ Build/Test/bootstrap.sh | 85 ++++++---- Build/Test/cibuild.sh | 83 +++++++-- Classes/ContextMenu/Preview.php | 18 +- .../Controller/Backend/PreviewController.php | 27 ++- .../TikaControlPanelModuleController.php | 106 ++++++------ Classes/Hooks/BackendControllerHook.php | 14 ++ Classes/Process.php | 70 ++++---- Classes/Report/TikaStatus.php | 7 +- .../Service/Extractor/AbstractExtractor.php | 19 ++- .../Service/Extractor/LanguageDetector.php | 46 +++-- .../Service/Extractor/MetaDataExtractor.php | 84 +++++----- Classes/Service/Extractor/TextExtractor.php | 51 +++--- Classes/Service/File/SizeValidator.php | 40 ++--- Classes/Service/Tika/AbstractService.php | 9 +- Classes/Service/Tika/AppService.php | 27 +-- Classes/Service/Tika/ServerService.php | 40 ++--- Classes/Service/Tika/ServiceFactory.php | 41 ++--- Classes/Service/Tika/ServiceInterface.php | 50 +++--- Classes/Service/Tika/SolrCellService.php | 61 +++---- .../Tika/UnsupportedOperationException.php | 31 ++-- Classes/Util.php | 69 +++----- Classes/Utility/FileUtility.php | 3 +- Classes/Utility/ShellUtility.php | 29 ++-- .../Backend/IsStringViewHelper.php | 53 ++++++ Configuration/Backend/Routes.php | 15 +- Documentation/Releases/11_0.rst | 124 +++++++++++--- Documentation/Settings.cfg | 6 +- Documentation/Settings.yml | 2 +- Documentation/conf.py | 4 +- README.md | 12 +- .../Private/Templates/Backend/Preview.html | 70 +++++--- .../Public/JavaScript/ContextMenuActions.js | 46 ++--- .../Service/Tika/AppServiceTest.php | 28 ++-- .../Tika/Fixtures/ServerServiceFixture.php | 5 +- .../Service/Tika/ServerServiceTest.php | 26 +-- .../Service/Tika/ServiceFactoryTest.php | 63 +++---- .../Tika/ServiceIntegrationTestCase.php | 158 ++++++++++++------ .../Service/Tika/SolrCellServiceTest.php | 22 +-- Tests/Unit/Backend/PreviewControllerTest.php | 45 +++-- .../TikaControlPanelModuleControllerTest.php | 76 +++++---- Tests/Unit/ExecMockFunctions.php | 28 +++- Tests/Unit/ExecRecorder.php | 43 ++--- Tests/Unit/ProcessTest.php | 44 +++-- .../Extractor/MetaDataExtractorTest.php | 40 ++--- .../Unit/Service/Tika/AbstractServiceTest.php | 36 ++-- Tests/Unit/UnitTestCase.php | 49 +++--- composer.json | 32 ++-- ext_emconf.php | 15 +- ext_localconf.php | 9 +- ext_tables.php | 3 +- 61 files changed, 1421 insertions(+), 1078 deletions(-) create mode 100644 .php-cs-fixer.php delete mode 100644 Build/Release/pre_upload_check.php delete mode 100755 Build/Release/ter_tag_uploader.sh create mode 100644 Build/Test/IntegrationTestsBootstrap.php create mode 100644 Build/Test/UnitTestsBootstrap.php create mode 100644 Classes/ViewHelpers/Backend/IsStringViewHelper.php diff --git a/.editorconfig b/.editorconfig index c4f7749dc..867955b22 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,9 +1,10 @@ # EditorConfig is awesome: http://EditorConfig.org -# TYPO3 Standard: https://github.com/TYPO3/TYPO3.CMS/blob/master/.editorconfig +# TYPO3 Standard: https://github.com/TYPO3/coding-standards # top-most EditorConfig file root = true +# Unix-style newlines with a newline ending every file [*] charset = utf-8 end_of_line = lf @@ -12,15 +13,50 @@ indent_size = 4 insert_final_newline = true trim_trailing_whitespace = true +# TS/JS-Files +[*.{ts,js}] +indent_size = 2 + +# JSON-Files +[*.json] +indent_style = tab + # ReST-Files [*.rst] -indent_size = 3 +indent_size = 4 max_line_length = 80 # YAML-Files [*.{yaml,yml}] indent_size = 2 +# NEON-Files +[*.neon] +indent_size = 2 +indent_style = tab + +# package.json +[package.json] +indent_size = 2 + +# TypoScript +[*.{typoscript,tsconfig}] +indent_size = 2 + # XLF/XML-Files [*.{xlf,xml}] indent_style = tab + +# SQL-Files +[*.sql] +indent_style = tab +indent_size = 2 + +# .htaccess +[{_.htaccess,.htaccess}] +indent_style = tab + +# Bash scripts +[*.sh] +indent_style = space +indent_size = 2 diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 430371b00..5150467f8 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -28,11 +28,11 @@ A clear and concise description of what you expected to happen. If applicable, add screenshots to help explain your problem. **Used versions (please complete the following information):** - - TYPO3 Version: [e.g. 10.4.20] + - TYPO3 Version: [e.g. 11.5.6] - Browser: [e.g. chrome, safari] - - EXT:solr Version: [e.g. 11.1.1] - - EXT:tika Version: [e.g. 10.0.0] - - Used Apache Solr Version: [e.g. 8.9.0] + - EXT:solr Version: [e.g. 11.5.1] + - EXT:tika Version: [e.g. 11.0.0] + - Used Apache Solr Version: [e.g. 8.11.1] - PHP Version: [e.g. 7.4.0] - MySQL Version: [e.g. 8.0.0] diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cf1610274..96c0e083a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,110 +2,108 @@ name: build on: push: - branches: [ main, release-10.0.x, release-6.0.x ] + branches: [ 'main', 'release-11.0.x', 'release-10.0.x' ] tags: - "**" pull_request: - branches: [ main, release-10.0.x, release-6.0.x ] + branches: [ 'main', 'release-11.0.x', 'release-10.0.x' ] env: + CI_BUILD_DIRECTORY: '/home/runner/work/ext-tika/ext-tika/.Build' TIKA_VERSION: '1.24.1' - TIKA_PATH: /ramfs/data-tika-binaries + TIKA_PATH: '/home/runner/work/ext-tika/ext-tika/.Build/data-tika-binaries' EXT_SOLR_VERSION: 'dev-release-11.5.x' - TYPO3_DATABASE_NAME: 'typo3_ci' - TYPO3_DATABASE_HOST: '127.0.0.1' - TYPO3_DATABASE_USERNAME: 'root' - TYPO3_DATABASE_PASSWORD: 'root' - PHP_CS_FIXER_VERSION: '^3.0.2' - LOCAL_IMAGE_NAME: 'solrci-image:latest' - LOCAL_CONTAINER_NAME: 'solrci-container' + SOLR_IMAGE_TAG: 'release-11.5.x' + SOLR_CONTAINER_NAME: 'solrci-container' TESTING_SOLR_PORT: 8983 - LOCAL_SOLR_VOLUME_NAME: 'solrci-volume' - LOCAL_SOLR_VOLUME_PATH: '/ramfs/data-solr' + SOLR_VOLUME_NAME: 'solrci-volume' + SOLR_VOLUME_PATH: '/home/runner/work/ext-tika/ext-tika/.Build/data-solr' - CI_BUILD_DIRECTORY: '/ramfs/data-build' jobs: tests: runs-on: ubuntu-latest strategy: matrix: - PHP: [ '7.4' ] - TYPO3: [ '^11.5'] + PHP: [ '7.4', '8.0', '8.1' ] + TYPO3: [ '^11.5', '11.5.x-dev' ] env: + TYPO3_DATABASE_NAME: 'typo3_ci' + TYPO3_DATABASE_HOST: '127.0.0.1' + TYPO3_DATABASE_USERNAME: 'root' + TYPO3_DATABASE_PASSWORD: 'root' TYPO3_VERSION: ${{ matrix.TYPO3 }} name: TYPO3 ${{ matrix.TYPO3 }} on PHP ${{ matrix.PHP }} steps: # Workaround for issue with actions/checkout@v2 wrong PR commit checkout: See https://github.com/actions/checkout/issues/299#issuecomment-677674415 - - name: Checkout current state of Pull Request + - + name: Checkout current state of Pull Request if: github.event_name == 'pull_request' uses: actions/checkout@v2 with: + fetch-depth: 2 ref: ${{ github.event.pull_request.head.sha }} - - name: Checkout current state of Branch + - + name: Checkout current state of Branch if: github.event_name == 'push' uses: actions/checkout@v2 - - - name: Cache Apache Tika Binaries + with: + fetch-depth: 2 + # End: Workaround for issue with actions/checkout@v2 wrong PR commit checkout + - + name: Cache Apache Tika Binaries id: tika-bineries uses: actions/cache@v2 with: path: $TIKA_PATH key: tika-bineries - - name: Mount RAMFS + - + name: Mount RAMFS run: | - id - sudo mkdir /ramfs - sudo mount -t tmpfs -o size=2048m none /ramfs - sudo mkdir -p /ramfs/data-{solr,mysql,build} && sudo chown $USER /ramfs/data-* && sudo chown 8983:8983 /ramfs/data-solr - - - name: Setup PHP + sudo mkdir -p ${{ env.CI_BUILD_DIRECTORY }} + sudo mount -t tmpfs -o size=2048m none ${{ env.CI_BUILD_DIRECTORY }} + sudo mkdir -p ${{ env.CI_BUILD_DIRECTORY }}/data-{solr,mysql,tika-binaries} \ + && sudo chown $USER ${{ env.CI_BUILD_DIRECTORY }}/data-{mysql,tika-binaries} \ + && sudo chown 8983:8983 ${{ env.CI_BUILD_DIRECTORY }}/data-solr + - + name: 'Start Docker: Solr, Tika, MySQL' + run: | + docker run --name "MySQL-CI" -v ${{ env.CI_BUILD_DIRECTORY }}/data-mysql:/var/lib/mysql -p 3306:3306 \ + -e MYSQL_DATABASE=$TYPO3_DATABASE_NAME \ + -e MYSQL_ROOT_PASSWORD=$TYPO3_DATABASE_PASSWORD \ + -d mysql:8.0 mysqld --default-authentication-plugin=mysql_native_password + sudo chmod g+w "$SOLR_VOLUME_PATH" + docker volume create --name "$LOCAL_VOLUME_NAME" --opt type=none --opt device="$SOLR_VOLUME_PATH" --opt o=bind + docker run --rm --name="$SOLR_CONTAINER_NAME" -d -p 127.0.0.1:8983:8983 -v "$LOCAL_VOLUME_NAME":"/var/solr" "typo3solr/ext-solr:$SOLR_IMAGE_TAG" + docker run -d -p 9998:9998 apache/tika:$TIKA_VERSION"-full" + docker ps + - + name: Setup PHP uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.PHP }} coverage: xdebug tools: composer:v2 - - - name: CI-Bootstrap + - + name: CI-Bootstrap run: | - echo "CI_BUILD_DIRECTORY=$CI_BUILD_DIRECTORY/" - cp -r ../ext-tika $CI_BUILD_DIRECTORY/. - cd $CI_BUILD_DIRECTORY/ext-tika ./Build/Test/bootstrap.sh --skip-solr-install --skip-tika-server-install - echo "Current Size of EXT:tika build Artefacts: " && du -sh $CI_BUILD_DIRECTORY/ext-tika - - - name: Build ext-solr docker image - run: | - cd $CI_BUILD_DIRECTORY/ext-tika - docker build -t $LOCAL_IMAGE_NAME -f .Build/Web/typo3conf/ext/solr/Docker/SolrServer/Dockerfile .Build/Web/typo3conf/ext/solr/ - - - name: 'Start Docker: Solr, Tika, MySQL' + echo "Current Size of EXT:tika build Artefacts: " \ + && sudo du -sh "${{ env.CI_BUILD_DIRECTORY }}" + - + name: CI-Build run: | - docker run --name "MySQL-CI" -v /ramfs/data-mysql:/var/lib/mysql -p 3306:3306 \ - -e MYSQL_DATABASE=$TYPO3_DATABASE_NAME \ - -e MYSQL_ROOT_PASSWORD=$TYPO3_DATABASE_PASSWORD \ - -d mysql:8.0 mysqld --default-authentication-plugin=mysql_native_password - sudo chmod g+w "$LOCAL_SOLR_VOLUME_PATH" - docker volume create --name "$LOCAL_VOLUME_NAME" --opt type=none --opt device="$LOCAL_SOLR_VOLUME_PATH" --opt o=bind - docker run --rm --name="$LOCAL_CONTAINER_NAME" -d -p 127.0.0.1:8983:8983 -v "$LOCAL_VOLUME_NAME":"/var/solr" "$LOCAL_IMAGE_NAME" - docker run -d -p 9998:9998 apache/tika:$TIKA_VERSION"-full" - docker ps - - - name: CI-Build - run: | - cd $CI_BUILD_DIRECTORY/ext-tika ./Build/Test/cibuild.sh - echo "Current Size of EXT:tika build Artefacts: " && du -sh $CI_BUILD_DIRECTORY/ && du -sh $CI_BUILD_DIRECTORY/ext-tika/.Build/* - - - name: Upload code coverage to Scrutinizer + echo "Current Size of EXT:tika build Artefacts: " \ + && sudo du -sh $CI_BUILD_DIRECTORY/ \ + && sudo du -sh $CI_BUILD_DIRECTORY/* + - + name: Upload code coverage to Scrutinizer run: | - cd $CI_BUILD_DIRECTORY/ext-tika - mkdir -p $GITHUB_WORKSPACE/bin - wget https://scrutinizer-ci.com/ocular.phar -O $GITHUB_WORKSPACE/bin/ocular && chmod +x $GITHUB_WORKSPACE/bin/ocular - php $GITHUB_WORKSPACE/bin/ocular code-coverage:upload --format=php-clover coverage.unit.clover - php $GITHUB_WORKSPACE/bin/ocular code-coverage:upload --format=php-clover coverage.integration.clover + ocular code-coverage:upload --format=php-clover coverage.unit.clover + ocular code-coverage:upload --format=php-clover coverage.integration.clover publish: name: Publish new version to TER @@ -116,21 +114,23 @@ jobs: TYPO3_API_TOKEN: ${{ secrets.TYPO3_API_TOKEN }} steps: - - name: Checkout repository + - + name: Checkout repository uses: actions/checkout@v2 with: ref: ${{ github.event.pull_request.head.sha }} - - - name: Check tag + - + name: Check tag run: | if ! [[ ${{ github.ref }} =~ ^refs/tags/[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$ ]]; then exit 1 fi - - name: Get version + - + name: Get version id: get-version run: echo ::set-output name=version::${GITHUB_REF/refs\/tags\//} - - - name: Get comment + - + name: Get comment id: get-comment run: | readonly local comment=$(git tag -n99 -l ${{ steps.get-version.outputs.version }} | sed "s/^[0-9.]*[ ]*//g") @@ -139,17 +139,18 @@ jobs: else echo ::set-output name=comment::$comment fi - - name: Setup PHP + - + name: Setup PHP uses: shivammathur/setup-php@v2 with: php-version: 7.4 extensions: intl, mbstring, json, zip, curl tools: composer:v2 - - - name: Install tailor + - + name: Install tailor run: composer global require typo3/tailor --prefer-dist --no-progress - - - name: Publish EXT:tika to TER + - + name: Publish EXT:tika to TER run: php ~/.composer/vendor/bin/tailor ter:publish --comment "${{ steps.get-comment.outputs.comment }}" ${{ steps.get-version.outputs.version }} diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php new file mode 100644 index 000000000..4ea4def24 --- /dev/null +++ b/.php-cs-fixer.php @@ -0,0 +1,11 @@ +getFinder() + ->exclude([ + '.Build' + ]) + ->in(__DIR__); +return $config; diff --git a/.scrutinizer.yml b/.scrutinizer.yml index f0a6bcf73..452c5d4f2 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -12,12 +12,10 @@ tools: php_cpd: enabled: true + # we do this on GitHub-Actions via typo3/coding-standards php_code_sniffer: - enabled: true - config: - standard: TYPO3CMS - - # we do this on travis + enabled: false + # we do this on GitHub-Actions via typo3/coding-standards php_cs_fixer: enabled: false @@ -38,25 +36,25 @@ tools: timeout: 2400 checks: - php: - excluded_dependencies: - - typo3/cms-install - avoid_superglobals: false + php: + excluded_dependencies: + - typo3/cms-install + avoid_superglobals: false + +build_failure_conditions: + - 'patches.label("Doc Comments").count > 10' + - 'patches.label("Spacing").count > 15' + - 'issues.label("coding-style").count > 10' + - 'issues.severity(>= MAJOR).count > 60' + - 'project.metric("scrutinizer.quality", < 8)' + - 'project.metric_change("scrutinizer.test_coverage", < -0.10)' build: environment: # We want to test with the smallest supported by TYPO3 PHP version - php: 7.2 - dependencies: - override: - - composer install --dev --no-interaction --no-scripts + php: 7.4 nodes: analysis: - dependencies: - after: - - composer require --dev squizlabs/php_codesniffer:^3.6 -# tests: -# override: -# - php-scrutinizer-run -# - command: phpcs-run -# use_website_config: false + tests: + override: + - php-scrutinizer-run diff --git a/Build/Release/pre_upload_check.php b/Build/Release/pre_upload_check.php deleted file mode 100644 index bd204e6e3..000000000 --- a/Build/Release/pre_upload_check.php +++ /dev/null @@ -1,16 +0,0 @@ - 0) { - echo 'Version was a valid release version: ' . $version . PHP_EOL; - exit(0); -} - echo 'Version was NOT a valid release version: ' . $version . PHP_EOL; - exit(1); diff --git a/Build/Release/ter_tag_uploader.sh b/Build/Release/ter_tag_uploader.sh deleted file mode 100755 index 04d9dea2c..000000000 --- a/Build/Release/ter_tag_uploader.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env bash - -REPOSITORY_NAME="ext-tika" -EXTENSION_KEY="tika" - -# This script is triggered by travis when a build has been triggered and was tagged -# -# See: http://insight.helhum.io/post/140850737265/automatically-upload-typo3-extensions-to-ter-with - -echo "PWD: $(pwd)" -echo "Travis tag is: ${TRAVIS_TAG}" - -export PATH="$PATH:$HOME/.composer/vendor/bin" - -if [ -n "$TRAVIS_TAG" ] && [ -n "$TYPO3_ORG_USERNAME" ] && [ -n "$TYPO3_ORG_PASSWORD" ]; then - php Build/Release/pre_upload_check.php - if [ $? -eq 0 ]; then - echo -e "Preparing upload of release ${TRAVIS_TAG} to TER\n" - curl -sSL https://raw.githubusercontent.com/alrra/travis-after-all/1.4.4/lib/travis-after-all.js | node - if [ $? -eq 0 ]; then - # Link the git checkout directory to a directory called like the extension key, because the uploader requires that. - echo "Moving checkout to expected folder structure." - EXTENSION_DIR=$(pwd) - PARENT_DIR="$EXTENSION_DIR/../" - cd $PARENT_DIR - mv $REPOSITORY_NAME $EXTENSION_KEY - cd $EXTENSION_KEY - pwd - - git reset --hard HEAD && git clean -fx - echo "Files in this package" - ls -l - - TAG_MESSAGE=`git tag -n10 -l $TRAVIS_TAG | sed 's/^[0-9.]*[ ]*//g'` - echo "Uploading release ${TRAVIS_TAG} to TER" - upload . "$TYPO3_ORG_USERNAME" "$TYPO3_ORG_PASSWORD" "$TAG_MESSAGE" - fi; - fi; -else - echo "Nothing todo" -fi; \ No newline at end of file diff --git a/Build/Test/IntegrationTests.xml b/Build/Test/IntegrationTests.xml index 697990140..b246f6732 100644 --- a/Build/Test/IntegrationTests.xml +++ b/Build/Test/IntegrationTests.xml @@ -1,4 +1,5 @@ - + + + + ../../Classes/ + + ../../Tests/Integration/ - - - - ../../Classes/ - - diff --git a/Build/Test/IntegrationTestsBootstrap.php b/Build/Test/IntegrationTestsBootstrap.php new file mode 100644 index 000000000..ec3208b8c --- /dev/null +++ b/Build/Test/IntegrationTestsBootstrap.php @@ -0,0 +1,23 @@ +defineOriginalRootPath(); + $testbase->createDirectory(ORIGINAL_ROOT . 'typo3temp/var/tests'); + $testbase->createDirectory(ORIGINAL_ROOT . 'typo3temp/var/transient'); +}); diff --git a/Build/Test/UnitTests.xml b/Build/Test/UnitTests.xml index 053921960..f40871e94 100644 --- a/Build/Test/UnitTests.xml +++ b/Build/Test/UnitTests.xml @@ -1,4 +1,5 @@ - + - + verbose="false" +> + + + ../../Classes/ + + ../../Tests/Unit/ - - - ../../Classes/ - - diff --git a/Build/Test/UnitTestsBootstrap.php b/Build/Test/UnitTestsBootstrap.php new file mode 100644 index 000000000..533287acf --- /dev/null +++ b/Build/Test/UnitTestsBootstrap.php @@ -0,0 +1,78 @@ +getWebRoot(), '/')); + } + if (!getenv('TYPO3_PATH_WEB')) { + putenv('TYPO3_PATH_WEB=' . rtrim($testbase->getWebRoot(), '/')); + } + + $testbase->defineSitePath(); + + $requestType = \TYPO3\CMS\Core\Core\SystemEnvironmentBuilder::REQUESTTYPE_BE | \TYPO3\CMS\Core\Core\SystemEnvironmentBuilder::REQUESTTYPE_CLI; + \TYPO3\CMS\Core\Core\SystemEnvironmentBuilder::run(0, $requestType); + + $testbase->createDirectory(\TYPO3\CMS\Core\Core\Environment::getPublicPath() . '/typo3conf/ext'); + $testbase->createDirectory(\TYPO3\CMS\Core\Core\Environment::getPublicPath() . '/typo3temp/assets'); + $testbase->createDirectory(\TYPO3\CMS\Core\Core\Environment::getPublicPath() . '/typo3temp/var/tests'); + $testbase->createDirectory(\TYPO3\CMS\Core\Core\Environment::getPublicPath() . '/typo3temp/var/transient'); + + // Retrieve an instance of class loader and inject to core bootstrap + $classLoader = require $testbase->getPackagesPath() . '/autoload.php'; + \TYPO3\CMS\Core\Core\Bootstrap::initializeClassLoader($classLoader); + + // Initialize default TYPO3_CONF_VARS + $configurationManager = new \TYPO3\CMS\Core\Configuration\ConfigurationManager(); + $GLOBALS['TYPO3_CONF_VARS'] = $configurationManager->getDefaultConfiguration(); + + $cache = new \TYPO3\CMS\Core\Cache\Frontend\PhpFrontend( + 'core', + new \TYPO3\CMS\Core\Cache\Backend\NullBackend('production', []) + ); + + // Set all packages to active + if (interface_exists(\TYPO3\CMS\Core\Package\Cache\PackageCacheInterface::class)) { + $packageManager = \TYPO3\CMS\Core\Core\Bootstrap::createPackageManager( + \TYPO3\CMS\Core\Package\UnitTestPackageManager::class, + \TYPO3\CMS\Core\Core\Bootstrap::createPackageCache($cache) + ); + } else { + // v10 compatibility layer + $packageManager = \TYPO3\CMS\Core\Core\Bootstrap::createPackageManager( + \TYPO3\CMS\Core\Package\UnitTestPackageManager::class, + $cache + ); + } + + \TYPO3\CMS\Core\Utility\GeneralUtility::setSingletonInstance(\TYPO3\CMS\Core\Package\PackageManager::class, $packageManager); + \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::setPackageManager($packageManager); + + $testbase->dumpClassLoadingInformation(); + + \TYPO3\CMS\Core\Utility\GeneralUtility::purgeInstances(); +}); diff --git a/Build/Test/bootstrap.sh b/Build/Test/bootstrap.sh index dcbcb09ef..af31cb9be 100755 --- a/Build/Test/bootstrap.sh +++ b/Build/Test/bootstrap.sh @@ -1,7 +1,11 @@ #!/usr/bin/env bash -SCRIPTPATH=$( cd $(dirname $0) ; pwd -P ) -EXTENSION_ROOTPATH="$SCRIPTPATH/../../" +if [[ -n ${BASH_SOURCE[0]} ]]; then + SCRIPT_PATH=$( cd $(dirname "${BASH_SOURCE[0]}") ; pwd -P ) +else + SCRIPT_PATH=$( cd $(dirname "$0") ; pwd -P ) +fi +EXTENSION_ROOT_PATH="$SCRIPT_PATH/../../" TIKA_SERVER_SOURCE="https://archive.apache.org/dist/tika/" # @@ -10,50 +14,55 @@ TIKA_SERVER_SOURCE="https://archive.apache.org/dist/tika/" # if [[ $* == *--local* ]]; then - echo -n "Choose a TYPO3 Version (e.g. dev-master, ^10.4.20): " - read typo3Version + echo -n "Choose a TYPO3 Version (e.g. dev-main, ^11.5): " + read -r typo3Version export TYPO3_VERSION=$typo3Version - echo -n "Choose a EXT:solr Version (e.g. dev-master, dev-release-11.1.x): " - read extSolrVersion + echo -n "Choose a EXT:solr Version (e.g. dev-main, dev-release-11.5.x): " + read -r extSolrVersion export EXT_SOLR_VERSION=$extSolrVersion echo -n "Choose a tika Version (e.g. 1.24.1): " - read tikaVersion + read -r tikaVersion export TIKA_VERSION=$tikaVersion echo -n "Choose a database hostname: " - read typo3DbHost + read -r typo3DbHost export TYPO3_DATABASE_HOST=$typo3DbHost echo -n "Choose a database name: " - read typo3DbName + read -r typo3DbName export TYPO3_DATABASE_NAME=$typo3DbName echo -n "Choose a database user: " - read typo3DbUser + read -r typo3DbUser export TYPO3_DATABASE_USERNAME=$typo3DbUser echo -n "Choose a database password: " - read typo3DbPassword + read -r typo3DbPassword export TYPO3_DATABASE_PASSWORD=$typo3DbPassword fi test -n "$TIKA_PATH" || TIKA_PATH="$HOME/bin" - -if [ -z $TIKA_VERSION ]; then +if [ -z "$TIKA_VERSION" ]; then echo "Must set env var TIKA_VERSION" exit 1 fi -if [ -z $TYPO3_VERSION ]; then +if [ -z "$TYPO3_VERSION" ]; then echo "Must set env var TYPO3_VERSION" exit 1 fi -wget --version > /dev/null 2>&1 -if [ $? -ne "0" ]; then +if [ -z "$EXT_SOLR_VERSION" ]; then + echo "Must set env var EXT_SOLR_VERSION" + exit 1 +fi + + +if ! wget --version > /dev/null 2>&1 +then echo "Couldn't find wget." exit 1 fi @@ -88,36 +97,44 @@ if [[ $* != *--skip-tika-server-install* ]]; then # stop Tika server if one is still running if [ -f ./tika_pid ]; then - TIKA_PID=cat ./tika_pid + TIKA_PID=$(cat ./tika_pid) echo "Stopping Tika ($TIKA_PID)" - kill $TIKA_PID + kill "$TIKA_PID" fi # start tika server echo "Starting Apache Tika" - TIKA_PID=`nohup java -jar "$TIKA_PATH/tika-server-$TIKA_VERSION.jar" > /dev/null 2>&1 & echo $!` - echo $TIKA_PID > tika_pid + TIKA_PID=$(nohup java -jar "$TIKA_PATH/tika-server-$TIKA_VERSION.jar" > /dev/null 2>&1 & echo $!) + echo "$TIKA_PID" > tika_pid echo "Tika pid: $TIKA_PID" fi echo "PWD: $(pwd)" -export TYPO3_PATH_PACKAGES="${EXTENSION_ROOTPATH}.Build/vendor/" -export TYPO3_PATH_WEB="${EXTENSION_ROOTPATH}.Build/Web/" +export TYPO3_PATH_PACKAGES="${EXTENSION_ROOT_PATH}.Build/vendor/" +export TYPO3_PATH_WEB="${EXTENSION_ROOT_PATH}.Build/Web/" -echo "Using extension path $EXTENSION_ROOTPATH" +echo "Using extension path $EXTENSION_ROOT_PATH" echo "Using package path $TYPO3_PATH_PACKAGES" echo "Using web path $TYPO3_PATH_WEB" -if [[ $TYPO3_VERSION = *"dev"* ]]; then - composer config minimum-stability dev +# shellcheck disable=SC2034 +export COMPOSER_NO_INTERACTION=1 +# Install build tools +echo "Install build tools: " +if ! composer global require \ + sclable/xml-lint \ + scrutinizer/ocular +then + echo "The build tools(friendsofphp/php-cs-fixer, sclable/xml-lint, scrutinizer/ocular) could not be installed. Please fix this issue." + exit 1 fi -if [[ $TYPO3_VERSION = *"master"* ]]; then - TYPO3_MASTER_DEPENDENCIES='nimut/testing-framework:dev-master' +if [[ $TYPO3_VERSION = *"dev"* ]]; then + composer config minimum-stability dev fi -composer require --dev --update-with-dependencies --prefer-source \ +if ! composer require --dev --update-with-dependencies --prefer-source \ typo3/cms-core:"$TYPO3_VERSION" \ typo3/cms-backend:"$TYPO3_VERSION" \ typo3/cms-fluid:"$TYPO3_VERSION" \ @@ -126,14 +143,18 @@ composer require --dev --update-with-dependencies --prefer-source \ typo3/cms-reports:"$TYPO3_VERSION" \ typo3/cms-scheduler:"$TYPO3_VERSION" \ apache-solr-for-typo3/solr:"$EXT_SOLR_VERSION" \ - typo3/cms-tstemplate:"$TYPO3_VERSION" $TYPO3_MASTER_DEPENDENCIES + typo3/cms-tstemplate:"$TYPO3_VERSION" +then + echo "The test environment could not be installed by composer as expected. Please fix this issue." + exit 1 +fi export TYPO3_PATH_WEB=$PWD/.Build/Web -mkdir -p $TYPO3_PATH_WEB/uploads $TYPO3_PATH_WEB/typo3temp +mkdir -p "$TYPO3_PATH_WEB"/uploads "$TYPO3_PATH_WEB"/typo3temp # Setup Solr using install script if [[ $* != *--skip-solr-install* ]]; then - chmod u+x ${TYPO3_PATH_WEB}/typo3conf/ext/solr/Resources/Private/Install/install-solr.sh - ${TYPO3_PATH_WEB}/typo3conf/ext/solr/Resources/Private/Install/install-solr.sh -d "$HOME/solr" -t + chmod u+x "$TYPO3_PATH_WEB"/typo3conf/ext/solr/Resources/Private/Install/install-solr.sh + "$TYPO3_PATH_WEB"/typo3conf/ext/solr/Resources/Private/Install/install-solr.sh -d "$HOME/solr" -t fi diff --git a/Build/Test/cibuild.sh b/Build/Test/cibuild.sh index 71827a769..727d96f55 100755 --- a/Build/Test/cibuild.sh +++ b/Build/Test/cibuild.sh @@ -1,50 +1,111 @@ #!/usr/bin/env bash +test -n "$TIKA_PATH" || export TIKA_PATH="$HOME/bin" + +TYPO3_PATH_WEB=$(pwd)/.Build/Web +export TYPO3_PATH_WEB + +COMPOSERS_BIN_DIR="$(composer config home)/vendor/bin" +# Add composer's bin dir to $PATH, if not present +## Note: That is not https://getcomposer.org/doc/03-cli.md#composer-bin-dir +## avoid collisions on that. +if [[ $PATH != *"$COMPOSERS_BIN_DIR"* ]]; then + export PATH="$COMPOSERS_BIN_DIR:$PATH" +fi + echo "PWD: $(pwd)" +echo "composer's bin dir: $COMPOSERS_BIN_DIR" +echo "PATH: $PATH" -test -n "$TIKA_PATH" || export TIKA_PATH="$HOME/bin" +echo "Run PHP Lint" +if ! find . -name \*.php ! -path "./Tests/Unit/ExecMockFunctions.php" ! -path "./.Build/*" 2>/dev/null | \ + parallel --gnu php -d display_errors=stderr -l {} > /dev/null +then + echo "There are syntax errors, please check and fix them." + exit 1 +else + echo "No syntax errors! Great job!" +fi +echo -e "\n\n" -export TYPO3_PATH_WEB=$(pwd)/.Build/Web +echo "Check compliance against TYPO3 Coding Standards" +if ! .Build/bin/php-cs-fixer --version > /dev/null 2>&1 +then + echo "TYPO3 https://github.com/TYPO3/coding-standards is not set properly." + echo "Please fix that asap to avoid unwanted changes in the future." + exit 1 +else + echo "TYPO3 Coding Standards compliance: See https://github.com/TYPO3/coding-standards" + if ! composer exec php-cs-fixer fix -- --diff --verbose --dry-run + then + echo "Some files are not compliant to TYPO3 Coding Standards" + echo "Please fix the files listed above." + echo "Tip for auto fix: " + echo " composer install && composer exec php-cs-fixer fix" + exit 1 + else + echo "The code is TYPO3 Coding Standards compliant! Great job!" + fi +fi +echo -e "\n\n" -UNIT_BOOTSTRAP=".Build/vendor/nimut/testing-framework/res/Configuration/UnitTestsBootstrap.php" -.Build/bin/phpunit --colors -c Build/Test/UnitTests.xml --bootstrap=$UNIT_BOOTSTRAP --coverage-clover=coverage.unit.clover +echo "Run XML Lint" +if ! xmllint --version > /dev/null 2>&1; then + echo "XML Lint not found, skipping XML linting." +else + echo "Check syntax of XML files" + if ! xmllint Resources/Private/Language/ -p '*.xlf' + then + echo "Some XML files are not valid" + echo "Please fix the files listed above" + exit 1 + fi +fi +echo -e "\n\n" -if [ $? -ne "0" ]; then +echo "Run unit tests" +if ! .Build/bin/phpunit --colors -c Build/Test/UnitTests.xml --bootstrap=Build/Test/UnitTestsBootstrap.php --coverage-clover=coverage.unit.clover +then echo "Error during running the unit tests please check and fix them" exit 1 fi +echo -e "\n\n" # # Map the travis and shell variable names to the expected # casing of the TYPO3 core. # -if [ -n $TYPO3_DATABASE_NAME ]; then +if [[ -n $TYPO3_DATABASE_NAME ]]; then export typo3DatabaseName=$TYPO3_DATABASE_NAME else echo "No environment variable TYPO3_DATABASE_NAME set. Please set it to run the integration tests." exit 1 fi -if [ -n $TYPO3_DATABASE_HOST ]; then +if [[ -n $TYPO3_DATABASE_HOST ]]; then export typo3DatabaseHost=$TYPO3_DATABASE_HOST else echo "No environment variable TYPO3_DATABASE_HOST set. Please set it to run the integration tests." exit 1 fi -if [ -n $TYPO3_DATABASE_USERNAME ]; then +if [[ -n $TYPO3_DATABASE_USERNAME ]]; then export typo3DatabaseUsername=$TYPO3_DATABASE_USERNAME else echo "No environment variable TYPO3_DATABASE_USERNAME set. Please set it to run the integration tests." exit 1 fi -if [ -n $TYPO3_DATABASE_PASSWORD ]; then +if [[ -n $TYPO3_DATABASE_PASSWORD ]]; then export typo3DatabasePassword=$TYPO3_DATABASE_PASSWORD else echo "No environment variable TYPO3_DATABASE_PASSWORD set. Please set it to run the integration tests." exit 1 fi -INTEGRATION_BOOTSTRAP=".Build/vendor/nimut/testing-framework/res/Configuration/FunctionalTestsBootstrap.php" -.Build/bin/phpunit --colors -c Build/Test/IntegrationTests.xml --bootstrap=$INTEGRATION_BOOTSTRAP --coverage-clover=coverage.integration.clover +echo "Run integration tests" +if ! .Build/bin/phpunit --colors -c Build/Test/IntegrationTests.xml --bootstrap=Build/Test/IntegrationTestsBootstrap.php --coverage-clover=coverage.integration.clover +then + echo "Error during running the integration tests please check and fix them" + exit 1 +fi diff --git a/Classes/ContextMenu/Preview.php b/Classes/ContextMenu/Preview.php index 9220c7d63..271c22618 100644 --- a/Classes/ContextMenu/Preview.php +++ b/Classes/ContextMenu/Preview.php @@ -1,9 +1,24 @@ isAdmin()) { + if (empty($GLOBALS['BE_USER']) || !$GLOBALS['BE_USER']->isAdmin()) { return false; } diff --git a/Classes/Controller/Backend/PreviewController.php b/Classes/Controller/Backend/PreviewController.php index f5d7c553a..c6a5d9876 100644 --- a/Classes/Controller/Backend/PreviewController.php +++ b/Classes/Controller/Backend/PreviewController.php @@ -1,20 +1,34 @@ detectLanguageFromFile($file); - } catch (Exception $e) { + } catch (Throwable $e) { $language = 'not detectable'; } @@ -80,7 +94,6 @@ protected function getFileResourceFactory(): ResourceFactory /** * @return StandaloneView - * @throws InvalidExtensionNameException */ protected function getInitializedPreviewView(): StandaloneView { @@ -95,8 +108,8 @@ protected function getInitializedPreviewView(): StandaloneView /** * @return bool */ - protected function getIsAdmin() + protected function getIsAdmin(): bool { - return (bool)$GLOBALS['BE_USER']->isAdmin(); + return !empty($GLOBALS['BE_USER']) && $GLOBALS['BE_USER']->isAdmin(); } } diff --git a/Classes/Controller/Backend/SolrModule/TikaControlPanelModuleController.php b/Classes/Controller/Backend/SolrModule/TikaControlPanelModuleController.php index f4308a47e..1ce1f136a 100644 --- a/Classes/Controller/Backend/SolrModule/TikaControlPanelModuleController.php +++ b/Classes/Controller/Backend/SolrModule/TikaControlPanelModuleController.php @@ -1,30 +1,21 @@ - * 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. +/* + * This file is part of the TYPO3 CMS project. * - * The GNU General Public License can be found at - * http://www.gnu.org/copyleft/gpl.html. + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. * - * 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. + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. * - * This copyright notice MUST APPEAR in all copies of the script! - ***************************************************************/ + * The TYPO3 project - inspiring people to share! + */ use ApacheSolrForTypo3\Solr\Controller\Backend\Search\AbstractModuleController; use ApacheSolrForTypo3\Tika\Service\Tika\AbstractService; @@ -33,11 +24,13 @@ use ApacheSolrForTypo3\Tika\Service\Tika\ServiceFactory; use ApacheSolrForTypo3\Tika\Service\Tika\SolrCellService; use ApacheSolrForTypo3\Tika\Util; -use Exception; +use Psr\Http\Client\ClientExceptionInterface; +use Psr\Http\Message\ResponseInterface; +use TYPO3\CMS\Backend\Template\ModuleTemplate; +use TYPO3\CMS\Core\Http\RedirectResponse; use TYPO3\CMS\Core\Messaging\FlashMessage; use TYPO3\CMS\Core\Utility\GeneralUtility; -use TYPO3\CMS\Extbase\Mvc\Exception\StopActionException; -use TYPO3\CMS\Extbase\Mvc\View\ViewInterface; +use TYPO3Fluid\Fluid\View\ViewInterface; /** * Tika Control Panel @@ -52,7 +45,7 @@ class TikaControlPanelModuleController extends AbstractModuleController * * @var array */ - protected $tikaConfiguration = []; + protected array $tikaConfiguration = []; /** * @var AppService|ServerService|SolrCellService @@ -60,7 +53,9 @@ class TikaControlPanelModuleController extends AbstractModuleController protected $tikaService; /** - * Can be used in the test context to force a view. + * Can be used in the test context to mock a {@link view}. + * + * Purpose: PhpUnit * * @param ViewInterface $view */ @@ -69,6 +64,18 @@ public function overwriteView(ViewInterface $view): void $this->view = $view; } + /** + * Can be used in the test context to mock a {@link moduleTemplate}. + * + * Purpose: PhpUnit + * + * @param ModuleTemplate $moduleTemplate + */ + public function overwriteModuleTemplate(ModuleTemplate $moduleTemplate): void + { + $this->moduleTemplate = $moduleTemplate; + } + /** * @param AbstractService $tikaService */ @@ -79,14 +86,14 @@ public function setTikaService(AbstractService $tikaService): void /** * Initializes resources commonly needed for several actions. + * @noinspection PhpUnused */ protected function initializeAction(): void { parent::initializeAction(); - $tikaConfiguration = Util::getTikaExtensionConfiguration(); $this->setTikaConfiguration($tikaConfiguration); - $this->tikaService = ServiceFactory::getTika($this->tikaConfiguration['extractor']); + $this->tikaService = ServiceFactory::getTika($this->tikaConfiguration['extractor'] ?? ''); } /** @@ -100,17 +107,18 @@ public function setTikaConfiguration(array $tikaConfiguration): void /** * Index action * - * @throws Exception + * @return ResponseInterface + * @throws ClientExceptionInterface */ - public function indexAction() + public function indexAction(): ResponseInterface { $this->view->assign('configuration', $this->tikaConfiguration); $this->view->assign( 'extractor', - ucfirst($this->tikaConfiguration['extractor']) + ucfirst($this->tikaConfiguration['extractor'] ?? '') ); - if ($this->tikaConfiguration['extractor'] == 'server') { + if ($this->tikaConfiguration['extractor'] === 'server') { $this->checkTikaServerConnection(); $this->view->assign( @@ -129,10 +137,9 @@ public function indexAction() /** * Starts the Tika server - * - * @throws StopActionException + * @noinspection PhpUnused */ - public function startServerAction(): void + public function startServerAction(): ResponseInterface { $this->tikaService->/** @scrutinizer ignore-call */startServer(); @@ -146,15 +153,14 @@ public function startServerAction(): void ); } - $this->redirect('index'); + return new RedirectResponse($this->uriBuilder->uriFor('index'), 303); } /** * Stops the Tika server - * - * @throws StopActionException + * @noinspection PhpUnused */ - public function stopServerAction(): void + public function stopServerAction(): ResponseInterface { $this->tikaService->/** @scrutinizer ignore-call */stopServer(); @@ -168,16 +174,16 @@ public function stopServerAction(): void ); } - $this->redirect('index'); + return new RedirectResponse($this->uriBuilder->uriFor('index'), 303); } /** * Gets the Tika server version * * @return string Tika server version string - * @throws Exception + * @throws ClientExceptionInterface */ - protected function getTikaServerVersion() + protected function getTikaServerVersion(): string { return $this->tikaService->getTikaVersion(); } @@ -186,9 +192,8 @@ protected function getTikaServerVersion() * Tries to connect to Tika server * * @return bool TRUE if the Tika server responds, FALSE otherwise. - * @throws Exception */ - protected function isTikaServerRunning() + protected function isTikaServerRunning(): bool { return $this->tikaService->isServerRunning(); } @@ -199,7 +204,7 @@ protected function isTikaServerRunning() * * @return int|null Tika Server pid or null if not found */ - protected function getTikaServerPid() + protected function getTikaServerPid(): ?int { return $this->tikaService->/** @scrutinizer ignore-call */getServerPid(); } @@ -207,14 +212,14 @@ protected function getTikaServerPid() /** * Checks whether the server jar has been configured properly. * - * @return bool TRUE if a path for the jar has been configure and the path exists + * @return bool TRUE if a path for the jar has been configured and the path exists */ - protected function isTikaServerJarAvailable() + protected function isTikaServerJarAvailable(): bool { - $serverJarSet = !empty($this->tikaConfiguration['tikaServerPath']); - $serverJarExists = file_exists($this->tikaConfiguration['tikaServerPath']); - - return $serverJarSet && $serverJarExists; + if (!empty($this->tikaConfiguration['tikaServerPath'])) { + return file_exists($this->tikaConfiguration['tikaServerPath']); + } + return false; } /** @@ -223,7 +228,6 @@ protected function isTikaServerJarAvailable() * Checks whether exec() is allowed and whether configuration is available. * * @return bool TRUE if Tika server can be started/stopped - * @throws Exception */ protected function isTikaServerControllable(): bool { @@ -258,8 +262,6 @@ protected function isTikaServerControllable(): bool /** * Checks whether the configured Tika server can be reached and provides a * flash message according to the result of the check. - * - * @throws Exception */ protected function checkTikaServerConnection(): void { diff --git a/Classes/Hooks/BackendControllerHook.php b/Classes/Hooks/BackendControllerHook.php index 5da24704e..316d7d894 100644 --- a/Classes/Hooks/BackendControllerHook.php +++ b/Classes/Hooks/BackendControllerHook.php @@ -1,8 +1,22 @@ - * 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. +/* + * This file is part of the TYPO3 CMS project. * - * The GNU General Public License can be found at - * http://www.gnu.org/copyleft/gpl.html. + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. * - * 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. + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. * - * This copyright notice MUST APPEAR in all copies of the script! - ***************************************************************/ + * The TYPO3 project - inspiring people to share! + */ /** * Run, check, and stop external processes. Linux only. + * @author Ingo Renner */ class Process { @@ -37,21 +29,21 @@ class Process * * @var int|null */ - protected $pid; + protected ?int $pid = null; /** * Executable running the command * * @var string */ - protected $executable; + protected string $executable; /** * Executable arguments * * @var string */ - protected $arguments; + protected string $arguments; /** * Constructor @@ -59,9 +51,9 @@ class Process * @param string $executable * @param string $arguments */ - public function __construct($executable, $arguments = '') + public function __construct(string $executable, string $arguments = '') { - $this->executable = (string)$executable; + $this->executable = $executable; $this->arguments = $arguments; } @@ -70,7 +62,7 @@ public function __construct($executable, $arguments = '') * * @return string */ - public function getArguments() + public function getArguments(): string { return $this->arguments; } @@ -78,9 +70,9 @@ public function getArguments() /** * Arguments setter * - * @param $arguments + * @param string $arguments */ - public function setArguments($arguments): void + public function setArguments(string $arguments): void { $this->arguments = $arguments; } @@ -90,7 +82,7 @@ public function setArguments($arguments): void * * @return string */ - public function getExecutable() + public function getExecutable(): string { return $this->executable; } @@ -98,9 +90,9 @@ public function getExecutable() /** * Gets the process ID * - * @return int process ID + * @return int|null process ID */ - public function getPid() + public function getPid(): ?int { return $this->pid; } @@ -110,9 +102,9 @@ public function getPid() * * @param int $pid */ - public function setPid($pid): void + public function setPid(int $pid): void { - $this->pid = (int)$pid; + $this->pid = $pid; } /** @@ -120,7 +112,7 @@ public function setPid($pid): void * * @return int|null Null if the pid can't be found, otherwise the pid */ - public function findPid() + public function findPid(): ?int { $processCommand = $this->executable; if (!empty($this->arguments)) { @@ -146,10 +138,10 @@ public function findPid() * Escapes 'ps' command output to match what we expect to get as arguments * when executing a command. * - * @param $command + * @param string $command * @return string */ - protected function escapePsOutputCommand($command) + protected function escapePsOutputCommand(string $command): string { $command = explode(' ', $command); @@ -172,7 +164,7 @@ protected function escapePsOutputCommand($command) * * @return bool TRUE if the process could be started, FALSE otherwise */ - public function start() + public function start(): bool { $this->runCommand(); return $this->isRunning(); @@ -200,7 +192,7 @@ protected function runCommand(): void * * @return bool TRUE if the process is running, FALSE otherwise */ - public function isRunning() + public function isRunning(): bool { if (is_null($this->pid)) { return false; @@ -224,10 +216,8 @@ public function isRunning() * * @return bool */ - public function stop() + public function stop(): bool { - $stopped = null; - $command = 'kill ' . $this->pid; exec($command); diff --git a/Classes/Report/TikaStatus.php b/Classes/Report/TikaStatus.php index 98b52919e..3c3199dd4 100644 --- a/Classes/Report/TikaStatus.php +++ b/Classes/Report/TikaStatus.php @@ -1,6 +1,7 @@ priority; } @@ -99,7 +100,7 @@ public function getPriority() * * @return int */ - public function getExecutionPriority() + public function getExecutionPriority(): int { return $this->priority; } diff --git a/Classes/Service/Extractor/LanguageDetector.php b/Classes/Service/Extractor/LanguageDetector.php index f8d248915..b37fa911f 100644 --- a/Classes/Service/Extractor/LanguageDetector.php +++ b/Classes/Service/Extractor/LanguageDetector.php @@ -1,33 +1,26 @@ - * 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. +/* + * This file is part of the TYPO3 CMS project. * - * The GNU General Public License can be found at - * http://www.gnu.org/copyleft/gpl.html. + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. * - * 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. + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. * - * This copyright notice MUST APPEAR in all copies of the script! - ***************************************************************/ + * The TYPO3 project - inspiring people to share! + */ use ApacheSolrForTypo3\Tika\Service\Tika\ServiceFactory; -use Exception; +use Psr\Http\Client\ClientExceptionInterface; +use TYPO3\CMS\Core\Configuration\Exception\ExtensionConfigurationExtensionNotConfiguredException; +use TYPO3\CMS\Core\Configuration\Exception\ExtensionConfigurationPathDoesNotExistException; use TYPO3\CMS\Core\Resource\File; /** @@ -37,7 +30,7 @@ */ class LanguageDetector extends AbstractExtractor { - protected $supportedFileTypes = [ + protected array $supportedFileTypes = [ 'doc', 'docx', 'epub', @@ -59,7 +52,7 @@ class LanguageDetector extends AbstractExtractor /** * @var int */ - protected $priority = 98; + protected int $priority = 98; /** * Checks if the given file can be processed by this Extractor @@ -67,7 +60,7 @@ class LanguageDetector extends AbstractExtractor * @param File $file * @return bool */ - public function canProcess(File $file) + public function canProcess(File $file): bool { $isSupportedFileType = in_array($file->getProperty('extension'), $this->supportedFileTypes); $isSizeBelowLimit = $this->fileSizeValidator->isBelowLimit($file); @@ -81,12 +74,15 @@ public function canProcess(File $file) * @param File $file * @param array $previousExtractedData Already extracted/existing data * @return array - * @throws Exception + * + * @throws ClientExceptionInterface + * @throws ExtensionConfigurationExtensionNotConfiguredException + * @throws ExtensionConfigurationPathDoesNotExistException */ public function extractMetaData( File $file, array $previousExtractedData = [] - ) { + ): array { $metaData = []; $tika = ServiceFactory::getTika($this->configuration['extractor']); diff --git a/Classes/Service/Extractor/MetaDataExtractor.php b/Classes/Service/Extractor/MetaDataExtractor.php index 08f276380..9cfac36c0 100644 --- a/Classes/Service/Extractor/MetaDataExtractor.php +++ b/Classes/Service/Extractor/MetaDataExtractor.php @@ -1,41 +1,35 @@ - * 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. +/* + * This file is part of the TYPO3 CMS project. * - * The GNU General Public License can be found at - * http://www.gnu.org/copyleft/gpl.html. + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. * - * 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. + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. * - * This copyright notice MUST APPEAR in all copies of the script! - ***************************************************************/ + * The TYPO3 project - inspiring people to share! + */ use ApacheSolrForTypo3\Tika\Service\Tika\AppService; use ApacheSolrForTypo3\Tika\Service\Tika\ServerService; use ApacheSolrForTypo3\Tika\Service\Tika\ServiceFactory; use ApacheSolrForTypo3\Tika\Service\Tika\SolrCellService; -use Exception; +use Psr\Http\Client\ClientExceptionInterface; +use TYPO3\CMS\Core\Configuration\Exception\ExtensionConfigurationExtensionNotConfiguredException; +use TYPO3\CMS\Core\Configuration\Exception\ExtensionConfigurationPathDoesNotExistException; use TYPO3\CMS\Core\Resource\File; +use TYPO3\CMS\Core\Resource\FileInterface; use TYPO3\CMS\Core\Utility\GeneralUtility; /** - * A service to extract meta data from files using Apache Tika + * A service to extract meta-data from files using Apache Tika * * @author Ingo Renner */ @@ -44,16 +38,18 @@ class MetaDataExtractor extends AbstractExtractor /** * @var int */ - protected $priority = 100; + protected int $priority = 100; /** * Checks if the given file can be processed by this Extractor * * @param File $file * @return bool - * @throws Exception + * @throws ClientExceptionInterface + * @throws ExtensionConfigurationExtensionNotConfiguredException + * @throws ExtensionConfigurationPathDoesNotExistException */ - public function canProcess(File $file) + public function canProcess(File $file): bool { $tikaService = $this->getExtractor(); $mimeTypes = $tikaService->getSupportedMimeTypes(); @@ -72,7 +68,7 @@ public function canProcess(File $file) * @param array $mimeTypes * @return array */ - protected function mergeAllowedMimeTypes($mimeTypes) + protected function mergeAllowedMimeTypes(array $mimeTypes): array { if (empty($this->configuration['excludeMimeTypes'])) { return $mimeTypes; @@ -85,6 +81,8 @@ protected function mergeAllowedMimeTypes($mimeTypes) /** * @return AppService|ServerService|SolrCellService + * @throws ExtensionConfigurationExtensionNotConfiguredException + * @throws ExtensionConfigurationPathDoesNotExistException */ protected function getExtractor() { @@ -92,14 +90,14 @@ protected function getExtractor() } /** - * Extracts meta data from a file using Apache Tika + * Extracts meta-data from a file using Apache Tika * * @param File $file * @param array $previousExtractedData Already extracted/existing data * @return array - * @throws Exception + * @throws ClientExceptionInterface */ - public function extractMetaData(File $file, array $previousExtractedData = []) + public function extractMetaData(File $file, array $previousExtractedData = []): array { $extractedMetaData = $this->getExtractedMetaDataFromTikaService($file); return $this->normalizeMetaData($extractedMetaData); @@ -108,23 +106,25 @@ public function extractMetaData(File $file, array $previousExtractedData = []) /** * Creates an instance of the service and returns the result from "extractMetaData". * - * @param File $file + * @param FileInterface $file * @return array - * @throws Exception + * @throws ClientExceptionInterface + * @throws ExtensionConfigurationExtensionNotConfiguredException + * @throws ExtensionConfigurationPathDoesNotExistException */ - protected function getExtractedMetaDataFromTikaService($file) + protected function getExtractedMetaDataFromTikaService(FileInterface $file): array { $tikaService = $this->getExtractor(); return $tikaService->extractMetaData($file); } /** - * Normalizes the names / keys of the meta data found. + * Normalizes the names / keys of the meta-data found. * - * @param array $metaData An array of raw meta data from a file - * @return array An array with cleaned meta data keys + * @param array $metaData An array of raw meta-data from a file + * @return array An array with cleaned meta-data keys */ - protected function normalizeMetaData(array $metaData) + protected function normalizeMetaData(array $metaData): array { $metaDataCleaned = []; @@ -220,19 +220,17 @@ protected function normalizeMetaData(array $metaData) /** * Converts a date string into timestamp - * exiftags: 2002:09:07 15:29:52 + * exif-tags: 2002:09:07 15:29:52 * * @param string $date An exif date string * @return int Unix timestamp */ - protected function exifDateToTimestamp($date) + protected function exifDateToTimestamp(string $date): int { - if (is_string($date)) { - if (($timestamp = strtotime($date)) === -1) { - $date = 0; - } else { - $date = $timestamp; - } + if (($timestamp = strtotime($date)) === -1) { + $date = 0; + } else { + $date = $timestamp; } return $date; diff --git a/Classes/Service/Extractor/TextExtractor.php b/Classes/Service/Extractor/TextExtractor.php index 6dd77656f..8874a4eb2 100644 --- a/Classes/Service/Extractor/TextExtractor.php +++ b/Classes/Service/Extractor/TextExtractor.php @@ -1,35 +1,28 @@ - * 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. +/* + * This file is part of the TYPO3 CMS project. * - * The GNU General Public License can be found at - * http://www.gnu.org/copyleft/gpl.html. + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. * - * 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. + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. * - * This copyright notice MUST APPEAR in all copies of the script! - ***************************************************************/ + * The TYPO3 project - inspiring people to share! + */ use ApacheSolrForTypo3\Tika\Service\File\SizeValidator; use ApacheSolrForTypo3\Tika\Service\Tika\ServiceFactory; use ApacheSolrForTypo3\Tika\Util; -use Exception; +use Psr\Http\Client\ClientExceptionInterface; +use TYPO3\CMS\Core\Configuration\Exception\ExtensionConfigurationExtensionNotConfiguredException; +use TYPO3\CMS\Core\Configuration\Exception\ExtensionConfigurationPathDoesNotExistException; use TYPO3\CMS\Core\Resource\FileInterface; use TYPO3\CMS\Core\Resource\TextExtraction\TextExtractorInterface; use TYPO3\CMS\Core\Utility\GeneralUtility; @@ -45,7 +38,7 @@ class TextExtractor implements TextExtractorInterface /** * @var array */ - protected $configuration; + protected array $configuration; /** * Supported file types (by extension) @@ -53,7 +46,7 @@ class TextExtractor implements TextExtractorInterface * * @var array */ - protected $supportedFileTypes = [ + protected array $supportedFileTypes = [ 'doc', 'docx', 'epub', @@ -93,7 +86,7 @@ public function __construct() * @param FileInterface $file * @return bool */ - public function canExtractText(FileInterface $file) + public function canExtractText(FileInterface $file): bool { $isSupportedFileExtension = in_array($file->getExtension(), $this->supportedFileTypes); $isSizeBelowLimit = $this->fileSizeValidator->isBelowLimit($file); @@ -106,15 +99,13 @@ public function canExtractText(FileInterface $file) * * @param FileInterface $file * @return string Text extracted from the input file - * @throws Exception + * @throws ClientExceptionInterface + * @throws ExtensionConfigurationExtensionNotConfiguredException + * @throws ExtensionConfigurationPathDoesNotExistException */ - public function extractText(FileInterface $file) + public function extractText(FileInterface $file): string { - $extractedContent = null; - $tika = ServiceFactory::getTika($this->configuration['extractor']); - $extractedContent = $tika->extractText($file); - - return $extractedContent; + return $tika->extractText($file); } } diff --git a/Classes/Service/File/SizeValidator.php b/Classes/Service/File/SizeValidator.php index 6fb424d24..d6e8db756 100644 --- a/Classes/Service/File/SizeValidator.php +++ b/Classes/Service/File/SizeValidator.php @@ -4,34 +4,26 @@ namespace ApacheSolrForTypo3\Tika\Service\File; -use ApacheSolrForTypo3\Tika\Util; -use TYPO3\CMS\Core\Resource\FileInterface; - -/*************************************************************** - * Copyright notice - * - * (c) 2017 Timo Hund - * 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. +/* + * This file is part of the TYPO3 CMS project. * - * The GNU General Public License can be found at - * http://www.gnu.org/copyleft/gpl.html. + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. * - * 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. + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. * - * This copyright notice MUST APPEAR in all copies of the script! - ***************************************************************/ + * The TYPO3 project - inspiring people to share! + */ + +use ApacheSolrForTypo3\Tika\Util; +use TYPO3\CMS\Core\Resource\FileInterface; /** * Class SizeValidator + * + * @author Timo Hund */ class SizeValidator { @@ -39,7 +31,7 @@ class SizeValidator /** * @var array */ - protected $configuration; + protected array $configuration; /** * Constructor @@ -79,7 +71,7 @@ protected function getFileSizeLimit() * @param mixed $defaultValue * @return mixed */ - protected function getConfigurationOrDefaultValue($key, $defaultValue) + protected function getConfigurationOrDefaultValue(string $key, $defaultValue) { return $this->configuration[$key] ?? $defaultValue; } diff --git a/Classes/Service/Tika/AbstractService.php b/Classes/Service/Tika/AbstractService.php index f09f4f167..9defdcfda 100644 --- a/Classes/Service/Tika/AbstractService.php +++ b/Classes/Service/Tika/AbstractService.php @@ -1,6 +1,7 @@ configuration['logging']) { + if (empty($this->configuration['logging'])) { return; } $this->logger->log( @@ -76,9 +77,9 @@ protected function log(string $message, array $data = [], $severity = LogLevel:: } /** - * @return mixed + * @return array */ - public function getSupportedMimeTypes() + public function getSupportedMimeTypes(): array { return []; } diff --git a/Classes/Service/Tika/AppService.php b/Classes/Service/Tika/AppService.php index 0c000d755..52e3a48d2 100644 --- a/Classes/Service/Tika/AppService.php +++ b/Classes/Service/Tika/AppService.php @@ -1,6 +1,7 @@ getForLocalProcessing(false); $tikaCommand = ShellUtility::getLanguagePrefix() @@ -97,16 +98,16 @@ public function extractText(FileInterface $file) ] ); - return $extractedText; + return (string)$extractedText; } /** - * Takes a file reference and extracts its meta data. + * Takes a file reference and extracts its meta-data. * * @param FileInterface $file * @return array */ - public function extractMetaData(FileInterface $file) + public function extractMetaData(FileInterface $file): array { $localTempFilePath = $file->getForLocalProcessing(false); $tikaCommand = ShellUtility::getLanguagePrefix() @@ -140,7 +141,7 @@ public function extractMetaData(FileInterface $file) * @param FileInterface $file * @return string Language ISO code */ - public function detectLanguageFromFile(FileInterface $file) + public function detectLanguageFromFile(FileInterface $file): string { $localTempFilePath = $file->getForLocalProcessing(false); @@ -153,7 +154,7 @@ public function detectLanguageFromFile(FileInterface $file) * @param string $input * @return string Language ISO code */ - public function detectLanguageFromString($input) + public function detectLanguageFromString(string $input): string { $tempFilePath = GeneralUtility::tempnam('Tx_Tika_AppService_DetectLanguage'); file_put_contents($tempFilePath, $input); @@ -173,7 +174,7 @@ public function detectLanguageFromString($input) * @param string $localFilePath Path to a local file * @return string The file content's language */ - protected function detectLanguageFromLocalFile($localFilePath) + protected function detectLanguageFromLocalFile(string $localFilePath): string { $tikaCommand = ShellUtility::getLanguagePrefix() . CommandUtility::getCommand('java') @@ -200,7 +201,7 @@ protected function detectLanguageFromLocalFile($localFilePath) /** * @return array */ - public function getSupportedMimeTypes() + public function getSupportedMimeTypes(): array { if (is_array(self::$supportedMimeTypes) && count(self::$supportedMimeTypes) > 0) { return self::$supportedMimeTypes; @@ -214,7 +215,7 @@ public function getSupportedMimeTypes() /** * @return array */ - public function buildSupportedMimeTypes() + public function buildSupportedMimeTypes(): array { $mimeTypeOutput = $this->getMimeTypeOutputFromTikaJar(); $coreTypes = []; @@ -240,7 +241,7 @@ public function buildSupportedMimeTypes() * @param array $shellOutput An array containing shell output from exec() with one line per entry * @return array Key => value pairs */ - protected function shellOutputToArray(array $shellOutput) + protected function shellOutputToArray(array $shellOutput): array { $metaData = []; @@ -293,7 +294,7 @@ protected function shellOutputToArray(array $shellOutput) * * @return bool */ - public function isAvailable() + public function isAvailable(): bool { $tikaFileExists = is_file(FileUtility::getAbsoluteFilePath($this->configuration['tikaPath'])); if (!$tikaFileExists) { diff --git a/Classes/Service/Tika/ServerService.php b/Classes/Service/Tika/ServerService.php index 595b6571e..cd5b40573 100644 --- a/Classes/Service/Tika/ServerService.php +++ b/Classes/Service/Tika/ServerService.php @@ -1,6 +1,7 @@ getAdditionalCommandOptions() . ' ' . $arguments); @@ -194,8 +195,8 @@ public function ping(): bool { try { $tikaPing = $this->queryTika($this->createRequestForEndpoint('/tika')); - return GeneralUtility::isFirstPartOfStr($tikaPing, 'This is Tika Server'); - } catch (ClientExceptionInterface | Exception $exception) { + return str_starts_with($tikaPing, 'This is Tika Server'); + } catch (Throwable $exception) { return false; } } @@ -204,7 +205,6 @@ public function ping(): bool * The tika server is available when the server is pingable. * * @return bool - * @throws Exception */ public function isAvailable(): bool { @@ -269,7 +269,7 @@ protected function queryTika(RequestInterface $request): string } $tikaOutput = $response->getBody()->getContents(); - } catch (ClientExceptionInterface | Exception $exception) { + } catch (Throwable $exception) { $message = $exception->getMessage(); if ( strpos($message, 'Connection refused') === false && @@ -299,7 +299,7 @@ public function extractText(FileInterface $file): string ->withAddedHeader('Content-Type', 'application/octet-stream') ->withAddedHeader('Accept', 'text/plain') ->withAddedHeader('Connection', 'close') - ->withProtocolVersion(1.1) + ->withProtocolVersion('1.1') ->withBody($this->convertFileIntoStream($file)); $response = $this->queryTika($request); @@ -324,16 +324,16 @@ public function extractText(FileInterface $file): string * Takes a file reference and extracts its meta data. * * @param FileInterface $file - * @return array|null + * @return array * @throws ClientExceptionInterface */ - public function extractMetaData(FileInterface $file): ?array + public function extractMetaData(FileInterface $file): array { $request = $this->createRequestForEndpoint('/meta', 'PUT') ->withAddedHeader('Content-Type', 'application/octet-stream') ->withAddedHeader('Accept', 'application/json') ->withAddedHeader('Connection', 'close') - ->withProtocolVersion(1.1) + ->withProtocolVersion('1.1') ->withBody($this->convertFileIntoStream($file)); $rawResponse = $this->queryTika($request); @@ -367,7 +367,7 @@ public function detectLanguageFromFile(FileInterface $file): string $request = $this->createRequestForEndpoint('/language/stream', 'PUT') ->withAddedHeader('Content-Type', 'application/octet-stream') ->withAddedHeader('Connection', 'close') - ->withProtocolVersion(1.1) + ->withProtocolVersion('1.1') ->withBody($this->convertFileIntoStream($file)); $response = $this->queryTika($request); @@ -395,14 +395,14 @@ public function detectLanguageFromFile(FileInterface $file): string * @return string * @throws ClientExceptionInterface */ - public function detectLanguageFromString($input): string + public function detectLanguageFromString(string $input): string { $stream = new Stream('php://temp', 'rw'); $stream->write($input); $request = $this->createRequestForEndpoint('/language/string', 'PUT') ->withAddedHeader('Content-Type', 'application/octet-stream') ->withAddedHeader('Connection', 'close') - ->withProtocolVersion(1.1) + ->withProtocolVersion('1.1') ->withBody($stream); return $this->queryTika($request); @@ -412,7 +412,7 @@ public function detectLanguageFromString($input): string * List of supported mime types * * @return array - * @throws Exception + * @throws ClientExceptionInterface */ public function getSupportedMimeTypes(): array { @@ -437,7 +437,7 @@ protected function getMimeTypeJsonFromTikaServer(): string ->withAddedHeader('Content-Type', 'application/octet-stream') ->withAddedHeader('Accept', 'application/json') ->withAddedHeader('Connection', 'close') - ->withProtocolVersion(1.1); + ->withProtocolVersion('1.1'); return $this->queryTika($request); } diff --git a/Classes/Service/Tika/ServiceFactory.php b/Classes/Service/Tika/ServiceFactory.php index b6413757d..1b2702f43 100644 --- a/Classes/Service/Tika/ServiceFactory.php +++ b/Classes/Service/Tika/ServiceFactory.php @@ -1,34 +1,26 @@ - * All rights reserved +/* + * This file is part of the TYPO3 CMS project. * - * 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. + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. * - * The GNU General Public License can be found at - * http://www.gnu.org/copyleft/gpl.html. + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. * - * 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! - ***************************************************************/ + * The TYPO3 project - inspiring people to share! + */ use ApacheSolrForTypo3\Tika\Util; use InvalidArgumentException; -use RuntimeException; +use TYPO3\CMS\Core\Configuration\Exception\ExtensionConfigurationExtensionNotConfiguredException; +use TYPO3\CMS\Core\Configuration\Exception\ExtensionConfigurationPathDoesNotExistException; use TYPO3\CMS\Core\Utility\GeneralUtility; /** @@ -43,14 +35,13 @@ class ServiceFactory * Creates an instance of a Tika service * * @param string $tikaServiceType Tika Service type, one of jar, server, or solr (or tika for BC, same as jar) - * @param array $configuration EXT:tika EM configuration (initialized by this factory, parameter exists for tests) + * @param array|null $configuration EXT:tika EM configuration (initialized by this factory, parameter exists for tests) * @return AppService|ServerService|SolrCellService * - * @throws InvalidArgumentException for unknown Tika service type - * @throws RuntimeException if configuration cannot be initialized - * @noinspection PhpIncompatibleReturnTypeInspection + * @throws ExtensionConfigurationExtensionNotConfiguredException + * @throws ExtensionConfigurationPathDoesNotExistException */ - public static function getTika($tikaServiceType, array $configuration = null) + public static function getTika(string $tikaServiceType, array $configuration = null) { if (empty($configuration)) { $configuration = Util::getTikaExtensionConfiguration(); diff --git a/Classes/Service/Tika/ServiceInterface.php b/Classes/Service/Tika/ServiceInterface.php index 6c18ff41b..a666d5ed1 100644 --- a/Classes/Service/Tika/ServiceInterface.php +++ b/Classes/Service/Tika/ServiceInterface.php @@ -1,46 +1,38 @@ - * All rights reserved +/* + * This file is part of the TYPO3 CMS project. * - * 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. + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. * - * The GNU General Public License can be found at - * http://www.gnu.org/copyleft/gpl.html. + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. * - * 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! - ***************************************************************/ + * The TYPO3 project - inspiring people to share! + */ use TYPO3\CMS\Core\Resource\FileInterface; /** * A common interface for the different ways of accessing Tika, e.g. app, * server, and Solr Cell. + * + * @author Ingo Renner */ interface ServiceInterface { - /** * Gets the Tika version * * @return string */ - public function getTikaVersion(); + public function getTikaVersion(): string; /** * Takes a file reference and extracts the text from it. @@ -48,15 +40,15 @@ public function getTikaVersion(); * @param FileInterface $file * @return string */ - public function extractText(FileInterface $file); + public function extractText(FileInterface $file): string; /** - * Takes a file reference and extracts its meta data. + * Takes a file reference and extracts its meta-data. * * @param FileInterface $file * @return array */ - public function extractMetaData(FileInterface $file); + public function extractMetaData(FileInterface $file): array; /** * Takes a file reference and detects its content's language. @@ -64,7 +56,7 @@ public function extractMetaData(FileInterface $file); * @param FileInterface $file * @return string Language ISO code */ - public function detectLanguageFromFile(FileInterface $file); + public function detectLanguageFromFile(FileInterface $file): string; /** * Takes a string as input and detects its language. @@ -72,17 +64,17 @@ public function detectLanguageFromFile(FileInterface $file); * @param string $input * @return string Language ISO code */ - public function detectLanguageFromString($input); + public function detectLanguageFromString(string $input): string; /** - * @return mixed + * @return array */ - public function getSupportedMimeTypes(); + public function getSupportedMimeTypes(): array; /** * Public method to check the availability of this service. * * @return bool */ - public function isAvailable(); + public function isAvailable(): bool; } diff --git a/Classes/Service/Tika/SolrCellService.php b/Classes/Service/Tika/SolrCellService.php index 93a11adfe..29e30db6f 100644 --- a/Classes/Service/Tika/SolrCellService.php +++ b/Classes/Service/Tika/SolrCellService.php @@ -1,30 +1,21 @@ - * 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. +/* + * This file is part of the TYPO3 CMS project. * - * The GNU General Public License can be found at - * http://www.gnu.org/copyleft/gpl.html. + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. * - * 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. + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. * - * This copyright notice MUST APPEAR in all copies of the script! - ***************************************************************/ + * The TYPO3 project - inspiring people to share! + */ use ApacheSolrForTypo3\Solr\ConnectionManager; use ApacheSolrForTypo3\Solr\System\Solr\SolrConnection; @@ -34,6 +25,8 @@ /** * A Tika service implementation using a Solr server + * + * @author Ingo Renner */ class SolrCellService extends AbstractService { @@ -43,7 +36,7 @@ class SolrCellService extends AbstractService * * @var SolrConnection */ - protected $solrConnection; + protected SolrConnection $solrConnection; /** * Service initialization @@ -72,7 +65,7 @@ protected function initializeService(): void * @param mixed $defaultValue * @return mixed */ - protected function getConfigurationOrDefaultValue($key, $defaultValue) + protected function getConfigurationOrDefaultValue(string $key, $defaultValue) { return $this->configuration[$key] ?? $defaultValue; } @@ -83,7 +76,7 @@ protected function getConfigurationOrDefaultValue($key, $defaultValue) * @param FileInterface $file * @return string */ - public function extractText(FileInterface $file) + public function extractText(FileInterface $file): string { $localTempFilePath = $file->getForLocalProcessing(false); /** @var Query $query */ @@ -102,16 +95,16 @@ public function extractText(FileInterface $file) 'response' => $response, ]); - return $response[0]; + return $response[0] ?? ''; } /** - * Takes a file reference and extracts its meta data. + * Takes a file reference and extracts its meta-data. * * @param FileInterface $file * @return array */ - public function extractMetaData(FileInterface $file) + public function extractMetaData(FileInterface $file): array { $localTempFilePath = $file->getForLocalProcessing(false); /** @var Query $query */ @@ -145,7 +138,7 @@ public function extractMetaData(FileInterface $file) * @param FileInterface $file * @return string Language ISO code */ - public function detectLanguageFromFile(FileInterface $file) + public function detectLanguageFromFile(FileInterface $file): string { // TODO check whether Solr supports text extraction now throw new UnsupportedOperationException( @@ -160,7 +153,7 @@ public function detectLanguageFromFile(FileInterface $file) * @param string $input * @return string Language ISO code */ - public function detectLanguageFromString($input) + public function detectLanguageFromString(string $input): string { // TODO check whether Solr supports text extraction now throw new UnsupportedOperationException( @@ -173,10 +166,10 @@ public function detectLanguageFromString($input) * Turns the nested Solr response into the same format as produced by a * local Tika jar call * - * @param array $metaDataResponse The part of the Solr response containing the meta data - * @return array The cleaned meta data, matching the Tika jar call format + * @param array $metaDataResponse The part of the Solr response containing the meta-data + * @return array The cleaned meta-data, matching the Tika jar call format */ - protected function solrResponseToArray(array $metaDataResponse = []) + protected function solrResponseToArray(array $metaDataResponse = []): array { $cleanedData = []; @@ -198,10 +191,10 @@ protected function solrResponseToArray(array $metaDataResponse = []) * * @return string Apache Solr server version string */ - public function getTikaVersion() + public function getTikaVersion(): string { // TODO add patch for endpoint on Apache Solr to return Tika version - // for now returns the Solr version string f.e. "Apache Solr 5.2.0" + // for now returns the Solr version string f.e. "Apache Solr X.Y.Z" return $this->solrConnection->getAdminService()->getSolrServerVersion(); } @@ -210,7 +203,7 @@ public function getTikaVersion() * * @return array */ - public function getSupportedMimeTypes() + public function getSupportedMimeTypes(): array { $mapping = [ 'application/epub+zip' => ['epub'], @@ -258,7 +251,7 @@ public function getSupportedMimeTypes() * * @return bool */ - public function isAvailable() + public function isAvailable(): bool { return $this->solrConnection->getWriteService()->ping(); } diff --git a/Classes/Service/Tika/UnsupportedOperationException.php b/Classes/Service/Tika/UnsupportedOperationException.php index 0896b7587..445058552 100644 --- a/Classes/Service/Tika/UnsupportedOperationException.php +++ b/Classes/Service/Tika/UnsupportedOperationException.php @@ -1,36 +1,29 @@ - * 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. +/* + * This file is part of the TYPO3 CMS project. * - * The GNU General Public License can be found at - * http://www.gnu.org/copyleft/gpl.html. + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. * - * 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. + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. * - * This copyright notice MUST APPEAR in all copies of the script! - ***************************************************************/ + * The TYPO3 project - inspiring people to share! + */ use RuntimeException; /** * Exception thrown by Tika service implementations if they don't support a * particular feature, f.e. Solr Cell does not support language detection. + * + * @author Ingo Renner */ class UnsupportedOperationException extends RuntimeException { diff --git a/Classes/Util.php b/Classes/Util.php index 4a4f7bbc5..eb7a16e7d 100644 --- a/Classes/Util.php +++ b/Classes/Util.php @@ -1,71 +1,40 @@ - * All rights reserved + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. * - * 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 3 of the License, or - * (at your option) any later version. + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. * - * 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! - ***************************************************************/ + * The TYPO3 project - inspiring people to share! + */ + +use TYPO3\CMS\Core\Configuration\Exception\ExtensionConfigurationExtensionNotConfiguredException; +use TYPO3\CMS\Core\Configuration\Exception\ExtensionConfigurationPathDoesNotExistException; +use TYPO3\CMS\Core\Configuration\ExtensionConfiguration; +use TYPO3\CMS\Core\Utility\GeneralUtility; /** * Utility class for tx_tika + * + * (c) dkd Internet services GmbH */ class Util { - - /** - * @todo This method is just added for compatibility checks for TYPO3 version 9 and will be removed when TYPO9 support is dropped - * @return bool - */ - public static function getIsTYPO3VersionBelow10() - { - return GeneralUtility::makeInstance(Typo3Version::class)->getMajorVersion() < 10; - } - - /** - * @todo This method is just added for compatibility checks for TYPO3 version 9 and will be removed when TYPO9 support is dropped - * @return bool - */ - public static function getIsTYPO3VersionAbove9() - { - return GeneralUtility::makeInstance(Typo3Version::class)->getMajorVersion() > 9; - } - - /** - * @return bool - */ - public static function getIsTYPO3Version10Lts() - { - return GeneralUtility::makeInstance(Typo3Version::class)->getBranch() === '10.4'; - } - /** * Returns extension configuration. * * @return array + * @throws ExtensionConfigurationExtensionNotConfiguredException + * @throws ExtensionConfigurationPathDoesNotExistException */ public static function getTikaExtensionConfiguration(): array { diff --git a/Classes/Utility/FileUtility.php b/Classes/Utility/FileUtility.php index e295e608b..fb8d81647 100644 --- a/Classes/Utility/FileUtility.php +++ b/Classes/Utility/FileUtility.php @@ -1,6 +1,7 @@ registerArgument('value', 'mixed', 'Value to be verified.', true); + } + + /** + * This method decides if the condition is true or false + * + * @param array $arguments ViewHelper arguments to evaluate the condition for this ViewHelper. + * @return bool + * @noinspection PhpMissingReturnTypeInspection + * @noinspection PhpUnused + */ + protected static function evaluateCondition($arguments = null) + { + return isset($arguments['value']) && is_string($arguments['value']); + } +} diff --git a/Configuration/Backend/Routes.php b/Configuration/Backend/Routes.php index b560cd249..3f2e5b47d 100644 --- a/Configuration/Backend/Routes.php +++ b/Configuration/Backend/Routes.php @@ -2,6 +2,19 @@ declare(strict_types=1); +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + /** * Definitions for routes provided by EXT:backend * Contains all "regular" routes for entry points @@ -9,7 +22,7 @@ * Please note that this setup is preliminary until all core use-cases are set up here. * Especially some more properties regarding modules will be added until TYPO3 CMS 7 LTS, and might change. * - * Currently the "access" property is only used so no token creation + validation is made, + * Currently, the "access" property is only used so no token creation + validation is made, * but will be extended further. */ return [ diff --git a/Documentation/Releases/11_0.rst b/Documentation/Releases/11_0.rst index 45c9157f7..b8c606cba 100644 --- a/Documentation/Releases/11_0.rst +++ b/Documentation/Releases/11_0.rst @@ -2,26 +2,104 @@ Apache Solr for TYPO3 - Tika Addon version 11.0.0 released ========================================================== -**Important**: -This version contains CVE-2021-44228 fixes for users, who starting -the Tika Server-daemons within TYPO3 BE or using Tika app modes. -All users using dedicated Tika server or Apache Solr Tika cell connections do not benefit from the update -and should harden the Solr Servers and/or Tika Servers with official CVE-2021-44228 patches manually. - -Manual action required for Tika App or enabled Tika Server module - -Please note that the release does not automatically include security measures against CVE-2021-44228. Rather, it is -now possible to specify additional parameters that can be passed when the java binary is executed. -The parameters can be set using the extension configuration javaCommandOptions. -Example: - -.. code-block:: - - # LocalConfiguration.php - return [ - 'EXTENSIONS' => [ - 'tika' => [ - 'javaCommandOptions' => '-Dlog4j2.formatMsgNoLookups=true', - ], - ], - ]; +We are happy to announce version 11.0.0 of EXT:tika. + +**Important**: This version is compatible with 11 LTS only. + +New in this Release +------------------- + +- [TASK] Prepare releases for TYPO3 11 LTS `910681d `_ +- [TASK] Fix issues recognized by scrutinizer `e10a03d `_ +- [FEATURE] Allow definition of additional Java command options `060b8ae `_ +- [BUGFIX] Handle custom java command options for server module as well `841c332 `_ +- [TASK] Let php-cs-fixer fix some CGL `9a5ba47 `_ +- [TASK] Move ext icon `4af9838 `_ +- [BUGFIX] Force variable as string `5e60539 `_ +- [TASK] Allow installation of 11.5 `695c60b `_ +- [BUGFIX] Use correct controller code `aa625b8 `_ +- [TASK] update ci pipeline `915344f `_ +- [TASK] TYPO3 11 LTS and PHP 8.1 compatibility `e0edd3c `_ + + +Contributors +------------ + +- Elias Häußler +- Georg Ringer +- Rafael Kähm +- Roman Schilter + +Thanks to everyone who helped in creating this release! + +Also a big thanks to our partners that have joined the EB2021 program: + +- +Pluswerk AG +- 711media websolutions GmbH +- Abt Sportsline GmbH +- ACO Severin Ahlmann GmbH & Co. KG +- AVM Computersysteme Vertriebs GmbH +- cosmoblonde GmbH +- creativ clicks GmbH +- cron IT GmbH +- CS2 AG +- CW Media & Systems +- Earlybird GmbH & Co KG +- FLOWSITE GmbH +- form4 GmbH & Co. KG +- Getdesigned GmbH +- Granpasso Digital Strategy GmbH +- Ikanos GmbH +- internezzo ag +- Intersim AG +- Ion2s GmbH +- Leitgab Gernot +- mellowmessage GmbH +- Moselwal Digitalagentur UG (haftungsbeschränkt) +- network.publishing Möller-Westbunk GmbH +- OST Ostschweizer Fachhochschule +- Plan.Net Suisse AG +- Provitex GmbH +- punkt.de GmbH +- queo GmbH +- Rechnungshof +- Schoene neue kinder GmbH +- SIT GmbH +- SIZ GmbH +- Stämpfli AG +- Triplesense Reply Frankfurt +- TWT reality bytes GmbH +- visol digitale Dienstleistungen GmbH +- Web Commerce GmbH +- webconsulting business services gmbh +- webschuppen GmbH +- Webstobe GmbH +- Webtech AG +- wow! solution +- XIMA MEDIA GmbH +- Bundesanstalt Statistik Österreich +- ECOS TECHNOLOGY GMBH +- Fachhochschule Erfurt +- Hochschule Furtwangen - IMZ Online-Services +- Hochschule Niederrhein University of Applied Sciences +- l'Autorité des marchés financiers +- La Financière agricole du Québec +- LfdA - Labor für digitale Angelegenheiten GmbH + +How to Get Involved +------------------- + +There are many ways to get involved with Apache Solr for TYPO3: + +- Submit bug reports and feature requests on [GitHub](https://github.com/TYPO3-Solr/ext-solr) +- Ask or help or answer questions in our [Slack channel](https://typo3.slack.com/messages/ext-solr/) +- Provide patches through Pull Request or review and comment on existing [Pull Requests](https://github.com/TYPO3-Solr/ext-solr/pulls) +- Go to [www.typo3-solr.com](http://www.typo3-solr.com) or call [dkd](http://www.dkd.de) to sponsor the ongoing development of Apache Solr for TYPO3 + +Support us in 2021 by becoming an EB partner: + +http://www.typo3-solr.com/en/contact/ + +or call: + ++49 (0)69 - 2475218 0 diff --git a/Documentation/Settings.cfg b/Documentation/Settings.cfg index 82cbf72b4..43e1a7d21 100644 --- a/Documentation/Settings.cfg +++ b/Documentation/Settings.cfg @@ -1,10 +1,10 @@ [general] project = Apache Tika for TYPO3 -version = 10.0.0 -release = 10.0.0 +version = 11.0.0 +release = 11.0.0 t3author = Ingo Renner, Timo Hund -copyright = 2021 +copyright = 2022 description = Documentation for EXT:tika diff --git a/Documentation/Settings.yml b/Documentation/Settings.yml index 10a5fd5c8..a8012790d 100644 --- a/Documentation/Settings.yml +++ b/Documentation/Settings.yml @@ -4,7 +4,7 @@ --- conf.py: - copyright: 2009-2021 + copyright: 2009-2022 project: Apache Tika for TYPO3 version: 11.0.0 release: 11.0.0 diff --git a/Documentation/conf.py b/Documentation/conf.py index 61ab3c24b..e2d105fb8 100644 --- a/Documentation/conf.py +++ b/Documentation/conf.py @@ -55,14 +55,14 @@ # General information about the project. project = u'EXT:tika Apache Tika for TYPO3' -copyright = u'2021, Ingo Renner' +copyright = u'2022, Ingo Renner' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. -version = '10.0' +version = '11.0' # The full version, including alpha/beta/rc tags. release = '11.0.0' diff --git a/README.md b/README.md index b5ec4d4dc..1b2ee2e16 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # Apache Tika for TYPO3 -[![Build Status](https://github.com/TYPO3-Solr/ext-tika/actions/workflows/ci.yml/badge.svg?branch=release-10.0.x)](https://github.com/TYPO3-Solr/ext-tika/actions?query=branch:release-10.0.x) -[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/TYPO3-Solr/ext-tika/badges/quality-score.png?b=release-10.0.x)](https://scrutinizer-ci.com/g/TYPO3-Solr/ext-tika/?branch=release-10.0.x) -[![Code Coverage](https://scrutinizer-ci.com/g/TYPO3-Solr/ext-tika/badges/coverage.png?b=release-10.0.x)](https://scrutinizer-ci.com/g/TYPO3-Solr/ext-tika/?branch=release-10.0.x) +[![Build Status](https://github.com/TYPO3-Solr/ext-tika/actions/workflows/ci.yml/badge.svg?branch=release-11.0.x)](https://github.com/TYPO3-Solr/ext-tika/actions?query=branch:release-10.0.x) +[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/TYPO3-Solr/ext-tika/badges/quality-score.png?b=release-11.0.x)](https://scrutinizer-ci.com/g/TYPO3-Solr/ext-tika/?branch=release-11.0.x) +[![Code Coverage](https://scrutinizer-ci.com/g/TYPO3-Solr/ext-tika/badges/coverage.png?b=release-11.0.x)](https://scrutinizer-ci.com/g/TYPO3-Solr/ext-tika/?branch=release-11.0.x) [![Latest Stable Version](https://poser.pugx.org/apache-solr-for-typo3/tika/v/stable)](https://packagist.org/packages/apache-solr-for-typo3/tika) [![License](https://poser.pugx.org/apache-solr-for-typo3/tika/license)](https://packagist.org/packages/apache-solr-for-typo3/tika) [![Monthly Downloads](https://poser.pugx.org/apache-solr-for-typo3/tika/d/monthly)](https://packagist.org/packages/apache-solr-for-typo3/tika) @@ -28,9 +28,9 @@ To run the test suite locally, please use our DDEV docker environment https://gi **Note**: This requires a proper combination of branches: -* solr-ddev-site on release-11.1.x branch - * packages/ext-solr on release-11.1.x - * packages/ext-tika on release-10.0.x +* solr-ddev-site on release-11.5.x branch + * packages/ext-solr on release-11.5.x + * packages/ext-tika on release-11.0.x * Please refer to [version matrix](https://raw.githubusercontent.com/TYPO3-Solr/ext-solr/master/Documentation/Appendix/VersionMatrix.rst) for proper combination of branches ```shell diff --git a/Resources/Private/Templates/Backend/Preview.html b/Resources/Private/Templates/Backend/Preview.html index 0e3b6ae58..955370aac 100644 --- a/Resources/Private/Templates/Backend/Preview.html +++ b/Resources/Private/Templates/Backend/Preview.html @@ -1,26 +1,52 @@ -
+ xmlns:tika="http://typo3.org/ns/ApacheSolrForTypo3/Tika/ViewHelpers/Backend" + f:schemaLocation="https://fluidtypo3.org/schemas/fluid-master.xsd"> -
- - - - - +
+

Extracted content:

+
{content}
-
- - - - - - - - - -
Extracted content: -
{content}
-
Detected Language:{language}
{key}:{value}
-
+ + + + + + + + + + + + + + +
KeyValue
Detected Language:{language}
+
+ + + + + {tableRowFiledName} + + + {tableRowValue} + + + + + + + + + + + + + + + + + +
Key Value
+
diff --git a/Resources/Public/JavaScript/ContextMenuActions.js b/Resources/Public/JavaScript/ContextMenuActions.js index abefa0248..ade772a64 100644 --- a/Resources/Public/JavaScript/ContextMenuActions.js +++ b/Resources/Public/JavaScript/ContextMenuActions.js @@ -5,32 +5,32 @@ * @exports TYPO3/CMS/Tika/ContextMenuActions */ define(function () { - 'use strict'; + 'use strict'; - /** - * @exports TYPO3/CMS/Tika/ContextMenuActions - */ - var ContextMenuActions = {}; + /** + * @exports TYPO3/CMS/Tika/ContextMenuActions + */ + const ContextMenuActions = {}; - ContextMenuActions.tikaPreview = function (table, uid) { - if (table === 'sys_file') { + ContextMenuActions.tikaPreview = function (table, uid) { + if (table === 'sys_file') { - require([ - 'jquery', - 'TYPO3/CMS/Backend/Modal' - ], function ($, Modal) { + require([ + 'jquery', + 'TYPO3/CMS/Backend/Modal' + ], function ($, Modal) { - var configuration = { - title: 'Tika Preview', - content: top.TYPO3.settings.TikaPreview.moduleUrl + '&identifier=' + top.rawurlencode(uid), - size: Modal.sizes.large, - type: Modal.types.ajax - } - Modal.advanced(configuration); - }); - } + const configuration = { + title: 'Tika Preview', + content: top.TYPO3.settings.TikaPreview.moduleUrl + '&identifier=' + encodeURIComponent(uid).replace(/\*/g, '%2A'), + size: Modal.sizes.large, + type: Modal.types.ajax + }; + Modal.advanced(configuration); + }); + } - }; + }; - return ContextMenuActions; -}); \ No newline at end of file + return ContextMenuActions; +}); diff --git a/Tests/Integration/Service/Tika/AppServiceTest.php b/Tests/Integration/Service/Tika/AppServiceTest.php index 50ccfc001..a3af05ba8 100644 --- a/Tests/Integration/Service/Tika/AppServiceTest.php +++ b/Tests/Integration/Service/Tika/AppServiceTest.php @@ -1,6 +1,7 @@ + * @author Ingo Renner + * + * @todo: Move all *Parameter() methods to Unit, to speedup the tests. */ class AppServiceTest extends ServiceIntegrationTestCase { @@ -43,7 +47,7 @@ public function getTikaVersionUsesVParameter(): void $service->setLogger(new NullLogger()); $service->getTikaVersion(); - self::assertContains('-V', ExecRecorder::$execCommand); + self::assertStringContainsString('-V', ExecRecorder::$execCommand); } /** @@ -63,7 +67,7 @@ public function extractTextUsesTParameter(): void $service->setLogger(new NullLogger()); $service->extractText($file); - self::assertContains('-t', ExecRecorder::$execCommand); + self::assertStringContainsString('-t', ExecRecorder::$execCommand); } /** @@ -71,7 +75,7 @@ public function extractTextUsesTParameter(): void */ public function extractMetaDataUsesMParameter(): void { - ExecRecorder::setReturnExecOutput(['foo']); + ExecRecorder::setReturnExecOutput(['foo : bar']); $file = new File( [ 'identifier' => 'testWORD.doc', @@ -82,9 +86,9 @@ public function extractMetaDataUsesMParameter(): void $service = new AppService($this->getConfiguration()); $service->setLogger(new NullLogger()); - $service->extractMetaData($file); + $array = $service->extractMetaData($file); - self::assertContains('-m', ExecRecorder::$execCommand); + self::assertStringContainsString('-m', ExecRecorder::$execCommand); } /** @@ -104,7 +108,7 @@ public function detectLanguageFromFileUsesLParameter(): void $service->setLogger(new NullLogger()); $service->detectLanguageFromFile($file); - self::assertContains('-l', ExecRecorder::$execCommand); + self::assertStringContainsString('-l', ExecRecorder::$execCommand); } /** @@ -116,7 +120,7 @@ public function detectLanguageFromStringUsesLParameter(): void $service->setLogger(new NullLogger()); $service->detectLanguageFromString('foo'); - self::assertContains('-l', ExecRecorder::$execCommand); + self::assertStringContainsString('-l', ExecRecorder::$execCommand); } /** @@ -127,7 +131,7 @@ public function callsTikaAppCorrectlyToGetMimeList(): void $service = new AppService($this->getConfiguration()); $service->setLogger(new NullLogger()); $service->getSupportedMimeTypes(); - self::assertContains('--list-supported-types', ExecRecorder::$execCommand); + self::assertStringContainsString('--list-supported-types', ExecRecorder::$execCommand); } /** @@ -137,10 +141,10 @@ public function canParseMimeList(): void { $fixtureContent = file_get_contents(__DIR__ . '/Fixtures/mimeOut'); - /** @var $service AppService */ + /** @var $service AppService|MockObject */ $service = $this->getMockBuilder(AppService::class) ->disableOriginalConstructor() - ->setMethods(['getMimeTypeOutputFromTikaJar'])->getMock(); + ->onlyMethods(['getMimeTypeOutputFromTikaJar'])->getMock(); $service->expects(self::once())->method('getMimeTypeOutputFromTikaJar')->willReturn($fixtureContent); $supportedMimeTypes = $service->getSupportedMimeTypes(); @@ -157,6 +161,6 @@ public function includesAdditionalCommandOptions(): void $service = new AppService($this->getConfiguration()); $service->setLogger(new NullLogger()); $service->getTikaVersion(); - self::assertContains('-Dlog4j2.formatMsgNoLookups=\'true\'', ExecRecorder::$execCommand); + self::assertStringContainsString('-Dlog4j2.formatMsgNoLookups=\'true\'', ExecRecorder::$execCommand); } } diff --git a/Tests/Integration/Service/Tika/Fixtures/ServerServiceFixture.php b/Tests/Integration/Service/Tika/Fixtures/ServerServiceFixture.php index 4db5839a2..1cdbab59a 100644 --- a/Tests/Integration/Service/Tika/Fixtures/ServerServiceFixture.php +++ b/Tests/Integration/Service/Tika/Fixtures/ServerServiceFixture.php @@ -1,6 +1,7 @@ + * @author Ingo Renner */ class ServerServiceFixture extends ServerService { @@ -33,7 +34,7 @@ class ServerServiceFixture extends ServerService * * @var string */ - protected $recordedEndpoint = ''; + protected string $recordedEndpoint = ''; /** * @return string diff --git a/Tests/Integration/Service/Tika/ServerServiceTest.php b/Tests/Integration/Service/Tika/ServerServiceTest.php index 439f692fa..b352c525e 100644 --- a/Tests/Integration/Service/Tika/ServerServiceTest.php +++ b/Tests/Integration/Service/Tika/ServerServiceTest.php @@ -1,6 +1,7 @@ prophesize(Registry::class); $registryMock->get('tx_tika', 'server.pid')->willReturn(1000); $registryMock->remove('tx_tika', 'server.pid')->shouldBeCalled(); GeneralUtility::setSingletonInstance(Registry::class, $registryMock->reveal()); + /* @var Process|ObjectProphecy $processMock */ $processMock = $this->prophesize(Process::class); $processMock->setPid(1000)->shouldBeCalled(); $processMock->stop()->shouldBeCalled(); @@ -97,6 +94,7 @@ public function stopServerRemovesPidFromRegistry(): void */ public function getServerPidGetsPidFromRegistry(): void { + /* @var Registry|ObjectProphecy $registryMock */ $registryMock = $this->prophesize(Registry::class); $registryMock->get('tx_tika', 'server.pid')->willReturn(1000); GeneralUtility::setSingletonInstance(Registry::class, $registryMock->reveal()); @@ -113,6 +111,7 @@ public function getServerPidGetsPidFromRegistry(): void */ public function getServerPidFallsBackToProcess(): void { + /* @var Registry|ObjectProphecy $registryMock */ $registryMock = $this->prophesize(Registry::class); $registryMock->get('tx_tika', 'server.pid')->willReturn(''); GeneralUtility::setSingletonInstance(Registry::class, $registryMock->reveal()); @@ -133,6 +132,7 @@ public function getServerPidFallsBackToProcess(): void */ public function isServerRunningReturnsTrueForRunningServerFromRegistry(): void { + /* @var Registry|ObjectProphecy $registryMock */ $registryMock = $this->prophesize(Registry::class); $registryMock->get('tx_tika', 'server.pid')->willReturn(1000); GeneralUtility::setSingletonInstance(Registry::class, $registryMock->reveal()); @@ -147,10 +147,12 @@ public function isServerRunningReturnsTrueForRunningServerFromRegistry(): void */ public function isServerRunningReturnsTrueForRunningServerFromProcess(): void { + /* @var Registry|ObjectProphecy $registryMock */ $registryMock = $this->prophesize(Registry::class); $registryMock->get('tx_tika', 'server.pid')->willReturn(''); GeneralUtility::setSingletonInstance(Registry::class, $registryMock->reveal()); + /* @var Process|ObjectProphecy $processMock */ $processMock = $this->prophesize(Process::class); $processMock->findPid()->willReturn(1000); GeneralUtility::addInstance(Process::class, $processMock->reveal()); @@ -165,12 +167,14 @@ public function isServerRunningReturnsTrueForRunningServerFromProcess(): void */ public function isServerRunningReturnsFalseForStoppedServer(): void { + /* @var Registry|ObjectProphecy $registryMock */ $registryMock = $this->prophesize(Registry::class); $registryMock->get('tx_tika', 'server.pid')->willReturn(''); GeneralUtility::setSingletonInstance(Registry::class, $registryMock->reveal()); + /* @var Process|ObjectProphecy $processMock */ $processMock = $this->prophesize(Process::class); - $processMock->findPid()->willReturn(''); + $processMock->findPid()->willReturn(null); GeneralUtility::addInstance(Process::class, $processMock->reveal()); $service = new ServerService($this->getConfiguration()); @@ -322,7 +326,7 @@ public function extractsTextFromDocFile(): void $expectedText = 'Sample Word Document'; $extractedText = $service->extractText($this->getMockedFileInstanceForTestWordDotDocFile()); - self::assertContains($expectedText, $extractedText); + self::assertStringContainsString($expectedText, $extractedText); } /** @@ -342,8 +346,8 @@ public function extractsTextFromZipFile(): void )); $expectedTextFromPDF= 'Tika - Content Analysis Toolkit'; - self::assertContains($expectedTextFromWord, $extractedText); - self::assertContains($expectedTextFromPDF, $extractedText); + self::assertStringContainsString($expectedTextFromWord, $extractedText); + self::assertStringContainsString($expectedTextFromPDF, $extractedText); } /** @@ -351,7 +355,7 @@ public function extractsTextFromZipFile(): void * * @return array */ - public function languageFileDataProvider() + public function languageFileDataProvider(): array { return [ 'danish' => ['da'], diff --git a/Tests/Integration/Service/Tika/ServiceFactoryTest.php b/Tests/Integration/Service/Tika/ServiceFactoryTest.php index fc9aa1773..78a48ecb2 100644 --- a/Tests/Integration/Service/Tika/ServiceFactoryTest.php +++ b/Tests/Integration/Service/Tika/ServiceFactoryTest.php @@ -1,50 +1,40 @@ - * All rights reserved +/* + * This file is part of the TYPO3 CMS project. * - * 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. + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. * - * The GNU General Public License can be found at - * http://www.gnu.org/copyleft/gpl.html. + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. * - * 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! - ***************************************************************/ + * The TYPO3 project - inspiring people to share! + */ use ApacheSolrForTypo3\Tika\Service\Tika\AppService; use ApacheSolrForTypo3\Tika\Service\Tika\ServerService; use ApacheSolrForTypo3\Tika\Service\Tika\ServiceFactory; use ApacheSolrForTypo3\Tika\Service\Tika\SolrCellService; +use InvalidArgumentException; +use TYPO3\CMS\Core\Cache\Backend\TransientMemoryBackend; use TYPO3\CMS\Core\Cache\CacheManager; +use TYPO3\CMS\Core\Cache\Frontend\VariableFrontend; use TYPO3\CMS\Core\Utility\ExtensionManagementUtility; use TYPO3\CMS\Core\Utility\GeneralUtility; /** * Class AppServiceTest + * + * @author Ingo Renner */ class ServiceFactoryTest extends ServiceIntegrationTestCase { - - /** - * @var array - */ - private $globalsBackup; - /** * @test */ @@ -88,38 +78,25 @@ public function getTikaReturnsSolrCellServiceForSolrExtractor(): void /** * @test - * @expectedException \InvalidArgumentException */ public function getTikaThrowsExceptionForInvalidExtractor(): void { + $this->expectException(InvalidArgumentException::class); ServiceFactory::getTika('foo', $this->getConfiguration()); } protected function setUp(): void { parent::setUp(); - $this->globalsBackup = [ - 'TYPO3_CONF_VARS' => $GLOBALS['TYPO3_CONF_VARS'], - ]; - GeneralUtility::makeInstance(CacheManager::class)->setCacheConfigurations([ 'cache_hash' => [ - 'frontend' => \TYPO3\CMS\Core\Cache\Frontend\VariableFrontend::class, - 'backend' => \TYPO3\CMS\Core\Cache\Backend\TransientMemoryBackend::class, + 'frontend' => VariableFrontend::class, + 'backend' => TransientMemoryBackend::class, ], 'cache_runtime' => [ - 'frontend' => \TYPO3\CMS\Core\Cache\Frontend\VariableFrontend::class, - 'backend' => \TYPO3\CMS\Core\Cache\Backend\TransientMemoryBackend::class, + 'frontend' => VariableFrontend::class, + 'backend' => TransientMemoryBackend::class, ], ]); - unset($GLOBALS['TYPO3_CONF_VARS']); - } - - protected function tearDown(): void - { - foreach ($this->globalsBackup as $key => $data) { - $GLOBALS[$key] = $data; - } - unset($this->globalsBackup); } } diff --git a/Tests/Integration/Service/Tika/ServiceIntegrationTestCase.php b/Tests/Integration/Service/Tika/ServiceIntegrationTestCase.php index 4b0191407..167c38546 100644 --- a/Tests/Integration/Service/Tika/ServiceIntegrationTestCase.php +++ b/Tests/Integration/Service/Tika/ServiceIntegrationTestCase.php @@ -1,35 +1,29 @@ - * 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. +/* + * This file is part of the TYPO3 CMS project. * - * The GNU General Public License can be found at - * http://www.gnu.org/copyleft/gpl.html. + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. * - * 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. + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. * - * This copyright notice MUST APPEAR in all copies of the script! - ***************************************************************/ + * The TYPO3 project - inspiring people to share! + */ -use ApacheSolrForTypo3\Tika\Util; use function getenv; -use Nimut\TestingFramework\TestCase\FunctionalTestCase; +use InvalidArgumentException; use PHPUnit\Framework\MockObject\MockObject; +use Prophecy\PhpUnit\ProphecyTrait; +use ReflectionException; +use ReflectionObject; +use RuntimeException; use TYPO3\CMS\Core\Cache\Backend\TransientMemoryBackend; use TYPO3\CMS\Core\Cache\CacheManager; use TYPO3\CMS\Core\Cache\Frontend\VariableFrontend; @@ -40,12 +34,16 @@ use TYPO3\CMS\Core\Resource\ResourceStorage; use TYPO3\CMS\Core\Utility\ExtensionManagementUtility; use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase; /** * Base class for EXT:tika tests + * + * @author Ingo Renner */ abstract class ServiceIntegrationTestCase extends FunctionalTestCase { + use ProphecyTrait; /** * @var array @@ -59,37 +57,37 @@ abstract class ServiceIntegrationTestCase extends FunctionalTestCase /** * @var array A backup of registered singleton instances */ - protected $singletonInstances = []; + protected array $singletonInstances = []; /** * @var string */ - protected $testDocumentsPath; + protected string $testDocumentsPath; /** * @var string */ - protected $testLanguagesPath; + protected string $testLanguagesPath; /** * @var ResourceStorage */ - protected $documentsStorageMock; + protected ResourceStorage $documentsStorageMock; /** * @var ResourceStorage */ - protected $languagesStorageMock; + protected ResourceStorage $languagesStorageMock; /** * @var int */ - protected $documentsStorageUid = 9000; + protected int $documentsStorageUid = 9000; /** * @var int */ - protected $languagesStorageUid = 9001; + protected int $languagesStorageUid = 9001; /** * @var array @@ -106,7 +104,7 @@ abstract class ServiceIntegrationTestCase extends FunctionalTestCase */ public function __sleep() { - $objectVars = parent::__sleep(); + $objectVars = get_object_vars($this); unset( $objectVars['documentsStorageMock'], $objectVars['languagesStorageMock'] @@ -134,14 +132,10 @@ protected function setUp(): void $this->setUpDocumentsStorageMock(); $this->setUpLanguagesStorageMock(); - $metaDataRepositoryConstructorArgs = []; - - if (Util::getIsTYPO3VersionAbove9()) { - /** @noinspection PhpFullyQualifiedNameUsageInspection */ - $metaDataRepositoryConstructorArgs = [ - GeneralUtility::makeInstance(\TYPO3\CMS\Core\EventDispatcher\EventDispatcher::class), - ]; - } + /** @noinspection PhpFullyQualifiedNameUsageInspection */ + $metaDataRepositoryConstructorArgs = [ + GeneralUtility::makeInstance(\TYPO3\CMS\Core\EventDispatcher\EventDispatcher::class), + ]; /* @var MetaDataRepository|MockObject $mockedMetaDataRepository */ $mockedMetaDataRepository = $this->getMockBuilder(MetaDataRepository::class) @@ -152,6 +146,8 @@ protected function setUp(): void ->method('findByFile') ->willReturn(['file' => 1]); GeneralUtility::setSingletonInstance(MetaDataRepository::class, $mockedMetaDataRepository); + // Set $GLOBALS['TYPO3_CONF_VARS'], to avoid PHP 8.0+ warning like "Undefined global variable" + $GLOBALS['TYPO3_CONF_VARS']['BE']['disable_exec_function'] = false; } protected function setUpDocumentsStorageMock(): void @@ -178,7 +174,7 @@ protected function setUpDocumentsStorageMock(): void ]; $this->documentsStorageMock = $this->getMockBuilder(ResourceStorage::class) - ->setMethods(['getUid']) + ->onlyMethods(['getUid']) ->setConstructorArgs([$documentsDriver, $documentsStorageRecord]) ->getMock(); @@ -213,7 +209,7 @@ protected function setUpLanguagesStorageMock(): void ]; $this->languagesStorageMock = $this->getMockBuilder(ResourceStorage::class) - ->setMethods(['getUid']) + ->onlyMethods(['getUid']) ->setConstructorArgs([$languagesDriver, $languagesStorageRecord]) ->getMock(); $this->languagesStorageMock->expects(self::any()) @@ -236,9 +232,9 @@ protected function tearDown(): void */ protected function createDriverFixture( array $driverConfiguration = [], - $mockedDriverMethods = [] - ) { - /** @var LocalDriver $driver */ + array $mockedDriverMethods = [] + ): LocalDriver { + /* @var LocalDriver $driver */ $mockedDriverMethods[] = 'isPathValid'; $driver = $this->getAccessibleMock( LocalDriver::class, @@ -277,8 +273,7 @@ protected function convertConfigurationArrayToFlexformXml( foreach ($configuration as $key => $value) { $flexformArray['data']['sDEF']['lDEF'][$key] = ['vDEF' => $value]; } - $configuration = GeneralUtility::array2xml($flexformArray); - return $configuration; + return GeneralUtility::array2xml($flexformArray); } /** @@ -323,22 +318,18 @@ protected function getMockedFileInstance( ResourceStorage $storage = null, array $metaData = [] ) { - if (Util::getIsTYPO3VersionBelow10()) { - return new File($fileData, $storage ?: $this->documentsStorageMock, $metaData); - } - $fileMock = $this->getMockBuilder(File::class) ->setConstructorArgs([ $fileData, $storage ?? $this->documentsStorageMock, $metaData, ]) - ->setMethods(['getMetaData']) + ->onlyMethods(['getMetaData']) ->getMock(); $metaDataAspectMock = $this->getMockBuilder(MetaDataAspect::class) ->setConstructorArgs([$fileMock]) - ->setMethods(['get']) + ->onlyMethods(['get']) ->getMock(); $metaDataAspectMock->expects(self::any())->method('get')->willReturn($metaData); @@ -346,4 +337,71 @@ protected function getMockedFileInstance( return $fileMock; } + + /* + Nimut testing framework goodies, copied from https://github.com/Nimut/testing-framework + */ + + /** + * Injects $dependency into property $name of $target + * + * This is a convenience method for setting a protected or private property in + * a test subject for the purpose of injecting a dependency. + * + * Copied from https://github.com/Nimut/testing-framework/blob/3d0573b23fe16157460b4e73e51e1cc0903ea35c/src/TestingFramework/TestCase/AbstractTestCase.php#L247-L284 + * + * @param object $target The instance which needs the dependency + * @param string $name Name of the property to be injected + * @param mixed $dependency The dependency to inject – usually an object but can also be any other type + * @throws InvalidArgumentException + * @throws RuntimeException + */ + protected function inject(object $target, string $name, $dependency) + { + if (!is_object($target)) { + throw new InvalidArgumentException('Wrong type for argument $target, must be object.', 1476107338); + } + + $objectReflection = new ReflectionObject($target); + $methodNamePart = strtoupper($name[0]) . substr($name, 1); + if ($objectReflection->hasMethod('set' . $methodNamePart)) { + $methodName = 'set' . $methodNamePart; + $target->$methodName($dependency); + } elseif ($objectReflection->hasMethod('inject' . $methodNamePart)) { + $methodName = 'inject' . $methodNamePart; + $target->$methodName($dependency); + } elseif ($objectReflection->hasProperty($name)) { + $property = $objectReflection->getProperty($name); + $property->setAccessible(true); + $property->setValue($target, $dependency); + } else { + throw new RuntimeException( + 'Could not inject ' . $name . ' into object of type ' . get_class($target), + 1476107339 + ); + } + } + + /** + * Helper function to call protected or private methods + * + * Copied from https://github.com/Nimut/testing-framework/blob/3d0573b23fe16157460b4e73e51e1cc0903ea35c/src/TestingFramework/TestCase/AbstractTestCase.php#L227-L245 + * + * @param object $object The object to be invoked + * @param string $name the name of the method to call + * @return mixed + * @throws ReflectionException + */ + protected function callInaccessibleMethod(object $object, string $name) + { + // Remove first two arguments ($object and $name) + $arguments = func_get_args(); + array_splice($arguments, 0, 2); + + $reflectionObject = new ReflectionObject($object); + $reflectionMethod = $reflectionObject->getMethod($name); + $reflectionMethod->setAccessible(true); + + return $reflectionMethod->invokeArgs($object, $arguments); + } } diff --git a/Tests/Integration/Service/Tika/SolrCellServiceTest.php b/Tests/Integration/Service/Tika/SolrCellServiceTest.php index 3660b6980..caf1095dc 100644 --- a/Tests/Integration/Service/Tika/SolrCellServiceTest.php +++ b/Tests/Integration/Service/Tika/SolrCellServiceTest.php @@ -1,6 +1,7 @@ + * + * @todo: Move duplicated code in methods. */ class SolrCellServiceTest extends ServiceIntegrationTestCase { - /** - * @var Prophet - */ - protected $prophet; - protected function assertPreConditions(): void { if (!ExtensionManagementUtility::isLoaded('solr')) { @@ -52,7 +50,7 @@ public function newInstancesAreInitializedWithASolrConnection(): void { $service = new SolrCellService($this->getConfiguration()); $service->setLogger(new NullLogger()); - self::assertAttributeInstanceOf(SolrConnection::class, 'solrConnection', $service); + self::assertTrue($service->isAvailable()); } /** @@ -62,6 +60,7 @@ public function extractByQueryTextReturnsTextElementFromResponse(): void { $expectedValue = 'extracted text element'; + /* @var SolrWriteService|ObjectProphecy $solrWriter */ $solrWriter = $this->prophesize(SolrWriteService::class); $solrWriter->extractByQuery(Argument::type(Query::class)) ->willReturn([ @@ -69,6 +68,7 @@ public function extractByQueryTextReturnsTextElementFromResponse(): void 'meta data element', // meta data is index 1 ]); + /* @var SolrConnection|ObjectProphecy $connectionMock */ $connectionMock = $this->prophesize(SolrConnection::class); $connectionMock->getWriteService()->shouldBeCalled()->willReturn($solrWriter); @@ -96,6 +96,7 @@ public function extractByQueryTextUsesSolariumExtractQuery(): void $solrWriter = $this->prophesize(SolrWriteService::class); $solrWriter->extractByQuery(Argument::type(Query::class))->shouldBeCalled(); + /* @var SolrConnection|ObjectProphecy $connectionMock */ $connectionMock = $this->prophesize(SolrConnection::class); $connectionMock->getWriteService()->shouldBeCalled()->willReturn($solrWriter); @@ -105,9 +106,9 @@ public function extractByQueryTextUsesSolariumExtractQuery(): void $file = new File( [ - 'identifier' => 'testWORD.doc', - 'name' => 'testWORD.doc', - ], + 'identifier' => 'testWORD.doc', + 'name' => 'testWORD.doc', + ], $this->documentsStorageMock ); @@ -131,6 +132,7 @@ public function extractMetaDataUsesSolariumExtractQuery(): void ] ); + /* @var SolrConnection|ObjectProphecy $connectionMock */ $connectionMock = $this->prophesize(SolrConnection::class); $connectionMock->getWriteService()->shouldBeCalled()->willReturn($solrWriter); diff --git a/Tests/Unit/Backend/PreviewControllerTest.php b/Tests/Unit/Backend/PreviewControllerTest.php index b4d952144..c6582e9df 100644 --- a/Tests/Unit/Backend/PreviewControllerTest.php +++ b/Tests/Unit/Backend/PreviewControllerTest.php @@ -4,48 +4,42 @@ namespace ApacheSolrForTypo3\Tika\Tests\Unit\Backend; -/*************************************************************** - * Copyright notice +/* + * This file is part of the TYPO3 CMS project. * - * (c) 2018 Timo Hund + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. * - * All rights reserved + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. * - * 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! - ***************************************************************/ + * The TYPO3 project - inspiring people to share! + */ use ApacheSolrForTypo3\Tika\Controller\Backend\PreviewController; use ApacheSolrForTypo3\Tika\Service\Tika\ServerService; use ApacheSolrForTypo3\Tika\Tests\Unit\UnitTestCase; +use PHPUnit\Framework\MockObject\MockObject; use Psr\Http\Message\ServerRequestInterface; use TYPO3\CMS\Core\Http\Response; use TYPO3\CMS\Core\Resource\FileInterface; use TYPO3\CMS\Core\Resource\ResourceFactory; +/** + * Class PreviewControllerTest + * + * @author Timo Hund + */ class PreviewControllerTest extends UnitTestCase { - /** * @test */ public function previewActionTriggersTikaServices(): void { - /** @var $controller PreviewController */ - $controller = $this->getMockBuilder(PreviewController::class)->setMethods([ + /** @var $controller PreviewController|MockObject */ + $controller = $this->getMockBuilder(PreviewController::class)->onlyMethods([ 'getFileResourceFactory', 'getInitializedPreviewView', 'getConfiguredTikaService', @@ -66,6 +60,7 @@ public function previewActionTriggersTikaServices(): void $controller->expects(self::once())->method('getConfiguredTikaService')->willReturn($serviceMock); $request = $this->getMockBuilder(ServerRequestInterface::class)->getMock(); + $request->expects(self::once())->method('getQueryParams')->willReturn(self::returnValue(['identifier' => ''])); $controller->previewAction($request); } @@ -74,8 +69,8 @@ public function previewActionTriggersTikaServices(): void */ public function previewActionShowsErrorWhenNoAdmin(): void { - /** @var $controller PreviewController */ - $controller = $this->getMockBuilder(PreviewController::class)->setMethods([ + /** @var $controller PreviewController|MockObject */ + $controller = $this->getMockBuilder(PreviewController::class)->onlyMethods([ 'getFileResourceFactory', 'getInitializedPreviewView', 'getConfiguredTikaService', diff --git a/Tests/Unit/Backend/SolrModule/TikaControlPanelModuleControllerTest.php b/Tests/Unit/Backend/SolrModule/TikaControlPanelModuleControllerTest.php index cad7618a7..3615c7beb 100644 --- a/Tests/Unit/Backend/SolrModule/TikaControlPanelModuleControllerTest.php +++ b/Tests/Unit/Backend/SolrModule/TikaControlPanelModuleControllerTest.php @@ -1,37 +1,34 @@ - * - * All rights reserved +/* + * This file is part of the TYPO3 CMS project. * - * 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. + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. * - * The GNU General Public License can be found at - * http://www.gnu.org/copyleft/gpl.html. + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. * - * 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! - ***************************************************************/ + * The TYPO3 project - inspiring people to share! + */ use ApacheSolrForTypo3\Tika\Controller\Backend\SolrModule\TikaControlPanelModuleController; use ApacheSolrForTypo3\Tika\Service\Tika\ServerService; use ApacheSolrForTypo3\Tika\Tests\Unit\UnitTestCase; -use TYPO3\CMS\Extbase\Mvc\View\ViewInterface; +use PHPUnit\Framework\MockObject\MockObject; +use TYPO3\CMS\Backend\Template\ModuleTemplate; +use TYPO3Fluid\Fluid\View\ViewInterface; +/** + * Class + * + * @author Timo Hund + */ class TikaControlPanelModuleControllerTest extends UnitTestCase { /** @@ -40,17 +37,25 @@ class TikaControlPanelModuleControllerTest extends UnitTestCase protected $controller; /** - * @var \TYPO3\CMS\Extbase\Mvc\View\ViewInterface + * @var ViewInterface */ protected $viewMock; + /** + * @var ModuleTemplate|MockObject + */ + protected $moduleTemplateMock; + public function setUp(): void { $this->viewMock = $this->getDumbMock(ViewInterface::class); + $this->moduleTemplateMock = $this->getDumbMock(ModuleTemplate::class); + $this->controller = $this->getMockBuilder(TikaControlPanelModuleController::class) ->disableOriginalConstructor() - ->setMethods(['addFlashMessage']) + ->onlyMethods(['addFlashMessage', 'getModuleTemplateResponse']) ->getMock(); + $this->controller->overwriteModuleTemplate($this->moduleTemplateMock); $this->controller->overwriteView($this->viewMock); } @@ -61,25 +66,30 @@ public function setUp(): void */ public function canShowInformationFromStandaloneTikaServer(): void { + /* @var ServerService|MockObject $tikaServerService */ $tikaServerService = $this->getDumbMock(ServerService::class); $tikaServerService->expects(self::atLeastOnce())->method('isServerRunning')->willReturn(true); $tikaServerService->expects(self::atLeastOnce())->method('getServerPid')->willReturn(4711); $tikaServerService->expects(self::atLeastOnce())->method('getTikaVersion')->willReturn('1.11'); $this->controller->setTikaService($tikaServerService); - $this->controller->setTikaConfiguration([ + $tikaConfiguration = [ 'extractor' => 'server', 'tikaServerPath' => $this->getFixturePath('fake-server-jar.jar'), - ]); + ]; + $this->controller->setTikaConfiguration($tikaConfiguration); - $this->viewMock->expects(self::at(2))->method('assign')->with( - 'server', - [ - 'jarAvailable' => true, - 'isRunning' => true, - 'isControllable' => true, - 'pid' => 4711, - 'version' => '1.11', + $this->viewMock->expects(self::any())->method('assign')->withConsecutive( + [ 'configuration', $tikaConfiguration ], + [ 'extractor', ucfirst($tikaConfiguration['extractor']) ], + [ 'server', + [ + 'jarAvailable' => true, + 'isRunning' => true, + 'isControllable' => true, + 'pid' => 4711, + 'version' => '1.11', + ], ] ); diff --git a/Tests/Unit/ExecMockFunctions.php b/Tests/Unit/ExecMockFunctions.php index bdf1476ca..538af593e 100644 --- a/Tests/Unit/ExecMockFunctions.php +++ b/Tests/Unit/ExecMockFunctions.php @@ -1,18 +1,32 @@ - * 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. + +namespace ApacheSolrForTypo3\Tika\Tests\Unit; + +/* + * This file is part of the TYPO3 CMS project. * - * The GNU General Public License can be found at - * http://www.gnu.org/copyleft/gpl.html. + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. * - * 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. + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. * - * This copyright notice MUST APPEAR in all copies of the script! - ***************************************************************/ - -// a namespace declaration needs to be the first statement in a file -// we just need any namespace declaration to work around that requirement -namespace ApacheSolrForTypo3\Tika\Foo; + * The TYPO3 project - inspiring people to share! + */ // load the mocked functions into the namespaces which need them during tests // include() or require() cannot load into namespaces @@ -40,6 +29,8 @@ /** * Class ExecRecorder, holds exec() results + * + * @author Ingo Renner */ class ExecRecorder { @@ -49,21 +40,21 @@ class ExecRecorder * * @var string */ - public static $execCommand = ''; + public static string $execCommand = ''; /** * Output to return to exec() calls * * @var array */ - public static $execOutput = []; + public static array $execOutput = []; /** * Indicator whether/how many times the exec() mock was called. * * @var int */ - public static $execCalled = 0; + public static int $execCalled = 0; /** * Resets the exec() mock diff --git a/Tests/Unit/ProcessTest.php b/Tests/Unit/ProcessTest.php index 1742a56e5..906a93890 100644 --- a/Tests/Unit/ProcessTest.php +++ b/Tests/Unit/ProcessTest.php @@ -1,35 +1,28 @@ - * All rights reserved +/* + * This file is part of the TYPO3 CMS project. * - * 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. + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. * - * The GNU General Public License can be found at - * http://www.gnu.org/copyleft/gpl.html. + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. * - * 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! - ***************************************************************/ + * The TYPO3 project - inspiring people to share! + */ use ApacheSolrForTypo3\Tika\Process; /** * Test case for class \ApacheSolrForTypo3\Tika\Process + * + * @author Ingo Renner */ class ProcessTest extends UnitTestCase { @@ -51,13 +44,13 @@ public function constructorSetsExecutableAndArguments(): void public function findPidUsesExecutableBasename(): void { $process = new Process('/usr/bin/foo', '-bar'); - ExecRecorder::setReturnExecOutput(['foo']); + ExecRecorder::setReturnExecOutput(['78986 foo']); $process->findPid(); self::assertTrue((bool)ExecRecorder::$execCalled); - self::assertContains('foo', ExecRecorder::$execCommand); - self::assertNotContains('/usr/bin', ExecRecorder::$execCommand); + self::assertStringContainsString('foo', ExecRecorder::$execCommand); + self::assertStringNotContainsString('/usr/bin', ExecRecorder::$execCommand); } /** @@ -67,11 +60,12 @@ public function isRunningUsesPid(): void { $process = new Process('/usr/bin/foo', '-bar'); $process->setPid(1337); + ExecRecorder::setReturnExecOutput(['1337 foo']); $process->isRunning(); self::assertTrue((bool)ExecRecorder::$execCalled); - self::assertContains('1337', ExecRecorder::$execCommand); + self::assertStringContainsString('1337', ExecRecorder::$execCommand); } /** @@ -125,11 +119,13 @@ public function stopStopsProcess(): void { $process = new Process('/usr/bin/foo', '-bar'); $process->setPid(1337); - ExecRecorder::setReturnExecOutput(['1337 /usr/bin/foo -bar']); + $outputLinesForIsRunningCall = ['1337 /usr/bin/foo -bar']; + ExecRecorder::setReturnExecOutput($outputLinesForIsRunningCall); $running = $process->isRunning(); self::assertTrue($running); + ExecRecorder::setReturnExecOutput($outputLinesForIsRunningCall); $stopped = $process->stop(); self::assertTrue($stopped); diff --git a/Tests/Unit/Service/Extractor/MetaDataExtractorTest.php b/Tests/Unit/Service/Extractor/MetaDataExtractorTest.php index f3c5c0fac..907b62a38 100644 --- a/Tests/Unit/Service/Extractor/MetaDataExtractorTest.php +++ b/Tests/Unit/Service/Extractor/MetaDataExtractorTest.php @@ -1,38 +1,32 @@ - * 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. +/* + * This file is part of the TYPO3 CMS project. * - * The GNU General Public License can be found at - * http://www.gnu.org/copyleft/gpl.html. + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. * - * 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. + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. * - * This copyright notice MUST APPEAR in all copies of the script! - ***************************************************************/ + * The TYPO3 project - inspiring people to share! + */ use ApacheSolrForTypo3\Tika\Service\Extractor\MetaDataExtractor; use ApacheSolrForTypo3\Tika\Service\Tika\AppService; use ApacheSolrForTypo3\Tika\Tests\Unit\UnitTestCase; +use PHPUnit\Framework\MockObject\MockObject; use TYPO3\CMS\Core\Resource\File; /** * Class MetaDataExtractorTest + * + * @author Timo Hund */ class MetaDataExtractorTest extends UnitTestCase { @@ -82,10 +76,10 @@ public function extractMetaDataReturnsNormalizedMetaData(): void { $fakedTikaExtractResponse = $this->getFakedExtratorResponseForJGEPImage(); - /** @var $metaDataExtractor MetaDataExtractor */ + /** @var $metaDataExtractor MetaDataExtractor|MockObject */ $metaDataExtractor = $this->getMockBuilder(MetaDataExtractor::class) ->setConstructorArgs([[]]) - ->setMethods(['getExtractedMetaDataFromTikaService']) + ->onlyMethods(['getExtractedMetaDataFromTikaService']) ->getMock(); $metaDataExtractor->expects(self::once())->method('getExtractedMetaDataFromTikaService')->willReturn( $fakedTikaExtractResponse @@ -114,7 +108,7 @@ public function canProcessReturnsFalseForExeFile(): void $metaDataExtractor = $this->getMockBuilder(MetaDataExtractor::class) ->setConstructorArgs([[]]) - ->setMethods(['getExtractor'])->getMock(); + ->onlyMethods(['getExtractor'])->getMock(); $metaDataExtractor->expects(self::once())->method('getExtractor')->willReturn($tikaAppServiceMock); self::assertFalse($metaDataExtractor->canProcess($exeFileMock)); } @@ -134,7 +128,7 @@ public function canProcessReturnsTrueForSxwFile(): void $metaDataExtractor = $this->getMockBuilder(MetaDataExtractor::class) ->setConstructorArgs([[]]) - ->setMethods(['getExtractor'])->getMock(); + ->onlyMethods(['getExtractor'])->getMock(); $metaDataExtractor->expects(self::once())->method('getExtractor')->willReturn($tikaAppServiceMock); self::assertTrue($metaDataExtractor->canProcess($exeFileMock)); } diff --git a/Tests/Unit/Service/Tika/AbstractServiceTest.php b/Tests/Unit/Service/Tika/AbstractServiceTest.php index 863053bc3..7c08c7cc2 100644 --- a/Tests/Unit/Service/Tika/AbstractServiceTest.php +++ b/Tests/Unit/Service/Tika/AbstractServiceTest.php @@ -1,35 +1,31 @@ - * All rights reserved +/* + * This file is part of the TYPO3 CMS project. * - * 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. + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. * - * The GNU General Public License can be found at - * http://www.gnu.org/copyleft/gpl.html. + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. * - * 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! - ***************************************************************/ + * The TYPO3 project - inspiring people to share! + */ use ApacheSolrForTypo3\Tika\Tests\Unit\UnitTestCase; +/** + * Class AbstractServiceTest + * + * @autor Ingo Renner + */ class AbstractServiceTest extends UnitTestCase { @@ -39,7 +35,7 @@ class AbstractServiceTest extends UnitTestCase public function constructorCallsInitializeService(): void { $service = $this->getMockBuilder(AbstractService::class) - ->setMethods(['initializeService']) + ->onlyMethods(['initializeService']) ->disableOriginalConstructor() ->getMockForAbstractClass(); diff --git a/Tests/Unit/UnitTestCase.php b/Tests/Unit/UnitTestCase.php index 4bc8b5123..ccba7358b 100644 --- a/Tests/Unit/UnitTestCase.php +++ b/Tests/Unit/UnitTestCase.php @@ -1,52 +1,42 @@ - * All rights reserved +/* + * This file is part of the TYPO3 CMS project. * - * 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. + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. * - * The GNU General Public License can be found at - * http://www.gnu.org/copyleft/gpl.html. + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. * - * 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! - ***************************************************************/ + * The TYPO3 project - inspiring people to share! + */ -use Nimut\TestingFramework\TestCase\UnitTestCase as TYPO3UnitTestCase; use PHPUnit\Framework\MockObject\MockObject; use ReflectionClass; -use ReflectionException; +use TYPO3\TestingFramework\Core\Unit\UnitTestCase as TYPO3TestingFrameworkUnitTestCase; /** * Testcase to check if the status check returns the expected results. * - * @author Timo Schmidt + * @author Timo Hund */ -class UnitTestCase extends TYPO3UnitTestCase +class UnitTestCase extends TYPO3TestingFrameworkUnitTestCase { /** * Creates configuration to be used fo tests * * @return array */ - protected function getConfiguration() + protected function getConfiguration(): array { - $tikaVersion = getenv('TIKA_VERSION') ? getenv('TIKA_VERSION') : '1.24.1'; - $tikaPath = getenv('TIKA_PATH') ? getenv('TIKA_PATH') : '/opt/tika'; + $tikaVersion = getenv('TIKA_VERSION') ?: '1.24.1'; + $tikaPath = getenv('TIKA_PATH') ?: '/opt/tika'; $envVarNamePrefix = 'TESTING_TIKA_'; return [ @@ -79,7 +69,7 @@ protected function getConfiguration() * @param string $className * @return MockObject */ - protected function getDumbMock($className) + protected function getDumbMock(string $className): MockObject { return $this->getMockBuilder($className)->disableOriginalConstructor()->getMock(); } @@ -91,7 +81,7 @@ protected function getDumbMock($className) * @return string * @throws string */ - protected function getFixturePath($fixtureName) + protected function getFixturePath(string $fixtureName): string { return $this->getRuntimeDirectory() . '/Fixtures/' . $fixtureName; } @@ -100,9 +90,8 @@ protected function getFixturePath($fixtureName) * Returns the directory on runtime. * * @return string - * @throws ReflectionException */ - protected function getRuntimeDirectory() + protected function getRuntimeDirectory(): string { $rc = new ReflectionClass(get_class($this)); return dirname($rc->getFileName()); diff --git a/composer.json b/composer.json index dfe6fe5c9..956c4e477 100644 --- a/composer.json +++ b/composer.json @@ -6,7 +6,7 @@ "prefer-stable": true, "license": "GPL-3.0-or-later", "keywords": ["typo3", "cms", "tika", "meta data", "language", "text", "extraction"], - "homepage": "http://www.typo3-solr.com", + "homepage": "https://www.typo3-solr.com", "authors": [ { "name": "Ingo Renner", @@ -15,8 +15,10 @@ } ], "support": { - "email": "typo3-project-solr@lists.typo3.org", - "issues": "https://github.com/TYPO3-Solr/ext-tika/issues", + "email": "solr-eb-support@dkd.de", + "issues": "https://github.com/TYPO3-Solr/ext-solr/issues", + "forum": "https://talk.typo3.org", + "slack": "https://typo3.slack.com/app_redirect?channel=C02FF05Q4", "source": "https://github.com/TYPO3-Solr/ext-tika" }, "replace": { @@ -25,18 +27,19 @@ "require": { "ext-json": "*", "ext-pdo": "*", - - "typo3/cms-core": "^10.4.10 || ^11.5", - "typo3/cms-backend": "*", - "typo3/cms-extbase": "*", - "typo3/cms-reports": "*", - "typo3/cms-filemetadata": "*" + "typo3/cms-core": "^11.5", + "typo3/cms-backend": "^11.5", + "typo3/cms-extbase": "^11.5", + "typo3/cms-reports": "^11.5", + "typo3/cms-filemetadata": "^11.5" }, "require-dev": { - "phpunit/phpunit": "^7.5.6 || ^8", - "nimut/testing-framework": "^5.0.0", - "apache-solr-for-typo3/solr": "dev-release-11.1.x", - "psr/log": "*" + "psr/log": "*", + "phpunit/phpunit": "^9.5", + "phpspec/prophecy-phpunit":"*", + "typo3/testing-framework": "^6.12", + "apache-solr-for-typo3/solr": "dev-release-11.5.x", + "typo3/coding-standards": ">=0.5.0" }, "suggest": { "apache-solr-for-typo3/solr": "Allows to use Solr Cell - Apache Tika embedded in Apache Solr." @@ -53,6 +56,7 @@ } }, "config": { + "allow-plugins": true, "optimize-autoloader": true, "vendor-dir": ".Build/vendor", "bin-dir": ".Build/bin" @@ -65,7 +69,7 @@ }, "extra": { "branch-alias": { - "dev-main": "11.0.x-dev" + "dev-release-11.0.x": "11.0.x-dev" }, "typo3/cms": { "extension-key": "tika", diff --git a/ext_emconf.php b/ext_emconf.php index 124e784d3..0724ed5c4 100644 --- a/ext_emconf.php +++ b/ext_emconf.php @@ -1,24 +1,31 @@ 'Apache Tika for TYPO3', 'description' => 'Provides Tika services for TYPO3 to detect a document\'s language, extract meta data, and extract content from files. Can either use a stand alone Tika executable or Tika integrated in a Solr server with an activated extracting request handler.', 'version' => '11.0.0', 'state' => 'stable', 'category' => 'services', - 'author' => 'Ingo Renner, Timo Hund, Markus Friedrich', - 'author_email' => 'ingo@typo3.org', + 'author' => 'Ingo Renner, Timo Hund, Markus Friedrich, Rafael Kähm', + 'author_email' => 'solr-eb-support@dkd.de', 'author_company' => 'dkd Internet Service GmbH', 'clearCacheOnLoad' => true, 'constraints' => [ 'depends' => [ - 'typo3' => '10.4.10-11.5.99', + 'typo3' => '11.5.4-11.5.99', 'filemetadata' => '', ], 'conflicts' => [], 'suggests' => [ - 'solr' => '11.1.0-0.0.0', + 'solr' => '11.5.0-0.0.0', + ], + ], + 'autoload' => [ + 'psr-4' => [ + 'ApacheSolrForTypo3\\Tika\\' => 'Classes/', ], ], '_md5_values_when_last_written' => '', diff --git a/ext_localconf.php b/ext_localconf.php index 62161e050..b3413712d 100644 --- a/ext_localconf.php +++ b/ext_localconf.php @@ -1,8 +1,9 @@ registerExtractionService(\ApacheSolrForTypo3\Tika\Service\Extractor\MetaDataExtractor::class); $extConf = \ApacheSolrForTypo3\Tika\Util::getTikaExtensionConfiguration(); @@ -23,7 +25,8 @@ } unset($extConf); -$textExtractorRegistry = \TYPO3\CMS\Core\Resource\TextExtraction\TextExtractorRegistry::getInstance(); +/* @var \TYPO3\CMS\Core\Resource\TextExtraction\TextExtractorRegistry $textExtractorRegistry */ +$textExtractorRegistry = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Resource\TextExtraction\TextExtractorRegistry::class); $textExtractorRegistry->registerTextExtractor(\ApacheSolrForTypo3\Tika\Service\Extractor\TextExtractor::class); // Add Context Menu and JS diff --git a/ext_tables.php b/ext_tables.php index a7cd262e4..87767103a 100644 --- a/ext_tables.php +++ b/ext_tables.php @@ -1,8 +1,9 @@ Date: Sat, 29 Jan 2022 15:45:01 +0100 Subject: [PATCH 19/20] [TASK] Fix scrutinizer issues on release-11.0.x Fixes: #133 --- Classes/ContextMenu/Preview.php | 3 +-- .../Controller/Backend/PreviewController.php | 18 ++++++++++--- .../TikaControlPanelModuleController.php | 10 +++++--- Classes/Process.php | 8 +----- Classes/Report/TikaStatus.php | 24 ++++++++++-------- .../Service/Extractor/AbstractExtractor.php | 2 +- Classes/Service/Tika/AbstractService.php | 2 +- Classes/Service/Tika/AppService.php | 16 ++++++------ Classes/Service/Tika/ServerService.php | 25 +++++++++++++++---- Classes/Utility/ShellUtility.php | 3 +-- README.md | 2 ++ composer.json | 1 + 12 files changed, 70 insertions(+), 44 deletions(-) diff --git a/Classes/ContextMenu/Preview.php b/Classes/ContextMenu/Preview.php index 271c22618..fd2dcd1a7 100644 --- a/Classes/ContextMenu/Preview.php +++ b/Classes/ContextMenu/Preview.php @@ -100,9 +100,8 @@ public function addItems(array $items): array { $this->initDisabledItems(); $localItems = $this->prepareItems($this->itemsConfiguration); - $items = $items + $localItems; //passes array of items to the next item provider - return $items; + return $items + $localItems; } /** diff --git a/Classes/Controller/Backend/PreviewController.php b/Classes/Controller/Backend/PreviewController.php index c6a5d9876..ef978113e 100644 --- a/Classes/Controller/Backend/PreviewController.php +++ b/Classes/Controller/Backend/PreviewController.php @@ -23,6 +23,7 @@ use ApacheSolrForTypo3\Tika\Service\Tika\ServiceFactory; use ApacheSolrForTypo3\Tika\Service\Tika\SolrCellService; use Psr\Http\Client\ClientExceptionInterface; +use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Throwable; use TYPO3\CMS\Core\Http\HtmlResponse; @@ -42,7 +43,7 @@ class PreviewController * @return string|Response * @throws ClientExceptionInterface */ - public function previewAction(ServerRequestInterface $request) + public function previewAction(ServerRequestInterface $request): ResponseInterface { $response = new HtmlResponse(''); if (!$this->getIsAdmin()) { @@ -55,11 +56,20 @@ public function previewAction(ServerRequestInterface $request) $file = $this->getFileResourceFactory()->getFileObjectFromCombinedIdentifier($identifier); $tikaService = $this->getConfiguredTikaService(); - $metadata = $tikaService->extractMetaData($file); - $content = $tikaService->extractText($file); + $metadata = $tikaService->extractMetaData( + /** @scrutinizer ignore-type because checked in {@link \ApacheSolrForTypo3\Tika\ContextMenu\Preview::canHandle()} */ + $file + ); + $content = $tikaService->extractText( + /** @scrutinizer ignore-type because checked in {@link \ApacheSolrForTypo3\Tika\ContextMenu\Preview::canHandle()} */ + $file + ); try { - $language = $tikaService->detectLanguageFromFile($file); + $language = $tikaService->detectLanguageFromFile( + /** @scrutinizer ignore-type because checked in {@link \ApacheSolrForTypo3\Tika\ContextMenu\Preview::canHandle()} */ + $file + ); } catch (Throwable $e) { $language = 'not detectable'; } diff --git a/Classes/Controller/Backend/SolrModule/TikaControlPanelModuleController.php b/Classes/Controller/Backend/SolrModule/TikaControlPanelModuleController.php index 1ce1f136a..b7f974996 100644 --- a/Classes/Controller/Backend/SolrModule/TikaControlPanelModuleController.php +++ b/Classes/Controller/Backend/SolrModule/TikaControlPanelModuleController.php @@ -26,6 +26,7 @@ use ApacheSolrForTypo3\Tika\Util; use Psr\Http\Client\ClientExceptionInterface; use Psr\Http\Message\ResponseInterface; +use Throwable; use TYPO3\CMS\Backend\Template\ModuleTemplate; use TYPO3\CMS\Core\Http\RedirectResponse; use TYPO3\CMS\Core\Messaging\FlashMessage; @@ -48,7 +49,7 @@ class TikaControlPanelModuleController extends AbstractModuleController protected array $tikaConfiguration = []; /** - * @var AppService|ServerService|SolrCellService + * @var AbstractService|AppService|ServerService|SolrCellService */ protected $tikaService; @@ -162,12 +163,12 @@ public function startServerAction(): ResponseInterface */ public function stopServerAction(): ResponseInterface { - $this->tikaService->/** @scrutinizer ignore-call */stopServer(); + $this->tikaService->/** @scrutinizer ignore-call */ stopServer(); // give it some time to stop sleep(2); - if (!$this->tikaService->isServerRunning()) { + if (!$this->tikaService->/** @scrutinizer ignore-call */ isServerRunning()) { $this->addFlashMessage( 'Tika server stopped.', FlashMessage::OK @@ -182,6 +183,7 @@ public function stopServerAction(): ResponseInterface * * @return string Tika server version string * @throws ClientExceptionInterface + * @throws Throwable */ protected function getTikaServerVersion(): string { @@ -195,7 +197,7 @@ protected function getTikaServerVersion(): string */ protected function isTikaServerRunning(): bool { - return $this->tikaService->isServerRunning(); + return $this->tikaService->/** @scrutinizer ignore-call */ isServerRunning(); } /** diff --git a/Classes/Process.php b/Classes/Process.php index c87293db0..a7f8ae9a5 100644 --- a/Classes/Process.php +++ b/Classes/Process.php @@ -221,12 +221,6 @@ public function stop(): bool $command = 'kill ' . $this->pid; exec($command); - if ($this->isRunning() == false) { - $stopped = true; - } else { - $stopped = false; - } - - return $stopped; + return !$this->isRunning(); } } diff --git a/Classes/Report/TikaStatus.php b/Classes/Report/TikaStatus.php index 3c3199dd4..6b7e8be9d 100644 --- a/Classes/Report/TikaStatus.php +++ b/Classes/Report/TikaStatus.php @@ -26,6 +26,8 @@ use Psr\Log\LoggerAwareInterface; use Psr\Log\LoggerAwareTrait; use Solarium\QueryType\Extract\Query; +use TYPO3\CMS\Core\Configuration\Exception\ExtensionConfigurationExtensionNotConfiguredException; +use TYPO3\CMS\Core\Configuration\Exception\ExtensionConfigurationPathDoesNotExistException; use TYPO3\CMS\Core\Utility\CommandUtility; use TYPO3\CMS\Core\Utility\ExtensionManagementUtility; use TYPO3\CMS\Core\Utility\GeneralUtility; @@ -47,11 +49,13 @@ class TikaStatus implements StatusProviderInterface, LoggerAwareInterface * * @var array */ - protected $tikaConfiguration = []; + protected array $tikaConfiguration = []; /** * Constructor, reads the extension's configuration * @param array|null $extensionConfiguration + * @throws ExtensionConfigurationExtensionNotConfiguredException + * @throws ExtensionConfigurationPathDoesNotExistException */ public function __construct(array $extensionConfiguration = null) { @@ -94,7 +98,7 @@ public function getStatus() * * @return Status */ - protected function getOkStatus() + protected function getOkStatus(): Status { return GeneralUtility::makeInstance( Status::class, @@ -136,7 +140,7 @@ protected function getJavaInstalledStatus(int $severity = Status::ERROR): Status * * @return Status */ - protected function getAppConfigurationStatus() + protected function getAppConfigurationStatus(): Status { $status = $this->getOkStatus(); if (!$this->isFilePresent($this->tikaConfiguration['tikaPath'])) { @@ -158,7 +162,7 @@ protected function getAppConfigurationStatus() * @return Status * @throws Exception */ - protected function getServerConfigurationStatus() + protected function getServerConfigurationStatus(): Status { $status = $this->getOkStatus(); @@ -181,7 +185,7 @@ protected function getServerConfigurationStatus() * * @return Status */ - protected function getSolrCellConfigurationStatus() + protected function getSolrCellConfigurationStatus(): Status { $status = $this->getOkStatus(); @@ -228,7 +232,7 @@ protected function getSolrCellConfigurationStatus() /** * @return SolrConnection */ - protected function getSolrConnectionFromTikaConfiguration() + protected function getSolrConnectionFromTikaConfiguration(): SolrConnection { $solrConfig = [ 'host' => $this->tikaConfiguration['solrHost'], @@ -248,7 +252,7 @@ protected function getSolrConnectionFromTikaConfiguration() * @return ServerService * @noinspection PhpIncompatibleReturnTypeInspection */ - protected function getTikaServiceFromTikaConfiguration() + protected function getTikaServiceFromTikaConfiguration(): ServerService { return GeneralUtility::makeInstance( ServerService::class, @@ -261,7 +265,7 @@ protected function getTikaServiceFromTikaConfiguration() * * @return bool */ - protected function isJavaInstalled() + protected function isJavaInstalled(): bool { return CommandUtility::checkCommand('java'); } @@ -272,7 +276,7 @@ protected function isJavaInstalled() * @param string $fileName * @return bool */ - protected function isFilePresent($fileName) + protected function isFilePresent(string $fileName): bool { return is_file(FileUtility::getAbsoluteFilePath($fileName)); } @@ -286,7 +290,7 @@ protected function isFilePresent($fileName) */ protected function writeDevLog(string $message, string $extKey, array $data = []): void { - $this->logger->debug( + $this->logger->/** @scrutinizer ignore-call */ debug( $message, [ 'extension' => $extKey, diff --git a/Classes/Service/Extractor/AbstractExtractor.php b/Classes/Service/Extractor/AbstractExtractor.php index d85f47601..ebb509896 100644 --- a/Classes/Service/Extractor/AbstractExtractor.php +++ b/Classes/Service/Extractor/AbstractExtractor.php @@ -116,7 +116,7 @@ protected function log(string $message, array $data = []): void if (!$this->configuration['logging']) { return; } - $this->logger->log( + $this->logger->/** @scrutinizer ignore-call */ log( LogLevel::DEBUG, // Previous value 0 $message, $data diff --git a/Classes/Service/Tika/AbstractService.php b/Classes/Service/Tika/AbstractService.php index 9defdcfda..db4f4c7d2 100644 --- a/Classes/Service/Tika/AbstractService.php +++ b/Classes/Service/Tika/AbstractService.php @@ -69,7 +69,7 @@ protected function log(string $message, array $data = [], $severity = LogLevel:: if (empty($this->configuration['logging'])) { return; } - $this->logger->log( + $this->logger->/** @scrutinizer ignore-call */ log( $severity, $message, $data diff --git a/Classes/Service/Tika/AppService.php b/Classes/Service/Tika/AppService.php index 52e3a48d2..45502273c 100644 --- a/Classes/Service/Tika/AppService.php +++ b/Classes/Service/Tika/AppService.php @@ -61,13 +61,13 @@ protected function initializeService(): void */ public function getTikaVersion(): string { - $tikaCommand = CommandUtility::getCommand('java') + $tikaCommand = /** @scrutinizer ignore-type */ CommandUtility::getCommand('java') . ' -Dfile.encoding=UTF8' // forces UTF8 output . $this->getAdditionalCommandOptions() . ' -jar ' . escapeshellarg(FileUtility::getAbsoluteFilePath($this->configuration['tikaPath'])) . ' -V'; - return shell_exec($tikaCommand); + return shell_exec($tikaCommand) ?: ''; } /** @@ -80,7 +80,7 @@ public function extractText(FileInterface $file): string { $localTempFilePath = $file->getForLocalProcessing(false); $tikaCommand = ShellUtility::getLanguagePrefix() - . CommandUtility::getCommand('java') + . /** @scrutinizer ignore-type */ CommandUtility::getCommand('java') . ' -Dfile.encoding=UTF8' // forces UTF8 output . $this->getAdditionalCommandOptions() . ' -jar ' . escapeshellarg(FileUtility::getAbsoluteFilePath($this->configuration['tikaPath'])) @@ -111,7 +111,7 @@ public function extractMetaData(FileInterface $file): array { $localTempFilePath = $file->getForLocalProcessing(false); $tikaCommand = ShellUtility::getLanguagePrefix() - . CommandUtility::getCommand('java') + . /** @scrutinizer ignore-type */ CommandUtility::getCommand('java') . ' -Dfile.encoding=UTF8' . $this->getAdditionalCommandOptions() . ' -jar ' . escapeshellarg(FileUtility::getAbsoluteFilePath($this->configuration['tikaPath'])) @@ -177,14 +177,14 @@ public function detectLanguageFromString(string $input): string protected function detectLanguageFromLocalFile(string $localFilePath): string { $tikaCommand = ShellUtility::getLanguagePrefix() - . CommandUtility::getCommand('java') + . /** @scrutinizer ignore-type */ CommandUtility::getCommand('java') . ' -Dfile.encoding=UTF8' . $this->getAdditionalCommandOptions() . ' -jar ' . escapeshellarg(FileUtility::getAbsoluteFilePath($this->configuration['tikaPath'])) . ' -l' . ' ' . ShellUtility::escapeShellArgument($localFilePath); - $language = trim(shell_exec($tikaCommand)); + $language = trim(shell_exec($tikaCommand) ?: ''); $this->log( 'Language Detection using local Tika', @@ -315,12 +315,12 @@ public function isAvailable(): bool protected function getMimeTypeOutputFromTikaJar(): string { $tikaCommand = ShellUtility::getLanguagePrefix() - . CommandUtility::getCommand('java') + . /** @scrutinizer ignore-type */ CommandUtility::getCommand('java') . ' -Dfile.encoding=UTF8' . $this->getAdditionalCommandOptions() . ' -jar ' . escapeshellarg(FileUtility::getAbsoluteFilePath($this->configuration['tikaPath'])) . ' --list-supported-types'; - return trim(shell_exec($tikaCommand)); + return trim(shell_exec($tikaCommand) ?: ''); } } diff --git a/Classes/Service/Tika/ServerService.php b/Classes/Service/Tika/ServerService.php index cd5b40573..30e6229c7 100644 --- a/Classes/Service/Tika/ServerService.php +++ b/Classes/Service/Tika/ServerService.php @@ -20,6 +20,8 @@ use ApacheSolrForTypo3\Tika\Process; use ApacheSolrForTypo3\Tika\Utility\FileUtility; use GuzzleHttp\Exception\BadResponseException; +use Psr\Container\ContainerExceptionInterface; +use Psr\Container\NotFoundExceptionInterface; use Psr\Http\Client\ClientExceptionInterface; use Psr\Http\Client\ClientInterface; use Psr\Http\Message\RequestInterface; @@ -69,6 +71,9 @@ class ServerService extends AbstractService /** * Service initialization * + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + * * @noinspection PhpUnused */ protected function initializeService(): void @@ -113,9 +118,7 @@ protected function getStartCommand(): string $command = '-jar ' . escapeshellarg($tikaJar); $command .= ' -p ' . escapeshellarg($this->configuration['tikaServerPort']); - $command = escapeshellcmd($command); - - return $command; + return escapeshellcmd($command); } /** @@ -138,6 +141,9 @@ public function startServer(): void public function stopServer(): void { $pid = $this->getServerPid(); + if (null === $pid) { + return; + } $process = $this->getProcess(); $process->setPid($pid); @@ -236,6 +242,7 @@ public function getTikaServerUri(): Uri * * @return string Tika server version string * @throws ClientExceptionInterface + * @throws Throwable */ public function getTikaVersion(): string { @@ -254,6 +261,7 @@ public function getTikaVersion(): string * @param RequestInterface $request * @return string Tika output * @throws ClientExceptionInterface + * @throws Throwable */ protected function queryTika(RequestInterface $request): string { @@ -292,6 +300,7 @@ protected function queryTika(RequestInterface $request): string * @param FileInterface $file * @return string * @throws ClientExceptionInterface + * @throws Throwable */ public function extractText(FileInterface $file): string { @@ -321,11 +330,12 @@ public function extractText(FileInterface $file): string } /** - * Takes a file reference and extracts its meta data. + * Takes a file reference and extracts its meta-data. * * @param FileInterface $file * @return array * @throws ClientExceptionInterface + * @throws Throwable */ public function extractMetaData(FileInterface $file): array { @@ -361,6 +371,7 @@ public function extractMetaData(FileInterface $file): array * @param FileInterface $file * @return string * @throws ClientExceptionInterface + * @throws Throwable */ public function detectLanguageFromFile(FileInterface $file): string { @@ -394,6 +405,7 @@ public function detectLanguageFromFile(FileInterface $file): string * @param string $input * @return string * @throws ClientExceptionInterface + * @throws Throwable */ public function detectLanguageFromString(string $input): string { @@ -413,6 +425,7 @@ public function detectLanguageFromString(string $input): string * * @return array * @throws ClientExceptionInterface + * @throws Throwable */ public function getSupportedMimeTypes(): array { @@ -430,10 +443,11 @@ public function getSupportedMimeTypes(): array * * @return string * @throws ClientExceptionInterface + * @throws Throwable */ protected function getMimeTypeJsonFromTikaServer(): string { - $request = $this->createRequestForEndpoint('/mime-types', 'GET') + $request = $this->createRequestForEndpoint('/mime-types') ->withAddedHeader('Content-Type', 'application/octet-stream') ->withAddedHeader('Accept', 'application/json') ->withAddedHeader('Connection', 'close') @@ -447,6 +461,7 @@ protected function getMimeTypeJsonFromTikaServer(): string * * @return array * @throws ClientExceptionInterface + * @throws Throwable */ protected function buildSupportedMimeTypes(): array { diff --git a/Classes/Utility/ShellUtility.php b/Classes/Utility/ShellUtility.php index a30ffb1b2..9554b17c1 100644 --- a/Classes/Utility/ShellUtility.php +++ b/Classes/Utility/ShellUtility.php @@ -27,7 +27,7 @@ class ShellUtility /** * @return string */ - public static function getLanguagePrefix() + public static function getLanguagePrefix(): string { if (!empty($GLOBALS['TYPO3_CONF_VARS']['SYS']['UTF8filesystem']) && !Environment::isWindows()) { return 'LC_CTYPE="' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLocale'] . '" '; @@ -43,7 +43,6 @@ public static function getLanguagePrefix() */ public static function escapeShellArgument(string $argument): string { - $currentLocale = null; $isUTF8Filesystem = !empty($GLOBALS['TYPO3_CONF_VARS']['SYS']['UTF8filesystem']); if ($isUTF8Filesystem) { $currentLocale = setlocale(LC_CTYPE, 0); diff --git a/README.md b/README.md index 1b2ee2e16..c8558650a 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,9 @@ [![Code Coverage](https://scrutinizer-ci.com/g/TYPO3-Solr/ext-tika/badges/coverage.png?b=release-11.0.x)](https://scrutinizer-ci.com/g/TYPO3-Solr/ext-tika/?branch=release-11.0.x) [![Latest Stable Version](https://poser.pugx.org/apache-solr-for-typo3/tika/v/stable)](https://packagist.org/packages/apache-solr-for-typo3/tika) [![License](https://poser.pugx.org/apache-solr-for-typo3/tika/license)](https://packagist.org/packages/apache-solr-for-typo3/tika) +[![Total Downloads](http://poser.pugx.org/apache-solr-for-typo3/tika/downloads)](https://packagist.org/packages/apache-solr-for-typo3/tika) [![Monthly Downloads](https://poser.pugx.org/apache-solr-for-typo3/tika/d/monthly)](https://packagist.org/packages/apache-solr-for-typo3/tika) +[![PHP Version Require](http://poser.pugx.org/apache-solr-for-typo3/tika/require/php)](https://packagist.org/packages/apache-solr-for-typo3/tika) A TYPO3 CMS extension that provides Apache Tika functionality including diff --git a/composer.json b/composer.json index 956c4e477..3b8c161f4 100644 --- a/composer.json +++ b/composer.json @@ -25,6 +25,7 @@ "typo3-ter/tika": "self.version" }, "require": { + "php": "^7.4 || ^8.0", "ext-json": "*", "ext-pdo": "*", "typo3/cms-core": "^11.5", From 24f2929b3f5f6dda271d9d48deead1c166e514c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20K=C3=A4hm?= Date: Sun, 30 Jan 2022 13:44:56 +0100 Subject: [PATCH 20/20] [TASK] Update Apache TIKA to v1.27 on release-11.0.x We must upgrade TIKA App/Server Versions to 1.27, because Apache Solr 8.11.1 uses the TIKA v1.27. Fixes: #183 --- .editorconfig | 4 + .github/workflows/ci.yml | 20 +- .scrutinizer.yml | 7 +- Build/Helpers/download_tika_binaries.sh | 269 ++++++++++++++++++ Build/Test/bootstrap.sh | 175 ++++-------- .../Controller/Backend/PreviewController.php | 3 +- Resources/Tika/tika-server | 2 +- .../Tika/ServiceIntegrationTestCase.php | 8 +- Tests/Unit/UnitTestCase.php | 2 +- composer.json | 42 ++- 10 files changed, 383 insertions(+), 149 deletions(-) create mode 100755 Build/Helpers/download_tika_binaries.sh diff --git a/.editorconfig b/.editorconfig index 867955b22..11c238360 100644 --- a/.editorconfig +++ b/.editorconfig @@ -39,6 +39,10 @@ indent_style = tab [package.json] indent_size = 2 +# composer.json (Reason: git history in composer.json) +[composer.json] +indent_size = 2 + # TypoScript [*.{typoscript,tsconfig}] indent_size = 2 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 96c0e083a..febc068ae 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,6 @@ on: env: CI_BUILD_DIRECTORY: '/home/runner/work/ext-tika/ext-tika/.Build' - TIKA_VERSION: '1.24.1' TIKA_PATH: '/home/runner/work/ext-tika/ext-tika/.Build/data-tika-binaries' EXT_SOLR_VERSION: 'dev-release-11.5.x' @@ -67,6 +66,13 @@ jobs: sudo mkdir -p ${{ env.CI_BUILD_DIRECTORY }}/data-{solr,mysql,tika-binaries} \ && sudo chown $USER ${{ env.CI_BUILD_DIRECTORY }}/data-{mysql,tika-binaries} \ && sudo chown 8983:8983 ${{ env.CI_BUILD_DIRECTORY }}/data-solr + - + name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.PHP }} + coverage: xdebug + tools: composer:v2 - name: 'Start Docker: Solr, Tika, MySQL' run: | @@ -77,19 +83,13 @@ jobs: sudo chmod g+w "$SOLR_VOLUME_PATH" docker volume create --name "$LOCAL_VOLUME_NAME" --opt type=none --opt device="$SOLR_VOLUME_PATH" --opt o=bind docker run --rm --name="$SOLR_CONTAINER_NAME" -d -p 127.0.0.1:8983:8983 -v "$LOCAL_VOLUME_NAME":"/var/solr" "typo3solr/ext-solr:$SOLR_IMAGE_TAG" - docker run -d -p 9998:9998 apache/tika:$TIKA_VERSION"-full" + docker run -d -p 9998:9998 apache/tika:$(composer tika:version)"-full" docker ps - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.PHP }} - coverage: xdebug - tools: composer:v2 - name: CI-Bootstrap run: | - ./Build/Test/bootstrap.sh --skip-solr-install --skip-tika-server-install + composer info + ./Build/Test/bootstrap.sh echo "Current Size of EXT:tika build Artefacts: " \ && sudo du -sh "${{ env.CI_BUILD_DIRECTORY }}" - diff --git a/.scrutinizer.yml b/.scrutinizer.yml index 452c5d4f2..372cee219 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -51,8 +51,11 @@ build_failure_conditions: build: environment: - # We want to test with the smallest supported by TYPO3 PHP version - php: 7.4 + # We want to test with the smallest supported TYPO3 PHP version + php: + version: 7.4.27 + pecl_extensions: + - zip nodes: analysis: tests: diff --git a/Build/Helpers/download_tika_binaries.sh b/Build/Helpers/download_tika_binaries.sh new file mode 100755 index 000000000..47fbc1cc7 --- /dev/null +++ b/Build/Helpers/download_tika_binaries.sh @@ -0,0 +1,269 @@ +#!/usr/bin/env bash + +## BASH COLORS +RED='\033[0;31m' +GREEN='\033[0;32m' +NC='\033[0m' + +Help() +{ +# Usage via composer --------------------------------------------------------------------------------------------------- + if [[ -n "$CALLED_VIA_COMPOSER" ]]; then + cat <<-EOF + +Usage: + $(basename ${COMPOSER_BINARY}) tika:download + $(basename ${COMPOSER_BINARY}) tika:download [--] [] + $(basename ${COMPOSER_BINARY}) tika:download [--] [] [