[BUGFIX] Fix indexed_search page browsing calculation 92/32992/2
authorMarkus Klein <klein.t3@reelworx.at>
Tue, 15 Jul 2014 17:30:24 +0000 (19:30 +0200)
committerMarkus Klein <klein.t3@reelworx.at>
Sat, 27 Sep 2014 10:19:01 +0000 (12:19 +0200)
Fix the calculation of pages shown by the indexed_search page browsers
to avoid negative page numbers or numbers exceeding the maximum available
page number.

Resolves: #60346
Releases: master, 6.2
Change-Id: I97de1c1afe42e29d450733f6741bca049f9803f6
Reviewed-on: http://review.typo3.org/32992
Reviewed-by: Markus Klein <klein.t3@reelworx.at>
Tested-by: Markus Klein <klein.t3@reelworx.at>
typo3/sysext/indexed_search/Classes/Controller/SearchFormController.php
typo3/sysext/indexed_search/Classes/ViewHelpers/PageBrowsingViewHelper.php
typo3/sysext/indexed_search/pi/locallang.xlf

index 4c06507..2b97ac4 100644 (file)
@@ -1585,51 +1585,55 @@ class SearchFormController extends \TYPO3\CMS\Frontend\Plugin\AbstractPlugin {
        /**
         * Returns a results browser
         *
-        * @param       boolean         Show result count
-        * @param       string          String appended to "displaying results..." notice.
-        * @param       string          String appended after section "displaying results...
-        * @param       string          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!
-        * @return      string          HTML output
+        * @param boolean $showResultCount Show result count
+        * @param string $addString String appended to "displaying results..." notice.
+        * @param string $addPart String appended after section "displaying results...
+        * @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!
+        * @return string HTML output
         * @todo Define visibility
         */
-       public function pi_list_browseresults($showResultCount = 1, $addString = '', $addPart = '', $freeIndexUid = -1) {
+       public function pi_list_browseresults($showResultCount = TRUE, $addString = '', $addPart = '', $freeIndexUid = -1) {
                // Initializing variables:
-               $pointer = $this->piVars['pointer'];
-               $count = $this->internal['res_count'];
+               $pointer = (int)$this->piVars['pointer'];
+               $count = (int)$this->internal['res_count'];
                $results_at_a_time = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($this->internal['results_at_a_time'], 1, 1000);
-               $maxPages = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($this->internal['maxPages'], 1, 100);
                $pageCount = ceil($count / $results_at_a_time);
-               $sTables = '';
+
+               $links = array();
+               // only show the result browser if more than one page is needed
                if ($pageCount > 1) {
-                       // only show the result browser if more than one page is needed
-                       $pointer = (int)$pointer;
-                       $links = array();
+                       $maxPages = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($this->internal['maxPages'], 1, $pageCount);
+
                        // Make browse-table/links:
                        if ($pointer > 0) {
                                // all pages after the 1st one
-                               $links[] = '<li>' . $this->makePointerSelector_link($this->pi_getLL('pi_list_browseresults_prev', '< Previous', TRUE), ($pointer - 1), $freeIndexUid) . '</li>';
-                       }
-                       for ($a = 0; $a < $pageCount; $a++) {
-                               $min = max(0, $pointer + 1 - ceil($maxPages / 2));
-                               $max = $min + $maxPages;
-                               if ($max > $pageCount) {
-                                       $min = $min - ($max - $pageCount);
-                               }
-                               if ($a >= $min && $a < $max) {
-                                       if ($a == $pointer) {
-                                               $links[] = '<li' . $this->pi_classParam('browselist-currentPage') . '><strong>' . $this->makePointerSelector_link(trim(($this->pi_getLL('pi_list_browseresults_page', 'Page', 1) . ' ' . ($a + 1))), $a, $freeIndexUid) . '</strong></li>';
-                                       } else {
-                                               $links[] = '<li>' . $this->makePointerSelector_link(trim(($this->pi_getLL('pi_list_browseresults_page', 'Page', TRUE) . ' ' . ($a + 1))), $a, $freeIndexUid) . '</li>';
-                                       }
+                               $links[] = '<li>' . $this->makePointerSelector_link($this->pi_getLL('pi_list_browseresults_prev', '< Previous', TRUE), $pointer - 1, $freeIndexUid) . '</li>';
+                       }
+                       $minPage = $pointer - floor($maxPages / 2);
+                       $maxPage = $minPage + $maxPages - 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 = $this->pi_getLL('pi_list_browseresults_page', 'Page', TRUE);
+                       for ($a = $minPage; $a <= $maxPage; $a++) {
+                               $label = trim($pageLabel . ' ' . ($a + 1));
+                               $link = $this->makePointerSelector_link($label, $a, $freeIndexUid);
+                               if ($a === $pointer) {
+                                       $links[] = '<li' . $this->pi_classParam('browselist-currentPage') . '><strong>' . $link . '</strong></li>';
+                               } else {
+                                       $links[] = '<li>' . $link . '</li>';
                                }
                        }
                        if ($pointer + 1 < $pageCount) {
-                               $links[] = '<li>' . $this->makePointerSelector_link($this->pi_getLL('pi_list_browseresults_next', 'Next >', TRUE), ($pointer + 1), $freeIndexUid) . '</li>';
+                               $links[] = '<li>' . $this->makePointerSelector_link($this->pi_getLL('pi_list_browseresults_next', 'Next >', TRUE), $pointer + 1, $freeIndexUid) . '</li>';
                        }
                }
-               $pR1 = $pointer * $results_at_a_time + 1;
-               $pR2 = $pointer * $results_at_a_time + $results_at_a_time;
-               if (is_array($links)) {
+               if (!empty($links)) {
                        $addPart .= '
                <ul class="browsebox">
                        ' . implode('', $links) . '
@@ -1638,9 +1642,17 @@ class SearchFormController extends \TYPO3\CMS\Frontend\Plugin\AbstractPlugin {
                $label = str_replace(
                        array('###TAG_BEGIN###', '###TAG_END###'),
                        array('<strong>', '</strong>'),
-                       $this->pi_getLL('pi_list_browseresults_display', 'Displaying results ###TAG_BEGIN###%s to %s###TAG_END### out of ###TAG_BEGIN###%s###TAG_END###')
+                       $this->pi_getLL('pi_list_browseresults_display', 'Displaying results ###TAG_BEGIN###%1$s to %2$s###TAG_END### out of ###TAG_BEGIN###%3$s###TAG_END###')
                );
-               $sTables = '<div' . $this->pi_classParam('browsebox') . '>' . ($showResultCount ? '<p>' . sprintf($label, $pR1, min(array($this->internal['res_count'], $pR2)), $this->internal['res_count']) . $addString . '</p>' : '') . $addPart . '</div>';
+               $resultsFrom = $pointer * $results_at_a_time + 1;
+               $resultsTo = min($resultsFrom + $results_at_a_time - 1, $count);
+               $resultCountText = '';
+               if ($showResultCount) {
+                       $resultCountText = '<p>' . sprintf($label, $resultsFrom, $resultsTo, $count) . $addString . '</p>';
+               }
+               $sTables = '<div' . $this->pi_classParam('browsebox') . '>'
+                       . $resultCountText
+                       . $addPart . '</div>';
                return $sTables;
        }
 
index 1a7330d..45121f0 100644 (file)
@@ -31,50 +31,59 @@ class PageBrowsingViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractVi
        /**
         * Main render function
         *
-        * @param integer $maximumNumberOfResultPages
-        * @param integer $numberOfResults
-        * @param integer $resultsPerPage
-        * @param integer $currentPage
-        * @param string|NULL $freeIndexUid
+        * @param integer $maximumNumberOfResultPages The number of page links shown
+        * @param integer $numberOfResults Total number of results
+        * @param integer $resultsPerPage Number of results per page
+        * @param integer $currentPage The current page starting with 0
+        * @param string|NULL $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!
         * @return string The content
         */
-       public function render($maximumNumberOfResultPages, $numberOfResults, $resultsPerPage, $currentPage = 1, $freeIndexUid = NULL) {
+       public function render($maximumNumberOfResultPages, $numberOfResults, $resultsPerPage, $currentPage = 0, $freeIndexUid = NULL) {
                $pageCount = ceil($numberOfResults / $resultsPerPage);
-               $content = '';
                // only show the result browser if more than one page is needed
-               if ($pageCount > 1) {
-                       $currentPage = (int)$currentPage;
-                       // prev page
-                       // show on all pages after the 1st one
-                       if ($currentPage > 0) {
-                               $label = \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('displayResults.previous', 'IndexedSearch');
-                               $content .= '<li>' . $this->makecurrentPageSelector_link($label, $currentPage - 1, $freeIndexUid) . '</li>';
-                       }
-                       $maximumNumberOfResultPages = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($maximumNumberOfResultPages, 1, 200000000, 10);
-                       $min = max(0, $currentPage + 1 - ceil($maximumNumberOfResultPages / 2));
-                       $max = $min + $maximumNumberOfResultPages;
-                       if ($max > $pageCount) {
-                               $min -= $max - $pageCount;
-                       }
-                       for ($a = $min; $a < $pageCount && $a < $max; $a++) {
-                               $label = \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('displayResults.page', 'IndexedSearch');
-                               $label = trim($label . ' ' . ($a + 1));
-                               $label = $this->makecurrentPageSelector_link($label, $a, $freeIndexUid);
-                               if ($a === $currentPage) {
-                                       $content .= '<li class="tx-indexedsearch-browselist-currentPage"><strong>' . $label . '</strong></li>';
-                               } else {
-                                       $content .= '<li>' . $label . '</li>';
-                               }
-                       }
-                       // next link
-                       if ($currentPage + 1 < $pageCount) {
-                               $label = \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('displayResults.next', 'IndexedSearch');
-                               $content .= '<li>' . $this->makecurrentPageSelector_link($label, ($currentPage + 1), $freeIndexUid) . '</li>';
-                       }
-                       $content = '<ul class="tx-indexedsearch-browsebox">' . $content . '</ul>';
+               if ($pageCount === 1) {
+                       return '';
                }
 
-               return $content;
+               // Check if $currentPage is in range
+               $currentPage = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($currentPage, 0, $pageCount - 1);
+
+               $content = '';
+               // prev page
+               // show on all pages after the 1st one
+               if ($currentPage > 0) {
+                       $label = \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('displayResults.previous', 'IndexedSearch');
+                       $content .= '<li>' . $this->makecurrentPageSelector_link($label, $currentPage - 1, $freeIndexUid) . '</li>';
+               }
+               // Check if $maximumNumberOfResultPages is in range
+               $maximumNumberOfResultPages = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($maximumNumberOfResultPages, 1, $pageCount, 10);
+               // Assume $currentPage is in the middle and calculate the index limits of the result page listing
+               $minPage = $currentPage - 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 = \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('displayResults.page', 'IndexedSearch');
+               for ($a = $minPage; $a <= $maxPage; $a++) {
+                       $label = trim($pageLabel . ' ' . ($a + 1));
+                       $label = $this->makecurrentPageSelector_link($label, $a, $freeIndexUid);
+                       if ($a === $currentPage) {
+                               $content .= '<li class="tx-indexedsearch-browselist-currentPage"><strong>' . $label . '</strong></li>';
+                       } else {
+                               $content .= '<li>' . $label . '</li>';
+                       }
+               }
+               // next link
+               if ($currentPage < $pageCount - 1) {
+                       $label = \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('displayResults.next', 'IndexedSearch');
+                       $content .= '<li>' . $this->makecurrentPageSelector_link($label, ($currentPage + 1), $freeIndexUid) . '</li>';
+               }
+               return '<ul class="tx-indexedsearch-browsebox">' . $content . '</ul>';
        }
 
        /**
index be3445e..d6a1f10 100644 (file)
@@ -234,7 +234,7 @@ All search words are converted to lowercase.</source>
                                <source>Next &gt;</source>
                        </trans-unit>
                        <trans-unit id="pi_list_browseresults_display" xml:space="preserve">
-                               <source>Displaying results ###TAG_BEGIN###%s to %s###TAG_END### out of ###TAG_BEGIN###%s###TAG_END###</source>
+                               <source>Displaying results ###TAG_BEGIN###%1$s to %2$s###TAG_END### out of ###TAG_BEGIN###%3$s###TAG_END###</source>
                        </trans-unit>
                        <trans-unit id="local_operator_AND" xml:space="preserve">
                                <source>AND</source>