src/Controller/NodeController.php line 149

Open in your IDE?
  1. <?php
  2. /*
  3.  * 2001-2019 Reflet Communication
  4.  *
  5.  * NOTICE OF LICENSE
  6.  *
  7.  * This source file is subject to the Open Software License (OSL 3.0) that is available
  8.  * through the world-wide-web at this URL: http://www.opensource.org/licenses/OSL-3.0
  9.  * If you are unable to obtain it through the world-wide-web, please send an email
  10.  * to agence@reflet-digital.com so we can send you a copy immediately.
  11.  *
  12.  * @author Reflet Communication
  13.  * @copyright 2001-2019 Reflet Communication
  14.  * @license http://www.opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
  15.  */
  16. namespace App\Controller;
  17. use App\Entity\Url;
  18. use App\Exception\BadResponseException;
  19. use App\Filter\ProxyFilter;
  20. use App\Manager\Api\Catalog\BrandManager;
  21. use App\Manager\Api\Catalog\CategoryManager;
  22. use App\Manager\Api\Catalog\ProductManager;
  23. use App\Navigation\BreadcrumbNavigation;
  24. use App\Navigation\CategoryNavigation;
  25. use App\Navigation\Page\Route as Page;
  26. use App\Service\ApiService;
  27. use App\Service\ProxyService;
  28. use DateTime;
  29. use Symfony\Component\HttpFoundation\Request;
  30. use Symfony\Component\HttpFoundation\RequestStack;
  31. use Symfony\Component\HttpFoundation\Response;
  32. use Symfony\Component\HttpFoundation\ServerBag;
  33. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  34. use Symfony\Component\Routing\Annotation\Route;
  35. use Symfony\Component\Routing\RouterInterface;
  36. use Symfony\Contracts\Cache\TagAwareCacheInterface;
  37. /**
  38.  * Class NodeController
  39.  *
  40.  * @package App\Controller
  41.  *
  42.  * @Route(
  43.  *     name = "node_",
  44.  *     options = {
  45.  *         "priority" = 2
  46.  *     }
  47.  * )
  48.  */
  49. class NodeController extends ProxyAwareController
  50. {
  51.     /**
  52.      * @var CategoryManager
  53.      */
  54.     private $categoryManager;
  55.     /**
  56.      * @var ProductManager
  57.      */
  58.     private $productManager;
  59.     /**
  60.      * @var BrandManager
  61.      */
  62.     private $brandManager;
  63.     /**
  64.      * @var ServerBag
  65.      */
  66.     private $bag;
  67.     /**
  68.      * NodeController constructor.
  69.      *
  70.      * @param RequestStack $stack
  71.      * @param ApiService $apiService
  72.      * @param ProxyFilter $proxyFilter
  73.      * @param ProxyService $proxyService
  74.      * @param TagAwareCacheInterface $cache
  75.      */
  76.     public function __construct(
  77.         RequestStack $stack,
  78.         ApiService $apiService,
  79.         ProxyFilter $proxyFilter,
  80.         ProxyService $proxyService,
  81.         TagAwareCacheInterface $cache
  82.     ) {
  83.         parent::__construct($stack$proxyService$proxyFilter$cache);
  84.         $bag $this
  85.             ->request
  86.             ->server
  87.         ;
  88.         $this->categoryManager = new CategoryManager($apiService$bag$cache);
  89.         $this->productManager = new ProductManager($apiService$bag$cache);
  90.         $this->brandManager = new BrandManager($apiService$bag$cache);
  91.     }
  92.     /**
  93.      * @Route(
  94.      *     "/{path}",
  95.      *     name = "category",
  96.      *     requirements = {
  97.      *         "path" = "^[a-z0-9]+(-[a-z0-9]+)*(\/[a-z0-9]+(-[a-z0-9]+)*)?$",
  98.      *     }
  99.      * )
  100.      *
  101.      * @param Request $request
  102.      * @param string $path
  103.      * @param $filters
  104.      *
  105.      * @throws NotFoundHttpException
  106.      *
  107.      * @return Response
  108.      */
  109.     public function category(Request $request$path$filters null): Response
  110.     {
  111.         $path explode('/'$path);
  112.         try {
  113.             try {
  114.                 $category $this
  115.                     ->categoryManager
  116.                     ->getItem(end($path), 'slug')
  117.                 ;
  118.                 $categoryPath explode('/'$category->path);
  119.             } catch (BadResponseException $e) {
  120.                 if (count($path) > 1) {
  121.                     $request->attributes->set('_route''node_product');
  122.                     return $this->forward('App\Controller\NodeController::product', [
  123.                         'path' => $path[0],
  124.                         'slug' => $path[1],
  125.                         'request' => $request,
  126.                     ]);
  127.                 }
  128.                 throw new NotFoundHttpException('Page not found');
  129.             }
  130.             if (
  131.                 empty($category->enabled)
  132.                 || reset($categoryPath) != reset($path)
  133.             ) {
  134.                 throw new NotFoundHttpException('Page not found');
  135.             }
  136.         } catch (NotFoundHttpException $e) {
  137.             $request->attributes->set('_route''sulu_page_index');
  138.             return $this->forward('App\Controller\SuluPageController::index', [
  139.                 'path' => implode('/'$path),
  140.                 'request' => $request,
  141.             ]);
  142.         }
  143.         try {
  144.             $categories $this
  145.                 ->categoryManager
  146.                 ->getList([
  147.                     'parent' => $category->id,
  148.                     'enabled' => true,
  149.                     'sort' => 'order',
  150.                 ])
  151.             ;
  152.         } catch (BadResponseException $exception) {
  153.             // Ignore
  154.         }
  155.         if (!empty($categories->data)) {
  156.             $children = [];
  157.             foreach ($categories->data as $child) {
  158.                 try {
  159.                     $children[$child->id] = $this
  160.                         ->categoryManager
  161.                         ->getList([
  162.                             'parent' => $child->id,
  163.                             'enabled' => true,
  164.                             'sort' => 'order',
  165.                         ])
  166.                     ;
  167.                 } catch (BadResponseException $e) {
  168.                     // Ignore
  169.                 }
  170.             }
  171.             return $this->render('controller/node/category/category-list.html.twig', [
  172.                 'path' => implode('/'$path),
  173.                 'filters' => $filters,
  174.                 'category' => $category,
  175.                 'categories' => $categories,
  176.                 'children' => $children,
  177.             ]);
  178.         }
  179.         try {
  180.             $products $this
  181.                 ->productManager
  182.                 ->getList([
  183.                     'enabled' => true,
  184.                     'category' => $category->id,
  185.                 ])
  186.             ;
  187.         } catch (BadResponseException $exception) {
  188.             // Ignore
  189.         }
  190.         if (!empty($products->data)) {
  191.             foreach ($products->data as &$product) {
  192.                 foreach ($product->categories as &$productCategory) {
  193.                     $productCategory $this
  194.                         ->categoryManager
  195.                         ->getItem($productCategory)
  196.                     ;
  197.                 }
  198.                 unset($productCategory);
  199.                 if (!empty($product->slug)) {
  200.                     $product->item_link = new Url($request->server$this->generateUrl('node_product', [
  201.                         'path' => implode('/'$path),
  202.                         'slug' => $product->slug,
  203.                     ]));
  204.                     $product->picture_path $this->getMainPicturePath($request->server->get('CATALOG_MEDIA_URL'), $product);
  205.                 }
  206.                 try {
  207.                     if (!empty($product->brand)) {
  208.                         $product->brand $this
  209.                             ->brandManager
  210.                             ->getItem($product->brand)
  211.                         ;
  212.                     }
  213.                 } catch (BadResponseException $e) {
  214.                     // Ignore
  215.                 }
  216.             }
  217.             unset($product);
  218.             try {
  219.                 $block $this
  220.                     ->proxyEntityManager
  221.                     ->getContent('/blocks/catalog')
  222.                 ;
  223.                 $proxyFilter $this->proxyFilter;
  224.                 $block $proxyFilter($request$block);
  225.             } catch (BadResponseException $e) {
  226.                 // Ignore
  227.             }
  228.             return $this->render('controller/node/category/product-list.html.twig', [
  229.                 'path' => implode('/'$path),
  230.                 'filters' => $filters,
  231.                 'category' => $category,
  232.                 'products' => $products,
  233.                 'block' => $block ?? null,
  234.             ]);
  235.         }
  236.         try {
  237.             $page $this
  238.                 ->proxyEntityManager
  239.                 ->getContent($request->getRequestUri())
  240.             ;
  241.             $proxyFilter $this->proxyFilter;
  242.             $page $proxyFilter($request$page);
  243.         } catch (BadResponseException $exception) {
  244.             // Ignore
  245.         }
  246.         if (!empty($page['body'])) {
  247.             return $this->render('controller/node/category/page.html.twig', [
  248.                 'path' => implode('/'$path),
  249.                 'filters' => $filters,
  250.                 'category' => $category,
  251.                 'page' => $page,
  252.             ]);
  253.         }
  254.         // TODO: Should we return a true 404 anyway?
  255.         // throw new NotFoundHttpException('Page not found');
  256.         $request->attributes->set('_route''sulu_page_index');
  257.         return $this->forward('App\Controller\SuluPageController::index', [
  258.             'path' => implode('/'$path),
  259.             'request' => $request,
  260.         ]);
  261.     }
  262.     /**
  263.      * @Route(
  264.      *     "/{path}/{slug}",
  265.      *     name = "product",
  266.      *     requirements = {
  267.      *         "path" = "^[a-z0-9]+(-[a-z0-9]+)*(\/[a-z0-9]+(-[a-z0-9]+)*)?$",
  268.      *         "slug": "^([a-z0-9]+(-[a-z0-9]+)*)$",
  269.      *     }
  270.      * )
  271.      *
  272.      * @param Request $request
  273.      * @param RouterInterface $router
  274.      * @param BreadcrumbNavigation $breadcrumbNavigation
  275.      * @param CategoryNavigation $categoryNavigation
  276.      * @param string $path
  277.      * @param string $slug
  278.      * @param $filters
  279.      *
  280.      * @throws NotFoundHttpException
  281.      *
  282.      * @return Response
  283.      */
  284.     public function product(
  285.         Request $request,
  286.         RouterInterface $router,
  287.         BreadcrumbNavigation $breadcrumbNavigation,
  288.         CategoryNavigation $categoryNavigation,
  289.         $path,
  290.         $slug,
  291.         $filters null
  292.     ): Response
  293.     {
  294.         $path explode('/'$path);
  295.         try {
  296.             try {
  297.                 $category $this
  298.                     ->categoryManager
  299.                     ->getItem(end($path), 'slug')
  300.                 ;
  301.                 $categoryPath explode('/'$category->path);
  302.             } catch (BadResponseException $e) {
  303.                 throw new NotFoundHttpException('Page not found');
  304.             }
  305.             if (
  306.                 empty($category->enabled)
  307.                 || reset($categoryPath) != reset($path)
  308.             ) {
  309.                 throw new NotFoundHttpException('Page not found');
  310.             }
  311.             try {
  312.                 $product $this
  313.                     ->productManager
  314.                     ->getItem($slug'slug')
  315.                 ;
  316.                 $product->date_published DateTime::createFromFormat('U'$product->date_published);
  317.             } catch (BadResponseException $s) {
  318.                 throw new NotFoundHttpException('Page not found');
  319.             }
  320.             if (
  321.                 empty($product->date_published)
  322.                 || $product->date_published > new DateTime()
  323.                 || !in_array($category->id$product->categories)
  324.             ) {
  325.                 throw new NotFoundHttpException('Page not found');
  326.             }
  327.         } catch (NotFoundHttpException $e) {
  328.             $request->attributes->set('_route''sulu_page_index');
  329.             return $this->forward('App\Controller\SuluPageController::index', [
  330.                 'path' => implode('/'array_merge($path, [
  331.                     $slug,
  332.                 ])),
  333.                 'request' => $request,
  334.             ]);
  335.         }
  336.         foreach ($product->categories as &$productCategory) {
  337.             $productCategory $this
  338.                 ->categoryManager
  339.                 ->getItem($productCategory)
  340.             ;
  341.         }
  342.         unset($productCategory);
  343.         $route $request
  344.             ->attributes
  345.             ->get('_route')
  346.         ;
  347.         $breadcrumbNavigation
  348.             ->findOneBy('name''node_category-'.$category->id)
  349.             ->addPage([
  350.                 'label' => $product->label,
  351.                 'name' => $route.'-'.$product->id,
  352.                 'route' => $route,
  353.                 'type' => Page::class,
  354.                 'matched_route' => $request,
  355.                 'router' => $router,
  356.                 'params' => [
  357.                     'path' => implode('/'$path),
  358.                     'slug' => $product->slug,
  359.                 ],
  360.                 'active' => true,
  361.             ])
  362.         ;
  363.         $categoryNavigation
  364.             ->findOneBy('name''node_category-'.$category->id)
  365.             ->setActive(true)
  366.         ;
  367.         if (!empty($product->brand)) {
  368.             try {
  369.                 $product->brand $this
  370.                     ->brandManager
  371.                     ->getItem($product->brand)
  372.                 ;
  373.             } catch (BadResponseException $e) {
  374.                 // Ignore
  375.             }
  376.         }
  377.         $product->item_link = new Url($request->server$this->generateUrl('node_product', [
  378.             'path' => implode('/'$path),
  379.             'slug' => $slug,
  380.         ]));
  381.         $product->picture_path $this->getMainPicturePath($request->server->get('CATALOG_MEDIA_URL'), $product);
  382.         try {
  383.             $blocks $this
  384.                 ->proxyEntityManager
  385.                 ->getContent('/blocks/push-'.str_replace('_''-'reset($path)))
  386.             ;
  387.             $proxyFilter $this->proxyFilter;
  388.             $blocks $proxyFilter($this->request$blocks);
  389.         } catch (BadResponseException $e) {
  390.             // Ignore
  391.         }
  392.         try {
  393.             $similarProducts $this
  394.                 ->productManager
  395.                 ->getSimilarItems($product->id'id'3)
  396.             ;
  397.             foreach ($similarProducts->data as &$similarProduct) {
  398.                 foreach ($similarProduct->categories as &$similarCategory) {
  399.                     $similarCategory $this
  400.                         ->categoryManager
  401.                         ->getItem($similarCategory)
  402.                     ;
  403.                 }
  404.                 unset($similarCategory);
  405.                 $similarCategory reset($similarProduct->categories);
  406.                 if (!empty($similarProduct->brand)) {
  407.                     $similarProduct->brand $this
  408.                         ->brandManager
  409.                         ->getItem($similarProduct->brand)
  410.                     ;
  411.                 }
  412.                 $similarPath explode('/'$similarCategory->path);
  413.                 array_splice($similarPath1max(count($similarPath) - 20));
  414.                 $similarProduct->item_link = new Url($request->server$this->generateUrl('node_product', [
  415.                     'path' => implode('/'$similarPath),
  416.                     'slug' => $similarProduct->slug,
  417.                 ]));
  418.                 $similarProduct->picture_path $this->getMainPicturePath($request->server->get('CATALOG_MEDIA_URL'), $product);
  419.             }
  420.             unset($similarProduct);
  421.         } catch (BadResponseException $e) {
  422.             // Ignore
  423.         }
  424.         return $this->render('controller/node/product.html.twig', [
  425.             'path' => implode('/'$path),
  426.             'filters' => $filters,
  427.             'category' => $category,
  428.             'product' => $product,
  429.             'brand' => $brand ?? null,
  430.             'blocks' => $blocks ?? null,
  431.             'similarProducts' => $similarProducts ?? null,
  432.         ]);
  433.     }
  434. }