I'm working on a telegram bot shop via https://github.com/php-telegram-bot/core in laravel.
In this app , each Product has many images that path of them is stored on th DB.
Now I want when send details of a product , images of that shown one by one that user can navigate them via a prev and next inline keyboard. like this picture :
For that after show all products in the shop as a inline query and after use choose one of them , On Chosen inline result Command, I get a product Id and fetch first image of that from DB like this :
class ChoseninlineresultCommand extends SystemCommand
{
public function execute ()
{
$chosenInlineResult = $this->getChosenInlineResult();
$chosenInlineResultId = $product_id = $chosenInlineResult->getResultId();
$chat_id = $chosenInlineResult->getFrom()->getId();
$product = Product::findOrFail($product_id);
$picture = $product->images->first();
$keyboard = KeyboardController::showProductKeyboard($product_id, $chat_id);
$result = view('show-product', compact('product','picture'))->render();
Request::sendMessage([
'chat_id' => $chat_id,
'text' => $result,
'reply_markup' => $keyboard,
'parse_mode' => 'HTML'
]);
}
}
Also showProductKeyboard of KeyboardController is like this :
static public function showProductKeyboard ($product_id, $user_id)
{
$inlineKeyboard = new InlineKeyboard([]);
$inlineKeyboard->addRow(new InlineKeyboardButton([
'text' => ' previous picture ⬅️️',
'callback_data' => 'prev_pic'
]), new InlineKeyboardButton([
'text' => '➡️ next picture ',
'callback_data' => 'next_pic'
]));
return $inlineKeyboard;
}
And finally show-product blade is simple as :
🛍️ <b>{{$product->title}}</b>
✅ <b>{{str_limit(strip_tags($product->desc), 50)}}</b>
💵 <b>{{number_format($product->price)}}</b> dollor
Picture
Problem is that I do not know how can I implement what I want .
You can't change the product image by callback query, you can change only the text by method editMessageText https://core.telegram.org/bots/api#editmessagetext
The solution can be deleting the message and send a new message with next picture.
And you should set more data in callback_data. For example showproduct_<id next product>
Related
I have a question about using editMessageReplyMarkup method in Telegram bot API in PHP.
I'm trying to provide user choose category and sub-category after with InlineKeyboardMarkup . But I want to make it with replacing one Keyboard with another.
I found method editMessageReplyMarkup which does exectly what I need , but for some reason it returns me false.
On the first screenshot you can see how bot sends me categories.
After I choose any of it next code is running:
if (is_array($update[count($update)-1]["callback_query"])) {
$chat_id = $update[count($update)-1]["callback_query"]["from"]["id"];
$requested_category = $update[count($update)-1]["callback_query"]['data'];
$message_answer_id = $update[count($update)-1]["callback_query"]['message']['message_id'];
send_sub_projects($user_model, $telegram, $chat_id, $requested_category, $message_answer_id);
}
Here is the method send_sub_projects
function send_sub_projects($user_model, $telegram, $chat_id, $category, $message_id) {
$subcategories = $user_model->get_sub_categories($category);
for ($i=0; $i < count($subcategories); $i++) {
$subcategories[$i] =
array(array('text'=>$subcategories[$i],'callback_data'=>$subcategories[$i]));
}
$decoded_subcategories = json_encode(array('inline_keyboard' => $subcategories));
$parameters =
array(
'chat_id' => $chat_id,
'message_id' => $message_id,
'reply_markup' => $decoded_subcategories
);
$telegram->editMessageReplyMarkup($parameters)
}
So basically I send everything which is requeired: message_id, chat_id, new_markup. And when I run that script I can see arrays are built fine, see the next screenshot:
And everything I got from this is false returning me from method I called, of coruse no changes in telegram bot message.
Does anyone have any ideas? Thank you for reply.
Long story short, I am using Fullcalendar with Codeigniter. I am color coding the events in the calendar depending on the category of the event.
In Admin dashboard admin can add event category and provide name and color (from select menu). Hex value gets saved to database.
When Admin adds an event, they add title, description, start, end and category.
Category option is a select menu from Event Categories, pulled from database.
When I add a new event, I want to use the event category name and grab its color and then store it with the event in the database in the last column like so:
Saving an Event:
I am using codeigniter form validation, and if all fields are validated I am trying to grab the color from the event category table and add it to the event in my $save_data array:
public function add_save()
{
$this->form_validation->set_rules('title', 'Title', 'trim|required|max_length[500]');
$this->form_validation->set_rules('start', 'Start', 'trim|required');
$this->form_validation->set_rules('end', 'End', 'trim|required');
$this->form_validation->set_rules('description', 'Description', 'trim|required|max_length[1000]');
$this->form_validation->set_rules('category', 'Category', 'trim|required|max_length[100]');
$this->form_validation->set_rules('has_attendance', 'Has Attendance', 'trim|max_length[1]');
$this->form_validation->set_rules('is_recurring', 'Is Recurring', 'trim|required|max_length[1]');
if ($this->form_validation->run()) {
// I am adding this to capture color from event_category table
// 1. use the input category field from event
// 2. then I select all from event_category table
// 3. WHERE name is equal to the selected category name from input
// 4. The color is the reulting rows color field
$selected_event_category = $this->input->post('category');
$this->db->get('event_category');
$this->db->where('name',$selected_event_category);
$the_color = $this->db->get()->result()->row('color');
$save_data = [
'title' => $this->input->post('title'),
'start' => $this->input->post('start'),
'end' => $this->input->post('end'),
'description' => $this->input->post('description'),
'category' => $this->input->post('category'),
'has_attendance' => $this->input->post('has_attendance'),
'is_recurring' => $this->input->post('is_recurring'),
'color' => $the_color //I have added this from above query
];
$save_events = $this->model_events->store($save_data);
} else {
$this->data['success'] = false;
$this->data['message'] = validation_errors();
}
echo json_encode($this->data);
}
I have tried to do the query and store the result in a variable called $the_color. I am then using this variable in my $save_data array as the color value.
But the form will not post and I am not getting any errors. The event will not save, it does not go into the database at all.
I am hoping someone could possibly help point out where I am going wrong?
How about this? I think you can use the row() method if you expect a single record from the database. Moreover, when you store data, you don't have to assign it to a variable.
Method in model file:
public function getEventCategory($selected_event_category) {
$this->db->where('name', $selected_event_category);
$q = $this->db->get('event_category');
$q = $q->row();
return $q;
}
And then in controller
if ($this->form_validation->run()) {
// I am adding this to capture color from event_category table
// 1. use the input category field from event
// 2. then I select all from event_category table
// 3. WHERE name is equal to the selected category name from input
// 4. The color is the reulting rows color field
$selected_event_category = $this->input->post('category');
$event_category = $this->Your_model_here->getEventCategory($selected_event_categor);
$the_color = $event_category->color;
$save_data = [
'title' => $this->input->post('title'),
'start' => $this->input->post('start'),
'end' => $this->input->post('end'),
'description' => $this->input->post('description'),
'category' => $this->input->post('category'),
'has_attendance' => $this->input->post('has_attendance'),
'is_recurring' => $this->input->post('is_recurring'),
'color' => $the_color //I have added this from above query
];
$this->model_events->store($save_data);
} else {
$this->data['success'] = false;
$this->data['message'] = validation_errors();
}
echo json_encode($this->data);
}
Another issue is you should pass your query to model. Codeigniter is base on the MVC model, so we should avoid using queries in the controller.
I am trying to add callback data to reply_markup.
This is my code:
$option[] = array("test");
$replyMarkup = array('keyboard'=>$option,'one_time_keyboard'=>false,'resize_keyboard'=>true,'selective'=>true);
$encodedMarkup = json_encode($replyMarkup,true);
This code sends TEST to button and a call back to server TEST string for case
But I want use TEST string to show user and call back to server by KEY
This code does not work for me:
$option[] = array("text"=>"test","call_back"=>"key");
It looks you try to use ReplyKeyboardMarkup. It defines a keyboard with templates of messages which an user can send by tapping on a button.
But you want to get specific key so take a look at InlineKeyboardMarkup for this.
$options[][] = array('text' => 'Your text', 'callback_data' => 'test-data');
$replyMarkup = array('inline_keyboard' => $options);
$encodedMarkup = json_encode($replyMarkup, true);
When an user presses the button, your bot will receive a special update, CallbackQuery.
I have following code:
return array(
ULogt::UPDATE => '
<div>
Navigate
</div>
'
This code locates in the class called links.php.
I need to navigate to ('viewform', array('model'=>$this->loadJson($id)), when the user presses Navigate button. I do not know how to insert this code instead of #link. How can I do it?
CHtml::link(
"Navigate",
"javascript:void(0);", // link for destination or you can handle same with jQuery
array(
'id' => 'navigation-id', // id for handeling in jQuery
'key' => $data, // Required data will be appeared as attributes for this link
)
);
You can create link like
Yii::app()->createUrl(
'/profile/membership/view', // your link
array(
'id'=> 1 // data to be sent
)
)
Check for URL formating
I have a system that is outputting a number of images, with a A link next to them to set them as the album cover.
I have multiple albums, and in my database have a field called "is_feature" that is set to 1 if the image is the cover, and 0 if it isnt.
I don't know the best way of selecting the image, i originally outputted something like below;
Set
(image_id is the images id obviously), this function would call the model and set all other photos "is_feature" field to 0, and this photos "is_feature" to 1.
The problem is it is wiping all the other album features as well. I almost need to pass to variables in the A link, the first being the id of the image, the second being the id of the album, then my model function can only set "is_feature" to 0 where album_id = the id of the album passed.
Is there anyway to pass two variables like this? Or am i going about this in totally the wrong way?
You can set the values in the URL as query parameters
<a href="/admin/set_photo?var1=<?= $image_id;?>&var2=<?= $size;?>"
title="Set this photo as the feature photo"> Set </a>
Which you can retrieve in the controller
$image_id = $this->input->get('var1');
$image_size = $this->input->get('var2');
Uh what? You can pass whatever you need.
$data = array(
'title' => 'My Title',
'heading' => 'My Heading',
'message' => 'My Message'
);
$this->load->view('blogview', $data);
Depending upon data type as string or as array, there are 3 ways of passing data (You can use any of them explained below, BASED upon YOUR REQUIREMENT):
Through View
//For data you collected through POST method from FORM, collect them as array
$data=array(
'employee_name' => $this->input->post('emp_name'),
'employee_email' => $this->input->post('emp_email'),
'employee_password' => $this->input->post('emp_password')
);
$this->load-> view(''mynextpage", $data)
Through Controller
redirect('controller_name/index'.$valueofcustomer);
OR
redirect(base_url()."controller_name/index/".$valueofcustomer);
//then in your 'view', you can access value of customer like this:
$v_o_c = $this->uri->segment(3);
echo "your value is " .$v_o_c;
Through Session
$data = array(
'user_name' => $user_name,
'is_logged_in' => true
);
$this->session->set_userdata($data); //set the session
redirect('another_controller/index');
//then access those in another_controller like this:
$in = $this->session->set_userdata('$data');
Note: Session data will available only for redirect and lost on next page request