← Вернуться к списку тем

Вывод корзины по кнопке

Хочу вывести корзину по нажатию кнопки на клавиатуре. Если корзина есть выводим ее аналогично нажатию кнопки перейти в корзину, после добавления товара в корзину.
Если нет, выводим стандартный текст, в корзине пусто.

Кнопку клавиатуры вывел в starbot, в router как прописать действие?
За вывод корзины отвечает метод showBasket я верно понимаю? Но видимо плохо соображаю какую переменную ему нужно скормить для отображения корзины? Можете помочь?

Ответы


  • iMakeBots [14.12.2019 в 13:11 → Art Kub]
    При нажатии кнопки клавиатуры "Корзина" - в бот прилетит обычное текстовое значение "Корзина" - его и надо будет ловить в роутере:

     
    ...
                   } elseif ($text == "Корзина") {
                        // Вывод корзины
                        $this->showBasket($data['callback_query']);
    ...
    
  • Art Kub [14.12.2019 в 15:03 → iMakeBots]
    Кнопка прописана как KeybordButton в startBot
    
        $buttons_first = [
          [
            $this->buildKeyboardButton("? Корзина"),
            $this->buildKeyboardButton("? Мои заказы"),
          ],
          [
            $this->buildKeyboardButton("? Доставка и оплата"),
            $this->buildKeyboardButton("ℹ️ Помощь"),
          ],
          [
            $this->buildKeyboardButton("? Главная"),
            $this->buildKeyboardButton("? Поиск товара"),
          ]
        ];
        
        $this->sendMessage($chat_id, "Ниже - категории товаров, кликайте для выбора товара", $buttons_first, true);
    

    router($data) прописываю в секцию: if (array_key_exists("text", $data['message'])) {

    
                    } elseif ($text == "? Корзина") {
                        //$this->sendMessage($chat_id, "После нажатия кнопки показываем inline корзину. Если корзина пуста - значит текст, что корзина пуста");
              $this->setFileLog('Нажали кнопку корзина');
              $this->setFileLog($data);
              if($this->showBasket($data['callback_query'])){$this->setFileLog('showBasket - запустился');}
              else {$this->setFileLog('showBasket - отдыхает :(');}
              $this->setFileLog($this->showBasket($data['callback_query']));
    

    Но судя по всему в данном случае $data['callback_query'] отсутствует :(
    Т.к. в логах:
    
    Нажали кнопку корзина
    Нажали кнопку корзина
    Array
    (
        [update_id] => xxxxxxxxx
        [message] => Array
            (
                [message_id] => 379
                [from] => Array
                    (
                        [id] => yyyyyyyyy
                        [is_bot] => 
                        [first_name] => Din
                        [last_name] => Don
                        [language_code] => en
                    )
    
                [chat] => Array
                    (
                        [id] => yyyyyyyyy
                        [first_name] => Din
                        [last_name] => Don
                        [type] => private
                    )
    
                [date] => 1576324587
                [text] => ? Корзина
            )
    
    )
    
    Запуск метода showBasket
    
    showBasket - отдыхает :(
    Запуск метода showBasket
    

    В функцию showBasket добавил setFileLog чтобы как-то начинать разбираться что происходит:
    
    private function showBasket($data)
        {
            // получаем данные
            $chat_id = $this->getChatId($data);
            // меняем действие
            @$this->setActionUser("show_basket", $chat_id);
            // Выводим корзину
            $this->showBasketBegin($chat_id, $data);
            // глушим уведомление
            $this->notice($data['id']);
        $this->setFileLog("Запуск метода showBasket");
        $this->setFileLog($data);
        }
    

    Т.е. showBasket ожидает $data['callback_query'] которого нет при нажатии на кнопку "Корзина". Как же его получить?
  • iMakeBots [14.12.2019 в 15:10 → Art Kub]
    )) сорри давно уже писал этот бот.

    попробуйте передавать в роутере сразу в метод $this->showBasketBegin($user_id, $data)
    пусть $data будет как там есть (объект Message)
    ===
    Сейчас совсем по другому мой роутер работает, там все проще.
  • Art Kub [14.12.2019 в 15:59 → iMakeBots]
    Итак, метод showBasketBegin хочет получить на вход user_id и data
    Добавил опять же немного логгирования чтоб разобраться.
    
        private function showBasketBegin($user_id, $data)
        {
        $this->setFileLog("Запуск метода showBasketBegin");
            // получаем все из корзины пользователя
            $check = $this->pdo->prepare("SELECT * FROM bot_shop_basket WHERE user_id = :user_id");
            $check->execute(['user_id' => $user_id]);
            // количество в корзине
            $basketCount = $check->rowCount();
            // если в корзине что-то есть
            if ($basketCount > 0) {
                // получаем данные для отрисовки корзины
                $array = $this->drawBasket($user_id, 0, $basketCount);
                $text = $array['text'];
                $buttons = $array['buttons'];
            } else {
                // если в корзине пусто
                $text = "У вас нет добавленных товаров в корзине.";
            }
            // готовим данные для отображения
            $data_send = [
                'chat_id' => $user_id,
                'text' => $text,
                'message_id' => $this->getMessageId($data),
                'parse_mode' => 'html',
            ];
            // проверяем наличие кнопок
            if (is_array($buttons)) {
                $data_send['reply_markup'] = $this->buildInlineKeyBoard($buttons);
            }
            // отправляем сообщение
            $this->botApiQuery("editMessageText", $data_send);
        
        $this->setFileLog("Входящие данные user_id и data");
        $this->setFileLog($user_id);
        $this->setFileLog($data);
        $this->setFileLog("Конец входящих данных в showBasketBegin");
        }
    

    С user_id вроде понятно, в роутере это $chat_id = $this->getChatId($data);
    $data в showBasketBegin нам нужна чтобы понять id сообщения через 'message_id' => $this->getMessageId($data),
    чтобы понять на месте какого сообщения выводить корзину. Я верно рассуждаю?

    private function getMessageId($data)
    {
    if ($this->getType($data) == "callback_query") {
    return $data['callback_query']['message']['message_id'];
    }
    return $data['message']['message_id'];
    }

    Однако все равно не запускается, подозреваю что это из-за $this->botApiQuery("editMessageText", $data_send);
    Ведь если мы нажимаем кнопку на клавиатуре то нам нужно отправить новое сообщение, а не редактировать текущее, верно?

    Для этого сделал проверку:
    
        if ($this->getType($data) == "callback_query") {
          $this->setFileLog("Пришло callback_query, редактируем текущее сообщение");
          $this->botApiQuery("editMessageText", $data_send);
        }
        else {
          $this->setFileLog("Пришло НЕ callback_query, Пишем новое сообщение");
          $this->sendMessage($user_id, $text, $buttons);
        }
    

    Заработало, по кнопке стала показываться корзина. Но видимо проверка $this->getType($data) == "callback_query" - в данном случае никогда не пройдет, и даже после добавления товара в корзину и переход в корзину по inline-кнопке все равно отдает корзину в новое сообщение. Подскажите как условие составить?
  • iMakeBots [14.12.2019 в 16:02 → Art Kub]
    Можно флаг поставить в showBasketBegin($chat_id, $data, $flag = true)
    по умолчанию true - это для старой логики и если вы отсылаете через клаву то передавать флаг false

    и сама проверка делается в showBasketBegin если флаг true то логику для кнопки если false то логику для клавы
  • Art Kub [14.12.2019 в 16:12 → Art Kub]
    Туплю, конечно же:) Спасибо за ответы! И не нужно извиняться, вы тут никому ничего не должны. Ещё раз спасибо!
  • artem Sh [29.07.2020 в 11:15 → Art Kub]
    Красавчик - Земляк! :-) можешь подсказать с корзиной?