src/WebBundle/Helper/TwigTe.php line 218

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace WebBundle\Helper;
  4. use Exception;
  5. use Twig\Error\Error;
  6. use WebBundle\Entity\BuyOrder;
  7. use WebBundle\Entity\Idea;
  8. use WebBundle\Entity\User;
  9. use WebBundle\Enum\BuyOrderStatusEnum;
  10. use WebBundle\Repository\FilterRepository;
  11. use WebBundle\Service\SitemapGenerator;
  12. /**
  13.  * class: TwigTe
  14.  * Исключительн хелпер для твига , все его статические функции автоматически доступны в шаблоне
  15.  * -----------------------------------------------------
  16.  * Created by MihailShirnin on 25.10.2016.
  17.  * @package WebBundle\Helper
  18.  */
  19. class TwigTe
  20. {
  21.     /**
  22.      * Отдаем текущий статический класс. Сделано для твига
  23.      * @return TwigTe
  24.      */
  25.     public static function that()
  26.     {
  27.         return new self();
  28.     }
  29.     /**
  30.      * @return UrlHelper
  31.      */
  32.     public static function path()
  33.     {
  34.         return UrlHelper::that();
  35.     }
  36.     public static function pathGenerate($type$article)
  37.     {
  38.         return PathHelper::pathGenerate($type$article);
  39.     }
  40.     /**
  41.      * @return null|User
  42.      * @throws Exception
  43.      */
  44.     public static function user()
  45.     {
  46.         return App::getCurUser();
  47.     }
  48.     /**
  49.      * @return StrHelper
  50.      */
  51.     public static function str()
  52.     {
  53.         return StrHelper::that();
  54.     }
  55.     /**
  56.      * @return LocaleHelper
  57.      */
  58.     public static function locale()
  59.     {
  60.         return LocaleHelper::that();
  61.     }
  62.     /**
  63.      * @param array $params
  64.      */
  65.     public function dump(...$params)
  66.     {
  67.         $params count($params) == $params[0] : $params;
  68.         App::dump($params);
  69.     }
  70.     /**
  71.      * Формирование массива ссылок фильтров в футер меню
  72.      * Возвращаем массив: название (в текущей локали) => ссылка (catalog/свойство)
  73.      *
  74.      * @return array
  75.      * @throws Exception
  76.      */
  77.     public static function getFooterLinks()
  78.     {
  79.         $lc in_array(App::getCurLocale(), App::getParameter('locales')) ? App::getCurLocale() : 'en';
  80.         /**  @var FilterRepository $oRepoFilter */
  81.         $oRepoFilter App::getRepository('WebBundle:FilterEntity');
  82.         $list $oRepoFilter->getForFooterByGroupAlias();
  83.         foreach ($list as $id => $item) {
  84.             if (!empty($item[$lc])) {
  85.                 $list[$id] = $item[$lc];
  86.             }
  87.         }
  88.         return $list;
  89.     }
  90.     /**
  91.      * Удаление значения из массива
  92.      * @param array $arr
  93.      * @param       $keys
  94.      * @return array
  95.      */
  96.     public static function unsetArr(array $arr$keys)
  97.     {
  98.         $keys is_array($keys) ? $keys explode(','$keys);
  99.         foreach ($keys as $key) {
  100.             $key trim($key);
  101.             if (!empty($arr[$key])) {
  102.                 unset($arr[$key]);
  103.             }
  104.         }
  105.         return $arr;
  106.     }
  107.     /**
  108.      * Формируем LITE меню фильтров
  109.      * @param Boolean $withLiteFilters // рендерить ли lite-filters
  110.      * @param array $collection //если коллекция уже получена при поиске зачем получать ее еще раз в getDataMenuLite ?
  111.      * @param array $calculate //если использовался sphinx, то у нас будут совсем другие количества результатов для фильтров
  112.      * @return string
  113.      * @throws Exception
  114.      */
  115.     public static function buildLeftMenuLite(bool $withLiteFilters true)
  116.     {
  117.         $oLeftService App::getContainer()->get('app.service.leftmenu');
  118.         $output $oLeftService->getDataMenuLite();
  119.         $output['withLiteFilters'] = $withLiteFilters;
  120.         //  App::debugExit($output);
  121.         $render App::getTwig()->render('@Web/Left/_left_menu.html.twig'$output);
  122.         return $render;
  123.     }
  124.     /**
  125.      * Получение значения из объекта для составных имен методов класса
  126.      * @param $obj
  127.      * @param $dop
  128.      * @return mixed
  129.      */
  130.     public static function runMethodGet($obj$dop)
  131.     {
  132.         $aDop explode('.'$dop);
  133.         $res $obj;
  134.         foreach ($aDop as $dop) {
  135.             if (strripos($dop'get') === false) {
  136.                 $dop 'get' StrHelper::ucFirst($dop);
  137.             }
  138.             $res $res->$dop();
  139.         }
  140.         return $res;
  141.     }
  142.     /**
  143.      * Проверка DEV окружения
  144.      * @return bool
  145.      * @throws Exception
  146.      */
  147.     public static function checkIsDev()
  148.     {
  149.         return App::isDev();
  150.     }
  151.     /**
  152.      * проверка окружения для вакансий - учетом локали ру
  153.      * @param bool $isDev
  154.      * @return bool
  155.      * @throws Exception
  156.      */
  157.     public static function isVacancyTE($isDev false)
  158.     {
  159.         return App::isVacancyTE($isDev);
  160.     }
  161.     public static function checkIsUpdated()
  162.     {
  163.         return App::getParameter('show_alert_update');
  164.     }
  165.     public static function getRequest()
  166.     {
  167.         return RequestHelper::syRequest();
  168.     }
  169.     public static function replaceStr($search$replace$subject, &$count null)
  170.     {
  171.         return str_replace($search$replace$subject$count);
  172.     }
  173.     public function valK($val)
  174.     {
  175.         if ($val 999) {
  176.             $val LocaleHelper::floatSign($val 10001) . 'K';
  177.         }
  178.         return $val;
  179.     }
  180.     /**
  181.      * @param null $route
  182.      * @param null|array $params
  183.      * @param null|array $hrefFlag
  184.      * @return string
  185.      * @throws Error
  186.      * @throws Exception
  187.      */
  188.     public static function getSEOLink($route null$params null$hrefFlag null): string
  189.     {
  190.         $params $params_ = empty($params) ? [] : $params;
  191.         $sanitizeParamValues = static function (array $input): array {
  192.             foreach ($input as $key => $value) {
  193.                 if (is_string($value) && strpos($value'?') !== false) {
  194.                     $input[$key] = strtok($value'?');
  195.                 }
  196.             }
  197.             return $input;
  198.         };
  199.         $params $sanitizeParamValues($params);
  200.         $params_ $sanitizeParamValues($params_);
  201.         $stripQueryKeys = ['msg''sort'];
  202.         $keyBase ArrHelper::get($params'key');
  203.         $links = [];
  204.         $lcFull App::getCurLocale(true);
  205.         $canonical false;
  206.         $robots false;
  207.         $sitemapLocales null;
  208.         $curCountry strtolower((string) App::getCurCountry());
  209.         $requestQuery $sanitizeParamValues(App::getRequest()->query->all());
  210.         foreach ($stripQueryKeys as $stripKey) {
  211.             if (array_key_exists($stripKey$requestQuery)) {
  212.                 unset($requestQuery[$stripKey]);
  213.             }
  214.         }
  215.         $add_hreflang = [
  216.             'en-at',
  217.             'en-be',
  218.             'en-ca',
  219.             'en-ch',
  220.             'en-de',
  221.             'en-dk',
  222.             'en-fi',
  223.             'en-lu',
  224.             'en-no',
  225.             'en-pl',
  226.             'en-pt',
  227.             'en-se',
  228.         ];
  229.         // Ограничиваем hreflang только локалями, для которых реально генерируется sitemap т еще чуть-чуть :)
  230.         // Это убирает "лишние" языки/страны (например, en-fi), для которых sitemap отсутствует.
  231.         try {
  232.             /** @var SitemapGenerator $sitemapGenerator */
  233.             $sitemapGenerator App::getContainer()->get(SitemapGenerator::class);
  234.             $sitemapLocales $sitemapGenerator->generateLocaleCountryList();
  235.             $sitemapLocales array_merge($add_hreflang$sitemapLocales);
  236.         } catch (\Throwable $_) {
  237.             $sitemapLocales null// fallback: поведение как раньше
  238.         }
  239.         if ($route) {
  240.             $lcList LocaleHelper::getListCodeAvailable();
  241.             $countryList App::getCountryList();
  242.             $fs App::getContainer()->get('app.service.filters');
  243.             // Если для локали нет sitemap — не добавляем hreflang.
  244.             if (is_array($sitemapLocales) && in_array($lcFull$sitemapLocales)) {
  245.                 foreach ($lcList as $loc) {
  246.                     $loc strtolower($loc);
  247.                     if ($loc === 'zh') {
  248.                         continue;
  249.                     }
  250.                     if ($route === 'app_catalog' || $route === 'app_catalog_short') {
  251.                         if ($keyBase) {
  252.                             $key $fs->getWord(null$loc);
  253.                             if (!$key) {
  254.                                 continue;
  255.                             } else {
  256.                                 //по стандарту RFC 3986 в урл не может быть & если нет перед ?
  257.                                 $params['key'] = urlencode($key);
  258.                             }
  259.                         } else {
  260.                             continue;
  261.                         }
  262.                     }
  263.                     if ($route === 'app_publication_single') {
  264.                         if (!empty($hrefFlag[$loc])) {
  265.                             $params['id'] = $hrefFlag[$loc];
  266.                         } else {
  267.                             continue;
  268.                         }
  269.                     }
  270.                     if ($route === 'app_collection' && !empty($params['elementId'])) {
  271.                         $translated $fs->getWord($params['elementId'], $loc);
  272.                         if ($params['type'] == "f") {
  273.                             $canParams $params;
  274.                             unset($canParams ['type']);
  275.                             unset($canParams ['elementId']);
  276.                             $canonical App::generateUrl($route$canParams0);
  277.                             $robots 'noindex, nofollow';
  278.                         }
  279.                         if (!$translated) {
  280.                             continue;
  281.                         }
  282.                         $tmpParams $params;
  283.                         $tmpParams['elementId'] = $translated;
  284.                     } else {
  285.                         $tmpParams $params;
  286.                     }
  287.                     foreach ($countryList as $code => $country) {
  288.                         $code strtolower($code);
  289.                         if (
  290.                             empty($code) || $code == 'ru' || $code == 'en' || ($code != 'en' && !in_array(
  291.                                 $loc,
  292.                                 $country['localesArr']
  293.                             )) || ($code == 'ru' && $loc != 'ru')
  294.                         ) {
  295.                             continue;
  296.                         }
  297.                         $lf $loc '-' $code;
  298.                         if ($loc == $code) {
  299.                             $l $loc;
  300.                         } else {
  301.                             $l $lf;
  302.                         }
  303.                         //для ru нет такой страницы
  304.                         if (!empty($tmpParams['url']) && $tmpParams['url'] === 'improving-site' && $l === 'ru') {
  305.                             continue;
  306.                         }
  307.                         $links[] = [
  308.                             'url' => App::generateUrl(
  309.                                 $route,
  310.                                 array_merge(
  311.                                     $tmpParams,
  312.                                     array_merge(['_locale' => $l], $requestQuery)
  313.                                 ),
  314.                                 0
  315.                             ),
  316.                             'locale' => $lf,
  317.                         ];
  318.                         if ($lcFull == $lf || $lf == $lcFull '-' $lcFull) {
  319.                             $tmpCanonical array_merge(
  320.                                 $tmpParams,
  321.                                 array_merge(['_locale' => $l], $requestQuery)
  322.                             );
  323.                         }
  324.                     }
  325.                 }
  326.             }
  327.         }
  328.         if (in_array($lcFull, ['it''fi'])) {
  329.             $params array_merge($params_, ['_locale' => $lcFull]);
  330.             if ($params != $params_) {
  331.                 $canonical App::generateUrl($routearray_merge($params, ['_locale' => $lcFull]), 0);
  332.             }
  333.         }
  334.         if (!$canonical && !empty($tmpCanonical)) {
  335.             $page App::getRequest()->get('page');
  336.             if (!empty($page) && $page 1) {
  337.                 $canParams array_merge(['page' => $page], $tmpCanonical);
  338.             } else {
  339.                 $canParams $tmpCanonical;
  340.             }
  341.             $canonical App::generateUrl($route$canParams0);
  342.         }
  343.         if (!$canonical) {
  344.             if ($lcFull == 'en') {
  345.                 $params['_locale'] = 'en-us';
  346.             }
  347.             $canonical App::generateUrl($route$params0);
  348.         }
  349.         //если не добавляем hreflang то меняем каноникал на первый язык в стране
  350.         if (!is_array($sitemapLocales) || !in_array($lcFull$sitemapLocales)) {
  351.             if ($route === 'app_catalog' || $route === 'app_catalog_short') {
  352.                 if ($keyBase) {
  353.                     $key $fs->getWord(null$countryList[$curCountry]['localesArr'][0]);
  354.                     if ($key) {
  355.                         //по стандарту RFC 3986 в урл не может быть & если нет перед ?
  356.                         $params['key'] = urlencode($key);
  357.                     }
  358.                 }
  359.             }
  360.             $params['_locale'] = $countryList[$curCountry]['localesArr'][0] == $curCountry $curCountry $countryList[$curCountry]['localesArr'][0] . '-' $curCountry;
  361.             $canonical App::generateUrl($route$params0);
  362.             $robots 'noindex, nofollow';
  363.         }
  364.         if ($route === 'app_collection_slideshow_f' && !empty($params['elementId'])) {
  365.             $canParams $params;
  366.             unset($canParams ['filter']);
  367.             $canonical App::generateUrl('app_collection_slideshow'$canParams0);
  368.             $robots 'noindex, nofollow';
  369.         }
  370.         return App::getTwig()->render(
  371.             '@Web/Common/seo-link.html.twig',
  372.             [
  373.                 'links' => $links,
  374.                 'canonical' => $canonical,
  375.                 'robots' => $robots,
  376.             ]
  377.         );
  378.     }
  379.     /**
  380.      * @return string
  381.      */
  382.     public static function getCanonicalTR(): string
  383.     {
  384.         return '';
  385.     }
  386.     /**
  387.      * Используется как уникальная строка в твиге
  388.      * @return string
  389.      */
  390.     public static function getUniqId()
  391.     {
  392.         return uniqid();
  393.     }
  394.     public static function isArray($val)
  395.     {
  396.         return is_array($val);
  397.     }
  398.     /**
  399.      * Получить параметр из файла конфига parameters.yml
  400.      * Для получения url web socket сервера
  401.      * @param string $param Имя параметра в файле конфига parameters.yml
  402.      * @return mixed
  403.      * @throws Exception
  404.      * @todo возможно есть лучшее решение, не нашел
  405.      */
  406.     public static function getParameter($param 'portal_ws_server')
  407.     {
  408.         if (!$param) {
  409.             throw new Exception('Pass empty parameter');
  410.         }
  411.         return App::getParameter($param);
  412.     }
  413.     /**
  414.      * @param BuyOrder $buyOrder
  415.      * @return string
  416.      * @throws Exception
  417.      */
  418.     public static function headerBO($buyOrder)
  419.     {
  420.         return App::getTwig()->render('@Web/BuyOrder/header.html.twig', [
  421.             'header' => OrderHelper::header($buyOrder),
  422.             'noObligation' => $buyOrder->getStatus() < BuyOrderStatusEnum::PARTIALLY_PAID && !$buyOrder->getBankTransferRequested(),
  423.         ]);
  424.     }
  425.     /**
  426.      * @throws Exception
  427.      */
  428.     public static function ideaUrl(Idea $idea): string
  429.     {
  430.         return App::generateUrl('app_idea', ['url' => $idea->getId()], 0);
  431.     }
  432.     /**
  433.      * Костыль для получения языка на страницах 404 500 b т.д.
  434.      */
  435.     public function getLangFromUri(): ?string
  436.     {
  437.         $localeFromUri LocaleHelper::getCurLocale();
  438.         return $localeFromUri;
  439.     }
  440.     public function getCountryFromUri(): ?string
  441.     {
  442.         $localeFromUri LocaleHelper::getCurCountry();
  443.         return $localeFromUri;
  444.     }
  445.     public function fakePrice(array $article): array
  446.     {
  447.         return LocaleHelper::fakePrice($article);
  448.     }
  449.     /**
  450.      * Ссылка на страницу Новинок сайта
  451.      * @return mixed
  452.      */
  453.     public static function linkTopPage()
  454.     {
  455.         return FilterHelper::getUrl('recently-added-tiles');
  456.     }
  457.     public function truncate($string$length)
  458.     {
  459.         if (strlen($string) > $length) {
  460.             $string substr($string0$length) . '...';
  461.         }
  462.         return $string;
  463.     }
  464.     /**
  465.      * @param string $key
  466.      * @param $count
  467.      * @param $locale
  468.      * @param array $params
  469.      * @param int $allowKey
  470.      * @return string
  471.      * Plural on twig
  472.      */
  473.     public function transByVariant(string $key$count$locale null$params = [], int $allowKey 0)
  474.     {
  475.         try {
  476.             $locale $locale ?: App::getCurLocale();
  477.             return App::getTranslator()->trans(
  478.                 $key,
  479.                 ['%count%' => App::plural((int)$count$locale$allowKey)] + $params,
  480.                 null,
  481.                 $locale
  482.             );
  483.         } catch (Exception $e) {
  484.             return '';
  485.         }
  486.     }
  487. }