<?php
namespace Plugin\ApexOrderItemOption\Event;
use Eccube\Event\TemplateEvent;
use Eccube\Form\Type\AddCartType;
use Plugin\ApexOrderItemOption\Entity\OptionCategory;
use Plugin\ApexOrderItemOption\Service\CartItemOptionFormService;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\FormFactoryInterface;
class CartEvent implements EventSubscriberInterface
{
/**
* @var FormFactoryInterface
*/
private $formFactory;
/**
* @var CartItemOptionFormService
*/
private $cartItemOptionFormService;
public function __construct(
FormFactoryInterface $formFactory,
CartItemOptionFormService $cartItemOptionFormService
) {
$this->formFactory = $formFactory;
$this->cartItemOptionFormService = $cartItemOptionFormService;
}
/**
* @return array
*/
public static function getSubscribedEvents()
{
return [
'Cart/index.twig' => 'onTemplateCart',
];
}
public function onTemplateCart(TemplateEvent $event)
{
$this->addCartItemOptionForms($event);
$source = $event->getSource();
if(preg_match("/url\('cart\_handle\_item'\s*,\s*\{'operation'\s*:\s*'down'\s*,\s*'productClassId'\s*:\s*ProductClass\.id/",$source, $result)){
$search = $result[0];
$snipet = "url('productoption_cart_handle_item', {'operation': 'down', 'cartItemId': CartItem.id";
$replace = $snipet;
$source = str_replace($search, $replace, $source);
}
if(preg_match("/url\('cart\_handle\_item'\s*,\s*\{'operation'\s*:\s*'up'\s*,\s*'productClassId'\s*:\s*ProductClass\.id/",$source, $result)){
$search = $result[0];
$snipet = "url('productoption_cart_handle_item', {'operation': 'up', 'cartItemId': CartItem.id";
$replace = $snipet;
$source = str_replace($search, $replace, $source);
}
if(preg_match("/url\('cart\_handle\_item',\s\{'operation'\:\s'remove',\s'productClassId'\:\sProductClass\.id/",$source, $result)){
$search = $result[0];
$snipet = "url('productoption_cart_handle_item', {'operation': 'remove', 'cartItemId': CartItem.id";
$replace = $snipet;
$source = str_replace($search, $replace, $source);
}
if(preg_match("/\<\/div\>[\n|\r\n\\r]\s*<div\sclass\=\"ec\-cartRow\_\_unitPrice\"\>/",$source, $result)){
$search = $result[0];
$replace = "{{ include('@ApexOrderItemOption/default/Cart/cart_option.twig') }}" . $search;
$source = str_replace($search, $replace, $source);
}
$event->setSource($source);
}
/**
* カート明細ごとに、オプション編集用の AddCartType を組み立ててテンプレートへ渡す.
*
* 現在の option_serial / 数量 / 規格を初期値として流し込み、
* widget の id は明細IDを付けて一意にする(同じ商品が複数明細に並ぶため).
*
* @param TemplateEvent $event
*/
private function addCartItemOptionForms(TemplateEvent $event)
{
$parameters = $event->getParameters();
if (!isset($parameters['Carts'])) {
return;
}
$forms = [];
foreach ($parameters['Carts'] as $Cart) {
foreach ($Cart->getCartItems() as $CartItem) {
$ProductClass = $CartItem->getProductClass();
if (is_null($ProductClass)) {
continue;
}
$Product = $ProductClass->getProduct();
if (is_null($Product) || count($Product->getProductOptions()) === 0) {
continue;
}
// 在庫切れの場合 AddCartExtension がオプション項目を組み立てないため、
// フォームを渡さず編集ボタン自体を出さない
if (!$Product->getStockFind()) {
continue;
}
$builder = $this->formFactory->createNamedBuilder(
'',
AddCartType::class,
null,
[
'product' => $Product,
'id_add_product_id' => false,
]
);
// 初期値は必ずビルダー段階で入れること.
// AddCartType / AddCartExtension が 'data'(既定値) を渡している項目は
// data_locked となり、組み立て後の Form::setData() が無視されるため.
// 規格は変更させないため、現在の明細の規格で固定する
$builder->get('ProductClass')->setData($ProductClass);
if ($builder->has('quantity')) {
$builder->get('quantity')->setData($CartItem->getQuantity());
}
$this->cartItemOptionFormService->applyOptionSerial($Product, $builder, $CartItem->getOptionSerial());
$view = $builder->getForm()->createView();
$this->cartItemOptionFormService->uniquifyWidgetIds($view, 'ci'.$CartItem->getId());
$forms[$CartItem->getId()] = $view;
}
}
$parameters['CartItemOptionForms'] = $forms;
$event->setParameters($parameters);
// オプション項目のスタイル(.plg_aoio / .option_Label 等)はテーマのCSSには無く、
// このテンプレートにしか定義がないため、カート画面でも読み込む
if (count($forms) > 0) {
$event->addAsset('Product/option_css.twig');
}
}
}