src/WebBundle/Service/LeftMenuService.php line 76

Open in your IDE?
  1. <?php
  2. namespace WebBundle\Service;
  3. use FlexApp\Constant\TimeConstant;
  4. use FlexApp\Service\RedisCachePool;
  5. use Symfony\Contracts\Translation\TranslatorInterface;
  6. use WebBundle\Entity\Collection;
  7. use WebBundle\Entity\FilterEntity;
  8. use WebBundle\Enum\LotusCollectionStatusEnum;
  9. use WebBundle\Helper\App;
  10. use WebBundle\Helper\HideFactoryCountriesHelper;
  11. use WebBundle\Helper\LocaleHelper;
  12. use WebBundle\Helper\RequestHelper;
  13. use WebBundle\Helper\StrHelper;
  14. use WebBundle\Repository\CollectionRepository;
  15. use WebBundle\Repository\FactoryRepository;
  16. use WebBundle\Repository\FilterRepository;
  17. use WebBundle\Repository\PublicationRepository;
  18. class LeftMenuService
  19. {
  20.     /** @required */
  21.     public SphinxSearcherService $sphinxSearcherService;
  22.     /** @required */
  23.     public CollectionRepository $collectionRepository;
  24.     /** @required */
  25.     public FactoryRepository $factoryRepository;
  26.     /** @required */
  27.     public FilterRepository $filterRepository;
  28.     /** @required */
  29.     public PublicationRepository $publicationRepository;
  30.     /** @required */
  31.     public TranslatorInterface $translator;
  32.     public function getDataMenuLite(): array
  33.     {
  34.         /** @var Collection $coll */
  35.         $route RequestHelper::get('_route');
  36.         $searchParams = [];
  37.         $locale App::getCurLocale();
  38.         $localeUc ucfirst($locale);
  39.         $showReset false;
  40.         // Разделитель ключей фильтров (новый/старый) — для корректного парсинга выбранных фильтров
  41.         $sepNew '--';
  42.         $sepOld '&';
  43.         try {
  44.             $sepNewParam App::getParameter('filters.separator.new');
  45.             if (is_string($sepNewParam) && $sepNewParam !== '') {
  46.                 $sepNew $sepNewParam;
  47.             }
  48.         } catch (\Throwable $e) {
  49.             // noop
  50.         }
  51.         try {
  52.             $sepOldParam App::getParameter('filters.separator.old');
  53.             if (is_string($sepOldParam) && $sepOldParam !== '') {
  54.                 $sepOld $sepOldParam;
  55.             }
  56.         } catch (\Throwable $e) {
  57.             // noop
  58.         }
  59.         // тут получаем полную выборку для калькулятора по стране //пересчет делать через ajax
  60.         $redisCachePool App::getContainer()->get(RedisCachePool::class)->getPool();
  61.         $memKeyCalc 'all_calculate_' App::getCurCountry() . '_' LocaleHelper::getUserMeasure(); //этот кеш пересечета фильтра ToDO добавить в команду php bin/console sphinx:count
  62.         $memcKeyCountColl 'collection_count_not_filtered' App::getCurCountry();
  63.         $allCalculate $redisCachePool->getItem($memKeyCalc);
  64.         if ($allCalculate->isHit()) {
  65.             $calculate $allCalculate->get();
  66.         } else {
  67.             $calculate false;
  68.         }
  69.         $countCollItem $redisCachePool->getItem($memcKeyCountColl);
  70.         //это только количество колекций в стране, загружаются же левые через ajax
  71.         if (!$countCollItem->isHit()) {
  72.             $aColls $this->collectionRepository->getCollections([
  73.                 'order' => 'c.id',
  74.                 'onlyCF' => true,
  75.                 'leftCollectionCount' => true,
  76.                 'locale' => $locale,
  77.             ]);
  78.             $countColl count($aColls);
  79.         } else {
  80.             $countColl $countCollItem->get();
  81.         }
  82.         $collection = [
  83.             'name' => 'collection',
  84.             'alias' => 'left_menu_collections',
  85.             'first' => $this->translator->trans('left_menu_collections'),
  86.             'type' => 'select',
  87.             'selected' => null,
  88.             'count' => $countColl,
  89.             'countCur' => $countColl,
  90.             'list' => [],
  91.         ];
  92.         // без учета скрытых фабрик как оказалось не только скрытых но и тех что не выводим колекции по какимто причинам
  93.         $countFactory $calculate count($calculate['factory']) : $this->filterRepository->getBrand(['count' => 1]);
  94.         // формирование подсказки для быстрых образцов
  95.         $expressSampleTooltip null;
  96.         if ($estLink $this->publicationRepository->getUrlBlogExpressSamples()) {
  97.             $linkMore $this->translator->trans('how_to_order_sample');
  98.             $linkMore "<a href=\"$estLink\" target='_blank' onclick=\"event.stopPropagation()\">$linkMore</a>";
  99.             $estTxt $this->translator->trans('menu.express_delivery.tooltip', ['%link_more%' => $linkMore]);
  100.             $expressSampleTooltip = [
  101.                 'url' => $estLink,
  102.                 'text' => $estTxt,
  103.             ];
  104.         }
  105.         //////////////////////////////////////////////////////////
  106.         $filters = [
  107.             // фабрики
  108.             'factory' => [
  109.                 'name' => 'factory',
  110.                 'alias' => 'left_menu_factories',
  111.                 'title' => $this->translator->trans('left_menu_factories'),
  112.                 'first' => $this->translator->trans('left_menu_factories'),
  113.                 'type' => 'select',
  114.                 'selected' => null,
  115.                 'count' => $countFactory,
  116.                 'countCur' => $countFactory,
  117.                 //'countNew' => $countNewFactory,//новые фабрики не нужны
  118.                 'list' => [],
  119.             ],
  120.             // Фактура под
  121.             'getFacturas' => [
  122.                 'name' => 'effect',
  123.                 'alias' => 'left_menu_effect',
  124.                 'title' => $this->translator->trans('left_menu_effect'),
  125.                 'first' => $this->translator->trans('left_all_effect'),
  126.                 'type' => 'checkbox',
  127.                 'selected' => null,
  128.                 'list' => [],
  129.             ],
  130.             'getStone' => [
  131.                 'name' => 'effect',
  132.                 'alias' => 'left_menu_effect',
  133.                 'title' => $this->translator->trans('left_menu_effect'),
  134.                 'first' => $this->translator->trans('left_all_effect'),
  135.                 'type' => 'checkbox',
  136.                 'selected' => null,
  137.                 'list' => [],
  138.             ],
  139.             // Стиль
  140.             'getStyles' => [
  141.                 'name' => 'style',
  142.                 'alias' => 'left_menu_style',
  143.                 'title' => $this->translator->trans('left_menu_style'),
  144.                 'first' => $this->translator->trans('left_all_style'),
  145.                 'type' => 'checkbox',
  146.                 'selected' => null,
  147.                 'list' => [],
  148.             ],
  149.             // Цена руб/м2
  150.             'getCostCategory' => [
  151.                 'name' => 'price',
  152.                 'alias' => 'left_menu_price',
  153.                 'title' => $this->translator->trans('left_menu_price'),
  154.                 'first' => $this->translator->trans('left_all_price'),
  155.                 'type' => 'checkbox',
  156.                 'selected' => null,
  157.                 'list' => [],
  158.             ],
  159.             // Цвет
  160.             'getColors' => [
  161.                 'name' => 'color',
  162.                 'alias' => 'left_menu_color',
  163.                 'title' => $this->translator->trans('left_menu_color'),
  164.                 'first' => $this->translator->trans('left_all_color'),
  165.                 'type' => 'checkbox',
  166.                 'selected' => null,
  167.                 'list' => [],
  168.             ],
  169.             // Цвет
  170.             'getTypeUsings' => [
  171.                 'name' => 'using',
  172.                 'alias' => 'left_menu_use',
  173.                 'title' => $this->translator->trans('left_menu_use'),
  174.                 'first' => $this->translator->trans('left_all_use'),
  175.                 'type' => 'checkbox',
  176.                 'selected' => null,
  177.                 'list' => [],
  178.             ],
  179.             // Экспресс образцы
  180.             'expressSample' => [
  181.                 'name' => 'expressSample',
  182.                 'alias' => 'articleQuickSample',
  183.                 'title' => $this->translator->trans('articleQuickSample'),
  184.                 'first' => $this->translator->trans('articleQuickSample'),
  185.                 'type' => 'checkbox',
  186.                 'selected' => null,
  187.                 'tooltip' => $expressSampleTooltip,
  188.                 'list' => [],
  189.             ],
  190.         ];
  191.         $queryKeys = [];
  192.         if ($route == 'app_catalog' || $route == 'app_catalog_short') {
  193.             $key = (string) RequestHelper::get('key');
  194.             if ($sepOld !== $sepNew) {
  195.                 $key str_replace($sepOld$sepNew$key);
  196.             }
  197.             $queryKeys array_values(array_filter(explode($sepNew$key), static fn ($v) => $v !== ''));
  198.         }
  199.         if ($route == 'app_collection' || $route == 'app_tile') {
  200.             $collUrl RequestHelper::get('collectionUrl');
  201.             $factUrl StrHelper::toLower(RequestHelper::get('factoryUrl'));
  202.             $factId $this->factoryRepository->getIdByUrl($factUrl);
  203.             if ($collUrl) {
  204.                 $coll $this->collectionRepository->findOneBy(['url' => $collUrl'factory' => $factId,]);
  205.                 if (
  206.                     $coll
  207.                     && ($coll->getStatus() == LotusCollectionStatusEnum::PUBLISHED
  208.                         || $coll->getStatus() == LotusCollectionStatusEnum::DISCONTINUED
  209.                         || $coll->getStatus() == LotusCollectionStatusEnum::TEMPORARY_NOT_PUBLISHED
  210.                     )
  211.                 ) {
  212.                     $oFactory $coll->getFactory()->getFilter();
  213.                     if ($oFactory) {
  214.                         $queryKeys[] = $factUrl;
  215.                         $rowCollection = [
  216.                             'id' => $coll->getId(),
  217.                             'url' => $coll->getUrl(),
  218.                             'name' => $coll->getName(),
  219.                             'dataLink' => App::generateUrl(
  220.                                 'app_collection',
  221.                                 [
  222.                                     'factoryUrl' => $factUrl,
  223.                                     'collectionUrl' => $coll->getUrl(),
  224.                                 ]
  225.                             ),
  226.                             'factory' => [
  227.                                 'id' => $oFactory->getOldId(),
  228.                                 'name' => $oFactory->getCountry()->getPage()->{'getNameMenu' ucfirst($locale)}(),
  229.                             ],
  230.                         ];
  231.                         $collection['selected'] = $rowCollection;
  232.                         $searchParams['collection'] = $rowCollection;
  233.                         $filters['factory']['countCur'] = 1;
  234.                     }
  235.                 }
  236.             }
  237.             // получение доп фильтров коллекции, для передачи в короткое меню
  238.             $filterKeys RequestHelper::get('elementId');
  239.             if ($filterKeys) {
  240.                 $filterKeys = (string) $filterKeys;
  241.                 if ($sepOld !== $sepNew) {
  242.                     $filterKeys str_replace($sepOld$sepNew$filterKeys);
  243.                 }
  244.                 $filterKeys array_values(array_filter(explode($sepNew$filterKeys), static fn ($v) => $v !== ''));
  245.                 $queryKeys array_merge($queryKeys$filterKeys);
  246.             }
  247.         }
  248.         $aFilters $this->filterRepository->getArrListForMenu(
  249.             ['effect''style''samples''price''color''using''brand'],
  250.             $locale
  251.         );
  252.         $subFilter = [];
  253.         /** @var FilterEntity $filter */
  254.         foreach ($aFilters as $aFilter) {
  255.             foreach ($aFilter as $filter) {
  256.                 if (!empty($filters[$filter['oldCommand']])) {
  257.                     $url $filter['url' $localeUc];
  258.                     $name $filter['pageNameMenu' $localeUc];
  259.                     if (!$name) {
  260.                         continue;
  261.                     }
  262.                     // костыль для фильтра цен, что бы показывать верно для разных стран
  263.                     if ($filter['groupsAltName'] == 'price') {
  264.                         $name LocaleHelper::getNamePriceFilter($name$locale);
  265.                     }
  266.                     //удаляем фильтры которые и есть и нет если был пересчет например https://tile.expert/en-us/advanced-search?c=/en-us/catalogue/price-under-10
  267.                     if ($calculate && (empty($calculate[$filter['oldCommand']]) || empty($calculate[$filter['oldCommand']][$filter['id']]))) {
  268.                         continue;
  269.                     }
  270.                     $row = [
  271.                         'id' => $filter['oldId'],
  272.                         'fid' => $filter['id'],
  273.                         'pid' => $filter['pid'],
  274.                         'groups' => $filter['groupsAltName'],
  275.                         'url' => $url,
  276.                         'alias' => $filter['leftMenu'],
  277.                         'important' => $filter['important'],
  278.                         'name' => $name,
  279.                         'selected' => [],
  280.                         'count' => !empty($calculate[$filter['oldCommand']]) && !empty($calculate[$filter['oldCommand']][$filter['id']]) ? $calculate[$filter['oldCommand']][$filter['id']] : $filter['paramCount'],
  281.                         //'new_count' =>!empty($calculate[$filter['oldCommand']]) && !empty($calculate[$filter['oldCommand']][$filter['id']]) ? $calculate[$filter['oldCommand']][$filter['id']] : 0,
  282.                         'sub' => [],
  283.                     ];
  284.                     if (!empty($filter['country'])) {
  285.                         $row['country'] = [
  286.                             'id' => $filter['country']['oldId'],
  287.                             'name' => $this->translator->trans($filter['country']['leftMenu']),
  288.                         ];
  289.                     }
  290.                     if (in_array($row['url'], $queryKeys)) {
  291.                         $showReset true;
  292.                         $row['selected'] = $row['url'];
  293.                         $filters[$filter['oldCommand']]['selected'] = $row;
  294.                         if ($filter['oldCommand'] == 'factory') {
  295.                             $collection['countCur'] = $this->collectionRepository->countCollections(['factoryId' => $row['id']]);
  296.                         }
  297.                     }
  298.                     // не кладём в список фабрики
  299.                     if ($filter['oldCommand'] != 'factory') {
  300.                         if ($filter['pid'] != null) {
  301.                             if ($filter['id'] != '10147') {
  302.                                 $subFilter[$row['pid']][$row['fid']] = $row;
  303.                             }
  304.                         } else {
  305.                             $filters[$filter['oldCommand']]['list'][] = $row;
  306.                         }
  307.                     }
  308.                 }
  309.             }
  310.         }
  311.         $factory $filters['factory'];
  312.         unset($filters['factory']);
  313.         $searchParams['factory'] = $factory;
  314.         $filters $this->addSubFilters($filters$subFilter);
  315.         return [
  316.             'locale' => $localeUc,
  317.             'searchParams' => $searchParams,
  318.             'filters' => $filters,
  319.             'collection' => $collection,
  320.             'brand' => $factory,
  321.             'showReset' => $showReset,
  322.             'countryList' => App::getCountryList(),
  323.         ];
  324.     }
  325.     /**
  326.      * Вставляем вложенные фильтры, если есть такие
  327.      *
  328.      * @param array $filterGroups
  329.      * @param array $subFilter
  330.      * @return array
  331.      */
  332.     private function addSubFilters(array $filterGroups, array $subFilter): array
  333.     {
  334.         $filterGroups array_filter($filterGroups, static fn(array $group) => !empty($group['list']));
  335.         foreach ($filterGroups as &$filterGroup) {
  336.             foreach ($filterGroup['list'] as $key => &$filter) {
  337.                 if (!empty($subFilter[$filter['fid']])) {
  338.                     //если родитель выбран, то и дети выбраны
  339.                     if (!empty($filter['selected'])) {
  340.                         $filter['selected'] = [];
  341.                         foreach ($subFilter[$filter['fid']] as $sk => $sv) {
  342.                             $subFilter[$filter['fid']][$sk]['selected'] = $subFilter[$filter['fid']][$sk]['url'];
  343.                             $filterGroup['selected'][] = $subFilter[$filter['fid']][$sk];
  344.                         }
  345.                     }
  346.                     $filter['sub'] = array_values($subFilter[$filter['fid']]);
  347.                 }
  348.             }
  349.         }
  350.         return $filterGroups;
  351.     }
  352. }