Skip to content

Instantly share code, notes, and snippets.

@Nemo64
Last active October 2, 2018 09:46
Show Gist options
  • Save Nemo64/d6bf6561fc4b32d490b1b39966107ff5 to your computer and use it in GitHub Desktop.
Save Nemo64/d6bf6561fc4b32d490b1b39966107ff5 to your computer and use it in GitHub Desktop.
createQueryBuilder for typo3 extbase repository using dbal
<?php
namespace Vendor\Extension\Domain\Repository;
use TYPO3\CMS\Core\Database\Connection;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper;
use TYPO3\CMS\Extbase\Persistence\Repository;
abstract class AbstractDbalRepository extends Repository
{
public function createQueryBuilder(string $alias): QueryBuilder
{
$dataMapper = $this->objectManager->get(DataMapper::class);
$dataMap = $dataMapper->getDataMap($this->objectType);
$qb = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($dataMap->getTableName());
$qb->select("$alias.*");
$qb->from($dataMap->getTableName(), $alias);
$recordTypeColumnName = $dataMap->getRecordTypeColumnName();
if ($recordTypeColumnName) {
$typeNames = [$dataMap->getRecordType()];
foreach ($dataMap->getSubclasses() as $subclass) {
$typeNames[] = $dataMapper->getDataMap($subclass)->getRecordType();
}
$typeNameParameter = $qb->createNamedParameter($typeNames, Connection::PARAM_STR_ARRAY);
$qb->andWhere($qb->expr()->in("$alias.$recordTypeColumnName", $typeNameParameter));
}
$querySettings = clone ($this->defaultQuerySettings ?? $this->createQuery()->getQuerySettings());
if (method_exists($querySettings, 'initializeObject')) {
$querySettings->initializeObject();
}
if ($querySettings->getRespectStoragePage()) {
$pidColumn = $dataMap->getPageIdColumnName();
$storagePageIds = $querySettings->getStoragePageIds();
$storagePageIdsParameter = $qb->createNamedParameter($storagePageIds, Connection::PARAM_INT_ARRAY);
$qb->andWhere($qb->expr()->in("$alias.$pidColumn", $storagePageIdsParameter));
}
if ($querySettings->getIgnoreEnableFields()) {
if ($querySettings->getEnableFieldsToBeIgnored()) {
throw new \RuntimeException("Not implemented");
} else {
$qb->getRestrictions()->removeAll();
$qb->getRestrictions()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
}
} else {
if (is_string($GLOBALS['TSFE']->fe_group)) {
$qb->getRestrictions()->add(GeneralUtility::makeInstance(FrontendGroupRestriction::class));
}
}
// TODO probably even more
return $qb;
}
// resolves https://forge.typo3.org/issues/86385
public static function resolveRestriction(QueryBuilder $qb)
{
$restrictions = $qb->getRestrictions();
// there is no access to this outside the query builder so i'll have to make myself one
$unquoteMethod = new \ReflectionMethod(get_class($qb), 'unquoteSingleIdentifier');
$unquoteClosure = $unquoteMethod->getClosure($qb);
$fromTables = array_combine(
array_map($unquoteClosure, array_column($qb->getQueryPart('from'), 'alias')),
array_map($unquoteClosure, array_column($qb->getQueryPart('from'), 'table'))
);
$fromCondition = $restrictions->buildExpression($fromTables, $qb->expr());
if ($fromCondition->count() > 0) {
$qb->andWhere($fromCondition);
}
$joins = $qb->getQueryPart('join');
$qb->resetQueryPart('join');
foreach ($joins as $fromAlias => $furtherJoins) {
foreach ($furtherJoins as $join) {
$joinCondition = $qb->expr()->andX();
if ($join['joinCondition'] !== null) {
$joinCondition->add($join['joinCondition']);
}
$joinTables = [$unquoteClosure($join['joinAlias']) => $unquoteClosure($join['joinTable'])];
$joinExpression = $restrictions->buildExpression($joinTables, $qb->expr());
if ($joinExpression->count() > 0) {
$joinCondition->add($joinExpression);
}
if ($joinCondition->count() === 0) {
$joinCondition = null;
}
$join['joinCondition'] = $joinCondition;
$qb->getConcreteQueryBuilder()->add('join', [$fromAlias => $join], true);
}
}
$restrictions->removeAll();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment