Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Abstract creating commands from requests #375

Merged
Merged
Show file tree
Hide file tree
Changes from 6 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
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "Shop API for Sylius E-Commerce.",
"license": "MIT",
"require": {
"php": "^7.1",
"php": "^7.2",

"sylius/sylius": "^1.1",
"league/tactician-bundle": "^1.1",
Expand Down
46 changes: 46 additions & 0 deletions spec/Parser/CommandRequestParserSpec.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

declare(strict_types=1);

namespace spec\Sylius\ShopApiPlugin\Parser;

use PhpSpec\ObjectBehavior;
use Sylius\ShopApiPlugin\Exception\CannotParseCommand;
use Sylius\ShopApiPlugin\Parser\CommandRequestParserInterface;
use Sylius\ShopApiPlugin\Request\ChangeItemQuantityRequest;
use Sylius\ShopApiPlugin\Request\PickupCartRequest;
use Symfony\Component\HttpFoundation\ParameterBag;
use Symfony\Component\HttpFoundation\Request;

final class CommandRequestParserSpec extends ObjectBehavior
{
function let(): void
{
$this->beConstructedWith([
'ChangeItemQuantity' => ChangeItemQuantityRequest::class,
'PickupCart' => PickupCartRequest::class,
]);
}

function it_is_command_request(): void
Zales0123 marked this conversation as resolved.
Show resolved Hide resolved
{
$this->shouldImplement(CommandRequestParserInterface::class);
}

function it_provides_command_request_object_for_command_name(Request $request): void
{
$request->attributes = new ParameterBag([]);
$request->request = new ParameterBag([]);

$this->parse($request, 'ChangeItemQuantity')->shouldHaveType(ChangeItemQuantityRequest::class);
$this->parse($request, 'PickupCart')->shouldHaveType(PickupCartRequest::class);
}

function it_throws_exception_if_command_request_cannot_be_parsed(Request $request): void
{
$this
->shouldThrow(CannotParseCommand::withCommandName('InvalidCommand'))
->during('parse', [$request, 'InvalidCommand'])
;
}
}
4 changes: 3 additions & 1 deletion src/Controller/AddressBook/RemoveAddressAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@ public function __invoke(Request $request): Response
return $this->viewHandler->handle(View::create(null, Response::HTTP_UNAUTHORIZED));
}

$removeAddressRequest = new RemoveAddressRequest($request, $user->getEmail());
$removeAddressRequest = new RemoveAddressRequest();
$removeAddressRequest->populateData($request);
$removeAddressRequest->setUserEmail($user->getEmail());

$validationResults = $this->validator->validate($removeAddressRequest);

Expand Down
4 changes: 3 additions & 1 deletion src/Controller/AddressBook/SetDefaultAddressAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@ public function __invoke(Request $request): Response
return $this->viewHandler->handle(View::create(null, Response::HTTP_UNAUTHORIZED));
}

$setDefaultAddressRequest = new SetDefaultAddressRequest($request, $user->getEmail());
$setDefaultAddressRequest = new SetDefaultAddressRequest();
$setDefaultAddressRequest->populateData($request);
$setDefaultAddressRequest->setUserEmail($user->getEmail());

$validationResults = $this->validator->validate($setDefaultAddressRequest);

Expand Down
2 changes: 2 additions & 0 deletions src/Controller/Cart/AddCouponAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use FOS\RestBundle\View\View;
use FOS\RestBundle\View\ViewHandlerInterface;
use League\Tactician\CommandBus;
use Sylius\ShopApiPlugin\Command\AddCoupon;
use Sylius\ShopApiPlugin\Factory\ValidationErrorViewFactoryInterface;
use Sylius\ShopApiPlugin\Request\AddCouponRequest;
use Sylius\ShopApiPlugin\ViewRepository\Cart\CartViewRepositoryInterface;
Expand Down Expand Up @@ -54,6 +55,7 @@ public function __invoke(Request $request): Response

if (0 === count($validationResults)) {
$addCouponCommand = $addCouponRequest->getCommand();
assert($addCouponCommand instanceof AddCoupon);

$this->bus->handle($addCouponCommand);

Expand Down
13 changes: 10 additions & 3 deletions src/Controller/Cart/ChangeItemQuantityAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
use FOS\RestBundle\View\View;
use FOS\RestBundle\View\ViewHandlerInterface;
use League\Tactician\CommandBus;
use Sylius\ShopApiPlugin\Command\ChangeItemQuantity;
use Sylius\ShopApiPlugin\Factory\ValidationErrorViewFactoryInterface;
use Sylius\ShopApiPlugin\Request\ChangeItemQuantityRequest;
use Sylius\ShopApiPlugin\Parser\CommandRequestParserInterface;
use Sylius\ShopApiPlugin\ViewRepository\Cart\CartViewRepositoryInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
Expand All @@ -32,23 +33,28 @@ final class ChangeItemQuantityAction
/** @var CartViewRepositoryInterface */
private $cartQuery;

/** @var CommandRequestParserInterface */
private $commandRequestParser;

public function __construct(
ViewHandlerInterface $viewHandler,
CommandBus $bus,
ValidatorInterface $validator,
ValidationErrorViewFactoryInterface $validationErrorViewFactory,
CartViewRepositoryInterface $cartQuery
CartViewRepositoryInterface $cartQuery,
CommandRequestParserInterface $commandRequestParser
) {
$this->viewHandler = $viewHandler;
$this->bus = $bus;
$this->validator = $validator;
$this->validationErrorViewFactory = $validationErrorViewFactory;
$this->cartQuery = $cartQuery;
$this->commandRequestParser = $commandRequestParser;
}

public function __invoke(Request $request): Response
{
$changeItemQuantityRequest = new ChangeItemQuantityRequest($request);
$changeItemQuantityRequest = $this->commandRequestParser->parse($request, ChangeItemQuantity::class);

$validationResults = $this->validator->validate($changeItemQuantityRequest);

Expand All @@ -57,6 +63,7 @@ public function __invoke(Request $request): Response
}

$changeItemQuantityCommand = $changeItemQuantityRequest->getCommand();
assert($changeItemQuantityCommand instanceof ChangeItemQuantity);

$this->bus->handle($changeItemQuantityCommand);

Expand Down
16 changes: 11 additions & 5 deletions src/Controller/Cart/DropCartAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
use FOS\RestBundle\View\View;
use FOS\RestBundle\View\ViewHandlerInterface;
use League\Tactician\CommandBus;
use Sylius\ShopApiPlugin\Command\DropCart;
use Sylius\ShopApiPlugin\Factory\ValidationErrorViewFactoryInterface;
use Sylius\ShopApiPlugin\Request\DropCartRequest;
use Sylius\ShopApiPlugin\Parser\CommandRequestParserInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Validator\Validator\ValidatorInterface;
Expand All @@ -27,26 +28,31 @@ final class DropCartAction
/** @var ValidationErrorViewFactoryInterface */
private $validationErrorViewFactory;

/** @var CommandRequestParserInterface */
private $commandRequestParser;

public function __construct(
ViewHandlerInterface $viewHandler,
CommandBus $bus,
ValidatorInterface $validator,
ValidationErrorViewFactoryInterface $validationErrorViewFactory
ValidationErrorViewFactoryInterface $validationErrorViewFactory,
CommandRequestParserInterface $commandRequestParser
) {
$this->viewHandler = $viewHandler;
$this->bus = $bus;
$this->validator = $validator;
$this->validationErrorViewFactory = $validationErrorViewFactory;
$this->commandRequestParser = $commandRequestParser;
}

public function __invoke(Request $request): Response
{
$pickupRequest = new DropCartRequest($request);
$dropCartRequest = $this->commandRequestParser->parse($request, DropCart::class);

$validationResults = $this->validator->validate($pickupRequest);
$validationResults = $this->validator->validate($dropCartRequest);

if (0 === count($validationResults)) {
$this->bus->handle($pickupRequest->getCommand());
$this->bus->handle($dropCartRequest->getCommand());

return $this->viewHandler->handle(View::create(null, Response::HTTP_NO_CONTENT));
}
Expand Down
13 changes: 10 additions & 3 deletions src/Controller/Cart/PickupAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
use FOS\RestBundle\View\View;
use FOS\RestBundle\View\ViewHandlerInterface;
use League\Tactician\CommandBus;
use Sylius\ShopApiPlugin\Command\PickupCart;
use Sylius\ShopApiPlugin\Factory\ValidationErrorViewFactoryInterface;
use Sylius\ShopApiPlugin\Request\PickupCartRequest;
use Sylius\ShopApiPlugin\Parser\CommandRequestParserInterface;
use Sylius\ShopApiPlugin\ViewRepository\Cart\CartViewRepositoryInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
Expand All @@ -32,28 +33,34 @@ final class PickupAction
/** @var CartViewRepositoryInterface */
private $cartQuery;

/** @var CommandRequestParserInterface */
private $commandRequestParser;

public function __construct(
ViewHandlerInterface $viewHandler,
CommandBus $bus,
ValidatorInterface $validator,
ValidationErrorViewFactoryInterface $validationErrorViewFactory,
CartViewRepositoryInterface $cartQuery
CartViewRepositoryInterface $cartQuery,
CommandRequestParserInterface $commandRequestParser
) {
$this->viewHandler = $viewHandler;
$this->bus = $bus;
$this->validator = $validator;
$this->validationErrorViewFactory = $validationErrorViewFactory;
$this->cartQuery = $cartQuery;
$this->commandRequestParser = $commandRequestParser;
}

public function __invoke(Request $request): Response
{
$pickupRequest = new PickupCartRequest($request);
$pickupRequest = $this->commandRequestParser->parse($request, PickupCart::class);

$validationResults = $this->validator->validate($pickupRequest);

if (0 === count($validationResults)) {
$pickupCartCommand = $pickupRequest->getCommand();
assert($pickupCartCommand instanceof PickupCart);

$this->bus->handle($pickupCartCommand);

Expand Down
31 changes: 21 additions & 10 deletions src/Controller/Cart/PutItemToCartAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@
use FOS\RestBundle\View\View;
use FOS\RestBundle\View\ViewHandlerInterface;
use League\Tactician\CommandBus;
use Sylius\ShopApiPlugin\Command\PutOptionBasedConfigurableItemToCart;
use Sylius\ShopApiPlugin\Command\PutSimpleItemToCart;
use Sylius\ShopApiPlugin\Command\PutVariantBasedConfigurableItemToCart;
use Sylius\ShopApiPlugin\Factory\ValidationErrorViewFactoryInterface;
use Sylius\ShopApiPlugin\Normalizer\RequestCartTokenNormalizerInterface;
use Sylius\ShopApiPlugin\Request\PutOptionBasedConfigurableItemToCartRequest;
use Sylius\ShopApiPlugin\Request\PutSimpleItemToCartRequest;
use Sylius\ShopApiPlugin\Request\PutVariantBasedConfigurableItemToCartRequest;
use Sylius\ShopApiPlugin\Parser\CommandRequestParserInterface;
use Sylius\ShopApiPlugin\Request\CommandRequestInterface;
use Sylius\ShopApiPlugin\ViewRepository\Cart\CartViewRepositoryInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
Expand Down Expand Up @@ -39,20 +41,25 @@ final class PutItemToCartAction
/** @var RequestCartTokenNormalizerInterface */
private $requestCartTokenNormalizer;

/** @var CommandRequestParserInterface */
private $commandRequestParser;

public function __construct(
ViewHandlerInterface $viewHandler,
CommandBus $bus,
ValidatorInterface $validator,
ValidationErrorViewFactoryInterface $validationErrorViewFactory,
CartViewRepositoryInterface $cartQuery,
RequestCartTokenNormalizerInterface $requestCartTokenNormalizer
RequestCartTokenNormalizerInterface $requestCartTokenNormalizer,
CommandRequestParserInterface $commandRequestParser
) {
$this->viewHandler = $viewHandler;
$this->bus = $bus;
$this->validator = $validator;
$this->validationErrorViewFactory = $validationErrorViewFactory;
$this->cartQuery = $cartQuery;
$this->requestCartTokenNormalizer = $requestCartTokenNormalizer;
$this->commandRequestParser = $commandRequestParser;
}

public function __invoke(Request $request): Response
Expand All @@ -64,7 +71,6 @@ public function __invoke(Request $request): Response
}

$commandRequest = $this->provideCommandRequest($request);

$validationResults = $this->validator->validate($commandRequest);

if (0 !== count($validationResults)) {
Expand All @@ -76,6 +82,12 @@ public function __invoke(Request $request): Response
}

$command = $commandRequest->getCommand();
assert(
$command instanceof PutSimpleItemToCart ||
$command instanceof PutVariantBasedConfigurableItemToCart ||
$command instanceof PutOptionBasedConfigurableItemToCart
);

$this->bus->handle($command);

try {
Expand All @@ -87,22 +99,21 @@ public function __invoke(Request $request): Response
}
}

/** @return PutOptionBasedConfigurableItemToCartRequest|PutSimpleItemToCartRequest|PutVariantBasedConfigurableItemToCartRequest */
private function provideCommandRequest(Request $request)
private function provideCommandRequest(Request $request): CommandRequestInterface
{
$hasVariantCode = $request->request->has('variantCode');
$hasOptionCode = $request->request->has('options');

if (!$hasVariantCode && !$hasOptionCode) {
return PutSimpleItemToCartRequest::fromRequest($request);
return $this->commandRequestParser->parse($request, PutSimpleItemToCart::class);
}

if ($hasVariantCode && !$hasOptionCode) {
return PutVariantBasedConfigurableItemToCartRequest::fromRequest($request);
return $this->commandRequestParser->parse($request, PutVariantBasedConfigurableItemToCart::class);
}

if (!$hasVariantCode && $hasOptionCode) {
return PutOptionBasedConfigurableItemToCartRequest::fromRequest($request);
return $this->commandRequestParser->parse($request, PutOptionBasedConfigurableItemToCart::class);
}

throw new NotFoundHttpException('Variant not found for given configuration');
Expand Down
5 changes: 3 additions & 2 deletions src/Controller/Cart/PutItemsToCartAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use FOS\RestBundle\View\ViewHandlerInterface;
use League\Tactician\CommandBus;
use Sylius\ShopApiPlugin\Normalizer\RequestCartTokenNormalizerInterface;
use Sylius\ShopApiPlugin\Request\CommandRequestInterface;
use Sylius\ShopApiPlugin\Request\PutOptionBasedConfigurableItemToCartRequest;
use Sylius\ShopApiPlugin\Request\PutSimpleItemToCartRequest;
use Sylius\ShopApiPlugin\Request\PutVariantBasedConfigurableItemToCartRequest;
Expand Down Expand Up @@ -74,6 +75,7 @@ public function __invoke(Request $request): Response

foreach ($request->request->get('items') as $item) {
$item['token'] = $token;

$commandRequests[] = $this->provideCommandRequest($item);
}

Expand Down Expand Up @@ -121,8 +123,7 @@ public function __invoke(Request $request): Response
}
}

/** @return PutOptionBasedConfigurableItemToCartRequest|PutSimpleItemToCartRequest|PutVariantBasedConfigurableItemToCartRequest */
private function provideCommandRequest(array $item)
private function provideCommandRequest(array $item): CommandRequestInterface
{
$hasVariantCode = isset($item['variantCode']);
$hasOptions = isset($item['options']);
Expand Down
Loading