Here is my output of print_r($_POST)
array([id] => '123', [name] => '', [place] => '', [color] => '')
Where name , place and color are optional fields submitted by user..... user may select only name, place or color, name + color, color + place, or all three name + color + place.
How can I put where condition for these options chosen by user? Let's say for example, In Laravel we select DB table using the following statement...
$Select_db = Db::table('mytable')
->where('name', Input::get('name'))
->where('place', Input::get('place'))
->where('color', Input::get('color'))
->select()
->get();
As you can see above condition works only if there is an input for all fields from user, based on user input I want add where condition, how do we fix this???
Note: In this particular scenario, I am aware I could use isset() for each condition. However, what if there are many optional inputs?
Try this:-
$Select_db = DB::table('mytable');
if (Input::get('name') != "")
$Select_db->where('name', Input::get('name'));
if (Input::get('place') != "")
$Select_db->where('place', Input::get('place'));
if (Input::get('color') != "")
$Select_db->where('color', Input::get('color'));
$result = $Select_db->get();
And if there are multiple columns to match, then try using this:-
$Select_db = DB::table('mytable');
foreach($_POST as $key => $val){
if(Input::get($key) != ""){
$Select_db->where($key, Input::get($key));
}
}
$Select_db->get();
what about
$Select_db = Db::table('mytable');
foreach($_POST as $key => $val) {
$Select_db->where($key, Input::get($key));
}
$Select_db->query()->get();
maybe consider to copy your $_POST and remove undesired values before you enter foreach:
unset($postcopy['badvar'])
public function filter(Request $request)
{
$first_name = $request->input('first_name');
$sur_name = $request->input('sur_name');
$email_work = $request->input('email_work');
$country = $request->input('country');
$position = $request->input('position');
$event_id = $request->input('event_id');
$event_name = $request->input('event_name');
$nature_of_business = $request->input('nature_of_business');
$mobile_number = $request->input('mobile_number');
$event_date = $request->input('event_date');
$record = DB::table('exceldatas');
if ($request->has('first_name')){
$record->where('first_name', $first_name);
}
if ($request->has('sur_name')) {
$record->where('sur_name', $sur_name);
}
if ($request->has('email_work')) {
$record->where('email_work', $email_work);
}
if ($request->has('country')) {
$record->where('country', $country);
}
if ($request->has('event_name')) {
$record->where('event_name', $event_name);
}
if ($request->has('nature_of_business')) {
$record->where('nature_of_business', $nature_of_business);
}
if ($request->has('mobile_number')) {
$record->where('mobile_number', $mobile_number);
}
if ($request->has('event_date')) {
$record->where('event_date', $event_date);
}
$record =$record->paginate(15);
return view('showresult')->with('record', $record);
}
Related
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.
i want to create a condition which a user would choose whether he wants to use an input which means a database would create an auto_incremented id or he wants to use an older data which will not use new id but only use it. i have used dropdown database populate for my old input.
My Dropdown list
//get contractor list
$Contractor_List = $this->foo_pro->get_list_contractors();
$opt = array('' => '');
foreach ($Contractor_List as $Contractor_No) {
$opt[$Contractor_No] = $Contractor_No;
}
$data['con_list'] = form_dropdown('',$opt,'','ProjectID = "Contractor_No" name="contractorNo" id="" class="w3-select w3-border w3-hover-light-grey"');
My Controller
public function save_createdProject()
{
$data_project = array();
$data_contractor = array();
//project data
if ($this->input->post('year') === '') {
$data_project['P_Year'] = 15;
}else{
$data_project['P_Year'] = $this->input->post('year');
}
if ($this->input->post('code') === '') {
$data_project['Code'] = 'KO';
}else{
$data_project['Code'] = $this->input->post('code');
}
$data_project['ProjectID'] = $this->input->post('project');
$data_project['Contract_Amount'] = $this->input->post('camount');
//contractor data
if ($this->input->post('cname') === '' && $this->input->post('caddress') === '') {
$data_project['Contractor_No'] = $this->input->post('contractorNo');
}else{
$data_contractor['Contractor_Name'] = $this->input->post('cname');
$data_contractor['Contractor_Address'] = $this->input->post('caddress');
}
$this->foo_pro->add_project($data_project, $data_contractor);
redirect('Main/project','refresh');
//var_dump($data);exit;
}
My Model
public function add_project($data_project, $data_contractor)
{
//contractor
$this->db->insert('contractor', $data_contractor);
$Contractor_No = $this->db->insert_id();
//project
$data_project['Contractor_No'] = $Contractor_No;
$this->db->insert('project', $data_project);
$ProjectID = $this->db->insert_id();
}
this here is my problem except inserting the older data which is the contractor_no 1 it creates another data that would insert as contractor_no 4.. but also i need to insert new data for new contractor_name..
Here i have a list of categories and user can add a new category as well as edit them.
Now at the edit time i'm using server-side validation by codeigniter for reduce redundancies . but the issue is the, whenever i edit an existing category then it can't update it because it compare with their original value, that is wrong. i trying to many time but unable to fix this issue.
Here is my code
public function category_upd()
{
extract($_POST);
$userId = $this->session->userdata('id');
$original_value = $this->db->query("SELECT cat_name FROM category WHERE user_id=".$userId." and cat_name ='".$_POST['cat_name']."'") ;
$original_value = $original_value->result_array();
$original_value = $original_value[0]['cat_name'];
$original_value2 = $this->db->query("SELECT cat_name FROM category WHERE user_id=".$userId." and cat_name ='".$_POST['cat_name']."'") ;
$original_value2 = $original_value2->result_array();
$original_value2 = $original_value2[0]['cat_name'];
if(ucwords($_POST['cat_name']) != $original_value) {
$this->session->set_flashdata('cat_failed','Category must be unique.');
$is_unique = '|is_unique[category.cat_name]';
} else if(ucwords($original_value2 == "")){
echo "go";
exit;
$this->session->set_flashdata('cat_failed','Category must be unique.');
$is_unique = '|is_unique[category.cat_name]';
} else {
$is_unique = '';
}
$this->form_validation->set_rules('cat_name','Category','trim|required'.$is_unique);
if($this->form_validation->run() ) {
A snap with error
I need your kind efforts. Thanks
Set validation Rules like this and you need to pass category id value
$this->form_validation->set_rules('cat_name', 'cat_name', 'required|trim|edit_unique[category.category_name.' . $_POST['category_id'].'.'.$_POST['user_id']. ']', array('edit_unique' => 'Category must be unique.'));
And developed one function edit_unique on Form_validation.php like this
Filepath system/libraries/Form_validation.php
public function edit_unique($str, $field)
{
sscanf($field, '%[^.].%[^.].%[^.].%[^.]', $table, $field,$id, $field2);
return isset($this->CI->db)
? ($this->CI->db->limit(1)->get_where($table, array($field => $str, 'id !=' => $id,'user_id'=>$field2))->num_rows() === 0)
: FALSE;
}
Check category name is alredy in database.
$newcategoryName=$this->input->post('category');
$query = $this->db->get_where('category', array('cat_name' => $newcategoryName,'user_id' => $userId));
$val=$query->result_array();
$original_value = $val[0]['cat_name'];
if($newcategoryName != $original_value) {
$is_unique = '|is_unique[users.EMAIL]';
} else {
$is_unique = '';
}
$this->form_validation->set_rules('cat_name', 'Category', 'required|trim|xss_clean'.$is_unique);
I want to query dynamically based on payload(json) from database.
Example:
$data = [{"key":"age","relation":">","value":"15"},{"operator":"OR"},{"key":"age","relation":"<=","value":"20"}]
I want to do query based on that payload.
Right now what I'm doing is:
$query = User::all();
$payload = json_decode($data, true);
foreach($payload as $value){
if ($value['key'] == 'age') {
$query = $query->where('birthday', $value['relation'], Carbon::now()->subYears($value['age'])->format('Y-m-d');)
}
if($value['key'] == 'gender'{
$query = $query->where('gender', $value['relation'], $value['gender']);
}
}
The problem is yes it can work, but I don't think this is best approach. I don't get any solution to use the "operator" key. Operator usage is to change where to orWhere.
Any solution or tips to make it call dynamically like this?. I want my column at DB neat and simple. I can only think this way.
Thanks!
Encountering this problem, I would go with Local Query Scopes. In this approach You create a model method named scopeJson() or whatever you feel better with to handl all conditions inside. I tried to handle most conditions here not only single where and orWhere. I assumed that your payload contains only one builder at a time.
public function scopeJson($query, $json)
{
$wheres = [
'between' => ['whereBetween', 'not' => 'whereNotBetween'],
'null' => ['whereNull', 'not' => 'whereNotNull'],
'or' => ['orWhere', 'not' => 'orWhereNot'],
'in' => ['whereIn', 'not' => 'whereNotIn'],
'and' => ['where', 'not' => 'orWhereNot'],
'raw' => 'whereRaw'
];
$builder = json_decode($json);
if (count($builder) > 0) {
$query->where(
$builder[0]->key,
$builder[0]->relation,
$builder[0]->value
);
// notBetween, notNull, notOr, notIn, notAnd
if (stripos($builder[1]->operator, 'not') !== false) {
$whereCondition = $wheres[strtolower(substr($builder[1]->operator, 3))]['not'];
} else {
$whereCondition = $wheres[strtolower($builder[1]->operator)];
}
if (count($builder[2]) == 3) {
if ($whereCondition == 'whereRaw') {
$query->$whereCondition(implode(" ", $builder[2]));
} else {
// where, whereNot
$query->$whereCondition(
$builder[2]->key,
$builder[2]->relation,
$builder[2]->value
);
}
} elseif (count($builder[2]) == 2) {
// whereBetween, whereNotBetween, where, whereNot
$query->$whereCondition(
$builder[2]->key,
$builder[2]->value
);
} elseif (count($builder[2]) == 1) {
// whereNull, whereNotNull, whereRaw
$query->$whereCondition(
$builder[2]->key ?? $builder[2]->value // PHP 7.0 Null Coalescing Operator
);
}
}
return $query;
}
If this method is defined within your User's model then you can use it this way:
$users = User::json($data)->get();
PS: Although it should work, I didn't test it.
You can do raw query like this.
$data = '[{"key":"age","relation":">","value":"15"},{"operator":"OR"},{"key":"age","relation":"<=","value":"20"}]';
$query = "SELECT * FROM tablename WHERE";
$payload = json_decode($data, true);
foreach ($payload as $value) {
if (isset($value['operator'])) {
$query .= " " . $value['operator'];
} else {
if ($value['key'] == 'age') {
$query .= " 'birthday' " . $value['relation'] . " " . Carbon::now()->subYears($value['value'])->format('Y-m-d');
}
if ($value['key'] == 'gender') {
$query .= " 'gender' " . $value['relation'] . " " . $value['gender'];
}
}
}
This results in a query like this :
SELECT * FROM tablename WHERE 'birthday' > 2001-07-02 OR 'birthday' <= 1996-07-02
Of course, you might use printf() for formatting and making this cleaner in some other way but this will get you started hopefully.
You can use a variable function name to add your orWhere logic:
$query = User::all();
$payload = json_decode($data, true);
$function = 'where';
foreach($payload as $value){
if(isset($value['operator'])){
$function = $value['operator'] == 'OR' ? 'orWhere' : 'where';
} else {
if ($value['key'] == 'age') {
$query = $query->$function('birthday', $value['relation'], Carbon::now()->subYears($value['age'])->format('Y-m-d');)
} else {
$query = $query->$function($value['key'], $value['relation'], $value['value']);
}
}
}
As long as your json data doesn't match your database (ie. the json has age but the database has birthday) you will not be able to avoid having that if/else statement. That custom logic will have to remain.
Ultimately this idea is its own limiter because the stored queries will have to represent the current state of the database. This means that the maintenance cost of these queries will be significant the moment data is stored in a different way -- if you changed the column birthday to date_of birth all of your stored queries will break. Avoid this.
Instead this goal is better achieved by storing the queries on the Model using Query Scopes and Relationships. If you still need a dynamic list of requests you can store keywords that are associated with the queries and loop through them.
I am struggling to workout a good method to update one column of my wcx_options table.
The new data is sent fine to the controller but my function isn't working at all.
I assumed i could loop through each column by option_id updating with the values from the array.
The database:
I update the option_value column with the new information via a jQuery AJAX Call to a controller which then calls a function from the backend class.
So far i have the following code:
if(isset($_POST['selector'])) {
if($_POST['selector'] == 'general') {
if($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest' && isset($_POST['token'])
&& $_POST['token'] === $_SESSION['token']){
$site_name = $_POST['sitename'];
$site_url = $_POST['siteurl'];
$site_logo = $_POST['sitelogo'];
$site_tagline = $_POST['sitetagline'];
$site_description = $_POST['sitedescription'];
$site_admin = $_POST['siteadmin'];
$admin_email = $_POST['adminemail'];
$contact_info = $_POST['contactinfo'];
$site_disclaimer = $_POST['sitedisclaimer'];
$TimeZone = $_POST['TimeZone'];
$options = array($site_name, $site_url, $site_logo, $site_tagline, $site_description, $site_admin, $admin_email,$contact_info, $site_disclaimer, $TimeZone);
// Send the new data as an array to the update function
$backend->updateGeneralSettings($options);
}
else {
$_SESSION['status'] = '<div class="error">There was a Problem Updating the General Settings</div>';
}
}
}
This is what i have so far in terms of a function (It doesnt work):
public function updateGeneralSettings($options) {
$i = 1;
foreach($options as $option_value) {
$where = array('option_id' => $i);
$this->queryIt("UPDATE wcx_options SET option_value='$option_value' WHERE option_id='$where'");
$i++;
}
if($this->execute()) {
$_SESSION['success'] = 'Updated General Settings Successfully';
}
}
With the given DB-layout i'd suggest to organize your data as assiciative array using the db fieldnames, like:
$option = array(
'site_name' => $_POST['sitename'],
'site_url' => $_POST['siteurl'],
// etc.
'timeZone' => $_POST['TimeZone']
);
And than use the keys in your query:
public function updateGeneralSettings($options) {
foreach($options as $key => $value) {
$this->queryIt("UPDATE wcx_options SET option_value='$value' WHERE option_name='$key'");
if($this->execute()) {
$_SESSION['success'] = 'Updated General Settings Successfully';
}
}
}
(However, are you sure, you do not want to have all options together in one row?)
Change your query, you try to use an array as where condition. In the syntax you used that won't work. Just use the counter as where condition instead of define a $where variable. Try this:
public function updateGeneralSettings($options) {
$i = 1;
foreach($options as $option_value) {
$this->queryIt("UPDATE wcx_options SET option_value='$option_value' WHERE option_id='$i'");
$i++;
}
if($this->execute()) {
$_SESSION['success'] = 'Updated General Settings Successfully';
}
}