Show list of registered users base on current month using laravel - laravel

Im new to laravel and im tryin to learn the fundamentals of it. My question is how can I display all the registered users that is registered only on the current month.

$from = now()->startOfMonth(); // first date of the current month
$to = now();
$usersRegisteredThisMonth = User::whereBetween('created_at', [$from, $to])->get();

There is a simple way of doing it.
Just use this code
User::whereMonth('created_at', now()->month) // checking if the month of created_at is current month
->whereYear('created_at', now()->year) // checking if the year of created_at is current year
->get();
This line will give you Users from current month.

Nobody explained that these queries might be put in user model with local scope scopeWith magic method. I assume you read docs from top to bottom.
Simple example:
public function scopeRegisteredLastMonth($query){ return $query->whereBetween... }
Laravel Local Scope
You can specyficy additional arguments for this method.
The final call in controller will look like this:
$lastMonthUsers = User::registeredLastMonth()->get();
This function should be set to something like 'public function withRegisteredBetween($query, $date_start, $date_end) and return query based on date range.
PS: Don't use DB:: when you can use Model::method() or Model::query()->method()
PS2: for date management I advise you to install carbon, it's an additional addon - sometimes it's easy, sometimes not, overall not bad.

You could use the users table with a whereBetween clause like this:
$from = date('2022-01-05 00:00:00');
$to = date('2022-31-05 00:00:00');
$usersRegisteredThisMonth = DB::table('users')->
whereBetween('created_at', [$from, $to])->get();

Related

Any reason why a model's fields not updating despite an update call?

In Laravel 5.3 I am, using Model events to take certain actions. For the most part, things are working fine, just one place in the program flow where data is not updating.
Here is the whole story:
I have a database structure with courses and weeks. So Course 1 with Week1, Week2, etc.
Then to repeat a given course I also have courseinstance and weekinstance which contain date info for given instances of courses and weeks.
I am using Angular in the backend to handle CRUD, and when I create a course it automatically creates a courseinstance where a start_date and end_date are null.
The code for that in the course API controller is
$thiscourse= \App\Courses::create(Input::all());
After that the course model executes this:
public static function boot() {
parent::boot();
static::created(function($course) {
// add first instance of this course - dates will be null at this point
$instance = new Coursesinstance;
$instance->course_id = $course->id;
$instance->save();
});
}
That is successful. Then in my backend, I add a week to the course (which is for descriptive data about the week's topic) and that creates a first instance of the week where there are a start and end date. In the API week controller first we have this:
$week = \App\Week::create(Input::all());
Then that triggers create event on the model and we go to:
static::created(function($week) {
// add first instance of this week
$instance = new Weekinstance;
$instance->week_id = $week->id;
$instance->weekstart = $week->weekstart;
$instance->zoomstart = $week->zoomstart;
$coursesinstance_id = DB::table('coursesinstance')
->select('id')
->where('course_id', $week->courses->id)
->first();
$instance->coursesinstance_id = $coursesinstance_id->id;
$instance->save();
});
This is a success, things looking fine in the database, all relationships proper, various id's just as they should be.
Now since a new week instance is created, we go to this in the Weekinstance model so that I can look at all weeks in the instance and update the course instance start and end dates.
static::created(function($weekinstance) {
// get all week instances corresponding to this course instance
$weekinstances = DB::table('weekinstance')
->select('*')
->where('coursesinstance_id', $weekinstance->coursesinstance_id)
->get();
$weekstarts=array();
foreach ($weekinstance as $instance)
{
$weekstart = $instance->weekstart;
$weekstarts[].=$weekstart;
}
$dates = array_map('strtotime', $weekstarts);
$startdate = min($dates);
$enddate = strtotime("+7 day", max($dates));
// update start and end date for the course instance
$result = \App\Coursesinstance::where('id', $weekinstance->coursesinstance_id)
->update([
'start_date' => $startdate,
'end_date' => $enddate
]);
});
And here is where things break down. The week is successfully created, the weekinstance is created, but the update call above just doesn't set the start_date and end_date of the courseinstance.
I have ran in a debugger, and at the moment of the update, all seems well. A $startdate and $enddate variable are created as timestamps, the where clause is indeed returning the course instance, the return result is a 1, so Laravel is not returning any errors, and in log file no issues. start_date and end_date are fillable on the model. Everything truly looks normal.
The date fields are are stored as TIMESTAMP in MySQL. It does not accept Unix timestamp's as an argument. So you must convert the timestamp's into the correct format, before updating. One way to do this:
->update([
'start_date' => Carbon\Carbon::createFromTimestamp($startdate),
'end_date' => Carbon\Carbon::createFromTimestamp($enddate)
]);
Ok, after spending so much time on this I finally realized the problem is that I was passing my timestamp values directly to the query builder. Little did I know that MYSQL expects a timestamp as a date string. I thought the data type datetime was meant for strings and that a timestamp, as name suggests, could be used for an actual timestamp. Crazy thinking, I know.
So here is how I had to create the "timestamps":
$startdate = date('Y-m-d H:i:s',min($dates));
$enddate = date('Y-m-d H:i:s',strtotime("+7 day", max($dates)));
So in other words, 180 degrees away from what I would consider logical based on definition of a timestamp.
Thanks,
Brian

Laravel 5.4: How do I get records from just this week?

To get all records of the current day, I did
$dt = Carbon::now();
$dataToday = Data::whereDay('created_at', $dt->day)->get();
To get records from this week, I tried the following but without success.
$dataThisWeek = Data::where('created_at', $dt->weekOfYear);
$dataThisWeek = Data::where('created_at', $dt->weekOfMonth);
$dataThisWeek = Data::whereWeek('created_at', $dt->week);
How do we approach this with Eloquent and Carbon (preferably) or a native MYSQL function?
Try this:
Data::whereBetween('created_at', [Carbon::now()->startOfWeek(), Carbon::now()->endOfWeek()])->get();
To set the week start/end:
Carbon::setWeekStartsAt(Carbon::SUNDAY);
Carbon::setWeekEndsAt(Carbon::SATURDAY);
You can also try
$dataThisWeek = Data::where(\DB::raw("WEEKOFYEAR(created_at)"), $dt->weekOfYear)->get();
For some reason using Laravel 7.4^ the accepted solution above is not working on my end. No data is shown, to fix it I added a format like this:
$now = Carbon::now();
Data::whereBetween("created_at", [
$now->startOfWeek()->format('Y-m-d'), //This will return date in format like this: 2022-01-10
$now->endOfWeek()->format('Y-m-d')
])->get();
To complete #user320487 answer:
To avoid conflict between different third-party libraries, static setters should not be used. Use $weekEndsAt optional parameter instead when using endOfWeek method.
Data::whereBetween('created_at', [Carbon::now()->startOfWeek(Carbon::SUNDAY), Carbon::now()->endOfWeek(Carbon::SATURDAY)])->get();
You can also use the 'first_day_of_week' locale setting to change the start of week according to current locale selected and implicitly the end of week.

Laravel query for showing records starting soonest but not records where date has passed

I'm a little new so I only know the basics. I have a course table where it has the start_date of a course (timestamp) and I would like to show the courses starting closes to the current date but not courses that have passed (e.g yesterdays courses).
I also need to not do this with a scope.
My model is App\Course. My current code is
$course = Course::latest()->take(6)->get());
Could anyone help? Thanks!
Try this:
$course = Course::where('start_date', '>', Carbon::now())->orderBy('start_date', 'desc')->take(6)->get());
It will work if you'll add start_date to a $dates variable.

how to select one month back records from data base in laravel

how select one month back records from current date from database in laravel. I am trying this code.
This is controller code.
class LoginHistoryController extends Controller {
public function index()
{
$login_history = LoginHistory::where('login_date','BETWEEN', '(CURDATE() -
INTERVAL 10 DAY) AND CURDATE()' )->get();
}
}
but i am getting error.
I will have a approach something like this. First I will calculate the date like
$today = date('Y-m-d');
$date = date_create($today);
date_sub($date, date_interval_create_from_date_string("30 days"));
$beforeOneMonth = date_format($date, "Y-m-d");
You should have the intended value in $beforeOneMonth by now. Now you can compare it in anyway you like whether you use IN operator or >=. For eg.
$login_history = LoginHistory::where('login_date','>=', $beforeOneMonth)->get();
Give it a try. If you are storing date in some other format, you can do your own tricks to format the date and do the thing
Another way to do it would be with whereRaw:
$login_history = LoginHistory::whereRaw(
'login_date BETWEEN (CURDATE() - INTERVAL 10 DAY) AND CURDATE()'
)->get();
Note that whereRaw has the side effect of making your code less portable since you're using SQL that might be specific to your database server. But sometimes you just can't do what you would like using the query builder.

How to set model attribute to current date format using MySQL functions?

I have a model Users And every time user logges in loggedin_at field is updated.
$user = User::find(1);
$user->token = md5(time());
$user->loggedin_at = date('Y-d-m H:i:s');
$user->save();
return $user;
But I know from experience already that sometimes there is difference between MySQL time and PHP time. So when you use comparisons like time > NOW() - INTERVAL 1 HOUR it might now work correctly because you set date from PHP and compare it from MySQL.
Anyway my question is I want to use NOW() to update my date. I try
$user->loggedin_at = DB::raw('NOW()');
But that does not work. By looking into Eloquent source I've managed out this to work
$user->loggedin_at = new \Carbon\Carbon();
This is what Eloquent uses to alter times.
How to use NOW() to set time?
Should I use NOW() or better continue with Carbon?
It's better to use Carbon, it's what it's there for. Laravel uses it out of the box, and uses it within created_at and updated_at.
If you use Carbon, also, you can synchronize PHP's time and Carbon's "NOW" using the timezone configuration inside of config/app.php.
Furthermore, if you want to change the result you get from Carbon, you can do something like:
$now = Carbon::now(new DateTimeZone('Europe/London'));
//can also be passed as a string
$now = Carbon::now('Europe/London');

Resources