Skip to content

Commit 36fca42

Browse files
authored
PHPLIB-1635 BuilderEncoder accepts an instance of encoder instead of a class string (#1608)
BuilderEncoder accepts an instance of encoder instead of a class string Remove AbstractExpressionEncoder and ExpressionEncoder interface
1 parent dd77c8d commit 36fca42

14 files changed

+108
-65
lines changed

psalm-baseline.xml

+11-6
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,10 @@
4141
<code><![CDATA[stdClass]]></code>
4242
</MoreSpecificReturnType>
4343
</file>
44-
<file src="src/Builder/Encoder/AbstractExpressionEncoder.php">
45-
<MixedAssignment>
46-
<code><![CDATA[$val]]></code>
47-
<code><![CDATA[$val]]></code>
48-
<code><![CDATA[$value[$key]]]></code>
49-
</MixedAssignment>
44+
<file src="src/Builder/BuilderEncoder.php">
45+
<MixedReturnStatement>
46+
<code><![CDATA[$encoder->encode($value)]]></code>
47+
</MixedReturnStatement>
5048
</file>
5149
<file src="src/Builder/Encoder/CombinedFieldQueryEncoder.php">
5250
<MixedAssignment>
@@ -99,6 +97,13 @@
9997
<code><![CDATA[$value]]></code>
10098
</MixedAssignment>
10199
</file>
100+
<file src="src/Builder/Encoder/RecursiveEncode.php">
101+
<MixedAssignment>
102+
<code><![CDATA[$val]]></code>
103+
<code><![CDATA[$val]]></code>
104+
<code><![CDATA[$value[$key]]]></code>
105+
</MixedAssignment>
106+
</file>
102107
<file src="src/Builder/Query.php">
103108
<ArgumentTypeCoercion>
104109
<code><![CDATA[$query]]></code>

src/Builder/BuilderEncoder.php

+17-8
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
use MongoDB\Builder\Encoder\CombinedFieldQueryEncoder;
1010
use MongoDB\Builder\Encoder\DateTimeEncoder;
1111
use MongoDB\Builder\Encoder\DictionaryEncoder;
12-
use MongoDB\Builder\Encoder\ExpressionEncoder;
1312
use MongoDB\Builder\Encoder\FieldPathEncoder;
1413
use MongoDB\Builder\Encoder\OperatorEncoder;
1514
use MongoDB\Builder\Encoder\OutputWindowEncoder;
@@ -33,14 +32,15 @@
3332

3433
use function array_key_exists;
3534
use function is_object;
35+
use function is_string;
3636

3737
/** @template-implements Encoder<Type|stdClass|array|string|int, Pipeline|StageInterface|ExpressionInterface|QueryInterface> */
3838
final class BuilderEncoder implements Encoder
3939
{
4040
/** @template-use EncodeIfSupported<Type|stdClass|array|string|int, Pipeline|StageInterface|ExpressionInterface|QueryInterface> */
4141
use EncodeIfSupported;
4242

43-
/** @var array<class-string, class-string<ExpressionEncoder>> */
43+
/** @var array<class-string, class-string<Encoder>> */
4444
private array $defaultEncoders = [
4545
Pipeline::class => PipelineEncoder::class,
4646
Variable::class => VariableEncoder::class,
@@ -53,10 +53,10 @@ final class BuilderEncoder implements Encoder
5353
DateTimeInterface::class => DateTimeEncoder::class,
5454
];
5555

56-
/** @var array<class-string, ExpressionEncoder|null> */
56+
/** @var array<class-string, Encoder|null> */
5757
private array $cachedEncoders = [];
5858

59-
/** @param array<class-string, class-string<ExpressionEncoder>> $customEncoders */
59+
/** @param array<class-string, Encoder> $customEncoders */
6060
public function __construct(private readonly array $customEncoders = [])
6161
{
6262
}
@@ -82,7 +82,7 @@ public function encode(mixed $value): Type|stdClass|array|string|int
8282
return $encoder->encode($value);
8383
}
8484

85-
private function getEncoderFor(object $value): ExpressionEncoder|null
85+
private function getEncoderFor(object $value): Encoder|null
8686
{
8787
$valueClass = $value::class;
8888
if (array_key_exists($valueClass, $this->cachedEncoders)) {
@@ -93,13 +93,22 @@ private function getEncoderFor(object $value): ExpressionEncoder|null
9393

9494
// First attempt: match class name exactly
9595
if (isset($encoderList[$valueClass])) {
96-
return $this->cachedEncoders[$valueClass] = new $encoderList[$valueClass]($this);
96+
$encoder = $encoderList[$valueClass];
97+
if (is_string($encoder)) {
98+
$encoder = new $encoder($this);
99+
}
100+
101+
return $this->cachedEncoders[$valueClass] = $encoder;
97102
}
98103

99104
// Second attempt: catch child classes
100-
foreach ($encoderList as $className => $encoderClass) {
105+
foreach ($encoderList as $className => $encoder) {
101106
if ($value instanceof $className) {
102-
return $this->cachedEncoders[$valueClass] = new $encoderClass($this);
107+
if (is_string($encoder)) {
108+
$encoder = new $encoder($this);
109+
}
110+
111+
return $this->cachedEncoders[$valueClass] = $encoder;
103112
}
104113
}
105114

src/Builder/Encoder/CombinedFieldQueryEncoder.php

+4-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use LogicException;
88
use MongoDB\Builder\Type\CombinedFieldQuery;
99
use MongoDB\Codec\EncodeIfSupported;
10+
use MongoDB\Codec\Encoder;
1011
use MongoDB\Exception\UnsupportedValueException;
1112
use stdClass;
1213

@@ -17,13 +18,14 @@
1718
use function sprintf;
1819

1920
/**
20-
* @template-extends AbstractExpressionEncoder<stdClass, CombinedFieldQuery>
21+
* @template-implements Encoder<stdClass, CombinedFieldQuery>
2122
* @internal
2223
*/
23-
final class CombinedFieldQueryEncoder extends AbstractExpressionEncoder
24+
final class CombinedFieldQueryEncoder implements Encoder
2425
{
2526
/** @template-use EncodeIfSupported<stdClass, CombinedFieldQuery> */
2627
use EncodeIfSupported;
28+
use RecursiveEncode;
2729

2830
public function canEncode(mixed $value): bool
2931
{

src/Builder/Encoder/DateTimeEncoder.php

+3-2
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@
77
use DateTimeInterface;
88
use MongoDB\BSON\UTCDateTime;
99
use MongoDB\Codec\EncodeIfSupported;
10+
use MongoDB\Codec\Encoder;
1011
use MongoDB\Exception\UnsupportedValueException;
1112

1213
/**
13-
* @template-extends AbstractExpressionEncoder<UTCDateTime, DateTimeInterface>
14+
* @template-implements Encoder<UTCDateTime, DateTimeInterface>
1415
* @internal
1516
*/
16-
final class DateTimeEncoder extends AbstractExpressionEncoder
17+
final class DateTimeEncoder implements Encoder
1718
{
1819
/** @template-use EncodeIfSupported<UTCDateTime, DateTimeInterface> */
1920
use EncodeIfSupported;

src/Builder/Encoder/DictionaryEncoder.php

+3-2
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,15 @@
66

77
use MongoDB\Builder\Type\DictionaryInterface;
88
use MongoDB\Codec\EncodeIfSupported;
9+
use MongoDB\Codec\Encoder;
910
use MongoDB\Exception\UnsupportedValueException;
1011
use stdClass;
1112

1213
/**
13-
* @template-extends AbstractExpressionEncoder<string|int|array|stdClass, DictionaryInterface>
14+
* @template-implements Encoder<string|int|array|stdClass, DictionaryInterface>
1415
* @internal
1516
*/
16-
final class DictionaryEncoder extends AbstractExpressionEncoder
17+
final class DictionaryEncoder implements Encoder
1718
{
1819
/** @template-use EncodeIfSupported<string|int|array|stdClass, DictionaryInterface> */
1920
use EncodeIfSupported;

src/Builder/Encoder/ExpressionEncoder.php

-21
This file was deleted.

src/Builder/Encoder/FieldPathEncoder.php

+3-2
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@
66

77
use MongoDB\Builder\Type\FieldPathInterface;
88
use MongoDB\Codec\EncodeIfSupported;
9+
use MongoDB\Codec\Encoder;
910
use MongoDB\Exception\UnsupportedValueException;
1011

1112
/**
12-
* @template-extends AbstractExpressionEncoder<string, FieldPathInterface>
13+
* @template-implements Encoder<string, FieldPathInterface>
1314
* @internal
1415
*/
15-
final class FieldPathEncoder extends AbstractExpressionEncoder
16+
final class FieldPathEncoder implements Encoder
1617
{
1718
/** @template-use EncodeIfSupported<string, FieldPathInterface> */
1819
use EncodeIfSupported;

src/Builder/Encoder/OperatorEncoder.php

+4-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use MongoDB\Builder\Type\OperatorInterface;
1010
use MongoDB\Builder\Type\Optional;
1111
use MongoDB\Codec\EncodeIfSupported;
12+
use MongoDB\Codec\Encoder;
1213
use MongoDB\Exception\UnsupportedValueException;
1314
use stdClass;
1415

@@ -17,13 +18,14 @@
1718
use function sprintf;
1819

1920
/**
20-
* @template-extends AbstractExpressionEncoder<stdClass, OperatorInterface>
21+
* @template-implements Encoder<stdClass, OperatorInterface>
2122
* @internal
2223
*/
23-
final class OperatorEncoder extends AbstractExpressionEncoder
24+
final class OperatorEncoder implements Encoder
2425
{
2526
/** @template-use EncodeIfSupported<stdClass, OperatorInterface> */
2627
use EncodeIfSupported;
28+
use RecursiveEncode;
2729

2830
public function canEncode(mixed $value): bool
2931
{

src/Builder/Encoder/OutputWindowEncoder.php

+4-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use MongoDB\Builder\Type\OutputWindow;
1010
use MongoDB\Builder\Type\WindowInterface;
1111
use MongoDB\Codec\EncodeIfSupported;
12+
use MongoDB\Codec\Encoder;
1213
use MongoDB\Exception\UnsupportedValueException;
1314
use stdClass;
1415

@@ -18,13 +19,14 @@
1819
use function sprintf;
1920

2021
/**
21-
* @template-extends AbstractExpressionEncoder<stdClass, OutputWindow>
22+
* @template-implements Encoder<stdClass, OutputWindow>
2223
* @internal
2324
*/
24-
final class OutputWindowEncoder extends AbstractExpressionEncoder
25+
final class OutputWindowEncoder implements Encoder
2526
{
2627
/** @template-use EncodeIfSupported<stdClass, OutputWindow> */
2728
use EncodeIfSupported;
29+
use RecursiveEncode;
2830

2931
public function canEncode(mixed $value): bool
3032
{

src/Builder/Encoder/PipelineEncoder.php

+5-3
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,18 @@
66

77
use MongoDB\Builder\Pipeline;
88
use MongoDB\Codec\EncodeIfSupported;
9+
use MongoDB\Codec\Encoder;
910
use MongoDB\Exception\UnsupportedValueException;
1011

1112
/**
12-
* @template-extends AbstractExpressionEncoder<list<mixed>, Pipeline>
13+
* @template-implements Encoder<list<mixed>, Pipeline>
1314
* @internal
1415
*/
15-
final class PipelineEncoder extends AbstractExpressionEncoder
16+
final class PipelineEncoder implements Encoder
1617
{
1718
/** @template-use EncodeIfSupported<list<mixed>, Pipeline> */
1819
use EncodeIfSupported;
20+
use RecursiveEncode;
1921

2022
/** @psalm-assert-if-true Pipeline $value */
2123
public function canEncode(mixed $value): bool
@@ -32,7 +34,7 @@ public function encode(mixed $value): array
3234

3335
$encoded = [];
3436
foreach ($value->getIterator() as $stage) {
35-
$encoded[] = $this->encoder->encodeIfSupported($stage);
37+
$encoded[] = $this->recursiveEncode($stage);
3638
}
3739

3840
return $encoded;

src/Builder/Encoder/QueryEncoder.php

+4-2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use MongoDB\Builder\Type\QueryInterface;
99
use MongoDB\Builder\Type\QueryObject;
1010
use MongoDB\Codec\EncodeIfSupported;
11+
use MongoDB\Codec\Encoder;
1112
use MongoDB\Exception\UnsupportedValueException;
1213
use stdClass;
1314

@@ -16,13 +17,14 @@
1617
use function sprintf;
1718

1819
/**
19-
* @template-extends AbstractExpressionEncoder<stdClass, QueryObject>
20+
* @template-implements Encoder<stdClass, QueryObject>
2021
* @internal
2122
*/
22-
final class QueryEncoder extends AbstractExpressionEncoder
23+
final class QueryEncoder implements Encoder
2324
{
2425
/** @template-use EncodeIfSupported<stdClass, QueryObject> */
2526
use EncodeIfSupported;
27+
use RecursiveEncode;
2628

2729
public function canEncode(mixed $value): bool
2830
{

src/Builder/Encoder/AbstractExpressionEncoder.php src/Builder/Encoder/RecursiveEncode.php

+2-9
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,13 @@
44

55
namespace MongoDB\Builder\Encoder;
66

7-
use MongoDB\BSON\Type;
87
use MongoDB\Builder\BuilderEncoder;
98
use stdClass;
109

1110
use function get_object_vars;
1211
use function is_array;
1312

14-
/**
15-
* @template BSONType of Type|stdClass|array|string|int
16-
* @template NativeType
17-
* @template-implements ExpressionEncoder<BSONType, NativeType>
18-
* @internal
19-
*/
20-
abstract class AbstractExpressionEncoder implements ExpressionEncoder
13+
trait RecursiveEncode
2114
{
2215
final public function __construct(protected readonly BuilderEncoder $encoder)
2316
{
@@ -33,7 +26,7 @@ final public function __construct(protected readonly BuilderEncoder $encoder)
3326
*
3427
* @template T
3528
*/
36-
final protected function recursiveEncode(mixed $value): mixed
29+
private function recursiveEncode(mixed $value): mixed
3730
{
3831
if (is_array($value)) {
3932
foreach ($value as $key => $val) {

src/Builder/Encoder/VariableEncoder.php

+3-2
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@
66

77
use MongoDB\Builder\Expression\Variable;
88
use MongoDB\Codec\EncodeIfSupported;
9+
use MongoDB\Codec\Encoder;
910
use MongoDB\Exception\UnsupportedValueException;
1011

1112
/**
12-
* @template-extends AbstractExpressionEncoder<string, Variable>
13+
* @template-implements Encoder<string, Variable>
1314
* @internal
1415
*/
15-
final class VariableEncoder extends AbstractExpressionEncoder
16+
final class VariableEncoder implements Encoder
1617
{
1718
/** @template-use EncodeIfSupported<string, Variable> */
1819
use EncodeIfSupported;

0 commit comments

Comments
 (0)