Codeigniter 2.1 - counting the array before get - php

I have this function:
function gi_get_by($col,$id, $itd, $tbl, $limit = 10)
{
$this->db->select('*');
$this->db->from('global_info');
$this->db->join($tbl, 'id_' . $tbl . ' = id_global_info');
$this->db->where('info_type_id', $itd);
if($col == 'date_created' || $col == 'tag') {$this->db->like($col, $id);}
else {$this->db->where($col, $id);}
if($tbl == 'ad') :
$this->db->order_by('paid', 'desc');
endif;
$this->db->order_by('date_created', 'desc');
$this->db->limit($limit, $this->uri->segment(2));
$q = $this->db->get();
return $q = $q->result_array();
}
What I need is to count number of results before limit and to use them later in controller. I have an idea to duplicate this function without $limit but then it will be duplicating the same function. Is there another way to do this or I have to go with duplication?

I don't quite understand what you want to do but if you want an optional limit you can default it to false:
function gi_get_by($col,$id, $itd, $tbl, $limit=false)
{
$this->db->select('*');
$this->db->from('global_info');
$this->db->join($tbl, 'id_' . $tbl . ' = id_global_info');
$this->db->where('info_type_id', $itd);
if($col == 'date_created' || $col == 'tag') {$this->db->like($col, $id);}
else {$this->db->where($col, $id);}
if($tbl == 'ad') :
$this->db->order_by('paid', 'desc');
endif;
$this->db->order_by('date_created', 'desc');
if ($limit) {
$this->db->limit($limit, $this->uri->segment(2));
}
$q = $this->db->get();
return $q = $q->result_array();
}
This will conditionally add limit clause if it is passed in to the function.
Also it would be best to pass in wwhatever $this->uri->segment(2) into the function as a parameter instead of accessing it from within the function.

Why not select
sql_calc_found_rows
in your query?
http://www.justincarmony.com/blog/2008/07/01/mysql-php-sql_calc_found_rows-an-easy-way-to-get-the-total-number-of-rows-regardless-of-limit/

Well, how about something like this:
function gi_get_by($col,$id, $itd, $tbl, $limit = 10)
{
$count = $this->db->query('SELECT * FROM my_table')->num_rows();
//the rest stuff
}

You should use Active Record Cache:
http://codeigniter.com/user_guide/database/active_record.html#caching
function gi_get_by($col,$id, $itd, $tbl, $limit = 10)
{
// Start the cache
$this->db->start_cache();
$this->db->select('*');
$this->db->from('global_info');
$this->db->join($tbl, 'id_' . $tbl . ' = id_global_info');
$this->db->where('info_type_id', $itd);
if($col == 'date_created' || $col == 'tag') {$this->db->like($col, $id);}
else {$this->db->where($col, $id);}
if($tbl == 'ad') :
$this->db->order_by('paid', 'desc');
endif;
$this->db->order_by('date_created', 'desc');
// Stop the cache
$this->db->stop_cache();
// Get the total
$total = $this->db->count_all_results();
// Now set the limit
$this->db->limit($limit, $this->uri->segment(2));
$q = $this->db->get();
// Important! Clear the cache
$this->db->flush_cache();
return $q = $q->result_array();
}

Related

Using REGEXP with where condition when paginating in codeigniter

I have this search terms i am receiving from the user and i want to return some data which is finally being used to query mysql like this
This is how i am querying mysql SELECT * FROM search_data WHERE index_desc REGEXP 'one|two'
public function results()
{
$searchterm = $this->input->post('searchterm');
//echo clean($searchterm);
$myst = clean($searchterm);
$myst = trim($myst);
//Mysql REGEXP
$search_keywords = str_replace(' ', '|', $myst);
$config = array();
$config["base_url"] = base_url() . "search/results";
$config["total_rows"] = $this->Ion_auth_model->record_count();
$config["per_page"] = 5;
$config["uri_segment"] = 3;
$this->pagination->initialize($config);
$page = ($this->uri->segment(3)) ? $this->uri->segment(3) : 0;
$data["results"] = $this->Ion_auth_model->fetch_data($config["per_page"], $page, $search_keywords);
$data["links"] = $this->pagination->create_links();
$this->load->view("results", $data);
}
This is the model function
public function fetch_data($limit, $start,$search_keywords) {
$where_string = 'REGEXP'.$search_keywords;
$this->db->where('index_desc', $where_string );
$this->db->limit($limit, $start);
$query = $this->db->get("search_data");
if ($query->num_rows() > 0) {
foreach ($query->result() as $row) {
$data[] = $row;
}
return $data;
}
return false;
}
This is where i am having a problem
$where_string = 'REGEXP'.$search_keywords;
$this->db->where('index_desc', $where_string );
since this is what i am expecting SELECT * FROM search_data WHERE index_desc REGEXP 'one|two' and i am not getting the results i want. How can i solve this problem?.
you can use a custom string in CI where() function like:
$where_string = "index_desc REGEXP '$search_keywords'";
$this->db->where($where_string );
see Looking for specific data, last bullet (4)

I want to build an advanced query in codeigniter

I want to build a query nested in codeigniter
here is the my controller
public function advancedSearch(){
if (!$this->session->userdata('logged_in')) {
redirect('main/login', 'refresh');
}
$session_data = $this->session->userdata('logged_in');
$data['code'] = $session_data['code'];
$start = $this->input->post('start');
$end =$this->input->post('end');
$ticket = $this->input->post('ticket');
$type =$this->input->post('type');
$this->db->select('*');
$this->db->from('table');
if ($start && $end) {
$this->db->where('date >=',$start);
$this->db->where('date <=',$end);
} else if ($ticket) {
$this->db->where('ticket','yes');
} else if ($type) {
$this->db->where('type',$type);
}
$query = $this->db->get();
if ($query->num_rows() > 0) {
$data['data'] = $query->result();
}
//print_r($data);
$this->load->view('advanced-search',$data);
with this code I just get the first input a click and search, If I click just ticket I get the $this->db->where('ticket','yes'); I hope I explained well.
Greetings
Hope this will help you :
instead of using if else use it with only if with empty check
if ( ! empty($start))
{
$this->db->where('date >=',$start);
}
if (! empty($end))
{
$this->db->where('date <=',$end);
}
if (! empty($ticket))
{
$this->db->where('ticket','yes');
}
if (! empty($type))
{
$this->db->where('type',$type);
}
$query = $this->db->get();
if ($query->num_rows() > 0)
{
$data['data'] = $query->result();
}
//print_r($data);
$this->load->view('advanced-search',$data);

insert or replace in codeigniter

I want to insert of replace if exist in database with codeigniter
this my model
public function upload($id_akun,$data){
$query = $this->db->query("SELECT * FROM akun WHERE
id_akun = '{$data['id_akun']}' ");
$result = $query->result_array();
$count = count($result);
if (empty($count)) {
$this->db->insert('foto', $data);
}
elseif ($count == 1) {
$this->db->where('id_akun', $data['id_akun']);
$this->db->update('foto', $data);
}
I'm succesful replace(update) data if exist but it not inserting data if (empty($count))
conditional ($count == 1)---> it's ok
condtional (empty($count))--->problem?
Try this
In Model
public function upload($id_akun,$table){
$query = $this->db->query("SELECT * FROM akun WHERE id_akun = '$id_akun' ");
$result = $query->result_array();
$count = count($result);
if (empty($count)){
$this->db->insert('foto', $table);
return 0;
}
elseif ($count == 1) {
$this->db->where('id_akun', $id_akun);
$this->db->update('foto', $table);
return 1;
}
elseif (($count >= 1) {
return 2;
}
}
In Controller
$id_akun = 25;
$table = 'table_name';
$result = $this->model_name->upload($id_akun,$table);
switch ($result) {
case 0:
$output = 'Data Inserted'
break;
case 1:
$output = 'Record Inserted'
break;
case 2:
$output = 'Multiple Record Found'
break;
}
You can try like this ..
public function upload($id_akun,$data){
$this->db->where('id_akun',$data['id_akun']);
$this->db->from('akun');
$query = $this->db->get();
$rowcount = $query->num_rows();
if ($rowcount==0) {
$this->db->insert('foto', $data);
}
else {
$this->db->where('id_akun', $data['id_akun']);
$this->db->update('foto', $data);
}
Your problem is you're checking to see if the result of a count() is empty. That will always evaluate to false.
public function upload($id_akun, $data)
{
//use active record methods, otherwise, you need to sanitize input
$this->db->select('*');
$this->db->where('id_akun', $data['id_akun']);
$query = $this->db->get('akun');
if($query->num_rows() == 0){
$this->db->update...
}else{
....
}
}
Explanation
The function result_array() results empty array if nothing is find in fetching record. Hence when you fetch record it returns you the empty array and you are taking count of this empty array which returns you the zero length which is not equals to empty hence your condition is always remain false.
You may use the following Code.
Code
function upload($id_akun, $data) {
//use active record methods, otherwise, you need to sanitize input
$this->db->select('*');
$this->db->where('id_akun', $data['id_akun']);
$query = $this->db->get('akun');
if ($query->num_rows() == 0) {
//write your Insert query here
} elseif ($query->num_rows() > 0) {
//write your Update query here
}
}
There are several benefits to using Active Record (or Query Builder as its going to be called soon):
Security
Code-Cleanliness
Database-Agnostic
so, all time try to use active record.
<?php
public function upload($id_akun,$data){
$query = $this->db->select('*')->where('id_akun', $data['id_akun'])->from('akun')->get();
$count = $query->num_rows();
$result = $query->result_array();
if ($count == 0)
return $this->db->insert('foto', $data);
}
elseif ($count > 1) {
$this->db->where('id_akun', $data['id_akun']);
return $this->db->update('foto', $data);
}
}

get() returns empty rows in Codeigniter

I am using the function below but it did not return any rows. I tried to do $query->num_rows() but it has null values. I got the last query using $this->db->last_query(), used this in the database and there are results. Am I missing a setup in Code Igniter? Looking forward to your reply.
function search($conditions=NULL,$tablename="",$orderby='id', $order='DESC',$limit=1000000,$offset=0)
{
if($tablename=="")
{
$tablename = $this->table;
}
if($conditions != NULL)
$this->db->where($conditions);
if ( $orderby !== "" and $order !== "")
$this->db->order_by($orderby, $order);
$query = $this->db->get($tablename,$limit,$offset=0);
return $query->result_array();
}
Try like
if($conditions != NULL)
$this->db->where($conditions);
if ( $orderby !== "" and $order !== "")
$this->db->order_by($orderby, $order);
$this->db->limit($limit,$offset);
$query = $this->db->get($tablename);
first you check $tablename is table name or blank
function search($conditions=NULL,$tablename="",$orderby='id', $order='DESC',$limit=1000000,$offset=0)
{
if($tablename=="")
{
$tablename = $this->table;
}
if($conditions != NULL)
$this->db->where($conditions);
if ( $orderby !== "id" and $order !== "DESC")
$this->db->order_by($orderby, $order);
$this->db->limit($limit);
$this->db->offset ($offset );
$query = $this->db->get($tablename);
if($query->num_rows() == 0){
}

jqGrid integrated toolbar search not working

I am trying to get the integrated search toolbars working on my page, however I am not having any luck. The regular search function is working for me, but whenever I type anything into the integrated toolbars, it returns 0 results.
Here is my jquery:
$("#parts_table").jqGrid({
url:'testparts2.php',
datatype: "json",
colNames:['Part ID','Name', 'Description', 'Weight'],
colModel:[
{name:'part_ID',index:'part_ID', search: true, stype:'text', width:55},
{name:'part_name',index:'part_name', width:90},
{name:'part_desc',index:'part_desc', width:100},
{name:'part_weight',index:'part_weight', width:80, align:"right"},
],
rowNum:30,
rowList:[10,20,30],
pager: '#pager2',
sortname: 'part_ID',
viewrecords: true,
sortorder: "asc",
caption:"Parts in Database",
width: '800',
height: '300',
});
$("#parts_table").jqGrid('navGrid','#pager2',{edit:false,add:false,del:false});
$("#parts_table").jqGrid('filterToolbar',{stringResult: false,searchOnEnter : false, defaultSearch: 'cn', ignoreCase: true});
and here is my PHP code:
<?php
include "begin.php";
$page = $_REQUEST['page']; // get the requested page
$limit = $_REQUEST['rows']; // get how many rows we want to have into the grid
$sidx = $_REQUEST['sidx']; // get index row - i.e. user click to sort
$sord = $_REQUEST['sord']; // get the direction
if(!$sidx) $sidx =1;
//array to translate the search type
$ops = array(
'eq'=>'=', //equal
'ne'=>'<>',//not equal
'lt'=>'<', //less than
'le'=>'<=',//less than or equal
'gt'=>'>', //greater than
'ge'=>'>=',//greater than or equal
'bw'=>'LIKE', //begins with
'bn'=>'NOT LIKE', //doesn't begin with
'in'=>'LIKE', //is in
'ni'=>'NOT LIKE', //is not in
'ew'=>'LIKE', //ends with
'en'=>'NOT LIKE', //doesn't end with
'cn'=>'LIKE', // contains
'nc'=>'NOT LIKE' //doesn't contain
);
function getWhereClause($col, $oper, $val){
global $ops;
if($oper == 'bw' || $oper == 'bn') $val .= '%';
if($oper == 'ew' || $oper == 'en' ) $val = '%'.$val;
if($oper == 'cn' || $oper == 'nc' || $oper == 'in' || $oper == 'ni') $val = '%'.$val.'%';
return " WHERE $col {$ops[$oper]} '$val' ";
}
$where = ""; //if there is no search request sent by jqgrid, $where should be empty
$searchField = isset($_GET['searchField']) ? $_GET['searchField'] : false;
$searchOper = isset($_GET['searchOper']) ? $_GET['searchOper']: false;
$searchString = isset($_GET['searchString']) ? $_GET['searchString'] : false;
if ($_GET['_search'] == 'true') {
$where = getWhereClause($searchField,$searchOper,$searchString);
}
$totalrows = isset($_REQUEST['totalrows']) ? $_REQUEST['totalrows']: false;
if($totalrows) {
$limit = $totalrows;
}
$result = mysql_query("SELECT COUNT(*) AS count FROM parts");
$row = mysql_fetch_array($result,MYSQL_ASSOC);
$count = $row['count'];
if( $count >0 ) {
$total_pages = ceil($count/$limit);
} else {
$total_pages = 0;
}
if ($page > $total_pages) $page=$total_pages;
if ($limit<0) $limit = 0;
$start = $limit*$page - $limit; // do not put $limit*($page - 1)
if ($start<0) $start = 0;
$SQL = "SELECT * FROM parts ".$where." ORDER BY $sidx $sord LIMIT $start , $limit";
$result = mysql_query( $SQL ) or die("Couldn't execute query.".mysql_error());
$response->page = $page;
$response->total = $total_pages;
$response->records = $count;
$i=0;
while($row = mysql_fetch_array($result,MYSQL_ASSOC)) {
$response->rows[$i]['part_ID']=$row[part_ID];
$response->rows[$i]['cell']=array($row[part_ID],$row[part_name],$row[part_desc],$row[part_weight]);
$i++;
}
echo json_encode($response);
?>
It took me hours of searching to find a PHP example that worked for regular searching (see above), however it doesn't seem to work for the toolbar searching. Can anyone help? Thanks
edit: Here is code from jqGrid's demo folder for using this search, but it appears to be full of errors and I have no idea how to use it for my case. I don't need to specify data type for the searches (they are all varchars, so strings will work fine)..so I think that I can strip out the switch/case part for value conversion. I think I just need to change my original code to use $_REQUEST['filters'] and a foreach loop to build the query, but I'm not that great with PHP so any help is appreciated.
demo code:
$wh = "";
$searchOn = Strip($_REQUEST['_search']);
if($searchOn=='true') {
$searchstr = Strip($_REQUEST['filters']);
$wh= constructWhere($searchstr);
//echo $wh;
}
function constructWhere($s){
$qwery = "";
//['eq','ne','lt','le','gt','ge','bw','bn','in','ni','ew','en','cn','nc']
$qopers = array(
'eq'=>" = ",
'ne'=>" <> ",
'lt'=>" < ",
'le'=>" <= ",
'gt'=>" > ",
'ge'=>" >= ",
'bw'=>" LIKE ",
'bn'=>" NOT LIKE ",
'in'=>" IN ",
'ni'=>" NOT IN ",
'ew'=>" LIKE ",
'en'=>" NOT LIKE ",
'cn'=>" LIKE " ,
'nc'=>" NOT LIKE " );
if ($s) {
$jsona = json_decode($s,true);
if(is_array($jsona)){
$gopr = $jsona['groupOp'];
$rules = $jsona['rules'];
$i =0;
foreach($rules as $key=>$val) {
$field = $val['field'];
$op = $val['op'];
$v = $val['data'];
if($v && $op) {
$i++;
// ToSql in this case is absolutley needed
$v = ToSql($field,$op,$v);
if ($i == 1) $qwery = " AND ";
else $qwery .= " " .$gopr." ";
switch ($op) {
// in need other thing
case 'in' :
case 'ni' :
$qwery .= $field.$qopers[$op]." (".$v.")";
break;
default:
$qwery .= $field.$qopers[$op].$v;
}
}
}
}
}
return $qwery;
}
function ToSql ($field, $oper, $val) {
// we need here more advanced checking using the type of the field - i.e. integer, string, float
switch ($field) {
case 'id':
return intval($val);
break;
case 'amount':
case 'tax':
case 'total':
return floatval($val);
break;
default :
//mysql_real_escape_string is better
if($oper=='bw' || $oper=='bn') return "'" . addslashes($val) . "%'";
else if ($oper=='ew' || $oper=='en') return "'%" . addcslashes($val) . "'";
else if ($oper=='cn' || $oper=='nc') return "'%" . addslashes($val) . "%'";
else return "'" . addslashes($val) . "'";
}
}
$result = mysql_query("SELECT COUNT(*) AS count FROM invheader a, clients b WHERE a.client_id=b.client_id".$wh);
$row = mysql_fetch_array($result,MYSQL_ASSOC);
$count = $row['count'];
if( $count >0 ) {
$total_pages = ceil($count/$limit);
} else {
$total_pages = 0;
}
if ($page > $total_pages) $page=$total_pages;
$start = $limit*$page - $limit; // do not put $limit*($page - 1)
if ($start<0) $start = 0;
$SQL = "SELECT a.id, a.invdate, b.name, a.amount,a.tax,a.total,a.note FROM invheader a, clients b WHERE a.client_id=b.client_id".$wh." ORDER BY ".$sidx." ".$sord. " LIMIT ".$start." , ".$limit;
$result = mysql_query( $SQL ) or die("Could not execute query.".mysql_error());
$responce->page = $page;
$responce->total = $total_pages;
$responce->records = $count;
$i=0;
while($row = mysql_fetch_array($result,MYSQL_ASSOC)) {
$responce->rows[$i]['id']=$row[id];
$responce->rows[$i]['cell']=array($row[id],$row[invdate],$row[name],$row[amount],$row[tax],$row[total],$row[note]);
$i++;
}
//echo $json->encode($responce); // coment if php 5
echo json_encode($responce);
I actually just had this same problem myself yesterday. You are correct, you need to bring in the filters using $_REQUEST['filters'] and then break it up so that you can use each piece.
First, you are going to need to set stringResult: true in your jQuery file where you initialize the FilterToolbar.
Here is the code that PHP will use to bring in, and break up the filters object:
// Gets the 'filters' object from JSON
$filterResultsJSON = json_decode($_REQUEST['filters']);
// Converts the 'filters' object into a workable Array
$filterArray = get_object_vars($filterResultsJSON);
Now that you have $filterArray containing the contents of the filters object, you can now break up the rules object which is contained inside. Basically, there is another array inside the $filterArray which contains the search details if the user tries performing this search across multiple columns in their table - it's called rules.
Here is how I break up the rules object and perform a SELECT query based on the user's input:
// Begin the select statement by selecting cols from tbl
$sql = 'select '.implode(',',$crudColumns).' from '.$crudTableName;
// Init counter to 0
$counter = 0;
// Loop through the $filterArray until we process each 'rule' array inside
while($counter < count($filterArray['rules']))
{
// Convert the each 'rules' object into a workable Array
$filterRules = get_object_vars($filterArray['rules'][$counter]);
// If this is the first pass, start with the WHERE clause
if($counter == 0){
$sql .= ' WHERE ' . $filterRules['field'] . ' LIKE "%' . $filterRules['data'] . '%"';
}
// If this is the second or > pass, use AND
else {
$sql .= ' AND ' . $filterRules['field'] . ' LIKE "%' . $filterRules['data'] . '%"';
}
$counter++;
}
// Finish off the select statement
$sql .= ' ORDER BY ' . $postConfig['sortColumn'] . ' ' . $postConfig['sortOrder'];
$sql .= ' LIMIT '.$intStart.','.$intLimit;
/* run the query */
$result = mysql_query( $sql )
I'm sure you'll have questions, so feel free to ask if you do!

Categories