Add an Entity trait, format the example RSS feed, work on the Repository patterns.

This commit is contained in:
Dave Smith-Hayes 2024-05-23 21:24:57 -04:00
parent 75bccb789d
commit b908dc6ea3
7 changed files with 167 additions and 13 deletions

43
app/src/Domain/Entity.php Normal file
View File

@ -0,0 +1,43 @@
<?php
namespace Slovocast\Domain;
use DateTime;
use DateTimeImmutable;
trait Entity
{
protected int $id;
protected DateTimeImmutable $createdAt;
protected DateTime $updatedAt;
public function setId(int $id): void
{
$this->id = $id;
}
public function getId(): int
{
return $this->id;
}
public function setCreatedAt(DateTimeImmutable $createdAt): void
{
$this->createdAt = $createdAt;
}
public function getCreatedAt(): DateTimeImmutable
{
return $this->createdAt;
}
public function setUpdatedAt(DateTime $updatedAt): void
{
$this->updatedAt = $updatedAt;
}
public function getUpdatedAt(): DateTime
{
return $this->updatedAt;
}
}

View File

@ -1,6 +1,6 @@
<?php <?php
namespace Slovocast\Domain\Model; namespace Slovocast\Domain\Entity;
class Channel class Channel
{ {

View File

@ -1,19 +1,18 @@
<?php <?php
namespace Slovocast\Domain\Model; namespace Slovocast\Domain\Entity;
use Slovocast\Domain\Entity;
class User class User
{ {
use Entity;
public function __construct( public function __construct(
private readonly ?int $id,
private string $email, private string $email,
private string $password, private string $password,
private string $name private string $name
) { ) { }
$this->email = $email;
$this->password = $password;
$this->name;
}
public function getEmail(): string public function getEmail(): string
{ {
@ -37,7 +36,7 @@ class User
*/ */
public function isNew(): bool public function isNew(): bool
{ {
return (bool) $this->id; return (bool) $this->getId();
} }
/** /**
@ -46,11 +45,19 @@ class User
*/ */
public static function fromArray(array $props): User public static function fromArray(array $props): User
{ {
return new self( $user = new self(
$props['id'] ?? null,
$props['email'], $props['email'],
$props['password'], $props['password'],
$props['name'] $props['name']
); );
if ($props['id']) {
$user->setId($props['id']);
}
$user->setCreatedAt($props['createdAt']);
$user->setUpdatedAt($props['updatedAt']);
return $user;
} }
} }

View File

@ -0,0 +1,79 @@
<?php
namespace Slovocast\Domain\Repository;
use Slovocast\Infrastructure\DatabaseConnectionInterface;
use Slovocast\Exception\EntityNotFoundException;
use Slovocast\Domain\Entity\User;
use PDO;
class UserRepository implements UserRepositoryInterface
{
public function __construct(
private DatabaseConnectionInterface $database
) {}
/**
* @param array $results The Query Results asking for all properties from
* the database tables.
* @return User
*/
protected function userFromQueryResults(array $results): User
{
return User::fromArray([
'id' => $results['id'],
'email' => $results['email'],
'password' => $results['password'],
'name' => $results['name'],
'createdAt' => $results['created_at'],
'updatedAt' => $results['updated_at']
]);
}
/**
* @param string $query The Query for getting a User
* @param arary $params The parameters in the query
* @param PDO $connection The PDO connection
* @return array The column data from the Database
* @throws EntityNotFoundException The User does no exist
*/
protected function queryForUser(
string $query,
array $params,
PDO $connection
): array {
$statement = $connection->prepare($query);
$statement->execute($params);
$results = $statement->fetchAll();
if (!$results) {
throw new EntityNotFoundException("Unable to find User");
}
return array_shift($results);
}
public function get(int $id): User
{
$query = "SELECT * FROM users WHERE id = :id LIMIT 1";
$connection = $this->database->getConnection();
$userData = $this->queryForUser(
$query,
[ 'id' => $id ],
$connection
);
return $this->userFromQueryResults($userData);
}
public function getFromEmail(string $email): User
{
$query = "SELECT * FROM users WHERE email = :email LIMIT 1";
$connection = $this->database->getConnection();
$userData = $this->queryForUser(
$query,
[ 'email' => $email ],
$connection
);
return $this->userFromQueryResults($userData);
}
}

View File

@ -0,0 +1,13 @@
<?php
namespace Slovocast\Domain\Repository;
use Slovocast\Domain\Model\User;
interface UserRepositoryInterface
{
public function get(int $id): User;
public function getFromEmail(string $email): User;
public function save(User $user): bool;
public function update(User $user): bool;
}

View File

@ -0,0 +1,7 @@
<?php
namespace Slovocast\Exception;
use Exception;
class EntityNotFoundException extends Exception { }

View File

@ -53,8 +53,12 @@
<comments>https://kevyscountrybreakfast.podbean.com/e/episode-5-sarasota-sizzle/#comments</comments> <comments>https://kevyscountrybreakfast.podbean.com/e/episode-5-sarasota-sizzle/#comments</comments>
<pubDate>Tue, 12 May 2020 21:30:08 -0300</pubDate> <pubDate>Tue, 12 May 2020 21:30:08 -0300</pubDate>
<guid isPermaLink="false">kevyscountrybreakfast.podbean.com/d7b42df5-ecf9-593a-803f-40d3a054cc6f</guid> <guid isPermaLink="false">kevyscountrybreakfast.podbean.com/d7b42df5-ecf9-593a-803f-40d3a054cc6f</guid>
<description><![CDATA[<p>Ah, the sounds of spring. Birds chirping, dogs grilling, and the triumphant return of Kevys Country Breakfast. Join us for an all access guided tour as the Princes of Pod prepare to reclaim their crown of audio royalty. Plus, Taiwanese Baseball and Daves perverted palate.</p>]]></description> <description>
<content:encoded><![CDATA[<p>Ah, the sounds of spring. Birds chirping, dogs grilling, and the triumphant return of Kevys Country Breakfast. Join us for an all access guided tour as the Princes of Pod prepare to reclaim their crown of audio royalty. Plus, Taiwanese Baseball and Daves perverted palate.</p>]]></content:encoded> <![CDATA[<p>Ah, the sounds of spring. Birds chirping, dogs grilling, and the triumphant return of Kevys Country Breakfast. Join us for an all access guided tour as the Princes of Pod prepare to reclaim their crown of audio royalty. Plus, Taiwanese Baseball and Daves perverted palate.</p>]]>
</description>
<content:encoded>
<![CDATA[<p>Ah, the sounds of spring. Birds chirping, dogs grilling, and the triumphant return of Kevys Country Breakfast. Join us for an all access guided tour as the Princes of Pod prepare to reclaim their crown of audio royalty. Plus, Taiwanese Baseball and Daves perverted palate.</p>]]>
</content:encoded>
<enclosure url="https://mcdn.podbean.com/mf/web/sby3om/kcb-episode-5-demo-cut-14.mp3" length="49453453" type="audio/mpeg"/> <enclosure url="https://mcdn.podbean.com/mf/web/sby3om/kcb-episode-5-demo-cut-14.mp3" length="49453453" type="audio/mpeg"/>
@ -68,6 +72,7 @@
<itunes:episodeType>full</itunes:episodeType> <itunes:episodeType>full</itunes:episodeType>
<itunes:image href="https://pbcdn1.podbean.com/imglogo/image-logo/4943691/kcb-banner.jpg" /> <itunes:image href="https://pbcdn1.podbean.com/imglogo/image-logo/4943691/kcb-banner.jpg" />
</item> </item>
<item> <item>
<title>Episode #4: Oh Barry, Where Art Thou?</title> <title>Episode #4: Oh Barry, Where Art Thou?</title>
<itunes:title>Episode #4: Oh Barry, Where Art Thou?</itunes:title> <itunes:title>Episode #4: Oh Barry, Where Art Thou?</itunes:title>