1
0
Fork 0

Refactor: split `BaseEntity` abstract class into a set of traits

This commit is contained in:
Krzysztof Sikorski 2022-04-17 20:39:54 +02:00
parent 101516d438
commit 2280822ab4
Signed by: krzysztof-sikorski
GPG Key ID: 4EB564BD08FE8476
11 changed files with 118 additions and 47 deletions

View File

@ -5,14 +5,9 @@ declare(strict_types=1);
namespace App\Contract\Doctrine\Entity;
use DateTimeImmutable;
use Symfony\Component\Uid\Uuid;
interface BaseEntityInterface
interface DatedEntityInterface
{
public function getId(): Uuid;
public function setId(Uuid $id): void;
public function getCreatedAt(): ?DateTimeImmutable;
public function setCreatedAt(DateTimeImmutable $createdAt): void;

View File

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\Contract\Doctrine\Entity;
use Symfony\Component\Uid\Uuid;
interface UuidPrimaryKeyInterface
{
public function getId(): Uuid;
public function setId(Uuid $id): void;
}

View File

@ -4,42 +4,21 @@ declare(strict_types=1);
namespace App\Doctrine\Entity;
use App\Contract\Config\AppParameters;
use App\Contract\Doctrine\Entity\BaseEntityInterface;
use DateTimeImmutable;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Uid\Uuid;
abstract class BaseEntity implements BaseEntityInterface
/**
* Implementation for `\App\Contract\Doctrine\Entity\DatedEntityInterface` interface
*/
trait DatedEntityTrait
{
#[
ORM\Id,
ORM\Column(name: 'id', type: AppParameters::DOCTRINE_COLUMN_TYPE_UUID),
]
protected Uuid $id;
#[ORM\Column(name: 'created_at', type: Types::DATETIMETZ_IMMUTABLE, nullable: false)]
protected ?DateTimeImmutable $createdAt = null;
#[ORM\Column(name: 'last_modified_at', type: Types::DATETIMETZ_IMMUTABLE, nullable: false)]
protected ?DateTimeImmutable $lastModifiedAt = null;
public function __construct(?Uuid $id = null)
{
$this->id = $id ?? Uuid::v4();
}
public function getId(): Uuid
{
return $this->id;
}
public function setId(Uuid $id): void
{
$this->id = $id;
}
public function getCreatedAt(): ?DateTimeImmutable
{
return $this->createdAt;

View File

@ -4,8 +4,11 @@ declare(strict_types=1);
namespace App\Doctrine\Entity\Nexus;
use App\Contract\Doctrine\Entity\DatedEntityInterface;
use App\Contract\Doctrine\Entity\UuidPrimaryKeyInterface;
use App\Contract\Entity\LeaderboardTypes;
use App\Doctrine\Entity\BaseEntity;
use App\Doctrine\Entity\DatedEntityTrait;
use App\Doctrine\Entity\UuidPrimaryKeyTrait;
use App\Doctrine\Repository\Nexus\LeaderboardRepository;
use Doctrine\ORM\Mapping as ORM;
@ -14,8 +17,11 @@ use Doctrine\ORM\Mapping as ORM;
ORM\Table(name: 'nexus_leaderboard'),
ORM\UniqueConstraint(name: 'nexus_leaderboard_uniq', fields: ['title']),
]
class Leaderboard extends BaseEntity
class Leaderboard implements UuidPrimaryKeyInterface, DatedEntityInterface
{
use UuidPrimaryKeyTrait;
use DatedEntityTrait;
#[ORM\Column(name: 'title', type: 'text', nullable: false)]
private ?string $title = null;
@ -25,6 +31,11 @@ class Leaderboard extends BaseEntity
#[ORM\Column(name: 'career', type: 'boolean', nullable: false)]
private bool $career = false;
public function __construct()
{
$this->generateId();
}
public function getTitle(): ?string
{
return $this->title;

View File

@ -4,7 +4,10 @@ declare(strict_types=1);
namespace App\Doctrine\Entity\Nexus;
use App\Doctrine\Entity\BaseEntity;
use App\Contract\Doctrine\Entity\DatedEntityInterface;
use App\Contract\Doctrine\Entity\UuidPrimaryKeyInterface;
use App\Doctrine\Entity\DatedEntityTrait;
use App\Doctrine\Entity\UuidPrimaryKeyTrait;
use App\Doctrine\Repository\Nexus\LeaderboardEntryRepository;
use Doctrine\ORM\Mapping as ORM;
@ -14,8 +17,11 @@ use Doctrine\ORM\Mapping as ORM;
ORM\UniqueConstraint(name: 'nexus_leaderboard_entry_uniq', fields: ['position']),
ORM\Index(fields: ['leaderboard'], name: 'nexus_leaderboard_entry_leaderboard_idx'),
]
class LeaderboardEntry extends BaseEntity
class LeaderboardEntry implements UuidPrimaryKeyInterface, DatedEntityInterface
{
use UuidPrimaryKeyTrait;
use DatedEntityTrait;
#[
ORM\ManyToOne(targetEntity: Leaderboard::class),
ORM\JoinColumn(name: 'leaderboard_id', referencedColumnName: 'id', nullable: false),
@ -31,6 +37,11 @@ class LeaderboardEntry extends BaseEntity
#[ORM\Column(name: 'value', type: 'integer', nullable: false)]
private ?int $value = null;
public function __construct()
{
$this->generateId();
}
public function getLeaderboard(): ?Leaderboard
{
return $this->leaderboard;

View File

@ -4,7 +4,8 @@ declare(strict_types=1);
namespace App\Doctrine\Entity;
use App\Contract\Doctrine\Entity\BaseEntityInterface;
use App\Contract\Doctrine\Entity\DatedEntityInterface;
use App\Contract\Doctrine\Entity\UuidPrimaryKeyInterface;
use App\Doctrine\Repository\NexusRawDataRepository;
use DateTimeImmutable;
use DateTimeInterface;
@ -18,8 +19,11 @@ use JsonSerializable;
ORM\Index(columns: ['created_at', 'request_started_at', 'id'], name: 'nexus_raw_data_sorting_idx'),
ORM\Index(columns: ['submitter_id'], name: 'nexus_raw_data_submitter_idx'),
]
class NexusRawData extends BaseEntity implements BaseEntityInterface, JsonSerializable
class NexusRawData implements UuidPrimaryKeyInterface, DatedEntityInterface, JsonSerializable
{
use UuidPrimaryKeyTrait;
use DatedEntityTrait;
#[
ORM\ManyToOne(targetEntity: User::class),
ORM\JoinColumn(name: 'submitter_id', referencedColumnName: 'id', nullable: false),
@ -50,6 +54,11 @@ class NexusRawData extends BaseEntity implements BaseEntityInterface, JsonSerial
#[ORM\Column(name: 'parser_errors', type: 'json', nullable: true)]
private mixed $parserErrors = null;
public function __construct()
{
$this->generateId();
}
public function jsonSerialize(): array
{
return [

View File

@ -5,7 +5,8 @@ declare(strict_types=1);
namespace App\Doctrine\Entity;
use App\Contract\Config\AppParameters;
use App\Contract\Doctrine\Entity\BaseEntityInterface;
use App\Contract\Doctrine\Entity\DatedEntityInterface;
use App\Contract\Doctrine\Entity\UuidPrimaryKeyInterface;
use App\Doctrine\Repository\UserRepository;
use DateTimeInterface;
use Doctrine\DBAL\Types\Types;
@ -19,9 +20,13 @@ use Symfony\Component\Security\Core\User\UserInterface;
ORM\Table(name: '"user"'),
ORM\UniqueConstraint(name: 'user_username_uniq', fields: [AppParameters::SECURITY_USER_ENTITY_ID_FIELD]),
]
class User extends BaseEntity
implements BaseEntityInterface, UserInterface, PasswordAuthenticatedUserInterface, JsonSerializable
class User
implements UuidPrimaryKeyInterface, DatedEntityInterface,
UserInterface, PasswordAuthenticatedUserInterface, JsonSerializable
{
use UuidPrimaryKeyTrait;
use DatedEntityTrait;
public const USERNAME_MAX_LENGTH = 180;
#[ORM\Column(name: 'username', type: Types::STRING, length: self::USERNAME_MAX_LENGTH, nullable: false)]
@ -36,6 +41,11 @@ class User extends BaseEntity
#[ORM\Column(name: 'enabled', type: Types::BOOLEAN, nullable: false)]
private bool $enabled = false;
public function __construct()
{
$this->generateId();
}
public function __toString(): string
{
return $this->getUserIdentifier();

View File

@ -4,7 +4,8 @@ declare(strict_types=1);
namespace App\Doctrine\Entity;
use App\Contract\Doctrine\Entity\BaseEntityInterface;
use App\Contract\Doctrine\Entity\DatedEntityInterface;
use App\Contract\Doctrine\Entity\UuidPrimaryKeyInterface;
use App\Doctrine\Repository\UserAccessTokenRepository;
use DateTimeImmutable;
use DateTimeInterface;
@ -18,8 +19,11 @@ use JsonSerializable;
ORM\UniqueConstraint(name: 'value_uniq', fields: ['value']),
ORM\Index(fields: ['owner'], name: 'user_access_token_owner_idx'),
]
class UserAccessToken extends BaseEntity implements BaseEntityInterface, JsonSerializable
class UserAccessToken implements UuidPrimaryKeyInterface, DatedEntityInterface, JsonSerializable
{
use UuidPrimaryKeyTrait;
use DatedEntityTrait;
#[ORM\Column(name: 'value', type: Types::TEXT, unique: true, nullable: false)]
private ?string $value = null;
@ -32,6 +36,11 @@ class UserAccessToken extends BaseEntity implements BaseEntityInterface, JsonSer
]
private ?User $owner = null;
public function __construct()
{
$this->generateId();
}
public function getValue(): ?string
{
return $this->value;

View File

@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
namespace App\Doctrine\Entity;
use App\Contract\Config\AppParameters;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Uid\Uuid;
/**
* Implementation for `\App\Contract\Doctrine\Entity\UuidPrimaryKeyInterface` interface
*/
trait UuidPrimaryKeyTrait
{
#[
ORM\Id,
ORM\Column(name: 'id', type: AppParameters::DOCTRINE_COLUMN_TYPE_UUID),
]
protected Uuid $id;
public function generateId(): void
{
$this->setId(id: Uuid::v4());
}
public function getId(): Uuid
{
return $this->id;
}
public function setId(Uuid $id): void
{
$this->id = $id;
}
}

View File

@ -26,11 +26,10 @@ final class UserAccessTokenManager
public function create(User $owner, DateInterval $duration): UserAccessToken
{
$uuid = Uuid::v4();
$createdAt = $this->clock->getCurrentDateTime();
$validUntil = $createdAt->add(interval: $duration);
$token = new UserAccessToken(id: $uuid);
$token = new UserAccessToken();
$token->setOwner(owner: $owner);
$token->setValue(value: $this->generateValue());
$token->setCreatedAt(createdAt: $createdAt);

View File

@ -8,7 +8,6 @@ use App\Contract\Service\ClockInterface;
use App\Doctrine\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Uid\Uuid;
final class UserManager
{
@ -30,10 +29,9 @@ final class UserManager
string $plaintextPassword,
array $roles
): User {
$uuid = Uuid::v4();
$createdAt = $this->clock->getCurrentDateTime();
$user = new User(id: $uuid);
$user = new User();
$user->setCreatedAt(createdAt: $createdAt);
$user->setLastModifiedAt(lastModifiedAt: $createdAt);
$user->setUsername(username: $username);