Is it possible to split query builder in Laravel? - php

Is it possible to split queries somehow like this?
public function getStatuses($dates)
{
$query = DB::table('tickets');
if ($dates['from'])
$query = $query->where('from', $dates['from']);
if ($dates['to'])
$query = $query->where('to', $dates['to']);
$query = $query->select('Active');
return $query->get()->toArray();
}

Yes, it's possibile. But don't reassign to the same variable or you risk messing it up:
public function getStatuses($dates)
{
$query = DB::table('tickets');
if ($dates['from'])
$query->where('from', $dates['from']);
if ($dates['to'])
$query->where('to', $dates['to']);
$query->select('Active');
return $query->get()->toArray();
}

In Laravel 4, its necessary to assign the get method to a variable
public function scopeGetPosts($query, $this_user = NULL){
$results = DB::table('post')
->select('*')
->where('post_status','=','publish');
if( $this_user != NULL ){
$results->where('post_author','=',$this_user->user_id);
}
$data = $results->orderBy('created_at', 'desc')
->get();
if( empty( $results ) )
$data = 'no results';
return $data;
}

In Laravel Eloquent :
$query = ModelName::where('status',1);
if($userId){
$query->where('user_id',$userId);
}
if($limit){
$query->limit($limit);
}
$result = $query->get();

Related

Codeigniter Select and Count MySQL Records

Using Codeigniter 3, I would like to display all the records from a table in a MySQL database. I'd also like to include the number of records selected.
For example;
Showing x number of records;
record 1
record 2
record 3
etc
Currently I have the following (which works);
// select all records
public function selectRecords() {
$this->db->select('*');
$this->db->from('records');
$query = $this->db->get();
return $query->result_array();
}
// count all records
public function countRecords() {
$this->db->select('count(*) as count');
$this->db->from('records');
$query = $this->db->get();
return $query->row();
}
My question is do I need two separate queries in order to achieve this (select and count)?
Is there a more efficient way of achieving what I want?
You can do something like this :
public function selectRecords()
{
$query = $this->db->get('records');
if ($query->num_rows() > 0 )
{
$records = $query->result_array();
$data['count'] = count($records);
$data['all_records'] = $records;
return $data;
}
}
Pass it to the view from your controller :
$data = $this->model_name->selectRecords();
/*print_r($data) to see the output*/
$this->load->view('your_view',$data);
In view :
<?php echo $count .' number of records';?>
you can do only:
public function selectRecords() {
$this->db->select('*');
$this->db->from('records');
$query = $this->db->get();
return $query->result_array();
}
and
$records = $this->selectRecords();
$count = count($records);
In The first function itself you can get the count using $query->num_rows() function
public function selectRecords() {
$return = array();
$this->db->select('*');
$this->db->from('records');
$query = $this->db->get();
$return['count'] = $query->num_rows();
$return['records'] = $query->result_array();
return $return;
}
try this
it will help you to provide pagination for records
public function selectRecords($params = array(), $count = false) {
$offset = isset($params['offset']) ? $params['offset'] : '';
$limit = isset($params['limit']) ? $params['limit'] : '';
$this->db->select('*');
$this->db->from('records');
$query = $this->db->get();
if ($count) {
return $this->db->get()->num_rows();
}
if (empty($offset) && !empty($limit)) {
$this->db->limit($limit);
}
if (!empty($offset) && !empty($limit)) {
$this->db->limit($limit, $offset);
}
$result = $this->db->get()->result();
return $result;
}

Concatenate queries using Eloquent Builder

How can I concatenate queries using Eloquent Builder?
I am building queries based on criteria (where clause) and taking limit and offset from URL. These queries are then passed to ->get() method to fetch result. I want to do it using Eloquent and not Query builder.
This is how you build a query in eloquent(I have given an example of using multiple where clauses):
$result = ModelName::where('key_1', '=' , 'value_1')
->where('key_2', '>', 'value_2')
->take(4)
->offset(2)
->get()
The take() method will limit the number of results to 4 with offset 2.
http://laravel.com/docs/5.0/eloquent
Update
Based on OP's question over here https://laracasts.com/discuss/channels/general-discussion/eloquent-query-builder , I am updating my answer.
You could do something like this:
if($params)
{
$query = $this->model;
foreach($params['search'] as $param)
{
$query = $query->where($param['where'],'=',$param['value']);
}
if (isset($params['start']))
{
$query = $query->offset($params['start'] );
}
if(isset($params['count']))
{
$query = $query->take($params['count']);
}
if (isset($params['sortColumn']))
{
$ascending = $params['ascending'] == 'true' ? 'ASC' : 'DESC';
$query = $query->orderBy($params['sortColumn'], $ascending);
}
}
$query->get();
What you need is assigning result of functions again to the model.
You had:
if($params)
{
foreach($params['search'] as $param)
{
$this->model->where($param['where'],'=',$param['value']);
}
if (isset($params['start']))
{
$this->model->offset($params['start'] );
}
if(isset($params['count']))
{
$this->model->take($params['count']);
}
if (isset($params['sortColumn']))
{
$ascending = $params['ascending'] == 'true' ? 'ASC' : 'DESC';
$this->model->orderBy($params['sortColumn'], $ascending);
}
}
$this->model->get();
and you need to use:
if($params)
{
foreach($params['search'] as $param)
{
$this->model = $this->model->where($param['where'],'=',$param['value']);
}
if (isset($params['start']))
{
$this->model = $this->model->offset($params['start'] );
}
if(isset($params['count']))
{
$this->model = $this->model->take($params['count']);
}
if (isset($params['sortColumn']))
{
$ascending = $params['ascending'] == 'true' ? 'ASC' : 'DESC';
$this->model = $this->model->orderBy($params['sortColumn'], $ascending);
}
}
$data = $this->model->get();

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

Codeigniter- get query results

I want to get all query results where I get the id's from another query. I get all relevant id's from both table but i can show only one result in my view. Where is my folt, and how can I fix this?
my Controller:
$results = $this->my_model->hd($query_array ,$limit, $offset);
$data['r']= $results ['rows'];
$data['num_results']= $results ['num_rows'];
$id_str = '';
foreach($results['rows'] as $row){
$id_str .= $row->id . ',';
}
$id_str = rtrim($id_str, '');
$doff = $this->my_model->off($id_str);
$data['o']= $doff ['rows'];
My Model:
function hd($query_array,$limit, $offset){
//result query
$q = $this->db->select('*')
->from('a')
->limit($limit, $offset);
if (strlen($query_array['cy'])){
$q->like('cy', $query_array['cy']);
}
if (strlen($query_array['cat'])){
$q->where('cat', $query_array['cat']);
}
if (strlen($query_array['rat'])){
$q->where('rat', $query_array['rat']);
}
$ret['rows'] = $q->get()->result();
$q = $this->db->select('COUNT(*) as count', FALSE)
->from('r');
if (strlen($query_array['cy'])){
$q->like('cy', $query_array['cy']);
}
if (strlen($query_array['cat'])){
$q->where('cat', $query_array['cat']);
}
if (strlen($query_array['rat'])){
$q->where('rat', $query_array['rat']);
}
$tmp = $q->get()->result();
$ret['num_rows'] = $tmp[0]->count;
return $ret;
}
function off($id_str){
$off_a = $this->db->select('*')
->from('off')
->where('r_id', $id_str);
$ret['rows'] = $off_a->get()->result();
return $ret;
}
I show in my view the result in a foreach loop. I tried to fix this problem since three days by my self and google, but no luck.

This query show me with this active record

I am having trouble getting two tables and passing them to controller:
IN A MODEL:
function get_all_entries() {
$query = $this->db->get('entry');
return $query->result();
$this->db->select('entry_id , count(comment_id) as total_comment');
$this->db->group_by('entry_id');
$comment = $this->db->get('comment');
return $comment->result();
}
IN A CONTROLLER:
$data['query'] = $this->blog_model->get_all_entries();
$this->load->view('blog/index',$data);
How do I return $query and $comment variables to controller? I think I am doing it wrong.
Use this because you are not allowed to return twice in the same method
function get_all_entries()
{
$query = $this->db->get('entry');
$data[] = $query->result();
$this->db->select('entry_id , count(comment_id) as total_comment');
$this->db->group_by('entry_id');
$comment = $this->db->get('comment');
$data[] = $comment->result();
return $data;
}
EDITS:
In controller
function index(){
$this->load->model('mymodel');
$result = $this->mymodel->get_all_entries();
$entries = $result[0] ;
$comments = $result[1] ;
$data['entries'] = $entries;
$data['comments '] = $comments;
}
Your issue is that you're returning $query->result() in first place, return function halts the current function, so the next steps are not being processed.
Best way would be to create two methods for either $query get and $comment get.
An alternative to your issue would be
function get_all_entries() {
$query = $this->db->get('entry');
$this->db->select('entry_id , count(comment_id) as total_comment');
$this->db->group_by('entry_id');
$comment = $this->db->get('comment');
return array($query->result(),$comment->result());
}
Then in your controller
list($data['query'],$data['comment']) = $this->blog_model->get_all_entries();
$this->load->view('blog/index',$data);

Categories