Skip to content

Commit

Permalink
[FEATURE] Introduce Doctrine proxy
Browse files Browse the repository at this point in the history
Allows Doctrine usage on different major versions which change the
way queries are executed and fetched.
  • Loading branch information
NamelessCoder committed Oct 24, 2024
1 parent 022da09 commit 1dd4556
Show file tree
Hide file tree
Showing 15 changed files with 215 additions and 159 deletions.
3 changes: 2 additions & 1 deletion Classes/Content/ContentTypeValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use FluidTYPO3\Flux\Content\TypeDefinition\ContentTypeDefinitionInterface;
use FluidTYPO3\Flux\Content\TypeDefinition\FluidRenderingContentTypeDefinitionInterface;
use FluidTYPO3\Flux\Service\TemplateValidationService;
use FluidTYPO3\Flux\Utility\DoctrineQueryProxy;
use FluidTYPO3\Flux\Utility\ExtensionNamingUtility;
use TYPO3\CMS\Core\Database\Connection;
use TYPO3\CMS\Core\Database\ConnectionPool;
Expand Down Expand Up @@ -127,7 +128,7 @@ protected function countUsages(ContentTypeDefinitionInterface $definition): int
$queryBuilder->createNamedParameter($definition->getContentTypeName(), Connection::PARAM_STR)
)
);
return (integer) $queryBuilder->execute()->rowCount();
return (integer) DoctrineQueryProxy::executeQueryOnQueryBuilder($queryBuilder)->rowCount();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
*/

use Doctrine\DBAL\Exception\TableNotFoundException;
use FluidTYPO3\Flux\Utility\DoctrineQueryProxy;
use FluidTYPO3\Flux\Utility\ExtensionNamingUtility;
use TYPO3\CMS\Core\Database\Connection;
use TYPO3\CMS\Core\Database\ConnectionPool;
Expand All @@ -35,16 +36,17 @@ public function fetchContentTypeDefinitions(): array
$queryBuilder = $this->connectionPool->getQueryBuilderForTable('content_types');
/** @var string[] $keys */
$keys = array_keys($GLOBALS['TCA']['content_types']['columns'] ?? ['*' => '']);
/** @var array[] $typeRecords */
$typeRecords = $queryBuilder->select(...$keys)
$queryBuilder->select(...$keys)
->from('content_types')
->where(
$queryBuilder->expr()->eq('deleted', $queryBuilder->createNamedParameter(0, Connection::PARAM_INT)),
$queryBuilder->expr()->eq('hidden', $queryBuilder->createNamedParameter(0, Connection::PARAM_INT))
)
->orderBy('sorting', 'ASC')
->execute()
->fetchAll();
->orderBy('sorting', 'ASC');

$result = $typeRecords = DoctrineQueryProxy::executeQueryOnQueryBuilder($queryBuilder);
/** @var array[] $typeRecords */
$typeRecords = DoctrineQueryProxy::fetchAllAssociative($result);
} catch (TableNotFoundException $exception) {
$typeRecords = [];
}
Expand Down
10 changes: 6 additions & 4 deletions Classes/Form/Transformation/Transformer/FileTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use FluidTYPO3\Flux\Form\FormInterface;
use FluidTYPO3\Flux\Form\OptionCarryingInterface;
use FluidTYPO3\Flux\Form\Transformation\DataTransformerInterface;
use FluidTYPO3\Flux\Utility\DoctrineQueryProxy;
use FluidTYPO3\Flux\Utility\ExtensionConfigurationUtility;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Resource\Exception\ResourceDoesNotExistException;
Expand Down Expand Up @@ -92,19 +93,20 @@ public function transform(FormInterface $component, string $type, $value)
protected function fetchFileReferences(string $table, string $fieldName, int $recordUid): array
{
$queryBuilder = $this->connectionPool->getQueryBuilderForTable('sys_file_reference');
$result = $queryBuilder
$queryBuilder
->select('uid')
->from('sys_file_reference')
->where(
$queryBuilder->expr()->eq('uid_foreign', $queryBuilder->createNamedParameter($recordUid)),
$queryBuilder->expr()->eq('tablenames', $queryBuilder->createNamedParameter($table)),
$queryBuilder->expr()->eq('fieldname', $queryBuilder->createNamedParameter($fieldName))
)
->orderBy('sorting_foreign')
->execute();
->orderBy('sorting_foreign');

$result = DoctrineQueryProxy::executeQueryOnQueryBuilder($queryBuilder);

$references = [];
while ($row = $result->fetchAssociative()) {
while ($row = DoctrineQueryProxy::fetchAssociative($result)) {
/** @var array<string, int> $row */
try {
$references[] = $this->resourceFactory->getFileReferenceObject($row['uid']);
Expand Down
3 changes: 2 additions & 1 deletion Classes/Integration/FormEngine/UserFunctions.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

use FluidTYPO3\Flux\Provider\ProviderResolver;
use FluidTYPO3\Flux\Utility\ColumnNumberUtility;
use FluidTYPO3\Flux\Utility\DoctrineQueryProxy;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\StringUtility;
Expand Down Expand Up @@ -121,7 +122,7 @@ protected function determineTakenColumnPositionsWithinParent(string $table, int
$queryBuilder->expr()->gte('colPos', $minimumColPosValue),
$queryBuilder->expr()->lt('colPos', $maximumColPosValue)
);
$rows = $query->execute()->fetchAll();
$rows = DoctrineQueryProxy::fetchAllAssociative(DoctrineQueryProxy::executeQueryOnQueryBuilder($queryBuilder));
return empty($rows) ? [] : array_map(function ($colPos) {
return ColumnNumberUtility::calculateLocalColumnNumber($colPos);
}, array_unique(array_column($rows, 'colPos')));
Expand Down
22 changes: 16 additions & 6 deletions Classes/Integration/HookSubscribers/DataHandlerSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use FluidTYPO3\Flux\Provider\PageProvider;
use FluidTYPO3\Flux\Provider\ProviderResolver;
use FluidTYPO3\Flux\Utility\ColumnNumberUtility;
use FluidTYPO3\Flux\Utility\DoctrineQueryProxy;
use FluidTYPO3\Flux\Utility\ExtensionConfigurationUtility;
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\Cache\CacheManager;
Expand Down Expand Up @@ -161,7 +162,8 @@ public function processDatamap_afterDatabaseOperations($command, $table, $id, $f
$queryBuilder->createNamedParameter($GLOBALS['BE_USER']->workspace, Connection::PARAM_INT)
)
)
)->execute();
);
DoctrineQueryProxy::executeQueryOnQueryBuilder($queryBuilder);
}

static::$copiedRecords[$fieldArray['t3_origuid']] = true;
Expand Down Expand Up @@ -500,7 +502,9 @@ protected function getSingleRecordWithRestrictions(string $table, int $uid, stri
->from($table)
->where($queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($uid, Connection::PARAM_INT)));
/** @var array|false $firstResult */
$firstResult = $queryBuilder->execute()->fetch();
$firstResult = DoctrineQueryProxy::fetchAssociative(
DoctrineQueryProxy::executeQueryOnQueryBuilder($queryBuilder)
);
return $firstResult ?: null;
}

Expand All @@ -515,7 +519,9 @@ protected function getSingleRecordWithoutRestrictions(string $table, int $uid, s
->from($table)
->where($queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($uid, Connection::PARAM_INT)));
/** @var array|false $firstResult */
$firstResult = $queryBuilder->execute()->fetch();
$firstResult = DoctrineQueryProxy::fetchAssociative(
DoctrineQueryProxy::executeQueryOnQueryBuilder($queryBuilder)
);
return $firstResult ?: null;
}

Expand All @@ -535,7 +541,9 @@ protected function getMostRecentCopyOfRecord(int $uid, string $fieldsToSelect =
$queryBuilder->expr()->neq('t3ver_state', -1)
);
/** @var array|false $firstResult */
$firstResult = $queryBuilder->execute()->fetch();
$firstResult = DoctrineQueryProxy::fetchAssociative(
DoctrineQueryProxy::executeQueryOnQueryBuilder($queryBuilder)
);
return $firstResult ?: null;
}

Expand Down Expand Up @@ -568,7 +576,9 @@ protected function getTranslatedVersionOfParentInLanguageOnPage(
)
);
/** @var array|false $firstResult */
$firstResult = $queryBuilder->execute()->fetch();
$firstResult = DoctrineQueryProxy::fetchAssociative(
DoctrineQueryProxy::executeQueryOnQueryBuilder($queryBuilder)
);
return $firstResult ?: null;
}

Expand Down Expand Up @@ -642,7 +652,7 @@ protected function getParentAndRecordsNestedInGrid(
$query->andWhere($queryBuilder->expr()->neq('pid', -1));
}

$records = $query->execute()->fetchAll();
$records = DoctrineQueryProxy::fetchAllAssociative(DoctrineQueryProxy::executeQueryOnQueryBuilder($query));

// Selecting records to return. The "sorting DESC" is very intentional; copy operations will place records
// into the top of columns which means reading records in reverse order causes the correct final order.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
declare(strict_types=1);
namespace FluidTYPO3\Flux\Integration\NormalizedData\Converter;

use FluidTYPO3\Flux\Utility\DoctrineQueryProxy;
use TYPO3\CMS\Core\Configuration\FlexForm\FlexFormTools;
use TYPO3\CMS\Core\Database\Connection;
use TYPO3\CMS\Core\Database\ConnectionPool;
Expand Down Expand Up @@ -193,7 +194,8 @@ protected function insertFieldData(array $fieldData): int
{
$connection = $this->createConnectionForTable('flux_field');
$queryBuilder = $connection->createQueryBuilder();
$queryBuilder->insert('flux_field')->values($fieldData)->execute();
$queryBuilder->insert('flux_field')->values($fieldData);
DoctrineQueryProxy::executeQueryOnQueryBuilder($queryBuilder);
return (int) $connection->lastInsertId('flux_field');
}

Expand All @@ -204,7 +206,8 @@ protected function insertSheetData(array $sheetData): int
{
$connection = $this->createConnectionForTable('flux_sheet');
$queryBuilder = $connection->createQueryBuilder();
$queryBuilder->insert('flux_sheet')->values($sheetData)->execute();
$queryBuilder->insert('flux_sheet')->values($sheetData);
DoctrineQueryProxy::executeQueryOnQueryBuilder($queryBuilder);
return (int) $connection->lastInsertId('flux_sheet');
}

Expand All @@ -215,10 +218,13 @@ protected function fetchFieldData(int $uid): array
{
$settings = [];
$queryBuilder = $this->createQueryBuilderForTable('flux_field');
/** @var array[] $result */
$result = $queryBuilder->select('uid', 'field_name', 'field_value')->from('flux_field')->where(
$queryBuilder->select('uid', 'field_name', 'field_value')->from('flux_field')->where(
$queryBuilder->expr()->eq('sheet', $queryBuilder->createNamedParameter($uid, Connection::PARAM_INT))
)->execute()->fetchAllAssociative();
);
/** @var array[] $result */
$result = DoctrineQueryProxy::fetchAllAssociative(
DoctrineQueryProxy::executeQueryOnQueryBuilder($queryBuilder)
);
foreach ($result as $fieldRecord) {
$settings = $this->assignVariableByDottedPath(
$settings,
Expand All @@ -235,7 +241,7 @@ protected function fetchFieldData(int $uid): array
protected function fetchConfigurationRecords(): array
{
$queryBuilder = $this->createQueryBuilderForTable('flux_sheet');
return $queryBuilder->select('*')->from('flux_sheet')->where(
$queryBuilder->select('*')->from('flux_sheet')->where(
$queryBuilder->expr()->eq(
'source_table',
$queryBuilder->createNamedParameter($this->table, Connection::PARAM_STR)
Expand All @@ -244,7 +250,8 @@ protected function fetchConfigurationRecords(): array
'source_field',
$queryBuilder->createNamedParameter($this->field, Connection::PARAM_STR)
),
)->execute()->fetchAllAssociative();
);
return DoctrineQueryProxy::fetchAllAssociative(DoctrineQueryProxy::executeQueryOnQueryBuilder($queryBuilder));
}

/**
Expand All @@ -253,9 +260,10 @@ protected function fetchConfigurationRecords(): array
protected function fetchSheetRecord(string $sheetName): ?array
{
$queryBuilder = $this->createQueryBuilderForTable('flux_sheet');
return $queryBuilder->select('uid', 'name')->from('flux_sheet')->where(
$queryBuilder->select('uid', 'name')->from('flux_sheet')->where(
$queryBuilder->expr()->eq('name', $queryBuilder->createNamedParameter($sheetName, Connection::PARAM_STR))
)->execute()->fetchAssociative() ?: null;
);
return DoctrineQueryProxy::fetchAssociative(DoctrineQueryProxy::executeQueryOnQueryBuilder($queryBuilder));
}

/**
Expand Down
3 changes: 2 additions & 1 deletion Classes/Integration/Overrides/BackendLayoutView.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use FluidTYPO3\Flux\Provider\Interfaces\GridProviderInterface;
use FluidTYPO3\Flux\Provider\ProviderResolver;
use FluidTYPO3\Flux\Utility\ColumnNumberUtility;
use FluidTYPO3\Flux\Utility\DoctrineQueryProxy;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Utility\GeneralUtility;

Expand Down Expand Up @@ -152,7 +153,7 @@ protected function loadRecordFromTable(string $table, int $uid): ?array
->where($queryBuilder->expr()->eq('uid', $uid));
$query->getRestrictions()->removeAll();
/** @var array[] $results */
$results = $query->execute()->fetchAll();
$results = DoctrineQueryProxy::fetchAllAssociative(DoctrineQueryProxy::executeQueryOnQueryBuilder($query));
return $results[0] ?? null;
}

Expand Down
27 changes: 14 additions & 13 deletions Classes/Service/RecordService.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Doctrine\DBAL\Driver\ResultStatement;
use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\Result;
use FluidTYPO3\Flux\Utility\DoctrineQueryProxy;
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\Context\Context;
use TYPO3\CMS\Core\Context\VisibilityAspect;
Expand Down Expand Up @@ -55,7 +56,7 @@ public function get(
$statement->setFirstResult($offset);
}

return $statement->execute()->fetchAll();
return DoctrineQueryProxy::fetchAllAssociative(DoctrineQueryProxy::executeQueryOnQueryBuilder($statement));
}

public function getSingle(string $table, string $fields, int $uid): ?array
Expand All @@ -64,11 +65,12 @@ public function getSingle(string $table, string $fields, int $uid): ?array
return BackendUtility::getRecord($table, $uid, $fields);
}
$queryBuilder = $this->getQueryBuilder($table);
$results = $queryBuilder->from($table)
$queryBuilder->from($table)
->select(...explode(',', $fields))
->where($queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($uid)))
->execute()
->fetchAll() ?: [];
->where($queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($uid)));
$results = DoctrineQueryProxy::fetchAllAssociative(
DoctrineQueryProxy::executeQueryOnQueryBuilder($queryBuilder)
);
$firstResult = reset($results);
return $firstResult ? (array) $firstResult : null;
}
Expand All @@ -84,7 +86,7 @@ public function update(string $table, array $record)
foreach ($record as $name => $value) {
$builder->set($name, $value);
}
return $builder->execute();
return DoctrineQueryProxy::executeQueryOnQueryBuilder($builder);
}

/**
Expand All @@ -94,20 +96,19 @@ public function delete(string $table, $recordOrUid): bool
{
$clauseUid = true === is_array($recordOrUid) ? $recordOrUid['uid'] : $recordOrUid;
$queryBuilder = $this->getQueryBuilder($table);
return (bool) $queryBuilder->delete($table)
->where($queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($clauseUid)))
->execute();
$queryBuilder->delete($table)
->where($queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($clauseUid)));
return (bool) DoctrineQueryProxy::executeQueryOnQueryBuilder($queryBuilder);
}

public function preparedGet(string $table, string $fields, string $condition, array $values = []): array
{
return $this->getQueryBuilder($table)
$queryBuilder = $this->getQueryBuilder($table)
->select(...explode(',', $fields))
->from($table)
->where($condition)
->setParameters($values)
->execute()
->fetchAll();
->setParameters($values);
return DoctrineQueryProxy::fetchAllAssociative(DoctrineQueryProxy::executeQueryOnQueryBuilder($queryBuilder));
}

protected function getQueryBuilder(string $table): QueryBuilder
Expand Down
45 changes: 45 additions & 0 deletions Classes/Utility/DoctrineQueryProxy.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php
namespace FluidTYPO3\Flux\Utility;

use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\Result;
use TYPO3\CMS\Core\Database\Query\QueryBuilder;

class DoctrineQueryProxy
{
/**
* Returns \Doctrine\DBAL\Result on v11+, \Doctrine\DBAL\Driver\ResultStatement on v10
*
* @return Result
*/
public static function executeQueryOnQueryBuilder(QueryBuilder $queryBuilder)
{
if (method_exists($queryBuilder, 'executeQuery')) {
return $queryBuilder->executeQuery();
}
/** @var Result $result */
$result = $queryBuilder->execute();
return $result;
}

public static function fetchAssociative(Result $result): ?array
{
if (method_exists($result, 'fetchAssociative')) {
/** @var array|null $output */
$output = $result->fetchAssociative() ?: null;
} else {
/** @var array|null $output */
$output = $result->fetch(FetchMode::ASSOCIATIVE);
}

return $output;
}

public static function fetchAllAssociative(Result $result): array
{
if (method_exists($result, 'fetchAllAssociative')) {
return $result->fetchAllAssociative() ?: [];
}
return $result->fetchAll(FetchMode::ASSOCIATIVE) ?: [];
}
}
Loading

0 comments on commit 1dd4556

Please sign in to comment.