Skip to content

Commit

Permalink
Do not update child pages when parent page has slug_locked=1
Browse files Browse the repository at this point in the history
Relates: wazum#112
  • Loading branch information
Christoph Lehmann committed Nov 23, 2024
1 parent 8382d2e commit a503c7c
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 25 deletions.
26 changes: 26 additions & 0 deletions Classes/Database/SlugUnLockedRestriction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace Wazum\Sluggi\Database;

use TYPO3\CMS\Core\Database\Query\Expression\CompositeExpression;
use TYPO3\CMS\Core\Database\Query\Expression\ExpressionBuilder;
use TYPO3\CMS\Core\Database\Query\Restriction\QueryRestrictionInterface;

class SlugUnlockedRestriction implements QueryRestrictionInterface
{
public function buildExpression(array $queriedTables, ExpressionBuilder $expressionBuilder): CompositeExpression
{
$constraints = [];
foreach ($queriedTables as $tableAlias => $tableName) {
if ($tableName === 'pages') {
$constraints[] = $expressionBuilder->eq(
$tableAlias . '.' . 'slug_locked',
0
);
}
}
return $expressionBuilder->and(...$constraints);
}
}
81 changes: 56 additions & 25 deletions Classes/Service/SlugService.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,68 @@

namespace Wazum\Sluggi\Service;

use TYPO3\CMS\Redirects\RedirectUpdate\SlugRedirectChangeItem;
use TYPO3\CMS\Core\Database\Connection;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use Wazum\Sluggi\Database\SlugUnlockedRestriction;

final class SlugService extends \TYPO3\CMS\Redirects\Service\SlugService
{
protected function checkSubPages(array $currentPageRecord, SlugRedirectChangeItem $parentChangeItem): array
/**
* Prevent updating slugs of pages with slug_locked=1 AND its children
*/
protected function resolveSubPages(int $id, int $languageUid): array
{
$sourceHosts = [];
$languageUid = (int) $currentPageRecord['sys_language_uid'];
// resolveSubPages needs the page id of the default language
$pageId = 0 === $languageUid ? (int) $currentPageRecord['uid'] : (int) $currentPageRecord['l10n_parent'];
$subPageRecords = $this->resolveSubPages($pageId, $languageUid);
foreach ($subPageRecords as $subPageRecord) {
if ($subPageRecord['slug_locked']) {
continue;
}
// First resolve all sub-pages in default language
$queryBuilder = $this->getQueryBuilderForPages();
// Patch start
if ($languageUid === 0) {
$queryBuilder
->getRestrictions()
->add(GeneralUtility::makeInstance(SlugUnlockedRestriction::class));
}
// Patch end
$subPages = $queryBuilder
->select('*')
->from('pages')
->where(
$queryBuilder->expr()->eq('pid', $queryBuilder->createNamedParameter($id, Connection::PARAM_INT)),
$queryBuilder->expr()->eq('sys_language_uid', $queryBuilder->createNamedParameter(0, Connection::PARAM_INT))
)
->orderBy('uid', 'ASC')
->executeQuery()
->fetchAllAssociative();

$changeItem = $this->slugRedirectChangeItemFactory->create(
pageId: (int) $subPageRecord['uid'],
original: $subPageRecord
);
if (null === $changeItem) {
continue;
}
$updatedPageRecord = $this->updateSlug($subPageRecord, $parentChangeItem);
if (null !== $updatedPageRecord && $this->autoCreateRedirects) {
$subPageId = 0 === (int) $subPageRecord['sys_language_uid'] ? (int) $subPageRecord['uid'] : (int) $subPageRecord['l10n_parent'];
$changeItem = $changeItem->withChanged($updatedPageRecord);
$sourceHosts += array_values($this->createRedirects($changeItem, $subPageId, $languageUid));
// if the language is not the default language, resolve the language related records.
if ($languageUid > 0) {
$queryBuilder = $this->getQueryBuilderForPages();
// Patch start
$queryBuilder
->getRestrictions()
->add(GeneralUtility::makeInstance(SlugUnlockedRestriction::class));
// Patch end
$subPages = $queryBuilder
->select('*')
->from('pages')
->where(
$queryBuilder->expr()->in('l10n_parent', $queryBuilder->createNamedParameter(array_column($subPages, 'uid'), Connection::PARAM_INT_ARRAY)),
$queryBuilder->expr()->eq('sys_language_uid', $queryBuilder->createNamedParameter($languageUid, Connection::PARAM_INT))
)
->orderBy('uid', 'ASC')
->executeQuery()
->fetchAllAssociative();
}
$results = [];
if (!empty($subPages)) {
$subPages = $this->pageRepository->getPagesOverlay($subPages, $languageUid);
foreach ($subPages as $subPage) {
$results[] = $subPage;
// resolveSubPages needs the page id of the default language
$pageId = $languageUid === 0 ? (int)$subPage['uid'] : (int)$subPage['l10n_parent'];
foreach ($this->resolveSubPages($pageId, $languageUid) as $page) {
$results[] = $page;
}
}
}

return $sourceHosts;
return $results;
}
}

0 comments on commit a503c7c

Please sign in to comment.