Get query string parameters are lost when using pagination links in laravel - laravel

I have tried to use pagination with laravel and everything works fine
until I navigate to another page, then the request doesn't preserve the previous query string and, as a result, the query doesn't work anymore.
This is the query in the controller:
$inputDate =$request->input('date') ;
$endDate = date('Y-m-d', strtotime($inputDate. ' + 7 days'));
$shifts = DB::table('driver_shifts')
->join('drivers','drivers.PermitNumber','=','driver_shifts.driver_badge_id')
->where ('driver_shifts.shift_start_time','>',$inputDate)
->where ('driver_shifts.shift_start_time','<',$endDate)
->orderby("vehicle_id")
->orderby("shift_start_time")
->paginate(20);
return view('reports.WeeklyTaxiShifts.WeeklyTaxiShifts', compact('shifts','inputDate'));

You can try to use:
$shifts = DB::table('driver_shifts')
->join('drivers','drivers.PermitNumber','=','driver_shifts.driver_badge_id')
->where ('driver_shifts.shift_start_time','>',$inputDate)
->where ('driver_shifts.shift_start_time','<',$endDate)
->orderby("vehicle_id")
->orderby("shift_start_time")
->paginate(20)
// this line will put back the query string parameters on the generated links
->appends(request()->query());
That is also explained with a blade usage example in the documentation

Related

Eloquent pagination result does not include data, next_page_url and other parameters

The pagination is like this:
Qitem::filter(Request::get("search") ?: "")
->withUserNames()
->withTrashed()
->paginate(10)
->onEachSide(1)
->withQueryString()
The returned data is different what is expected (even according to the docs):
According to docs, there should be other attributes like prev_page_url, next_page_url, and instead of items, there should be a data attribute, containing the data from the table. It even behaves so if I simplify the query like:
Qitem::paginate(10)
Has anybody experienced similar phenomena? Any suggestions? Thanks in advance.
For the purposes which response do you need, you can do it like:
JSON response
Create resource:
php artisan make:resource QItemResource
More about resources in the docs
Next in your controller:
$items = Qitem::filter(Request::get("search") ?: "")
->withUserNames()
->withTrashed()
->paginate(10)
->onEachSide(1)
->withQueryString();
return QItemResourec::collection($items);
And you will get next_page_url, prev_page_url & data.
Collection
Just simply collect paginated data with collect().
$items = Qitem::filter(Request::get("search") ?: "")
->withUserNames()
->withTrashed()
->paginate(10)
->onEachSide(1)
->withQueryString();
dd(collect($items));

Caching Eloquent models in Laravel 5.1

I've created an API using Laravel and I'm trying to find out how to cache Eloquent models. Lets take this example as one of the API endpoints /posts to get all the posts. Also within the method there are various filter options such as category and search and also gives the option to expand the user.
public function index()
{
$posts = Post::active()->ordered();
if (Input::get('category')) $posts = $posts->category(Input::get('category'));
if (Input::get('search')) $posts = $posts->search(Input::get('search'));
if ($this->isExpand('user')) $posts = $posts->with('user');
$posts = $posts->paginate($this->limit);
return $this->respondWithCollection($this->postTransformer->transformCollection($posts->all()), $posts);
}
I have been reading up and found in Laravel 4 you could cache a model like this
return Post::remember($minutes);
But I see this has been removed for Laravel 5.1 and now you have to cache using the Cache facade, but is only retrievable by a single key string.
$posts = Cache::remember('posts', $minutes, function()
{
return Post::paginate($this->limit);
});
As you can see, my controller method contains different options, so for the cache to be effective I would have to create a unique key for each option like posts_cagetory_5, posts_search_search_term, posts_category_5_search_search_term_page_5 and this will clearly get ridiculous.
So either I'm not coming across the right way to do this or the Laravel cache appears to have gone backwards. What's the best solution for caching this API call?
As the search is arbitrary, using a key based on the search options appears to be the only option here. I certainly don't see it as "ridiculous" to add a cache to for expensive DB search queries. I may be wrong as I came by this post looking for a solution to your exact problem. My code:
$itemId = 1;
$platform = Input::get('platform'); // (android|ios|web)
$cacheKey = 'item:' . $itemId . ':' . $platform;
$item = Item::find(1);
if( Cache::has($cacheKey) ) {
$result = Cache::get($cacheKey);
} else {
$result = $this->response->collection( $item, new ItemTransformer( $platform ) );
Cache::tags('items')->put($cacheKey, $result, 60); // Or whatever time or caching and tagged to be able to clear the lot in one go...
}
return $result;
I realise that my example has less complexity but it seems to cover all the bases for me. I then use an observer to clear the cache on update.

Laravel Lumen - Eloquent Query Log

I'm using Laravel Lumen to build an API.
I've come to a point where I need to find out what SQL query is being generated by Eloquent. I know how to do this in Laravel 4 and Laravel 5 but i've tried the same code in Lumen and the query is blank?
$queries = DB::getQueryLog();
$last_query = end($queries);
echo 'Query<pre>';
print_r($last_query);
exit;
The above code, when run in Laravel works fine - in Lumen the query is blank?
To get the query log in Laravel Lumen working you need to enable it:
DB::connection()->enableQueryLog();
You can add that code in to your controller, middleware, etc then use:
$queries = DB::getQueryLog();
$lastQuery = end($queries);
dd($lastQuery)
To print your query.
You can also use the following with eloquent:
$myModel = Users::where('active', true);
dd($myModel->getSql(), $myModel->getBindings());
You must run the getSql() and getBindings() before you call ->first() or ->get(), etc
Just call this after the query to keep it quick and simple:
echo $query->toSql();

Paginator on laravel 4.2

I am new to laravel and I am trying to get a pagination function into my result pages, so I have the following function to generate results from query and I would like to have a pagination on the results page, but I don't seem to get it work correctly
public function showResults()
{
$selectedquery = Input::get('Annonces');
$what = Input::get('what');
$where = Input::get('where');
$results = DB::table('annonces')->where($selectedquery,'LIKE', '%'.$what.'%')
->where('Lieu','LIKE', '%'.$where.'%')
->get();
return View::make('results',array('results' => $results));
}
Any Help?
Well, for one, you're missing the call to ->paginate(n). Right now, your closure is ->get(), which returns all results for your annonces table. This is good, but doesn't work for pagination. Change the function like so:
$results = DB::table('annonces')->where($selectedquery,'LIKE', '%'.$what.'%')
->where('Lieu','LIKE', '%'.$where.'%')
->paginate(10);
This will return all results grouped into 10 results per page. Feel free to change that as you see fit.
Lastly, somewhere on your view where you display the results, you will need to use this code to display a page-viewer:
<?php echo $results->links(); ?>
<!-- OR -->
{{ $results->links(); }}
Also, be sure to check out the docs on Laravel's pagination. You'll find it's pretty comprehensive!
Laravel Pagination
Hope that helps!

Parentheses passed in url break codigniter query

I have a string being passed via an URL to a Codeigniter driven site. The string is urlencoded before being passed, then urldecoded by the controller before being passed to a function in the model that searches for the string in a database table. I've read several other posts/articles on this, but none offer a viable (for me) solution to the issue. Here are some of the things I have read:
URL having parentheses not working in codeigniter with datamapper ORM
Parenthesis issue in codeigniter url
php rawurldecode doesn't produce same string passed to rawurlencode
http://qubitlogs.com/PHP/2013/01/24/parentheses-in-urls-not-working-codeigniter-datamapper-orm/#.U0MtAce7mxa
And here is what is happening:
An url encoded string gets passed via an url, like so:
http://www.awebsite.com/controllername/functionname/test%28string%29
The controller handles this like so:
public function functionname($string) {
$this->load->model("codeigniter_model");
$dstring = urldecode($string);
$validString = $this->codeigniter_model->valid_string($dstring);
if (!$validString) {
$thiserror = "<br>Error: Invalid String. (".$dstring.")";
echo $thiserror;
exit;
}
}
And the model:
function valid_string($string)
{
$sql = "select id from dbtable where dbfield = ?";
$query = $this->db->query($sql, array($string));
//Added this in to see what the query actually end up being
echo $this->db->last_query();
if ($query->num_rows() > 0) :
return TRUE;
else:
return FALSE;
endif;
}
The echoed query is correct: select id from dbtable where dbfield = 'test(string)' and when run in Navicat returns the proper id. However - Codeigniter returns FALSE on the query.
I have also checked that the string in the query getting echoed does NOT contain HTML entities.
I have no control over the string being passed and really need Codeigniter to accept ( and ) as part of the string.
Thoughts, anyone?
EDIT: When the same string is passed to the Codeigniter controller via a post from a form, it works properly.
EDIT #2: Just tried creating the query using the Active Record method as suggested here: CAN'T ADD ANOTHER LINK SO : ellislab.com forums viewthread 162036
This:
$this->db->select('id');
$this->db->where('dbfield', "'".$string."'", FALSE);
$query = $this->db->get('dbfield');
does not work either.
EDIT #3: Thanks to Kyslik for suggesting using profiler. The string is apparently being html encoded after all: select id from users where string = 'test(string)' which, of course WOULD return false because of the HTML entities.
Unfortunately, adding code to remove those entities using both a regular query and an active record query:
$sql = "select id from dbtable where dbfield = ?";
$query = $this->db->query($sql, array(htmlspecialchars_decode($string)));
AND
$this->db->select('id');
$this->db->where('dbfield', "'".htmlspecialchars_decode ($string)."'", FALSE);
$query = $this->db->get('dbtable');
still do not work.
The answer is that htmlspecialchars_decode() does NOT decode the entities for ( and ). If I add this code to the controller before passing the string (and AFTER url decoding):
$dstring = str_replace("(", "(", $dstring);
$dstring = str_replace(")", ")", $dstring);
Then everything works as it should.

Resources