<?php
/**
* Created by PhpStorm.
* User: k_akiyoshi
* Date: 2020/08/06
* Time: 11:20
*/
namespace Plugin\ApgRichCategory;
use Doctrine\ORM\EntityManagerInterface;
use Eccube\Entity\Category;
use Eccube\Repository\CategoryRepository;
use Eccube\Request\Context;
use Plugin\ApgRichCategory\Domain\UrlType;
use Plugin\ApgRichCategory\Entity\Config;
use Plugin\ApgRichCategory\Repository\ConfigRepository;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpKernel\EventListener\RouterListener;
use Symfony\Component\Routing\Matcher\UrlMatcher;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\RouterInterface;
class RoutingListener extends RouterListener
{
/** @var Context */
private $context;
/** @var ContainerInterface */
private $container;
/** @var RequestStack */
private $requestStack;
/** @var EntityManagerInterface */
private $em;
/** @var RouterInterface */
private $router;
/** @var RouteCollection */
private $routeCollection;
/**
* コンストラクタ
*
* @param ContainerInterface $container
* @param RequestStack $requestStack
*/
public function __construct(
ContainerInterface $container,
Context $context,
RequestStack $requestStack,
EntityManagerInterface $entityManager,
RouterInterface $router
)
{
$this->context = $context;
$this->container = $container;
$this->requestStack = $requestStack;
$this->em = $entityManager;
$this->router = $router;
$this->routeCollection = $this->router->getRouteCollection();
$this->initialize();
$matcher = new UrlMatcher($this->routeCollection, new RequestContext());
parent::__construct($matcher, $requestStack);
}
private function initialize()
{
/** @var ConfigRepository $configRepository */
$configRepository = $this->em->getRepository(Config::class);
$config = $configRepository->getOrNew();
$request = $this->requestStack->getCurrentRequest();
$pathInfo = $request->getPathInfo();
$path = ltrim($pathInfo, "/");
$url = $request->getRequestUri();
if (empty(parse_url($url)['query'])) {
$queries = [];
} else {
parse_str(parse_url($url)['query'], $queries);
}
/** @var CategoryRepository $categoryRepository */
$categoryRepository = $this->em->getRepository(Category::class);
if ($config->getUrlType() === UrlType::SLUG) {
// カテゴリにつけられたスラッグのルーティングを全て設定する
$qb = $categoryRepository->createQueryBuilder('c')
->select('c.slug')
->getQuery();;
$slugList = $qb->getResult();
foreach ($slugList as $slug) {
if (!empty($slug['slug'])) {
$s = $slug['slug'];
$this->routeCollection->add('apg_rich_category.' . str_replace("/", ".", $s),
new Route(
'/' . $s,
[
'_controller' => "Eccube\Controller\ProductController::index",
]
)
);
}
}
if ($this->context->isFront()) {
$Category = $categoryRepository->findOneBy([
'slug' => $path
]);
if (empty($Category)) {
$pattern = '|products/list/([\d]+)|';
$matches = [];
if (preg_match($pattern, $path, $matches)) {
$categoryId = $matches[1];
if (!empty($categoryId)) {
/** @var Category $Category */
$Category = $categoryRepository->findOneBy([
'id' => $categoryId
]);
if (!empty($Category) && !empty($Category->getSlug())) {
unset($queries['category_id']);
$url = "/" . $Category->getSlug();
if (!empty($queries)) {
$newQueryStr = "";
foreach ($queries as $key => $value) {
$newQueryStr .= "&" . $key . "=" . $value;
}
$url .= "?" . ltrim($newQueryStr, "&");
}
$redirectResponse = new RedirectResponse($url, 302);
$redirectResponse->send();
return;
} elseif (!empty($Category)) {
$queries['category_id'] = $categoryId;
$url = $this->router->generate('product_list', $queries);
$redirectResponse = new RedirectResponse($url, 302);
$redirectResponse->send();
return;
}
}
} else {
$categoryId = $request->query->get('category_id');
if (!empty($categoryId)) {
/** @var Category $Category */
$Category = $categoryRepository->findOneBy([
'id' => $categoryId
]);
if (!empty($Category) && !empty($Category->getSlug())) {
unset($queries['category_id']);
$url = "/" . $Category->getSlug();
if (!empty($queries)) {
$newQueryStr = "";
foreach ($queries as $key => $value) {
$newQueryStr .= "&" . $key . "=" . $value;
}
$url .= "?" . ltrim($newQueryStr, "&");
}
$redirectResponse = new RedirectResponse($url, 302);
$redirectResponse->send();
return;
}
}
}
}
}
} elseif ($config->getUrlType() === UrlType::ID) {
if ($this->context->isFront()) {
$pattern = '|products/list/([\d]+)|';
$matches = [];
if (preg_match($pattern, $path, $matches)) {
$this->routeCollection->add('product_list.category_id',
new Route(
'/products/list/{category_id}',
[
'_controller' => "Eccube\Controller\ProductController::index",
]
)
);
} else {
$categoryId = $request->query->get('category_id');
if (!empty($categoryId)) {
unset($queries['category_id']);
$url = $this->router->generate('product_list');
$url = $url . '/' . $categoryId;
if (!empty($queries)) {
$newQueryStr = "";
foreach ($queries as $key => $value) {
$newQueryStr .= "&" . $key . "=" . $value;
}
$url .= "?" . ltrim($newQueryStr, "&");
}
$redirectResponse = new RedirectResponse($url, 302);
$redirectResponse->send();
return;
}
}
}
}
}
}