src/WebBundle/Service/CollectionSettingsService.php line 339

Open in your IDE?
  1. <?php
  2. namespace WebBundle\Service;
  3. use Doctrine\ORM\OptimisticLockException;
  4. use Doctrine\ORM\ORMException;
  5. use Exception;
  6. use WebBundle\Helper\App;
  7. use WebBundle\Helper\FilterHelper;
  8. use WebBundle\Helper\StrHelper;
  9. use WebBundle\Repository\ArticleRepository;
  10. use WebBundle\Repository\CollectionRepository;
  11. use WebBundle\Repository\FilterRepository;
  12. use WebBundle\Repository\InteriorRepository;
  13. class CollectionSettingsService extends ExtendService
  14. {
  15.     /** @var FilterRepository */
  16.     protected $repoFilter;
  17.     /** @var ArticleRepository */
  18.     protected $repoArticle;
  19.     /** @var InteriorRepository */
  20.     protected $repoInterior;
  21.     /** @var CollectionRepository */
  22.     protected $repoColl;
  23.     /**
  24.      * CollectionSettingsService constructor.
  25.      * @throws Exception
  26.      */
  27.     public function __construct()
  28.     {
  29.         $this->repoFilter App::getRepository('WebBundle:FilterEntity');
  30.         $this->repoArticle App::getRepository('WebBundle:Article');
  31.         $this->repoInterior App::getRepository('WebBundle:Interior');
  32.         $this->repoColl App::getRepository('WebBundle:Collection');
  33.         return $this;
  34.     }
  35.     private function parseAttr($attr)
  36.     {
  37.         $arr = [];
  38.         $keys = ['applies''styles''style''textures''pei''type''material''using''surface''edgeType''sliding''offShade'];
  39.         if (isset($attr['expressSample'])) {
  40.             if ($attr['expressSample']) {
  41.                 $arr['articleQuickSample'] = [
  42.                     'id' => 1,
  43.                     'name' => 'Экспресс образцы',
  44.                     'alias' => 'articleQuickSample',
  45.                     'key' => 'expressSample',
  46.                 ];
  47.             }
  48.         }
  49.         foreach ($keys as $key) {
  50.             if (!empty($attr[$key])) {
  51.                 $item $attr[$key];
  52.                 if (!empty($item['hide'])) {
  53.                     // скрытые фильтры не показываем в свойствах коллекции
  54.                     continue;
  55.                 }
  56.                 if (!empty($item['alias'])) {
  57.                     $item['key'] = $key;
  58.                     $arr[$item['alias']] = $item;
  59.                 } else {
  60.                     if (is_array($item)) {
  61.                         foreach ($item as $row) {
  62.                             if(empty($row['alias'])){
  63.                                 continue;
  64.                             }
  65.                             $row['key'] = $key;
  66.                             $arr[$row['alias']] = $row;
  67.                         }
  68.                     } else {
  69.                         $i FilterHelper::normaliseAltName($item);
  70.                         $arr[$i] = $item;
  71.                     }
  72.                 }
  73.             }
  74.         }
  75.         return $arr;
  76.     }
  77.     private function parseAttrDesigner($authors)
  78.     {
  79.         $arr = [];
  80.         foreach ($authors as $author) {
  81.             $key 'designer_' FilterHelper::normaliseAltName($author);
  82.             $arr[$key] = [
  83.                 'name'  => $author,
  84.                 'alias' => 'designer',
  85.             ];
  86.         }
  87.         return $arr;
  88.     }
  89.     private function getFilterIds($rows$cid$status)
  90.     {
  91.         $ids = [];
  92.         foreach ($rows as $k => $row) {
  93.             $f null;
  94.             if (preg_match('/pei_(.*)/ui'$k)) {
  95.                 $alias 'left_menu_' strtolower($k);
  96.                 $f $this->repoFilter->getFilterIdForSettingsCollectionByLeft($alias);
  97.             } elseif (!empty($row['alias'])) {
  98.                 if ($row['alias'] == 'designer') {
  99.                     $f $this->repoFilter->getFilterIdForSettingsColletionByIdDesigner($row['id']);
  100.                 } else {
  101.                     $f $this->repoFilter->getFilterIdForSettingsCollectionByLeft($row['alias']);
  102.                 }
  103.             }
  104.             if ($f) {
  105.                 $ids[$f['name']] = $f;
  106.             } else {
  107.                 if ($status != 2) {
  108.                     throw new Exception("Не нашли");
  109. //                    App::dumpExit('Не нашли', $row, ['id' => $cid, 'status' => $status]);
  110.                 }
  111.             }
  112.         }
  113.         return $ids;
  114.     }
  115.     /**
  116.      * Обновление ID фильтров свойств коллекции
  117.      * @param $cid
  118.      * @return bool
  119.      * @throws Exception
  120.      */
  121.     public function updateSettingsCollection($cid)
  122.     {
  123.         $this->getParseIdFiltersByAtrr($cid);
  124.         return true;
  125.     }
  126.     /**
  127.      * Парсим ID фильтров по признакам коллекции и сохраняем их сразу
  128.      * @param $cid
  129.      * @return array
  130.      * @throws ORMException
  131.      * @throws OptimisticLockException
  132.      * @throws Exception
  133.      */
  134.     public function getParseIdFiltersByAtrr($cid)
  135.     {
  136.         $coll $this->repoColl->getByIdForParseAttr($cid);
  137.         if (!$coll) {
  138.             throw new Exception("Ошибка, коллекции ID $cid нет.");
  139.         }
  140.         $interiors $this->repoInterior->getInteriorsByCollection($cid);
  141.         $articles $this->repoArticle->getArticleByCollection($cid);
  142.         $arr = [];
  143.         // смотрим интерьеры если accessible не TRUE
  144.         if (!$coll->getAccessible()) {
  145.             foreach ($interiors as $interior) {
  146.                 $arr_ $this->parseAttr($interior);
  147.                 $arr array_merge($arr$arr_);
  148.             }
  149.         }
  150.         foreach ($articles as $article) {
  151.             if(empty($article['file'])){
  152.                 continue;
  153.             }
  154.             $arr_ $this->parseAttr($article);
  155.             $arr array_merge($arr$arr_);
  156.             if (!empty($arr_['left_menu_glased_porcelain_no']) or !empty($arr_['left_menu_glased_porcelain_yes']) or !empty($arr_['left_menu_porcelain'])) {
  157.                 if (!empty($article['thinGranite']) and $article['thinGranite']) {
  158.                     // добавляем признак тонкого керамогранита
  159.                     $arr['left_menu_thin_porcelain_tile'] = [
  160.                         'id'    => 1,
  161.                         'alias' => 'left_menu_thin_porcelain_tile'
  162.                     ];
  163.                 } else {
  164.                     if ($article['thick'] >= 17) {
  165.                         // добавляем признак утолщенного керамогранита
  166.                         $arr['left_menu_thick_porcelain_tile'] = [
  167.                             'id'    => 2,
  168.                             'alias' => 'left_menu_thick_porcelain_tile'
  169.                         ];
  170.                     }
  171.                 }
  172.             }
  173.         }
  174.         $desIds $coll->getAuthorId();
  175.         if ($desIds) {
  176.             foreach ($desIds as $dId) {
  177.                 $arr["designer_{$dId}"] = [
  178.                     'id'  => $dId,
  179.                     'alias' => 'designer',
  180.                 ];
  181.             }
  182.             // добавляем сам стиль дизайнерский
  183.             $arr['left_menu_designer'] = [
  184.                 'id'    => 17,
  185.                 'alias' => 'left_menu_designer'
  186.             ];
  187.         }
  188.         $ids $this->getFilterIds($arr$cid$coll->getStatus());
  189.         $ids array_column($ids'id');
  190.         $coll->setFids($ids);
  191.         App::em()->persist($coll);
  192.         App::em()->flush();
  193.         return $ids;
  194.     }
  195.     /**
  196.      * Проставляем rank и size для фильтров
  197.      * @param $items
  198.      * @return array
  199.      * @throws Exception
  200.      */
  201.     private function setSize($items)
  202.     {
  203.         $rankService App::getContainer()->get('app.service.rank');
  204.         $rankArr = [];
  205.         $items_ = [];
  206.         foreach ($items as $k => $item) {
  207.             $rank = isset($item['rank']) ? intval($item['rank']) : 0;
  208.             $item['rank'] = $rank;
  209.             // ставим дефольный размер для всех
  210.             $item['size'] = $rankService->fontSizeByRank(50);
  211.             $items_[$item['altName']] = $item;
  212.             if (!in_array($item['group.altName'], ['resistance_abrasion''antislip_coff''shade_variation''designer'])) {
  213.                 $rankArr[$item['altName']] = $rank;
  214.             }
  215.         }
  216.         arsort($rankArr);
  217.         $rankArr array_keys($rankArr);
  218.         // количество выделяемых в четверти
  219.         $cnt = (int)ceil(count($rankArr) / 4);
  220.         foreach ($rankArr as $i => $k) {
  221.             if ($i <= $cnt) {
  222.                 // первая четверть
  223.                 $items_[$k]['size'] = $rankService->fontSizeByRank(100);
  224.             } elseif ($i $cnt and $i <= ( $cnt )) {
  225.                 // вторая четверть
  226.                 $items_[$k]['size'] = $rankService->fontSizeByRank(80);
  227.             }
  228.         }
  229.         return $items_;
  230.     }
  231.     /**
  232.      * @param $fids
  233.      * @return string
  234.      * @throws Exception
  235.      */
  236.     public function getFiltersTxt($fids)
  237.     {
  238.         $groups $this->getFilters($fids);
  239.         $str = [];
  240.         foreach ($groups as $r) {
  241.             // убираем surface, вместо нее коэффициенты выводятся
  242.             if ($r['altName'] == 'surface') {
  243.                 continue;
  244.             }
  245.             $s null;
  246.             if ($r['altName'] == 'shade_variation' || $r['altName'] == 'resistance_abrasion') {
  247.                 $s "#{$r['name']}";
  248.             } elseif ($r['altName'] == 'antislip_coff') {
  249.                 $s "#{$r['nameFull']}";
  250.             }
  251.             $l = [];
  252.             foreach ($r['list'] as $item) {
  253.                 $name $item['nameMany'];
  254.                 if ($r['altName'] == 'resistance_abrasion') {
  255.                     $name trim(str_replace('PEI'''$name));
  256.                 }
  257.                 if ($item['altName'] == 'vinil') {
  258.                     $name "<b>{$name}</b>";
  259.                 }
  260.                 $l[] = $name;
  261.             }
  262.             if ($s) {
  263.                 $s "{$s} " implode(', '$l);
  264.             } else {
  265.                 $s "#" implode(' #'$l);
  266.             }
  267.             $str[] = $s;
  268.         }
  269.         $str implode(' '$str);
  270.         return $str;
  271.     }
  272.     /**
  273.      * @param $fids
  274.      * @return string
  275.      * @throws Exception
  276.      */
  277.     public function getFiltersHtml($fids): string
  278.     {
  279.         $groups $this->getFilters($fids);
  280.         return $this->attrToHtml($groups);
  281.     }
  282.     public function attrToHtml($groups)
  283.     {
  284.         $html $this->render(
  285.             '@Web/Collection/attrs.html.twig',
  286.             [
  287.                 'lc'     => App::getCurLocale(),
  288.                 'groups' => $groups,
  289.             ]
  290.         );
  291.         $html trim(trim($html), ',');
  292.         return str_replace(' ,'','$html);
  293.     }
  294.     /**
  295.      * @param $fids
  296.      * @return array
  297.      * @throws Exception
  298.      */
  299.     public function getFilters($fidsbool $forReact=false)
  300.     {
  301.         $oRouter App::getRouter();
  302.         $items $this->repoFilter->getForCollSettings($fids);
  303.         $items $this->setSize($items);
  304.         $groups = [];
  305.         // упаковываем по группам
  306.         foreach ($items as $fAlt => $item) {
  307.             $grAlt $item['group.altName'];
  308.             // убираем с вывода свойств все виды изделий
  309.             // https://te.remote.team/#/discus/AE79130E-DE85-4F4A-0434-AFE6A828C451/
  310.             // UPD: Добавил условие для вывода типа изделия в лэере для реакта
  311.             // https://te.remote.team/#/discus/ACF4E5F1-9B69-A9B6-76A5-4EA1F860AC17/
  312.             if ($grAlt == 'type' && !$forReact) {
  313.                 continue;
  314.             }
  315.             // скрыл дизайнеров без коллекций
  316.             // https://te.remote.team/#/discus/BB0C92AC-A6BE-10D6-FC74-D4999FCFE2B2/
  317.             if ($grAlt == 'designer' and !$item['count']) {
  318.                 continue;
  319.             }
  320.             // формируем ссылку на фильтр
  321.             $link $item['slug'];
  322.             if ($link and $item['count']) {
  323.                 $link $oRouter->generate('app_catalog', ['key' => $link]);
  324.             } else {
  325.                 $link null;
  326.             }
  327.             if (empty($groups[$grAlt])) {
  328.                 $nameFull null;
  329.                 switch ($grAlt) {
  330.                     case 'antislip_coff':
  331.                         //$nameFull = App::getTranslator()->trans('catalog.options.non_slip_rating', ['%d%' => '']);
  332.                         $nameFull App::getTranslator()->trans('antislip_full_name', ['%d%' => '']);
  333.                         break;
  334.                     case 'resistance_abrasion':
  335.                         $nameFull App::getTranslator()->trans('catalog.options.pei');
  336.                         break;
  337.                     case 'shade_variation':
  338.                         $nameFull App::getTranslator()->trans('catalog.options.shade_variation', ['%d%' => '']);
  339.                         break;
  340.                 }
  341.                 $name $item['group.name'];
  342.                 // для PEI оставляем верний регистр
  343.                 if ($grAlt != 'resistance_abrasion') {
  344.                     $name StrHelper::toLower($name);
  345.                 }
  346.                 $groups[$grAlt] = [
  347.                     'id'       => $item['group.id'],
  348.                     'altName'  => $item['group.altName'],
  349.                     'name'     => $name,
  350.                     'nameFull' => $nameFull,
  351.                     'list'     => [],
  352.                 ];
  353.             }
  354.             $groups[$grAlt]['list'][$fAlt] = [
  355.                 'id'         => $item['id'],
  356.                 'sphinxId'   => $item['sphinxId'],
  357.                 'sphinxName' => $item['sphinxName'],
  358.                 'altName'    => $item['altName'],
  359.                 'name'       => $item['name'],
  360.                 'nameMany'   => $item['nameMany'],
  361.                 'nameFull'   => $item['nameFull'],
  362.                 'slug'       => $item['slug'],
  363.                 'link'       => $link,
  364.                 'count'      => $item['count'],
  365.                 'rank'       => $item['rank'],
  366.                 'size'       => $item['size'],
  367.             ];
  368.         }
  369.         // переносим в конец
  370.         if (!empty($groups['antislip_coff'])) {
  371.             $shade $groups['antislip_coff'];
  372.             unset($groups['antislip_coff']);
  373.             $groups['antislip_coff'] = $shade;
  374.         }
  375.         // удаляем признак дизайнеров, если есть сами дизайнеры у нас
  376.         if (!empty($groups['designer'])) {
  377.             $designer $groups['style']['list']['designer'];
  378.             $designer['list'] = $groups['designer']['list'];
  379.             $designer['nameFull'] = StrHelper::toLower($designer['nameFull']);
  380.             $groups['designer'] = $designer;
  381.             unset($groups['style']['list']['designer']);
  382.         }
  383.         // переносим в конец
  384.         if (!empty($groups['resistance_abrasion'])) {
  385.             $resistance $groups['resistance_abrasion'];
  386.             unset($groups['resistance_abrasion']);
  387.             $groups['resistance_abrasion'] = $resistance;
  388.         }
  389.         // переносим в конец
  390.         if (!empty($groups['shade_variation'])) {
  391.             $shade $groups['shade_variation'];
  392.             unset($groups['shade_variation']);
  393.             $groups['shade_variation'] = $shade;
  394.         }
  395.         // переносим в конец
  396.         if (!empty($groups['designer'])) {
  397.             $designer $groups['designer'];
  398.             unset($groups['designer']);
  399.             $groups['designer'] = $designer;
  400.         }
  401.         return $groups;
  402.     }
  403.     public function arrayInsert(&$array$position$insert)
  404.     {
  405.         if (is_int($position)) {
  406.             array_splice($array$position0$insert);
  407.         } else {
  408.             $pos   array_search($positionarray_keys($array));
  409.             $array array_merge(
  410.                 array_slice($array0$pos+1),
  411.                 $insert,
  412.                 array_slice($array$pos+1)
  413.             );
  414.         }
  415.     }
  416. }