Skip to content

Commit

Permalink
Merge pull request #36 from jaljo/feat/patch-endpoint
Browse files Browse the repository at this point in the history
[RFR] add an update endpoint
  • Loading branch information
jaljo authored Jul 16, 2020
2 parents 3447baf + e78715d commit b5e6c0b
Show file tree
Hide file tree
Showing 11 changed files with 205 additions and 21 deletions.
7 changes: 7 additions & 0 deletions config/routes.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ create_article:
methods: [POST]
controller: App\Application\Controller\ArticleController::create

edit_article:
path: /articles/{id}
methods: [PATCH]
controller: App\Application\Controller\ArticleController::update
requirements:
id: '[\d]+'

publish_article:
path: /articles/{id}/publish
methods: [PATCH]
Expand Down
1 change: 1 addition & 0 deletions config/services/bus.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ services:
- '@App\Domain\Command\Handler\ListArticles'
- '@App\Domain\Command\Handler\WriteArticle'
- '@App\Domain\Command\Handler\PublishArticle'
- '@App\Domain\Command\Handler\EditArticle'
5 changes: 5 additions & 0 deletions config/services/command_handlers.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,8 @@ services:
arguments:
- '@Doctrine\ORM\EntityManagerInterface'
- '@App\Application\Repository\ArticleRepository'

App\Domain\Command\Handler\EditArticle:
arguments:
- '@Doctrine\ORM\EntityManagerInterface'
- '@App\Application\Repository\ArticleRepository'
53 changes: 43 additions & 10 deletions src/Application/Controller/ArticleController.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use App\Application\JsonDefinition\Article as ArticleDefinition;
use App\Domain\Command as Command;
use App\Domain\Command\Bus\CommandBus;
use App\Domain\Exception\ResourceNotFoundException;
use Exception;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
Expand All @@ -32,7 +33,6 @@ public function __construct(
$this->formFactory = $formFactory;
}

// @todo add swager doc here
public function list(): JsonResponse
{
try {
Expand All @@ -57,27 +57,24 @@ public function list(): JsonResponse
return new JsonResponse($definitions);
}

// @todo add swager doc here
public function read(string $slug): JsonResponse
{
try {
$article = $this->bus->executeCommand(new Command\ReadArticle($slug));
}
catch (ResourceNotFoundException $exception) {
return new JsonResponse(null, Response::HTTP_NOT_FOUND);
}
catch (Exception $exception) {
return new JsonResponse(
["error" => $exception->getMessage()],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}

if (null === $article) {
return new JsonResponse(null, Response::HTTP_NOT_FOUND);
}

return new JsonResponse(new ArticleDefinition($article));
}

// @todo add swager doc here
public function create(Request $request): JsonResponse
{
$createArticle = new Command\WriteArticle();
Expand All @@ -87,7 +84,6 @@ public function create(Request $request): JsonResponse

if (!$form->isSubmitted() || !$form->isValid()) {
return new JsonResponse(
// @TODO improve this to have clearer error output
$form->getErrors(true)->__toString(),
Response::HTTP_BAD_REQUEST
);
Expand All @@ -108,11 +104,48 @@ public function create(Request $request): JsonResponse
);
}

// @todo add swager doc here
public function update(Request $request, int $id): JsonResponse
{
try {
$article = $this->bus->executeCommand(new Command\ReadArticle($id));
$editArticle = new Command\EditArticle($article);

$form = $this->formFactory->create(ArticleType::class, $editArticle);
$form->submit($request->request->all(), false);

if (!$form->isSubmitted() || !$form->isValid()) {
return new JsonResponse(
$form->getErrors(true)->__toString(),
Response::HTTP_BAD_REQUEST
);
}

$editedArticle = $this->bus->executeCommand($editArticle);
}
catch (ResourceNotFoundException $exception) {
return new JsonResponse(null, Response::HTTP_NOT_FOUND);
}
catch (Exception $exception) {
return new JsonResponse(
["error" => $exception->getMessage()],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}

return new JsonResponse(
new ArticleDefinition($editedArticle),
Response::HTTP_CREATED
);
}

public function publish(int $id): JsonResponse
{
try {
$article = $this->bus->executeCommand(new Command\PublishArticle($id));
$publishArticle = new Command\PublishArticle($id);
$article = $this->bus->executeCommand($publishArticle);
}
catch (ResourceNotFoundException $exception) {
return new JsonResponse(null, Response::HTTP_NOT_FOUND);
}
catch (Exception $exception) {
return new JsonResponse(
Expand Down
2 changes: 2 additions & 0 deletions src/Application/Controller/Endpoint.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@ public function list(): JsonResponse;
public function read(string $slug): JsonResponse;

public function create(Request $request): JsonResponse;

public function update(Request $request, int $id): JsonResponse;
}
55 changes: 55 additions & 0 deletions src/Domain/Command/EditArticle.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

namespace App\Domain\Command;

use App\Domain\Model\Article;

class EditArticle
{
/**
* @var int
*/
private $id;

/**
* @var string
*/
private $title;

/**
* @var string
*/
private $content;

public function __construct(Article $article)
{
$this->id = $article->getId();
$this->title = $article->getTitle();
$this->content = $article->getContent();
}

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

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

public function setTitle(string $title)
{
$this->title = $title;
}

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

public function setContent(string $content)
{
$this->content = $content;
}
}
52 changes: 52 additions & 0 deletions src/Domain/Command/Handler/EditArticle.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

namespace App\Domain\Command\Handler;

use App\Domain\Command\EditArticle as EditArticleCommand;
use App\Domain\Exception\ResourceNotFoundException;
use App\Domain\Model\Article;
use App\Domain\Repository\ArticleRepository;
use Doctrine\Common\Persistence\ObjectManager;

class EditArticle
{
/**
* @var ObjectManager
*/
private $manager;

/**
* @var ArticleRepository
*/
private $repository;

public function __construct(
ObjectManager $manager,
ArticleRepository $repository
) {
$this->manager = $manager;
$this->repository = $repository;
}

/**
* @throws ResourceNotFoundException
*/
public function __invoke(EditArticleCommand $command): Article
{
$article = $this->repository->findOneById($command->getId());

if ($article === null) {
throw new ResourceNotFoundException();
}

$article->edit(
$command->getTitle(),
$command->getContent()
);

$this->manager->persist($article);
$this->manager->flush();

return $article;
}
}
6 changes: 3 additions & 3 deletions src/Domain/Command/Handler/PublishArticle.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

namespace App\Domain\Command\Handler;

use App\Domain\Model\Article;
use App\Domain\Command\PublishArticle as PublishArticleCommand;
use App\Domain\Exception\ResourceNotFoundException;
use App\Domain\Model\Article;
use App\Domain\Repository\ArticleRepository;
use Doctrine\Common\Persistence\ObjectManager;

Expand Down Expand Up @@ -33,9 +33,9 @@ public function __construct(
*/
public function __invoke(PublishArticleCommand $command): Article
{
$article = $this->repository->find($command->getId());
$article = $this->repository->findOneById($command->getId());

if (null === $article) {
if ($article === null) {
throw new ResourceNotFoundException();
}

Expand Down
21 changes: 18 additions & 3 deletions src/Domain/Command/Handler/ReadArticle.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

namespace App\Domain\Command\Handler;

use App\Domain\Model\Article;
use App\Domain\Command\ReadArticle as ReadArticleCommand;
use App\Domain\Exception\ResourceNotFoundException;
use App\Domain\Model\Article;
use App\Domain\Repository\ArticleRepository;

class ReadArticle
Expand All @@ -18,8 +19,22 @@ public function __construct(ArticleRepository $repository)
$this->repository = $repository;
}

public function __invoke(ReadArticleCommand $command): ?Article
/**
* @throws ResourceNotFoundException
*/
public function __invoke(ReadArticleCommand $command): Article
{
return $this->repository->findOneBySlug($command->getSlug());
$id = $command->getId();

$article = is_numeric($id)
? $this->repository->findOneById($id)
: $this->repository->findOneBySlug($id)
;

if ($article === null) {
throw new ResourceNotFoundException();
}

return $article;
}
}
16 changes: 11 additions & 5 deletions src/Domain/Command/ReadArticle.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,23 @@
class ReadArticle
{
/**
* @var string
* @var int|string
*/
private $slug;

public function __construct(string $slug)
/**
* @param int|string
*/
public function __construct($id)
{
$this->slug = $slug;
$this->id = $id;
}

public function getSlug(): string
/**
* @return int|string
*/
public function getId()
{
return $this->slug;
return $this->id;
}
}
8 changes: 8 additions & 0 deletions src/Domain/Model/Article.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ public static function write(string $title, string $content, string $slug): self
return new self($title, $content, $slug);
}

public function edit(string $title, string $content): self
{
$this->title = $title;
$this->content = $content;

return $this;
}

public function publish(): self
{
$this->draft = false;
Expand Down

0 comments on commit b5e6c0b

Please sign in to comment.