-
-
Notifications
You must be signed in to change notification settings - Fork 504
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
doc: Update custom mapping example #2654
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Documentation\CustomMapping; | ||
|
||
use DateTimeImmutable; | ||
use DateTimeZone; | ||
use Doctrine\ODM\MongoDB\Tests\BaseTestCase; | ||
use Doctrine\ODM\MongoDB\Types\Type; | ||
|
||
class CustomMappingTest extends BaseTestCase | ||
{ | ||
public function testTest(): void | ||
{ | ||
Type::addType('date_with_timezone', DateTimeWithTimezoneType::class); | ||
Type::overrideType('date_immutable', DateTimeWithTimezoneType::class); | ||
|
||
$thing = new Thing(); | ||
$thing->date = new DateTimeImmutable('2021-01-01 00:00:00', new DateTimeZone('Africa/Tripoli')); | ||
|
||
$this->dm->persist($thing); | ||
$this->dm->flush(); | ||
$this->dm->clear(); | ||
|
||
$result = $this->dm->find(Thing::class, $thing->id); | ||
$this->assertEquals($thing->date, $result->date); | ||
$this->assertEquals('Africa/Tripoli', $result->date->getTimezone()->getName()); | ||
|
||
// Ensure we don't need to handle null values | ||
$nothing = new Thing(); | ||
|
||
$this->dm->persist($nothing); | ||
$this->dm->flush(); | ||
$this->dm->clear(); | ||
|
||
$result = $this->dm->find(Thing::class, $nothing->id); | ||
$this->assertNull($result->date); | ||
} | ||
} |
47 changes: 47 additions & 0 deletions
47
tests/Documentation/CustomMapping/DateTimeWithTimezoneType.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Documentation\CustomMapping; | ||
|
||
use DateTimeImmutable; | ||
use DateTimeInterface; | ||
use DateTimeZone; | ||
use Doctrine\ODM\MongoDB\Types\ClosureToPHP; | ||
use Doctrine\ODM\MongoDB\Types\Type; | ||
use MongoDB\BSON\UTCDateTime; | ||
use RuntimeException; | ||
|
||
class DateTimeWithTimezoneType extends Type | ||
{ | ||
// This trait provides default closureToPHP used during data hydration | ||
use ClosureToPHP; | ||
|
||
/** @param array{utc: UTCDateTime, tz: string} $value */ | ||
public function convertToPHPValue($value): DateTimeImmutable | ||
{ | ||
if (! isset($value['utc'], $value['tz'])) { | ||
throw new RuntimeException('Database value cannot be converted to date with timezone. Expected array with "utc" and "tz" keys.'); | ||
} | ||
|
||
$timeZone = new DateTimeZone($value['tz']); | ||
$dateTime = $value['utc'] | ||
->toDateTime() | ||
->setTimeZone($timeZone); | ||
|
||
return DateTimeImmutable::createFromMutable($dateTime); | ||
} | ||
|
||
/** | ||
* @param DateTimeInterface $value | ||
* | ||
* @return array{utc: UTCDateTime, tz: string} | ||
*/ | ||
public function convertToDatabaseValue($value): array | ||
{ | ||
return [ | ||
'utc' => new UTCDateTime($value), | ||
'tz' => $value->getTimezone()->getName(), | ||
]; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Documentation\CustomMapping; | ||
|
||
use DateTimeImmutable; | ||
use Doctrine\ODM\MongoDB\Mapping\Annotations\Document; | ||
use Doctrine\ODM\MongoDB\Mapping\Annotations\Field; | ||
use Doctrine\ODM\MongoDB\Mapping\Annotations\Id; | ||
|
||
#[Document] | ||
class Thing | ||
{ | ||
#[Id] | ||
public string $id; | ||
|
||
#[Field(type: 'date_with_timezone')] | ||
public ?DateTimeImmutable $date = null; | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a suggestion, but this could benefit from some value checks:
The end result will be the same, but I feel like there can be more useful information in the exception message rather than letting PHP throw its type errors. Not sure if there's prior art for this in our type, so feel free to disregard and leave this as an exercise to the user.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Absolutely, it's easy to be sure of a property's value, especially with typing, but there can always be surprises with database content, especially when there's no schema (which is certainly very common).