src/WebBundle/Service/CollectionService.php line 768

Open in your IDE?
  1. <?php
  2. namespace WebBundle\Service;
  3. use AdmBundle\Helper\StrAdm;
  4. use Exception;
  5. use FlexApp\Constant\TimeConstant;
  6. use FlexApp\Entity\CommentEntity;
  7. use FlexApp\Service\LastUrlService;
  8. use FlexApp\Service\RedisCachePool;
  9. use Import1CBundle\Helper\v3\BiConst;
  10. use Import1CBundle\Helper\v3\TranslitNameHelper;
  11. use Monolog\Logger;
  12. use Symfony\Component\HttpFoundation\RedirectResponse;
  13. use Symfony\Component\HttpFoundation\Request;
  14. use Symfony\Component\HttpFoundation\Response;
  15. use Symfony\Component\HttpFoundation\Session\Session;
  16. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  17. use WebBundle\Entity\Article;
  18. use WebBundle\Entity\Collection;
  19. use WebBundle\Entity\FilterEntity;
  20. use WebBundle\Helper\App;
  21. use WebBundle\Helper\ArrHelper;
  22. use WebBundle\Helper\FilterHelper;
  23. use WebBundle\Helper\LocaleHelper;
  24. use WebBundle\Helper\PathHelper;
  25. use WebBundle\Helper\StrHelper;
  26. use WebBundle\Helper\TranslitHelper;
  27. use WebBundle\Helper\UserHelper;
  28. use WebBundle\Repository\ArticleRepository;
  29. use WebBundle\Repository\CollectionRepository;
  30. use WebBundle\Repository\FilterRepository;
  31. use WebBundle\Repository\InteriorRepository;
  32. class CollectionService extends ExtendService
  33. {
  34.     /** @required */
  35.     public LastUrlService $lastUrlService;
  36.     /** @required */
  37.     public CollectionRepository $collectionRepository;
  38.     /** @required */
  39.     public FilterRepository $filterRepository;
  40.     /** @required */
  41.     public FiltersService $filtersService;
  42.     /** @var Request $oRequest */
  43.     protected $oRequest;
  44.     /** @var Session $oSession */
  45.     protected $oSession;
  46.     /** Текущая локаль запроса */
  47.     protected string $sLocale;
  48.     private Logger $oLogger;
  49.     private array $readySettings = [];
  50.     public function __construct(Logger $logger)
  51.     {
  52.         $this->oSession App::getContainer()->get('session');
  53.         $this->oRequest App::getRequest();
  54.         $this->sLocale $this->oRequest->getLocale();
  55.         $this->oLogger $logger;
  56.     }
  57.     /**
  58.      * @param string $unid
  59.      * @return array
  60.      * @throws Exception
  61.      */
  62.     public function getCommentsCountData(string $unid): array
  63.     {
  64.         $commentRepo App::em()->getRepository(CommentEntity::class);
  65.         return [
  66.             'questions' => $commentRepo->getCommentCountData($unidApp::getCurLocale(), false),
  67.             'answers' => $commentRepo->getCommentCountData($unidApp::getCurLocale())
  68.         ];
  69.     }
  70.     /**
  71.      * Залипуха, что бы количество коллекций было одинаковым в разных местах, если нет фильтрации
  72.      * @return int
  73.      * @throws Exception
  74.      */
  75.     public function countNotFilteredCollection(): int
  76.     {
  77.         $redisCachePool App::getContainer()->get(RedisCachePool::class)->getPool();
  78.         $memKey 'collection_count_not_filtered'App::getCurCountry(); //ну как же без учета страны?
  79.         $cntItem $redisCachePool->getItem($memKey);
  80.         if (!$cntItem->isHit()) {
  81.             $data = [
  82.                 'searchFilter' => [],
  83.                 'searchSort' => 1,
  84.                 'searchPeriod' => null,
  85.                 'locale' => App::getCurLocale(),
  86.             ];
  87.             $aRes App::searchSphinx($data300false);
  88.             $cnt count($aRes);
  89.             $cntItem->set($cnt);
  90.             $cntItem->expiresAfter(86400);
  91.             $redisCachePool->save($cntItem);
  92.         }else{
  93.             $cnt=$cntItem->get();
  94.         }
  95.         return (int)$cnt;
  96.     }
  97.     /**
  98.      * @param $coll
  99.      * @param bool $flag
  100.      * @param string $format
  101.      * @param null $locale
  102.      * @return array|Response|null
  103.      * @throws Exception
  104.      */
  105.     public function settingsListAction($collbool $flag falsestring $format 'html'$locale null)
  106.     {
  107.         $settings = [];
  108.         $marker = [];
  109.         $offShade = [];
  110.         $sliding = [];
  111.         $nonSlip false;
  112.         $authorLink false;
  113.         $locale $locale $locale App::getCurLocale();
  114.         /** @var ArticleRepository $repoArticle */
  115.         $repoArticle App::getRepository('WebBundle:Article');
  116.         /** @var InteriorRepository $repoInterior */
  117.         $repoInterior App::getRepository('WebBundle:Interior');
  118.         /** @var $collectionRepository CollectionRepository */
  119.         $collectionRepository App::getRepository('WebBundle:Collection');
  120.         if (is_array($coll)) {
  121.             $collection $coll;
  122.             $collectionAuthor $collection['author'];
  123.             $collection['interiors'] = $repoInterior->getInteriorsByCollection($coll['id']);
  124.             $collection['articles'] = $repoArticle->getArticleByCollection($coll['id']);
  125.             $exhibitions = !empty($collection['exhibition']) ? $collection['exhibition'] : [];
  126.         } else {
  127.             $collection['articles'] = $repoArticle->getArticleByCollection($coll);
  128.             $collection['interiors'] = $repoInterior->getInteriorsByCollection($coll);
  129.             /** @var Collection $collection */
  130.             $collectionAuthor $collectionRepository->getCollAuthor($coll);
  131.             $exhibitions $collection->getExhibition()->toArray();
  132.         }
  133.         // приводим дизайнеров к массиву
  134.         if ($collectionAuthor and !is_array($collectionAuthor)) {
  135.             $collectionAuthor explode(','$collectionAuthor);
  136.             $collectionAuthor array_map('trim'$collectionAuthor);
  137.             $collectionAuthor array_diff($collectionAuthor, ['']);
  138.         }
  139.         // смотрим интерьеры если accessible не TRUE
  140.         if (!$collection['accessible']) {
  141.             foreach ($collection['interiors'] as $interior) {
  142.                 if (!empty($interior['applies'])) {
  143.                     $settings $this->parseFiltersForSettings($interior['applies'], $settings'getUsings'$collectionAuthor);
  144.                 }
  145.                 if (!empty($interior['styles'])) {
  146.                     $settings $this->parseFiltersForSettings($interior['styles'], $settings'getStyles'$collectionAuthor);
  147.                 }
  148.                 if (!empty($interior['textures'])) {
  149.                     foreach ($interior['textures'] as $i => $texture) {
  150.                         if ($texture['alias'] == 'left_menu_mono_color') {
  151.                             $settings $this->parseFiltersForSettings($texture$settings'getColors'$collectionAuthor);
  152.                         } else {
  153.                             $settings $this->parseFiltersForSettings($texture$settings'getFacturas'$collectionAuthor);
  154.                         }
  155.                     }
  156.                 }
  157.             }
  158.         }
  159.         /** @var Article|array $article */
  160.         foreach ($collection['articles'] as $article) {
  161.             // /en/tile/Serenissima-Cir/Marble-Style
  162.             if (!empty($article['pei'])) {
  163.                 $settings $this->parseFiltersForSettings($article$settings'Pei'$collectionAuthor);
  164.             }
  165.             if (!empty($article['style'])) {
  166.                 $settings $this->parseFiltersForSettings($article['style'], $settings'getStyles'$collectionAuthor);
  167.             }
  168.             if (!empty($article['type']) && $article['type']['id'] == 24) {
  169.                 $article['type']['name'] = App::getTranslator()->trans($article['type']['alias']);
  170.                 $settings $this->parseFiltersForSettings($article['type'], $settings'getType'$collectionAuthor);
  171.             }
  172.             if (!empty($article['material'])) {
  173.                 if ($article['thinGranite'] == 1) {
  174.                     $article['material']['name'] = App::getTranslator()->trans('left_menu_thin_porcelain_tile');
  175.                 } else {
  176.                     $article['material']['name'] = App::getTranslator()->trans($article['material']['alias']);
  177.                 }
  178.                 $settings $this->parseFiltersForSettings($article['material'], $settings'getMaterials'$collectionAuthor);
  179.             }
  180.             // пока так сделал.
  181.             if (!empty($article['using']) && $article['using']['hide'] == 0) {
  182.                 $name $locale != 'de' ?
  183.                     mb_convert_case(App::getTranslator()->trans($article['using']['alias']), MB_CASE_LOWER"UTF-8") :
  184.                     App::getTranslator()->trans($article['using']['alias']);
  185.                 $code FilterHelper::normaliseAltName($name);
  186.                 $searchLink $name;
  187.                 $searchLink str_replace([' ''-'], '_'StrHelper::toLower($searchLink));
  188.                 $link FilterHelper::getUrl($searchLink$locale);
  189.                 $val = [
  190.                     'name' => $name,
  191.                     'link' => $this->fixLink($link),
  192.                 ];
  193.                 if (empty($settings['getTypeUsings']) || (!in_array(
  194.                             $val,
  195.                             $settings['getTypeUsings']
  196.                         ) && ($article['using']['id'] == || !in_array(4$marker['getTypeUsings'])))
  197.                 ) {
  198.                     if ($article['using']['id'] == 4) {
  199.                         $settings['getTypeUsings'][$article['using']['alias']] = $val;
  200.                         $marker['getTypeUsings'][$code] = $article['using']['id'];
  201.                     } else {
  202.                         $settings['getTypeUsings'][$article['using']['alias']] = $val;
  203.                         $marker['getTypeUsings'][$code] = $article['using']['id'];
  204.                     }
  205.                 }
  206.             }
  207.             if (!empty($article['surface'])) {
  208.                 if ($article['surface']['id'] == 8) {
  209.                     $article['surface']['name'] = App::getTranslator()->trans('catalog.options.non_slip');
  210.                 } else {
  211.                     $article['surface']['name'] = App::getTranslator()->trans($article['surface']['alias']);
  212.                 }
  213.                 $settings $this->parseFiltersForSettings($article['surface'], $settings'getSurfaces'$collectionAuthor);
  214.                 if ($article['surface']['id'] == 8) {
  215.                     $name App::getTranslator()->trans($article['surface']['alias']);
  216.                     $nonSlip FilterHelper::normaliseAltName($name);
  217.                 }
  218.             }
  219.             if (!empty($article['textures'])) {
  220.                 foreach ($article['textures'] as $i => $texture) {
  221.                     if ($texture['alias'] == 'left_menu_mono_color') {
  222.                         $settings $this->parseFiltersForSettings($texture$settings'getColors'$collectionAuthor);
  223.                     } else {
  224.                         $settings $this->parseFiltersForSettings($texture$settings'getFacturas'$collectionAuthor);
  225.                     }
  226.                 }
  227.             }
  228.             if (!empty($article['edgeType'])) {
  229.                 $settings $this->parseFiltersForSettings($article['edgeType'], $settings'getEdgeType'$collectionAuthor);
  230.             }
  231.             if (!empty($article['sliding']) && !empty($article['sliding']['id'])) {
  232.                 $elem = [
  233.                     'name' => 'R' $article['sliding']['id'],
  234.                     'title' => App::getTranslator()->trans(
  235.                         'catalog.options.non_slip_rating',
  236.                         ['%d%' => 'R' $article['sliding']['id']]
  237.                     ),
  238.                 ];
  239.                 if (!in_array($elem$sliding)) {
  240.                     $sliding[] = $elem;
  241.                 }
  242.             }
  243.             if (!empty($article['offShade'])) {
  244.                 if (!in_array('V' $article['offShade']['id'], $offShade)) {
  245.                     $offShade[] = 'V' $article['offShade']['id'];
  246.                 }
  247.             }
  248.         }
  249.         if (!empty($settings['getStylesDesigners']) and !empty($settings['getStyles'])) {
  250.             unset($settings['getStyles']['left_menu_designer']);
  251.             if (isset($settings['getStyles'])) {
  252.                 unset($settings['getStyles']);
  253.             }
  254.         }
  255.         if ($nonSlip !== false) {
  256.             $settings['getSurfaces'][$nonSlip]['list'] = $sliding;
  257.         }
  258.         if (count($offShade) > 0) {
  259.             $nm App::getTranslator()->trans('catalog.options.shade_variation', ['%d%' => implode(', '$offShade)]);
  260.             $settings['offShade'][] = [
  261.                 'name' => App::getCurCountry() != 'de' StrHelper::lcFirstOnly($nm) : StrHelper::ucFirstOnly($nm),
  262.                 'link' => null,
  263.             ];
  264.         }
  265.         if (empty($settings['getEdgeType'])) {
  266.             $name App::getTranslator()->trans('left_menu_no_retified');
  267.             $code FilterHelper::normaliseAltName($name);
  268.             $link FilterHelper::getUrl(str_replace([' ''-'], '_'StrHelper::toLower($name)));
  269.             $val = [
  270.                 'name' => $name,
  271.                 'link' => $this->fixLink($link),
  272.             ];
  273.             $settings['getEdgeType'][$code] = $val;
  274.         }
  275.         if (!empty($settings['getSurfaces'])) {
  276.             $surfaceList ArrHelper::get($settings'getSurfaces.antislip_surface.list');
  277.             if (!empty($settings['getSurfaces']['left_menu_antislip']) and $surfaceList) {
  278.                 unset($settings['getSurfaces']['antislip_surface']);
  279.                 $settings['getSurfaces']['left_menu_antislip']['list'] = $surfaceList;
  280.             }
  281.         }
  282.         // перенес дизайнеров в конец, что бы перечислением хоть как то адекватно вписалось к остальным свойствам
  283.         if (!empty($settings['getStylesDesigners'])) {
  284.             $designers $settings['getStylesDesigners'];
  285.             unset($settings['getStylesDesigners']);
  286.             $settings['getStylesDesigners'] = $designers;
  287.         }
  288.         $rankService App::getContainer()->get('app.service.rank');
  289.         if ($exhibitions) {
  290.             $exhibitions array_values($this->filterRepository->getExhibitions($collection['exhibition']));
  291.             foreach ($exhibitions as $i => $e) {
  292.                 $r = [
  293.                     'name' => $e['name'],
  294.                     'title' => $e['tooltip'],
  295.                     'link' => $e['urlLocal'],
  296.                     'nameGroup' => 'exhibition',
  297.                     'rank' => 0,
  298.                 ];
  299.                 $exhibitions[$i] = $r;
  300.             }
  301.             // добавляем хитро в начало
  302.             $settings array_reverse($settingstrue);
  303.             $settings['exhibitions'] = $exhibitions;
  304.             $settings array_reverse($settingstrue);
  305.         }
  306.         $settingsJoin = [];
  307.         foreach ($settings as $k => $row) {
  308.             // выстраиваем в ряд значения PEI, если их больше одного
  309.             if ($k == 'Pei' && count($row) > 1) {
  310.                 $pei = ['name' => 'PEI '];
  311.                 foreach ($row as $item) {
  312.                     $pei['name'] = $pei['name'] . trim(str_replace('PEI'''$item['name'])) . ', ';
  313.                     $pei['link'] = $this->fixLink($item['link']);
  314.                     $pei['title'] = $item['title'];
  315.                     $pei['noLower'] = $item['noLower'];
  316.                 }
  317.                 $pei['name'] = trim(trim($pei['name']), ',');
  318.                 $row = ['pei' => $pei];
  319.             }
  320.             foreach ($row as $i => $item) {
  321.                 $rank ArrHelper::get($item'rank'0);
  322.                 $row[$i]['rank'] = $rank;
  323.                 $row[$i]['size'] = $rankService->fontSizeByRank($rank);
  324.             }
  325.             $settingsJoin array_merge($settingsJoin$row);
  326.         }
  327.         // формируем размеры под свойства на основании RANK
  328.         //////////////////////////////////////////////////////////////
  329.         $rankArr = [];
  330.         foreach ($settingsJoin as $k => $row) {
  331.             // задаем значение для сортировки
  332.             $rankArr[$k] = $row['rank'];
  333.         }
  334.         $settingsSorting $settingsJoin;
  335.         array_multisort($rankArrSORT_DESC$settingsSorting);
  336.         // Формируем пороги для выделения размеров, выделяем первые две четверти
  337.         $cnt count($settingsJoin);
  338.         // количество выделяемых в четверти
  339.         $cnt = (int)ceil($cnt 4);
  340.         $i 0;
  341.         foreach ($settingsSorting as $key => $row) {
  342.             if (StrHelper::isInStr($key'pei_') or $key == 'antislip_surface' or !$key) {
  343.                 $settingsJoin[$key]['size'] = $rankService->fontSizeByRank(50);
  344.             } else {
  345.                 $i++;
  346.                 if ($i <= $cnt) {
  347.                     // первая четверть
  348.                     $settingsJoin[$key]['size'] = $rankService->fontSizeByRank(100);
  349.                 } elseif ($i $cnt and $i <= ($cnt 2)) {
  350.                     // вторая четверть
  351.                     $settingsJoin[$key]['size'] = $rankService->fontSizeByRank(80);
  352.                 } else {
  353.                     //     остальное
  354.                     $settingsJoin[$key]['size'] = $rankService->fontSizeByRank(50);
  355.                 }
  356.             }
  357.         }
  358.         if ($format == 'json') {
  359.             return new Response(json_encode($settingsJoin));
  360.         } elseif ($format == 'array') {
  361.             return $settingsJoin;
  362.         } elseif ($format == 'comby') {
  363.             $html $this->render(
  364.                 '@Web/Collection/setting.html.twig',
  365.                 [
  366.                     'locale' => $locale,
  367.                     'settings' => $settingsJoin,
  368.                     'flag' => $flag,
  369.                     'authorLink' => $authorLink,
  370.                 ]
  371.             );
  372.             $html trim(trim($html), ',');
  373.             return [
  374.                 'html' => $html,
  375.                 'array' => $settingsJoin,
  376.             ];
  377.         } else {
  378.             return new Response($this->render(
  379.                 '@Web/Collection/setting.html.twig',
  380.                 [
  381.                     'locale' => $locale,
  382.                     'settings' => $settingsJoin,
  383.                     'flag' => $flag,
  384.                     'authorLink' => $authorLink,
  385.                 ]
  386.             ));
  387.         }
  388.     }
  389.     /**
  390.      * @param $link
  391.      * @return string|string[]|null
  392.      */
  393.     private function fixLink($link)
  394.     {
  395.         return preg_replace('#/' App::getCurLocale() . '/#isUu''/' App::getCurLocale(true) . '/'$link);
  396.     }
  397.     /**
  398.      * @param array $collection
  399.      * @return string
  400.      * @throws Exception
  401.      */
  402.     public function getSettings(array $collection): string
  403.     {
  404.         $settings '';
  405.         if (!empty($collection['fids'])) {
  406.             $filterGroups $this->filtersService
  407.                 ->loadByIds($collection['fids'], App::getCurLocale())
  408.                 ->buildFilterGroupsDTO();
  409.             // https://te2.remote.team/discus/BA6DD5B6-8F79-DA20-E6E6-7F983685A57D
  410.             $filterGroups
  411.                 ->deleteGroup('apply')
  412.                 ->deleteGroup('material')
  413.                 ->deleteGroup('samples')
  414.                 ->deleteGroup('using')
  415.                 ->deleteGroup('type');
  416.             $settings $this->filtersService->buldFiltersToStr($filterGroupstruefalsefalse);
  417.         }
  418.         return $settings;
  419.     }
  420.     /**
  421.      * @param array $aData
  422.      * @param array $aSettings
  423.      * @param $nameGroup
  424.      * @param null $author
  425.      * @return array
  426.      * @throws Exception
  427.      */
  428.     public function parseFiltersForSettings(array $aData, array $aSettings$nameGroup$author null)
  429.     {
  430.         if ($nameGroup == 'Pei') {
  431.             $aSettings $this->parsePeiForSettings($aData$aSettings);
  432.         } else {
  433.             $aSettings $this->parseBaseForSettings($aData$aSettings$nameGroup$author);
  434.         }
  435.         return $aSettings;
  436.     }
  437.     /**
  438.      * @param array $data
  439.      * @param array $aSettings
  440.      * @return array
  441.      * @throws Exception
  442.      */
  443.     private function parsePeiForSettings(array $data, array $aSettings)
  444.     {
  445.         $code FilterHelper::normaliseAltName($data['pei']);
  446.         if (!ArrHelper::get($aSettings'Pei.' $code)) {
  447.             $val = [
  448.                 'name' => $data['pei'],
  449.                 'link' => '',
  450.                 'title' => App::getTranslator()->trans('catalog.options.pei'),
  451.                 'noLower' => true,
  452.                 'rank' => 50,
  453.             ];
  454.             $aSettings['Pei'][$code] = $val;
  455.         }
  456.         return $aSettings;
  457.     }
  458.     /**
  459.      * @param array $aData
  460.      * @param array $aSettings
  461.      * @param $nameGroup
  462.      * @param null $author
  463.      * @return array
  464.      * @throws Exception
  465.      */
  466.     private function parseBaseForSettings(array $aData, array $aSettings$nameGroup$author null)
  467.     {
  468.         $aData = !ArrHelper::get($aData"0.id") ? [$aData] : $aData;
  469.         $lcFull App::getCurLocale(true);
  470.         $linkCatalog $url $this->generateUrl('app_catalog', ['_locale' => $lcFull]);
  471.         foreach ($aData as $data) {
  472.             // оптимизируем, проверяя на дубли свойств
  473.             $keyReady $nameGroup $data['id'];
  474.             if (in_array($keyReady$this->readySettings)) {
  475.                 continue;
  476.             }
  477.             $this->readySettings[] = $keyReady;
  478.             if ($nameGroup == 'getType') {
  479.                 $nameGroup 'getTypes';
  480.                 // фикс для моноколор
  481.             } elseif ($nameGroup == 'getFacturas' and $data['id'] == '99') {
  482.                 $nameGroup 'getColors';
  483.                 // фикс не верноого фильтра для типа карая Неректифицированный
  484.             } elseif ($nameGroup == 'getEdgeType' and $data['id'] == '5') {
  485.                 $data['id'] = 4;
  486.                 // спрятал из свойств стиль модерн по просьбе Жени https://te.remote.team/#/discus/89E08181-AE1F-67AC-0FA3-EDACFF049082/
  487.             } elseif ($nameGroup == 'getStyles' and $data['id'] == '11') {
  488.                 unset($aSettings[$nameGroup]);
  489.                 continue;
  490.             } elseif ($nameGroup == 'getFacturas') {
  491.                 // фактуры объемная и состаренная стали объемной и состаренной поверхностями.
  492.                 // https://te.remote.team/#/discus/07F31922-2ADC-9129-5616-86112BCFD072/
  493.                 if ($data['id'] == '14') {
  494.                     $nameGroup 'getSurfaces';
  495.                     $data['id'] = 11;
  496.                 } elseif ($data['id'] == '11') {
  497.                     $nameGroup 'getSurfaces';
  498.                     $data['id'] = 12;
  499.                 }
  500.             }
  501.             $code FilterHelper::normaliseAltName($data['alias']);
  502.             //App::dump($data, $aSettings, $nameGroup, "{$nameGroup}." . $code , $code);
  503.             if (!ArrHelper::get($aSettings"{$nameGroup}.{$code}")) {
  504.                 $filter $this->filterRepository->findFilterForSettingsColletion($data['id'], $nameGroup);
  505.                 if ($filter) {
  506.                     $link $this->generateUrl('app_catalog', ['_locale' => $lcFull'key' => $filter['url']]);
  507.                     $name $filter['name'];
  508.                     // фикс для DE локали, там нужны заглавные
  509.                     if (App::getCurLocale() == 'de') {
  510.                         $name ucfirst($name);
  511.                     }
  512.                     // Если ссылка ведет на главную каталога, значит проблема. пишем в лог
  513.                     if ($link == $linkCatalog) {
  514.                         $this->oLogger->critical("[bad_collection_settings_link] nameGroup: {$nameGroup}, name: {$name}, alias: {$data['alias']}, url: {$this->oRequest->getRequestUri()}");
  515.                     }
  516.                     if (ArrHelper::get($aData'hide')) {
  517.                         $link '';
  518.                     }
  519.                     $link str_replace("?_locale={$lcFull}"''$link);
  520.                     $val = [
  521.                         'name' => $name,
  522.                         'link' => $link,
  523.                         'nameGroup' => $nameGroup,
  524.                         'rank' => ArrHelper::get($filter'rank'50),
  525.                     ];
  526.                     $aSettings[$nameGroup][$code] = $val;
  527.                 } else {
  528.                     // если фильтр не найден, тоже пишем в лог
  529.                     $this->oLogger->critical("[bad_collection_settings_link] NOT FOUND nameGroup: {$nameGroup}, id: {$data['id']}, alias: {$data['alias']}, url: {$this->oRequest->getRequestUri()}");
  530.                 }
  531.             }
  532.             // по старому ID стиля определяем дизайнеровский и выводим дизайнеров
  533.             if ($data['id'] == 17) {
  534.                 $authors $author $author : [];
  535.                 foreach ($authors as $i => $authorLink) {
  536.                     $authorLink trim($authorLink);
  537.                     $fAltName FilterHelper::normaliseAltName($authorLink);
  538.                     $code StrHelper::toLower($fAltName);
  539.                     if (!ArrHelper::get($aSettings'getStylesDesigners.' $code)) {
  540.                         // формируем заголовок для дизайнера со всякими приставками и ссылками
  541.                         $key $this->filterRepository->getKeyDesignerStyle();
  542.                         $href App::getRouter()->generate('app_catalog', ['key' => $key]);
  543.                         $header App::getTranslator()->trans('collection_header_designer');
  544.                         $replace FilterEntity::REPLACE_DESIGNE_RUSER;
  545.                         $replace $replace '|' StrHelper::toLower($replace);
  546.                         $header preg_replace_callback("/{$replace}/i", function ($matches) use ($href) {
  547.                             $name $matches[0];
  548.                             return "<a href=\"{$href}\">#{$name}</a>";
  549.                         }, $header);
  550.                         if ($i != 0) {
  551.                             $header null;
  552.                         }
  553.                         $val = [
  554.                             'header' => $header,
  555.                             'name' => $authorLink,
  556.                             'link' => $this->fixLink(FilterHelper::getUrl($fAltName)),
  557.                             'url' => $this->fixLink(FilterHelper::getUrl($fAltName)),
  558.                             'authorLink' => $authorLink,
  559.                         ];
  560.                         $aSettings['getStylesDesigners'][$code] = $val;
  561.                     }
  562.                 }
  563.             }
  564.         }
  565.         //App::dump($aSettings);
  566.         return $aSettings;
  567.     }
  568.     /**
  569.      * Получаем валидную коллекцию из базы
  570.      * @param $factoryUrl
  571.      * @param $collectionUrl
  572.      * @return array
  573.      * @throws Exception
  574.      */
  575.     public function findCollectionInDb($factoryUrl$collectionUrl): array
  576.     {
  577.         // Получаем коллекцию по редиректу
  578.         $curRoute App::getRequest()->get('_route');
  579.         $params App::getRequest()->get('_route_params');
  580.         $currentUrl App::getRequest()->getUri();
  581.         // перенаправляем те, что с _  на -,
  582.         $searchChar '_';
  583.         $changeChar '-';
  584.         $collUrl str_replace($searchChar$changeChar$collectionUrl);
  585.         $facUrl str_replace($searchChar$changeChar$factoryUrl);
  586.         if ($factoryUrl != $facUrl || $collectionUrl != $collUrl) {
  587.             $params['factoryUrl'] = $facUrl;
  588.             $params['collectionUrl'] = $collUrl;
  589.             $url $this->generateUrl($curRoute$params);
  590.             // если есть параметр gclid (добавляется AdWords), то оставляем его
  591.             if (strpos($currentUrl'gclid')) {
  592.                 $gclid substr($currentUrlstrpos($currentUrl'?gclid'));
  593.                 $url $url $gclid;
  594.             }
  595.             $redirect = new RedirectResponse(urldecode($url), 301);
  596.             return ['return' => $redirect];
  597.         }
  598.         $collection $this->collectionRepository->getMainBaseCollectionLight($factoryUrl$collectionUrl);
  599.         // проверка на сменный URL коллекции
  600.         if (!$collection) {
  601.             $redirect $this->lastUrlService->getCollectionRedirectUrl($collectionUrl$factoryUrl);
  602.             if ($redirect) {
  603.                 $response = new RedirectResponse($redirect);
  604.                 return ['return' => $response];
  605.             }
  606.         }
  607.         $collection $this->getMainBaseCollectionHandler($collection);
  608.         // Получаем коллекцию без фильтрации по статусу, и фильтруем руками, отдавая свою заглушку вместо стандартного 404
  609.         if (
  610.             !$collection
  611.             || $collection['status'] != BiConst::STATE_PUBLISHED
  612.             && $collection['status'] != BiConst::STATE_DISCONTINUED
  613.             && $collection['status'] != BiConst::STATE_WORK_CONTINUED
  614.             && $collection['status'] != BiConst::STATE_CHECKING
  615.             && $collection['publishDate'] == null //на основании https://te.remote.team/#/discus/7B2C1D62-1AFC-B81F-1E11-0DABFD79046D/
  616.         ) {
  617.             // сказали не разделять 404 теперь
  618.             throw new NotFoundHttpException('collection not found');
  619.         }
  620.         //на основании https://te.remote.team/#/discus/7B2C1D62-1AFC-B81F-1E11-0DABFD79046D/
  621.         if ($collection['status'] > 3) {
  622.             $collection['status'] = 3;
  623.         }
  624.         $user App::getCurUser();
  625.         if ($collection['testAccess'] && !($user && UserHelper::isEmployee($user->getEmail()))) {
  626.             throw new NotFoundHttpException('collection not found');
  627.         }
  628.         if ($collection['url'] != $collectionUrl || $collection['factory']['url'] != $factoryUrl) {
  629.             $params['factoryUrl'] = TranslitHelper::clearUrl($collection['factory']['url'], true);
  630.             $params['collectionUrl'] = TranslitHelper::clearUrl($collection['url'], true);
  631.             $url $this->generateUrl($curRoute$params);
  632.             // если есть параметр gclid (добавляется AdWords), то оставляем его
  633.             if (strpos($currentUrl'gclid')) {
  634.                 $gclid substr($currentUrlstrpos($currentUrl'?gclid'));
  635.                 $url $url $gclid;
  636.             }
  637.             $asJson App::getRequest()->get('as_json'null);
  638.             if ($asJson) {
  639.                 $url $url '?as_json=1';
  640.             }
  641.             $redirect = new RedirectResponse(urldecode($url), 301);
  642.             return ['return' => $redirect];
  643.         }
  644.         if (!empty($collection['id'])) {//count visits
  645.             $collId $collection['id'];
  646.             $oSession App::getSession();
  647.             $sessionCollData $oSession->get('collectionData');
  648.             //Session has not collId  >so> Collection->setViews(+1) && upd session  else -  continue
  649.             if (empty($sessionCollData[$collId])) {
  650.                 $this->collectionRepository->increaseViewByCollectionId((int) $collId);
  651.                 //upd session
  652.                 $sessionCollData[$collId] = '1';
  653.                 $oSession->set('collectionData'$sessionCollData);
  654.             }
  655.         }
  656.         return ['collection' => $collection];
  657.     }
  658.     /**
  659.      * Получаем строку с примененными фильтрами из FilterService, чистим ее и выдаем почищенную
  660.      * @param SearchService $oSearchService
  661.      * @return mixed|string
  662.      * @throws Exception
  663.      */
  664.     public function getSettingsFiltersCollection(SearchService $oSearchService)
  665.     {
  666.         $oFilterService App::getContainer()->get('app.service.filters');
  667.         $oSearchService->buildPageParams($oFilterService);
  668.         $list $oSearchService->getTitleHtml();
  669.         preg_match_all('#<strong>(.+?)</strong>#is'$list$arr);
  670.         $list trim(ArrHelper::get($arr'0.0'));
  671.         return $list;
  672.     }
  673.     /**
  674.      * Снята с производства коллекция или фабрика закрыта
  675.      * @param array $collection
  676.      * @throws Exception
  677.      */
  678.     public function getAlertMessageIfCollectionInDiscontinuedState(array $collection): ?array
  679.     {
  680.         if ($collection['status'] == BiConst::STATE_DISCONTINUED
  681.             || $collection['factory']['status'] == BiConst::STATE_DISCONTINUED
  682.         ) {
  683.             $msg = [];
  684.             $msg['header'] = App::trans('catalog.alert.header'null, ['%name%' => $collection['name']]);
  685.             if ($collection['factory']['status'] == BiConst::STATE_PUBLISHED) {
  686.                 $msg['body'] = App::trans(
  687.                     'catalog.alert.msg_factory',
  688.                     null,
  689.                     [
  690.                         '%factory%' => $collection['factory']['name'],
  691.                         '%link%' => $this->generateUrl('app_catalog', [
  692.                             'key' => $collection['factory']['url']
  693.                         ])
  694.                     ]
  695.                 );
  696.             } else {
  697.                 $msg['body'] = App::trans(
  698.                     'catalog.alert.msg_catalog',
  699.                     null,
  700.                     [
  701.                         '%catalogue%' => App::trans('catalog_simple_title'),
  702.                         '%link%' => $this->generateUrl('app_catalog')
  703.                     ]
  704.                 );
  705.             }
  706.             return $msg;
  707.         }
  708.         return null;
  709.     }
  710.     private function getMainBaseCollectionHandler($collection): ?array
  711.     {
  712.         if ($collection && count($collection) > 0) {
  713.             $locale App::getCurLocale();
  714.             $body = !empty($collection['body']) ? $collection['body'][$locale] : null;
  715.             if ($body) {
  716.                 $body LocaleHelper::modifeLinkForLocales($body);
  717.                 $body StrHelper::replaceUmlautChar($body);
  718.                 $body TranslitNameHelper::replacePrime($bodyfalse);
  719.             }
  720.             $collection['body'] = $body;
  721.             $collection['metaKeywords'] = $collection['metaKeywords'] ? $collection['metaKeywords'][$locale] : null;
  722.             $collection['metaDescription'] = $collection['metaDescription'] ? $collection['metaDescription'][$locale] : null;
  723.             if (BiConst::CHOICE_ADDRESS_URL) {
  724.                 $furl StrAdm::toLower($collection['factory']['url']);
  725.                 $collection['factory']['url'] = $furl;
  726.                 $curl StrAdm::toLower($collection['url']);
  727.                 $collection['url'] = $curl;
  728.                 $collection['path'] = PathHelper::getImgWebPath() .
  729.                     $furl '/' .
  730.                     $curl .
  731.                     '/' BiConst::PER_SITO '/';
  732.             } else {
  733.                 $collection['path'] = PathHelper::getImgWebPath() .
  734.                     rawurlencode(TranslitHelper::clearDirName(StrAdm::toLower($collection['factory']['name']))) .
  735.                     '/' rawurlencode(str_replace(['~q~''&prime;'], '\''StrAdm::toLower($collection['name']))) . '/per_sito/';
  736.             }
  737.             $actualName = empty($collection['factory']['alternateName'])
  738.                 ? $collection['factory']['name']
  739.                 : $collection['factory']['alternateName'];
  740.             $collection['factory']['ActualName'] = str_replace(['~q~''&prime;'], '\''$actualName);
  741.             $actualName = empty($collection['alternateName']) ? $collection['name'] : $collection['alternateName'];
  742.             $collection['ActualName'] = str_replace(['~q~''&prime;'], '\''$actualName);
  743.             $collection['alt'] = $collection['factory']['ActualName'] . ' ' $collection['ActualName'] . ' ';
  744.             return $collection;
  745.         }
  746.         return null;
  747.     }
  748. }