skip to Main Content

For a Telegram bot that I am building I want to return inline buttons dynamically depending the returned PHP PDO recordset Telegram API docs.

Hardcoded a good function piece of code looks like the below.
This is confirmed working. It return two rows of buttons. The first row containing two buttons, the second row two buttons.

$reply  = "Some message to show before the buttons";
$keyb   = array('inline_keyboard' => array(
            array(
                array('text'=>'Link text', 'callback_data'=>'/command'),
                array('text'=>"Link text", 'callback_data'=>'/command')
            ),
            array(
                array('text'=>'Link text', 'callback_data'=>'/command'),
                array('text'=>'Link text', 'callback_data'=>'/command')
            )
          )
        );

$replyMarkup = json_encode($keyb);
sendMessage($chatID, $reply, $replyMarkup);

So far so good.
But now I want to populate these buttons dynamically given a PHP recordset.

The below does return the desired buttons, but I do not know how I can specify a cut-off point after two buttons to create the second row. In the format below all buttons end up on a single row. Even if the recordset returns 5 results.

$reply  = "Some message to show before the buttons";

$i=0;
// Loop through all results to create individual buttons
foreach ($stmt as $row) 
{
    $options[] = array('text'=>urlencode($row['title']), 'callback_data'=>'/x');
    $i++;
}

$keyb           = array('inline_keyboard' => array( $options ));
$replyMarkup    = json_encode($keyb);
sendMessage($chatID, $reply, $replyMarkup);

I considered using an if statement with modulo operator ($i%2=1), but do not know how to cope with the parent array() that defines the row…

...
if($i%2=1)
{ 
    $options[]="array("; // <-- Setting an array as a value will obviously fail
}    
... remaining code

Happy to hear any thoughts that might help me on my way!

Thanks.

2

Answers


  1. This should do the trick:

    <?php
    // DUMMY DATA
    $stmt = array(
                array('title'=>'Link text1', 'callback_data'=>'/command'),
                array('title'=>"Link text2", 'callback_data'=>'/command'),
                array('title'=>'Link text3', 'callback_data'=>'/command'),
                array('title'=>'Link text4', 'callback_data'=>'/command'),
                array('title'=>'Link text5', 'callback_data'=>'/command')
          );
    
    $i=0;
    $r=1;
    foreach ($stmt as $row)
    {
        // here's the trick: $options[$r][]
        $options[$r][] = array('text'=>urlencode($row['title']), 'callback_data'=>'/x');
        $i++;
        if($i===2) { // if counter at row 3
            $r++; // increase row index here
            $i=0; // reset counter
        };
    }
    
    // for debugging only:
    echo "<pre>";
    var_dump($options);
    echo "</pre>";
                                            // note the change here
    $keyb           = array('inline_keyboard' => $options);
    ?>
    

    The version of @abfackeln (what a username if you understand german..) is acutally nicer, because he uses modulus and doesn’t reset the counter.

    Login or Signup to reply.
  2. Forgive me here, I must jump in and shout:

    NOOOOOOO!

    to the other answers.

    PHP already provides a function that can break an array into “chunks” called array_chunk(). Do NOT use incrementing and modulus conditions to generate keys, use this one function.

    Code (Demo):

    $stmt = array(
                array('title'=>'Link ? text1', 'callback_data'=>'/x'),
                array('title'=>"Link & text2", 'callback_data'=>'/x'),
                array('title'=>'Link # text3', 'callback_data'=>'/x'),
                array('title'=>'Link * text4', 'callback_data'=>'/x'),
                array('title'=>'Link @ text5', 'callback_data'=>'/x')
          );
    
    // prepare the subarrays using resultset
    foreach($stmt as $row){
        $options[]=['text'=>urlencode($row['title']),'callback_data'=>'/x'];
    }
    
    // then chunk into pairs, assign key, json encode --> DONE
    var_export(json_encode(['inline_keyboard'=>array_chunk($options,2)]));
    //sendMessage($chatID,$reply,json_encode(['inline_keyboard'=>array_chunk($options,2)]));
    

    Output:

    {"inline_keyboard":[[[{"text":"Link+%3F+text1","callback_data":"\/x"},{"text":"Link+%26+text2","callback_data":"\/x"}],[{"text":"Link+%23+text3","callback_data":"\/x"},{"text":"Link+%2A+text4","callback_data":"\/x"}],[{"text":"Link+%40+text5","callback_data":"\/x"}]]]}
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search