Skip to content

Commit

Permalink
Merge pull request #508 from Yoast/bugfix/overview-db-mount
Browse files Browse the repository at this point in the history
[BUGFIX] DB Mounts within Overview module, pagination, error handling within PreviewService
  • Loading branch information
RinyVT authored Aug 3, 2022
2 parents 3709d9a + bcf12dc commit cc26ef7
Showing 12 changed files with 340 additions and 149 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -33,8 +33,10 @@ jobs:
composer --version
- name: Install
run: |
composer config allow-plugins.typo3/cms-composer-installers true
composer config allow-plugins.typo3/class-alias-loader true
composer config allow-plugins.phpstan/extension-installer true
composer require typo3/cms-core:^${{ matrix.typo3 }} typo3/cms-backend:^${{ matrix.typo3 }} typo3/cms-extbase:^${{ matrix.typo3 }} typo3/cms-fluid:^${{ matrix.typo3 }} typo3/cms-frontend:^${{ matrix.typo3 }} typo3/cms-install:^${{ matrix.typo3 }} --no-progress
git checkout composer.json
- name: Lint
run: composer test:php:lint
- name: CGL
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -8,6 +8,14 @@ We will follow [Semantic Versioning](http://semver.org/).
## Yoast SEO Premium for TYPO3
Besides the free version of our plugin, we also have a premium version. The free version enables you to do all necessary optimizations. With the premium version, we make it even easier to do! More information can be found on https://www.maxserv.com/yoast.

## UNRELEASED
### Fixed
- Lists within the Overview module now take the "DB Mounts" of a user into account
- Optimized pagination of Overview module
- Fixed PHP8 error when the metatag `x-yoast-title-config` (for some reason) cannot be read from the frontend
- Added extra try-catch block to catch guzzle exceptions within `PreviewService`
- Path to the Yoast Backend CSS for the new composer mode

## 8.2.0 June 23, 2022
### Added
- Support for new TYPO3 composer mode
55 changes: 22 additions & 33 deletions Classes/Controller/OverviewController.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

declare(strict_types=1);

namespace YoastSeoForTypo3\YoastSeo\Controller;

/*
@@ -24,13 +26,13 @@
use TYPO3\CMS\Core\Localization\LanguageService;
use TYPO3\CMS\Core\Localization\Locales;
use TYPO3\CMS\Core\Page\PageRenderer;
use TYPO3\CMS\Core\Pagination\ArrayPaginator;
use TYPO3\CMS\Core\Pagination\SimplePagination;
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\PathUtility;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
use TYPO3\CMS\Extbase\Mvc\View\ViewInterface;
use YoastSeoForTypo3\YoastSeo\Pagination\ArrayPaginator;
use YoastSeoForTypo3\YoastSeo\Pagination\Pagination;

/**
* Class OverviewController
@@ -119,7 +121,9 @@ protected function initializeAction(): void

$this->currentFilter = $this->filters[$this->activeFilter];

$publicResourcesPath = PathUtility::getAbsoluteWebPath(ExtensionManagementUtility::extPath('yoast_seo')) . 'Resources/Public/';
$publicResourcesPath = PathUtility::getAbsoluteWebPath(
ExtensionManagementUtility::extPath('yoast_seo') . 'Resources/Public/'
);

$this->pageRenderer->addCssFile(
$publicResourcesPath . 'CSS/yoast-seo-backend.min.css'
@@ -134,8 +138,13 @@ public function listAction(int $currentPage = 1): void
$params = $this->getParams();
$items = GeneralUtility::callUserFunction($this->currentFilter['dataProvider'], $params, $this) ?: [];

$arrayPaginator = $this->getArrayPaginator($items, $currentPage, (int)$this->settings['itemsPerPage']);
$pagination = $this->getPagination($arrayPaginator);
$arrayPaginator = GeneralUtility::makeInstance(
ArrayPaginator::class,
$items,
$currentPage,
(int)$this->settings['itemsPerPage']
);
$pagination = GeneralUtility::makeInstance(Pagination::class, $arrayPaginator);

$this->view->assignMultiple([
'items' => $items,
@@ -170,7 +179,11 @@ public function getAvailableFilters()
) {
$params = $this->getParams();
foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['yoast_seo']['overview_filters'] as $key => &$filter) {
$filter['numberOfItems'] = (int)GeneralUtility::callUserFunction($filter['countProvider'], $params, $this);
$filter['numberOfItems'] = (int)GeneralUtility::callUserFunction(
$filter['countProvider'],
$params,
$this
);
}
return (array)$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['yoast_seo']['overview_filters'];
}
@@ -233,7 +246,9 @@ protected function makeLanguageMenu(): void
$lang = $this->getLanguageService();
$languageMenu = $this->view->getModuleTemplate()->getDocHeaderComponent()->getMenuRegistry()->makeMenu();
$languageMenu->setIdentifier('languageMenu');
$languageMenu->setLabel($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language'));
$languageMenu->setLabel(
$lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language')
);
$returnUrl = ($this->request->hasArgument('returnUrl')) ? $this->request->getArgument('returnUrl') : '';
foreach ($this->MOD_MENU['language'] as $key => $language) {
$parameters = [
@@ -263,32 +278,6 @@ protected function makeLanguageMenu(): void
}
}

/**
* @param array $items
* @param int $currentPage
* @param int $itemsPerPage
* @return \TYPO3\CMS\Core\Pagination\ArrayPaginator|\YoastSeoForTypo3\YoastSeo\Pagination\ArrayPaginator
*/
protected function getArrayPaginator(array $items, int $currentPage, int $itemsPerPage)
{
if (class_exists(ArrayPaginator::class)) {
return new ArrayPaginator($items, $currentPage, $itemsPerPage);
}
return new \YoastSeoForTypo3\YoastSeo\Pagination\ArrayPaginator($items, $currentPage, $itemsPerPage);
}

/**
* @param $arrayPaginator
* @return \TYPO3\CMS\Core\Pagination\SimplePagination|\YoastSeoForTypo3\YoastSeo\Pagination\SimplePagination
*/
protected function getPagination($arrayPaginator)
{
if (class_exists(SimplePagination::class)) {
return new SimplePagination($arrayPaginator);
}
return new \YoastSeoForTypo3\YoastSeo\Pagination\SimplePagination($arrayPaginator);
}

/**
* Returns the current BE user.
*
82 changes: 82 additions & 0 deletions Classes/DataProviders/AbstractOverviewDataProvider.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

declare(strict_types=1);

namespace YoastSeoForTypo3\YoastSeo\DataProviders;

/*
@@ -15,11 +17,38 @@
* The TYPO3 project - inspiring people to share!
*/

use Doctrine\DBAL\Driver\ResultStatement;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Database\Platform\PlatformInformation;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use YoastSeoForTypo3\YoastSeo\Utility\PageAccessUtility;

/**
* Class CornerstoneOverviewDataProvider
*/
abstract class AbstractOverviewDataProvider implements OverviewDataProviderInterface
{
protected const PAGES_TABLE = 'pages';

protected const PAGES_FIELDS = [
'uid',
'doktype',
'hidden',
'starttime',
'endtime',
'fe_group',
't3ver_state',
'nav_hide',
'is_siteroot',
'module',
'content_from_pid',
'extendToSubpages',
'sys_language_uid',
'title',
'seo_title',
'tx_yoastseo_score_readability',
'tx_yoastseo_score_seo'
];

/**
* @var array
@@ -49,4 +78,57 @@ public function numberOfItems(array $params): int

return $this->getData(true);
}

protected function getRestrictedPagesResults(bool $returnOnlyCount = false)
{
$pageIds = PageAccessUtility::getPageIds();
if ($pageIds === null) {
return $this->allResults($returnOnlyCount);
}

$connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable(self::PAGES_TABLE);
$maxBindParameters = PlatformInformation::getMaxBindParameters($connection->getDatabasePlatform());

$pages = [];
$pageCount = 0;
foreach (array_chunk($pageIds, $maxBindParameters - 10) as $chunk) {
$query = $this->getResults($chunk);
if ($query === null) {
continue;
}

if ($returnOnlyCount) {
$pageCount += $query->rowCount();
continue;
}

foreach ($query->fetchAll() as $page) {
$pages[] = $page;
}
}

if ($returnOnlyCount === false) {
return $pages;
}

return $pageCount;
}

protected function getResults(array $pageIds = []): ?ResultStatement
{
// Needs to be overwritten by provider, not possible to set an abstract function due to API change
return null;
}

protected function allResults(bool $returnOnlyCount = false)
{
$query = $this->getResults();
if ($query === null) {
return $returnOnlyCount ? 0 : [];
}
if ($returnOnlyCount) {
return $query->rowCount();
}
return $query->fetchAll();
}
}
38 changes: 20 additions & 18 deletions Classes/DataProviders/CornerstoneOverviewDataProvider.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<?php

namespace YoastSeoForTypo3\YoastSeo\DataProviders;

/*
@@ -14,6 +15,7 @@
* The TYPO3 project - inspiring people to share!
*/

use Doctrine\DBAL\Driver\ResultStatement;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Utility\GeneralUtility;

@@ -22,34 +24,34 @@
*/
class CornerstoneOverviewDataProvider extends AbstractOverviewDataProvider
{

/**
* @param bool $returnOnlyCount
* @return int|array
*/
public function getData($returnOnlyCount = false)
{
$language = (int)$this->callerParams['language'];
$constraints = [];
$table = 'pages';

$qb = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
return $this->getRestrictedPagesResults($returnOnlyCount);
}

if ($language > 0) {
$constraints[] = $qb->expr()->eq('sys_language_uid', $language);
protected function getResults(array $pageIds = []): ?ResultStatement
{
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable(self::PAGES_TABLE);

$constraints = [
$queryBuilder->expr()->eq('sys_language_uid', (int)$this->callerParams['language']),
$queryBuilder->expr()->eq('tx_yoastseo_cornerstone', 1)
];

if (count($pageIds) > 0) {
$constraints[] = $queryBuilder->expr()->in(
(int)$this->callerParams['language'] > 0 ? $GLOBALS['TCA']['pages']['ctrl']['transOrigPointerField'] : 'uid',
$pageIds
);
}

$constraints[] = $qb->expr()->eq('tx_yoastseo_cornerstone', 1);

$query = $qb->select('*')
->from($table)
return $queryBuilder->select('*')
->from(self::PAGES_TABLE)
->where(...$constraints)
->execute();

if ($returnOnlyCount === false) {
return $query->fetchAll();
}

return $query->rowCount();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

declare(strict_types=1);

namespace YoastSeoForTypo3\YoastSeo\DataProviders;

/*
@@ -15,6 +17,7 @@
* The TYPO3 project - inspiring people to share!
*/

use Doctrine\DBAL\Driver\ResultStatement;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use YoastSeoForTypo3\YoastSeo\Utility\YoastUtility;
@@ -24,37 +27,41 @@
*/
class PagesWithoutDescriptionOverviewDataProvider extends AbstractOverviewDataProvider
{
protected const PAGES_TABLE = 'pages';

/**
* @param bool $returnOnlyCount
* @return int|array
*/
public function getData($returnOnlyCount = false)
{
$doktypes = implode(',', YoastUtility::getAllowedDoktypes()) ?: '-1';
$table = 'pages';
return $this->getRestrictedPagesResults($returnOnlyCount);
}

$qb = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
protected function getResults(array $pageIds = []): ?ResultStatement
{
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable(self::PAGES_TABLE);

$constraints = [
$qb->expr()->orX(
$qb->expr()->eq('description', $qb->createNamedParameter('')),
$qb->expr()->isNull('description')
$queryBuilder->expr()->orX(
$queryBuilder->expr()->eq('description', $queryBuilder->createNamedParameter('')),
$queryBuilder->expr()->isNull('description')
),
$qb->expr()->in('doktype', $doktypes),
$qb->expr()->eq('tx_yoastseo_hide_snippet_preview', 0),
$qb->expr()->eq('sys_language_uid', (int)$this->callerParams['language'])
$queryBuilder->expr()->in('doktype', YoastUtility::getAllowedDoktypes()),
$queryBuilder->expr()->eq('tx_yoastseo_hide_snippet_preview', 0),
$queryBuilder->expr()->eq('sys_language_uid', (int)$this->callerParams['language'])
];

$query = $qb->select('*')
->from($table)
->where(...$constraints)
->execute();

if ($returnOnlyCount === false) {
return $query->fetchAll();
if (count($pageIds) > 0) {
$constraints[] = $queryBuilder->expr()->in(
(int)$this->callerParams['language'] > 0 ? $GLOBALS['TCA']['pages']['ctrl']['transOrigPointerField'] : 'uid',
$pageIds
);
}

return $query->rowCount();
return $queryBuilder->select(...self::PAGES_FIELDS)
->from(self::PAGES_TABLE)
->where(...$constraints)
->execute();
}
}
Loading

0 comments on commit cc26ef7

Please sign in to comment.