Join 3 tables codeigniter php - php

I have 3 tables guest_user_info,pg_company,user_profile.
In guest_user_info have 2 columns:
g_uid | company_id
In pg_company have 2 columns:
company_id | user_id
In user_profile have 2 columns:
id |user_email
Here i want to get user_email from user_profile.i have g_uid value (in guest_user_info table).i want company_id from guest_user_info and get the company_id and match with pg_company table,there i can get user_id.then match with that user_id with id in user_profile table.at last i need user_email from user_profile table

Well its a simple one, you just need to join using active query in CodeIgniter.
$this->db->select("UP.id", "UP.user_email");
$this->db->from("guest_user_info AS GU");
$this->db->join("pg_company AS PC", "PC.company_id=GU.company_id");
$this->db->join("user_profile AS UP", "UP.id=PC.user_id");
$this->db->where("GU.g_uid", $guid);
$query = $this->db->get();
return $query->result();
In above code, $guid you have to provide which you have.
Also please take a look at these links:
https://www.codeigniter.com/userguide3/database/query_builder.html
https://www.codeigniter.com/userguide2/database/active_record.html
You get so many things after reading this.

Check bellow code it`s working fine and common model function also
supported more then one join and also supported multiple where condition
order by ,limit.it`s EASY TO USE and REMOVE CODE REDUNDANCY.
================================================================
*Album.php
//put bellow code in your controller
=================================================================
$album_id='';//album id
//pass join table value in bellow format
$join_str[0]['table'] = 'pg_company';
$join_str[0]['join_table_id'] = 'pg_company.company_id';
$join_str[0]['from_table_id'] = 'guest_user_info.company_id';
$join_str[0]['join_type'] = '';//set join type
$join_str[1]['table'] = 'user_profile';
$join_str[1]['join_table_id'] = 'user_profile.id';
$join_str[1]['from_table_id'] = 'guest_user_info.user_id';
$join_str[1]['join_type'] = '';
$selected ="guest_user_info.*,user_profile.user_name,pg_company.name";
$condition_array=array('guest_user_info.g_uid' => $g_uid);
$albumData= $this->common->select_data_by_condition('guest_user_info', $condition _array, $selected, '', '', '', '', $join_str);
//call common model function
if (!empty($albumData)) {
print_r($albumData); // print album data
}
=========================================================================
Common.php
//put bellow code in your common model file
========================================================================
function select_data_by_condition($tablename, $condition_array = array(), $data = '*', $sortby = '', $orderby = '', $limit = '', $offset = '', $join_str = array()) {
$this->db->select($data);
//if join_str array is not empty then implement the join query
if (!empty($join_str)) {
foreach ($join_str as $join) {
if ($join['join_type'] == '') {
$this->db->join($join['table'], $join['join_table_id'] . '=' . $join['from_table_id']);
} else {
$this->db->join($join['table'], $join['join_table_id'] . '=' . $join['from_table_id'], $join['join_type']);
}
}
}
//condition array pass to where condition
$this->db->where($condition_array);
//Setting Limit for Paging
if ($limit != '' && $offset == 0) {
$this->db->limit($limit);
} else if ($limit != '' && $offset != 0) {
$this->db->limit($limit, $offset);
}
//order by query
if ($sortby != '' && $orderby != '') {
$this->db->order_by($sortby, $orderby);
}
$query = $this->db->get($tablename);
//if limit is empty then returns total count
if ($limit == '') {
$query->num_rows();
}
//if limit is not empty then return result array
return $query->result_array();
}

Related

Ambiguous column in Codeigniter Datatables server side

I'm working on a system that has several server-side datatables but i facing issues with 2 joins when i try to order de columns.
I receive the following message when try to sort the columns:
Query error: Column 'notes' in order clause is ambiguous - Invalid query: SELECT *
FROM `tbl_project`
LEFT JOIN `tbl_client` ON `tbl_project`.`client_id`=`tbl_client`.`client_id`
LEFT JOIN `tbl_account_details` ON `tbl_project`.`created_by` = `tbl_account_details`.`user_id`
LEFT JOIN `tbl_notes` ON `tbl_project`.`notes` = `tbl_notes`.`notes_id`
WHERE `tbl_project`.`client_id` = '100'
ORDER BY `notes` DESC
LIMIT 10
This is the code with my query:
$id = $this->input->post("client_id");
$client_details = get_row('tbl_client', array('client_id' => $id));
$draw = intval($this->input->post("draw"));
$start = intval($this->input->post("start"));
$length = intval($this->input->post("length"));
$order = $this->input->post("order");
$search= $this->input->post("search");
$search = $search['value'];
$col = 0;
$dir = "";
if(!empty($order))
{
foreach($order as $o)
{
$col = $o['column'];
$dir= $o['dir'];
}
}
if($dir != "desc" && $dir != "desc")
{
$dir = "desc";
}
$valid_columns = array(
0=>'project_id',
1=>'client',
2=>'fullname',
3=>'notes',
4=>'origen',
5=>'end_date',
6=>'project_status',
7=>'action',
);
if(!isset($valid_columns[$col]))
{
$order = null;
}
else
{
$order = $valid_columns[$col];
}
if($order !=null)
{
$this->db->order_by($order, $dir);
}
$searchQuery = "";
if($search != ''){
$searchQuery = " (tbl_project.project_id like'%".$search."%' OR tbl_project.end_date like'%".$search."%' OR tbl_project.project_status like'%".$search."%' OR tbl_notes.notes like'%".$search."%' OR tbl_notes.eco like'%".$search."%' OR tbl_account_details.origen like'%".$search."%' OR tbl_client.name like'%".$search."%') ";
}
$this->db->select('*');
$this->db->from('tbl_project');
$this->db->join('tbl_client', 'tbl_project.client_id=tbl_client.client_id','left');
$this->db->join('tbl_account_details', 'tbl_project.created_by = tbl_account_details.user_id','left');
$this->db->join('tbl_notes', 'tbl_project.notes = tbl_notes.notes_id','left');
$this->db->where('tbl_project.client_id', $client_details->client_id);
if($searchQuery != '')
$this->db->where($searchQuery);
$this->db->limit($length,$start);
$cita = $this->db->get()->result();
For some reason the ORDER BY is not set as tbl_notes.notes
Any suggestion on how to fix this?
Thanks in advance
EDIT: i have added more code so there is more visibility of the process
The error occurs, because your column name is not unique, it exists in more than one table.
append the table name of the searched column to your query to make it unique:
for example in this line:
$this->db->order_by('my_table_name.'.$order, $dir);
that would generate something like
ORDER BY `my_table_name.notes` DESC
edit: or in case you have to address columns from several different tables you could change your $valid_columns array:
$valid_columns = array(
0=>'my_table_name1.project_id',
1=>'my_table_name2.client',
2=>'my_table_name2.fullname',
3=>'my_table_name3.notes',
// etc.
);
and maintain the remaining original code.

Unable to change value at edit time with codeIgniter validation

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);

sort varchar column codeigniter

i first checked if there any same problems like mine i ddnt find anything.
all are sorting alphanumeric column mixed with numeric data.
here is my problem.
i have a table that contain column A datas like this.
WRG-01 WRG-39 WRG-22 WRG-45 WRG-43
need to sort that as
WRG-01 WRG-22 WRG-39 WRG-43 WRG-45
this is the code i using so far in codeigniter frame work
$data['products'] = $this->db->order_by('product_id', 'asc')->get('products');
in mysql i can use this query to get done my work
preg_replace("/[^\d]/", "",'product_id'), 'asc')
How to apply it to my above codeigniter code?
here is search funtion
public function search()
{
$data['title'] = 'Search Product';
$product_name = $this->input->get('product_name');
$product_id = $this->input->get('product_id');
$product_category = $this->input->get('product_category');
$secondCategory = $this->input->get('secondCategory');
$thirdCategory = $this->input->get('thirdCategory');
$data['category'] = $this->db->order_by('id', 'asc')->get_where('categories', ['parent' => 0]);
if($product_category != '')
{
$data['secondCategory'] = $this->db->get_where('categories', ['parent' => $product_category]);
}
if($secondCategory != '')
{
$data['thirdCategory'] = $this->db->get_where('categories', ['parent' => $secondCategory]);
}
if($product_name != '')
{
$this->db->like('product_name', $product_name);
}
if($product_id != '')
{
$this->db->where('product_id', $product_id);
}
if($product_category != '')
{
$this->db->where('product_category', $product_category);
}
if($secondCategory != '')
{
$this->db->where('secondCategory', $secondCategory);
}
if($thirdCategory != '')
{
$this->db->where('thirdCategory', $thirdCategory);
}
$data['products'] = $this->db->order_by('product_id' 'asc')->get('products');
theme('all_product', $data);
}
i can't use sql query here because products is result array from product table.
Use MySQL cast
cast(product_id as SIGNED)
or
cast(product_id as UNSIGNED)
Try query like that :-
select * from products cast(product_id as UNSIGNED) ASC|DESC
Try this
$query= $this->db->query("SELECT * FROM products WHERE ??==?? ORDER BY product_id ASC");
$result= $query->result_array();
return $result;
as default data will sort by Ascending Order
This is in model. So if you pass it to controller it will return data as Objective Array.
So in controller you can access
$result = $this->model_name->method_for_above_code();
$name = $result[0]['name'];
$id = $result[0]['id'];
if in View
$result['this_for_view'] = $this->model_name->method_for_above_code();
foreach ($this_for_view as $new_item) {
echo "Name is ".$new_item['name'];
echo "ID is ".$new_item['id'];
}

Making simple allowed array in PHP? (CodeIgniter)

I have some simple function to collect allowed array, but something is not ok, can somebody help me? Here is my code
public function getAllbyLink($table, $what, $url)
{
$link=mysql_real_escape_string($url);
$query = $this->db->query("SELECT * FROM ".$table." WHERE ".$what." = '{$link}' LIMIT 0 , 1");
if ($query->num_rows() > 0)
{
return $query->result();
}
else redirect('');
}
Please read something about MVC pattern, question is clearly pointed on how to write a Model.
consider using this function
public function getTable($table, $where = array(), $select = '*', $order_by = '', $limit = '', $offset = '') {
if ($order_by !== '' && $order_by != 'RANDOM') $this->db->order_by($order_by);
if ($order_by == 'RANDOM') $this->db->order_by('id', 'RANDOM');
if ($limit !== '') $this->db->limit($limit, $offset);
$this->db->select($select);
$q = $this->db->get_where($table, $where);
return ($q->num_rows() > 0) ? $q->result() : FALSE;
}
for your purpose call the function like this:
getTable($talbe, array('what' => $link));
//returns FALSE if no data are selected,
//or returns object with data,
if you wish return array instead replace $q->result() with $q->array_result()
Please note that active record auto escapes.
After comments:
comment-1, you can simplify that function easily just delete what you do not need, for example
public function getTable2($table, $where = array(), $limit = '', $offset = '') {
if ($limit !== '') $this->db->limit($limit, $offset);
$q = $this->db->get_where($table, $where);
return ($q->num_rows() > 0) ? $q->result() : FALSE;
}
comment-2,when there is no data use this if-else statement
if (!$my_data = getTable2('table', array('where' => $link))) {
//there is some DATA to work with
echo "<pre>";
var_dump($my_data);
echo "</pre>";
} else {
//no DATA do redirect or tell user that there is no DATA
redirect(); //redirect to default_controller
}
comment-3, no comment;
comment-4, It also allows for safer queries, since the values are escaped automatically by the system. from this source. And another SO question about active record providing exact answer you are seeking.
My understanding of your code is:
Read all rows from table
Check if linkurl is in the list
If so, return a random row for that value
Else, redirect.
In this case, try this:
public function getAllbyLink($table,$url,$what)
{
$query = $this->db->query("
SELECT *
FROM `".$table."`
WHERE `".$what."` = '".mysql_real_escape_string($linkurl)."'
ORDER BY RAND()
LIMIT 1
");
if( !$query) return redirect('');
$result = $query->result();
if( !$result) return redirect('');
return $result;
}

MySQL Search from Multiple User supplied where clause - Fix and Better Algorithm

I want to run search query where i have multiple where clause. and multiple depends upon the user argument.
for example i mean, Search may depend on 1 column, 2 column, 3 column or 6 column in my case, and i don't want to run if-elseif-else statement with all column probability. So, i have just built up below function, but i am stuck with and that comes in between multiple column search case. Below is my code :-
function listPlayer($player="player_guest", $group="group_guest",
$weapon="weapon_guest", $point="point_guest", $power="level_guest",
$status="status_guest") {
$lePlayer = (isset($player) && $player != "player_guest") ?
'player= '.$mysqli->real_escape_string($player).' and' : '';
$leGroup = (isset($group) && $group != "group_guest") ?
'group= '.$mysqli->real_escape_string($group).' and' : '';
$leWeapon = (isset($weapon) && $weapon != "weapon_guest") ?
'weapon= '.$mysqli->real_escape_string($weapon).' and' : '';
$lePoint = (isset($point) && $point != "point_guest") ?
'point= '.$mysqli->real_escape_string($point).' and' : '';
$lePower = (isset($power) && $power != "level_guest") ?
'level= '.$mysqli->real_escape_string($power).' and' : '';
$leStatus = (isset($status) && $status != "status_guest") ?
'status= '.$mysqli->real_escape_string($status).' and' : '';
$query = "Select pid, name from game where {$lePlayer} {$leGroup} {$leWeapon} {$lePoint} {$lePower} {$leStatus} ";
$runQuery = $mysqli->query($query);
}
but problem is and at the end. If i use them, than i have extra and at the end, and if i don't use them that's again an error.
Can some one help me to fix and find better way to do it.
Update: My Update Code that works if some one needs them Thanks to Barmar
function listPlayer($player="player_guest", $group="group_guest",
$weapon="weapon_guest", $point="point_guest", $power="level_guest",
$status="status_guest") {
$lePlayer = (isset($player) && $player != "player_guest") ?
'player= '.$mysqli->real_escape_string($player) : '' ;
$leGroup = (isset($group) && $group != "group_guest") ?
'group= '.$mysqli->real_escape_string($group) : '' ;
$leWeapon = (isset($weapon) && $weapon != "weapon_guest") ?
'weapon= '.$mysqli->real_escape_string($weapon) : '' ;
$lePoint = (isset($point) && $point != "point_guest") ?
'point= '.$mysqli->real_escape_string($point) : '' ;
$lePower = (isset($power) && $power != "level_guest") ?
'level= '.$mysqli->real_escape_string($power) : '' ;
$leStatus = (isset($status) && $status != "status_guest") ?
'status= '.$mysqli->real_escape_string($status) : '' ;
$condition_array = ( $lePlayer , $leGroup , $leWeapon , $lePoint , $lePower , $leStatus)
$condition_stirng = implode(' and ', $condition_array);
$query = "Select pid, name from game where ".$condition_stirng;
$runQuery = $mysqli->query($query);
}
Update:
I got mail from someone at my email which says my code is vulnerable to SQL Injection. Here it is POC http://www.worldofhacker.com/2013/09/interesting-sql-vulnerable-code-even.html
Thanks
Put all the conditions in an array. Then combine them with:
$condition_string = implode(' and ', $condition_array);
The simple solution is to trim the "and" off at the end:
$query = substr($query, 0, strlen($query) - 3);
however a more efficient way would be to put them in a loop, like this:
$wheres = array("player_guest"=>$player, "group_guest"=>$group.....);
$query_where = "";
$i = 0;
foreach($wheres as $where=>$value){
list($condition, $null) = explode("_",$where);
if(isset($value)){
$query_where .= $condition . "='" . $mysqli->real_escape_string($value)."'";
if($i != sizeof($wheres)){
$query_where .= " and ";
}
}
$i++;
}
This is extendable for any number of conditions, and doesnt require the extra string function at the end.
Notice the $defaults is needed to make sure your conditions work. A bit repetitive, but it's all due to your function declaration.
function listPlayer(
$player="player_guest",
$group="group_guest",
$weapon="weapon_guest",
$point="point_guest",
$power="level_guest",
$status="status_guest") {
//I'm just copying whatever is in the default parameters ;)
$defaults = array(
'player' => 'player_guest',
'group' => 'group_guest',
'weapon' => 'weapon_guest',
'point' => 'point_guest',
'power' => 'level_guest',
'status' => 'status_guest'
);
//Set all user parameters into an array, easier to loop through
$data = compact(array_flip($defaults));
//Then we build conditions
$conditions = array();
foreach($data as $k => $v) {
if ($defaults[k] !== $v) {
$v = $mysqli->real_escape_string($v);
$conditions[] = "$k='$v'";
}
}
//And build query
$query = "SELECT pid, name FROM game WHERE ".implode(" AND ", $conditions);
$runQuery = $mysqli->query($query);
}
First of all I recommend you to look at PDO when you work with MySQL in PHP.
Such tasks are always simply solved with array maps.
function listPlayer($player = null, $group = null, $weapon = null, $point = null, $power = null, $status = null) {
$defaults = array(
'player' => 'player_guest',
'group' => 'group_guest',
'weapon' => 'weapon_guest',
'point' => 'point_guest',
'status' => 'status_guest',
);
$values = compact(array_keys($defaults));
$filtered = array_filter(array_diff_assoc($values, $defaults)); //firstly filtering out defaults, then - nulls.
$where = '';
foreach($filtered as $column => $value){
if($where){
$where .= ' AND ';
}
$where .= sprintf("`%s` = '%s'", $column, $mysqli->real_escape_string($value));
}
$query = "SELECT pid, name FROM game WHERE $where";
//executing...
}

Categories