diff --git a/Classes/Controller/AbstractController.php b/Classes/Controller/AbstractController.php
index 9dd36dc2..a8b9e6b0 100644
--- a/Classes/Controller/AbstractController.php
+++ b/Classes/Controller/AbstractController.php
@@ -15,7 +15,6 @@
use TYPO3\CMS\Core\Routing\SiteMatcher;
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
use TYPO3\CMS\Core\Database\Query\QueryHelper;
-#use TYPO3\CMS\Core\Page\PageRenderer;
use TYPO3\CMS\Core\Domain\Repository\PageRepository;
use TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager;
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
@@ -42,7 +41,7 @@ abstract class AbstractController extends ActionController
/**
* init all actions
*/
- public function initializeAction()
+ public function initializeAction(): void
{
$site = $this->request->getAttribute('site');
$this->rootPageId = $site->getRootPageId();
@@ -62,8 +61,6 @@ public function initializeAction()
$queryBuilder->expr()->eq('root', $queryBuilder->createNamedParameter(1, \PDO::PARAM_INT))
)
->executeQuery()->fetchOne();
-
-# $pageRenderer = GeneralUtility::makeInstance(PageRenderer::class);
}
diff --git a/Classes/Controller/ConfigController.php b/Classes/Controller/ConfigController.php
index e39af6ce..1e04fbf2 100644
--- a/Classes/Controller/ConfigController.php
+++ b/Classes/Controller/ConfigController.php
@@ -28,14 +28,14 @@
final class ConfigController extends AbstractController
{
public function __construct(
- private ModuleTemplateFactory $moduleTemplateFactory
+ protected readonly ModuleTemplateFactory $moduleTemplateFactory
) {
}
/**
* Init all actions.
*/
- public function initializeAction()
+ public function initializeAction(): void
{
parent::initializeAction();
}
diff --git a/Classes/DataProcessing/BootstrapProcessor.php b/Classes/DataProcessing/BootstrapProcessor.php
index 9709c0c6..a5a76e06 100644
--- a/Classes/DataProcessing/BootstrapProcessor.php
+++ b/Classes/DataProcessing/BootstrapProcessor.php
@@ -315,13 +315,13 @@ public function process(ContentObjectRenderer $cObj, array $contentObjectConfigu
$processedData['lightBox'] = true;
}
// lightbox
- if ($cType == 't3sbs_gallery' || !empty($processedData['data']['image_zoom'])) {
+ if ($cType === 't3sbs_gallery' || !empty($processedData['data']['image_zoom'])) {
$processedData['lightBox'] = true;
}
}
// child of autoLayout_row
- if ($parentCType == 'autoLayout_row') {
+ if ($parentCType === 'autoLayout_row') {
$processedData['newLine'] = $flexconf['newLine'] ? true : false;
$processedData['class'] .= $classHelper->getAutoLayoutClass($flexconf);
}
@@ -376,7 +376,6 @@ public function process(ContentObjectRenderer $cObj, array $contentObjectConfigu
}
-
/**
* @param array $animationSettingsArray
* @return string
diff --git a/Classes/DataProcessing/ConfigProcessor.php b/Classes/DataProcessing/ConfigProcessor.php
index 3dd6a7dc..2fa672c7 100644
--- a/Classes/DataProcessing/ConfigProcessor.php
+++ b/Classes/DataProcessing/ConfigProcessor.php
@@ -45,7 +45,6 @@ public function process(ContentObjectRenderer $cObj, array $contentObjectConfigu
if (!$frontendController) {
$frontendController = self::getFrontendController();
}
-
if (!empty($contentObjectConfiguration['settings.']['config.']['uid'])
&& is_numeric($contentObjectConfiguration['settings.']['config.']['uid'])) {
$processedRecordVariables = $contentObjectConfiguration['settings.']['config.'];
@@ -179,10 +178,10 @@ public function process(ContentObjectRenderer $cObj, array $contentObjectConfigu
if (!empty($navbarMenu['data']['tx_t3sbootstrap_fontawesome_icon'])) {
$mainMenu[$key]['faIcon'] = ' ';
}
- $mainMenu[$key]['linkTitle'] = $navbarMenu['data']['title'];
- if (!empty($settings['navbar.']['noLinkTitle'])) {
- $mainMenu[$key]['linkTitle'] = '';
- }
+ $mainMenu[$key]['linkTitle'] = $navbarMenu['data']['title'];
+ if (!empty($settings['navbar.']['noLinkTitle'])) {
+ $mainMenu[$key]['linkTitle'] = '';
+ }
if ($navbarMenu['data']['tx_t3sbootstrap_icon_only']) {
$mainMenu[$key]['linkTitle'] = $navbarMenu['data']['title'];
$mainMenu[$key]['title'] = '';
@@ -385,7 +384,7 @@ public function process(ContentObjectRenderer $cObj, array $contentObjectConfigu
$processedData['config']['navbar']['sbmauto'] = ' ms-auto';
}
if ($processedData['config']['navbar']['mauto'] == ' ms-auto') {
- $processedData['config']['navbar']['sbmauto'] = ' float-right ms-3';
+ $processedData['config']['navbar']['sbmauto'] = ' float-end ms-3';
}
if ($processedData['config']['navbar']['mauto'] == 'center') {
$processedData['config']['navbar']['sbmauto'] = '';
diff --git a/Classes/ViewHelpers/PageBrowsingViewHelper.php b/Classes/ViewHelpers/PageBrowsingViewHelper.php
index 9f19c058..0e1bfd22 100644
--- a/Classes/ViewHelpers/PageBrowsingViewHelper.php
+++ b/Classes/ViewHelpers/PageBrowsingViewHelper.php
@@ -1,127 +1,176 @@
registerArgument('maximumNumberOfResultPages', 'int', '', true);
- $this->registerArgument('numberOfResults', 'int', '', true);
- $this->registerArgument('resultsPerPage', 'int', '', true);
- $this->registerArgument('currentPage', 'int', '', false, 0);
- $this->registerArgument('freeIndexUid', 'int', '');
- }
-
-
- public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext): string
- {
- $maximumNumberOfResultPages = $arguments['maximumNumberOfResultPages'];
- $numberOfResults = $arguments['numberOfResults'];
- $resultsPerPage = $arguments['resultsPerPage'];
- $currentPage = $arguments['currentPage'];
- $freeIndexUid = $arguments['freeIndexUid'];
-
- if ($resultsPerPage <= 0) {
- $resultsPerPage = 10;
- }
- $pageCount = (int)ceil($numberOfResults / $resultsPerPage);
- // only show the result browser if more than one page is needed
- if ($pageCount === 1) {
- return '';
- }
-
- // Check if $currentPage is in range
- $currentPage = MathUtility::forceIntegerInRange($currentPage, 0, $pageCount - 1);
-
- $content = '';
- // prev page
- // show on all pages after the 1st one
- if ($currentPage > 0 && !empty($freeIndexUid)) {
- $label = LocalizationUtility::translate('displayResults.previous', 'IndexedSearch');
- $content .= '
' . self::makecurrentPageSelector_link((string) $label, $currentPage - 1, (string) $freeIndexUid) . '';
- }
- // Check if $maximumNumberOfResultPages is in range
- $maximumNumberOfResultPages = MathUtility::forceIntegerInRange($maximumNumberOfResultPages, 1, $pageCount, 10);
- // Assume $currentPage is in the middle and calculate the index limits of the result page listing
- $minPage = $currentPage - (int)floor($maximumNumberOfResultPages / 2);
- $maxPage = $minPage + $maximumNumberOfResultPages - 1;
- // Check if the indexes are within the page limits
- if ($minPage < 0) {
- $maxPage -= $minPage;
- $minPage = 0;
- } elseif ($maxPage >= $pageCount) {
- $minPage -= $maxPage - $pageCount + 1;
- $maxPage = $pageCount - 1;
- }
- $pageLabel = '';
-
- for ($a = $minPage; $a <= $maxPage; $a++) {
- $label = trim($pageLabel . ' ' . ($a + 1));
- if (!empty($freeIndexUid)) {
- $label = self::makecurrentPageSelector_link((string) $label, (int) $a, (string) $freeIndexUid);
- }
- if ($a === $currentPage) {
- $content .= '' . $label . '';
- } else {
- $content .= '' . $label . '';
- }
- }
-
-
- // next link
- if ($currentPage < $pageCount - 1 && !empty($freeIndexUid)) {
- $label = LocalizationUtility::translate('displayResults.next', 'IndexedSearch');
- $content .= '' . self::makecurrentPageSelector_link((string) $label, ($currentPage + 1), (string) $freeIndexUid) . '';
- }
- return '';
- }
-
- /**
- * Used to make the link for the result-browser.
- * Notice how the links must resubmit the form after setting the new currentPage-value in a hidden formfield.
- *
- * $str String to wrap in tag
- * $p currentPage value
- * $freeIndexUid List of integers pointing to free indexing configurations to search. -1 represents no filtering, 0 represents TYPO3 pages only, any number above zero is a uid of an indexing configuration!
- */
- protected static function makecurrentPageSelector_link(string $str, int $p, string $freeIndexUid): string
- {
- $onclick = 'document.getElementById(' . GeneralUtility::quoteJSvalue(self::$prefixId . '_pointer') . ').value=' . GeneralUtility::quoteJSvalue($p) . ';';
- if ($freeIndexUid !== null) {
- $onclick .= 'document.getElementById(' . GeneralUtility::quoteJSvalue(self::$prefixId . '_freeIndexUid') . ').value=' . GeneralUtility::quoteJSvalue($freeIndexUid) . ';';
- }
- $onclick .= 'document.getElementById(' . GeneralUtility::quoteJSvalue(self::$prefixId) . ').submit();return false;';
- return '' . htmlspecialchars($str) . '';
- }
+ protected static string $prefixId = 'tx_indexedsearch';
+
+ /**
+ * @var string
+ */
+ protected $tagName = 'ul';
+
+ public function __construct(private readonly AssetCollector $assetCollector)
+ {
+ parent::__construct();
+ }
+
+ public function initializeArguments(): void
+ {
+ $this->registerArgument('maximumNumberOfResultPages', 'int', '', true);
+ $this->registerArgument('numberOfResults', 'int', '', true);
+ $this->registerArgument('resultsPerPage', 'int', '', true);
+ $this->registerArgument('currentPage', 'int', '', false, 0);
+ $this->registerArgument('freeIndexUid', 'int', '');
+ $this->registerUniversalTagAttributes();
+ }
+
+ public function render(): string
+ {
+ $maximumNumberOfResultPages = $this->arguments['maximumNumberOfResultPages'];
+ $numberOfResults = $this->arguments['numberOfResults'];
+ $resultsPerPage = $this->arguments['resultsPerPage'];
+ $currentPage = $this->arguments['currentPage'];
+ $freeIndexUid = $this->arguments['freeIndexUid'];
+
+ if ($resultsPerPage <= 0) {
+ $resultsPerPage = 10;
+ }
+ $pageCount = (int)ceil($numberOfResults / $resultsPerPage);
+ // only show the result browser if more than one page is needed
+ if ($pageCount === 1) {
+ return '';
+ }
+
+ // Check if $currentPage is in range
+ $currentPage = MathUtility::forceIntegerInRange($currentPage, 0, $pageCount - 1);
+
+ $content = '';
+ // prev page
+ // show on all pages after the 1st one
+ if ($currentPage > 0) {
+ $label = LocalizationUtility::translate('displayResults.previous', 'IndexedSearch') ?? '';
+ $content .= '' . $this->makecurrentPageSelector_link($label, $currentPage - 1, $freeIndexUid) . '';
+ }
+ // Check if $maximumNumberOfResultPages is in range
+ $maximumNumberOfResultPages = MathUtility::forceIntegerInRange($maximumNumberOfResultPages, 1, $pageCount, 10);
+ // Assume $currentPage is in the middle and calculate the index limits of the result page listing
+ $minPage = $currentPage - (int)floor($maximumNumberOfResultPages / 2);
+ $maxPage = $minPage + $maximumNumberOfResultPages - 1;
+ // Check if the indexes are within the page limits
+ if ($minPage < 0) {
+ $maxPage -= $minPage;
+ $minPage = 0;
+ } elseif ($maxPage >= $pageCount) {
+ $minPage -= $maxPage - $pageCount + 1;
+ $maxPage = $pageCount - 1;
+ }
+ $pageLabel = LocalizationUtility::translate('displayResults.page', 'IndexedSearch');
+ for ($a = $minPage; $a <= $maxPage; $a++) {
+ $isCurrentPage = $a === $currentPage;
+ $label = trim($pageLabel . ' ' . ($a + 1));
+ $label = $this->makecurrentPageSelector_link($label, $a, $freeIndexUid, $isCurrentPage);
+ if ($isCurrentPage) {
+ $content .= '' . $label . '';
+ } else {
+ $content .= '' . $label . '';
+ }
+ }
+ // next link
+ if ($currentPage < $pageCount - 1) {
+ $label = LocalizationUtility::translate('displayResults.next', 'IndexedSearch') ?? '';
+ $content .= '' . $this->makecurrentPageSelector_link($label, $currentPage + 1, $freeIndexUid) . '';
+ }
+
+ if (!$this->tag->hasAttribute('class')) {
+ $this->tag->addAttribute('class', 'tx-indexedsearch-browsebox pagination');
+ }
+
+ $this->tag->setContent($content);
+
+ return $this->tag->render();
+ }
+
+ /**
+ * Used to make the link for the result-browser.
+ * Notice how the links must resubmit the form after setting the new currentPage-value in a hidden formfield.
+ *
+ * @param string $str String to wrap in tag
+ * @param int $p currentPage value
+ * @param string $freeIndexUid List of integers pointing to free indexing configurations to search. -1 represents no filtering, 0 represents TYPO3 pages only, any number above zero is a uid of an indexing configuration!
+ * @param bool $isCurrentPage
+ * @return string Input string wrapped in tag with onclick event attribute set.
+ */
+ protected function makecurrentPageSelector_link($str, $p, $freeIndexUid, bool $isCurrentPage = false)
+ {
+ $this->providePageSelectorJavaScript();
+ $attributes = [
+ 'href' => '#',
+ 'class' => 'tx-indexedsearch-page-selector page-link',
+ 'data-prefix' => self::$prefixId,
+ 'data-pointer' => $p,
+ 'data-free-index-uid' => $freeIndexUid,
+ ];
+ if ($isCurrentPage) {
+ $attributes['aria-current'] = 'page';
+ }
+ return sprintf(
+ '%s',
+ GeneralUtility::implodeAttributes($attributes, true),
+ htmlspecialchars($str)
+ );
+ }
+
+ private function providePageSelectorJavaScript(): void
+ {
+ if ($this->assetCollector->hasInlineJavaScript(self::class)) {
+ return;
+ }
+
+ $this->assetCollector->addInlineJavaScript(
+ 'vanilla_indexSearch',
+ implode(' ', [
+ "document.addEventListener('click', (evt) => {",
+ "if (!evt.target.classList.contains('tx-indexedsearch-page-selector')) {",
+ 'return;',
+ '}',
+ 'evt.preventDefault();',
+ 'var data = evt.target.dataset;',
+ "document.getElementById(data.prefix + '_pointer').value = data.pointer;",
+ "document.getElementById(data.prefix + '_freeIndexUid').value = data.freeIndexUid;",
+ 'document.getElementById(data.prefix).submit();',
+ '});',
+ ]),
+ [],
+ ['useNonce' => true],
+ );
+ }
}
diff --git a/Classes/Wrapper/CollapsibleAccordion.php b/Classes/Wrapper/CollapsibleAccordion.php
index 5f8a56a4..c1f2b3b3 100644
--- a/Classes/Wrapper/CollapsibleAccordion.php
+++ b/Classes/Wrapper/CollapsibleAccordion.php
@@ -1,4 +1,5 @@
findByRelation('tt_content', 'assets', (int)$processedData['data']['uid']);
- if (!empty($file)) {$file = $file[0];}
- $processedData['appearance'] = $parentflexconf['appearance'];
- $processedData['show'] = !empty($flexconf['active']) ? ' show' : '';
- $processedData['collapsed'] = !empty($flexconf['active']) ? '' : ' collapsed';
- $processedData['expanded'] = !empty($flexconf['active']) ? 'true' : 'false';
- $processedData['alwaysOpen'] = !empty($parentflexconf['alwaysOpen']) ? 'true' : 'false';
- $processedData['buttonstyle'] = !empty($flexconf['style']) ? $flexconf['style'] : 'primary';
- $processedData['collapsibleByPid'] = !empty($flexconf['collapsibleByPid']) ? $flexconf['collapsibleByPid'] : '';
- $processedData['media'] = $file ? $file : '';
-
- $processedData['appearance'] = $parentflexconf['appearance'];
-
- return $processedData;
- }
-
+ /**
+ * Returns the $processedData
+ */
+ public function getProcessedData(array $processedData, array $flexconf, array $parentflexconf): array
+ {
+ $fileRepository = GeneralUtility::makeInstance(FileRepository::class);
+
+ $file = $fileRepository->findByRelation('tt_content', 'assets', (int)$processedData['data']['uid']);
+ if (!empty($file)) {
+ $file = $file[0];
+ }
+ $processedData['appearance'] = $parentflexconf['appearance'];
+ $processedData['show'] = !empty($flexconf['active']) ? ' show' : '';
+ $processedData['collapsed'] = !empty($flexconf['active']) ? '' : ' collapsed';
+ $processedData['expanded'] = !empty($flexconf['active']) ? 'true' : 'false';
+ $processedData['alwaysOpen'] = !empty($parentflexconf['alwaysOpen']) ? 'true' : 'false';
+ $processedData['buttonstyle'] = !empty($flexconf['style']) ? $flexconf['style'] : 'primary';
+ $processedData['collapsibleByPid'] = !empty($flexconf['collapsibleByPid']) ? $flexconf['collapsibleByPid'] : '';
+ $processedData['media'] = $file ? $file : '';
+
+ $processedData['appearance'] = $parentflexconf['appearance'];
+
+ return $processedData;
+ }
}
diff --git a/Configuration/TCA/Overrides/sys_file_reference.php b/Configuration/TCA/Overrides/sys_file_reference.php
index edcd96e8..13f5149e 100644
--- a/Configuration/TCA/Overrides/sys_file_reference.php
+++ b/Configuration/TCA/Overrides/sys_file_reference.php
@@ -9,336 +9,335 @@
* Add extra field tx_t3sbootstrap_extra_class etc. to sys_file_reference record
*/
$tempSysFileReferenceColumns = [
- 'tx_t3sbootstrap_extra_class' => [
- 'exclude' => 1,
- 'label' => 'Extra Class - figure-tag',
- 'config' => [
- 'type' => 'input',
- 'size' => 40,
- 'eval' => 'trim',
- 'valuePicker' => [
- 'items' => [
- [ 'm-3 (margin)', 'm-3', ],
- [ 'mt-3 (margin-top)', 'mt-3', ],
- [ 'mb-3 (margin-bottom)', 'mb-3', ],
- [ 'ms-3 (margin-left)', 'ms-3', ],
- [ 'me-3 (margin-right)', 'me-3', ],
- [ 'mx-3 (margin-left and -right)', 'mx-3', ],
- [ 'my-3 (margin-top and -bottom)', 'my-3', ],
- [ 'Hover zoom (basic)', 'img-hover-zoom', ],
- [ 'Hover zoom (rotate)', 'img-hover-zoom--zoom-n-rotate', ],
- [ 'Hover zoom (slowmo)', 'img-hover-zoom--slowmo', ],
- [ 'Hover zoom (brightness)', 'img-hover-zoom--brightness', ],
- [ 'Hover zoom (blurzoom)', 'img-hover-zoom--blur', ],
- [ 'Hover zoom (colorize)', 'img-hover-zoom--colorize', ]
- ],
- ],
- ],
- ],
- 'tx_t3sbootstrap_extra_imgclass' => [
- 'exclude' => 1,
- 'label' => 'Extra Class - img-tag',
- 'config' => [
- 'type' => 'input',
- 'size' => 40,
- 'eval' => 'trim',
- 'valuePicker' => [
- 'items' => [
- [ 'img-transform scale', 'img-transform', ],
- [ 'rounded', 'rounded', ],
- [ 'rounded-circle', 'rounded-circle', ],
- [ 'img-thumbnail', 'img-thumbnail', ],
- [ 'float-start', 'float-start', ],
- [ 'float-right', 'float-end', ],
- [ 'mx-auto d-block', 'mx-auto d-block', ],
- ],
- ],
- ],
- ],
- 'tx_t3sbootstrap_hover_effect' => [
- 'label' => 'Link Hover Effect (title and/or description)',
- 'exclude' => 1,
- 'displayCond' => [
- 'AND' => [
- 'FIELD:tablenames:=:tt_content',
- 'FIELD:fieldname:=:assets',
- ]
- ],
- 'config' => [
- 'type' => 'select',
- 'renderType' => 'selectSingle',
- 'items' => [
- [
- 'label' => 'none',
- 'value' => '',
- ],
- [
- 'label' => 'Effect 1',
- 'value' => 'snip1273',
- ],
- [
- 'label' => 'Effect 2',
- 'value' => 'snip1321',
- ],
- [
- 'label' => 'Effect 3',
- 'value' => 'snip1577',
- ],
- [
- 'label' => 'Effect 4',
- 'value' => 'snip0015',
- ],
- [
- 'label' => 'Effect 5 (title only)',
- 'value' => 'snip1573',
- ],
- [
- 'label' => 'Effect 6',
- 'value' => 'snip1477',
- ],
- [
- 'label' => 'Effect 7',
- 'value' => 'snip1361',
- ],
- [
- 'label' => 'Effect 8',
- 'value' => 'snip1206',
- ],
- [
- 'label' => 'Effect 9',
- 'value' => 'snip1190',
- ],
- [
- 'label' => 'Effect 10',
- 'value' => 'snip0016',
- ],
- ],
- 'default' => ''
- ]
- ],
- 'tx_t3sbootstrap_lazy_load' => [
- 'label' => 'Lazy loading',
- 'exclude' => 1,
- 'displayCond' => [
- 'OR' => [
- 'FIELD:tablenames:=:tt_content',
- 'FIELD:tablenames:=:tx_news_domain_model_news',
- 'FIELD:fieldname:=:assets',
- 'FIELD:fieldname:=:image',
- ],
- ],
- 'config' => [
- 'type' => 'check'
- ]
- ],
- 'tx_t3sbootstrap_description_align' => [
- 'label' => 'Description align',
- 'exclude' => 1,
- 'config' => [
- 'type' => 'select',
- 'renderType' => 'selectSingle',
- 'items' => [
- [
- 'label' => 'left',
- 'value' => 'start',
- ],
- [
- 'label' => 'center',
- 'value' => 'center',
- ],
- [
- 'label' => 'right',
- 'value' => 'end',
- ],
- ],
- 'default' => 'start'
- ]
- ],
- 'tx_t3sbootstrap_copyright' => [
- 'exclude' => 1,
- 'label' => 'Copyright note',
- 'config' => [
- 'type' => 'input',
- 'size' => 50,
- 'eval' => 'trim',
- ],
- ],
- 'tx_t3sbootstrap_copyright_color' => [
- 'exclude' => 1,
- 'label' => 'Copyright color',
- 'config' => [
- 'type' => 'select',
- 'renderType' => 'selectSingle',
- 'items' => [
- [
- 'label' => 'light',
- 'value' => 'text-light',
- ],
- [
- 'label' => 'dark',
- 'value' => 'text-dark',
- ],
- [
- 'label' => 'primary',
- 'value' => 'text-primary',
- ],
- [
- 'label' => 'secondary',
- 'value' => 'text-secondary',
- ],
- [
- 'label' => 'success',
- 'value' => 'text-success',
- ],
- [
- 'label' => 'danger',
- 'value' => 'text-danger',
- ],
- [
- 'label' => 'warning',
- 'value' => 'text-warning',
- ],
- [
- 'label' => 'info',
- 'value' => 'text-info',
- ],
- [
- 'label' => 'white',
- 'value' => 'text-white',
- ],
- ],
- 'default' => 'text-dark',
- 'size' => 1,
- 'maxitems' => 1
- ]
- ],
- 'tx_t3sbootstrap_copyright_source' => [
- 'exclude' => 1,
- 'label' => 'Copyright source',
- 'config' => [
- 'type' => 'input',
- 'size' => 50,
- 'eval' => 'trim',
- ],
- ],
- 'tx_t3sbootstrap_imgtag' => [
- 'label' => 'Output image in - instead in