Laravel Trends with Carbon Based on Rating - php

I want to find out if a product is trending on my website (trending up or down) based on the period that is passed in. I.e. If week is passed in, it compares the current week up to the day to the previous week up to the same day.
e.g. If today is Wednesday, and the mode is week, it will compare this week up to today, with last week up to last Wednesday.
I have so far:
public function getTrendAttribute($period)
{
$last_period = $this->ratings()->where(DB::raw(), )->avg('rating');
$this_period = $this->ratings()->where(DB::raw(), )->avg('rating');
}
Which I don't think is the correct start :(.
How can I achieve this (I have the Carbon library in my app)?
What about this? I am not sure if it is very efficient but it seems to be giving me some numbers that make sense:
public function getTrendAttribute($period)
{
$tz = 'Europe/London';
$this_week_start = Carbon::now($tz)->startOfWeek();
$now = Carbon::now($tz);
$last_week_start = Carbon::now($tz)->subWeek(1)->startOfWeek();
$now_last_week = Carbon::now($tz)->subWeek(1);
$last_period = $this->ratings()->where('created_at', '>=', $last_week_start)->where('created_at', '<=', $now_last_week)->avg('rating');
$this_period = $this->ratings()->where('created_at', '>=', $this_week_start)->where('created_at', '<=', $now)->avg('rating');
return $last_period > $this_period ? -1 : $last_period < $this_period ? 1 : 0;
}

Try this. Note that it is specific to the week grouping, and you would have to modify that query for grouping by month, or day, or anything else like that. But you should be able to use MySQL date functions to accomplish this.
$last_period = $this->ratings()->where(DB::raw('week(created_at)'), DB::raw('week(now()) - 1'))->where(DB::raw('dayofweek(created_at)'), '<=', DB::raw('dayofweek(now())'))->avg('rating');
$this_period = $this->ratings()->where(DB::raw('week(created_at)'), DB::raw('week(now())')->avg('rating');

Related

How to compare created_at timestamp with Carbon date In laravel?

I have orders table , I want to get orders that have been created at this month only (delivery process happens at the same day).
I want to compare between the carbon date which refers to this current month with the created_at field of type timestamps for orders.
This is my attempt:
$month = Carbon::today();
$currentMont = $month->month;
$thisMonthOrders = Order::where('place_id',$id)->where('stage',9)->whereDate('created_at',$currentMont)->get();
dd($thisMonthOrders);
The output that it gives me is an empty array.
You'll need to use the MONTH function in MySQL, along with a whereRaw:
$thisMonthOrders = Order::where('place_id',$id)
->where('stage',9)
->whereRaw('MONTH(created_at) = ?',[$currentMont])
->get();
However, you'll have issues when you have multiple years, unless you also add in a YEAR check. You might have better luck with whereBetween instead.
$start = Carbon::now()->startOfMonth();
$end = $start->copy()->endOfMonth();
$thisMonthOrders = Order::where('place_id',$id)
->where('stage',9)
->whereBetween('created_at',[$start, $end])
->get();

how to filter results inside where clause in laravel?

I am new to laravel, I am building a small application which alerts when event date is a week away from current date. Here is my controller code
public function index()
{
$domain_count = domain_details::get()->count();
$domain_alert = domain_details::
where('domain_ex_date','>',date('Y-m-d'))
->get();
}
The domain_ex_date is in the format (YYYY-mm-dd) stored with the help of Carbon. The line where('domain_ex_date','>',date('Y-m-d')) gets me whole record when the domain_ex_date is away from the current date. i.e 2017-06-12 > 2016-09-15 gets the whole record. Here what i want to do is , i want to filter and get the only records which is only a week away from the current date. How do i do this ? i have tried like subweek() and subdays() but nothing helped.
I should get the record only when it satisfies this condition domain_ex_date - current date = 7
You can use strtotime():
domain_details:: where('domain_ex_date','<',date('Y-m-d',strtotime("+7 days")))
-> where('domain_ex_date','>',date('Y-m-d'))
->get();
Use Carbon!
Carbon is a build in date-extension ... Try it! :)
$week = Carbon::now()->addWeek();
$now = Carbon::now();
domain_details::where("domain_ex_date","<" $week)
->where("domain_ex_date", ">" $now)
->get()
Or you could also use the addDays($days) method!
$week = Carbon::now()->addDays(7);
I used carbon and this is what worked well for me
$week = Carbon::now()->subWeek();
$now = Carbon::now();
$domain_count = domain_details::get()->count();
$domain_alert = domain_details::where("domain_ex_date",">", $week)
->where("domain_ex_date", "<" ,$now)
->get();

trying to hide an event two days after it's passed

I'm trying to hide an event two days after it's passed in php (using a mysql query). There are two date options. Start date, and End date. I can't seem to figure out how to make the query work.
$query->select('*');
$query->from('#__events_items');
$query->where('date2 >= "'.$today.'"');
$query->where('date2 <= "'.$sixmths.'"');
$query->where('state = 1');
$query->order('date1 asc');
I've tried
$today = #date('Y-m-d');
$enddate = #date('Y-m-d',(strtotime(#date('Y-m-d')."+ 2 days")));
But obviously the end date won't be greater or equal to $enddate.. Any help would be greatly appreciated!
You can either modify today like so:
$today = date('Y-m-d', strtotime('-2 days'));
Or modify your query like so :
$query->select('*');
$query->from('#__events_items');
$query->where('date2 >= "'.$today.'" - INTERVAL 2 DAY');
$query->where('date2 <= "'.$sixmths.'"');
$query->where('state = 1');
$query->order('date1 asc');
I would say the second is probably better form since having $today represent two days ago would be nasty self documenting code.

Querying Data and Grouping by Day with Laravel

I run a website that stores images and users get a hotlink.
I want to be able to query records made in the last 7 days in the table containing the uploaded image data, extract the created_at column only, and compile the data into an array, similar to making an archive list for a blog.
I would like for the results to be presented like:
[
'Sunday' => 5,
'Monday' => 45,
'Tuesday' => 452,
...
]
Where each number represents the number of records created on each day. As long as I can output an array like that, I can handle the Javascript side easily.
Anybody have any suggestions?
EDIT
This is the code I've tried so far:
<?php
class Admin
{
public function getCreatedAtAttribute($value)
{
$this->attributes['created_at'] = Carbon::createFromFormat('Y-m-d H:i:s', $value);
}
public static function uploadsGraph()
{
$date = \Carbon\Carbon::now();
$uploads = Upload::select('created_at')->where('created_at', '>=', \Carbon\Carbon::now()->subWeek())->get();
foreach($uploads as $date)
{
echo $date->created_at . '<br>';
}
}
}
EDIT 2
Here's another version I tried, but that didn't work out well.
class Admin
{
public static function uploadsGraph()
{
$date = \Carbon\Carbon::now();
$uploadsByDay = DB::table('uploads')
->select(DB::raw('
YEAR(created_at) year,
MONTH(created_at) month,
MONTHNAME(created_at) month_name
'))
->groupBy('year')
->groupBy('month')
->orderBy('year', 'desc')
->orderBy('month', 'desc')
->get();
dd($uploadsByDay);
}
}
I'm assuming that the number next to each day of the week represents the number of records made on that day, with the entire dataset you want to query ranging only over the last 7 days.
The idea here is to select the count of items that were created on the same day (ignoring completely the timestamp portion of the created_at column), so we can use DB::raw inside of a select() call to aggregate all of the entries that were created on a specific day and then restrict that dataset to only those created in the last week. Something like this ought to work:
$data = Upload::select([
// This aggregates the data and makes available a 'count' attribute
DB::raw('count(id) as `count`'),
// This throws away the timestamp portion of the date
DB::raw('DATE(created_at) as day')
// Group these records according to that day
])->groupBy('day')
// And restrict these results to only those created in the last week
->where('created_at', '>=', Carbon\Carbon::now()->subWeeks(1))
->get()
;
$output = [];
foreach($data as $entry) {
$output[$entry->day] = $entry->count;
}
print_r($output);
Also note that I assumed this to be a 'rolling' week, where if today happens to be a Thursday, then the first date in the dataset will be the previous Thursday. It will not start on the most recent Sunday, if that is what you need. If it is, you can change the -where() condition to something like this:
...
->where('created_at', '>=', Carbon\Carbon::parse('last sunday'))
...
DB::table("clicks")
->select("id" ,DB::raw("(COUNT(*)) as total_click"))
->orderBy('created_at')
->groupBy(DB::raw("MONTH(created_at)"))
->get();

Laravel: How to get count of all records created within in current week as of yesterday

I want to get count of one week old created records as of yesterday in laravel using created_at time stamp, I have:
//week date range upto current day
$name_current_day = date("l");
$name_current_week = date("Y-m-d",strtotime('monday this week')).'to'.date("Y-m-d",strtotime("$name_current_day this week"));
//query to get count
foreach($name_list as $name){
//created in week
$data[$network->name.'_week'] = Info::select( DB::raw('DATE(`created_at`) as `date`'),DB::raw('COUNT(*) as `count`'))
->where('created_at', '>', $name_current_week)
->where('name',$name->f_name)
->groupBy('date')
->orderBy('date', 'DESC')
->lists('count', 'date');
}
When I run this query, I am not getting accurate results, Is this the cirrect way to get last 7 days records in Laravel.
You need to compare date() as well, and it's easier to use Carbon, though you don't need that. It's up to you.
EDIT: your question is a bit unclear, but it seems that you don't want week-old, but only current week's results.
Anyway, this will work for you:
// week old results:
// $fromDate = Carbon\Carbon::now()->subDays(8)->format('Y-m-d');
// $tillDate = Carbon\Carbon::now()->subDay()->format('Y-m-d');
// this week results
$fromDate = Carbon\Carbon::now()->subDay()->startOfWeek()->toDateString(); // or ->format(..)
$tillDate = Carbon\Carbon::now()->subDay()->toDateString();
Info::selectRaw('date(created_at) as date, COUNT(*) as count'))
->whereBetween( DB::raw('date(created_at)'), [$fromDate, $tillDate] )
->where('name',$name->f_name)
->groupBy('date')
->orderBy('date', 'DESC')
->lists('count', 'date');
You can use Carbon for this, which makes working with dates easier in Laravel. It's included with the framework. You can then do this:
$yesterday = Carbon::now()->subDays(1);
$one_week_ago = Carbon::now()->subWeeks(1);
foreach($name_list as $name){
//created in week
$data[$network->name.'_week'] = Info::select( DB::raw('DATE(`created_at`) as `date`'),DB::raw('COUNT(*) as `count`'))
->where('created_at', '>=', $one_week_ago)
->where('created_at', '<=', $yesterday)
->where('name',$name->f_name)
->groupBy('date')
->orderBy('date', 'DESC')
->lists('count', 'date');
}

Categories