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 0000000000000000000000000000000000000000..98d4d5074bf53bcd932899e07738b8766ffbfd4d --- /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 e078f4f0dee1c6e62b987652389ad14563d1a1e9..56012789a64ac465c65ed69e92d023870fa5a7c1 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 926b1fdd97be63f5ae965550d1dabb792bae2579..4a9c4b53075cb17d09fa1c5c51c5c7123253614a 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 0000000000000000000000000000000000000000..8c5e215cba38fe8dbc2be369f34aa3619e807ae2 --- /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(); + } +}