From 1d07441c49cd6a25fb2b421ee604c7b18c5f35ae Mon Sep 17 00:00:00 2001 From: Joerg Boesche <typo3@joergboesche.de> Date: Fri, 15 Sep 2017 10:45:40 +0200 Subject: [PATCH] [FEATURE] Hook to modify the display results before FluidView assignment To modify the display result rows before data is assigned to the fluid view there is a new hook inside the `getDisplayResults()` method called `getDisplayResults_postProc`. Resolves: #82488 Releases: master Change-Id: I2f0ac073692fb28b9c71a18def027c71a418606f Reviewed-on: https://review.typo3.org/54148 Reviewed-by: Jigal van Hemert <jigal.van.hemert@typo3.org> Tested-by: Jigal van Hemert <jigal.van.hemert@typo3.org> --- ...-HookToModifyResultsBeforeAssignToView.rst | 51 ++++++++++ .../Classes/Controller/SearchController.php | 5 + .../Classes/Example/PluginHook.php | 19 ++++ .../Unit/Classes/Example/PluginHookTest.php | 96 +++++++++++++++++++ 4 files changed, 171 insertions(+) create mode 100644 typo3/sysext/core/Documentation/Changelog/master/Feature-82488-HookToModifyResultsBeforeAssignToView.rst create mode 100644 typo3/sysext/indexed_search/Tests/Unit/Classes/Example/PluginHookTest.php diff --git a/typo3/sysext/core/Documentation/Changelog/master/Feature-82488-HookToModifyResultsBeforeAssignToView.rst b/typo3/sysext/core/Documentation/Changelog/master/Feature-82488-HookToModifyResultsBeforeAssignToView.rst new file mode 100644 index 000000000000..98d4d5074bf5 --- /dev/null +++ b/typo3/sysext/core/Documentation/Changelog/master/Feature-82488-HookToModifyResultsBeforeAssignToView.rst @@ -0,0 +1,51 @@ +.. include:: ../../Includes.txt + +======================================================================================= +Feature: #82488 - Possibility to modify the display results before FluidView assignment +======================================================================================= + +See :issue:`82488` + +Description +=========== + +To manipulate the data of the search results prior to rendering them in the frontend a +hook has been introduced at the end of the :php:`getDisplayResults()` method, called +:php:`getDisplayResults_postProc`. +The hook can modify all data just before it is passed to fluid. + +Basic Usage +=========== + +Registration of the new hook in :php:``ext_localconf.php`` of your custom extension. + +.. code-block:: php + + $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['indexed_search']['pi1_hooks']['getDisplayResults_postProc'] = \Vendor\ExtensionName\Hooks\CustomHook::class; + +CustomHook class example :php:``\Vendor\ExtensionName\Hooks\CustomHook`` + +.. code-block:: php + + <?php + declare(strict_types=1); + namespace Vendor\ExtensionName\Hooks; + + class CustomHook + { + /** + * @param array $result + * @return array + */ + public function getDisplayResults_postProc(array $result): array + { + if ($result['count'] > 0) { + foreach($result['rows'] as $rowIndex => $row) { + $result['rows'][$rowIndex]['description'] = \str_replace('foo', 'bar', $row['description']); + } + } + return $result; + } + } + +.. index:: ext:indexed_search, PHP-API diff --git a/typo3/sysext/indexed_search/Classes/Controller/SearchController.php b/typo3/sysext/indexed_search/Classes/Controller/SearchController.php index e078f4f0dee1..56012789a64a 100644 --- a/typo3/sysext/indexed_search/Classes/Controller/SearchController.php +++ b/typo3/sysext/indexed_search/Classes/Controller/SearchController.php @@ -345,6 +345,11 @@ class SearchController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionControlle if (substr($this->searchData['sections'], 0, 2) === 'rl') { $result['searchedInSectionInfo'] = LocalizationUtility::translate('result.inSection', 'IndexedSearch') . ' "' . $this->getPathFromPageId(substr($this->searchData['sections'], 4)) . '"'; } + + if ($hookObj = $this->hookRequest('getDisplayResults_postProc')) { + $result = $hookObj->getDisplayResults_postProc($result); + } + return $result; } diff --git a/typo3/sysext/indexed_search/Classes/Example/PluginHook.php b/typo3/sysext/indexed_search/Classes/Example/PluginHook.php index 926b1fdd97be..4a9c4b53075c 100644 --- a/typo3/sysext/indexed_search/Classes/Example/PluginHook.php +++ b/typo3/sysext/indexed_search/Classes/Example/PluginHook.php @@ -43,6 +43,25 @@ class PluginHook $this->pObj->optValues['order'] = array_reverse($this->pObj->optValues['order']); } + /** + * Example of how the content displayed in the result rows can be extended or modified + * before the data is assigned to the fluid template as {resultsets}. + * The code example replaces all occurrences of the search string with the replacement + * string in the description of all rows in the result. + * + * @param array $result + * @return array + */ + public function getDisplayResults_postProc(array $result): array + { + if ($result['count'] > 0) { + foreach ($result['rows'] as $rowIndex => $row) { + $result['rows'][$rowIndex]['description'] = \str_replace('foo', 'bar', $row['description']); + } + } + return $result; + } + /** * Providing an alternative search algorithm! * diff --git a/typo3/sysext/indexed_search/Tests/Unit/Classes/Example/PluginHookTest.php b/typo3/sysext/indexed_search/Tests/Unit/Classes/Example/PluginHookTest.php new file mode 100644 index 000000000000..8c5e215cba38 --- /dev/null +++ b/typo3/sysext/indexed_search/Tests/Unit/Classes/Example/PluginHookTest.php @@ -0,0 +1,96 @@ +<?php + +namespace TYPO3\CMS\IndexedSearch\Tests\Unit; + +/* + * 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! + */ + +use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\IndexedSearch\Example\PluginHook; +use TYPO3\TestingFramework\Core\Unit\UnitTestCase; + +/** + * This class contains unit tests for the indexer + */ +class PluginHookTest extends UnitTestCase +{ + /** + * @var array A backup of registered singleton instances + */ + protected $singletonInstances = []; + + /** + * Indexer instance + * + * @var \TYPO3\CMS\IndexedSearch\Example\PluginHook + */ + protected $subject; + + /** + * Sets up the test + */ + protected function setUp() + { + $this->singletonInstances = GeneralUtility::getSingletonInstances(); + $this->subject = new PluginHook(); + } + + /** + * @test + */ + public function getDisplayResults_postProcReturnsTheOriginalSearchResultBecauseOfMissingItems() + { + $searchResult = [ + 'count' => 0, + 'rows' => [] + ]; + + $result = $this->subject->getDisplayResults_postProc($searchResult); + self::assertSame($searchResult, $result); + } + + /** + * @test + */ + public function getDisplayResults_postProcModifiesTheDescriptionInARowOfSearchResult() + { + $searchResult = [ + 'count' => 2, + 'rows' => [ + ['description' => 'I am a description field with joe and foo.'], + ['description' => 'Description will be modified to two bar. foo, bar, joe. '] + ] + ]; + + $expected = [ + 'count' => 2, + 'rows' => [ + ['description' => 'I am a description field with joe and bar.'], + ['description' => 'Description will be modified to two bar. bar, bar, joe. '] + ] + ]; + + $result = $this->subject->getDisplayResults_postProc($searchResult); + self::assertSame($expected, $result); + } + + /** + * Tear down the tests + */ + protected function tearDown() + { + GeneralUtility::resetSingletonInstances($this->singletonInstances); + unset($this->subject); + parent::tearDown(); + } +} -- GitLab