diff --git a/Classes/Controller/Backend/PageModuleSummary.php b/Classes/Backend/SettingsPreviewOnPlugins.php similarity index 62% rename from Classes/Controller/Backend/PageModuleSummary.php rename to Classes/Backend/SettingsPreviewOnPlugins.php index 573979d219..6927a25898 100644 --- a/Classes/Controller/Backend/PageModuleSummary.php +++ b/Classes/Backend/SettingsPreviewOnPlugins.php @@ -13,56 +13,72 @@ * The TYPO3 project - inspiring people to share! */ -namespace ApacheSolrForTypo3\Solr\Controller\Backend; +namespace ApacheSolrForTypo3\Solr\Backend; use TYPO3\CMS\Backend\Utility\BackendUtility; -use TYPO3\CMS\Backend\View\PageLayoutView; +use TYPO3\CMS\Backend\View\Event\PageContentPreviewRenderingEvent; use TYPO3\CMS\Core\Localization\LanguageService; use TYPO3\CMS\Core\Service\FlexFormService; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Extbase\Reflection\ObjectAccess; use TYPO3\CMS\Fluid\View\StandaloneView; +use function str_starts_with; + /** - * Summary to display flexform settings in the page layout backend module. - * - * @author Ingo Renner - * @author Timo Hund + * Summary to display flexform settings of EXT:solr plugin in BE page module. */ -class PageModuleSummary +class SettingsPreviewOnPlugins { - /** - * PageLayoutView - * - * @var PageLayoutView - */ - protected $pageLayoutView; + protected array $pluginsTtContentRecord; + private array $flexformData; - /** - * @var array - */ - protected $pluginContentElement = []; + protected array $settings = []; - /** - * @var array - */ - protected $flexformData = []; + public function __construct( + protected FlexFormService $flexFormService + ) { + } + + public function __invoke(PageContentPreviewRenderingEvent $event): void + { + $this->pluginsTtContentRecord = $event->getRecord(); + if ( + $event->getTable() !== 'tt_content' + || !str_starts_with($this->pluginsTtContentRecord['list_type'], 'solr_pi_') + ) { + return; + } + $this->flexformData = $this->flexFormService->convertFlexFormContentToArray($this->pluginsTtContentRecord['pi_flexform'] ?? ''); + $event->setPreviewContent($this->getPreviewContent()); + } /** - * @var array + * @return string */ - protected $settings = []; + protected function getPreviewContent(): string + { + $this->collectSummary(); + + /* @var StandaloneView $standaloneView */ + $standaloneView = GeneralUtility::makeInstance(StandaloneView::class); + $standaloneView->setTemplatePathAndFilename( + GeneralUtility::getFileAbsFileName('EXT:solr/Resources/Private/Templates/Backend/PageModule/Summary.html') + ); + + $standaloneView->assignMultiple([ + 'pluginLabel' => $this->getPluginLabel(), + 'hidden' => $this->pluginsTtContentRecord['hidden'] ?? 0, + 'settings' => $this->settings, + ]); + return $standaloneView->render(); + } /** * Returns information about a plugin's flexform configuration - * - * @param array $parameters Parameters to the hook - * @return string Plugin configuration information */ - public function getSummary(array $parameters) + public function collectSummary(): void { - $this->initialize($parameters['row'], $parameters['pObj']); - $this->addTargetPage(); $this->addSettingFromFlexForm('Filter', 'search.query.filter'); $this->addSettingFromFlexForm('Sorting', 'search.query.sortBy'); @@ -71,31 +87,17 @@ public function getSummary(array $parameters) $this->addSettingFromFlexForm('Boost Query', 'search.query.boostQuery'); $this->addSettingFromFlexForm('Tie Breaker', 'search.query.tieParameter'); $this->addSettingFromFlexForm('Template', 'view.templateFiles.results'); - return $this->render(); - } - - /** - * @param array $contentElement - * @param PageLayoutView $pObj - */ - protected function initialize(array $contentElement, PageLayoutView $pObj) - { - $this->pageLayoutView = $pObj; - - /** @var $service \TYPO3\CMS\Core\Service\FlexFormService::class */ - $service = GeneralUtility::makeInstance(FlexFormService::class); - $this->flexformData = $service->convertFlexFormContentToArray($contentElement['pi_flexform']); - $this->pluginContentElement = $contentElement; } /** * Adds the target page to the settings. */ - protected function addTargetPage() + protected function addTargetPage(): void { $targetPageId = $this->getFieldFromFlexform('search.targetPage'); if (!empty($targetPageId)) { - $page = BackendUtility::getRecord('pages', $targetPageId, 'title'); + $page = BackendUtility::getRecord('pages', $targetPageId, 'title') + ?? ['title' => 'ERROR: page is gone']; $this->settings['Target Page'] = '[' . (int)$targetPageId . '] ' . $page['title']; } } @@ -104,12 +106,13 @@ protected function addTargetPage() * @param string $settingName * @param string $flexFormField */ - protected function addSettingFromFlexForm($settingName, $flexFormField) + protected function addSettingFromFlexForm(string $settingName, string $flexFormField): void { $value = $this->getFieldFromFlexform($flexFormField); if (is_array($value)) { - $value = $this->addSettingFromFlexFormArray($settingName, $value); + $this->addSettingFromFlexFormArray($settingName, $value); + return; } $this->addSettingIfNotEmpty($settingName, (string)$value); } @@ -117,9 +120,8 @@ protected function addSettingFromFlexForm($settingName, $flexFormField) /** * @param string $settingName * @param array $values - * @return bool */ - protected function addSettingFromFlexFormArray($settingName, $values) + protected function addSettingFromFlexFormArray(string $settingName, array $values): void { foreach ($values as $item) { if (!isset($item['field'])) { @@ -128,8 +130,8 @@ protected function addSettingFromFlexFormArray($settingName, $values) $field = $item['field']; $label = $settingName . ' '; - $label .= isset($field['field']) ? $field['field'] : ''; - $fieldValue = isset($field['value']) ? $field['value'] : ''; + $label .= $field['field'] ?? ''; + $fieldValue = $field['value'] ?? ''; $this->addSettingIfNotEmpty($label, (string)$fieldValue); } } @@ -138,7 +140,7 @@ protected function addSettingFromFlexFormArray($settingName, $values) * @param string $settingName * @param string $value */ - protected function addSettingIfNotEmpty($settingName, $value) + protected function addSettingIfNotEmpty(string $settingName, string $value): void { if (!empty($value)) { $this->settings[$settingName] = $value; @@ -152,45 +154,26 @@ protected function addSettingIfNotEmpty($settingName, $value) * @param string $path name of the field * @return mixed|null if nothing found, value if found */ - protected function getFieldFromFlexform(string $path) + protected function getFieldFromFlexform(string $path): mixed { return ObjectAccess::getPropertyPath($this->flexformData, $path); } - /** - * @return string - */ - protected function render() - { - /** @var $standaloneView StandaloneView */ - $standaloneView = GeneralUtility::makeInstance(StandaloneView::class); - $standaloneView->setTemplatePathAndFilename( - GeneralUtility::getFileAbsFileName('EXT:solr/Resources/Private/Templates/Backend/PageModule/Summary.html') - ); - - $standaloneView->assignMultiple([ - 'pluginLabel' => $this->getPluginLabel(), - 'hidden' => $this->pluginContentElement['hidden'], - 'settings' => $this->settings, - ]); - return $standaloneView->render(); - } - /** * Returns the plugin label * * @return string */ - protected function getPluginLabel() + protected function getPluginLabel(): string { - $label = BackendUtility::getLabelFromItemListMerged($this->pluginContentElement['pid'], 'tt_content', 'list_type', $this->pluginContentElement['list_type']); + $label = BackendUtility::getLabelFromItemListMerged($this->pluginsTtContentRecord['pid'], 'tt_content', 'list_type', $this->pluginsTtContentRecord['list_type']); if (!empty($label)) { $label = $this->getLanguageService()->sL($label); } else { - $label = sprintf($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.noMatchingValue'), $this->pluginContentElement['list_type']); + $label = sprintf($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.noMatchingValue'), $this->pluginsTtContentRecord['list_type']); } - return $this->pageLayoutView->linkEditContent(htmlspecialchars($label), $this->pluginContentElement); + return $label; } /** diff --git a/Classes/Domain/Index/Queue/RecordMonitor/Helper/RootPageResolver.php b/Classes/Domain/Index/Queue/RecordMonitor/Helper/RootPageResolver.php index 1e2c8f7bcc..d89a954e72 100644 --- a/Classes/Domain/Index/Queue/RecordMonitor/Helper/RootPageResolver.php +++ b/Classes/Domain/Index/Queue/RecordMonitor/Helper/RootPageResolver.php @@ -240,7 +240,7 @@ protected function getRootPageIdByTableAndUid(string $table, int $uid): int protected function getRecordPageId(string $table, int $uid): int { $record = BackendUtility::getRecord($table, $uid, 'pid'); - return $record['pid'] ? (int)$record['pid'] : 0; + return $record['pid'] ? (int)$record['pid'] : 0; } /** diff --git a/Configuration/Services.yaml b/Configuration/Services.yaml index ff77c4c3f6..0ca97d0f38 100644 --- a/Configuration/Services.yaml +++ b/Configuration/Services.yaml @@ -14,6 +14,16 @@ services: autowire: true tags: ['backend.controller'] + # BE modules, plugins + ApacheSolrForTypo3\Solr\Backend\SettingsPreviewOnPlugins: + arguments: + $flexFormService: '@TYPO3\CMS\Core\Service\FlexFormService' + tags: + - name: event.listener + identifier: 'solr.plugin.be.settings.preview' + event: TYPO3\CMS\Backend\View\Event\PageContentPreviewRenderingEvent + # END: BE modules + viewhelper_backend: namespace: ApacheSolrForTypo3\Solr\ViewHelpers\Backend\ resource: '../Classes/ViewHelpers/Backend/*' diff --git a/Configuration/TCA/Overrides/tt_content.php b/Configuration/TCA/Overrides/tt_content.php index af779ae943..f70a94dfe2 100644 --- a/Configuration/TCA/Overrides/tt_content.php +++ b/Configuration/TCA/Overrides/tt_content.php @@ -35,10 +35,12 @@ 'pi_results', 'LLL:EXT:solr/Resources/Private/Language/locallang.xlf:tt_content.list_type_pi_results' ); + $GLOBALS['TCA']['tt_content']['types']['list']['subtypes_excludelist'][$pluginSignature] = 'layout,select_key,pages,recursive'; $GLOBALS['TCA']['tt_content']['types']['list']['subtypes_addlist'][$pluginSignature] = 'pi_flexform'; + \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPiFlexFormValue( $pluginSignature, 'FILE:EXT:solr/Configuration/FlexForms/Results.xml' diff --git a/Resources/Private/Templates/Backend/PageModule/Summary.html b/Resources/Private/Templates/Backend/PageModule/Summary.html index 561a6fdcab..36ed20adfc 100644 --- a/Resources/Private/Templates/Backend/PageModule/Summary.html +++ b/Resources/Private/Templates/Backend/PageModule/Summary.html @@ -1,4 +1,10 @@ - + + +
@@ -11,4 +17,6 @@ -
{pluginLabel}{settingValue}
\ No newline at end of file + + + diff --git a/Tests/Integration/Backend/SettingsPreviewOnPluginsTest.php b/Tests/Integration/Backend/SettingsPreviewOnPluginsTest.php new file mode 100644 index 0000000000..e113d0c7f0 --- /dev/null +++ b/Tests/Integration/Backend/SettingsPreviewOnPluginsTest.php @@ -0,0 +1,118 @@ + [ + 'targetPage' => '4711', + 'initializeWithEmptyQuery' => '0', + 'showResultsOfInitialEmptyQuery' => '0', + 'initializeWithQuery' => 'test', + 'showResultsOfInitialQuery' => '0', + 'query' => [ + 'sortBy' => 'sorting', + 'boostFunction' => 'boostFunction', + 'boostQuery' => 'boostQuery', + 'filter' => [ + '5947784b97b1e034174380' => [ + 'field' => + [ + 'field' => 'appKey', + 'value' => 'test', + ], + ], + '59477a29d19e9226739710' => [ + 'field' => [ + 'field' => 'changed', + 'value' => '1', + ], + ], + ], + ], + 'results' => [ + 'resultsPerPage' => '10', + ], + ], + 'view' => [ + 'templateFiles' => [ + 'results' => 'myTemplateFile.html', + ], + ], + ]; + + protected function setUp(): void + { + $GLOBALS['LANG'] = $this->createMock(LanguageService::class); + parent::setUp(); + } + + /** + * @test + */ + public function printsPreviewOnExtSolrPluginsCorrectly() + { + $settingsPreviewOnPlugins = new SettingsPreviewOnPlugins( + $this->getMockOfFlexFormService($this->flexFormArray) + ); + $event = $this->getFakePageContentPreviewRenderingEvent( + 'tt_content', + [ + 'pid' => 11, + 'pi_flexform' => 'provided via mock return value $this->flexFormArray', + 'list_type' => 'solr_pi_results', + 'hidden' => 0, + ] + ); + $settingsPreviewOnPlugins->__invoke($event); + $result = $event->getPreviewContent(); + + self::assertStringContainsString('ERROR: page is gone', $result, 'Summary did not contain plugin label'); + self::assertStringContainsString('>Filter appKey', $result, 'Summary did not contain filter label'); + self::assertStringContainsString('test', $result, 'Summary did not contain filter value'); + self::assertStringContainsString('sorting', $result, 'Summary did not contain sorting'); + self::assertStringContainsString('boostFunction', $result, 'Summary did not contain boostFunction'); + self::assertStringContainsString('boostQuery', $result, 'Summary did not contain boostQuery'); + self::assertStringContainsString('10', $result, 'Summary did not contain resultsPerPage'); + self::assertStringContainsString('myTemplateFile.html', $result, 'Templatefile not in settingsPreviewOnPlugins'); + } + + protected function getFakePageContentPreviewRenderingEvent(string $table = 'tt_content', array $record = []): PageContentPreviewRenderingEvent + { + return new PageContentPreviewRenderingEvent( + $table, + $record, + $this->createMock(PageLayoutContext::class) + ); + } + + protected function getMockOfFlexFormService(array $expectedFlexFormArray = []): MockObject|FlexFormService + { + $flexFormServiceMock = $this->getMockBuilder(FlexFormService::class) + ->disableOriginalConstructor() + ->onlyMethods([ + 'convertFlexFormContentToArray', + ]) + ->getMock(); + $flexFormServiceMock + ->expects(self::any()) + ->method('convertFlexFormContentToArray') + ->willReturn($expectedFlexFormArray); + + return $flexFormServiceMock; + } +} diff --git a/Tests/Integration/Controller/Backend/Fixtures/fakeFlexform.xml b/Tests/Integration/Controller/Backend/Fixtures/fakeFlexform.xml deleted file mode 100644 index d8524bda2e..0000000000 --- a/Tests/Integration/Controller/Backend/Fixtures/fakeFlexform.xml +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - - 4711 - - - - - - - 0 - - - 0 - - - test - - - 0 - - - sorting - - - 10 - - - boostFunction - - - boostQuery - - - - - - - - appKey - - - test - - - - 0 - - - - - - changed - - - 1 - - - - 0 - - - - - - - - - myTemplateFile.html - - - - - \ No newline at end of file diff --git a/Tests/Integration/Controller/Backend/PageModuleSummaryTest.php b/Tests/Integration/Controller/Backend/PageModuleSummaryTest.php deleted file mode 100644 index d9e5864ab5..0000000000 --- a/Tests/Integration/Controller/Backend/PageModuleSummaryTest.php +++ /dev/null @@ -1,67 +0,0 @@ - - */ -class PageModuleSummaryTest extends IntegrationTest -{ - /** - * @throws NoSuchCacheException - */ - protected function setUp(): void - { - parent::setUp(); - $GLOBALS['LANG'] = $this->createMock(LanguageService::class); - } - - /** - * @test - */ - public function canGetSummary() - { - $flexFormData = $this->getFixtureContentByName('fakeFlexform.xml'); - - $fakeRow = ['pi_flexform' => $flexFormData]; - $pageLayoutViewMock = $this->createMock(PageLayoutView::class); - $pageLayoutViewMock->expects(self::any())->method('linkEditContent')->willReturn('fakePluginLabel'); - $data = [ - 'row' => $fakeRow, - 'pObj' => $pageLayoutViewMock, - ]; - $summary = new PageModuleSummary(); - $result = $summary->getSummary($data); - - self::assertStringContainsString('fakePluginLabel', $result, 'Summary did not contain plugin label'); - self::assertStringContainsString('>Filter appKey', $result, 'Summary did not contain filter label'); - self::assertStringContainsString('test', $result, 'Summary did not contain filter value'); - self::assertStringContainsString('sorting', $result, 'Summary did not contain sorting'); - self::assertStringContainsString('boostFunction', $result, 'Summary did not contain boostFunction'); - self::assertStringContainsString('boostQuery', $result, 'Summary did not contain boostQuery'); - self::assertStringContainsString('10', $result, 'Summary did not contain resultsPerPage'); - self::assertStringContainsString('myTemplateFile.html', $result, 'Templatefile not in summary'); - } -} diff --git a/Tests/Unit/Backend/SettingsPreviewOnPluginsTest.php b/Tests/Unit/Backend/SettingsPreviewOnPluginsTest.php new file mode 100644 index 0000000000..876905498b --- /dev/null +++ b/Tests/Unit/Backend/SettingsPreviewOnPluginsTest.php @@ -0,0 +1,99 @@ +createMock(LanguageService::class); + parent::setUp(); + } + + /** + * @test + */ + public function doesNotPrintPreviewOnNonExtSolrPlugins() + { + $settingPreviewMock = $this->getMockOfSettingsPreviewOnPlugins(['getPreviewContent']); + $settingPreviewMock + ->expects(self::never()) + ->method('getPreviewContent'); + $settingPreviewMock->__invoke( + $this->getFakePageContentPreviewRenderingEvent( + 'tt_content', + [ + 'list_type' => 'some_other_CE', + ] + ) + ); + } + + protected function getMockOfSettingsPreviewOnPlugins(array $methods = []): MockObject|SettingsPreviewOnPlugins + { + return $this->getMockBuilder(SettingsPreviewOnPlugins::class) + ->setConstructorArgs([ + 'flexFormService' => $this->getMockOfFlexFormService(), + ]) + ->onlyMethods($methods) + ->getMock(); + } + + protected function getFakePageContentPreviewRenderingEvent( + string $table = 'tt_content', + array $record = [], + ): PageContentPreviewRenderingEvent { + /* @var PageLayoutContext|MockObject $pageLayoutContextMock */ + $pageLayoutContextMock = $this->getDumbMock(PageLayoutContext::class); + return new PageContentPreviewRenderingEvent( + $table, + $record, + $pageLayoutContextMock + ); + } + + protected function getMockOfFlexFormService( + array $expectedFlexFormArray = [], + ): MockObject|FlexFormService { + $flexFormServiceMock = $this->getMockBuilder(FlexFormService::class) + ->disableOriginalConstructor() + ->onlyMethods([ + 'convertFlexFormContentToArray', + ]) + ->getMock(); + $flexFormServiceMock + ->expects(self::any()) + ->method('convertFlexFormContentToArray') + ->willReturn($expectedFlexFormArray); + + return $flexFormServiceMock; + } +} diff --git a/ext_localconf.php b/ext_localconf.php index 4ea42e9c59..8de04c87f5 100644 --- a/ext_localconf.php +++ b/ext_localconf.php @@ -21,12 +21,6 @@ // ----- # ----- # ----- # ----- # ----- # ----- # ----- # ----- # ----- # - // page module plugin settings summary - - $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/layout/class.tx_cms_layout.php']['list_type_Info']['solr_pi_results']['solr'] = \ApacheSolrForTypo3\Solr\Controller\Backend\PageModuleSummary::class . '->getSummary'; - - // ----- # ----- # ----- # ----- # ----- # ----- # ----- # ----- # ----- # - // register search components \ApacheSolrForTypo3\Solr\Search\SearchComponentManager::registerSearchComponent(