src/Controller/Catalog/CatalogController.php line 71

Open in your IDE?
  1. <?php
  2. namespace App\Controller\Catalog;
  3. use App\Controller\BaseController;
  4. use Doctrine\DBAL\Connection;
  5. use Symfony\Component\HttpFoundation\JsonResponse;
  6. use Symfony\Component\HttpFoundation\Request;
  7. use Symfony\Component\HttpFoundation\Response;
  8. use Symfony\Component\Routing\Annotation\Route;
  9. class CatalogController extends BaseController
  10. {
  11.     /**
  12.      * @Route("/catalog", name="catalog", methods={"GET"})
  13.      */
  14.     public function catalog(Request $requestConnection $dbCatalogRepository $catalog): Response
  15.     {
  16.         $activeCategory $this->normalizeCatalogCategory((string) $request->query->get('category''all'));
  17.         $query trim((string) $request->query->get('q'''));
  18.         $filters $this->catalogRequestFilters($request);
  19.         $result $catalog->listCatalogProducts(240$query$activeCategory === 'all' '' $activeCategory$filters);
  20.         $officialProducts $catalog->officialProducts(10);
  21.         return $this->render('catalog.html.twig', [
  22.             'user' => $this->publicUser($this->getAuthorizedUser($request$db)),
  23.             'catalog_products' => $result['products'],
  24.             'catalog_payload_json' => $catalog->payloadJson($result['products'], $result['total'], [
  25.                 'official_products' => $officialProducts,
  26.                 'has_more' => $result['has_more'],
  27.                 'next_offset' => $result['next_offset'],
  28.                 'limit' => $result['limit'],
  29.             ]),
  30.             'catalog_official_products' => $officialProducts,
  31.             'catalog_total' => $result['total'],
  32.             'catalog_category_filters' => $this->catalogCategoryFilters($request$activeCategory),
  33.             'catalog_type_filters' => $this->catalogTypeFilters(),
  34.             'catalog_genre_filters' => $catalog->popularGenreOptions(),
  35.             'catalog_active_category' => $activeCategory,
  36.             'catalog_query' => $query,
  37.             'catalog_active_sort' => $filters['sort'],
  38.         ]);
  39.     }
  40.     /**
  41.      * @Route("/catalog/items", name="catalog_items", methods={"GET"})
  42.      */
  43.     public function catalogItems(Request $requestCatalogRepository $catalog): JsonResponse
  44.     {
  45.         $activeCategory $this->normalizeCatalogCategory((string) $request->query->get('category''all'));
  46.         $query trim((string) $request->query->get('q'''));
  47.         $limit max(1min(80, (int) $request->query->get('limit'24)));
  48.         $offset max(0, (int) $request->query->get('offset'0));
  49.         $result $catalog->listCatalogProducts(
  50.             $limit,
  51.             $offset,
  52.             $query,
  53.             $activeCategory === 'all' '' $activeCategory,
  54.             $this->catalogRequestFilters($request)
  55.         );
  56.         $response = new JsonResponse($result);
  57.         $response->setEncodingOptions(JSON_HEX_TAG JSON_HEX_AMP JSON_HEX_APOS JSON_HEX_QUOT JSON_UNESCAPED_UNICODE JSON_UNESCAPED_SLASHES);
  58.         return $response;
  59.     }
  60.     /**
  61.      * @Route("/product", name="product", methods={"GET"})
  62.      */
  63.     public function product(Request $requestConnection $dbCatalogRepository $catalog): Response
  64.     {
  65.         $slug trim((string) $request->query->get('slug'$request->query->get('id''')));
  66.         $product $slug !== '' $catalog->findProduct($slug) : null;
  67.         if ($slug !== '' && !$product) {
  68.             throw $this->createNotFoundException('Товар не найден или сейчас не в наличии.');
  69.         }
  70.         return $this->render('product.html.twig', [
  71.             'user' => $this->publicUser($this->getAuthorizedUser($request$db)),
  72.             'product' => $product,
  73.         ]);
  74.     }
  75.     private function catalogCategoryFilters(Request $requeststring $activeCategory): array
  76.     {
  77.         $definitions = [
  78.             ['id' => 'all''label' => 'Все''icon' => 'catalog.svg'],
  79.             ['id' => 'donate''label' => 'Донат''icon' => 'cat-donate.svg'],
  80.             ['id' => 'subscriptions''label' => 'Подписки''icon' => 'cat-subscribes.svg'],
  81.             ['id' => 'items''label' => 'Предметы''icon' => 'cat-items.svg'],
  82.             ['id' => 'accounts''label' => 'Аккаунты''icon' => 'cat-accounts.svg'],
  83.             ['id' => 'keys''label' => 'Ключи''icon' => 'cat-keys.svg'],
  84.             ['id' => 'steam_gift''label' => 'Steam Gift''icon' => 'cat-currency.svg'],
  85.             ['id' => 'other''label' => 'Другое''icon' => 'cat-other.svg'],
  86.             ['id' => 'services''label' => 'Услуги''icon' => 'cat-services.svg'],
  87.         ];
  88.         $query $request->query->all();
  89.         unset($query['page']);
  90.         return array_map(function (array $definition) use ($query$activeCategory): array {
  91.             $urlQuery $query;
  92.             if ($definition['id'] === 'all') {
  93.                 unset($urlQuery['category']);
  94.             } else {
  95.                 $urlQuery['category'] = $definition['id'];
  96.             }
  97.             $definition['active'] = $definition['id'] === $activeCategory;
  98.             $definition['url'] = $this->generateUrl('catalog'$urlQuery);
  99.             return $definition;
  100.         }, $definitions);
  101.     }
  102.     private function catalogTypeFilters(): array
  103.     {
  104.         return [
  105.             ['id' => 'steam_gift''label' => 'Steam Gift'],
  106.             ['id' => 'keys''label' => 'Ключ Steam'],
  107.             ['id' => 'donate''label' => 'Донат'],
  108.             ['id' => 'subscriptions''label' => 'Подписки'],
  109.             ['id' => 'items''label' => 'Предметы'],
  110.             ['id' => 'accounts''label' => 'Аккаунты'],
  111.             ['id' => 'other''label' => 'Другое'],
  112.         ];
  113.     }
  114.     private function catalogRequestFilters(Request $request): array
  115.     {
  116.         return [
  117.             'types' => $this->requestValueList($request'type'),
  118.             'genres' => $this->requestValueList($request'genre'),
  119.             'min_price' => trim((string) $request->query->get('min_price''')),
  120.             'max_price' => trim((string) $request->query->get('max_price''')),
  121.             'sort' => $this->normalizeCatalogSort((string) $request->query->get('sort''popular')),
  122.         ];
  123.     }
  124.     private function requestValueList(Request $requeststring $key): array
  125.     {
  126.         $value $request->query->get($key'');
  127.         if (is_array($value)) {
  128.             $items $value;
  129.         } else {
  130.             $items preg_split('/[,\s]+/', (string) $value) ?: [];
  131.         }
  132.         return array_values(array_filter(array_unique(array_map(function ($item): string {
  133.             return strtolower(trim((string) $item));
  134.         }, $items)), function (string $item): bool {
  135.             return $item !== '';
  136.         }));
  137.     }
  138.     private function normalizeCatalogSort(string $sort): string
  139.     {
  140.         $sort strtolower(trim($sort));
  141.         $allowed = ['popular''price_asc''price_desc''new''rating'];
  142.         return in_array($sort$allowedtrue) ? $sort 'popular';
  143.     }
  144.     private function normalizeCatalogCategory(string $category): string
  145.     {
  146.         $category strtolower(trim($category));
  147.         $allowed = ['all''donate''subscriptions''items''accounts''keys''steam_gift''other''services'];
  148.         return in_array($category$allowedtrue) ? $category 'all';
  149.     }
  150. }