Skip to content

Commit

Permalink
[MAINTENANCE] Add support for Typo3 v12 (fixes kitodo#900)
Browse files Browse the repository at this point in the history
- Update composer.json for Typo3 v12
- Add missing dependency for `typo3/cms-scheduler`
- Add version restriction for phpunit v9 (phpunit v10 has breaking changes)
- Upgrade dependency `typo3/testing-framework` to v7, which is compatible with Typo3 v11 and v12
- Fix basic problems with extension configuration (see Typo3 Feature #96733)
- Replace `TYPO3_MODE` references (see Typo3 Deprecation #92947)
- Remove phpstan ignore rule `TYPO3_MODE not found`, which is not required any more
- Fix flash message rendering (see Typo3 Depcrecation #97787)
- Fix `SolrSearch` implementation by extending from `Query` class (see Typo3 Breaking #96044)
- Avoid initialization via constructor in `AbstractController` (required to access $request when migrating to v13, see Typo3 Deprecation #99615)
- Fix NewTenantController by using dependency injection (see Typo3 Manual)
- Return ResponseInterfaces in controller actions (see Typo3 Deprecation #92784)
- Change `forward` calls to `redirect` in controller classes (see Typo3 Deprecation #92815)
- Remove reference to old `ObjectManager` (see Typo3 Deprecation #94619)
- Determine login status via Context class instead of `$GLOBALS["TSFE"]` (see Typo3 Manual)
- Update GitHub CI tests to Typo3 v11 (with PHP 7.4) and v12 (with PHP 8.1)
- Remove columns `cruser_id`, `t3ver_oid`, `t3ver_wsid`, `t3ver_state`, `t3ver_stage` from test fixtures, which are not available in Typo3 v12 any more (see Typo3 Breaking #98024)
- Fix OAI-PMH template in case of request without verb or other parameters
- Fix various undefined array key issues that are raised when using PHP 8+
  • Loading branch information
thomaslow committed Sep 17, 2024
1 parent 55f8976 commit b8c402e
Show file tree
Hide file tree
Showing 56 changed files with 416 additions and 399 deletions.
1 change: 0 additions & 1 deletion .github/phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ parameters:
- '#Constant LOG_SEVERITY_ERROR not found\.#'
- '#Constant LOG_SEVERITY_NOTICE not found\.#'
- '#Constant LOG_SEVERITY_WARNING not found\.#'
- '#Constant TYPO3_MODE not found\.#'
level: 5
paths:
- ../Classes/
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,19 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
typo3: [ 10.4, 11.5 ]
variants: [ {typo3: 11.5, php: 7.4}, {typo3: 12.4, php: 8.1} ]
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Install dependencies
run: Build/Test/runTests.sh -s composerInstall -t ${{ matrix.typo3 }}
run: Build/Test/runTests.sh -s composerInstall -t ${{ matrix.variants.typo3 }} -p ${{ matrix.variants.php }}

- name: Run unit tests
run: Build/Test/runTests.sh -s unit
run: Build/Test/runTests.sh -s unit -p ${{ matrix.variants.php }}

- name: Run functional tests
run: Build/Test/runTests.sh -s functional
run: Build/Test/runTests.sh -s functional -p ${{ matrix.variants.php }}

- name: Upload coverage reports
uses: codecov/codecov-action@v4
Expand Down
2 changes: 1 addition & 1 deletion Build/Test/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ services:
"
solr:
image: docker.io/solr:9
image: docker.io/solr:9.6
volumes:
- ${DLF_ROOT}/Configuration/ApacheSolr/configsets:/var/solr/data/configsets
- ./solr/modules/ocrsearch:/opt/solr/modules/ocrsearch
Expand Down
4 changes: 2 additions & 2 deletions Build/Test/runTests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,12 @@ Options:
- functional: PHP functional tests
- unit (default): PHP unit tests
-t <|10.4|11.5>
-t <|11.5|12.4>
Only with -s composerInstall
Specifies which TYPO3 version to install. When unset, installs either the packages from
composer.lock, or the latest version otherwise (default behavior of "composer install").
- 10.4
- 11.5
- 12.4
-a <mysqli|pdo_mysql>
Only with -s functional
Expand Down
2 changes: 1 addition & 1 deletion Classes/Command/BaseCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ protected function initializeRepositories(int $storagePid): void
*
* @return int matching uid of Solr core
*/
protected function getSolrCoreUid(array $solrCores, $inputSolrId): int
protected function getSolrCoreUid(array $solrCores, $inputSolrId): ?int
{
if (MathUtility::canBeInterpretedAsInteger($inputSolrId)) {
$solrCoreUid = MathUtility::forceIntegerInRange((int) $inputSolrId, 0);
Expand Down
12 changes: 6 additions & 6 deletions Classes/Common/Helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@

use TYPO3\CMS\Core\Configuration\ConfigurationManager;
use TYPO3\CMS\Core\Configuration\ExtensionConfiguration;
use TYPO3\CMS\Core\Core\Environment;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Http\Uri;
use TYPO3\CMS\Core\Http\ApplicationType;
use TYPO3\CMS\Core\Http\RequestFactory;
use TYPO3\CMS\Core\Log\LogManager;
use TYPO3\CMS\Core\Context\Context;
Expand Down Expand Up @@ -583,7 +585,7 @@ public static function processDatabaseAsAdmin(array $data = [], array $cmd = [],
$context = GeneralUtility::makeInstance(Context::class);

if (
\TYPO3_MODE === 'BE'
ApplicationType::fromRequest($GLOBALS['TYPO3_REQUEST'])->isBackend()
&& $context->getPropertyFromAspect('backend.user', 'isAdmin')
) {
// Instantiate TYPO3 core engine.
Expand Down Expand Up @@ -783,8 +785,7 @@ public static function translate(string $indexName, string $table, string $pid):
*/
public static function whereExpression(string $table, bool $showHidden = false): string
{
// TODO: Check with applicationType; TYPO3_MODE is removed in v12
if (\TYPO3_MODE === 'FE') {
if (!Environment::isCli() && ApplicationType::fromRequest($GLOBALS['TYPO3_REQUEST'])->isFrontend()) {
// Should we ignore the record's hidden flag?
$ignoreHide = 0;
if ($showHidden) {
Expand All @@ -799,14 +800,13 @@ public static function whereExpression(string $table, bool $showHidden = false):
} else {
return '';
}
// TODO: Check with applicationType; TYPO3_MODE is removed in v12
} elseif (\TYPO3_MODE === 'BE') {
} elseif (Environment::isCli() || ApplicationType::fromRequest($GLOBALS['TYPO3_REQUEST'])->isBackend()) {
return GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable($table)
->expr()
->eq($table . '.' . $GLOBALS['TCA'][$table]['ctrl']['delete'], 0);
} else {
self::log('Unexpected TYPO3_MODE', LOG_SEVERITY_ERROR);
self::log('Unexpected application type (neither frontend or backend)', LOG_SEVERITY_ERROR);
return '1=-1';
}
}
Expand Down
27 changes: 25 additions & 2 deletions Classes/Common/KitodoFlashMessageRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class KitodoFlashMessageRenderer implements FlashMessageRendererInterface
* @var array The message severity class names
*/
protected static array $classes = [
// Todo: FlashMessage constants deprecated in v12, remove when dropping v11 support
FlashMessage::NOTICE => 'notice',
FlashMessage::INFO => 'info',
FlashMessage::OK => 'success',
Expand All @@ -44,6 +45,7 @@ class KitodoFlashMessageRenderer implements FlashMessageRendererInterface
* @var array The message severity icon names
*/
protected static array $icons = [
// Todo: FlashMessage constants deprecated in v12, remove when dropping v11 support
FlashMessage::NOTICE => 'lightbulb-o',
FlashMessage::INFO => 'info',
FlashMessage::OK => 'check',
Expand All @@ -65,6 +67,27 @@ public function render(array $flashMessages): string
return $this->getMessageAsMarkup($flashMessages);
}

/**
* Gets the message severity as integer value for compatibility with Typo3 v12
*
* @access public
*
* @param FlashMessage $flashMessage
*
* @return int The message severity as integer
*/
protected function getSeverityAsInt(FlashMessage $flashMessage): int
{
$severity = $flashMessage->getSeverity();
if (is_int($severity)) {
// $severity is integer constant from FlashMessage in Typo3 v11
return $severity;
}
// $severity is instance of ContextualFeedbackSeverity enum introduced in Typo3 v12
// TODO: migrate message severity to ContextualFeedbackSeverity when dropping support for Typo3 v11
return $severity->value;
}

/**
* Gets the message severity class name
*
Expand All @@ -76,7 +99,7 @@ public function render(array $flashMessages): string
*/
protected function getClass(FlashMessage $flashMessage): string
{
return 'alert-' . self::$classes[$flashMessage->getSeverity()];
return 'alert-' . self::$classes[$this->getSeverityAsInt($flashMessage)];
}

/**
Expand All @@ -90,7 +113,7 @@ protected function getClass(FlashMessage $flashMessage): string
*/
protected function getIconName(FlashMessage $flashMessage): string
{
return self::$icons[$flashMessage->getSeverity()];
return self::$icons[$this->getSeverityAsInt($flashMessage)];
}

/**
Expand Down
17 changes: 16 additions & 1 deletion Classes/Common/Solr/SolrSearch.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use TYPO3\CMS\Core\Utility\MathUtility;
use TYPO3\CMS\Extbase\Persistence\Generic\QueryResult;
use TYPO3\CMS\Extbase\Persistence\QueryResultInterface;
use TYPO3\CMS\Extbase\Persistence\QueryInterface;

/**
* Targeted towards being used in ``PaginateController`` (``<f:widget.paginate>``).
Expand Down Expand Up @@ -318,6 +319,20 @@ public function getQuery()
return new SolrSearchQuery($this);
}

/**
* Sets query.
*
* @access public
*
* @param QueryInterface $query the query
*
* @return void
*/
public function setQuery(QueryInterface $query): void
{
throw new \Exception("setQuery not supported on SolrSearch instance");
}

/**
* Gets first.
*
Expand Down Expand Up @@ -860,7 +875,7 @@ private function getDocument(Document $record, array $highlighting, array $field
*/
private function translateLanguageCode(&$doc): void
{
if (array_key_exists('language', $doc['metadata'])) {
if (isset($doc['metadata']) && array_key_exists('language', $doc['metadata'])) {
foreach($doc['metadata']['language'] as $indexName => $language) {
$doc['metadata']['language'][$indexName] = Helper::getLanguageName($language);
}
Expand Down
68 changes: 4 additions & 64 deletions Classes/Common/Solr/SolrSearchQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
namespace Kitodo\Dlf\Common\Solr;

use TYPO3\CMS\Extbase\Persistence\QueryInterface;
use TYPO3\CMS\Extbase\Persistence\Generic\Qom\AndInterface;
use TYPO3\CMS\Extbase\Persistence\Generic\Qom\ConstraintInterface;
use TYPO3\CMS\Extbase\Persistence\Generic\Qom\OrInterface;
use TYPO3\CMS\Extbase\Persistence\Generic\Qom\SourceInterface;
use TYPO3\CMS\Extbase\Persistence\Generic\Query;
use TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface;

/**
Expand All @@ -18,7 +21,7 @@
* @property int $limit
* @property int $offset
*/
class SolrSearchQuery implements QueryInterface
class SolrSearchQuery extends Query
{
/**
* @access private
Expand All @@ -27,18 +30,6 @@ class SolrSearchQuery implements QueryInterface
private SolrSearch $solrSearch;

/**
* @access private
* @var int
*/
private int $limit;

/**
* @access private
* @var int
*/
private int $offset;

/**
* Constructs SolrSearchQuery instance.
*
* @access public
Expand All @@ -55,10 +46,6 @@ public function __construct($solrSearch)
$this->limit = count($solrSearch);
}

// this class contains a lot of methods which are inherited but not implemented
// @phpstan-ignore-next-line
public function getSource() {}

/**
* Executes SOLR search query.
*
Expand All @@ -83,9 +70,6 @@ public function execute($returnRawQueryResult = false)
return $result;
}

// @phpstan-ignore-next-line
public function setOrderings(array $orderings) {}

/**
* Sets limit for SOLR search query.
*
Expand Down Expand Up @@ -116,44 +100,6 @@ public function setOffset($offset): SolrSearchQuery
return $this;
}

// @phpstan-ignore-next-line
public function matching($constraint) {}
// @phpstan-ignore-next-line
public function logicalAnd($constraint1) {}
// @phpstan-ignore-next-line
public function logicalOr($constraint1) {}
// @phpstan-ignore-next-line
public function logicalNot(ConstraintInterface $constraint) {}
// @phpstan-ignore-next-line
public function equals($propertyName, $operand, $caseSensitive = true) {}
// @phpstan-ignore-next-line
public function like($propertyName, $operand) {}
// @phpstan-ignore-next-line
public function contains($propertyName, $operand) {}
// @phpstan-ignore-next-line
public function in($propertyName, $operand) {}
// @phpstan-ignore-next-line
public function lessThan($propertyName, $operand) {}
// @phpstan-ignore-next-line
public function lessThanOrEqual($propertyName, $operand) {}
// @phpstan-ignore-next-line
public function greaterThan($propertyName, $operand) {}
// @phpstan-ignore-next-line
public function greaterThanOrEqual($propertyName, $operand) {}
// @phpstan-ignore-next-line
public function getType() {}
public function setQuerySettings(QuerySettingsInterface $querySettings) {}
// @phpstan-ignore-next-line
public function getQuerySettings() {}

public function count()
{// @phpstan-ignore-next-line
// TODO?
}

// @phpstan-ignore-next-line
public function getOrderings() {}

/**
* Gets limit for SOLR search query.
*
Expand All @@ -178,10 +124,4 @@ public function getOffset(): int
return $this->offset;
}

// @phpstan-ignore-next-line
public function getConstraint() {}
public function isEmpty($propertyName) {}
public function setSource(SourceInterface $source) {}
// @phpstan-ignore-next-line
public function getStatement() {}
}
21 changes: 16 additions & 5 deletions Classes/Controller/AbstractController.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,19 @@
use Kitodo\Dlf\Common\Helper;
use Kitodo\Dlf\Domain\Model\Document;
use Kitodo\Dlf\Domain\Repository\DocumentRepository;
use Psr\Http\Message\ResponseInterface;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerAwareTrait;
use TYPO3\CMS\Core\Configuration\ExtensionConfiguration;
use TYPO3\CMS\Core\Localization\LanguageService;
use TYPO3\CMS\Core\Pagination\PaginationInterface;
use TYPO3\CMS\Core\Utility\ArrayUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\MathUtility;
use TYPO3\CMS\Core\Pagination\PaginatorInterface;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
use TYPO3\CMS\Extbase\Mvc\RequestInterface;


/**
* Abstract controller class for most of the plugin controller.
Expand Down Expand Up @@ -97,11 +101,14 @@ public function injectDocumentRepository(DocumentRepository $documentRepository)
* Initialize the plugin controller
*
* @access protected
*
* @param RequestInterface $request the HTTP request
*
* @return void
*/
protected function initialize(): void
protected function initialize(RequestInterface $request): void
{
// replace with $this->request->getQueryParams() when dropping support for Typo3 v11, see Deprecation-100596
$this->requestData = GeneralUtility::_GPmerged('tx_dlf');
$this->pageUid = (int) GeneralUtility::_GET('id');

Expand Down Expand Up @@ -376,15 +383,19 @@ protected function setDefaultPage(): void
}

/**
* This is the constructor
* Wrapper for ActionController::processRequest in order to initialize things
* without using a constructor.
*
* @access public
*
* @param RequestInterface $request the request
*
* @return void
* @return ResponseInterface the response
*/
public function __construct()
public function processRequest(RequestInterface $request): ResponseInterface
{
$this->initialize();
$this->initialize($request);
return parent::processRequest($request);
}

/**
Expand Down
Loading

0 comments on commit b8c402e

Please sign in to comment.