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

ShoppingException を使用する #156

Open
wants to merge 2 commits into
base: next-poc
Choose a base branch
from
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
44 changes: 44 additions & 0 deletions GraphQL/Error/ShoppingException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

/*
* This file is part of EC-CUBE
*
* Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
*
* http://www.ec-cube.co.jp/
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Plugin\Api42\GraphQL\Error;

use GraphQL\Error\ClientAware;
use GraphQL\Error\Error;
use GraphQL\Language\Source;

class ShoppingException extends Error implements ClientAware
{
public function __construct(
$message = '',
$nodes = null,
?Source $source = null,
array $positions = [],
$path = null,
$previous = null,
array $extensions = []
) {
$extensions['level'] = Level::Danger;
parent::__construct($message, $nodes, $source, $positions, $path, $previous, $extensions);
}

public function isClientSafe()
{
return true;
}

public function getCategory()
{
return Category::Global;
}
}
17 changes: 11 additions & 6 deletions GraphQL/Mutation/AbstractMutation.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ protected function getInputObject(FormInterface $form): InputObjectType
{
$fields = [];
$this->convertArgs($form, $fields);

return new InputObjectType([
'name' => $form->getName().'Input',
'fields' => $fields,
Expand Down Expand Up @@ -133,16 +134,18 @@ protected function convertArgs(FormInterface $form, array &$args = []): void

public function getMutation(): array
{
$args = [];
$builder = $this->formFactory->createBuilder($this->getArgsType(), null, ['csrf_protection' => false]);
$form = $builder->getForm();
if ($form->getName() !== 'form') {
$args['input'] = [
'type' => $this->getInputObject($form),
];
}

return [
'type' => $this->types->get($this->getTypesClass()),
'args' => [
'input' => [
'type' => $this->getInputObject($form),
],
],
'args' => $args,
'resolve' => function ($value, array $args, $context, ResolveInfo $info) use ($form) {
return $this->resolver($value, $args, $context, $info, $form);
}
Expand Down Expand Up @@ -198,7 +201,9 @@ protected function convertFormValues(FormInterface $form, &$formValues = [], $i
protected function resolver($value, array $args, $context, ResolveInfo $info, FormInterface $form): mixed
{
$formValues = [];
$this->convertFormValues($form, $formValues, $args['input']);
if (array_key_exists('input', $args)) {
$this->convertFormValues($form, $formValues, $args['input']);
}

$form->submit($formValues);
if (!$form->isValid()) {
Expand Down
12 changes: 7 additions & 5 deletions GraphQL/Mutation/PaymentMethodMutation.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
use Eccube\Service\CartService;
use Eccube\Service\OrderHelper;
use GraphQL\Type\Definition\Type;
use Plugin\Api42\GraphQL\Error\InvalidArgumentException;
use Plugin\Api42\GraphQL\Error\ShoppingException;
use Plugin\Api42\GraphQL\Mutation;
use Plugin\Api42\GraphQL\Types;

Expand Down Expand Up @@ -70,16 +70,18 @@ public function paymentMethodMutation($root, $args)
/** @var Order|null $Order */
$Order = $this->orderHelper->getPurchaseProcessingOrder($preOrderId);
if (!$Order) {
log_info('[注文確認] 購入処理中の受注が存在しません.', [$preOrderId]);
throw new InvalidArgumentException();
$message = '[注文確認] 購入処理中の受注が存在しません.';
log_info($message, [$preOrderId]);
throw new ShoppingException($message);
}

if (!empty($args['payment_method_id'])) {
/** @var Payment|null $Payment */
$Payment = $this->entityManager->find(Payment::class, $args['payment_method_id']);
if (!$Payment) {
log_info('[注文確認] 支払い方法が存在しません.', [$args['payment_method_id']]);
throw new InvalidArgumentException();
$message = '[注文確認] 支払い方法が存在しません.';
log_info($message, [$args['payment_method_id']]);
throw new ShoppingException($message);
}
log_info('[注文確認] 支払い方法を変更します.', [$Payment->getMethod()]);
$Order->setPayment($Payment);
Expand Down
48 changes: 26 additions & 22 deletions GraphQL/Mutation/PurchaseMutation.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,12 @@
use Eccube\Service\PurchaseFlow\PurchaseFlow;
use Eccube\Service\PurchaseFlow\PurchaseFlowResult;
use Plugin\Api42\GraphQL\Error\InvalidArgumentException;
use Plugin\Api42\GraphQL\Mutation;
use Plugin\Api42\GraphQL\Types;
use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\Form\FormFactoryInterface;

class PurchaseMutation implements Mutation
class PurchaseMutation extends AbstractMutation
{
private Types $types;

private EntityManager $entityManager;
private CartService $cartService;
private OrderHelper $orderHelper;
Expand All @@ -55,49 +54,54 @@ public function __construct(
PurchaseFlow $cartPurchaseFlow,
PaymentMethodLocator $locator,
MailService $mailService,
FormFactoryInterface $formFactory,
) {
$this->types = $types;
$this->entityManager = $entityManager;
$this->cartService = $cartService;
$this->orderHelper = $orderHelper;
$this->securityContext = $securityContext;
$this->cartPurchaseFlow = $cartPurchaseFlow;
$this->locator = $locator;
$this->mailService = $mailService;
$this->setTypes($types);
$this->setFormFactory($formFactory);
}

public function getName(): string
{
return 'purchaseMutation';
}

public function getMutation(): array
public function getTypesClass(): string
{
return Order::class;
}

public function getArgsType(): string
{
return [
'type' => $this->types->get(Order::class),
'args' => [],
'resolve' => [$this, 'purchaseMutation'],
];
return FormType::class;
}

public function purchaseMutation()
public function executeMutation($root, array $args): mixed
{
$Customer = $this->securityContext->getLoginUser();
if (!$Customer instanceof Customer) {
throw new InvalidArgumentException('ログインしていません');
throw new ShoppingException('ログインしていません');
}
// ログイン状態のチェック.
if ($this->orderHelper->isLoginRequired()) {
log_info('[注文処理] 未ログインもしくはRememberMeログインのため, ログイン画面に遷移します.');
throw new InvalidArgumentException();
$message = '[注文処理] 未ログインもしくはRememberMeログインのため, ログイン画面に遷移します.';
log_info($message);
throw new ShoppingException($message);
}

// 受注の存在チェック
$preOrderId = $this->cartService->getPreOrderId();
$Order = $this->orderHelper->getPurchaseProcessingOrder($preOrderId);
if (!$Order) {
log_info('[注文処理] 購入処理中の受注が存在しません.', [$preOrderId]);
throw new InvalidArgumentException();
$message = '[注文処理] 購入処理中の受注が存在しません.';
log_info($message, [$preOrderId]);
throw new ShoppingException($message);
}

log_info('[注文処理] 注文処理を開始します.', [$Order->getId()]);
Expand Down Expand Up @@ -163,13 +167,13 @@ public function purchaseMutation()

$this->entityManager->rollback();

throw new InvalidArgumentException($e->getMessage());
throw new ShoppingException($e->getMessage());
} catch (\Exception $e) {
log_error('[注文処理] 予期しないエラーが発生しました.', [$e->getMessage()]);

// $this->entityManager->rollback(); FIXME ユニットテストで There is no active transaction エラーになってしまう

throw new InvalidArgumentException($e->getMessage());
throw new ShoppingException($e->getMessage());
}

// カート削除
Expand Down Expand Up @@ -216,10 +220,10 @@ protected function executePurchaseFlow(ItemHolderInterface $itemHolder, $returnR
/** @var PurchaseFlowResult $flowResult */
$flowResult = $this->purchaseFlow->validate($itemHolder, new PurchaseContext(clone $itemHolder, $itemHolder->getCustomer()));
foreach ($flowResult->getWarning() as $warning) {
throw new InvalidArgumentException();
$this->addWarning($warning->getMessage());
}
foreach ($flowResult->getErrors() as $error) {
throw new InvalidArgumentException();
throw new ShoppingException($error->getMessage());
}

if (!$returnResponse) {
Expand Down Expand Up @@ -307,7 +311,7 @@ protected function executeCheckout(PaymentMethodInterface $paymentMethod)
if (!$PaymentResult->isSuccess()) {
$this->entityManager->rollback();
foreach ($PaymentResult->getErrors() as $error) {
throw new InvalidArgumentException($error->getMessage());
throw new ShoppingException($error->getMessage());
}

log_info('[注文処理] PaymentMethod::checkoutのエラーのため, 購入エラー画面へ遷移します.', [$PaymentResult->getErrors()]);
Expand Down
55 changes: 27 additions & 28 deletions GraphQL/Mutation/ShoppingMutation.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,12 @@
use Eccube\Service\PurchaseFlow\PurchaseFlow;
use Eccube\Service\PurchaseFlow\PurchaseFlowResult;
use Plugin\Api42\GraphQL\Error\InvalidArgumentException;
use Plugin\Api42\GraphQL\Mutation;
use Plugin\Api42\GraphQL\Error\ShoppingException;
use Plugin\Api42\GraphQL\Types;
use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\Form\FormFactoryInterface;

class ShoppingMutation implements Mutation
class ShoppingMutation extends AbstractMutation
{
private Types $types;

Expand All @@ -46,49 +48,55 @@ public function __construct(
OrderHelper $orderHelper,
SecurityContext $securityContext,
PurchaseFlow $cartPurchaseFlow,
FormFactoryInterface $formFactory,
) {
$this->types = $types;
$this->entityManager = $entityManager;
$this->cartService = $cartService;
$this->orderHelper = $orderHelper;
$this->securityContext = $securityContext;
$this->cartPurchaseFlow = $cartPurchaseFlow;
$this->setTypes($types);
$this->setFormFactory($formFactory);
}

public function getName(): string
{
return 'orderMutation';
}

public function getMutation(): array
public function getTypesClass(): string
{
return [
'type' => $this->types->get(Order::class),
'args' => [],
'resolve' => [$this, 'orderMutation'],
];
return Order::class;
}

public function getArgsType(): string
{
return FormType::class;
}

/**
* @return Order|null
* @throws InvalidArgumentException
* @throws ORMException
* @throws ForeignKeyConstraintViolationException
*/
public function orderMutation($root, $args): ?Order
public function executeMutation($root, $args): mixed
{
$user = $this->securityContext->getLoginUser();

// ログイン状態のチェック.
if ($this->orderHelper->isLoginRequired()) {
log_info('[注文手続] 未ログインもしくはRememberMeログインのため, ログイン画面に遷移します.');
throw new InvalidArgumentException();
$message = '[注文手続] 未ログインもしくはRememberMeログインのため, ログイン画面に遷移します.';
log_info($mssage);
throw new ShoppingException($message);
}

// カートチェック.
$Cart = $this->cartService->getCart();
if (!($Cart && $this->orderHelper->verifyCart($Cart))) {
log_info('[注文手続] カートが購入フローへ遷移できない状態のため, カート画面に遷移します.');
throw new InvalidArgumentException();
$message = '[注文手続] カートが購入フローへ遷移できない状態のため, カート画面に遷移します.';
log_info($mssage);
throw new ShoppingException($message);
}

// 受注の初期化.
Expand All @@ -102,8 +110,9 @@ public function orderMutation($root, $args): ?Order
$this->entityManager->flush();

if ($flowResult->hasError()) {
log_info('[注文手続] Errorが発生したため購入エラー画面へ遷移します.', [$flowResult->getErrors()]);
throw new InvalidArgumentException();
$message = '[注文手続] Errorが発生したため購入エラー画面へ遷移します.';
log_info($message, [$flowResult->getErrors()]);
throw new ShoppingException($message);
}

if ($flowResult->hasWarning()) {
Expand Down Expand Up @@ -138,26 +147,16 @@ protected function executePurchaseFlow(ItemHolderInterface $itemHolder, bool $re
{
$flowResult = $this->cartPurchaseFlow->validate($itemHolder, new PurchaseContext(clone $itemHolder, $itemHolder->getCustomer()));
foreach ($flowResult->getWarning() as $warning) {
throw new InvalidArgumentException();
$this->addWarning($warning->getMessage());
}
foreach ($flowResult->getErrors() as $error) {
throw new InvalidArgumentException();
throw new ShoppingException($error->getMessage());
}

if (!$returnResponse) {
return $flowResult;
}

if ($flowResult->hasError()) {
log_info('Errorが発生したため購入エラー画面へ遷移します.', [$flowResult->getErrors()]);
throw new InvalidArgumentException();
}

if ($flowResult->hasWarning()) {
log_info('Warningが発生したため注文手続き画面へ遷移します.', [$flowResult->getWarning()]);
throw new InvalidArgumentException();
}

return null;
}
}