Problem in duplication after clicking submit button multiple times - php

My main problem is with that code in which when I click on submit buttons many times, it inserts duplication many times in the database in which I need to avoid that. Please help me to solve this problem. These are the two tables in which I am trying to insert. mat_ans_options_choose and mat_answer.
$val = $this->input->post(null, true);
$val['id'] = $this->input->post('id');
$val['sub_type'] = $this->input->post('sub_type');
$val['timeout'] = $this->input->post('timeout');
$val['level'] = $this->input->post('level');
$val['mat_category'] = $this->input->post('mat_category');
$option = $val['option'] = $this->input->post('option');
$type = $this->input->post('type');
$marks = [];
$uid = $this->session->userdata('id');
if (isset($val['id']) && isset($option)) {
$query = $this->db->query("SELECT * FROM mat_ans_options WHERE deleted=0 AND active=1 AND question=" . $val['id']);
$result = $query->result_array();
if ($query->num_rows() > 0) {
$count1 = 1;
foreach ($result as $res) {
if ($res['marks'] == 1) {
break;
} else {
$count1++;
}
}
}
// MAT answers options choose
$query1 = $this->db->query("SELECT * FROM mat_ans_options_choose WHERE deleted=0 AND active=1 AND uid=$uid AND q=" . $val['id']);
$result1 = $query1->result_array();
if ($query1->num_rows() > 0) {} else {
$data1 = [
'uid' => $uid,
'q' => $val['id'],
'option_chose' => $option,
'createdon' => $this->general_model->server_time(),
];
$this->db->insert('mat_ans_options_choose', $data1);
}
if ($count1 == $option) {
$marks = 1;
} else {
$marks = 0;
}
// if($marks==1 || $marks==0)
// {
// MAT answers
$query2 = $this->db->query("SELECT * FROM mat_answers WHERE deleted=0 AND active=1 AND uid=$uid AND q=" . $val['id'] . " AND type=" . $type . " AND sub_type=" . $val['sub_type'] . " AND level=" . $val['level']);
$result2 = $query2->result_array();
if ($query2->num_rows() > 0) {} else {
$data = [
'uid' => $uid,
'q' => $val['id'],
'type' => $type,
'level' => $val['level'],
'sub_type' => $val['sub_type'],
'mat_category' => $val['mat_category'],
'marks' => $marks,
'timeoutstatus' => $val['timeout'],
'createdon' => $this->general_model->server_time(),
];
$this->db->insert('mat_answers', $data);
}
// }
return 1;
} else {
return 0;
}

Use JS in which you disable the button after first click - it will work no matter if you are using AJAX or not.

You can use JS/jQuery to limit the number of requests made on the client side. For example by disabling the button on submit:
$("#my-button").prop("disabled", true);
But if the data is sensitive for duplicates (orders, user registration etc) you should make the request limit server side with PHP. You can achieve this by adding a unique index to the tables, either on user id or on a unique token that is submitted with the html form.

Create UNIQUE index in database for uid and q. The database will not insert same question's id from same user's id mulitple times.

Related

PHP repeated results

I'm having hard time with this issue
I have multiple queries some data appear in other results...
$query = "SELECT * FROM `hotels`";
$result=mysqli_query($connect,$query);
if(mysqli_num_rows($result)>0) {
while($row=mysqli_fetch_array($result)) {
$hotelname = $row['hotel_name'];
$queryPhotos="SELECT * FROM hotel_photo WHERE hotel_id = ".$row['id']." ";
$resultPhotos=mysqli_query($connect,$queryPhotos);
while($rowPhotos=mysqli_fetch_assoc($resultPhotos)) {
$photos[] = array(
"imgUrl" => $rowPhotos['img_url'],
"hotel_id" => $rowPhotos['hotel_id']
);
}
$apiResult[] = array(
'hotel_name' => $hotelname,
'hotel_photos' => $photos,
);
}
header('Content-type: application/json');
echo json_encode($apiResult, JSON_NUMERIC_CHECK);
}
This is my hotel database
and my hotel_photos database
Why I'm still seeing 'hotel_id 1' in dubai hotel...?
Thank you so much for your help.
You aren't empting the $photos array in every new iteration for a new hotel. Hence, the previous results also exists in the array. You need to fix as below:
<?php
while($row = mysqli_fetch_array($result)) {
$hotelname = $row['hotel_name'];
$photos = []; // add this line

Implementing a function from another one

this is my first post and im really new to php world, Sorry if i use wrong words or terms to describe my problem.
I have a script that was written in php for telegram, and i have two commands that is almost the same.
with this one it is possible to add to multiple groups using this separator ","
/madd
groupid, groupid
this one it is not possible to do
/wadd
groupid
I want to be able to use the second command with a separator between the group ids
I can see in the code how it is written to be able to do that in /madd but I cant figure out how to implement this in /wadd
I will put here the two scripts for the commands, would appreciate any help <3
Thanks.
This is the one with the separator
if(strpos($text,"/madd") === 0){
$e = explode("\n",$text);
if(!isset($e[1]) || !isset($e[2])) exit($bot->sendMessage($user['id'],"/madd\ntelegram_username or ID\ngroup, ids\nmax_posts per day (default 1)\nnumber of reposts (default 0)\n\nAdds new telegram username to the manual autodrop users list.\n\nReplace group_id with * to add to all groups"));
$group = $e[2]; $username = strtolower(ltrim($e[1],"#"));
$addto = [];
if($group == "*"){
$addto = $groups;
}else{
$ex = explode(",",$group);
foreach($ex AS $id){
$id = trim($id);
if(isset($groups[$id])){
$addto[$id] = $groups[$id];
}
}
}
$add = mysqli_fetch_assoc($conn->query("SELECT * FROM utenti WHERE username LIKE '%".mysqli_real_escape_string($conn,$username)."%'"));
if(!isset($add['id'])){
$add = mysqli_fetch_assoc($conn->query("SELECT * FROM utenti WHERE id = ".mysqli_real_escape_string($conn,$username)));
}
if(!isset($add['id'])){ exit($bot->sendMessage($user['id'],"šŸ˜” User $username not found! They need to start the bot, or send a simple message in one of the groups.")); }
$result = "ā• <b>Selected User:</b> <a href='tg://user?id=".$add['id']."'>".$add['username']." (".$add['id'].")</a>";
$manual = [
'max_posts' => $e[3] ?? 1,
'reposts' => $e[4] ?? 0,
'groups' => []
];
foreach($addto AS $id => $r){
$manual['groups'][] = $r['group_id'];
}
$conn->query("UPDATE utenti SET manual = '".mysqli_real_escape_string($conn,json_encode($manual,true))."' WHERE id = ".$add['id']);
$bot->sendMessage($user['id'],$result."\n\n".json_encode($manual,JSON_PRETTY_PRINT));
exit();
}
and this is without the separator
if(strpos($text,"/wadd") === 0){
$e = explode("\n",$text);
if(!isset($e[1]) || !isset($e[2])) exit($bot->sendMessage($user['id'],"/wadd\ngroup_id\ntelegram_username or ID\nmax_posts per day (default 5)\nnumber of reposts (default 0)\n\nAdds new telegram username to the whitelisted users list.\n\nReplace group_id with * to add to all groups"));
$group = $e[1]; $username = strtolower(ltrim($e[2],"#"));
if($group != "*" && !isset($groups[$group])) exit($bot->sendMessage($user['id'],"šŸ‘„ <b>Group $group</b> not whitelisted."));
$add = mysqli_fetch_assoc($conn->query("SELECT * FROM utenti WHERE username LIKE '%".mysqli_real_escape_string($conn,$username)."%'"));
if(!isset($add['id'])){
$add = mysqli_fetch_assoc($conn->query("SELECT * FROM utenti WHERE id = ".mysqli_real_escape_string($conn,$username)));
}
if(!isset($add['id'])){ exit($bot->sendMessage($user['id'],"šŸ˜” User $username not found! They need to start the bot, or send a simple message in one of the groups.")); }
$result = "ā• <b>Selected User:</b> <a href='tg://user?id=".$add['id']."'>".$add['username']." (".$add['id'].")</a>";
$premiums = json_decode($add['premiums'],true);
if(!is_array($premiums)) $premiums = [];
$groups_to_update = []; if($group == "*"){ foreach($groups AS $group => $data){ $groups_to_update[] = $group; } }else{ $groups_to_update[] = "-".abs($group); }
$max_posts = $e[3] ?? 5; $reposts = $e[4] ?? 0;
foreach($groups_to_update AS $group_id){
if(isset($premiums[$group_id])){
if($premiums[$group_id]['max_posts'] == $max_posts && $premiums[$group_id]['reposts'] == $reposts){
$result.="\n\nšŸ• <i>No changes for group</i> <code>$group_id</code>";
}else{
$result.="\n\nā™»ļø <b>Updated</b> for group <code>$group_id</code>\nMax. Posts: $max_posts | Reposts: $reposts";
$premiums[$group_id] = ['max_posts' => $max_posts,'reposts' => $reposts];
}
}else{
$result.="\n\nāž• <b>Added</b> for group <code>$group_id</code>\nMax. Posts: $max_posts | Reposts: $reposts";
$premiums[$group_id] = ['max_posts' => $max_posts,'reposts' => $reposts];
}
}
$conn->query("UPDATE utenti SET premiums = '".mysqli_real_escape_string($conn,json_encode($premiums,true))."' WHERE id = ".$add['id']);
$bot->sendMessage($user['id'],$result);
exit();
}

Unique code generation using Last Insert Id in Code Igniter?

I need to create a drcode using the last insert id in the prescribed format,
previously I have used cor php to get the code but now in codeigniter am not able to get the code as the previous one. How can i do this? I am providing my controller and model
Controller
public function newdoctor_post() {
$employee_id = $this->post('EMPLOYEE_ID');
$doctorname = $this->post('DOCTOR_NAME');
$mobilenumber = $this->post('DRMOBILE');
$users_data = $this->Rest_user_model->doctor_exists($mobilenumber);
if ($users_data == 1) {
$message = ['status' => 2,
// 'result' => array(),
'message' => 'Doctor already registered'];
} else {
$speciality = $this->post('SPECIALITY');
$longitude = $this->post('LONGITUDE');
$latitude = $this->post('LATITUDE');
$drcode = $this->post('DRCODE');
$createdon = date('Y-m-d H:i:s');
$insert_array = array('EMPLOYEE_ID' => $employee_id, 'DOCTOR_NAME' => $doctorname, 'DRMOBILE' => $mobilenumber, 'SPECIALITY' => $speciality, 'LONGITUDE' => $longitude, 'LATITUDE' => $latitude, 'CREATEDON' => $createdon);
$users_data = $this->Rest_user_model->doctorregistration($insert_array);
$message = ['status' => 1, // 'result' => $users_data,
'message' => 'Doctor Registered Successfully'];
}
$this->set_response($message, REST_Controller::HTTP_OK);
}
Model
public function doctorregistration($data) {
if (!empty($data)) {
$this->db->insert('DOCTORDETAILS', $data);
return $this->db->insert_id();
}
return 0;
}
Code Generation
$sql1="SELECT DRCODE FROM DOCTORDETAILS ORDER BY DRCODEDESC LIMIT 1";
$query=mysql_query($sql1);
if (!$sql1) { // add this check.
die('Invalid query: ' . mysql_error());
}
$output_array2=array();
while($row=mysql_fetch_assoc($query))
{
$ids=$row['DRCODE'];
}
// echo $ids;
if($ids){
$su=1;
$num =$num = 'DR' . str_pad($su + substr($ids, 3), 6, '0', STR_PAD_LEFT);;
$unique=$num;
}else{
$unique='DR000001';
}
Try this - replace this code below with your Code Generation code.
$sql1="SELECT DRCODE FROM DOCTORDETAILS ORDER BY DRCODEDESC LIMIT 1";
$query=$this->db->query($sql1);
if (!$sql1) { // add this check.
die('Invalid query');
}
$output_array2=array();
foreach($query->result_array() as $row)
{
$ids=$row['DRCODE'];
}
// echo $ids;
if($ids){
$su=1;
$num =$num = 'DR' . str_pad($su + substr($ids, 3), 6, '0', STR_PAD_LEFT);;
$unique=$num;
}else{
$unique='DR000001';
}
You should make a different column fr drcode, leave it blank.
Now make a trigger on insert, it should be run after insert.
I am assuming DOCTORDETAILS as table name and drcode as column name
DELIMITER $$
CREATE TRIGGER trigger_after_insert
AFTER INSERT ON `DOCTORDETAILS` FOR EACH ROW
begin
UPDATE `DOCTORDETAILS` set drcode=CONCAT('DR',new.id);
END$$
DELIMITER ;
The trigger create a new string with your new auto generated id
Trigger in MySQL:
TechonTheNet
MySQL Trigger on after insert

Auto increment Invoice ID in Code-igniter

i am very new to code igniter /php .
Before i was using randomly generated invoice number like
$invoice_no = rand(9999,9999999999);
But now i wanted to increment invoice number and add current year as a prefix to it . But somewhere i am doing wrong as this code failed execute . Can some one point me in the right direction .
My model is ...
function insertInvoice($data)
{
$this->db->trans_begin();
$invoice = array();
if(!empty($data['client_id']))
{
$invoice['invoice_client_id'] = $data['client_id'];
}else{
$client_data = array(
'client_name' => $data['customername'],
'client_address1' => $data['address1']
);
$this->db->insert('client_details', $client_data);
$insert_id = $this->db->insert_id();
$invoice['invoice_client_id'] = $insert_id;
}
$query = $this->db->query("SELECT * FROM invoice ORDER BY invoice_id DESC LIMIT 1");
$result = $query->result_array(0);
$result ++;
$curYear = date('Y');
$invoice_no = $curYear . '-' .$result;
$invoice['invoice_no'] = $invoice_no;
$invoice['invoice_subtotal'] = $data['subTotal'];
$invoice['invoice_tax'] = $data['tax'];
$invoice['invoice_tax_amount'] = $data['taxAmount'];
$invoice['invoice_total'] = $data['totalAftertax'];
$invoice['invoice_total_extra'] = $data['totalextra'];
$invoice['invoice_rent'] = $data['rent'];
$invoice['invoice_paid'] = $data['amountPaid'];
$invoice['invoice_due'] = $data['amountDue'];
$invoice['invoice_desc'] = $data['notes'];
$invoice['invoice_items_count'] = $data['item_count'];
$invoice['invoice_extra_count'] = $data['extra_count'];
$invoice['invoice_miscellaneous'] = $data['miscellaneous'];
$this->db->insert('invoice', $invoice);
$i=1;
do {
$items = array(
'invoice_no' => $invoice_no,
'item_name' => $data['invoice']['product_name'][$i],
'item_price' => $data['invoice']['product_price'][$i],
'item_qty' => $data['invoice']['product_qty'][$i],
'item_total' => $data['invoice']['total'][$i],
'item_noof_crate_wait' => $data['invoice']['noof_crate_wait'][$i],
'item_crate_wait' => $data['invoice']['crate_wait'][$i],
'item_choot' => $data['invoice']['choot'][$i],
'item_net_quantity' => $data['invoice']['net_qty'][$i]
);
$this->db->insert('invoice_items',$items);
$i++;
} while($i<$data['item_count']);
$j=1;
do {
$extraitems = array(
'invoice_no' => $invoice_no,
'extra_item_name' => $data['extra']['name'][$j],
'extra_item_qunatity' => $data['extra']['qty'][$j],
'extra_item_price' => $data['extra']['price'][$j],
'extra_item_total' => $data['extra']['total'][$j]
);
$this->db->insert('extra_items',$extraitems);
$j++;
} while($j<$data['extra_count']);
if ($this->db->trans_status() === FALSE)
{
$this->db->trans_rollback();
return FALSE;
}
else
{
$this->db->trans_commit();
return TRUE;
}
}
invoice_id is primary key in DB .
You're attempting to increment the result array but what you really need is to acquire and increment a field value.
//you only need one field so ask only for that
$query = $this->db->query("SELECT invoice_id FROM invoice ORDER BY invoice_id DESC LIMIT 1");
//you really should check to make sure $query is set
// before trying to get a value from it.
//You can add that yourself
//Asked for only one row, so only retrieve one row -> and its contents
$result = $query->row()->invoice_id;
$result ++;
...
I'm guessing you're getting an "Object conversion to String error" on line $invoice_no = $curYear . '-' .$result;
Since $result contains an object and you're using it as a string. Print the $result variable to check how to use the data assigned to it.

Cakephp custom query pagination

I'm trying to use custom query in Cake then paginate the results with the code below:
$query = $this->Petition->query($sql);
I tried:
$petitions = $this->paginate($query);
and it doesn't work. Is there a way we can do this?
OK I wasn't clear enough: I need to use variable array fetched from custom query on pagination so I can use this for pagination in the view. Is there an easy way of doing this?
Below is my code:
function index() {
if ($this->Session->read('Auth.User.group_id') != 1) {
$commune_id = $this->Session->read('Auth.User.commune_id');
$commune_id = $this->Petition->Commune->findbyId($commune_id);
$commune_id = $this->Petition->Commune->find('all',array('conditions' => array('group' => $commune_id['Commune']['group'])));
$count = count($commune_id);
$i=1;
$sql = "SELECT * FROM `petitions` WHERE `commune_id` = ";
foreach($commune_id as $commune_ids){
if($i==1){
$sql .= $commune_ids['Commune']['id'];
}else{
$sql .= " OR `commune_id` = ".$commune_ids['Commune']['id'];
}
/*if($i != $count){
$this->paginate = array(
'or' => array(
array('Petition.commune_id LIKE' => $commune_ids['Commune']['id'] . ","),
//array('Petition.commune_id LIKE' => "," . $commune_ids['Commune']['id'] . ",")
),
'limit' => 10
);
}*/
$i++;
}
$query = $this->Petition->query($sql);
}
$this->Petition->recursive = 0;
$petitions = $this->paginate();
$this->set('petitions', $petitions);
}
you seriously need to read the pagination part in the cake book:
function index() {
$conditions = array();
if ($this->Auth->user('group_id') != 1) {
$commune_id = $this->Petition->Commune->findById($this->Auth->user('commune_id'));
$conditions['Petition.id'] = $this->Petition->Commune->find('list',array(
'fields'=>array('id','id')
'conditions' => array('group' => $commune_id['Commune']['group'])
));
}
$this->Petition->recursive = 0;
$petitions = $this->paginate('Petition',$conditions);
$this->set('petitions', $petitions);
}
something like that.
this is not how pagination works
you need to fill $this->validate with your conditions etc
and then use $this->paginate() plainly
see
http://book.cakephp.org/view/1232/Controller-Setup
also note the chapter about the custom query part if it is really(!) necessary.

Categories