Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions UPGRADE-2.16.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,16 @@ be supported in MongoDB ODM 3.0.
Calling `Doctrine\ODM\MongoDB\Configuration::setProxyDir()` or
`Doctrine\ODM\MongoDB\Configuration::getProxyDir()` is deprecated and triggers
a deprecation notice when using native lazy objects.

## Override `Type::closureToPHP()` for custom type classes

The default implementation of `Doctrine\ODM\MongoDB\Types\Type::closureToPHP()`
will change in MongoDB ODM 3.0 to call `convertToPHPValue()`. If you have custom
type classes, use the `Doctrine\ODM\MongoDB\Types\ClosureToPHP` trait or
implement `closureToPHP()`.

## Deprecate `Type::closureToMongo()`

The method `Doctrine\ODM\MongoDB\Types\Type::closureToMongo()` is not used,
and will be removed in MongoDB ODM 3.0. Don't call this method, but use
`convertToDatabaseValue()` instead.
1 change: 1 addition & 0 deletions src/Types/ClosureToPHP.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use function sprintf;

/** This trait will be deprecated in 3.0 as this behavior will be used by default */
trait ClosureToPHP
{
/** @return string Redirects to the method convertToPHPValue from child class */
Expand Down
5 changes: 5 additions & 0 deletions src/Types/CollectionType.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,9 @@ public function convertToPHPValue($value)
{
return $value !== null ? array_values($value) : null;
}

public function closureToPHP(): string
{
return '$return = array_values($value);';
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

null is already handled by the generated hydrator code.

}
}
5 changes: 5 additions & 0 deletions src/Types/HashType.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,9 @@ public function convertToPHPValue($value)
{
return $value !== null ? (array) $value : null;
}

public function closureToPHP(): string
{
return '$return = (array) $value;';
}
}
2 changes: 2 additions & 0 deletions src/Types/KeyType.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
*/
class KeyType extends Type
{
use ClosureToPHP;

/** @return MinKey|MaxKey|null */
public function convertToDatabaseValue($value)
{
Expand Down
2 changes: 2 additions & 0 deletions src/Types/TimestampType.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
*/
class TimestampType extends Type
{
use ClosureToPHP;

/** @return Timestamp|null */
public function convertToDatabaseValue($value)
{
Expand Down
10 changes: 10 additions & 0 deletions src/Types/Type.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use function gettype;
use function is_object;
use function str_replace;
use function trigger_deprecation;

/**
* The Type interface.
Expand Down Expand Up @@ -129,18 +130,27 @@ public function convertToPHPValue($value)
/**
* Get the PHP code equivalent to {@see convertToDatabaseValue()}, used in code generator.
* Use variables $value for input and $return for output.
*
* @deprecated Since 2.16, will be removed in 3.0.
*/
public function closureToMongo(): string
{
trigger_deprecation('doctrine/mongodb-odm', '2.16', 'Type::closureToMongo() is deprecated and will be removed in 3.0.');

return '$return = $value;';
}

/**
* Get the PHP code equivalent to {@see convertToPHPValue()}, used in code generator.
* Use variables $value for input and $return for output.
*
* @abstract The default implementation will change in 3.0.
*/
public function closureToPHP(): string
{
trigger_deprecation('doctrine/mongodb-odm', '2.16', 'The method Type::closureToPHP() will change its default implementation in 3.0 to use convertToPHPValue(). Override this method if you need custom behavior before upgrading to 3.0 or use the trait ClosureToPHP to get the upcoming behavior now.');
// return sprintf('$return = \%s::getType($typeIdentifier)->convertToPHPValue($value);', Type::class);

return '$return = $value;';
}

Expand Down
14 changes: 14 additions & 0 deletions tests/Tests/Functional/CustomTypeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Doctrine\ODM\MongoDB\Types\Type;
use Exception;
use PHPUnit\Framework\Attributes\After;
use PHPUnit\Framework\Attributes\IgnoreDeprecations;
use ReflectionProperty;

use function array_map;
Expand All @@ -26,6 +27,7 @@ public function setUp(): void

Type::addType('date_collection', DateCollectionType::class);
Type::addType(Language::class, LanguageType::class);
Type::addType('custom_type_without_closure_to_php', CustomTypeWithoutClosureToPHP::class);
}

#[After]
Expand Down Expand Up @@ -89,6 +91,14 @@ public function testTypeFromPHPVariable(): void
$databaseValue = Type::convertPHPToDatabaseValue($lang);
self::assertSame(['name' => 'French', 'code' => 'fr'], $databaseValue);
}

#[IgnoreDeprecations]
public function testNotOverridingClosureToPHPIsDeprecated(): void
{
$type = Type::getType('custom_type_without_closure_to_php');

self::assertSame('$return = $value;', $type->closureToPHP());
}
}

class DateCollectionType extends Type
Expand Down Expand Up @@ -198,3 +208,7 @@ public function convertToPHPValue($value): ?Language
return new Language($value['name'], $value['code']);
}
}

class CustomTypeWithoutClosureToPHP extends Type
{
}
10 changes: 10 additions & 0 deletions tests/Tests/Types/TypeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,16 @@ public function testConversion(string $typeName, mixed $phpValue, mixed $bsonVal
self::assertSameTypeAndValue($bsonValue, $type->convertToDatabaseValue($phpValue));
}

#[DataProvider('provideTypes')]
public function testConversionWithClosureToPHP(string $typeIdentifier, mixed $expectedValue, mixed $value = null): void
{
$value ??= $expectedValue;
$return = $this;
eval(Type::getType($typeIdentifier)->closureToPHP());

self::assertSameTypeAndValue($expectedValue, $return);
}

public static function provideTypes(): array
{
return [
Expand Down