Skip to content
Open
Show file tree
Hide file tree
Changes from 4 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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ a release.
## [Unreleased]
### Added
- Support for Symfony 8
- SoftDeleteable: Add support for `date_point` type (#3013)
- Timestampable: Add support for `date_point` type (#3013)

## [3.21.0] - 2025-09-22
### Added
Expand Down
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
"phpstan/phpstan-phpunit": "^2.0.3",
"phpunit/phpunit": "^9.6",
"rector/rector": "^2.2.6",
"symfony/clock": "^6.4 || ^7.3 || ^8.0",
"symfony/console": "^5.4 || ^6.4 || ^7.3 || ^8.0",
"symfony/doctrine-bridge": "^5.4 || ^6.4 || ^7.3 || ^8.0",
"symfony/phpunit-bridge": "^6.4 || ^7.3 || ^8.0",
Expand Down
2 changes: 1 addition & 1 deletion src/SoftDeleteable/Mapping/Event/Adapter/ORM.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ private function getRawDateValue($mapping)
return (int) $datetime->format('U');
}

if (in_array($type, ['date_immutable', 'time_immutable', 'datetime_immutable', 'datetimetz_immutable'], true)) {
if (in_array($type, ['date_immutable', 'time_immutable', 'datetime_immutable', 'datetimetz_immutable', 'date_point'], true)) {
return $datetime;
}

Expand Down
1 change: 1 addition & 0 deletions src/SoftDeleteable/Mapping/Validator.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class Validator
'datetimetz',
'datetimetz_immutable',
'timestamp',
'date_point',
];

/**
Expand Down
1 change: 1 addition & 0 deletions src/Timestampable/Mapping/Driver/Attribute.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class Attribute extends AbstractAnnotationDriver
'timestamp',
'vardatetime',
'integer',
'date_point',
];

public function readExtendedMetadata($meta, array &$config)
Expand Down
1 change: 1 addition & 0 deletions src/Timestampable/Mapping/Driver/Xml.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class Xml extends BaseXml
'timestamp',
'vardatetime',
'integer',
'date_point',
];

public function readExtendedMetadata($meta, array &$config)
Expand Down
1 change: 1 addition & 0 deletions src/Timestampable/Mapping/Driver/Yaml.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class Yaml extends File implements Driver
'timestamp',
'vardatetime',
'integer',
'date_point',
];

/**
Expand Down
2 changes: 1 addition & 1 deletion src/Timestampable/Mapping/Event/Adapter/ORM.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ private function getRawDateValue($mapping)
return (int) $datetime->format('U');
}

if (in_array($type, ['date_immutable', 'time_immutable', 'datetime_immutable', 'datetimetz_immutable'], true)) {
if (in_array($type, ['date_immutable', 'time_immutable', 'datetime_immutable', 'datetimetz_immutable', 'date_point'], true)) {
return $datetime;
}

Expand Down
85 changes: 85 additions & 0 deletions tests/Gedmo/SoftDeleteable/DatePointTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php

/*
* This file is part of the Doctrine Behavioral Extensions package.
* (c) Gediminas Morkevicius <gediminas.morkevicius@gmail.com> http://www.gediminasm.org
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Gedmo\Tests\SoftDeleteable;

use Carbon\Doctrine\DateTimeType;
use Doctrine\Common\EventManager;
use Doctrine\DBAL\Types\Type as DoctrineType;
use Doctrine\DBAL\Types\Types;
use Gedmo\SoftDeleteable\Filter\SoftDeleteableFilter;
use Gedmo\SoftDeleteable\SoftDeleteableListener;
use Gedmo\Tests\SoftDeleteable\Fixture\Entity\BookDatePoint;
use Gedmo\Tests\Tool\BaseTestCaseORM;
use Symfony\Component\Clock\DatePoint;

final class DatePointTest extends BaseTestCaseORM
Comment thread
IndraGunawan marked this conversation as resolved.
{
private const SOFT_DELETEABLE_FILTER_NAME = 'soft-deleteable';

private SoftDeleteableListener $softDeleteableListener;

protected function setUp(): void
{
parent::setUp();

$evm = new EventManager();
$this->softDeleteableListener = new SoftDeleteableListener();
$evm->addEventSubscriber($this->softDeleteableListener);
$config = $this->getDefaultConfiguration();
$config->addFilter(self::SOFT_DELETEABLE_FILTER_NAME, SoftDeleteableFilter::class);
$this->em = $this->getDefaultMockSqliteEntityManager($evm, $config);
$this->em->getFilters()->enable(self::SOFT_DELETEABLE_FILTER_NAME);

DoctrineType::overrideType(Types::DATETIME_MUTABLE, DateTimeType::class);
}

protected function tearDown(): void
{
parent::tearDown();

DoctrineType::overrideType(Types::DATETIME_MUTABLE, \Doctrine\DBAL\Types\DateTimeType::class);
}

public function testSoftDeleteable(): void
{
$repo = $this->em->getRepository(BookDatePoint::class);

$book0 = new BookDatePoint();
$field = 'title';
$value = 'Title 1';
$book0->setTitle($value);

$this->em->persist($book0);
$this->em->flush();

static::assertNull($book0->getDeletedAt());

$book = $repo->findOneBy([$field => $value]);
$this->em->remove($book);
$this->em->flush();

$book = $repo->findOneBy([$field => $value]);
static::assertNull($book);

// Now we deactivate the filter so we test if the entity appears in the result
$this->em->getFilters()->disable(self::SOFT_DELETEABLE_FILTER_NAME);

$book = $repo->findOneBy([$field => $value]);
static::assertIsObject($book);
static::assertInstanceOf(DatePoint::class, $book->getDeletedAt());
}

protected function getUsedEntityFixtures(): array
{
return [
BookDatePoint::class,
];
}
}
76 changes: 76 additions & 0 deletions tests/Gedmo/SoftDeleteable/Fixture/Entity/BookDatePoint.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php

declare(strict_types=1);

/*
* This file is part of the Doctrine Behavioral Extensions package.
* (c) Gediminas Morkevicius <gediminas.morkevicius@gmail.com> http://www.gediminasm.org
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Gedmo\Tests\SoftDeleteable\Fixture\Entity;

use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Symfony\Component\Clock\DatePoint;

/**
* @ORM\Entity
*
* @Gedmo\SoftDeleteable(fieldName="deletedAt")
*/
#[ORM\Entity]
#[Gedmo\SoftDeleteable(fieldName: 'deletedAt')]
class BookDatePoint
{
/**
* @var int|null
*
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
* @ORM\Column(type="integer")
*/
#[ORM\Id]
#[ORM\GeneratedValue(strategy: 'IDENTITY')]
#[ORM\Column(type: Types::INTEGER)]
private $id;

/**
* @ORM\Column(name="title", type="string")
*/
#[ORM\Column(name: 'title', type: Types::STRING)]
private ?string $title = null;

/**
* @ORM\Column(name="deletedAt", type="date_point", nullable=true)
*/
#[ORM\Column(name: 'deletedAt', type: 'date_point', nullable: true)]
private ?DatePoint $deletedAt = null;

public function getId(): ?int
{
return $this->id;
}

public function setTitle(?string $title): void
{
$this->title = $title;
}

public function getTitle(): ?string
{
return $this->title;
}

public function setDeletedAt(?DatePoint $deletedAt): void
{
$this->deletedAt = $deletedAt;
}

public function getDeletedAt(): ?DatePoint
{
return $this->deletedAt;
}
}
135 changes: 135 additions & 0 deletions tests/Gedmo/Timestampable/DatePointTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
<?php

/*
* This file is part of the Doctrine Behavioral Extensions package.
* (c) Gediminas Morkevicius <gediminas.morkevicius@gmail.com> http://www.gediminasm.org
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Gedmo\Tests\Timestampable;

use Doctrine\Common\EventManager;
use Gedmo\Tests\Timestampable\Fixture\ArticleDatePoint;
use Gedmo\Tests\Timestampable\Fixture\Author;
use Gedmo\Tests\Timestampable\Fixture\CommentDatePoint;
use Gedmo\Tests\Timestampable\Fixture\Type;
use Gedmo\Tests\Tool\BaseTestCaseORM;
use Gedmo\Timestampable\TimestampableListener;
use Symfony\Component\Clock\DatePoint;
use Symfony\Component\Clock\NativeClock;

final class DatePointTest extends BaseTestCaseORM
Comment thread
IndraGunawan marked this conversation as resolved.
{
protected function setUp(): void
{
parent::setUp();

$evm = new EventManager();
$evm->addEventSubscriber(new TimestampableListener());

$this->getDefaultMockSqliteEntityManager($evm);
}

protected function tearDown(): void
{
parent::tearDown();
}

public function testShouldHandleStandardBehavior(): void
{
$sport = new ArticleDatePoint();
$sport->setTitle('Sport');
$sport->setBody('Sport article body.');

$sportComment = new CommentDatePoint();
$sportComment->setMessage('hello');
$sportComment->setArticle($sport);
$sportComment->setStatus(0);

$author = new Author();
$author->setName('Original author');
$author->setEmail('original@author.dev');

$sport->setAuthor($author);

$this->em->persist($sport);
$this->em->persist($sportComment);
$this->em->flush();

/** @var ArticleDatePoint $sport */
$sport = $this->em->getRepository(ArticleDatePoint::class)->findOneBy(['title' => 'Sport']);
static::assertInstanceOf(DatePoint::class, $su = $sport->getUpdated());

static::assertNull($sport->getContentChanged());
static::assertNull($sport->getPublished());
static::assertNull($sport->getAuthorChanged());

$author = $sport->getAuthor();
$author->setName('New author');
$sport->setAuthor($author);

/** @var CommentDatePoint $sportComment */
$sportComment = $this->em->getRepository(CommentDatePoint::class)->findOneBy(['message' => 'hello']);
static::assertInstanceOf(DatePoint::class, $sc = $sportComment->getModified());

static::assertNotNull($sportComment->getModified());
static::assertNull($sportComment->getClosed());

$sportComment->setStatus(1);
$published = new Type();
$published->setTitle('Published');

$sport->setType($published);
$this->em->persist($sport);
$this->em->persist($published);
$this->em->persist($sportComment);
$this->em->flush();

$sportComment = $this->em->getRepository(CommentDatePoint::class)->findOneBy(['message' => 'hello']);
static::assertInstanceOf(DatePoint::class, $scc = $sportComment->getClosed());
static::assertInstanceOf(DatePoint::class, $sp = $sport->getPublished());
static::assertInstanceOf(DatePoint::class, $sa = $sport->getAuthorChanged());

$sport->setTitle('Updated');
$this->em->persist($sport);
$this->em->persist($published);
$this->em->persist($sportComment);
$this->em->flush();

// prevent "Failed asserting that two variables reference the same object." error, hence compare unix epoch
static::assertEquals($sport->getCreated()->format('U'), $sc->format('U'), 'Date created should remain same after update');
static::assertNotSame($su2 = $sport->getUpdated(), $su, 'Date updated should change after update');
static::assertInstanceOf(DatePoint::class, $sport->getUpdated());
static::assertSame($sport->getPublished(), $sp, 'Date published should remain the same after update');
static::assertNotSame($scc2 = $sport->getContentChanged(), $scc, 'Content must have changed after update');
static::assertInstanceOf(DatePoint::class, $sport->getContentChanged());
static::assertSame($sport->getAuthorChanged(), $sa, 'Author should remain same after update');

$author = $sport->getAuthor();
$author->setName('Third author');
$sport->setAuthor($author);

$sport->setBody('Body updated');
$this->em->persist($sport);
$this->em->persist($published);
$this->em->persist($sportComment);
$this->em->flush();

// prevent "Failed asserting that two variables reference the same object." error, hence compare unix epoch
static::assertEquals($sport->getCreated()->format('U'), $sc->format('U'), 'Date created should remain same after update');
static::assertNotSame($sport->getUpdated(), $su2, 'Date updated should change after update');
static::assertSame($sport->getPublished(), $sp, 'Date published should remain the same after update');
static::assertNotSame($sport->getContentChanged(), $scc2, 'Content must have changed after update');
static::assertNotSame($sport->getAuthorChanged(), $sa, 'Author must have changed after update');
}

protected function getUsedEntityFixtures(): array
{
return [
ArticleDatePoint::class,
CommentDatePoint::class,
Type::class,
];
}
}
Loading