From 5d2621e43351fbba02e7bb9b9116306d1b9aacb7 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Wed, 24 Oct 2018 15:59:30 +0200 Subject: [PATCH] Integrated doctrine ORM with the repository infrastructure Specifically: * introduced DBAL types for domain value types * mapped the `EmailAddress` to be a stringable - required by `Doctrine\ORM\UnitOfWork` --- bootstrap.php | 10 +++- ... => Authentication.Aggregate.User.dcm.xml} | 4 +- public/login.php | 8 ++- public/register.php | 7 ++- src/Authentication/Value/EmailAddress.php | 5 ++ .../DBAL/Type/EmailAddressType.php | 36 +++++++++++++ .../DBAL/Type/PasswordHashType.php | 36 +++++++++++++ .../Repository/DoctrineUsers.php | 51 +++++++++++++++++++ 8 files changed, 151 insertions(+), 6 deletions(-) rename mapping/{Authentication.Entity.User.dcm.xml => Authentication.Aggregate.User.dcm.xml} (58%) create mode 100644 src/Infrastructure/Authentication/DBAL/Type/EmailAddressType.php create mode 100644 src/Infrastructure/Authentication/DBAL/Type/PasswordHashType.php create mode 100644 src/Infrastructure/Authentication/Repository/DoctrineUsers.php diff --git a/bootstrap.php b/bootstrap.php index 392723d..be63607 100644 --- a/bootstrap.php +++ b/bootstrap.php @@ -1,10 +1,15 @@ setAutoGenerateProxyClasses(ProxyFactory::AUTOGENERATE_ALWAYS); +$configuration->setAutoGenerateProxyClasses(ProxyFactory::AUTOGENERATE_EVAL); + +Type::addType(EmailAddress::class, EmailAddressType::class); +Type::addType(PasswordHash::class, PasswordHashType::class); // Finally creating the EntityManager: our entry point for the ORM return EntityManager::create( diff --git a/mapping/Authentication.Entity.User.dcm.xml b/mapping/Authentication.Aggregate.User.dcm.xml similarity index 58% rename from mapping/Authentication.Entity.User.dcm.xml rename to mapping/Authentication.Aggregate.User.dcm.xml index 2d8fe8d..e840e9a 100644 --- a/mapping/Authentication.Entity.User.dcm.xml +++ b/mapping/Authentication.Aggregate.User.dcm.xml @@ -4,6 +4,8 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping ../vendor/doctrine/orm/doctrine-mapping.xsd" > - + + + diff --git a/public/login.php b/public/login.php index 12573bb..3625391 100644 --- a/public/login.php +++ b/public/login.php @@ -1,9 +1,10 @@ getRepository(User::class)); if (! $users->exists($email)) { echo 'Nope'; diff --git a/public/register.php b/public/register.php index ead6b62..f11e0cc 100644 --- a/public/register.php +++ b/public/register.php @@ -4,14 +4,17 @@ use Authentication\Value\ClearTextPassword; use Authentication\Value\EmailAddress; use Infrastructure\Authentication\ReadModel\CheckRegisteredEmailFromRepository; -use Infrastructure\Authentication\Repository\FilesystemUsers; +use Infrastructure\Authentication\Repository\DoctrineUsers; require_once __DIR__ . '/../vendor/autoload.php'; $email = EmailAddress::fromEmailAddress($_POST['emailAddress']); $password = ClearTextPassword::fromInputPassword($_POST['password']); -$users = new FilesystemUsers(__DIR__ . '/../data/users.json'); +/** @var \Doctrine\ORM\EntityManager $entityManager */ +$entityManager = require __DIR__ . '/../bootstrap.php'; + +$users = new DoctrineUsers($entityManager, $entityManager->getRepository(User::class)); $users->store(User::register($email, $password, new CheckRegisteredEmailFromRepository($users))); diff --git a/src/Authentication/Value/EmailAddress.php b/src/Authentication/Value/EmailAddress.php index de623e2..f0bb6aa 100644 --- a/src/Authentication/Value/EmailAddress.php +++ b/src/Authentication/Value/EmailAddress.php @@ -31,4 +31,9 @@ public function toString() : string { return $this->email; } + + public function __toString() : string + { + return $this->email; + } } diff --git a/src/Infrastructure/Authentication/DBAL/Type/EmailAddressType.php b/src/Infrastructure/Authentication/DBAL/Type/EmailAddressType.php new file mode 100644 index 0000000..fd9c444 --- /dev/null +++ b/src/Infrastructure/Authentication/DBAL/Type/EmailAddressType.php @@ -0,0 +1,36 @@ +toString(), $platform); + } + + public function requiresSQLCommentHint(AbstractPlatform $platform) + { + return true; + } + + public function getName() + { + return EmailAddress::class; + } +} diff --git a/src/Infrastructure/Authentication/DBAL/Type/PasswordHashType.php b/src/Infrastructure/Authentication/DBAL/Type/PasswordHashType.php new file mode 100644 index 0000000..ea28ff8 --- /dev/null +++ b/src/Infrastructure/Authentication/DBAL/Type/PasswordHashType.php @@ -0,0 +1,36 @@ +toString(), $platform); + } + + public function requiresSQLCommentHint(AbstractPlatform $platform) + { + return true; + } + + public function getName() + { + return PasswordHash::class; + } +} diff --git a/src/Infrastructure/Authentication/Repository/DoctrineUsers.php b/src/Infrastructure/Authentication/Repository/DoctrineUsers.php new file mode 100644 index 0000000..a117020 --- /dev/null +++ b/src/Infrastructure/Authentication/Repository/DoctrineUsers.php @@ -0,0 +1,51 @@ +objectManager = $objectManager; + $this->repository = $repository; + } + + public function exists(EmailAddress $emailAddress) : bool + { + return (bool) $this->repository->find($emailAddress); + } + + public function get(EmailAddress $emailAddress) : User + { + $user = $this->repository->find($emailAddress); + + if (! $user instanceof User) { + throw new \RuntimeException(sprintf( + 'User %s does not exist', + $emailAddress->toString() + )); + } + + return $user; + } + + public function store(User $user) : void + { + $this->objectManager->persist($user); + $this->objectManager->flush(); + } +}