var/cache/review/twig/fe/fe6ae84e185bac133a8df8c62c15d6de.php line 52

Open in your IDE?
  1. <?php
  2. use Twig\Environment;
  3. use Twig\Error\LoaderError;
  4. use Twig\Error\RuntimeError;
  5. use Twig\Extension\SandboxExtension;
  6. use Twig\Markup;
  7. use Twig\Sandbox\SecurityError;
  8. use Twig\Sandbox\SecurityNotAllowedTagError;
  9. use Twig\Sandbox\SecurityNotAllowedFilterError;
  10. use Twig\Sandbox\SecurityNotAllowedFunctionError;
  11. use Twig\Source;
  12. use Twig\Template;
  13. /* Map/page.html.twig */
  14. class __TwigTemplate_a28a045d3be3f3299f645cdfe29370c8 extends Template
  15. {
  16.     private $source;
  17.     private $macros = [];
  18.     public function __construct(Environment $env)
  19.     {
  20.         parent::__construct($env);
  21.         $this->source $this->getSourceContext();
  22.         $this->blocks = [
  23.             'mainContainer' => [$this'block_mainContainer'],
  24.             'javascripts' => [$this'block_javascripts'],
  25.         ];
  26.     }
  27.     protected function doGetParent(array $context)
  28.     {
  29.         // line 1
  30.         return "grid.html.twig";
  31.     }
  32.     protected function doDisplay(array $context, array $blocks = [])
  33.     {
  34.         $macros $this->macros;
  35.         $__internal_b91a4435ea3baf1e2b6bfda56133dace $this->extensions["Sentry\\SentryBundle\\Tracing\\Twig\\TwigTracingExtension"];
  36.         $__internal_b91a4435ea3baf1e2b6bfda56133dace->enter($__internal_b91a4435ea3baf1e2b6bfda56133dace_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "template""Map/page.html.twig"));
  37.         $__internal_5a27a8ba21ca79b61932376b2fa922d2 $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
  38.         $__internal_5a27a8ba21ca79b61932376b2fa922d2->enter($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "template""Map/page.html.twig"));
  39.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
  40.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f->enter($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "template""Map/page.html.twig"));
  41.         $this->parent $this->loadTemplate("grid.html.twig""Map/page.html.twig"1);
  42.         $this->parent->display($contextarray_merge($this->blocks$blocks));
  43.         
  44.         $__internal_b91a4435ea3baf1e2b6bfda56133dace->leave($__internal_b91a4435ea3baf1e2b6bfda56133dace_prof);
  45.         
  46.         $__internal_5a27a8ba21ca79b61932376b2fa922d2->leave($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof);
  47.         
  48.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f->leave($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof);
  49.     }
  50.     // line 3
  51.     public function block_mainContainer($context, array $blocks = [])
  52.     {
  53.         $macros $this->macros;
  54.         $__internal_b91a4435ea3baf1e2b6bfda56133dace $this->extensions["Sentry\\SentryBundle\\Tracing\\Twig\\TwigTracingExtension"];
  55.         $__internal_b91a4435ea3baf1e2b6bfda56133dace->enter($__internal_b91a4435ea3baf1e2b6bfda56133dace_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""mainContainer"));
  56.         $__internal_5a27a8ba21ca79b61932376b2fa922d2 $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
  57.         $__internal_5a27a8ba21ca79b61932376b2fa922d2->enter($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""mainContainer"));
  58.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
  59.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f->enter($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""mainContainer"));
  60.         // line 4
  61.         echo "   ";
  62.         // line 5
  63.         echo "    <div id=\"map_form\"></div>
  64.     <img src=\"";
  65.         // line 6
  66.         echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl("/static/preloader.gif"), "html"nulltrue);
  67.         echo "\" id=\"preloader\" style=\"display: none;\" />
  68.     <div id=\"map\"
  69.          data-city-uri-idenity=\"";
  70.         // line 8
  71.         echo twig_escape_filter($this->env, (isset($context["cityUriIdentity"]) || array_key_exists("cityUriIdentity"$context) ? $context["cityUriIdentity"] : (function () { throw new RuntimeError('Variable "cityUriIdentity" does not exist.'8$this->source); })()), "html"nulltrue);
  72.         echo "\"
  73.          data-city-latitude=\"";
  74.         // line 9
  75.         echo twig_escape_filter($this->env, (isset($context["cityLatitude"]) || array_key_exists("cityLatitude"$context) ? $context["cityLatitude"] : (function () { throw new RuntimeError('Variable "cityLatitude" does not exist.'9$this->source); })()), "html"nulltrue);
  76.         echo "\"
  77.          data-city-longitude=\"";
  78.         // line 10
  79.         echo twig_escape_filter($this->env, (isset($context["cityLongitude"]) || array_key_exists("cityLongitude"$context) ? $context["cityLongitude"] : (function () { throw new RuntimeError('Variable "cityLongitude" does not exist.'10$this->source); })()), "html"nulltrue);
  80.         echo "\"
  81.          style=\"width:100%; height:500px;\"></div>
  82. ";
  83.         
  84.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f->leave($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof);
  85.         
  86.         $__internal_5a27a8ba21ca79b61932376b2fa922d2->leave($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof);
  87.         
  88.         $__internal_b91a4435ea3baf1e2b6bfda56133dace->leave($__internal_b91a4435ea3baf1e2b6bfda56133dace_prof);
  89.     }
  90.     // line 14
  91.     public function block_javascripts($context, array $blocks = [])
  92.     {
  93.         $macros $this->macros;
  94.         $__internal_b91a4435ea3baf1e2b6bfda56133dace $this->extensions["Sentry\\SentryBundle\\Tracing\\Twig\\TwigTracingExtension"];
  95.         $__internal_b91a4435ea3baf1e2b6bfda56133dace->enter($__internal_b91a4435ea3baf1e2b6bfda56133dace_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""javascripts"));
  96.         $__internal_5a27a8ba21ca79b61932376b2fa922d2 $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
  97.         $__internal_5a27a8ba21ca79b61932376b2fa922d2->enter($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""javascripts"));
  98.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
  99.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f->enter($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""javascripts"));
  100.         // line 15
  101.         echo "    <script src=\"";
  102.         echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl("bundles/fosjsrouting/js/router.min.js"), "html"nulltrue);
  103.         echo "\"></script>
  104.     <script src=\"";
  105.         // line 16
  106.         echo $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("fos_js_routing_js", ["callback" => "fos.Router.setData"]);
  107.         echo "\"></script>
  108.     <script src=\"https://code.jquery.com/jquery-3.4.1.min.js\"></script>
  109.     <script src=\"https://api-maps.yandex.ru/2.1/?lang=ru_RU\" type=\"text/javascript\"></script>
  110.     <script type=\"text/javascript\">
  111.         ;var RoutingDecorator = {
  112.             generate: function (name, params) {
  113.                 const orig_name = name;
  114.                 try {
  115.                     Routing.getRoute(name)
  116.                 } catch(error) {
  117.                     name = name + '.' + '";
  118.         // line 27
  119.         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["app"]) || array_key_exists("app"$context) ? $context["app"] : (function () { throw new RuntimeError('Variable "app" does not exist.'27$this->source); })()), "request", [], "any"falsefalsefalse27), "locale", [], "any"falsefalsefalse27), "html"nulltrue);
  120.         echo "';
  121.                     try {
  122.                         Routing.getRoute(name)
  123.                     } catch(error) {
  124.                         name = orig_name;
  125.                     }
  126.                 }
  127.                 return Routing.generate(name, params);
  128.             }
  129.         };
  130.         ;(function () {
  131.             document.addEventListener('DOMContentLoaded', _ => {
  132.                 var avatarPath = '";
  133.         // line 42
  134.         echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl("""profile_media_avatar"), "html"nulltrue);
  135.         echo "';
  136.                 var photoPath = '";
  137.         // line 43
  138.         echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl("""profile_media"), "html"nulltrue);
  139.         echo "';
  140.                 var thumbPath = '";
  141.         // line 44
  142.         echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl("""saloon_media_thumb"), "html"nulltrue);
  143.         echo "';
  144.                 var mapContainer = document.querySelector('#map');
  145.                 var preloader = document.querySelector('#preloader');
  146.                 var cityUriIdentity = mapContainer.getAttribute('data-city-uri-idenity');
  147.                 var cityLatitude = mapContainer.getAttribute('data-city-latitude');
  148.                 var cityLongitude = mapContainer.getAttribute('data-city-longitude');
  149.                 var formName = 'filter_map_form';
  150.                 var multipleCities = ";
  151.         // line 51
  152.         echo twig_escape_filter($this->env, (isset($context["multipleCities"]) || array_key_exists("multipleCities"$context) ? $context["multipleCities"] : (function () { throw new RuntimeError('Variable "multipleCities" does not exist.'51$this->source); })()), "html"nulltrue);
  153.         echo ";
  154.                 var routesUrl = '/js/fos_js_routes";
  155.         // line 52
  156.         echo (((isset($context["multipleCities"]) || array_key_exists("multipleCities"$context) ? $context["multipleCities"] : (function () { throw new RuntimeError('Variable "multipleCities" does not exist.'52$this->source); })())) ? ("_city_prefixed") : (""));
  157.         echo ".json';
  158.                 loadRoutes();
  159.                 var myMap, clusterer;
  160.                 ymaps.ready(function () {
  161.                     myMap = new ymaps.Map('map', {
  162.                             center: [cityLatitude, cityLongitude],
  163.                             zoom: 9,
  164.                             behaviors: ['default', 'scrollZoom']
  165.                         }, {
  166.                             searchControlProvider: 'yandex#search'
  167.                         });
  168.                     clusterer = new ymaps.Clusterer({
  169.                             preset: 'islands#invertedVioletClusterIcons',//Через кластеризатор можно указать только стили кластеров,стили для меток нужно назначать каждой метке отдельно.
  170.                             groupByCoordinates: false,//Ставим true, если хотим кластеризовать только точки с одинаковыми координатами.
  171.                             //Опции кластеров указываем в кластеризаторе с префиксом \"cluster\".
  172.                             clusterDisableClickZoom: true,
  173.                             clusterHideIconOnBalloonOpen: false,
  174.                             geoObjectHideIconOnBalloonOpen: false
  175.                     });
  176.                     // Можно менять опции кластеризатора после создания.
  177.                     clusterer.options.set({
  178.                         gridSize: 80,
  179.                         clusterDisableClickZoom: true
  180.                     });
  181.                     loadForm();
  182.                 });
  183.                 function loadRoutes() {
  184.                     \$.ajax({
  185.                         url:routesUrl,
  186.                         dataType: \"json\",
  187.                         async: false,
  188.                         success: function (routes) {
  189.                             Routing.setRoutingData(routes);
  190.                         },
  191.                         error: function (xhr, ajaxOptions, thrownError) {}
  192.                     });
  193.                 }
  194.                 function setFormSubmitListener() {
  195.                     document.querySelector(\"form[name=\"+formName+\"]\").addEventListener('submit', function(e){
  196.                         e.preventDefault();
  197.                         if(!clusterer)
  198.                             return;
  199.                         filterData();
  200.                         return false;
  201.                     });
  202.                 }
  203.                 function loadForm() {
  204.                     fetch('";
  205.         // line 108
  206.         echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("map.form", ["city" => (isset($context["cityUriIdentity"]) || array_key_exists("cityUriIdentity"$context) ? $context["cityUriIdentity"] : (function () { throw new RuntimeError('Variable "cityUriIdentity" does not exist.'108$this->source); })())]), "html"nulltrue);
  207.         echo "', {
  208.                         mode: \"cors\",
  209.                         importance: \"low\",
  210.                         method: \"POST\",
  211.                         headers: {
  212.                             \"Content-Type\": \"application/x-www-form-urlencoded\",
  213.                             \"X-Requested-With\": \"XMLHttpRequest\"
  214.                         },
  215.                     }).then(response => {
  216.                         if (response.status < 300) {
  217.                             return response.text();
  218.                         } else {
  219.                             console.warn(\"🤔\");
  220.                             return null;
  221.                         }
  222.                     }).then(response => {
  223.                         document.querySelector('#map_form').innerHTML = response;
  224.                         filterData();
  225.                         setFormSubmitListener();
  226.                     });
  227.                 }
  228.                 function filterData() {
  229.                     preloader.style.display = 'block';
  230.                     var data = {};
  231.                     \$(\"form[name=\"+formName+\"]\").serializeArray().forEach((object)=>{
  232.                         //\"подгоняем\" данные под формат, ожидаемый формой при сабмите
  233.                         var fieldName = object.name.toString().replace(formName + '[', '').replace(']', '');
  234.                         var clearFieldName = fieldName.substr(0, fieldName.indexOf('['));
  235.                         if(~fieldName.indexOf('[]')) {
  236.                             checkArrayIsInFormObject(clearFieldName, data);
  237.                             data[clearFieldName].push(object.value);
  238.                         } else if(~fieldName.indexOf('[m')) {
  239.                             if(!object.value)
  240.                                 return;
  241.                             checkObjectIsInFormObject(clearFieldName, data);
  242.                             if(~fieldName.indexOf('[min]'))
  243.                                 data[clearFieldName]['min'] = object.value;
  244.                             if(~fieldName.indexOf('[max]'))
  245.                                 data[clearFieldName]['max'] = object.value;
  246.                         } else {
  247.                             data[fieldName] = object.value;
  248.                         }
  249.                     });
  250.                     \$.ajax({
  251.                         url:'";
  252.         // line 158
  253.         echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("map.filter", ["city" => (isset($context["cityUriIdentity"]) || array_key_exists("cityUriIdentity"$context) ? $context["cityUriIdentity"] : (function () { throw new RuntimeError('Variable "cityUriIdentity" does not exist.'158$this->source); })())]), "html"nulltrue);
  254.         echo "',
  255.                         type: \"POST\",
  256.                         dataType: \"json\",
  257.                         data: {
  258.                             \"form\": JSON.stringify(data),
  259.                         },
  260.                         async: true,
  261.                         success: function (return_data) {
  262.                             // console.log(return_data);
  263.                             getDetailsData({
  264.                                 data: return_data,
  265.                                 callback: (points) => updateMap(points)
  266.                             })
  267.                             preloader.style.display = 'none';
  268.                         },
  269.                         error: function (xhr, ajaxOptions, thrownError) {}
  270.                     });
  271.                 }
  272.                 function checkArrayIsInFormObject(name, formObject) {
  273.                     if(false == formObject.hasOwnProperty(name))
  274.                         formObject[name] = [];
  275.                 }
  276.                 function checkObjectIsInFormObject(name, formObject) {
  277.                     if(false == formObject.hasOwnProperty(name))
  278.                         formObject[name] = {};
  279.                 }
  280.                 function getDetailsData({data, callback}) {
  281.                     const profilesRawData = data.profiles || [];
  282.                     const saloonsRawData = data.saloons || [];
  283.                     const profilesAllId = profilesRawData.map(_data => _data[0]).flat();
  284.                     const saloonsAllId = saloonsRawData.map(_data => _data[0]).flat();
  285.                     const profileArray = Array.isArray(profilesAllId) ? profilesAllId : [];
  286.                     const saloonIdArray = Array.isArray(saloonsAllId) ? saloonsAllId : [];
  287.                     const requestBody = {};
  288.                     requestBody.profiles = profileArray;
  289.                     requestBody.saloons = saloonIdArray;
  290.                     fetch('";
  291.         // line 201
  292.         echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("map.detail", ["city" => (isset($context["cityUriIdentity"]) || array_key_exists("cityUriIdentity"$context) ? $context["cityUriIdentity"] : (function () { throw new RuntimeError('Variable "cityUriIdentity" does not exist.'201$this->source); })())]), "html"nulltrue);
  293.         echo "', {
  294.                         method: \"POST\",
  295.                         headers: {
  296.                             'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
  297.                             'X-Requested-With': 'XMLHttpRequest',
  298.                         },
  299.                         body: new URLSearchParams(requestBody).toString()
  300.                     })
  301.                     .then(response => response.json())
  302.                     .then(data => {
  303.                         const { profiles, saloons } = data;
  304.                         callback({ profiles, saloons });
  305.                     })
  306.                     .catch(error => console.error(error));
  307.                     ";
  308.         // line 233
  309.         echo "                }
  310.                 function updateMap(points) {
  311.                     clusterer.removeAll();
  312.                     if (!points || (points.profiles.length == 0 && points.saloons.length == 0)) return
  313.                     const mergedPoints = [...points.profiles, ...points.saloons];
  314.                     var getImgUrl = function(path, imgType) {
  315.                         if(path[0] == '/')
  316.                             return path;
  317.                             console.log(imgType)
  318.                             console.log(photoPath)
  319.                             console.log(thumbPath)
  320.                         var assetPackagePath = '';
  321.                         if(imgType == 'avatar')
  322.                             assetPackagePath = avatarPath;
  323.                         else if(imgType == 'photo')
  324.                             assetPackagePath = photoPath; // /media/profiles/vp/rd/vprdP4ShlKUpkOB.jpg
  325.                         else if(imgType == 'thumb')
  326.                             assetPackagePath = thumbPath; // /media/saloons/thumb///.jpg
  327.                         return `\${assetPackagePath}\${path.slice(0, 2).toLowerCase()}/\${path.slice(2, 4).toLowerCase()}/\${path}.jpg`;
  328.                     };
  329.                     var getPointData = function (point) {
  330.                         const isProfile = point[0] == 1;
  331.                         const isSaloon = point[0] == 2;
  332.                         let url = '';
  333.                         const uri = point[3];
  334.                         if(isProfile) {
  335.                             url = RoutingDecorator.generate(
  336.                                 'profile_preview.page',
  337.                                 multipleCities ? {city: cityUriIdentity, profile: uri} : {profile: uri}
  338.                             );
  339.                         } else if(isSaloon) {
  340.                             url = RoutingDecorator.generate(
  341.                                 'saloon_preview.page',
  342.                                 multipleCities ? {city: cityUriIdentity, saloon: uri} : {saloon: uri}
  343.                             );
  344.                         }
  345.                         var processProfileShowsUrl = '";
  346.         // line 278
  347.         echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("map.increment_profile_shows", (((isset($context["multipleCities"]) || array_key_exists("multipleCities"$context) ? $context["multipleCities"] : (function () { throw new RuntimeError('Variable "multipleCities" does not exist.'278$this->source); })())) ? (["city" => (isset($context["cityUriIdentity"]) || array_key_exists("cityUriIdentity"$context) ? $context["cityUriIdentity"] : (function () { throw new RuntimeError('Variable "cityUriIdentity" does not exist.'278$this->source); })())]) : ([]))), "html"nulltrue);
  348.         echo "';
  349.                         return {
  350.                             balloonContentHeader: '',
  351.                             balloonContentBody: '<p><img src=\"' + getImgUrl(point[5], isProfile ? 'avatar' : 'thumb') + '\" width=\"100\" /></p>' + '<font size=3><b><a target=\"_blank\" href=\"' + url + '\">Профиль</a></b></font>'
  352.                                 + '<img style=\"display:none;\" width=\"0\" height=\"0\" src=\"' + processProfileShowsUrl + '?id=' + (isProfile ? point[9] : null)+'\" />', //не убирать, функционально важно
  353.                             balloonContentFooter: '<font size=1>' + point[8] + ',' + point[9] + ',' + point[10] + '</strong>',
  354.                             clusterCaption: '<strong>' + (isSaloon ? 'Салон ' : '') + point[4] + '</strong>'
  355.                         };
  356.                     };
  357.                     var getPointOptions = function (index, type) {
  358.                         return {
  359.                             preset: type == 'profile' ? 'islands#violetIcon' : 'islands#redIcon'
  360.                         };
  361.                     };
  362.                     var geoObjects = [];
  363.                     for(var i = 0, len = mergedPoints.length; i < len; i++) {
  364.                         const _point = mergedPoints[i];
  365.                         geoObjects[i] = new ymaps.Placemark([_point[1], _point[2]], getPointData(_point), getPointOptions(i, _point[0] == 1));
  366.                     }
  367.                     //В кластеризатор можно добавить javascript-массив меток (не геоколлекцию) или одну метку.
  368.                     clusterer.add(geoObjects);
  369.                     myMap.geoObjects.add(clusterer);
  370.                     // Спозиционируем карту так, чтобы на ней были видны все объекты.
  371.                     myMap.setBounds(clusterer.getBounds(), {
  372.                         checkZoomRange: true
  373.                     });
  374.                 }
  375.             });
  376.         })();
  377.     </script>
  378. ";
  379.         
  380.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f->leave($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof);
  381.         
  382.         $__internal_5a27a8ba21ca79b61932376b2fa922d2->leave($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof);
  383.         
  384.         $__internal_b91a4435ea3baf1e2b6bfda56133dace->leave($__internal_b91a4435ea3baf1e2b6bfda56133dace_prof);
  385.     }
  386.     /**
  387.      * @codeCoverageIgnore
  388.      */
  389.     public function getTemplateName()
  390.     {
  391.         return "Map/page.html.twig";
  392.     }
  393.     /**
  394.      * @codeCoverageIgnore
  395.      */
  396.     public function isTraitable()
  397.     {
  398.         return false;
  399.     }
  400.     /**
  401.      * @codeCoverageIgnore
  402.      */
  403.     public function getDebugInfo()
  404.     {
  405.         return array (  409 => 278,  362 => 233,  342 => 201,  296 => 158,  243 => 108,  184 => 52,  180 => 51,  170 => 44,  166 => 43,  162 => 42,  144 => 27,  130 => 16,  125 => 15,  112 => 14,  96 => 10,  92 => 9,  88 => 8,  83 => 6,  80 => 5,  78 => 4,  65 => 3,  36 => 1,);
  406.     }
  407.     public function getSourceContext()
  408.     {
  409.         return new Source("{% extends 'grid.html.twig' %}
  410. {% block mainContainer %}
  411.    {# {{ form(form) }}#}
  412.     <div id=\"map_form\"></div>
  413.     <img src=\"{{ asset('/static/preloader.gif') }}\" id=\"preloader\" style=\"display: none;\" />
  414.     <div id=\"map\"
  415.          data-city-uri-idenity=\"{{ cityUriIdentity }}\"
  416.          data-city-latitude=\"{{ cityLatitude }}\"
  417.          data-city-longitude=\"{{ cityLongitude }}\"
  418.          style=\"width:100%; height:500px;\"></div>
  419. {% endblock %}
  420. {% block javascripts %}
  421.     <script src=\"{{ asset('bundles/fosjsrouting/js/router.min.js') }}\"></script>
  422.     <script src=\"{{ path('fos_js_routing_js', { callback: 'fos.Router.setData' }) }}\"></script>
  423.     <script src=\"https://code.jquery.com/jquery-3.4.1.min.js\"></script>
  424.     <script src=\"https://api-maps.yandex.ru/2.1/?lang=ru_RU\" type=\"text/javascript\"></script>
  425.     <script type=\"text/javascript\">
  426.         ;var RoutingDecorator = {
  427.             generate: function (name, params) {
  428.                 const orig_name = name;
  429.                 try {
  430.                     Routing.getRoute(name)
  431.                 } catch(error) {
  432.                     name = name + '.' + '{{ app.request.locale }}';
  433.                     try {
  434.                         Routing.getRoute(name)
  435.                     } catch(error) {
  436.                         name = orig_name;
  437.                     }
  438.                 }
  439.                 return Routing.generate(name, params);
  440.             }
  441.         };
  442.         ;(function () {
  443.             document.addEventListener('DOMContentLoaded', _ => {
  444.                 var avatarPath = '{{ asset('', 'profile_media_avatar') }}';
  445.                 var photoPath = '{{ asset('', 'profile_media') }}';
  446.                 var thumbPath = '{{ asset('', 'saloon_media_thumb') }}';
  447.                 var mapContainer = document.querySelector('#map');
  448.                 var preloader = document.querySelector('#preloader');
  449.                 var cityUriIdentity = mapContainer.getAttribute('data-city-uri-idenity');
  450.                 var cityLatitude = mapContainer.getAttribute('data-city-latitude');
  451.                 var cityLongitude = mapContainer.getAttribute('data-city-longitude');
  452.                 var formName = 'filter_map_form';
  453.                 var multipleCities = {{ multipleCities }};
  454.                 var routesUrl = '/js/fos_js_routes{{ multipleCities ? '_city_prefixed' }}.json';
  455.                 loadRoutes();
  456.                 var myMap, clusterer;
  457.                 ymaps.ready(function () {
  458.                     myMap = new ymaps.Map('map', {
  459.                             center: [cityLatitude, cityLongitude],
  460.                             zoom: 9,
  461.                             behaviors: ['default', 'scrollZoom']
  462.                         }, {
  463.                             searchControlProvider: 'yandex#search'
  464.                         });
  465.                     clusterer = new ymaps.Clusterer({
  466.                             preset: 'islands#invertedVioletClusterIcons',//Через кластеризатор можно указать только стили кластеров,стили для меток нужно назначать каждой метке отдельно.
  467.                             groupByCoordinates: false,//Ставим true, если хотим кластеризовать только точки с одинаковыми координатами.
  468.                             //Опции кластеров указываем в кластеризаторе с префиксом \"cluster\".
  469.                             clusterDisableClickZoom: true,
  470.                             clusterHideIconOnBalloonOpen: false,
  471.                             geoObjectHideIconOnBalloonOpen: false
  472.                     });
  473.                     // Можно менять опции кластеризатора после создания.
  474.                     clusterer.options.set({
  475.                         gridSize: 80,
  476.                         clusterDisableClickZoom: true
  477.                     });
  478.                     loadForm();
  479.                 });
  480.                 function loadRoutes() {
  481.                     \$.ajax({
  482.                         url:routesUrl,
  483.                         dataType: \"json\",
  484.                         async: false,
  485.                         success: function (routes) {
  486.                             Routing.setRoutingData(routes);
  487.                         },
  488.                         error: function (xhr, ajaxOptions, thrownError) {}
  489.                     });
  490.                 }
  491.                 function setFormSubmitListener() {
  492.                     document.querySelector(\"form[name=\"+formName+\"]\").addEventListener('submit', function(e){
  493.                         e.preventDefault();
  494.                         if(!clusterer)
  495.                             return;
  496.                         filterData();
  497.                         return false;
  498.                     });
  499.                 }
  500.                 function loadForm() {
  501.                     fetch('{{ path('map.form', {city: cityUriIdentity}) }}', {
  502.                         mode: \"cors\",
  503.                         importance: \"low\",
  504.                         method: \"POST\",
  505.                         headers: {
  506.                             \"Content-Type\": \"application/x-www-form-urlencoded\",
  507.                             \"X-Requested-With\": \"XMLHttpRequest\"
  508.                         },
  509.                     }).then(response => {
  510.                         if (response.status < 300) {
  511.                             return response.text();
  512.                         } else {
  513.                             console.warn(\"🤔\");
  514.                             return null;
  515.                         }
  516.                     }).then(response => {
  517.                         document.querySelector('#map_form').innerHTML = response;
  518.                         filterData();
  519.                         setFormSubmitListener();
  520.                     });
  521.                 }
  522.                 function filterData() {
  523.                     preloader.style.display = 'block';
  524.                     var data = {};
  525.                     \$(\"form[name=\"+formName+\"]\").serializeArray().forEach((object)=>{
  526.                         //\"подгоняем\" данные под формат, ожидаемый формой при сабмите
  527.                         var fieldName = object.name.toString().replace(formName + '[', '').replace(']', '');
  528.                         var clearFieldName = fieldName.substr(0, fieldName.indexOf('['));
  529.                         if(~fieldName.indexOf('[]')) {
  530.                             checkArrayIsInFormObject(clearFieldName, data);
  531.                             data[clearFieldName].push(object.value);
  532.                         } else if(~fieldName.indexOf('[m')) {
  533.                             if(!object.value)
  534.                                 return;
  535.                             checkObjectIsInFormObject(clearFieldName, data);
  536.                             if(~fieldName.indexOf('[min]'))
  537.                                 data[clearFieldName]['min'] = object.value;
  538.                             if(~fieldName.indexOf('[max]'))
  539.                                 data[clearFieldName]['max'] = object.value;
  540.                         } else {
  541.                             data[fieldName] = object.value;
  542.                         }
  543.                     });
  544.                     \$.ajax({
  545.                         url:'{{ path('map.filter', {city:cityUriIdentity}) }}',
  546.                         type: \"POST\",
  547.                         dataType: \"json\",
  548.                         data: {
  549.                             \"form\": JSON.stringify(data),
  550.                         },
  551.                         async: true,
  552.                         success: function (return_data) {
  553.                             // console.log(return_data);
  554.                             getDetailsData({
  555.                                 data: return_data,
  556.                                 callback: (points) => updateMap(points)
  557.                             })
  558.                             preloader.style.display = 'none';
  559.                         },
  560.                         error: function (xhr, ajaxOptions, thrownError) {}
  561.                     });
  562.                 }
  563.                 function checkArrayIsInFormObject(name, formObject) {
  564.                     if(false == formObject.hasOwnProperty(name))
  565.                         formObject[name] = [];
  566.                 }
  567.                 function checkObjectIsInFormObject(name, formObject) {
  568.                     if(false == formObject.hasOwnProperty(name))
  569.                         formObject[name] = {};
  570.                 }
  571.                 function getDetailsData({data, callback}) {
  572.                     const profilesRawData = data.profiles || [];
  573.                     const saloonsRawData = data.saloons || [];
  574.                     const profilesAllId = profilesRawData.map(_data => _data[0]).flat();
  575.                     const saloonsAllId = saloonsRawData.map(_data => _data[0]).flat();
  576.                     const profileArray = Array.isArray(profilesAllId) ? profilesAllId : [];
  577.                     const saloonIdArray = Array.isArray(saloonsAllId) ? saloonsAllId : [];
  578.                     const requestBody = {};
  579.                     requestBody.profiles = profileArray;
  580.                     requestBody.saloons = saloonIdArray;
  581.                     fetch('{{ path('map.detail', {city:cityUriIdentity}) }}', {
  582.                         method: \"POST\",
  583.                         headers: {
  584.                             'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
  585.                             'X-Requested-With': 'XMLHttpRequest',
  586.                         },
  587.                         body: new URLSearchParams(requestBody).toString()
  588.                     })
  589.                     .then(response => response.json())
  590.                     .then(data => {
  591.                         const { profiles, saloons } = data;
  592.                         callback({ profiles, saloons });
  593.                     })
  594.                     .catch(error => console.error(error));
  595.                     {# \$.ajax({
  596.                         url:'{{ path('map.detail', {city:cityUriIdentity}) }}',
  597.                         type: \"POST\",
  598.                         dataType: \"json\",
  599.                         data: {
  600.                             \"profiles\": profileArray.toString(),
  601.                             \"saloons\": saloonIdArray.toString(),
  602.                         },
  603.                         async: true,
  604.                         success: function (return_data) {
  605.                             console.log(return_data);
  606.                         },
  607.                         error: function (xhr, ajaxOptions, thrownError) {}
  608.                     }); #}
  609.                 }
  610.                 function updateMap(points) {
  611.                     clusterer.removeAll();
  612.                     if (!points || (points.profiles.length == 0 && points.saloons.length == 0)) return
  613.                     const mergedPoints = [...points.profiles, ...points.saloons];
  614.                     var getImgUrl = function(path, imgType) {
  615.                         if(path[0] == '/')
  616.                             return path;
  617.                             console.log(imgType)
  618.                             console.log(photoPath)
  619.                             console.log(thumbPath)
  620.                         var assetPackagePath = '';
  621.                         if(imgType == 'avatar')
  622.                             assetPackagePath = avatarPath;
  623.                         else if(imgType == 'photo')
  624.                             assetPackagePath = photoPath; // /media/profiles/vp/rd/vprdP4ShlKUpkOB.jpg
  625.                         else if(imgType == 'thumb')
  626.                             assetPackagePath = thumbPath; // /media/saloons/thumb///.jpg
  627.                         return `\${assetPackagePath}\${path.slice(0, 2).toLowerCase()}/\${path.slice(2, 4).toLowerCase()}/\${path}.jpg`;
  628.                     };
  629.                     var getPointData = function (point) {
  630.                         const isProfile = point[0] == 1;
  631.                         const isSaloon = point[0] == 2;
  632.                         let url = '';
  633.                         const uri = point[3];
  634.                         if(isProfile) {
  635.                             url = RoutingDecorator.generate(
  636.                                 'profile_preview.page',
  637.                                 multipleCities ? {city: cityUriIdentity, profile: uri} : {profile: uri}
  638.                             );
  639.                         } else if(isSaloon) {
  640.                             url = RoutingDecorator.generate(
  641.                                 'saloon_preview.page',
  642.                                 multipleCities ? {city: cityUriIdentity, saloon: uri} : {saloon: uri}
  643.                             );
  644.                         }
  645.                         var processProfileShowsUrl = '{{ path('map.increment_profile_shows', multipleCities ? {city:cityUriIdentity} : {}) }}';
  646.                         return {
  647.                             balloonContentHeader: '',
  648.                             balloonContentBody: '<p><img src=\"' + getImgUrl(point[5], isProfile ? 'avatar' : 'thumb') + '\" width=\"100\" /></p>' + '<font size=3><b><a target=\"_blank\" href=\"' + url + '\">Профиль</a></b></font>'
  649.                                 + '<img style=\"display:none;\" width=\"0\" height=\"0\" src=\"' + processProfileShowsUrl + '?id=' + (isProfile ? point[9] : null)+'\" />', //не убирать, функционально важно
  650.                             balloonContentFooter: '<font size=1>' + point[8] + ',' + point[9] + ',' + point[10] + '</strong>',
  651.                             clusterCaption: '<strong>' + (isSaloon ? 'Салон ' : '') + point[4] + '</strong>'
  652.                         };
  653.                     };
  654.                     var getPointOptions = function (index, type) {
  655.                         return {
  656.                             preset: type == 'profile' ? 'islands#violetIcon' : 'islands#redIcon'
  657.                         };
  658.                     };
  659.                     var geoObjects = [];
  660.                     for(var i = 0, len = mergedPoints.length; i < len; i++) {
  661.                         const _point = mergedPoints[i];
  662.                         geoObjects[i] = new ymaps.Placemark([_point[1], _point[2]], getPointData(_point), getPointOptions(i, _point[0] == 1));
  663.                     }
  664.                     //В кластеризатор можно добавить javascript-массив меток (не геоколлекцию) или одну метку.
  665.                     clusterer.add(geoObjects);
  666.                     myMap.geoObjects.add(clusterer);
  667.                     // Спозиционируем карту так, чтобы на ней были видны все объекты.
  668.                     myMap.setBounds(clusterer.getBounds(), {
  669.                         checkZoomRange: true
  670.                     });
  671.                 }
  672.             });
  673.         })();
  674.     </script>
  675. {% endblock %}""Map/page.html.twig""/app/templates/Map/page.html.twig");
  676.     }
  677. }