Skip to content

Commit

Permalink
[TASK] Modernize update scripts and cover by functional tests
Browse files Browse the repository at this point in the history
  • Loading branch information
benjaminkott committed May 10, 2023
1 parent b40af59 commit 3c87b53
Show file tree
Hide file tree
Showing 47 changed files with 1,277 additions and 887 deletions.
78 changes: 0 additions & 78 deletions Classes/Hooks/ExtensionUpdate.php

This file was deleted.

161 changes: 161 additions & 0 deletions Classes/Updates/AbstractUpdate.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
<?php
declare(strict_types = 1);

/*
* This file is part of the package t3g/blog.
*
* For the full copyright and license information, please read the
* LICENSE file that was distributed with this source code.
*/

namespace T3G\AgencyPack\Blog\Updates;

use T3G\AgencyPack\Blog\Updates\Criteria\EqualIntCriteria;
use T3G\AgencyPack\Blog\Updates\Criteria\EqualStringCriteria;
use T3G\AgencyPack\Blog\Updates\Criteria\InCriteria;
use T3G\AgencyPack\Blog\Updates\Criteria\IsNullCriteria;
use T3G\AgencyPack\Blog\Updates\Criteria\NotEqualIntCriteria;
use TYPO3\CMS\Core\Database\Connection;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Install\Updates\DatabaseUpdatedPrerequisite;

abstract class AbstractUpdate
{
const CONDITION_AND = 'AND';
const CONDITION_OR = 'OR';

/**
* @var string
*/
protected $title = '';

/**
* @var string
*/
protected $description = '';

/**
* @var Connection[]
*/
protected $connection = [];

public function getIdentifier(): string
{
return get_class($this);
}

public function getTitle(): string
{
return $this->title;
}

public function getDescription(): string
{
return $this->description;
}

public function getPrerequisites(): array
{
return [
DatabaseUpdatedPrerequisite::class
];
}

protected function getConnection(string $table): Connection
{
if (!isset($this->connection[$table])) {
$this->connection[$table] = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($table);
}

return $this->connection[$table];
}

protected function createQueryBuilder(string $table): QueryBuilder
{
$queryBuilder = $this->getConnection($table)->createQueryBuilder();
$queryBuilder->getRestrictions()->removeAll();

return $queryBuilder;
}

protected function tableHasColumn(string $table, string $column): bool
{
$schemaManager = $this->getConnection($table)->createSchemaManager();
$tableColumns = $schemaManager->listTableColumns($table);

if (array_key_exists($column, $tableColumns)) {
return true;
}

return false;
}

protected function createEqualIntCriteria(QueryBuilder $queryBuilder, string $field, int $value): EqualIntCriteria
{
return (new EqualIntCriteria($queryBuilder, $field))
->setValue($value);
}

protected function createNotEqualIntCriteria(QueryBuilder $queryBuilder, string $field, int $value): NotEqualIntCriteria
{
return (new NotEqualIntCriteria($queryBuilder, $field))
->setValue($value);
}

protected function createEqualStringCriteria(QueryBuilder $queryBuilder, string $field, string $value): EqualStringCriteria
{
return (new EqualStringCriteria($queryBuilder, $field))
->setValue($value);
}

protected function createInCriteria(QueryBuilder $queryBuilder, string $field, array $values): InCriteria
{
return (new InCriteria($queryBuilder, $field))
->setValues($values);
}

protected function createIsNullCriteria(QueryBuilder $queryBuilder, string $field): IsNullCriteria
{
return new IsNullCriteria($queryBuilder, $field);
}

protected function getRecordsByCriteria(QueryBuilder $queryBuilder, string $table, array $criteria, string $condition = self::CONDITION_AND): array
{
$queryBuilder->select('*');
$queryBuilder->from($table);
if ($condition === self::CONDITION_AND) {
$queryBuilder->where(...$criteria);
} else {
$queryBuilder->orWhere(...$criteria);
}

$result = $queryBuilder->executeQuery();

return $result->fetchAllAssociative();
}

protected function updateRecord(string $table, int $uid, array $values): void
{
$queryBuilder = $this->createQueryBuilder($table);
$queryBuilder->update($table)
->where($queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT)));

foreach ($values as $field => $value) {
$queryBuilder->set($field, $value);
}

$queryBuilder->executeStatement();
}

protected function getBlogStorageFolders(): array
{
$pageQueryBuilder = $this->createQueryBuilder('pages');
$pageCriteria = [
$this->createEqualIntCriteria($pageQueryBuilder, 'doktype', 254),
$this->createEqualStringCriteria($pageQueryBuilder, 'module', 'blog'),
];
return $this->getRecordsByCriteria($pageQueryBuilder, 'pages', $pageCriteria);
}
}
117 changes: 24 additions & 93 deletions Classes/Updates/AuthorSlugUpdate.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,112 +10,39 @@

namespace T3G\AgencyPack\Blog\Updates;

use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
use TYPO3\CMS\Core\DataHandling\Model\RecordStateFactory;
use TYPO3\CMS\Core\DataHandling\SlugHelper;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Install\Updates\DatabaseUpdatedPrerequisite;
use TYPO3\CMS\Install\Updates\UpgradeWizardInterface;

/**
* AuthorSlugUpdate
*/
class AuthorSlugUpdate implements UpgradeWizardInterface
final class AuthorSlugUpdate extends AbstractUpdate implements UpgradeWizardInterface
{
/**
* @var string
*/
protected $table = 'tx_blog_domain_model_author';
protected $title = 'EXT:blog: Generate Path-Segments for Authors';

/**
* @var string
*/
protected $slugField = 'slug';

/**
* @return string
*/
public function getIdentifier(): string
{
return self::class;
}

/**
* @return string
*/
public function getTitle(): string
{
return '[EXT:blog] Generate Path-Segments for Authors';
}

/**
* @return string
*/
public function getDescription(): string
{
return '';
}

/**
* @return array
*/
public function getPrerequisites(): array
{
return [
DatabaseUpdatedPrerequisite::class
];
}
protected $table = 'tx_blog_domain_model_author';

/**
* @return bool
*/
public function updateNecessary(): bool
{
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($this->table);
$queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));

$elementCount = $queryBuilder
->count('uid')
->from($this->table)
->where(
$queryBuilder->expr()->orX(
$queryBuilder->expr()->eq($this->slugField, $queryBuilder->createNamedParameter('')),
$queryBuilder->expr()->isNull($this->slugField)
)
)
->execute()->fetchColumn(0);

return (bool)$elementCount;
$records = $this->getAffectedRecords();
return (bool) count($records);
}

/**
* @return bool
*/
public function executeUpdate(): bool
{
$connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($this->table);
$queryBuilder = $connection->createQueryBuilder();
$queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));

$statement = $queryBuilder
->select('*')
->from($this->table)
->where(
$queryBuilder->expr()->orX(
$queryBuilder->expr()->eq($this->slugField, $queryBuilder->createNamedParameter('')),
$queryBuilder->expr()->isNull($this->slugField)
)
)
->execute();

$fieldConfig = $GLOBALS['TCA'][$this->table]['columns'][$this->slugField]['config'];
$fieldConfig = $GLOBALS['TCA'][$this->table]['columns']['slug']['config'];
$evalInfo = !empty($fieldConfig['eval']) ? GeneralUtility::trimExplode(',', $fieldConfig['eval'], true) : [];
$hasToBeUniqueInSite = in_array('uniqueInSite', $evalInfo, true);
$hasToBeUniqueInPid = in_array('uniqueInPid', $evalInfo, true);
$slugHelper = GeneralUtility::makeInstance(SlugHelper::class, $this->table, $this->slugField, $fieldConfig);
$slugHelper = GeneralUtility::makeInstance(SlugHelper::class, $this->table, 'slug', $fieldConfig);

while ($record = $statement->fetch()) {
$records = $this->getAffectedRecords();
foreach ($records as $record) {
$recordId = (int)$record['uid'];
$pid = (int)$record['pid'];

Expand All @@ -130,19 +57,23 @@ public function executeUpdate(): bool
}

// Update Record
$queryBuilder = $connection->createQueryBuilder();
$queryBuilder
->update($this->table)
->where(
$queryBuilder->expr()->eq(
'uid',
$queryBuilder->createNamedParameter($record['uid'], \PDO::PARAM_INT)
)
)
->set('slug', $slug);
$queryBuilder->execute();
$this->updateRecord($this->table, $recordId, [
'slug' => $slug
]);
}

return true;
}

private function getAffectedRecords(): array
{
$queryBuilder = $this->createQueryBuilder($this->table);
$criteria = [
$this->createEqualStringCriteria($queryBuilder, 'slug', ''),
$this->createIsNullCriteria($queryBuilder, 'slug')
];
$records = $this->getRecordsByCriteria($queryBuilder, $this->table, $criteria, AbstractUpdate::CONDITION_OR);

return $records;
}
}
Loading

0 comments on commit 3c87b53

Please sign in to comment.