laravel - group data by DATE(created_at) with pagination - pagination

I want to show photos grouped by date. It works, but only with two queries and without pagination. Is there a way to do it with only one query, with laravels paginate() ?
I need the last 5 days (only those that have pictures), and then always 5 days per page.
The problem is, that i want to paginate the days, not the pictures.
$days = Pic::select(DB::raw('DATE(created_at) as datum'))
->distinct()
->orderBy('datum','desc')
->take(5)
->get();
$daysarray = array();
foreach($days as $day)
{
$pics = Pic::where(DB::raw('DATE(created_at)'),'=',$day->datum)
->orderBy('id','desc')
->get();
$daysarray[$day->datum] = $pics;
}

I believe you will have to live with two queries in order to paginate the dates. The following should work for that bit.
$days = Pic::select(DB::raw('DATE(created_at) as datum'))
->distinct()
->orderBy('datum','desc')
->paginate(5);

$selectboxtwo = DB::table('downloads')
->distinct('date')
->groupBy('date')
->lists('date');
dd($selectboxtwo); // making sure if it works. you can see the following array is produced.
array(3) { [0]=> string(10) "2014-03-09" [1]=> string(10) "2015-06-22" [2]=> string(10) "2015-06-23" }
Hope it helps.

Related

Pagination doesn't work after perform search

I have a form in Laravel. I used pagination in this form and search option too. Pagination works fine when I didn't search anything. If I search something which has records more than 10 (my pagination record limit is 10), it shows result perfectly in first page but in second page or third page it shows the records of whole database. It's ignore the search criteria.
Controller Code:
public function index()
{
if (Input::has('invoiceNumber')) {
$invoiceNumber = Input::get('invoiceNumber');
$invoices = Invoice::where('invoiceNumber','like', '%'.$invoiceNumber.'%')->orderBy('date','desc')->paginate(10);
} elseif (Input::has('client')) {
$client = Input::get('client');
$invoices = Invoice::where('client','like', '%'.$client.'%')->orderBy('date', 'desc')->paginate(10);
} elseif (Input::has('startDate') && Input::has('endDate')) {
$startDate = Input::get('startDate');
$endDate = Input::get('endDate');
$invoices = Invoice::whereBetween('date', [$startDate, $endDate])->orderBy('date', 'desc')->paginate(10);
} elseif (Input::has('startDate')) {
$startDate = Input::get('startDate');
$invoices = Invoice::where('date', $startDate)->orderBy('date', 'desc')->paginate(10);
} elseif (Input::has('endDate')) {
$endDate = Input::get('endDate');
$invoices = Invoice::where('date', $endDate)->orderBy('date', 'desc')->paginate(10);
} else {
$invoices = DB::table('invoices')
->join('vehicles', 'invoices.vehicle', '=', 'vehicles.registration')
->select(
'invoices.*',
'vehicles.brand',
'vehicles.model',
'vehicles.seat',
'vehicles.remarks'
)
->orderBy('date', 'desc')
->paginate(10);
}
return view('invoice.index',compact('invoices'));
}
After performing search my URL look like this:
http://my-site.com/invoice?invoiceNumber=&client=&startDate=2016-01-01&endDate=2016-02-08
After this search when I click on page 2, the URL become this:
http://my-site.com/invoice?page=2
Try to use this bellow code (change as per your requirement)
return view('invoice.index')->withInvoices($invoices->appends(Input::except('page'));
Hope it's working for you...
In your view file, the render has to be like given below:
{!! $invoices->appends(Input::except('page'))->render() !!}
Simply use this on the result page.Pagination will be automatically visible at the bottom of the page
{!! $invoices->render() !!}

Show latest posts from each custom post type with pre_get_posts

What I have
On my front page I have managed to alter the main query on the front page to show my custom post types with "pre_get_posts" like this:
function custom_post_types_in_home_loop( $query ) {
if ( ! is_admin() && is_home() && $query->is_main_query() ) {
$query->set( 'post_type', array( 'member', 'press', 'calendar_event' ) );
}
return $query;
}
add_filter( 'pre_get_posts', 'custom_post_types_in_home_loop' );
What I want
The problem is that some post types have way more posts than others, so I want to show only 3 posts per post type to get a little variation in the loop.
What I've tried
With some help from this and this answer ive managed to do this but nothing's happening, what am I doing wrong?
function custom_post_types_in_home_loop( $query ) {
if ( ! is_admin() && is_home() && $query->is_main_query() ) {
$query->set( 'post_type', array( 'member', 'press', 'calendar_event' ) );
if ( $query->get( 'post_type' ) == 'member' ) {
$query->set('posts_per_page', 3);
}
/* And the same 'if' statement for 'press' and 'calendar_event' */
}
return $query;
}
add_filter( 'pre_get_posts', 'custom_post_types_in_home_loop' );
You are setting post_type on the main query to an array. And then comparing it against a string. None of these conditionals are true and hence aren't executing.
If you simply want to limit the number of queries and pick a random order you can do so with,
$query->set('posts_per_page', 9);
$query->set('orderby', 'rand);
This will give you 9 posts, 3 each, randomly choosen between the different Custom Post Types.
To keep the different types together, you'll need to build a more complex and resource intensive groupby query. If you need this, I'd suggest building 3 different Custom Loops for each post_type instead.

Order nodes by Node reference field Using Views 2 (Drupal 6)

Drupal 6.20, Views 6.x-2.12.
I have a view listing nodes of type A, each one having a Node reference field mynoderef_field. I can show A.titleĀ and A.mynoderef_field, but they show up randomly. I want to order the nodes by A.mynoderef_field, but it does not appear as a possible "Order by" field.
I googled for a while, and couldn't find the answer. Any idea?
Thanks
this should do the trick:
<?php
function modulename_views_pre_render(&$view) {
if ($view->name == 'field_name') {
$new_result = array();
$nids = explode(',', $view->args[0]);
foreach ($nids as $nid) {
foreach ($view->result as $res) {
if ($res->nid == $nid) {
$new_result[] = $res;
break;
}
}
}
$view->result = $new_result;
}
}
?>
I got this to work by using a relationship between the node A and mynoderef_field. Add node title to sort criteria and make sure the relationship is selected.

multi insert in kohana orm3

In my application i have a loop that executes about 1000 times, inside it i'm creating object and saving it. This is the part of application where i populate my database with data. In common this looks like this:
foreach(...){
...
try{
$object = new Model_Whatever;
$object->whatever=$whatever;
$object->save();}
catch(Exception $e){
...}
}
}
This produces 1000 of INSERT queries. Is it possible to, in some way, made kohana produce multi inserts. Split this into 10 inserts with 100 data sets in each. Is it possible and if yes that what is the way doing so?
Whilst the Kohana ORM doesn't support multi inserts, you can still use the query builder as follows:
$query = DB::insert('tablename', array('column1', 'column2','column3'));
foreach ($data as $d) {
$query->values($d);
}
try {
$result = $query->execute();
} catch ( Database_Exception $e ) {
echo $e->getMessage();
}
you'll still need to split the data up so the above doesn't try to execute a query with 1000 inserts.
$data assumes an array of arrays with the values corresponding to the order of the columns
thanks Isaiah in #kohana
php work very slow when insert multi array very big (so that method ::values have array_merge) so more fast:
class Database_Query_Builder_Bath_Insert
extends Database_Query_Builder_Insert{
public static function doExecute($table, $data) {
$insertQuery = DB::insert($table, array_keys(current($data)));
$insertQuery->_values = $data;
$insertQuery->execute();
}
}
call_user_func_array([$query, 'values'], $data);

Select top/latest 10 in couchdb?

How would I execute a query equivalent to "select top 10" in couch db?
For example I have a "schema" like so:
title body modified
and I want to select the last 10 modified documents.
As an added bonus if anyone can come up with a way to do the same only per category. So for:
title category body modified
return a list of latest 10 documents in each category.
I am just wondering if such a query is possible in couchdb.
To get the first 10 documents from your db you can use the limit query option.
E.g. calling
http://localhost:5984/yourdb/_design/design_doc/_view/view_name?limit=10
You get the first 10 documents.
View rows are sorted by the key; adding descending=true in the querystring will reverse their order. You can also emit only the documents you are interested using again the querystring to select the keys you are interested.
So in your view you write your map function like:
function(doc) {
emit([doc.category, doc.modified], doc);
}
And you query it like this:
http://localhost:5984/yourdb/_design/design_doc/_view/view_name?startkey=["youcategory"]&endkey=["youcategory", date_in_the_future]&limit=10&descending=true
here is what you need to do.
Map function
function(doc)
{
if (doc.category)
{
emit(['category', doc.category], doc.modified);
}
}
then you need a list function that groups them, you might be temped to abuse a reduce and do this, but it will probably throw errors because of not reducing fast enough with large sets of data.
function(head, req)
{
% this sort function assumes that modifed is a number
% and it sorts in descending order
function sortCategory(a,b) { b.value - a.value; }
var categories = {};
var category;
var id;
var row;
while (row = getRow())
{
if (!categories[row.key[0]])
{
categories[row.key[0]] = [];
}
categories[row.key[0]].push(row);
}
for (var cat in categories)
{
categories[cat].sort(sortCategory);
categories[cat] = categories[cat].slice(0,10);
}
send(toJSON(categories));
}
you can get all categories top 10 now with
http://localhost:5984/database/_design/doc/_list/top_ten/by_categories
and get the docs with
http://localhost:5984/database/_design/doc/_list/top_ten/by_categories?include_docs=true
now you can query this with a multiple range POST and limit which categories
curl -X POST http://localhost:5984/database/_design/doc/_list/top_ten/by_categories -d '{"keys":[["category1"],["category2",["category3"]]}'
you could also not hard code the 10 and pass the number in through the req variable.
Here is some more View/List trickery.
slight correction. it was not sorting untill I added the "return" keyword in your sortCategory function. It should be like this:
function sortCategory(a,b) { return b.value - a.value; }

Resources