Skip to content

Commit

Permalink
Merge pull request #67
Browse files Browse the repository at this point in the history
  • Loading branch information
williarin authored Jul 24, 2024
2 parents 06ccd53 + 8ec272d commit 3e1f8d8
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 56 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"require": {
"php": ">=8.0",
"doctrine/annotations": "^2.0",
"doctrine/dbal": "^3.3",
"doctrine/dbal": "^3.8 || ^4.0",
"phpdocumentor/reflection-docblock": "^5.3",
"phpstan/phpdoc-parser": "^1.27",
"symfony/config": "^6.0 || ^7.0",
Expand Down
68 changes: 23 additions & 45 deletions src/Bridge/Repository/AbstractEntityRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Doctrine\DBAL\Query\Expression\CompositeExpression;
use Doctrine\DBAL\Query\QueryBuilder;
use Doctrine\DBAL\Query\QueryException;
use JetBrains\PhpStorm\ArrayShape;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter;
Expand Down Expand Up @@ -142,9 +143,13 @@ public function createFindByQueryBuilder(array $criteria, ?array $orderBy): Quer

$prefixedEntityBaseFields = $this->getPrefixedEntityBaseFields('p');

$hasSelectColumns = array_filter(
$normalizedCriteria,
static fn (mixed $value) => $value instanceof SelectColumns,
);

$queryBuilder = $this->entityManager->getConnection()
->createQueryBuilder()
->select(...$prefixedEntityBaseFields)
->from($this->entityManager->getTablesPrefix() . static::TABLE_NAME, 'p')
->addGroupBy(...$prefixedEntityBaseFields)
;
Expand All @@ -155,7 +160,10 @@ public function createFindByQueryBuilder(array $criteria, ?array $orderBy): Quer
;
}

$this->addSelectForExtraFields($queryBuilder);
if (!$hasSelectColumns) {
$queryBuilder->select(...$prefixedEntityBaseFields);
$this->addSelectForExtraFields($queryBuilder);
}

foreach ($normalizedCriteria as $field => $value) {
if ($this->handleSpecialCriteria($queryBuilder, $criteria, $field, $value) === self::IS_SPECIAL_CRITERIA) {
Expand All @@ -167,8 +175,10 @@ public function createFindByQueryBuilder(array $criteria, ?array $orderBy): Quer

$this->addOrderByClause($queryBuilder, $orderBy);

$queryBuilder->addSelect(...$this->additionalFieldsToSelect);
$this->additionalFieldsToSelect = [];
if (!empty($this->additionalFieldsToSelect)) {
$queryBuilder->addSelect(...$this->additionalFieldsToSelect);
$this->additionalFieldsToSelect = [];
}

return $queryBuilder;
}
Expand Down Expand Up @@ -554,16 +564,15 @@ private function joinSelfMetaTable(QueryBuilder $queryBuilder, bool $incrementIf

private function hasJoin(QueryBuilder $queryBuilder, string $joinAlias): bool
{
$joinQueryPart = $queryBuilder->getQueryPart('join');
try {
if (preg_match_all('/JOIN (\w+) (\w+) ON p\./im', $queryBuilder->getSQL(), $matches, PREG_SET_ORDER)) {
return count(array_filter($matches, static fn (array $match) => $match[2] === $joinAlias)) > 0;
}
} catch (QueryException) {
return false;
}

return array_key_exists('p', $joinQueryPart)
&& is_array($joinQueryPart['p'])
&& count(
array_filter(
$joinQueryPart['p'],
static fn (array $part) => !empty($part['joinAlias']) && $part['joinAlias'] === $joinAlias,
)
) > 0;
return false;
}

private function createRelationshipCriteria(
Expand Down Expand Up @@ -809,18 +818,15 @@ private function getPrefixedCriteriaForPostRelationshipCondition(
private function selectColumns(QueryBuilder $queryBuilder, array $extraFields, SelectColumns $value): void
{
$selects = [];
$hasExtraFields = false;

$queryBuilder->resetQueryPart('groupBy');
$queryBuilder->resetGroupBy();

foreach ($value->getColumns() as $column) {
if (in_array($column, $extraFields, true)) {
$mappedMetaKey = $this->getMappedMetaKey($column);
$selects[] = select_from_eav($column, $mappedMetaKey);
$hasExtraFields = true;
} elseif (str_starts_with($column, 'MAX(')) {
$selects[] = $column;
$hasExtraFields = true;
$this->joinSelfMetaTable($queryBuilder);
} else {
foreach ($this->tableAliases as $alias => $fields) {
Expand All @@ -836,33 +842,5 @@ private function selectColumns(QueryBuilder $queryBuilder, array $extraFields, S

$queryBuilder->select(...$selects, ...$this->additionalFieldsToSelect);
$this->additionalFieldsToSelect = [];

if (!$hasExtraFields) {
$joinQueryPart = $queryBuilder->getQueryPart('join');

if (empty($joinQueryPart)) {
return;
}

$queryBuilder->resetQueryPart('join');

foreach ($joinQueryPart['p'] as $index => $part) {
if ($part['joinAlias'] === 'pm_self') {
unset($joinQueryPart['p'][$index]);
}
}

foreach ($joinQueryPart as $alias => $parts) {
foreach ($parts as $part) {
$method = match ($part['joinType']) {
'left' => 'leftJoin',
'right' => 'rightJoin',
default => 'join',
};

$queryBuilder->{$method}($alias, $part['joinTable'], $part['joinAlias'], $part['joinCondition']);
}
}
}
}
}
26 changes: 17 additions & 9 deletions src/Bridge/Repository/TermRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,25 @@ public function createFindByQueryBuilder(array $criteria, ?array $orderBy): Quer
->addGroupBy('tt.taxonomy')
;

preg_match('/SELECT (.*) FROM/im', $queryBuilder->getSQL(), $match);
$selectedFields = explode(', ', $match[1] ?? '');

preg_match('/GROUP BY (.*)\s?(?:HAVING|ORDER|LIMIT|OFFSET|FETCH|$)/im', $queryBuilder->getSQL(), $match);
$groupByFields = explode(', ', $match[1] ?? '');

if (\count(array_filter($criteria, static fn ($condition) => $condition instanceof SelectColumns)) === 0) {
$extraFields = array_diff(
$queryBuilder->getQueryPart('select'),
$selectedFields,
$this->getPrefixedFields(['term_id', 'name', 'slug', 'taxonomy', 'term_taxonomy_id', 'count']),
);

$queryBuilder->select([
$queryBuilder->select(
...$this->getPrefixedFields(['term_id', 'name', 'slug', 'taxonomy', 'term_taxonomy_id', 'count']),
...$extraFields,
]);
...$extraFields
);
} else {
foreach ($this->getPrefixedFields($queryBuilder->getQueryPart('select')) as $field) {
if (!\in_array($field, $queryBuilder->getQueryPart('groupBy'), true)) {
foreach ($this->getPrefixedFields($selectedFields) as $field) {
if (!\in_array($field, $groupByFields, true)) {
$queryBuilder->addGroupBy($field);
}
}
Expand Down Expand Up @@ -146,19 +152,21 @@ public function removeTermsFromEntity(BaseEntity $entity, array $terms): void

private function recountTerms(): void
{
$tableName = $this->entityManager->getTablesPrefix() . 'term_taxonomy';

$subSelect = $this->entityManager->getConnection()
->createQueryBuilder()
->select('COUNT(*)')
->from($this->entityManager->getTablesPrefix() . 'term_relationships', 'tr')
->leftJoin('tr', $this->entityManager->getTablesPrefix() . 'posts', 'p', 'p.id = tr.object_id')
->where('tr.term_taxonomy_id = tt.term_taxonomy_id')
->andWhere("tt.taxonomy NOT IN ('link_category')")
->where("tr.term_taxonomy_id = $tableName.term_taxonomy_id")
->andWhere("$tableName.taxonomy NOT IN ('link_category')")
->andWhere("p.post_status IN ('publish', 'future')")
;

$this->entityManager->getConnection()
->createQueryBuilder()
->update($this->entityManager->getTablesPrefix() . 'term_taxonomy', 'tt')
->update($tableName)
->set('count', sprintf('(%s)', $subSelect->getSQL()))
->executeStatement()
;
Expand Down
6 changes: 5 additions & 1 deletion test/Test/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\Tools\DsnParser;
use PHPUnit\Framework\TestCase as BaseTestCase;
use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor;
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
Expand Down Expand Up @@ -39,7 +40,10 @@ abstract class TestCase extends BaseTestCase

protected function setUp(): void
{
$this->connection = DriverManager::getConnection(['url' => getenv('WORDPRESS_DATABASE_URL')]);
$dsnParser = new DsnParser(['mysql' => 'pdo_mysql']);
$this->connection = DriverManager::getConnection(
$dsnParser->parse(getenv('WORDPRESS_DATABASE_URL'))
);

$loader = class_exists('\\Symfony\\Component\\Serializer\\Mapping\\Loader\\AnnotationLoader')
? new AnnotationLoader(new AnnotationReader())
Expand Down

0 comments on commit 3e1f8d8

Please sign in to comment.