Skip to content

Commit d8ab365

Browse files
committed
Merge branch 'tracked-entity'
2 parents e44be6f + ba1610c commit d8ab365

14 files changed

Lines changed: 130 additions & 65 deletions
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace DoctrineMigrations;
6+
7+
use Doctrine\DBAL\Schema\Schema;
8+
use Doctrine\Migrations\AbstractMigration;
9+
10+
final class Version20250715195941 extends AbstractMigration
11+
{
12+
public function getDescription(): string
13+
{
14+
return 'Add last modified columns';
15+
}
16+
17+
public function up(Schema $schema): void
18+
{
19+
$this->addSql(<<<'SQL'
20+
ALTER TABLE access_token ADD last_modified_at TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL
21+
SQL);
22+
$this->addSql(<<<'SQL'
23+
ALTER TABLE package ADD last_modified_at TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL
24+
SQL);
25+
$this->addSql(<<<'SQL'
26+
ALTER TABLE version ADD last_modified_at TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL
27+
SQL);
28+
}
29+
30+
public function down(Schema $schema): void
31+
{
32+
$this->addSql(<<<'SQL'
33+
ALTER TABLE version DROP last_modified_at
34+
SQL);
35+
$this->addSql(<<<'SQL'
36+
ALTER TABLE package DROP last_modified_at
37+
SQL);
38+
$this->addSql(<<<'SQL'
39+
ALTER TABLE access_token DROP last_modified_at
40+
SQL);
41+
}
42+
}

phpstan.dist.neon

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,16 @@ parameters:
1818
identifier: method.notFound
1919
count: 1
2020
path: src/DependencyInjection/DirigentConfiguration.php
21+
-
22+
message: '#^Class CodedMonkey\\Dirigent\\Doctrine\\Entity\\TrackedEntity has an uninitialized readonly property \$createdAt\. Assign it in the constructor\.$#'
23+
identifier: property.uninitializedReadonly
24+
count: 1
25+
path: src/Doctrine/Entity/TrackedEntity.php
26+
-
27+
message: '#^Readonly property CodedMonkey\\Dirigent\\Doctrine\\Entity\\TrackedEntity\:\:\$createdAt is assigned outside of the constructor\.$#'
28+
identifier: property.readOnlyAssignNotInConstructor
29+
count: 1
30+
path: src/Doctrine/Entity/TrackedEntity.php
2131
-
2232
message: '#^Left side of \|\| is always false\.$#'
2333
identifier: booleanOr.leftAlwaysFalse

src/Controller/ApiController.php

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -145,12 +145,9 @@ public function trackInstallations(Request $request): Response
145145
return new JsonResponse(['status' => 'error', 'message' => 'Invalid request format, must be a json object containing a downloads key filled with an array of name/version objects'], 200);
146146
}
147147

148-
$message = new TrackInstallations($contents['downloads'], new \DateTime());
149-
$envelope = new Envelope($message, [
150-
new TransportNamesStamp('async'),
151-
]);
152-
153-
$this->messenger->dispatch($envelope);
148+
$message = Envelope::wrap(new TrackInstallations($contents['downloads'], new \DateTimeImmutable()))
149+
->with(new TransportNamesStamp('async'));
150+
$this->messenger->dispatch($message);
154151

155152
return new JsonResponse(['status' => 'success'], Response::HTTP_CREATED);
156153
}

src/Doctrine/Entity/AbstractInstallations.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public function getMergedAt(): ?\DateTimeImmutable
5757
return $this->mergedAt;
5858
}
5959

60-
public function increase(\DateTimeInterface $date): void
60+
public function increase(\DateTimeImmutable $date): void
6161
{
6262
$key = $date->format('Ymd');
6363

src/Doctrine/Entity/AccessToken.php

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
use Doctrine\ORM\Mapping as ORM;
77

88
#[ORM\Entity(repositoryClass: AccessTokenRepository::class)]
9-
class AccessToken
9+
class AccessToken extends TrackedEntity
1010
{
1111
#[ORM\Column]
1212
#[ORM\GeneratedValue]
@@ -22,17 +22,13 @@ class AccessToken
2222
#[ORM\Column]
2323
private ?string $token = null;
2424

25-
#[ORM\Column]
26-
private readonly \DateTimeImmutable $createdAt;
27-
2825
#[ORM\Column(nullable: true)]
2926
private ?\DateTimeImmutable $expiresAt = null;
3027

3128
private ?string $plainToken = null;
3229

3330
public function __construct()
3431
{
35-
$this->createdAt = new \DateTimeImmutable();
3632
$this->plainToken = uniqid('dirigent-');
3733
}
3834

src/Doctrine/Entity/Package.php

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
#[ORM\Entity(repositoryClass: PackageRepository::class)]
1414
#[ORM\UniqueConstraint(name: 'package_name_idx', columns: ['name'])]
1515
#[UniquePackage]
16-
class Package
16+
class Package extends TrackedEntity
1717
{
1818
#[ORM\Id]
1919
#[ORM\Column]
@@ -74,17 +74,14 @@ class Package
7474
#[ORM\OneToMany(targetEntity: Version::class, mappedBy: 'package', cascade: ['remove'])]
7575
private Collection $versions;
7676

77-
#[ORM\Column(type: Types::DATETIME_MUTABLE)]
78-
private \DateTimeInterface $createdAt;
79-
80-
#[ORM\Column(type: Types::DATETIME_MUTABLE, nullable: true)]
81-
private ?\DateTimeInterface $updatedAt = null;
77+
#[ORM\Column(nullable: true)]
78+
private ?\DateTimeImmutable $updatedAt = null;
8279

83-
#[ORM\Column(type: Types::DATETIME_MUTABLE, nullable: true)]
84-
private ?\DateTimeInterface $updateScheduledAt = null;
80+
#[ORM\Column(nullable: true)]
81+
private ?\DateTimeImmutable $updateScheduledAt = null;
8582

86-
#[ORM\Column(type: Types::DATETIME_MUTABLE, nullable: true)]
87-
private ?\DateTimeInterface $dumpedAt = null;
83+
#[ORM\Column(nullable: true)]
84+
private ?\DateTimeImmutable $dumpedAt = null;
8885

8986
/**
9087
* @var array<string, Version> lookup table for versions
@@ -95,7 +92,6 @@ public function __construct()
9592
{
9693
$this->installations = new PackageInstallations($this);
9794
$this->versions = new ArrayCollection();
98-
$this->createdAt = new \DateTime();
9995
}
10096

10197
public function getId(): ?int
@@ -308,37 +304,37 @@ public function getVersion(string $normalizedVersion): ?Version
308304
return $this->cachedVersions[strtolower($normalizedVersion)] ?? null;
309305
}
310306

311-
public function getCreatedAt(): \DateTimeInterface
307+
public function getCreatedAt(): \DateTimeImmutable
312308
{
313309
return $this->createdAt;
314310
}
315311

316-
public function getUpdatedAt(): ?\DateTimeInterface
312+
public function getUpdatedAt(): ?\DateTimeImmutable
317313
{
318314
return $this->updatedAt;
319315
}
320316

321-
public function setUpdatedAt(\DateTimeInterface $updatedAt): void
317+
public function setUpdatedAt(\DateTimeImmutable $updatedAt): void
322318
{
323319
$this->updatedAt = $updatedAt;
324320
}
325321

326-
public function getUpdateScheduledAt(): ?\DateTimeInterface
322+
public function getUpdateScheduledAt(): ?\DateTimeImmutable
327323
{
328324
return $this->updateScheduledAt;
329325
}
330326

331-
public function setUpdateScheduledAt(?\DateTimeInterface $updateScheduledAt): void
327+
public function setUpdateScheduledAt(?\DateTimeImmutable $updateScheduledAt): void
332328
{
333329
$this->updateScheduledAt = $updateScheduledAt;
334330
}
335331

336-
public function getDumpedAt(): ?\DateTimeInterface
332+
public function getDumpedAt(): ?\DateTimeImmutable
337333
{
338334
return $this->dumpedAt;
339335
}
340336

341-
public function setDumpedAt(?\DateTimeInterface $dumpedAt): void
337+
public function setDumpedAt(?\DateTimeImmutable $dumpedAt): void
342338
{
343339
$this->dumpedAt = $dumpedAt;
344340
}

src/Doctrine/Entity/ResetPasswordRequest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class ResetPasswordRequest implements ResetPasswordRequestInterface
2121
#[ORM\JoinColumn(nullable: false)]
2222
private User $user;
2323

24-
public function __construct(User $user, \DateTimeInterface $expiresAt, string $selector, string $hashedToken)
24+
public function __construct(User $user, \DateTimeImmutable $expiresAt, string $selector, string $hashedToken)
2525
{
2626
$this->user = $user;
2727
$this->initialize($expiresAt, $selector, $hashedToken);
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
namespace CodedMonkey\Dirigent\Doctrine\Entity;
4+
5+
use Doctrine\ORM\Mapping as ORM;
6+
7+
#[ORM\MappedSuperclass]
8+
#[ORM\HasLifecycleCallbacks]
9+
abstract class TrackedEntity
10+
{
11+
#[ORM\Column]
12+
protected readonly \DateTimeImmutable $createdAt;
13+
14+
#[ORM\Column(nullable: true)]
15+
protected ?\DateTimeImmutable $lastModifiedAt = null;
16+
17+
public function getCreatedAt(): \DateTimeImmutable
18+
{
19+
return $this->createdAt;
20+
}
21+
22+
#[ORM\PrePersist]
23+
public function setCreatedAt(): void
24+
{
25+
$this->createdAt ??= new \DateTimeImmutable();
26+
}
27+
28+
public function getLastModifiedAt(): ?\DateTimeImmutable
29+
{
30+
return $this->lastModifiedAt;
31+
}
32+
33+
#[ORM\PreUpdate]
34+
public function setLastModifiedAt(): void
35+
{
36+
$this->lastModifiedAt = new \DateTimeImmutable();
37+
}
38+
}

src/Doctrine/Entity/Version.php

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
#[ORM\Entity(repositoryClass: VersionRepository::class)]
1414
#[ORM\UniqueConstraint(name: 'pkg_ver_idx', columns: ['package_id', 'normalized_version'])]
15-
class Version
15+
class Version extends TrackedEntity
1616
{
1717
#[ORM\Id]
1818
#[ORM\Column]
@@ -115,14 +115,11 @@ class Version
115115
#[ORM\OneToOne(mappedBy: 'version', cascade: ['persist', 'detach', 'remove'])]
116116
private VersionInstallations $installations;
117117

118-
#[ORM\Column(type: Types::DATETIME_MUTABLE)]
119-
private \DateTimeInterface $createdAt;
120-
121-
#[ORM\Column(type: Types::DATETIME_MUTABLE, nullable: true)]
122-
private ?\DateTimeInterface $updatedAt = null;
118+
#[ORM\Column(nullable: true)]
119+
private ?\DateTimeImmutable $updatedAt = null;
123120

124-
#[ORM\Column(type: Types::DATETIME_MUTABLE, nullable: true)]
125-
private ?\DateTimeInterface $releasedAt = null;
121+
#[ORM\Column(nullable: true)]
122+
private ?\DateTimeImmutable $releasedAt = null;
126123

127124
public function __construct()
128125
{
@@ -134,7 +131,6 @@ public function __construct()
134131
$this->suggest = new ArrayCollection();
135132
$this->tags = new ArrayCollection();
136133
$this->installations = new VersionInstallations($this);
137-
$this->createdAt = new \DateTime();
138134
}
139135

140136
public function __toString(): string
@@ -487,27 +483,22 @@ public function getInstallations(): VersionInstallations
487483
return $this->installations;
488484
}
489485

490-
public function getCreatedAt(): \DateTimeInterface
491-
{
492-
return $this->createdAt;
493-
}
494-
495-
public function getUpdatedAt(): ?\DateTimeInterface
486+
public function getUpdatedAt(): ?\DateTimeImmutable
496487
{
497488
return $this->updatedAt;
498489
}
499490

500-
public function setUpdatedAt(\DateTimeInterface $updatedAt): void
491+
public function setUpdatedAt(\DateTimeImmutable $updatedAt): void
501492
{
502493
$this->updatedAt = $updatedAt;
503494
}
504495

505-
public function getReleasedAt(): ?\DateTimeInterface
496+
public function getReleasedAt(): ?\DateTimeImmutable
506497
{
507498
return $this->releasedAt;
508499
}
509500

510-
public function setReleasedAt(?\DateTimeInterface $releasedAt): void
501+
public function setReleasedAt(?\DateTimeImmutable $releasedAt): void
511502
{
512503
$this->releasedAt = $releasedAt;
513504
}

src/Doctrine/Repository/ResetPasswordRequestRepository.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,6 @@ public function __construct(ManagerRegistry $registry)
2727
*/
2828
public function createResetPasswordRequest(object $user, \DateTimeInterface $expiresAt, string $selector, string $hashedToken): ResetPasswordRequestInterface
2929
{
30-
return new ResetPasswordRequest($user, $expiresAt, $selector, $hashedToken);
30+
return new ResetPasswordRequest($user, \DateTimeImmutable::createFromInterface($expiresAt), $selector, $hashedToken);
3131
}
3232
}

0 commit comments

Comments
 (0)