Skip to content

Commit

Permalink
[FEATURE] Raise compatibility to TYPO3 13.2
Browse files Browse the repository at this point in the history
  • Loading branch information
IchHabRecht committed Sep 6, 2024
1 parent ec87b5a commit 6683dda
Show file tree
Hide file tree
Showing 25 changed files with 319 additions and 215 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/analyze.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,14 @@ jobs:
uses: shivammathur/setup-php@v2
with:
php-version: ${{ env.php }}
extensions: mbstring, intl, pdo_sqlite, pdo_mysql
tools: composer:v2

- name: Environment Check
run: |
php --version
composer --version
find '.Log' -wholename '*.cov' | parallel --gnu 'echo ""; echo ""; echo "{}"; cat {}'
- name: Composer install
run: composer require --no-progress --no-suggest typo3/cms-core:"${{ env.typo3 }}" nimut/phpunit-merger
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ jobs:

- name: Unit Tests
if: ${{ hashFiles('Tests/Unit/') != '' }}
run: .Build/bin/phpunit --bootstrap .Build/vendor/typo3/testing-framework/Resources/Core/Build/UnitTestsBootstrap.php --testsuite unit
run: .Build/bin/phpunit --bootstrap .Build/vendor/typo3/testing-framework/Resources/Core/Build/UnitTestsBootstrap.php --no-coverage --no-logging --testsuite unit

- name: Functional Tests
if: ${{ success() || failure() }} && ${{ hashFiles('Tests/Functional/') != '' }}
Expand All @@ -94,4 +94,4 @@ jobs:
sudo /etc/init.d/mysql start
mkdir -p .Build/public/typo3conf/ext/
if [ ! -L .Build/public/typo3conf/ext/content_defender ]; then ln -snvf ../../../../. .Build/public/typo3conf/ext/content_defender; fi
find 'Tests/Functional' -wholename '*Test.php' | parallel --gnu 'echo; echo "Running functional test suite {}"; .Build/bin/phpunit --bootstrap .Build/vendor/typo3/testing-framework/Resources/Core/Build/FunctionalTestsBootstrap.php {}'
find 'Tests/Functional' -wholename '*Test.php' | parallel --gnu 'echo ""; echo ""; echo; echo "Running functional test suite {}"; .Build/bin/phpunit --bootstrap .Build/vendor/typo3/testing-framework/Resources/Core/Build/FunctionalTestsBootstrap.php --no-coverage --no-logging {}'
3 changes: 2 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,13 @@ jobs:
sudo /etc/init.d/mysql start
mkdir -p .Build/public/typo3conf/ext/
if [ ! -L .Build/public/typo3conf/ext/content_defender ]; then ln -snvf ../../../../. .Build/public/typo3conf/ext/content_defender; fi
find 'Tests/Functional' -wholename '*Test.php' | parallel --gnu 'echo "Running functional test suite {}"; HASH=${{ steps.version-cache.outputs.version }}_$( echo {} | md5sum | cut -d " " -f 1); .Build/bin/phpunit --bootstrap .Build/vendor/typo3/testing-framework/Resources/Core/Build/FunctionalTestsBootstrap.php --log-junit .Log/junit/functional_$HASH.xml --coverage-php .Log/coverage/functional_$HASH.cov {}'
find 'Tests/Functional' -wholename '*Test.php' | parallel --gnu 'echo ""; echo ""; echo "Running functional test suite {}"; HASH=${{ steps.version-cache.outputs.version }}_${{ matrix.php }}_$( echo {} | md5sum | cut -d " " -f 1); .Build/bin/phpunit --bootstrap .Build/vendor/typo3/testing-framework/Resources/Core/Build/FunctionalTestsBootstrap.php --log-junit .Log/junit/functional_$HASH.xml --coverage-php .Log/coverage/functional_$HASH.cov {}'
- name: Archive PHPUnit logs
uses: actions/upload-artifact@v4
with:
name: phpunit-logs-${{ runner.os }}-${{ matrix.typo3 }}-${{ matrix.php }}
path: .Log/*
compression-level: 0
include-hidden-files: true
retention-days: 1
2 changes: 1 addition & 1 deletion Classes/BackendLayout/BackendLayoutConfiguration.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public static function createFromPageId($pageId)
{
// TODO: Mitigate a problem in \TYPO3\CMS\Backend\Configuration\TypoScript\ConditionMatching\ConditionMatcher::determinePageId
// @see: https://github.com/IchHabRecht/content_defender/issues/91
if (GeneralUtility::_GP('id') === null) {
if (($_POST['id'] ?? $_GET['id'] ?? null) === null) {
$_GET['id'] = $pageId;
}
$backendLayoutView = GeneralUtility::makeInstance(BackendLayoutView::class);
Expand Down
17 changes: 16 additions & 1 deletion Classes/Hooks/AbstractDataHandlerHook.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/

use IchHabRecht\ContentDefender\Repository\ContentRepository;
use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Backend\Form\FormDataCompiler;
use TYPO3\CMS\Backend\Form\FormDataGroup\OnTheFly;
use TYPO3\CMS\Backend\Form\FormDataProvider\DatabaseRecordTypeValue;
Expand All @@ -27,6 +28,7 @@
use TYPO3\CMS\Backend\Form\FormDataProvider\TcaColumnsProcessShowitem;
use TYPO3\CMS\Backend\Form\FormDataProvider\TcaColumnsRemoveUnused;
use TYPO3\CMS\Backend\Form\FormDataProvider\UserTsConfig;
use TYPO3\CMS\Core\Information\Typo3Version;
use TYPO3\CMS\Core\Utility\GeneralUtility;

abstract class AbstractDataHandlerHook
Expand All @@ -36,12 +38,15 @@ abstract class AbstractDataHandlerHook
*/
protected $contentRepository;

protected string $versionBranch;

/**
* @param ContentRepository $contentRepository
*/
public function __construct(ContentRepository $contentRepository = null)
{
$this->contentRepository = $contentRepository ?? GeneralUtility::makeInstance(ContentRepository::class);
$this->versionBranch = (new Typo3Version())->getBranch();
}

/**
Expand All @@ -55,6 +60,10 @@ protected function isRecordAllowedByRestriction(array $columnConfiguration, arra
return true;
}

if (!($GLOBALS['TYPO3_REQUEST'] ?? null instanceof ServerRequestInterface) && version_compare($this->versionBranch, '13', '>=')) {
return true;
}

$formDataGroup = GeneralUtility::makeInstance(OnTheFly::class);
$formDataGroup->setProviderList(
[
Expand All @@ -70,12 +79,18 @@ protected function isRecordAllowedByRestriction(array $columnConfiguration, arra
$formDataCompiler = GeneralUtility::makeInstance(FormDataCompiler::class, $formDataGroup);
$formDataCompilerInput = [
'command' => 'edit',
'request' => $GLOBALS['TYPO3_REQUEST'] ?? null,
'databaseRow' => $record,
'effectivePid' => $record['pid'],
'tableName' => 'tt_content',
'vanillaUid' => (int)$record['uid'],
];
$result = $formDataCompiler->compile($formDataCompilerInput);

if (version_compare($this->versionBranch, '13', '<')) {
unset($formDataCompilerInput['request']);
}

$result = $formDataCompiler->compile($formDataCompilerInput, $formDataGroup);

$allowedConfiguration = array_intersect_key($columnConfiguration['allowed.'] ?? [], $result['processedTca']['columns']);
foreach ($allowedConfiguration as $field => $value) {
Expand Down
5 changes: 2 additions & 3 deletions Classes/Hooks/CmdmapDataHandlerHook.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
use IchHabRecht\ContentDefender\BackendLayout\BackendLayoutConfiguration;
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\DataHandling\DataHandler;
use TYPO3\CMS\Core\Utility\GeneralUtility;

class CmdmapDataHandlerHook extends AbstractDataHandlerHook
{
Expand All @@ -46,7 +45,7 @@ public function processCmdmap_beforeStart(DataHandler $dataHandler)
if ($command === 'move') {
// New colPos is passed as datamap array and already processed in processDatamap_beforeStart
$data = isset($dataHandler->datamap['tt_content'][$id])
? $dataHandler->datamap : GeneralUtility::_GP('data');
? $dataHandler->datamap : ($_POST['data'] ?? $_GET['data'] ?? null);
if (isset($data['tt_content'][$id])) {
if (isset($data['tt_content'][$id]['colPos'])
&& (int)$currentRecord['colPos'] !== (int)$data['tt_content'][$id]['colPos']
Expand Down Expand Up @@ -128,7 +127,7 @@ public function processCmdmap_beforeStart(DataHandler $dataHandler)
}

if (count($cmdmap['tt_content']) !== count($dataHandler->cmdmap['tt_content'])
&& empty(GeneralUtility::_GP('prErr'))
&& empty($_POST['prErr'] ?? $_GET['prErr'] ?? null)
) {
$dataHandler->printLogErrorMessages();
}
Expand Down
3 changes: 1 addition & 2 deletions Classes/Hooks/DatamapDataHandlerHook.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
use IchHabRecht\ContentDefender\BackendLayout\BackendLayoutConfiguration;
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\DataHandling\DataHandler;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\MathUtility;

class DatamapDataHandlerHook extends AbstractDataHandlerHook
Expand Down Expand Up @@ -75,7 +74,7 @@ public function processDatamap_beforeStart(DataHandler $dataHandler)
// DataHandler copies a record by first add a new content element (in the old colPos) and then adjust
// the colPos information to the target colPos. This means we have to allow this element to be added
// even if the maxitems is reached already. The copy command was checked in CmdmapDataHandlerHook.
if (empty($dataHandler->cmdmap) && !empty(GeneralUtility::_GP('CB')['paste'])) {
if (empty($dataHandler->cmdmap) && !empty($_POST['CB']['paste'] ?? $_GET['CB']['paste'] ?? null)) {
continue;
}

Expand Down
93 changes: 93 additions & 0 deletions Classes/Hooks/NewContentElementWizardHook.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?php

declare(strict_types=1);

namespace IchHabRecht\ContentDefender\Hooks;

/*
* This file is part of the TYPO3 extension content_defender.
*
* (c) Nicole Cordes <[email protected]>
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE file that was distributed with this source code.
*/

use IchHabRecht\ContentDefender\BackendLayout\BackendLayoutConfiguration;
use TYPO3\CMS\Backend\Controller\ContentElement\NewContentElementController;
use TYPO3\CMS\Backend\Wizard\NewContentElementWizardHookInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility;

class NewContentElementWizardHook extends WizardItemsHook implements NewContentElementWizardHookInterface
{
/**
* @param array $wizardItems
* @param NewContentElementController $parentObject
* @return void
*/
public function manipulateWizardItems(&$wizardItems, &$parentObject)
{
$pageId = (int)$parentObject->getPageInfo()['uid'];
$backendLayoutConfiguration = BackendLayoutConfiguration::createFromPageId($pageId);

$colPos = (int)$parentObject->getColPos();
$columnConfiguration = $backendLayoutConfiguration->getConfigurationByColPos($colPos);
if (empty($columnConfiguration) || (empty($columnConfiguration['allowed.']) && empty($columnConfiguration['disallowed.']))) {
return;
}

$allowedConfiguration = $columnConfiguration['allowed.'] ?? [];
foreach ($allowedConfiguration as $field => $value) {
$allowedValues = GeneralUtility::trimExplode(',', $value);
$wizardItems = $this->removeDisallowedValues($wizardItems, $field, $allowedValues);
}

$disallowedConfiguration = $columnConfiguration['disallowed.'] ?? [];
foreach ($disallowedConfiguration as $field => $value) {
$disAllowedValues = GeneralUtility::trimExplode(',', $value);
$wizardItems = $this->removeDisallowedValues($wizardItems, $field, $disAllowedValues, false);
}

$availableWizardItems = [];
foreach ($wizardItems as $key => $_) {
$keyParts = explode('_', $key, 2);
if (count($keyParts) === 1) {
continue;
}
$availableWizardItems[$keyParts[0]] = $key;
$availableWizardItems[$key] = $key;
}

$wizardItems = array_intersect_key($wizardItems, $availableWizardItems);
}

/**
* @param array $wizardItems
* @param string $field
* @param array $values
* @param bool $allowed
* @return array
*/
protected function removeDisallowedValues(array $wizardItems, $field, array $values, $allowed = true)
{
foreach ($wizardItems as $key => $configuration) {
$keyParts = explode('_', $key, 2);
if (count($keyParts) === 1 || !isset($configuration['tt_content_defValues'][$field])) {
continue;
}

if (($allowed && !in_array($configuration['tt_content_defValues'][$field], $values))
|| (!$allowed && in_array($configuration['tt_content_defValues'][$field], $values))
) {
unset($wizardItems[$key]);
continue;
}
}

return $wizardItems;
}
}
64 changes: 17 additions & 47 deletions Classes/Hooks/WizardItemsHook.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,10 @@
*/

use IchHabRecht\ContentDefender\BackendLayout\BackendLayoutConfiguration;
use TYPO3\CMS\Backend\Controller\ContentElement\NewContentElementController;
use TYPO3\CMS\Backend\Controller\Event\ModifyNewContentElementWizardItemsEvent;
use TYPO3\CMS\Backend\Wizard\NewContentElementWizardHookInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility;

class WizardItemsHook implements NewContentElementWizardHookInterface
class WizardItemsHook
{
public function modifyWizardItems(ModifyNewContentElementWizardItemsEvent $event)
{
Expand Down Expand Up @@ -64,47 +62,6 @@ public function modifyWizardItems(ModifyNewContentElementWizardItemsEvent $event
$event->setWizardItems(array_intersect_key($wizardItems, $availableWizardItems));
}

/**
* @param array $wizardItems
* @param NewContentElementController $parentObject
* @return void
*/
public function manipulateWizardItems(&$wizardItems, &$parentObject)
{
$pageId = (int)$parentObject->getPageInfo()['uid'];
$backendLayoutConfiguration = BackendLayoutConfiguration::createFromPageId($pageId);

$colPos = (int)$parentObject->getColPos();
$columnConfiguration = $backendLayoutConfiguration->getConfigurationByColPos($colPos);
if (empty($columnConfiguration) || (empty($columnConfiguration['allowed.']) && empty($columnConfiguration['disallowed.']))) {
return;
}

$allowedConfiguration = $columnConfiguration['allowed.'] ?? [];
foreach ($allowedConfiguration as $field => $value) {
$allowedValues = GeneralUtility::trimExplode(',', $value);
$wizardItems = $this->removeDisallowedValues($wizardItems, $field, $allowedValues);
}

$disallowedConfiguration = $columnConfiguration['disallowed.'] ?? [];
foreach ($disallowedConfiguration as $field => $value) {
$disAllowedValues = GeneralUtility::trimExplode(',', $value);
$wizardItems = $this->removeDisallowedValues($wizardItems, $field, $disAllowedValues, false);
}

$availableWizardItems = [];
foreach ($wizardItems as $key => $_) {
$keyParts = explode('_', $key, 2);
if (count($keyParts) === 1) {
continue;
}
$availableWizardItems[$keyParts[0]] = $key;
$availableWizardItems[$key] = $key;
}

$wizardItems = array_intersect_key($wizardItems, $availableWizardItems);
}

/**
* @param array $wizardItems
* @param string $field
Expand All @@ -114,18 +71,31 @@ public function manipulateWizardItems(&$wizardItems, &$parentObject)
*/
protected function removeDisallowedValues(array $wizardItems, $field, array $values, $allowed = true)
{
$group = '';
foreach ($wizardItems as $key => $configuration) {
$keyParts = explode('_', $key, 2);
if (count($keyParts) === 1 || !isset($configuration['tt_content_defValues'][$field])) {
if (count($keyParts) === 1 || (!isset($configuration['defaultValues'][$field]) && !isset($configuration['tt_content_defValues'][$field]))) {
if (!empty($group)) {
unset($wizardItems[$group]);
}
$group = $keyParts[0];
continue;
}

if (($allowed && !in_array($configuration['tt_content_defValues'][$field], $values))
|| (!$allowed && in_array($configuration['tt_content_defValues'][$field], $values))
$defaultValue = $configuration['defaultValues'][$field] ?? $configuration['tt_content_defValues'][$field] ?? '';

if (($allowed && !in_array($defaultValue, $values))
|| (!$allowed && in_array($defaultValue, $values))
) {
unset($wizardItems[$key]);
continue;
}

$group = '';
}

if (!empty($group)) {
unset($wizardItems[$group]);
}

return $wizardItems;
Expand Down
Loading

0 comments on commit 6683dda

Please sign in to comment.