Using Carbon for Laravel queries - php

how can I use Carbon to output created_at human readable queries like Facebook's 1 min ago on it's posts. The problem is I always return the results of the query to output in the browser directly. How can I integrate it so instead of 2015-07-01 12:32:43 it would be 1 min ago or other that's human readable and nice.
In my controller:
$posts = DB::table('posts')
->where('author_id', '=', $id)
->where('created_at', '<', $date)
->orderBy('created_at', 'desc')
->paginate(10);
return $posts;
It will then return a json format of all posts.

I recommend you use an Eloquent model and the features that come with it:
class Post extends Eloquent {
protected $appends = array('created_at_for_humans');
public function getCreatedAtForHumansAttribute(){
return Carbon::parse($this->attributes['created_at'])->diffForHumans();
}
}
This attribute accessor returns the formatted date and because it is registered in $appends the attribute will be included for array/JSON conversion.
And your query would look nearly the same:
$posts = Post::where('author_id', '=', $id)
->where('created_at', '<', $date)
->orderBy('created_at', 'desc')
->paginate(10);

Try:
foreach ($posts as &$post) {
$post->created_at = Carbon::parse($post->created_at)->diffForHumans();
}
before return

Related

How to get data filter date according to field table from database

my code in LaporanController.php
class LaporanController extends Controller
{
public function index(Request $request)
{
if (isset($request->start_date) && isset($request->end_date)) {
$start_date = Carbon::parse($request->start_date)->format('Y-m-d');
$end_date = Carbon::parse($request->end_date)->format('Y-m-d');
$attendance_absent = DB::table('attendance_absent as absent')
->whereBetween('absent.do_date_start', 'absent.do_date_end', [$start_date, $end_date])
->get();
dd($attendance_absent);
}
}
}
how to get request data from start_date and end_date according to attendance_absent table from database fields do_date_start and do_date_end? i try to use whereBetween but i get error : Illuminate\Database\Query\Builder::whereBetween(): Argument #2 ($values) must be of type array, string given. how to solve my problem ?
normally whereBetween using for single column date check. but in this case youu need get from the different columns. so try to check those date like this. i think it will we help full for you.
do try it like this
->whereDate('do_date_start', '>=', $from_date)
->whereDate('do_date_start', '<=', $to_date)
->whereDate('do_date_end', '>=', $from_date)
->whereDate('do_date_end', '<=', $to_date)
other thin if you used whereBetween you will not get equal date of today.
whereBetween function is used to query one field with 2 or more values, what you really want is just where function twice, try this:
...
->where([
['absent.do_date_start', '>=', $start_date],
['absent.do_date_end', '<=', $end_date],
])
->orWhere(function ($query) use ($start_date, $end_date) {
$query->where([
['absent.do_date_start', '>', $start_date],
['absent.do_date_start', '>', $end_date],
['absent.do_date_end', '<', $start_date],
['absent.do_date_end', '<', $end_date],
])
})
->get();
...

Laravel whereDate not working

I want to load more links of day, but the whereDate not working, and I don't know why... The date format is correct.
public function day_load_more($clicks, $total_links, $data) {
$data_carbon = Carbon::createFromFormat('d-m-Y h:i:s', '20-02-2018 00:00:00');
$ex_link_in = explode(',', $_POST['links_inserts']);
$links = Link::where('status', '=', 1)
->WhereNotIn('id', $ex_link_in)
->whereDate('created_at', $data_carbon)
->where('clicks', '<=', $clicks)
->orderBy('clicks', 'desc')
->with('page', 'tag')
->where('sponsored', 0)
->take(10)
->get();
}
The stranger thing, is that in the other method works fine (show only links of day):
public function linksofday($data){
$data_carbon = Carbon::createFromFormat('d-m-Y h:i:s', '20-02-2018 00:00:00');
$links = Link::where('status', '=', 1)
->orderBy('clicks', 'desc')
->with('page', 'tag')
->where('sponsored', 0)
->whereDate('created_at', $data_carbon)
->whereNotIn('id', [$this->getFirstLinkDay($data)->id])
->take(10)
->get();
}
I got 5 links of day 20-02, when I roll the page, should not show anything more, but shows links of others days...
I don't think the issue is with your parsing of the date but rather with some other where or maybe because some of the input variable has wrong data, also instead of using $_POST you can just access it's data with Request object

How do you filter the user with hasRole() in Laravel 5 within relational query?

I want to filter my query and return only if the user hasRole "Premium" and limit the result to 10.
Along with this query is a count of records which Conversion has and sort it in DESC order by total column.
Right now I have a working query that returns the count of Conversion and with a User but without user filter Role.
// Model Conversion belongs to User
// $from & $end uses Carbon::createDate()
// Current code
$query = Conversion::select('user_id',DB::raw('COUNT(*) as total'))
->whereBetween('created_at', [$from,$end])
->where('type','code')
->where('action','generate')
->whereNotNull('parent_id')
->with('user')
->groupBy('user_id')
->orderBy('total', 'DESC')
->take(10)
->get();
// current result
foreach ($query as $q) {
$q->user->name; // To access user's name
$q->total; // To access total count
}
// I tried this but no luck
$query = Conversion::select('user_id',DB::raw('COUNT(*) as total'))
->whereBetween('created_at', [$from,$end])
->where('type','code')
->where('action','generate')
->whereNotNull('parent_id')
->with('user', function($q) {
$q->hasRole('Premium');
})
->groupBy('user_id')
->orderBy('total', 'DESC')
->take(10)
->get();
You need to use whereHas instead of with, like this:
->whereHas('user', function ($query) {
$query->where('role','Premium');
})
Use the whereHas() instead of with(). Also, you can't use hasRole() if it's not a local scope:
->whereHas('user.roles', function($q) {
$q->where('name', 'Premium');
})

How to use now() with Eloquent?

What the best way to use now() with Eloquent? I mean, is there a native Eloquent function to return today's date? I'm using Slim framework and for this query, the only solution that I found is:
$now = date('Y/m/d H:i:s', time());
$articles = Article::where('created_at', '<', $now)
->orderBy('created_at', 'DESC')
->limit(10)
->get();
It's a bit messy, isn't it?
I could use Carbon but it would make an extra dependency...
Thanks
You have two options here: either use DB::raw method to make where method process the given expression as is:
$articles = Article::where(DB::raw('created_at < NOW()'))
->orderBy('created_at', 'DESC')
->limit(10)
->get();
... or use whereRaw method:
$articles = Article::whereRaw('created_at < NOW()')
->orderBy('created_at', 'DESC')
->limit(10)
->get();
As a sidenote, Eloquent has several helper methods for datetime-related processing - whereDate, whereMonth, whereDay, whereYear and whereTime. I'm really not sure those can be used in this specific case, but they might turn helpful elsewhere.

Adding parameters to the relation in laravel

I have a query the uses many ->with() in Laravel like so:
$campaign = $this->campaign
->with('tracks.flights.asset')->take(4)
->with('tracks.group')
->with('tracks.media')
->with('tracks.flights.comments')
->orderBy('created_at', 'desc')->find($id);
and in the Track model i have this method:
public function flights()
{
return $this->hasMany('Flight\Flight')->orderBy('start_date');
}
What I want to achieve is having the same result as now but i want to put date constrains on the flight level, for example something like this:
public function flights($start_date, $end_date) //dynamic dates
{
return $this->hasMany('Flight\Flight')->whereRaw('start_date > $start_date and end_date < $end_date')->orderBy('start_date');
}
How can I achieve this kind of result? I am fairly new to Laravel.
Thanks in advance.
Chain a whereHas onto your query.
$campaign = $this->campaign
->with('tracks.flights.asset')->take(4)
->with('tracks.group')
->with('tracks.media')
->with('tracks.flights.comments')
->whereHas('tracks.flights', function($q) use ($start_date, $end_date) {
$q->where('start_date', '>', $start_date)->where('end_date', '<', $end_date)->orderBy('start_date');
})
->orderBy('created_at', 'desc')->find($id);
Keep in mind the orderBy will only order the results returned within the flights relation, not the campaigns themselves.
This is the solution i came up with after reading Eloquent ORM in Laravel
$campaign = $this->campaign
->with(array('tracks.flights' => function($query)
{
$query->whereRaw('flights.start_date > "2016-01-09 00:00" AND flights.end_date < "2016-01-16 00:00"')
->with('asset')->take(4)
->with('comments');
}
))
->with('tracks.group')
->with('tracks.media')
->orderBy('created_at', 'desc')->find($id);

Categories