<?php
namespace Plugin\PiaProductRestock\EventSubscriber;
use Eccube\Event\TemplateEvent;
use Eccube\Repository\ProductRepository;
use Plugin\PiaProductRestock\Repository\ProductRestockRepository;
use Plugin\PiaProductRestock\Repository\ProductRestockCustomerRepository;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
class ProductRestockEventSubscriber implements EventSubscriberInterface
{
/**
* @var ProductRestockRepository
*/
private $productRestockRepository;
/**
* @var ProductRestockCustomerRepository
*/
private $productRestockCustomerRepository;
/**
* @var ProductRepository
*/
private $productRepository;
/**
* @var TokenStorageInterface
*/
private $tokenStorage;
public function __construct(
ProductRestockRepository $productRestockRepository,
ProductRestockCustomerRepository $productRestockCustomerRepository,
ProductRepository $productRepository,
TokenStorageInterface $tokenStorage
) {
$this->productRestockRepository = $productRestockRepository;
$this->productRestockCustomerRepository = $productRestockCustomerRepository;
$this->productRepository = $productRepository;
$this->tokenStorage = $tokenStorage;
}
/**
* @return array
*/
public static function getSubscribedEvents()
{
return [
'Product/detail.twig' => 'onProductDetail',
'@admin/Product/product.twig' => 'onAdminProductEdit',
];
}
/**
* 商品詳細ページに再入荷ボタンを追加
*/
public function onProductDetail(TemplateEvent $event)
{
$parameters = $event->getParameters();
$product = $parameters['Product'];
if (!$product) {
return;
}
$productId = $product->getId();
// 再入荷情報を取得
$restock = $this->productRestockRepository->findByProductId($productId);
$dispFlg = $restock ? $restock->getDispFlg() : 0;
// 在庫が0の場合は強制的に非表示
$stock = 0;
foreach ($product->getProductClasses() as $productClass) {
if ($productClass->isVisible()) {
$stock += $productClass->getStock();
}
}
if ($stock > 0) {
$dispFlg = 0; // 在庫がある場合は非表示
}
$parameters['product_restock_disp_flg'] = $dispFlg;
// ログインユーザーの登録状況
$registFlg = 2; // 未登録
$token = $this->tokenStorage->getToken();
if ($token && $token->getUser() && method_exists($token->getUser(), 'getId')) {
$customer = $token->getUser();
if ($restock) {
$isRegistered = $this->productRestockCustomerRepository->isRegistered(
$restock->getId(),
$customer->getId()
);
$registFlg = $isRegistered ? 1 : 2;
}
}
$parameters['product_restock_regist_flg'] = $registFlg;
$parameters['product_restock_id'] = $productId;
$event->setParameters($parameters);
// 再入荷ボタンを指定位置に追加
if ($dispFlg == 1) {
$source = $event->getSource();
// 指定されたHTMLの上に再入荷ボタンを挿入
$search = '/<p class="btm_txt"><a href="(.*)">ご利用方法の詳細はこちら<\/a><\/p>/';
if (preg_match($search, $source, $result)) {
$searchText = $result[0];
$replace = "{{ include('@PiaProductRestock/front/Product/restock_button.twig') }}" . $searchText;
$source = str_replace($searchText, $replace, $source);
$event->setSource($source);
}
}
}
/**
* 管理画面商品編集ページに再入荷ボタンを追加
*/
public function onAdminProductEdit(TemplateEvent $event)
{
$parameters = $event->getParameters();
$product = $parameters['Product'];
if (!$product || !$product->getId()) {
return;
}
$productId = $product->getId();
$restock = $this->productRestockRepository->findByProductId($productId);
$buttonText = '再入荷に登録';
$actionType = 1;
$statusText = '再入荷未登録';
$isRegistered = false;
if ($restock && $restock->getDispFlg() == 1) {
$buttonText = '再入荷から解除';
$actionType = 0;
$statusText = '再入荷登録中';
$isRegistered = true;
}
$parameters['product_restock_button_text'] = $buttonText;
$parameters['product_restock_action_type'] = $actionType;
$parameters['product_restock_status_text'] = $statusText;
$parameters['product_restock_product_id'] = $productId;
$parameters['product_restock_is_registered'] = $isRegistered;
$event->setParameters($parameters);
// テンプレートソースを取得して再入荷項目を追加
$source = $event->getSource();
// ProductPlusと同じように、フォーム要素の前に挿入
if (preg_match("/\{\%\sfor\sf\sin\sform(\s if|\|filter\(f\s\=\>)\sf\.vars\.eccube\_form\_options\.auto\_render/", $source, $result)) {
$search = $result[0];
$replace = "{{ include('@PiaProductRestock/admin/Product/restock_edit.twig') }}" . $search;
$source = str_replace($search, $replace, $source);
}
$event->setSource($source);
}
/**
* 商品詳細ページ用のスニペット
*/
private function getProductDetailSnippet($productId, $registFlg, $dispFlg)
{
if ($dispFlg != 1) {
return '';
}
$buttonText = $registFlg == 1 ? '再入荷通知を解除' : '再入荷通知を登録';
$buttonClass = $registFlg == 1 ? 'btn-secondary' : 'btn-primary';
$actionType = $registFlg == 1 ? 2 : 1;
return sprintf('
<script>
$(function() {
var restockHtml = `
<div class="ec-productRole__btn mt-3">
<button type="button" class="btn %s btn-block" onclick="handleRestockAction(%d, %d)">
%s
</button>
</div>
`;
$(".ec-productRole__btn").last().after(restockHtml);
});
function handleRestockAction(productId, type) {
if (confirm("再入荷通知を" + (type === 1 ? "登録" : "解除") + "しますか?")) {
location.href = "/product_restock/" + productId + "?type=" + type;
}
}
</script>
', $buttonClass, $productId, $actionType, $buttonText);
}
/**
* 管理画面商品編集ページ用のスニペット
*/
private function getAdminProductEditSnippet($productId, $buttonText, $actionType, $statusText)
{
return sprintf('
<script>
$(function() {
var restockHtml = `
<div class="row mb-2">
<div class="col-3">
<span class="badge badge-primary">再入荷管理</span>
</div>
<div class="col-9">
<div class="mb-2">%s</div>
<button type="button" class="btn btn-sm btn-outline-secondary" onclick="handleAdminRestockAction(%d, %d)">
%s
</button>
</div>
</div>
`;
$(".c-container .row").first().after(restockHtml);
});
function handleAdminRestockAction(productId, type) {
var action = type === 1 ? "登録" : "解除";
if (confirm("再入荷商品「" + action + "」しますか?")) {
location.href = "/admin/product_restock/regist/" + productId + "?type=" + type;
}
}
</script>
', $statusText, $productId, $actionType, $buttonText);
}
}