Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 71 additions & 46 deletions Classes/Controller/BrokenLinkListController.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Sypets\Brofix\CheckLinks\LinkTargetResponse\LinkTargetResponse;
use Sypets\Brofix\Configuration\Configuration;
use Sypets\Brofix\Controller\Filter\BrokenLinkListFilter;
use Sypets\Brofix\Controller\Pagination\PaginateInfo;
use Sypets\Brofix\LinkAnalyzer;
use Sypets\Brofix\Linktype\LinktypeInterface;
use Sypets\Brofix\Repository\BrokenLinkRepository;
Expand Down Expand Up @@ -46,6 +47,8 @@
*/
class BrokenLinkListController extends AbstractBrofixController
{
protected const PAGINATE_ITEMS_PER_PAGE = 100;

protected const MODULE_NAME = 'web_brofix_broken_links';

protected const DEFAULT_ORDER_BY = 'page';
Expand Down Expand Up @@ -186,6 +189,8 @@
protected bool $backendUserHasPermissionsForBrokenLinklist = false;
protected bool $backendUserHasPermissionsForExcludes = false;

protected ?PaginateInfo $paginateInfo = null;

public function __construct(
protected PagesRepository $pagesRepository,
protected BrokenLinkRepository $brokenLinkRepository,
Expand Down Expand Up @@ -440,10 +445,10 @@
if ($paginationPage !== null) {
$this->paginationCurrentPage = (int)$paginationPage;
} else {
$this->paginationCurrentPage = 1;
$this->paginationCurrentPage = PaginateInfo::PAGE_NUMBER_START;
}
if ($this->paginationCurrentPage < 1) {
$this->paginationCurrentPage = 1;
if ($this->paginationCurrentPage < PaginateInfo::PAGE_NUMBER_START) {
$this->paginationCurrentPage = PaginateInfo::PAGE_NUMBER_START;
}
}

Expand Down Expand Up @@ -562,11 +567,9 @@
*/
protected function initializeViewForBrokenLinks(): void
{
$this->moduleTemplate->assign('depth', $this->depth);

$items = [];
$totalCount = 0;

/** Determines whether link list should be displayed, if no page selected and traverse by subpages:
* no
*/
$shouldShow = true;
$howToTraverse = $this->filter->getHowtotraverse();
if ($howToTraverse === BrokenLinkListFilter::HOW_TO_TRAVERSE_PAGES) {
Expand All @@ -583,37 +586,16 @@
}

if ($shouldShow) {
/**
* @todo Currently, we fetch all and then paginate. We would like to optimize this to fetch only the broken
* links for one page. However, this would make it necessary to first fetch the total amount, which
* is similarly complicated to getBrokenLinks because of the array_chunking the pids. Possibly, set
* a hard limit to the number of pages and do away with array_chunking.
* There is already traverseMaxNumberOfPagesInBackend extension configuration which would have to
* effectively be set to a hard limit corresponding to (int)(BrokenLinkRepository::getMaxBindParameters() /2 - 4);
*/
$brokenLinks = $this->brokenLinkRepository->getBrokenLinks(
$this->pageList,
$this->linkTypes,
$this->configuration->getSearchFields(),
$this->filter,
$this->configuration,
self::ORDER_BY_VALUES[$this->orderBy] ?? []
);
if ($brokenLinks) {
$totalCount = count($brokenLinks);
// todo: do this in fetchPaginatedLinkList
//$totalCount = $this->fetchTotalCountOfBrokenLinks();

$itemsPerPage = 100;
if (($this->paginationCurrentPage - 1) * $itemsPerPage >= $totalCount) {
$this->resetPagination();
}
$paginator = GeneralUtility::makeInstance(ArrayPaginator::class, $brokenLinks, $this->paginationCurrentPage, $itemsPerPage);
$this->pagination = GeneralUtility::makeInstance(SimplePagination::class, $paginator);
// move end
foreach ($paginator->getPaginatedItems() as $row) {
$items[] = $this->renderTableRow($row['table_name'], $row);
}
$this->moduleTemplate->assign('listUri', $this->constructBackendUri());
}
// todo: do this in fetchPaginatedLinkList
//$paginateInfo = new PaginateInfo($totalCount, $this->paginationCurrentPage);

$items = $this->fetchPaginatedLinkList();

$howToTraverse = $this->filter->getHowtotraverse();
// check if limit was reached
if ($howToTraverse !== BrokenLinkListFilter::HOW_TO_TRAVERSE_ALL
&& $this->configuration->getTraverseMaxNumberOfPagesInBackend()
&& is_countable($this->pageList)
Expand All @@ -629,13 +611,18 @@
);
}
} else {
$this->pagination = null;
// todo : show message to select page
$totalCount = 0;
$items = [];
$paginateInfo = null;
}
$this->moduleTemplate->assign('totalCount', $totalCount);

$this->moduleTemplate->assign('depth', $this->depth);
$this->moduleTemplate->assign('totalCount', $this->paginateInfo ? $this->paginateInfo->getNumberOfItems() : 0);
$this->moduleTemplate->assign('filter', $this->filter);
$this->moduleTemplate->assign('viewMode', $this->viewMode);
if ($this->id === 0) {
$this->createFlashMessagesForRootPage();
if (!$shouldShow) {
$this->createFlashMessageToSelectPageInPagetree();
} elseif (empty($items)) {
$this->createFlashMessagesForNoBrokenLinks();
}
Expand All @@ -645,9 +632,10 @@
$this->moduleTemplate->assign('linktypes', $linktypes);
}

$this->moduleTemplate->assign('pagination', $this->pagination);
// todo replace with pageinateInfo
//$this->moduleTemplate->assign('pagination', $this->pagination);
$this->moduleTemplate->assign('orderBy', $this->orderBy);
$this->moduleTemplate->assign('paginationPage', $this->paginationCurrentPage ?: 1);
$this->moduleTemplate->assign('paginationPage', $this->paginationCurrentPage ?: PaginateInfo::PAGE_NUMBER_START);

// todo: only pass configuration
$this->moduleTemplate->assign('showPageLayoutButton', $this->configuration->isShowPageLayoutButton());
Expand All @@ -665,6 +653,40 @@
$this->moduleTemplate->assign('tableHeader', $this->getVariablesForTableHeader($sortActions));
}

protected function fetchPaginatedLinkList(): array

Check failure on line 656 in Classes/Controller/BrokenLinkListController.php

View workflow job for this annotation

GitHub Actions / all core-v12 (8.4, composerInstallMax)

Method Sypets\Brofix\Controller\BrokenLinkListController::fetchPaginatedLinkList() return type has no value type specified in iterable type array.

Check failure on line 656 in Classes/Controller/BrokenLinkListController.php

View workflow job for this annotation

GitHub Actions / all core-v12 (8.4, composerInstallMax)

Method Sypets\Brofix\Controller\BrokenLinkListController::fetchPaginatedLinkList() return type has no value type specified in iterable type array.

Check failure on line 656 in Classes/Controller/BrokenLinkListController.php

View workflow job for this annotation

GitHub Actions / all core v13 (8.5, composerInstallMax)

Method Sypets\Brofix\Controller\BrokenLinkListController::fetchPaginatedLinkList() return type has no value type specified in iterable type array.

Check failure on line 656 in Classes/Controller/BrokenLinkListController.php

View workflow job for this annotation

GitHub Actions / all core v13 (8.2, composerInstallMax)

Method Sypets\Brofix\Controller\BrokenLinkListController::fetchPaginatedLinkList() return type has no value type specified in iterable type array.

Check failure on line 656 in Classes/Controller/BrokenLinkListController.php

View workflow job for this annotation

GitHub Actions / all core-v12 (8.1, composerInstallMax)

Method Sypets\Brofix\Controller\BrokenLinkListController::fetchPaginatedLinkList() return type has no value type specified in iterable type array.

Check failure on line 656 in Classes/Controller/BrokenLinkListController.php

View workflow job for this annotation

GitHub Actions / all core-v12 (8.1, composerInstallMax)

Method Sypets\Brofix\Controller\BrokenLinkListController::fetchPaginatedLinkList() return type has no value type specified in iterable type array.

Check failure on line 656 in Classes/Controller/BrokenLinkListController.php

View workflow job for this annotation

GitHub Actions / all core v13 (8.5, composerInstallMax)

Method Sypets\Brofix\Controller\BrokenLinkListController::fetchPaginatedLinkList() return type has no value type specified in iterable type array.

Check failure on line 656 in Classes/Controller/BrokenLinkListController.php

View workflow job for this annotation

GitHub Actions / all core v13 (8.2, composerInstallMax)

Method Sypets\Brofix\Controller\BrokenLinkListController::fetchPaginatedLinkList() return type has no value type specified in iterable type array.
{
$brokenLinks = [];

// fetch total count
$totalCount = $this->brokenLinkRepository->getBrokenLinksCount($this->pageList,
$this->linkTypes,
$this->configuration->getSearchFields(),
$this->filter,
$this->configuration, 'tx_brofix_tmp_page_ids');

if ($this->paginateInfo === null) {
$this->paginateInfo = new PaginateInfo($totalCount, $this->paginationCurrentPage);
}

$dbalResult = $this->brokenLinkRepository->getBrokenLinks(
$this->pageList,
$this->linkTypes,
$this->configuration->getSearchFields(),
$this->filter,
$this->configuration,
self::ORDER_BY_VALUES[$this->orderBy] ?? [],
$this->paginateInfo,'tx_brofix_tmp_page_ids'
);

while ($row = $dbalResult->fetchAssociative()) {
// enrich content
$brokenLinks[] = $this->renderTableRow($row['table_name'], $row);
}
$this->moduleTemplate->assign('listUri', $this->constructBackendUri());

return $brokenLinks;
}

/**
* Used when there are no broken links found.
*/
Expand Down Expand Up @@ -698,7 +720,10 @@
);
}

protected function createFlashMessagesForRootPage(): void
/**
* "Select a page in the page tree!"
*/
protected function createFlashMessageToSelectPageInPagetree(): void
{
$this->createFlashMessage($this->getLanguageService()->sL('LLL:EXT:brofix/Resources/Private/Language/Module/locallang.xlf:list.rootpage'));
}
Expand Down Expand Up @@ -1143,7 +1168,7 @@
return true;
}

protected function resetPagination(int $pageNr = 1): void
protected function resetPagination(int $pageNr = PaginateInfo::PAGE_NUMBER_START): void
{
$this->paginationCurrentPage = $pageNr;
}
Expand Down
91 changes: 91 additions & 0 deletions Classes/Controller/Pagination/PaginateInfo.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?php
declare(strict_types=1);
namespace Sypets\Brofix\Controller\Pagination;

/**
* In contrast to core funtionality, like ArrayPaginator, this does not store the entire array for performance
* reasons. It just stores the basic information like the current page number (starting with 0) and number of
* items per page.
*
* The intention is to let the database get only the items that are needed for one page.
*
*/
class PaginateInfo
{
public const PAGE_NUMBER_START = 0;
public const ITEMS_PER_PAGE = 50;

public function __construct(protected int $numberOfItems, protected int $currentPage = self::PAGE_NUMBER_START,
protected int $itemsPerPage = self::ITEMS_PER_PAGE)
{}

public function getNumberOfItems(): int
{
return $this->numberOfItems;
}

public function getCurrentPageNumber(): ?int
{
return $this->currentPage;
}

public function getCurrentItemNumber(): ?int
{
$currentItemNumber = ($this->currentPage - self::PAGE_NUMBER_START) * $this->getItemsPerPage();
return $currentItemNumber;
}

public function getItemsPerPage(): int
{
return $this->itemsPerPage;
}

public function getPreviousPageNumber(): ?int
{
if ($this->currentPage > 1) {
return $this->currentPage - 1;
}
return null;
}

public function getNextPageNumber(): ?int
{
if ($this->currentPage * $this->itemsPerPage > $this->numberOfItems) {
return $this->currentPage + 1;
}
return null;
}

public function getFirstPageNumber(): int
{
return 0;
}

public function getLastPageNumber(): int
{
return $this->getNumberOfPages();
}

public function getNumberOfPages(): int
{
return (int) ($this->numberOfItems-1) / $this->itemsPerPage;
}

public function getStartRecordNumber(): int
{
return 0;
}

public function getEndRecordNumber(): int
{
return $this->numberOfItems-1;
}

public function getAllPageNumbers(): array

Check failure on line 84 in Classes/Controller/Pagination/PaginateInfo.php

View workflow job for this annotation

GitHub Actions / all core-v12 (8.4, composerInstallMax)

Method Sypets\Brofix\Controller\Pagination\PaginateInfo::getAllPageNumbers() return type has no value type specified in iterable type array.

Check failure on line 84 in Classes/Controller/Pagination/PaginateInfo.php

View workflow job for this annotation

GitHub Actions / all core-v12 (8.4, composerInstallMax)

Method Sypets\Brofix\Controller\Pagination\PaginateInfo::getAllPageNumbers() return type has no value type specified in iterable type array.

Check failure on line 84 in Classes/Controller/Pagination/PaginateInfo.php

View workflow job for this annotation

GitHub Actions / all core v13 (8.5, composerInstallMax)

Method Sypets\Brofix\Controller\Pagination\PaginateInfo::getAllPageNumbers() return type has no value type specified in iterable type array.

Check failure on line 84 in Classes/Controller/Pagination/PaginateInfo.php

View workflow job for this annotation

GitHub Actions / all core v13 (8.2, composerInstallMax)

Method Sypets\Brofix\Controller\Pagination\PaginateInfo::getAllPageNumbers() return type has no value type specified in iterable type array.

Check failure on line 84 in Classes/Controller/Pagination/PaginateInfo.php

View workflow job for this annotation

GitHub Actions / all core-v12 (8.1, composerInstallMax)

Method Sypets\Brofix\Controller\Pagination\PaginateInfo::getAllPageNumbers() return type has no value type specified in iterable type array.

Check failure on line 84 in Classes/Controller/Pagination/PaginateInfo.php

View workflow job for this annotation

GitHub Actions / all core-v12 (8.1, composerInstallMax)

Method Sypets\Brofix\Controller\Pagination\PaginateInfo::getAllPageNumbers() return type has no value type specified in iterable type array.

Check failure on line 84 in Classes/Controller/Pagination/PaginateInfo.php

View workflow job for this annotation

GitHub Actions / all core v13 (8.5, composerInstallMax)

Method Sypets\Brofix\Controller\Pagination\PaginateInfo::getAllPageNumbers() return type has no value type specified in iterable type array.

Check failure on line 84 in Classes/Controller/Pagination/PaginateInfo.php

View workflow job for this annotation

GitHub Actions / all core v13 (8.2, composerInstallMax)

Method Sypets\Brofix\Controller\Pagination\PaginateInfo::getAllPageNumbers() return type has no value type specified in iterable type array.
{
// not implemented
return [];
}


}
Loading
Loading