Skip to content

Commit 3e1f8d8

Browse files
authored
Merge pull request #67
2 parents 06ccd53 + 8ec272d commit 3e1f8d8

4 files changed

Lines changed: 46 additions & 56 deletions

File tree

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
"require": {
2121
"php": ">=8.0",
2222
"doctrine/annotations": "^2.0",
23-
"doctrine/dbal": "^3.3",
23+
"doctrine/dbal": "^3.8 || ^4.0",
2424
"phpdocumentor/reflection-docblock": "^5.3",
2525
"phpstan/phpdoc-parser": "^1.27",
2626
"symfony/config": "^6.0 || ^7.0",

src/Bridge/Repository/AbstractEntityRepository.php

Lines changed: 23 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

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

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

146+
$hasSelectColumns = array_filter(
147+
$normalizedCriteria,
148+
static fn (mixed $value) => $value instanceof SelectColumns,
149+
);
150+
145151
$queryBuilder = $this->entityManager->getConnection()
146152
->createQueryBuilder()
147-
->select(...$prefixedEntityBaseFields)
148153
->from($this->entityManager->getTablesPrefix() . static::TABLE_NAME, 'p')
149154
->addGroupBy(...$prefixedEntityBaseFields)
150155
;
@@ -155,7 +160,10 @@ public function createFindByQueryBuilder(array $criteria, ?array $orderBy): Quer
155160
;
156161
}
157162

158-
$this->addSelectForExtraFields($queryBuilder);
163+
if (!$hasSelectColumns) {
164+
$queryBuilder->select(...$prefixedEntityBaseFields);
165+
$this->addSelectForExtraFields($queryBuilder);
166+
}
159167

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

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

170-
$queryBuilder->addSelect(...$this->additionalFieldsToSelect);
171-
$this->additionalFieldsToSelect = [];
178+
if (!empty($this->additionalFieldsToSelect)) {
179+
$queryBuilder->addSelect(...$this->additionalFieldsToSelect);
180+
$this->additionalFieldsToSelect = [];
181+
}
172182

173183
return $queryBuilder;
174184
}
@@ -554,16 +564,15 @@ private function joinSelfMetaTable(QueryBuilder $queryBuilder, bool $incrementIf
554564

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

559-
return array_key_exists('p', $joinQueryPart)
560-
&& is_array($joinQueryPart['p'])
561-
&& count(
562-
array_filter(
563-
$joinQueryPart['p'],
564-
static fn (array $part) => !empty($part['joinAlias']) && $part['joinAlias'] === $joinAlias,
565-
)
566-
) > 0;
575+
return false;
567576
}
568577

569578
private function createRelationshipCriteria(
@@ -809,18 +818,15 @@ private function getPrefixedCriteriaForPostRelationshipCondition(
809818
private function selectColumns(QueryBuilder $queryBuilder, array $extraFields, SelectColumns $value): void
810819
{
811820
$selects = [];
812-
$hasExtraFields = false;
813821

814-
$queryBuilder->resetQueryPart('groupBy');
822+
$queryBuilder->resetGroupBy();
815823

816824
foreach ($value->getColumns() as $column) {
817825
if (in_array($column, $extraFields, true)) {
818826
$mappedMetaKey = $this->getMappedMetaKey($column);
819827
$selects[] = select_from_eav($column, $mappedMetaKey);
820-
$hasExtraFields = true;
821828
} elseif (str_starts_with($column, 'MAX(')) {
822829
$selects[] = $column;
823-
$hasExtraFields = true;
824830
$this->joinSelfMetaTable($queryBuilder);
825831
} else {
826832
foreach ($this->tableAliases as $alias => $fields) {
@@ -836,33 +842,5 @@ private function selectColumns(QueryBuilder $queryBuilder, array $extraFields, S
836842

837843
$queryBuilder->select(...$selects, ...$this->additionalFieldsToSelect);
838844
$this->additionalFieldsToSelect = [];
839-
840-
if (!$hasExtraFields) {
841-
$joinQueryPart = $queryBuilder->getQueryPart('join');
842-
843-
if (empty($joinQueryPart)) {
844-
return;
845-
}
846-
847-
$queryBuilder->resetQueryPart('join');
848-
849-
foreach ($joinQueryPart['p'] as $index => $part) {
850-
if ($part['joinAlias'] === 'pm_self') {
851-
unset($joinQueryPart['p'][$index]);
852-
}
853-
}
854-
855-
foreach ($joinQueryPart as $alias => $parts) {
856-
foreach ($parts as $part) {
857-
$method = match ($part['joinType']) {
858-
'left' => 'leftJoin',
859-
'right' => 'rightJoin',
860-
default => 'join',
861-
};
862-
863-
$queryBuilder->{$method}($alias, $part['joinTable'], $part['joinAlias'], $part['joinCondition']);
864-
}
865-
}
866-
}
867845
}
868846
}

src/Bridge/Repository/TermRepository.php

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,19 +38,25 @@ public function createFindByQueryBuilder(array $criteria, ?array $orderBy): Quer
3838
->addGroupBy('tt.taxonomy')
3939
;
4040

41+
preg_match('/SELECT (.*) FROM/im', $queryBuilder->getSQL(), $match);
42+
$selectedFields = explode(', ', $match[1] ?? '');
43+
44+
preg_match('/GROUP BY (.*)\s?(?:HAVING|ORDER|LIMIT|OFFSET|FETCH|$)/im', $queryBuilder->getSQL(), $match);
45+
$groupByFields = explode(', ', $match[1] ?? '');
46+
4147
if (\count(array_filter($criteria, static fn ($condition) => $condition instanceof SelectColumns)) === 0) {
4248
$extraFields = array_diff(
43-
$queryBuilder->getQueryPart('select'),
49+
$selectedFields,
4450
$this->getPrefixedFields(['term_id', 'name', 'slug', 'taxonomy', 'term_taxonomy_id', 'count']),
4551
);
4652

47-
$queryBuilder->select([
53+
$queryBuilder->select(
4854
...$this->getPrefixedFields(['term_id', 'name', 'slug', 'taxonomy', 'term_taxonomy_id', 'count']),
49-
...$extraFields,
50-
]);
55+
...$extraFields
56+
);
5157
} else {
52-
foreach ($this->getPrefixedFields($queryBuilder->getQueryPart('select')) as $field) {
53-
if (!\in_array($field, $queryBuilder->getQueryPart('groupBy'), true)) {
58+
foreach ($this->getPrefixedFields($selectedFields) as $field) {
59+
if (!\in_array($field, $groupByFields, true)) {
5460
$queryBuilder->addGroupBy($field);
5561
}
5662
}
@@ -146,19 +152,21 @@ public function removeTermsFromEntity(BaseEntity $entity, array $terms): void
146152

147153
private function recountTerms(): void
148154
{
155+
$tableName = $this->entityManager->getTablesPrefix() . 'term_taxonomy';
156+
149157
$subSelect = $this->entityManager->getConnection()
150158
->createQueryBuilder()
151159
->select('COUNT(*)')
152160
->from($this->entityManager->getTablesPrefix() . 'term_relationships', 'tr')
153161
->leftJoin('tr', $this->entityManager->getTablesPrefix() . 'posts', 'p', 'p.id = tr.object_id')
154-
->where('tr.term_taxonomy_id = tt.term_taxonomy_id')
155-
->andWhere("tt.taxonomy NOT IN ('link_category')")
162+
->where("tr.term_taxonomy_id = $tableName.term_taxonomy_id")
163+
->andWhere("$tableName.taxonomy NOT IN ('link_category')")
156164
->andWhere("p.post_status IN ('publish', 'future')")
157165
;
158166

159167
$this->entityManager->getConnection()
160168
->createQueryBuilder()
161-
->update($this->entityManager->getTablesPrefix() . 'term_taxonomy', 'tt')
169+
->update($tableName)
162170
->set('count', sprintf('(%s)', $subSelect->getSQL()))
163171
->executeStatement()
164172
;

test/Test/TestCase.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Doctrine\Common\Annotations\AnnotationReader;
88
use Doctrine\DBAL\Connection;
99
use Doctrine\DBAL\DriverManager;
10+
use Doctrine\DBAL\Tools\DsnParser;
1011
use PHPUnit\Framework\TestCase as BaseTestCase;
1112
use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor;
1213
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
@@ -39,7 +40,10 @@ abstract class TestCase extends BaseTestCase
3940

4041
protected function setUp(): void
4142
{
42-
$this->connection = DriverManager::getConnection(['url' => getenv('WORDPRESS_DATABASE_URL')]);
43+
$dsnParser = new DsnParser(['mysql' => 'pdo_mysql']);
44+
$this->connection = DriverManager::getConnection(
45+
$dsnParser->parse(getenv('WORDPRESS_DATABASE_URL'))
46+
);
4347

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

0 commit comments

Comments
 (0)