‪TYPO3CMS  ‪main
PageBrowsingViewHelper.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
24 use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractTagBasedViewHelper;
25 
32 final class ‪PageBrowsingViewHelper extends AbstractTagBasedViewHelper
33 {
34  protected static string ‪$prefixId = 'tx_indexedsearch';
35 
39  protected ‪$tagName = 'ul';
40 
41  public function ‪__construct(private readonly ‪AssetCollector $assetCollector)
42  {
43  parent::__construct();
44  }
45 
46  public function ‪initializeArguments(): void
47  {
48  $this->registerArgument('maximumNumberOfResultPages', 'int', '', true);
49  $this->registerArgument('numberOfResults', 'int', '', true);
50  $this->registerArgument('resultsPerPage', 'int', '', true);
51  $this->registerArgument('currentPage', 'int', '', false, 0);
52  $this->registerArgument('freeIndexUid', 'int', '');
53  $this->registerUniversalTagAttributes();
54  }
55 
56  public function ‪render(): string
57  {
58  $maximumNumberOfResultPages = $this->arguments['maximumNumberOfResultPages'];
59  $numberOfResults = $this->arguments['numberOfResults'];
60  $resultsPerPage = $this->arguments['resultsPerPage'];
61  $currentPage = $this->arguments['currentPage'];
62  $freeIndexUid = $this->arguments['freeIndexUid'];
63 
64  if ($resultsPerPage <= 0) {
65  $resultsPerPage = 10;
66  }
67  $pageCount = (int)ceil($numberOfResults / $resultsPerPage);
68  // only show the result browser if more than one page is needed
69  if ($pageCount === 1) {
70  return '';
71  }
72 
73  // Check if $currentPage is in range
74  $currentPage = ‪MathUtility::forceIntegerInRange($currentPage, 0, $pageCount - 1);
75 
76  $content = '';
77  // prev page
78  // show on all pages after the 1st one
79  if ($currentPage > 0) {
80  $label = ‪LocalizationUtility::translate('displayResults.previous', 'IndexedSearch') ?? '';
81  $content .= '<li class="tx-indexedsearch-browselist-prev">' . $this->‪makecurrentPageSelector_link($label, $currentPage - 1, $freeIndexUid) . '</li>';
82  }
83  // Check if $maximumNumberOfResultPages is in range
84  $maximumNumberOfResultPages = ‪MathUtility::forceIntegerInRange($maximumNumberOfResultPages, 1, $pageCount, 10);
85  // Assume $currentPage is in the middle and calculate the index limits of the result page listing
86  $minPage = $currentPage - (int)floor($maximumNumberOfResultPages / 2);
87  $maxPage = $minPage + $maximumNumberOfResultPages - 1;
88  // Check if the indexes are within the page limits
89  if ($minPage < 0) {
90  $maxPage -= $minPage;
91  $minPage = 0;
92  } elseif ($maxPage >= $pageCount) {
93  $minPage -= $maxPage - $pageCount + 1;
94  $maxPage = $pageCount - 1;
95  }
96  $pageLabel = ‪LocalizationUtility::translate('displayResults.page', 'IndexedSearch');
97  for ($a = $minPage; $a <= $maxPage; $a++) {
98  $isCurrentPage = $a === $currentPage;
99  $label = trim($pageLabel . ' ' . ($a + 1));
100  $label = $this->‪makecurrentPageSelector_link($label, $a, $freeIndexUid, $isCurrentPage);
101  if ($isCurrentPage) {
102  $content .= '<li class="tx-indexedsearch-browselist-currentPage"><strong>' . $label . '</strong></li>';
103  } else {
104  $content .= '<li>' . $label . '</li>';
105  }
106  }
107  // next link
108  if ($currentPage < $pageCount - 1) {
109  $label = ‪LocalizationUtility::translate('displayResults.next', 'IndexedSearch') ?? '';
110  $content .= '<li class="tx-indexedsearch-browselist-next">' . $this->‪makecurrentPageSelector_link($label, $currentPage + 1, $freeIndexUid) . '</li>';
111  }
112 
113  if (!$this->tag->hasAttribute('class')) {
114  $this->tag->addAttribute('class', 'tx-indexedsearch-browsebox');
115  }
116  $this->tag->setContent($content);
117  return $this->tag->render();
118  }
119 
130  protected function ‪makecurrentPageSelector_link($str, $p, $freeIndexUid, bool $isCurrentPage = false)
131  {
133  $attributes = [
134  'href' => '#',
135  'class' => 'tx-indexedsearch-page-selector',
136  'data-prefix' => ‪self::$prefixId,
137  'data-pointer' => $p,
138  'data-freeIndexUid' => $freeIndexUid,
139  ];
140  if ($isCurrentPage) {
141  $attributes['aria-current'] = 'page';
142  }
143  return sprintf(
144  '<a %s>%s</a>',
145  GeneralUtility::implodeAttributes($attributes, true),
146  htmlspecialchars($str)
147  );
148  }
149 
150  private function ‪providePageSelectorJavaScript(): void
151  {
152  if ($this->assetCollector->hasInlineJavaScript(self::class)) {
153  return;
154  }
155  $this->assetCollector->addInlineJavaScript(
156  self::class,
157  implode(' ', [
158  "document.addEventListener('click', (evt) => {",
159  "if (!evt.target.classList.contains('tx-indexedsearch-page-selector')) {",
160  'return;',
161  '}',
162  'evt.preventDefault();',
163  'var data = evt.target.dataset;',
164  "document.getElementById(data.prefix + '_pointer').value = data.pointer;",
165  "document.getElementById(data.prefix + '_freeIndexUid').value = data.freeIndexUid;",
166  'document.getElementById(data.prefix).submit();',
167  '});',
168  ]),
169  [],
170  ['useNonce' => true],
171  );
172  }
173 }
‪TYPO3\CMS\IndexedSearch\ViewHelpers\PageBrowsingViewHelper\initializeArguments
‪initializeArguments()
Definition: PageBrowsingViewHelper.php:45
‪TYPO3\CMS\Core\Page\AssetCollector
Definition: AssetCollector.php:42
‪TYPO3\CMS\IndexedSearch\ViewHelpers\PageBrowsingViewHelper\$prefixId
‪static string $prefixId
Definition: PageBrowsingViewHelper.php:34
‪TYPO3\CMS\Extbase\Utility\LocalizationUtility
Definition: LocalizationUtility.php:35
‪TYPO3\CMS\IndexedSearch\ViewHelpers\PageBrowsingViewHelper\providePageSelectorJavaScript
‪providePageSelectorJavaScript()
Definition: PageBrowsingViewHelper.php:149
‪TYPO3\CMS\IndexedSearch\ViewHelpers\PageBrowsingViewHelper
Definition: PageBrowsingViewHelper.php:33
‪TYPO3\CMS\Extbase\Utility\LocalizationUtility\translate
‪static string null translate(string $key, ?string $extensionName=null, array $arguments=null, Locale|string $languageKey=null)
Definition: LocalizationUtility.php:47
‪TYPO3\CMS\IndexedSearch\ViewHelpers\PageBrowsingViewHelper\makecurrentPageSelector_link
‪string makecurrentPageSelector_link($str, $p, $freeIndexUid, bool $isCurrentPage=false)
Definition: PageBrowsingViewHelper.php:129
‪TYPO3\CMS\IndexedSearch\ViewHelpers\PageBrowsingViewHelper\$tagName
‪string $tagName
Definition: PageBrowsingViewHelper.php:38
‪TYPO3\CMS\Core\Utility\MathUtility
Definition: MathUtility.php:24
‪TYPO3\CMS\Core\Utility\MathUtility\forceIntegerInRange
‪static int forceIntegerInRange(mixed $theInt, int $min, int $max=2000000000, int $defaultValue=0)
Definition: MathUtility.php:34
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\IndexedSearch\ViewHelpers
‪TYPO3\CMS\IndexedSearch\ViewHelpers\PageBrowsingViewHelper\__construct
‪__construct(private readonly AssetCollector $assetCollector)
Definition: PageBrowsingViewHelper.php:40
‪TYPO3\CMS\IndexedSearch\ViewHelpers\PageBrowsingViewHelper\render
‪render()
Definition: PageBrowsingViewHelper.php:55