<?php
namespace Plugin\PlgExpandProductColumns;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\DomCrawler\Crawler;
use Plugin\PlgExpandProductColumns\Form\Type\Admin\PlgExpandProductColumnsType;
use Symfony\Component\Form\FormFactoryInterface;
use Plugin\PlgExpandProductColumns\Entity\PlgExpandProductColumnsValue;
use Plugin\PlgExpandProductColumns\Entity\PlgExpandProductColumns;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
// use Eccube\Repository\ProductRepository;
use Customize\Repository\ProductRepository;
use Plugin\PlgExpandProductColumns\Form\Type\Admin\PlgExpandProductColumnsValueType;
use Eccube\Repository\BaseInfoRepository;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Eccube\Common\EccubeConfig;
use Eccube\Entity\Product;
use Knp\Component\Pager\PaginatorInterface;
use Eccube\Repository\Master\ProductListMaxRepository;
use Eccube\Form\Type\SearchProductType;
use Eccube\Event\EventArgs;
use Eccube\Event\EccubeEvents;
class Event implements EventSubscriberInterface
{
private $twig;
private $formFactory;
private $entityManager;
private $session;
private $productRepository;
private $baseInfo;
private $eventDispatcher;
private $paginator;
/**
* @var EccubeConfig
*/
protected $eccubeConfig;
/**
* @var ProductListMaxRepository
*/
protected $productListMaxRepository;
public function __construct(
\Twig\Environment $twig,
FormFactoryInterface $formFactory,
EntityManagerInterface $entityManager,
SessionInterface $session,
ProductRepository $productRepository,
BaseInfoRepository $baseInfoRepository,
EventDispatcherInterface $eventDispatcher,
PaginatorInterface $paginator,
ProductListMaxRepository $productListMaxRepository,
) {
$this->twig = $twig;
$this->formFactory = $formFactory;
$this->entityManager = $entityManager;
$this->session = $session;
$this->productRepository = $productRepository;
$this->baseInfo = $baseInfoRepository->get();
$this->eventDispatcher = $eventDispatcher;
$this->paginator = $paginator;
$this->productListMaxRepository = $productListMaxRepository;
}
/**
* @return array
*/
public static function getSubscribedEvents()
{
return [
KernelEvents::RESPONSE => 'onKernelResponse',
KernelEvents::REQUEST => 'onKernelRequest',
'deleteProductColumnValue' => 'deleteProductColumnValue',
];
}
public function onKernelResponse(ResponseEvent $event)
{
$request = $event->getRequest();
if ($request->attributes->get('_route') === 'admin_product_product_new' || $request->attributes->get('_route') === 'admin_product_product_edit') {
$this->addColumnProductAdmin($event);
}
}
public function onKernelRequest(RequestEvent $event)
{
$request = $event->getRequest();
// Show column to product_list
if ($request->attributes->get('_route') === 'product_list' || $request->attributes->get('_route') === 'product_detail' || $request->attributes->get('_route') === 'product_detail_locale') {
$this->setExpandColumns($event);
}
if ($request->attributes->get('_route') === 'admin_product_product_new' || $request->attributes->get('_route') === 'admin_product_product_edit' && $request->isMethod('POST')) {
$this->session->set('plg_expand_product_columns_value', $request->request->get('plg_expand_product_columns_value'));
$response = $event->getResponse();
if (!$response instanceof RedirectResponse) {
return;
}
}
if ($request->attributes->get('_route') === 'admin_product_product_new' || $request->attributes->get('_route') === 'admin_product_product_edit') {
if ($this->session->has('product_id')) {
$productId = $this->session->get('product_id');
if ($productId) {
$this->saveValueColumn($event, $productId, $this->session->get('plg_expand_product_columns_value'));
}
}
}
}
public function saveValueColumn($event, $productId, $data)
{
if (!empty($data)) {
foreach ($data as $key => $value) {
$productColumn = $this->entityManager->getRepository(PlgExpandProductColumns::class)->findOneBy(
[
'id' => (int)substr($key, strpos($key, "field_") + strlen("field_")),
]
);
$product = $this->entityManager->getRepository(Product::class)->findOneBy(
[
'id' => $productId,
]
);
$productColumnValue = $this->entityManager
->getRepository(PlgExpandProductColumnsValue::class)
->findOneBy([
'columnId' => $productColumn->getId(),
'productId' => $productId,
]);
// It is only allowed to add multies columns
if ($value) {
if (is_array($value)) {
$value = implode(';', $value);
}
// Update or create
if ($productColumnValue) {
$productColumnValue->setValue($value);
} else {
$productColumnValue = new PlgExpandProductColumnsValue();
$productColumnValue->setProductId($product);
$productColumnValue->setColumnId($productColumn);
$productColumnValue->setValue($value);
}
$this->entityManager->persist($productColumnValue);
$this->entityManager->flush();
} else {
if ($productColumnValue) {
$this->entityManager->remove($productColumnValue);
$this->entityManager->flush();
}
}
}
$this->session->remove('product_id');
$this->session->remove('plg_expand_product_columns_value');
}
}
public function onRenderAdminProductNew($event, $templateEvent)
{
}
public function addColumnProductAdmin($event)
{
$html = $event->getResponse()->getContent();
$request = $event->getRequest();
$productColumnValue = new PlgExpandProductColumnsValue();
$form = $this->formFactory->create(PlgExpandProductColumnsType::class, $productColumnValue);
$data = $this->entityManager->getRepository(PlgExpandProductColumns::class)->findAll();
// Edit product
$exColumnsValue = null;
$id = $request->attributes->get('id');
if ($id) {
$exColumnsValue = $this->entityManager->getRepository(PlgExpandProductColumnsValue::class)->findBy(
[
'productId' => $id
]
);
}
// PlgExpandProductColumnsValueType
$form = $this->formFactory->create(PlgExpandProductColumnsValueType::class, null, [
'data' => $data,
]);
// set default value in form
if (!empty($exColumnsValue)) {
foreach ($exColumnsValue as $key => $value) {
if (in_array($value['columnId']['type'], [5])) {
$form->get(('field_' . $value->getColumnId()->getId()))->setData(explode(';', $value->getValue()));
} else {
$form->get(('field_' . $value->getColumnId()->getId()))->setData($value->getValue());
}
}
}
$renderedTemplate = $this->twig->render('@PlgExpandProductColumns/admin/expand_column.twig', [
'form' => $form->createView(),
'data' => $data,
]);
$crawler = new Crawler($html);
$oldElement = $crawler->filter('.c-primaryCol')->filter('.rounded')->last();
if (count($oldElement) > 0) {
$html = str_replace('<div class="expandColumn">', '<div class="expandColumn">' . $renderedTemplate, $html);
$event->setResponse($event->getResponse()->setContent($html));
}
}
public function setExpandColumns($event)
{
$route = $event->getRequest()->attributes->get('_route');
$valueRepository = $this->entityManager->getRepository(PlgExpandProductColumnsValue::class);
$columnRepository = $this->entityManager->getRepository(PlgExpandProductColumns::class);
switch ($route) {
case 'product_detail':
$id = $event->getRequest()->attributes->get('id');
$exProductDetail = $this->getProductExt(
$id,
$valueRepository,
$columnRepository
);
return $this->twig->addGlobal('__EX_PRODUCT_DETAIL', $exProductDetail);
case 'product_detail_locale':
$id = $event->getRequest()->attributes->get('id');
$exProductDetail = $this->getProductExt(
$id,
$valueRepository,
$columnRepository
);
return $this->twig->addGlobal('__EX_PRODUCT_DETAIL', $exProductDetail);
case 'product_list':
$exProductList = [];
$products = $this->getPagination($event);
foreach ($products as $product) {
$exProductList[$product->getId()] = $this->getProductExt(
$product->getId(),
$valueRepository,
$columnRepository
);
}
return $this->twig->addGlobal('__EX_PRODUCT_LIST', $exProductList);
}
}
private function getProductExt($id, $value_repository, $column_repository)
{
$product_ex = [];
$columns = $column_repository->findAll();
/** @var \Plugin\PlgExpandProductColumns\Entity\PlgExpandProductColumns $column */
foreach ($columns as $column) {
$value = $value_repository->findOneBy([
'columnId' => $column->getId(),
'productId' => $id
]);
$product_ex[$column->getId()] = [
'id' => $column->getId(),
'name' => $column->getName(),
'value' => $value
];
}
return $product_ex;
}
// Custom pagination
private function getPagination($event)
{
$request = $event->getRequest();
if ($this->baseInfo->isOptionNostockHidden()) {
$this->entityManager->getFilters()->enable('option_nostock_hidden');
}
if ($request->getMethod() === 'GET') {
$request->query->set('pageno', $request->query->get('pageno', ''));
}
// searchForm
/* @var $builder \Symfony\Component\Form\FormBuilderInterface */
$builder = $this->formFactory->createNamedBuilder('', SearchProductType::class);
if ($request->getMethod() === 'GET') {
$builder->setMethod('GET');
}
$event = new EventArgs(
[
'builder' => $builder,
],
$request
);
$this->eventDispatcher->dispatch($event, EccubeEvents::FRONT_PRODUCT_INDEX_INITIALIZE);
/* @var $searchForm \Symfony\Component\Form\FormInterface */
$searchForm = $builder->getForm();
$searchForm->handleRequest($request);
$searchData = $searchForm->getData();
$categories = [];
for ($i = 0; $i <= 4; $i++) {
$paramName = 'category_id_' . $i;
if ($request->query->has($paramName)) {
$categories[] = $request->query->get($paramName);
}
}
$date = $request->query->get('date');
$qb = $this->productRepository->getQueryBuilderBySearchData($searchData, $this->entityManager, $categories, $date);
$event = new EventArgs(
[
'searchData' => $searchData,
'qb' => $qb,
],
$request
);
$this->eventDispatcher->dispatch($event, EccubeEvents::FRONT_PRODUCT_INDEX_SEARCH);
$searchData = $event->getArgument('searchData');
$query = $qb->getQuery();
/** @var SlidingPagination $pagination */
return $this->paginator->paginate(
$query,
!empty($searchData['pageno']) ? $searchData['pageno'] : 1,
!empty($searchData['disp_number']) ? $searchData['disp_number']->getId() : $this->productListMaxRepository->findOneBy([], ['sort_no' => 'ASC'])->getId()
);
}
/**
* Delete column before delete product
*
* @param EventArgs $event
* @return void
*/
public function deleteProductColumnValue(EventArgs $event)
{
$product = $event->getArgument('Product');
$productColumnValues = $this->entityManager
->getRepository(PlgExpandProductColumnsValue::class)
->findBy([
'productId' => $product->getId(),
]);
foreach ($productColumnValues as $productColumnValue) {
$this->entityManager->remove($productColumnValue);
}
$this->entityManager->flush();
}
}