<?php
/*
* Plugin Name: JoolenZR42
*
* Copyright(c) joolen inc. All Rights Reserved.
*
* https://www.joolen.co.jp/
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Plugin\JoolenZR42\EventListener;
use Eccube\Entity\Order;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Eccube\Event\EventArgs;
use Eccube\Event\TemplateEvent;
use Eccube\Repository\OrderRepository;
use Eccube\Repository\PluginRepository;
use Eccube\Service\CartService;
use Eccube\Service\OrderHelper;
use Eccube\Entity\Master\OrderStatus;
use Plugin\JoolenZR42\Repository\ConfigRepository;
use Plugin\JoolenZR42\Service\MailService;
class EventListener implements EventSubscriberInterface
{
const SESSION_ZRCONNECT_ORDER_ID = 'eccube.plugin.joolen_zr42.order.id';
/**
* ログ表示用
* @var string
*/
protected $methodName = '[Joolen ZR Plugin] ';
/**
* @var ConfigRepository
*/
protected $configRepository;
/**
* @var OrderRepository
*/
protected $orderRepository;
/**
* @var Session
*/
protected $session;
/**
* @var CartService
*/
protected $cartService;
/**
* @var OrderHelper
*/
protected $orderHelper;
/**
* @var MailService
*/
private $mailService;
public function __construct(
RequestStack $requestStack,
ConfigRepository $configRepository,
OrderRepository $orderRepository,
PluginRepository $PluginRepository,
CartService $cartService,
OrderHelper $orderHelper,
MailService $mailService
) {
$this->session = $requestStack->getSession();
$this->cartService = $cartService;
$this->orderHelper = $orderHelper;
$this->orderRepository = $orderRepository;
$this->configRepository = $configRepository;
$this->mailService = $mailService;
$this->Plugin = $PluginRepository->findOneBy([
'code' => 'JoolenZR42',
'enabled' => true,
]);
}
/**
* @return array
*/
public static function getSubscribedEvents()
{
return [
// 受注IDをセッションに保管するタイミング: 注文確認画面
// 決済のプラグインによっては、注文完了画面でOrder.idが消されてしまい取得できないため、予め確保しておく
'Shopping/index.twig' => 'setOrderIdToSession',
// 購入完了時のメール送信のタイミング: 注文完了画面信
'front.shopping.complete.initialize' => 'onSendOrderMailToZR',
];
}
/**
* セッションにOrder.idを保存
* @param TemplateEvent $event
* @return void
*/
public function setOrderIdToSession(TemplateEvent $event)
{
if (!$this->Plugin) {
return;
}
$Order = $this->getOrderFromCart();
if ($Order) {
log_info($this->methodName . '受注IDをセッションに保存 Order.id[' . $Order->getId() . ']');
$this->session->set(self::SESSION_ZRCONNECT_ORDER_ID, $Order->getId());
}
}
/**
* カートからOrderを取得
* @return Order|null
*/
private function getOrderFromCart()
{
// カートの取得
$Cart = $this->cartService->getCart();
if (!($Cart && $this->orderHelper->verifyCart($Cart))) {
// カートが購入フローへ遷移できない状態はnullを返す
log_info($this->methodName . 'カート不正のため CartからOrderを取得できず1');
return null;
}
// Order取得
if ($Order = $this->orderHelper->getPurchaseProcessingOrder($Cart->getPreOrderId())) {
return $Order;
}
log_info($this->methodName . 'カート不正のため CartからOrderを取得できず2');
return null;
}
/**
* 在庫ロボットへ受注メールを送信する
* @param EventArgs $event
* @return void
* @throws \Twig\Error\LoaderError
* @throws \Twig\Error\RuntimeError
* @throws \Twig\Error\SyntaxError
*/
public function onSendOrderMailToZR(EventArgs $event)
{
if (!$this->Plugin) {
return;
}
$methodName = $this->methodName . '在庫ロボット受注メール [フロント購入時の送信] ';
$Order = $this->getOrder($event, $methodName);
if (!$Order) {
$errorMessage = ' Orderを取得できないため、在庫ロボット受注メールを送信できませんでした';
log_info($methodName . '[失敗]' . $errorMessage);
return;
}
$checked = $this->checkOrder($Order, $methodName);
if (!$checked) {
return;
}
$Config = $this->configRepository->get();
if (!$Config || is_null($Config->getEmail())) {
$errorMessage = '送信情報の登録がないため、在庫ロボット受注メールを送信できませんでした';
log_info($methodName . '[失敗] ' . $errorMessage);
return;
}
log_info($methodName . '送信[開始]');
$this->mailService->sendOrderMailToZRFront($Config->getEmail(), $Order);
log_info($methodName . '送信[完了]');
}
/**
* @param EventArgs $event
* @param string $methodName
* @return Order|null
*/
private function getOrder(EventArgs $event, string $methodName)
{
$Order = $event->getArgument('Order');
if ($Order) {
return $Order;
}
// 決済プラグインによってはOrderを取得できない時があるので、独自セッションから取得を試みる
$orderId = $this->session->get(self::SESSION_ZRCONNECT_ORDER_ID);
$this->session->remove(self::SESSION_ZRCONNECT_ORDER_ID);
log_info($methodName . '通常処理でOrderを取得できないため、独自セッションからorder_idを取得した。 order_id:[' . $orderId . ']');
return $this->orderRepository->find($orderId);
}
/**
* @param Order $Order
* @param string $methodName
* @return bool
*/
private function checkOrder(Order $Order, string $methodName): bool
{
// ログメッセージにOrder.id情報を追加
$methodName .= 'Order.id[' . $Order->getId() . '] ';
// 決済が完了していない場合は終了
if (!$Order->getOrderStatus()) {
$errorMessage = '受注ステータスが確認できないため、在庫ロボット受注メールを送信できませんでした';
log_info($methodName . '[失敗] ' . $errorMessage);
return false;
}
if ($Order->getOrderStatus()->getId() === OrderStatus::PENDING || // 決済処理中
$Order->getOrderStatus()->getId() === OrderStatus::PROCESSING // 購入処理中
) {
$errorMessage = '受注ステータスが不正なため、在庫ロボット受注メールを送信できませんでした。OrderStatus.id[' . $Order->getOrderStatus()->getId() . ']';
log_info($methodName . '[失敗] ' . $errorMessage);
return false;
}
return true;
}
}