Ajax, json, jquery - не добавляется товар в корзине!

12
P
На сайте с 03.05.2020
Offline
4
150

Добрый день!

При нажатии на "Добавить в корзину",  во-первых, ссылка "Добавить в корзину" должна исчезнуть, во-вторых, напротив ссылки "В корзине" вместо слова "пусто" должна появляться цифра.

Главный вопрос - почему ни того, ни другого не происходит?

Нажимаю "Добавить в корзину", на странице ничего не меняется, и в консоли файрбага появляется:


Скрипт main.js сейчас выглядит так:

/**
*  Функция добавления товара в корзину
*
*  @param integer itemId ID продукта
*  @return в случае успеха обновятся данные корзины на странице
*/
function addToCart(itemId) {
    console.log("js - addToCart()");
    $.ajax({
        type: 'POST',
        async: false,
        url: "cart/addtocart/" + itemId + '/',
        dataType: 'json',
        success: function (data) {
            if(data['success']){
                $('#cartCntItems').html(data['cntItems']);

                $('#addCart_'+ itemId).hide();
                $('#removeCart_'+ itemId).show();
            }
        }

    });
}

Файл leftcolumn.tpl:

{* левый столбец *}

<div id="leftColumn">


    <div id="leftMenu">
        <div class="menuCaption">Меню:</div>
        {foreach $rsCategories as $item}
            <a href="/?controller=category&id={$item['id']}">{$item['name']}</a><br />
            {if isset($item['children'])}
                {foreach $item['children'] as $itemChild}
                    --<a href="?controller=category&id={$itemChild['id']}">{$itemChild['name']}</a><br />
                {/foreach}
            {/if}
        {/foreach}

    </div>

        <div class="menuCaption">Корзина</div>
        <a href="/cart/" title="Перейти в корзину">В корзине</a>
        <span id="cartCntItems">
            {if $cartCntItems > 0}{$cartCntItems}{else}пусто{/if}
        </span>
</div>

Файл header.tpl:

<html>
<head>
    <title>{$pageTitle}</title>
    <link rel="stylesheet" href="{$TemplateWebPath}css/main.css" type="text/css"/>
    <script src="js/jquery-3.5.1.min.js" type="text/javascript"></script>
    <script src="js/main.js" type="text/javascript"></script>
</head>
<body>
<div id="header">
    <h1>my shop - интернет магазин</h1>
</div>


{include file='leftcolumn.tpl'}

<div id="centerColumn">

Файл product.tpl:

{* страница продукта*}
    <h3>{$rsProduct['name']}</h3>
    <img width="575" src="../www/images/products/{$rsProduct['image']}">
    Стоимость: {$rsProduct['price']}

    <a id="addCart_{$rsProduct['id']}" onclick="addToCart({$rsProduct['id']}); return false;" href="#">Добавить в корзину</a>
    <p> Описание <br />{$rsProduct['description']}</p>

Файл ProductController.php:
<?php

/**
* ProductController.php
*
* Контроллер страницы товара (/product/1)
*
*/

//подключаем модели
include_once '../models/ProductsModel.php';
include_once '../models/CategoriesModel.php';

/**
* Формирование страницы продукта
*
* @param object $smarty шаблонизатор
*/

function indexAction($smarty) {
    $itemId = isset($_GET['id']) ? $_GET['id'] : null;
    if($itemId == null) exit();

    //получить данные продукта
    $rsProduct = getProductById($itemId);

    //получить все категории
    $rsCategories = getAllMainCatsWithChildren();

    $smarty->assign('pageTitle', '');
    $smarty->assign('rsCategories', $rsCategories);
    $smarty->assign('rsProduct', $rsProduct);

    loadTemplate($smarty, 'header');
    loadTemplate($smarty, 'product');
    loadTemplate($smarty, 'footer');
}

Ошибок, кроме одной в консоли Хрома, сейчас нигде не выводится.  Сообщение о ней появляется на всех страницах браузера:

Как  определить, почему не работает код, так как надо?

При помощи отладочной функции

function d($value = null, $die = 1)
{
    echo 'Debug: <br /><pre>';
    print_r($value);
    echo '</pre>';

    if($die) die;

определил, что в файл ProductController.php приходит значение идентификатора выбранного продукта в переменную $itemId. Такая же переменная есть и в файле main.js, которая приходит в функцию addToCart(itemId) и хотелось бы определить, что приходит в эту функцию, но, как это сделать я не знаю (это же не php код и функция d() тут не работает). Также, хотелось бы определить, что приходит в строку:

{if $cartCntItems > 0}{$cartCntItems}{else}пусто{/if}

в переменную $cartCntItems (и приходит ли, что-то?), но, как это сделать не знаю.

Вкладка Sourses при нажатии на "Добавить в корзину":


Вкладка Network при нажатии на "Добавить в корзину":



VHS
На сайте с 28.09.2007
Offline
142
VHS
#1

При выполнении запроса со стороны сервера приходит ответ. На вкладке network смотри док, который приходит в ответ на запрос (тип xhr, видимо 12/ это он). Нажми на него и посмотри текст ответа. Вариантов громадное количество, посмотри что возвращается. А еще лучше измени js на 


success: function (data) {
console.log(data)             if(data['success']){
                $('#cartCntItems').html(data['cntItems']);                 $('#addCart_'+ itemId).hide();                 $('#removeCart_'+ itemId).show();             }         }

И смотри приходящие данные в консоли. Если это не json, в чем я уверен на 99%, то смотри что отдает сервер.

S
На сайте с 13.10.2014
Offline
148
#2
ВО вкладке "сеть" если ткнуть на действие, то можно посмотреть отсылаемые и принимаемые данные.
смотрите туда.
если у вас уходит всё в точности, а товар не добавляется, значит скорее всего что-то на серверной стороне.

но надо смотреть работу скрипта живьём, иначе это сродни проведению операции по телефону
P
На сайте с 03.05.2020
Offline
4
#3
VHS #:

При выполнении запроса со стороны сервера приходит ответ. На вкладке network смотри док, который приходит в ответ на запрос (тип xhr, видимо 12/ это он). Нажми на него и посмотри текст ответа. Вариантов громадное количество, посмотри что возвращается. А еще лучше измени js на 


И смотри приходящие данные в консоли. Если это не json, в чем я уверен на 99%, то смотри что отдает сервер.

При нажатии на  12/ на вкладке Network - Preview появляется:

Это контент другого сайта (bitrix.mini), не имеющего отношения к тому, о котором создана тема! Каким-то образом данные другого сайта попадают в этот. Просто, я два разных сайта: myshop.local (о котором сейчас речь) и другой - bitrix.mini расположил в одной директории:

При нажатии на  12/ на вкладке Network - Headers появляется:

При нажатии на  12/ на вкладке Network - Cookies появляется:



При нажатии на  12/ на вкладке Network - Response  появляется:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru" lang="ru">
<head>
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <title></title>
        <link rel="shortcut icon" type="image/x-icon" href="/bitrix/templates/corp_services_blue/favicon.ico" />
        
        <link rel="stylesheet" type="text/css" href="/bitrix/templates/corp_services_blue/common.css" />
        
        <meta http-equiv="Content-Type" content="text/html; charset=windows-1251" />
<link href="/bitrix/js/main/core/css/core.min.css?15976054692854" type="text/css" rel="stylesheet" />



<link href="/bitrix/cache/css/s1/corp_services_blue/template_2d981ea5d389ce6b149d1b93878b6536/template_2d981ea5d389ce6b149d1b93878b6536_v1.css?159786877310359" type="text/css" data-template-style="true" rel="stylesheet" />
<script type="text/javascript">if(!window.BX)window.BX={};if(!window.BX.message)window.BX.message=function(mess){if(typeof mess=='object') for(var i in mess) BX.message[i]=mess[i]; return true;};</script>
<script type="text/javascript">(window.BX||top.BX).message({'JS_CORE_LOADING':'Загрузка...','JS_CORE_NO_DATA':'- Нет данных -','JS_CORE_WINDOW_CLOSE':'Закрыть','JS_CORE_WINDOW_EXPAND':'Развернуть','JS_CORE_WINDOW_NARROW':'Свернуть в окно','JS_CORE_WINDOW_SAVE':'Сохранить','JS_CORE_WINDOW_CANCEL':'Отменить','JS_CORE_WINDOW_CONTINUE':'Продолжить','JS_CORE_H':'ч','JS_CORE_M':'м','JS_CORE_S':'с','JSADM_AI_HIDE_EXTRA':'Скрыть лишние','JSADM_AI_ALL_NOTIF':'Показать все','JSADM_AUTH_REQ':'Требуется авторизация!','JS_CORE_WINDOW_AUTH':'Войти','JS_CORE_IMAGE_FULL':'Полный размер'});</script>

<script type="text/javascript" src="/bitrix/js/main/core/core.min.js?1597605468247888"></script>

<script>BX.setJSList(['/bitrix/js/main/core/core_ajax.js','/bitrix/js/main/core/core_promise.js','/bitrix/js/main/polyfill/promise/js/promise.js','/bitrix/js/main/loadext/loadext.js','/bitrix/js/main/loadext/extension.js','/bitrix/js/main/polyfill/promise/js/promise.js','/bitrix/js/main/polyfill/find/js/find.js','/bitrix/js/main/polyfill/includes/js/includes.js','/bitrix/js/main/polyfill/matches/js/matches.js','/bitrix/js/ui/polyfill/closest/js/closest.js','/bitrix/js/main/polyfill/fill/main.polyfill.fill.js','/bitrix/js/main/polyfill/find/js/find.js','/bitrix/js/main/polyfill/matches/js/matches.js','/bitrix/js/main/polyfill/core/dist/polyfill.bundle.js','/bitrix/js/main/polyfill/core/dist/polyfill.bundle.js','/bitrix/js/main/lazyload/dist/lazyload.bundle.js','/bitrix/js/main/polyfill/core/dist/polyfill.bundle.js','/bitrix/js/main/parambag/dist/parambag.bundle.js']);
BX.setCSSList(['/bitrix/js/main/lazyload/dist/lazyload.bundle.css','/bitrix/js/main/parambag/dist/parambag.bundle.css']);
</script>
<script type="text/javascript">(window.BX||top.BX).message({'LANGUAGE_ID':'ru','FORMAT_DATE':'DD.MM.YYYY','FORMAT_DATETIME':'DD.MM.YYYY HH:MI:SS','COOKIE_PREFIX':'BITRIX_SM','SERVER_TZ_OFFSET':'10800','SITE_ID':'s1','SITE_DIR':'/','USER_ID':'','SERVER_TIME':'1598284107','USER_TZ_OFFSET':'0','USER_TZ_AUTO':'Y','bitrix_sessid':'64ef157a16e5a6941cad1d1baa9639c4'});</script>


<script type="text/javascript">BX.setCSSList(['/bitrix/templates/corp_services_blue/styles.css','/bitrix/templates/corp_services_blue/template_styles.css']); </script>
<script type="text/javascript">
                                        (function () {
                                                "use strict";

                                                var counter = function ()
                                                {
                                                        var cookie = (function (name) {
                                                                var parts = ("; " + document.cookie).split("; " + name + "=");
                                                                if (parts.length == 2) {
                                                                        try {return JSON.parse(decodeURIComponent(parts.pop().split(";").shift()));}
                                                                        catch (e) {}
                                                                }
                                                        })("BITRIX_CONVERSION_CONTEXT_s1");

                                                        if (cookie && cookie.EXPIRE >= BX.message("SERVER_TIME"))
                                                                return;

                                                        var request = new XMLHttpRequest();
                                                        request.open("POST", "/bitrix/tools/conversion/ajax_counter.php", true);
                                                        request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
                                                        request.send(
                                                                "SITE_ID="+encodeURIComponent("s1")+
                                                                "&sessid="+encodeURIComponent(BX.bitrix_sessid())+
                                                                "&HTTP_REFERER="+encodeURIComponent(document.referrer)
                                                        );
                                                };

                                                if (window.frameRequestStart === true)
                                                        BX.addCustomEvent("onFrameDataReceived", counter);
                                                else
                                                        BX.ready(counter);
                                        })();
                                
</script>



        
        <!--[if lte IE 6]>
        <style type="text/css">
                
                #support-question {
                        background-image: none;
                        filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='./images/question.png', sizingMethod = 'crop');
                }
                
                #support-question { left: -9px;}
                
                #banner-overlay {
                        background-image: none;
                        filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='./images/overlay.png', sizingMethod = 'crop');
                }
                
        </style>
        <![endif]-->


        <link rel="stylesheet" type="text/css" href="/bitrix/templates/corp_services_blue/colors.css" />
                
</head>
<body>
                <div id="page-wrapper">
                
                        <div id="panel"></div>
        
                        <div id="header">
                                <table>
                                        <tr>
                                                <td id="logo"><a href="/" title="На главную страницу"></a></td>
                                                <td id="slogan"></td>
                                        </tr>
                                </table>

                                
                                <div id="search">
                                        <div class="flat">
        <form action="/search/index.php">
        <div id="search-button">
                        <input type="submit" name="s" id="search-submit-button" value="Поиск" onfocus="this.blur();">
        </div>
        <div class="search-box"><input type="text" name="q"></div>
        </form>
        </div>                          </div>
                        </div>


                                
                
                        <div id="content-wrapper">
                                <div id="content">
                                                                        <div id="breadcrumb">
                                                                                        </div>                                  
                                                                        
                                        <div id="workarea-wrapper">
                                                <div id="left-menu">
                                                
                                                </div>                                          
                                                <div id="workarea">
                                                        <div id="workarea-inner">
                                                        <h5></h5>


<p>CONTENT</p>

                                                        </div>
                                                </div>
                                        </div>
                                        
                                </div>
                                
                                <div id="sidebar">
                                        <div id="sidebar-inner">
                                        
                                                <div id="telephone"><nobr></nobr></div>
                                                
                                                <div id="schedule"><div class="schedule">
                                                                                                </div></div>
                                                
                                                <div id="support">
                                                        <div id="support-question"></div>
                                                        <b class="r0"></b>
                                                        <div id="support-text"><a href="/contacts/feedback.php">Задайте вопрос</a></div>        
                                                        <b class="r0"></b>
                                                </div>

                                                                                </div>
                                </div>
                        </div>
        
                        <div id="space-for-footer"></div>
                        
                </div>
                
                <div id="footer">
                
                        <div id="copyright">
                                                </div>
                        <div id="bottom-menu">                  
                        
                        </div>
                </div>  
</body>
</html>

Видите ли Вы ошибку? может, ещё, какие-либо вкладки, файлы стоит посмотреть?

ArbNet
На сайте с 27.10.2019
Offline
53
#4

Вот вам и Bitrix хвалёный 😂


Блажен, кто не стремится сделать лучше: он не рискует быть не понятым.
SeVlad
На сайте с 03.11.2008
Offline
1399
#5
ArbNet #:
Вот вам и Bitrix хвалёный 😂

Не то что твоя нерождённая ламборджинья

https://d.searchengines.guru/3/32/chian11__adf8a4e9.jpg

Делаю хорошие сайты хорошим людям. Предпочтение коммерческим направлениям. Топики помощи с ⓌordPress (https://searchengines.guru/ru/forum/1032910 ) и основы безопасности сайтов ( https://searchengines.guru/ru/forum/774117 ). *** Помощь\консультации в топиках форума - БЕСПЛАТНО. Платные услуги ( https://wp.me/P3YHjQ-3 ) - с бюджетом от 150$ ***
S
На сайте с 13.10.2014
Offline
148
#6

Смотрите. Обычно алгоритм поиска проблем с аяксом следующий
1. Отключаете любое кэширование
2. оставляете только xhr и очищаете все логи дебагера, включаете все сообщения в консоли
3. смотрите консоль нет ли каких ошибок с яваскриптом
4. производите действие. Которое должно привести к аяксовому запросу.
5. обращаетесь обратно к консоли. смотрите. Нет ли чего интересного (ошибок яваскрипта, сообщений от самого скрипта, выполнившего запрос)
6. если есть - изучаете вопрос, штопаете. Если нет открываете вкладку сеть
7. смотрите содержимое запроса. Что он передал на сервер (закладка "заголовки" и "запрс"  ) и что он получил от сервера (закладка "ответ")
7а. запрос должен быть вида (адрес: Вашсайт.ru/путь/до/скрипта/обработчика.php , + запрос постом, в котором указываются параметры товара ) на что сайт возвращает джейсон с параметрами корзины.
8. проверяете правильный ли адрес, на который уходят данные (бывает так, что дергается другой скрипт)
9. Проверяете полноту отправляемых клиентом данных и подпись (если она используется)
10. Проверяете ответ сервера.
11. если сервер обрабатывает запрос, но не отправляет валидные данные, то скорее всего в отправляемый контент влезает какой-то мусор, от варнинга, до лишнего пробела
12. это проверяется очень просто. при релоаде страницы товар должен быть в корзине. Это говорит о том. что запрос с клиента на сервер поступает, но в обратную сторону идет битый джейсон.
13. если запрос из п.9 валидный, а товар все-равно в корзине не появляется, значит где-то ошибка в пхп скрипте и надо копать его.

P
На сайте с 03.05.2020
Offline
4
#7
silicoid #:

Смотрите. Обычно алгоритм поиска проблем с аяксом следующий
1. Отключаете любое кэширование
2. оставляете только xhr и очищаете все логи дебагера, включаете все сообщения в консоли
3. смотрите консоль нет ли каких ошибок с яваскриптом
4. производите действие. Которое должно привести к аяксовому запросу.
5. обращаетесь обратно к консоли. смотрите. Нет ли чего интересного (ошибок яваскрипта, сообщений от самого скрипта, выполнившего запрос)
6. если есть - изучаете вопрос, штопаете. Если нет открываете вкладку сеть
7. смотрите содержимое запроса. Что он передал на сервер (закладка "заголовки" и "запрс"  ) и что он получил от сервера (закладка "ответ")
7а. запрос должен быть вида (адрес: Вашсайт.ru/путь/до/скрипта/обработчика.php , + запрос постом, в котором указываются параметры товара ) на что сайт возвращает джейсон с параметрами корзины.
8. проверяете правильный ли адрес, на который уходят данные (бывает так, что дергается другой скрипт)
9. Проверяете полноту отправляемых клиентом данных и подпись (если она используется)
10. Проверяете ответ сервера.
11. если сервер обрабатывает запрос, но не отправляет валидные данные, то скорее всего в отправляемый контент влезает какой-то мусор, от варнинга, до лишнего пробела
12. это проверяется очень просто. при релоаде страницы товар должен быть в корзине. Это говорит о том. что запрос с клиента на сервер поступает, но в обратную сторону идет битый джейсон.
13. если запрос из п.9 валидный, а товар все-равно в корзине не появляется, значит где-то ошибка в пхп скрипте и надо копать его.

Спасибо, конечно, но похоже,  приходят данные с другого сайта, который расположен в этой же директории (При нажатии на  12/ на вкладке Network - Preview, как я выше писал). Не пойму, почему так происходит?

S
На сайте с 13.10.2014
Offline
148
#8
Pavll #:

Спасибо, конечно, но похоже,  приходят данные с другого сайта, который расположен в этой же директории (При нажатии на  12/ на вкладке Network - Preview, как я выше писал). Не пойму, почему так происходит?

.htaccess смотрите или конфигурацию apache/nginx

P
На сайте с 03.05.2020
Offline
4
#9

Последние действия... Как я уже писал выше, папка с моим сайтом находится в директории C:\OSPanel\domains\test\www\myshop.local Так вот, файл index.php лежит в этой же директории C:\OSPanel\domains\test\www\index.php  (ранее я об этом не писал).  Файл index.php сейчас пуст, но эта пустота отображается, если нажать в Network  12/ на вкладке Network - Preview, как писалось выше. Если этот файл удалить, то в Network будет вот, что:

То есть, возможно дело не скриптах, а я, что-то напутал в путях. Но что?

Файл htaccess, который лежит в папке со всеми  сайтами:

Options -Indexes 
ErrorDocument 404 /404.php

php_value max_input_vars 10000

<IfModule mod_php5.c>
  php_flag allow_call_time_pass_reference 1
  php_flag session.use_trans_sid off
default_charset="cp1251"
  #php_value display_errors 1

  #php_value mbstring.func_overload 0

  #php_value mbstring.internal_encoding UTF-8
</IfModule>

<IfModule mod_rewrite.c>
  Options +FollowSymLinks
  RewriteEngine On

RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteCond %{REQUEST_FILENAME} [\xC2-\xDF][\x80-\xBF] [OR]
RewriteCond %{REQUEST_FILENAME} \xE0[\xA0-\xBF][\x80-\xBF] [OR]
RewriteCond %{REQUEST_FILENAME} [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} [OR]
RewriteCond %{REQUEST_FILENAME} \xED[\x80-\x9F][\x80-\xBF] [OR]
RewriteCond %{REQUEST_FILENAME} \xF0[\x90-\xBF][\x80-\xBF]{2} [OR]
RewriteCond %{REQUEST_FILENAME} [\xF1-\xF3][\x80-\xBF]{3} [OR]
RewriteCond %{REQUEST_FILENAME} \xF4[\x80-\x8F][\x80-\xBF]{2}
RewriteCond %{REQUEST_FILENAME} !/bitrix/virtual_file_system.php$
RewriteRule ^(.*)$ /bitrix/virtual_file_system.php [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-l
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_FILENAME} !/bitrix/urlrewrite.php$
  RewriteRule ^(.*)$ /bitrix/urlrewrite.php [L]
  RewriteRule .* - [E=REMOTE_USER:%{HTTP:Authorization}]
</IfModule>

<IfModule mod_dir.c>
  DirectoryIndex index.php index.html
</IfModule>

Тоже,  файл  htaccess, который лежит в сайте myshop.local, о котором и речь:

AddDefaultCharset utf-8

    Options +FollowSymLinks
    Options -Indexes
    DirectoryIndex index.php

    RewriteEngine On
    RewriteBase /  

RewriteRule ^([a-z]+)/([a-z]+)/([0-9]+)/$ /?controller=$1&action=$2&id=$3&%{QUERY_STRING} [NS,L]
RewriteRule ^([a-z]+)/([a-z]+)/$ /?controller=$1&action=$2&%{QUERY_STRING} [NS,L]
RewriteRule ^([a-z]+)/([0-9]+)/$ /?controller=$1&id=$2&%{QUERY_STRING} [NS,L]
RewriteRule ^([a-z]+)/$ /?controller=$1&%{QUERY_STRING} [NS,L]

        RewriteCond $1 !^(index\.php)
    RewriteCond %{REQUEST_URI} !\.(css│js│jpg│gif)$
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ index.php/$1 [L,QSA]

Файл index.php, тоже который в  сайте myshop.local:

<?php
session_start(); // стартуем сессию

// если в сессии нет массива корзины, то создаём его
if(! isset($_SESSION['cart'])) {
    $_SESSION['cart'] = array();
}


include_once '../config/config.php';        // Инициализация настроек
include_once '../config/db.php';        // Инициализация базы данных
include_once '../library/mainFunctions.php'; // Основные функции

// определяем с каким контроллером будем работать
$controllerName = isset($_GET['controller']) ? ucfirst($_GET['controller']) : 'Index';

// определяем с какой функцией будем работать
$actionName = isset($_GET['action']) ? $_GET['action'] : 'index';

// инициализируем переменную шаблонизатора количества элементов в корзине
$smarty->assign('cartCntItems', count($_SESSION['cart']));


loadPage($smarty, $controllerName, $actionName);

Не с путями ли, где-то, ошибка?

VHS
На сайте с 28.09.2007
Offline
142
VHS
#10

отправь запрос по полному URL, что будет?

Если сомневаешься в путях, пропиши в инклюдах вывод имени текущего файла и сравни результат со своими ожиданиями.

Насколько детально не делай выкладки, но разбираться в этой каше по скринам врядли кто-то будет, сам ты это сделаешь куда быстрее.

12

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий