Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
Empty file removed public/app/.gitignore
Empty file.
38 changes: 38 additions & 0 deletions public/app/blog-post/edit.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

declare(strict_types=1);

use Solid\App\BlogPost\Application\Find\FindUseCase;
use Solid\App\BlogPost\Application\Modify\ModifyUseCase;
use Solid\App\BlogPost\Domain\Service\Factory;
use Solid\App\BlogPost\Infrastructure\Normalizer\ReflectionNormalizer;
use Solid\App\BlogPost\Infrastructure\Persistence\Storage\FileStorage;
use Solid\App\BlogPost\Presentation\Controller\EditAction;
use Solid\App\BlogPost\Presentation\Renderer\HtmlRenderer;
use Solid\App\Shared\Domain\Exception\FormatExceptionRenderer;
use Solid\App\Shared\Domain\Exception\HtmlExceptionRenderer;
use Solid\App\Shared\Domain\Exception\JsonExceptionRenderer;

require __DIR__.'/../../../vendor/autoload.php';

$storageDir = __DIR__.'/../../../var/data';
$storage = new FileStorage(
new ReflectionNormalizer(),
$storageDir,
);
$action = new EditAction(
new FindUseCase(
$storage,
),
new ModifyUseCase(
new Factory(),
$storage,
),
new HtmlRenderer(),
);

try {
$action((int) ($_GET['id'] ?? 0));
} catch (RuntimeException $exception) {
(new HtmlExceptionRenderer())->render($exception);
}
25 changes: 25 additions & 0 deletions public/app/blog-post/list.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types=1);

use Solid\App\BlogPost\Application\Search\SearchUseCase;
use Solid\App\BlogPost\Infrastructure\Normalizer\ReflectionNormalizer;
use Solid\App\BlogPost\Infrastructure\Persistence\Storage\FileStorage;
use Solid\App\BlogPost\Presentation\Controller\ListAction;
use Solid\App\BlogPost\Presentation\Renderer\HtmlRenderer;

require __DIR__.'/../../../vendor/autoload.php';

$storageDir = __DIR__.'/../../../var/data';
$storage = new FileStorage(
new ReflectionNormalizer(),
$storageDir,
);
$action = new ListAction(
new SearchUseCase(
$storage,
),
new HtmlRenderer(),
);

$action();
27 changes: 27 additions & 0 deletions public/app/blog-post/new.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

use Solid\App\BlogPost\Application\Create\CreateUseCase;
use Solid\App\BlogPost\Domain\Service\Factory;
use Solid\App\BlogPost\Infrastructure\Normalizer\ReflectionNormalizer;
use Solid\App\BlogPost\Infrastructure\Persistence\Storage\FileStorage;
use Solid\App\BlogPost\Presentation\Controller\NewAction;
use Solid\App\BlogPost\Presentation\Renderer\HtmlRenderer;

require __DIR__.'/../../../vendor/autoload.php';

$storageDir = __DIR__.'/../../../var/data';
$storage = new FileStorage(
new ReflectionNormalizer(),
$storageDir,
);
$action = new NewAction(
new CreateUseCase(
new Factory(),
$storage,
),
new HtmlRenderer(),
);

$action();
45 changes: 45 additions & 0 deletions public/app/blog-post/show.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

declare(strict_types=1);

use Solid\App\BlogPost\Application\Find\FindUseCase;
use Solid\App\BlogPost\Infrastructure\Normalizer\ReflectionNormalizer;
use Solid\App\BlogPost\Infrastructure\Persistence\Storage\FileStorage;
use Solid\App\BlogPost\Presentation\Controller\ShowAction;
use Solid\App\BlogPost\Presentation\Renderer\HtmlRenderer;
use Solid\App\BlogPost\Presentation\Renderer\JsonRenderer;
use Solid\App\BlogPost\Presentation\Renderer\FormatRenderer;
use Solid\App\Shared\Domain\Exception\FormatExceptionRenderer;
use Solid\App\Shared\Domain\Exception\HtmlExceptionRenderer;
use Solid\App\Shared\Domain\Exception\JsonExceptionRenderer;

require __DIR__.'/../../../vendor/autoload.php';

$storageDir = __DIR__.'/../../../var/data';
$normalizer = new ReflectionNormalizer();
$storage = new FileStorage(
$normalizer,
$storageDir,
);
$action = new ShowAction(
new FindUseCase(
$storage,
),
new FormatRenderer([
'html' => new HtmlRenderer(),
'json' => new JsonRenderer(
$normalizer,
),
]),
);
$formatExceptionRenderer = new FormatExceptionRenderer([
'html' => new HtmlExceptionRenderer(),
'json' => new JsonExceptionRenderer(),
]);
$format = $_GET['format'] ?? 'html';

try {
$action((int) ($_GET['id'] ?? 0), $format);
} catch (RuntimeException $exception) {
$formatExceptionRenderer->render($exception, $format);
}
Empty file removed src/App/.gitignore
Empty file.
28 changes: 28 additions & 0 deletions src/App/BlogPost/Application/Create/CreateUseCase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace Solid\App\BlogPost\Application\Create;

use Solid\App\BlogPost\Domain\Model\BlogPost;
use Solid\App\BlogPost\Domain\Model\Storage;
use Solid\App\BlogPost\Domain\Service\Factory;

class CreateUseCase
{
public function __construct(
private readonly Factory $factory,
private readonly Storage $storage,
) {
}

public function execute(): BlogPost
{
$blogPost = $this->factory->create();

$this->storage->persist($blogPost);
$this->storage->flush();

return $blogPost;
}
}
28 changes: 28 additions & 0 deletions src/App/BlogPost/Application/Find/FindUseCase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace Solid\App\BlogPost\Application\Find;

use Solid\App\BlogPost\Domain\Model\BlogPost;
use Solid\App\BlogPost\Domain\Model\BlogPostNotFound;
use Solid\App\BlogPost\Domain\Model\Storage;

class FindUseCase
{
public function __construct(
private readonly Storage $storage,
) {
}

public function execute(int $id): BlogPost
{
$blogPost = $this->storage->findOne($id);

if (null === $blogPost) {
throw BlogPostNotFound::create();
}

return $blogPost;
}
}
28 changes: 28 additions & 0 deletions src/App/BlogPost/Application/Modify/ModifyUseCase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace Solid\App\BlogPost\Application\Modify;

use Solid\App\BlogPost\Domain\Model\BlogPost;
use Solid\App\BlogPost\Domain\Model\Storage;
use Solid\App\BlogPost\Domain\Service\Factory;

class ModifyUseCase
{
public function __construct(
private readonly Factory $factory,
private readonly Storage $storage,
) {
}

public function execute(BlogPost $blogPost): void
{
$newSample = $this->factory->create();

$blogPost->changeTitle($newSample->title());
$blogPost->changeContent($newSample->content());

$this->storage->flush();
}
}
24 changes: 24 additions & 0 deletions src/App/BlogPost/Application/Search/SearchUseCase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

declare(strict_types=1);

namespace Solid\App\BlogPost\Application\Search;

use Solid\App\BlogPost\Domain\Model\BlogPost;
use Solid\App\BlogPost\Domain\Model\Storage;

class SearchUseCase
{
public function __construct(
private readonly Storage $storage,
) {
}

/**
* @return iterable<BlogPost>
*/
public function execute(): iterable
{
return $this->storage->findAll();
}
}
71 changes: 71 additions & 0 deletions src/App/BlogPost/Domain/Model/BlogPost.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php

declare(strict_types=1);

namespace Solid\App\BlogPost\Domain\Model;

use DateTimeImmutable;

class BlogPost
{
private DateTimeImmutable $createdAt;
private ?DateTimeImmutable $updatedAt = null;

public static function create(int $id, string $author, string $title, string $content): self
{
$self = new self($id, $author, $title, $content);
$self->createdAt = new DateTimeImmutable();

return $self;
}

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

public function author(): string
{
return $this->author;
}

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

public function changeTitle(string $title): void
{
$this->title = $title;
$this->updatedAt = new DateTimeImmutable();
}

public function content(): string
{
return $this->content;
}

public function changeContent(string $content): void
{
$this->content = $content;
$this->updatedAt = new DateTimeImmutable();
}

public function createdAt(): DateTimeImmutable
{
return $this->createdAt;
}

public function updatedAt(): ?DateTimeImmutable
{
return $this->updatedAt;
}

private function __construct(
private readonly int $id,
private readonly string $author,
private string $title,
private string $content,
) {
}
}
15 changes: 15 additions & 0 deletions src/App/BlogPost/Domain/Model/BlogPostNotFound.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

declare(strict_types=1);

namespace Solid\App\BlogPost\Domain\Model;

use RuntimeException;

final class BlogPostNotFound extends RuntimeException
{
public static function create(string $message = 'Blog post not found.'): self
{
return new self($message);
}
}
12 changes: 12 additions & 0 deletions src/App/BlogPost/Domain/Model/Normalizer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare(strict_types=1);

namespace Solid\App\BlogPost\Domain\Model;

interface Normalizer
{
public function normalize(BlogPost $blogPost): array;

public function denormalize(array $data): BlogPost;
}
19 changes: 19 additions & 0 deletions src/App/BlogPost/Domain/Model/Storage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

declare(strict_types=1);

namespace Solid\App\BlogPost\Domain\Model;

interface Storage
{
public function findOne(int $id): ?BlogPost;

/**
* @return iterable<BlogPost>
*/
public function findAll(): iterable;

public function persist(BlogPost $blogPost): void;

public function flush(): void;
}
22 changes: 22 additions & 0 deletions src/App/BlogPost/Domain/Service/Factory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

namespace Solid\App\BlogPost\Domain\Service;

use Solid\App\BlogPost\Domain\Model\BlogPost;

class Factory
{
public function create(): BlogPost
{
$loripsum = explode("\n", file_get_contents('https://loripsum.net/api/1/long/headers'));

return BlogPost::create(
id: random_int(1, 1000),
author: 'John Doe',
title: strip_tags($loripsum[0]),
content: strip_tags($loripsum[2]),
);
}
}
Loading