How to get distinct dates from a datetime field - laravel

I have this field valid_upto which is a datetime, so if I do:
$dates = Game::where('week', $this->week)
->distinct('valid_upto')
->pluck('valid_upto');
It returns an array like:
["2022-09-08 19:20:00",
"2022-09-11 12:00:00",
"2022-09-11 15:25:00",
"2022-09-11 19:20:00",
"2022-09-12 19:15:00",]
But I only want the date part, like:
["2022-09-08",
"2022-09-11",
"2022-09-12",]
is there a way to do it directly in Laravel's ORM? I don't want to use a rawSelect or similar, I know I could apply DATE('valid_upto') as d in mySQL and Postgres, but I really like to use "general" approaches.
This would work:
foreach ($dates as $i => $d) $dates[$i]=explode(" ", $dates[$i])[0]
$dates = $dates->unique()
But I think its an horrible solution
Something I would like to do, instead of using that foreach, applying a lambda (like in Python) to the Collection and then use the distinct. But I don't know if Laravel has lambdas.

In Laravel you can use Mutators and Casters to determine how certain columns are formatted when you access them. Laravel applies the casting when the model is serialized to json or to an array. So your query could become:
$dates = Game::where('week', $this->week)
->distinct('valid_upto')
->get('valid_upto')
->toArray();
And if you apply a caster on your Game model like so:
protected $casts = [
'valid_upto' => 'datetime:Y-m-d',
];
that should get you a collection of the dates you want in the format you want.

Related

Error Call to a member function where() on array Laravel

I want to do filtering from the data that I display, but there is a problem when I add where to my data.
the plan in the future I want to add if isset $request name, date and others. but was constrained at this one point.
Thank you for helping to answer in advance
$matchs =Matchs::where('type', 'sparring')->where('status','Pending')->whereNull('deleted_at')->get()->toArray();
$data=[];
foreach ($matchs as $key) {
$lawan = Matchs::where('id', $key['id'])->first()->ToArray();
$pertandingan = Sparring::where('match_id', $key['id'])->first()->ToArray();
$dua_arah = MatchTwoTeam::where('match_id', $key['id'])->first()->ToArray();
$tim = Team::where('id', $dua_arah['home_team'])->first()->ToArray();
$transfer['name']=$tim['name'];
$transfer['city']=$lawan['city'];
$transfer['field_cost']=$pertandingan['field_cost'];
$transfer['referee_cost']=$pertandingan['referee_cost'];
$transfer['logo_path']=$tim['logo_path'];
$transfer['nama_lapangan']=$lawan['nama_lapangan'];
$transfer['date']=$lawan['date'];
array_push($data,$transfer);
array_push($data,$pertandingan);
}
$data->where('name', 'LIKE', '%'.'football'.'%')->get()->toArray();
$data = array_search('football', array_column($data, 'name'));
$tittle="Sparring";
return view('mode.sparring',[
'tittle' => $tittle,
'data' => $data,
]);
You are trying to call where in an array which is not possible.
As you can see in the first line of your code you are calling where method in your model class. Like Matchs::where('type', 'sparring'), this is possible because Matchs is a Model class.
Now you can run where even if you are using array. You can convert that day in collection and then use array on that collection.
As below:
collect($data)->where('name', 'football')->toArray();
Here collect() will convert the $data array to collectio and then run the where() method in collectio then toArray() will change it back to array. But unfortunately there is no like operator possible in collection class. See the list of available method in Laravel collection here: https://laravel.com/docs/8.x/collections#available-methods
There is a way to do what you are trying to do. As far as I understand you want to filter the Matches where the Team name has footbal in it. You can do it like this:
Matchs::where('type', 'sparring')
->where('status','Pending')
->whereNull('deleted_at')
->whereHas('team', function($team) {
return $team->where('name', 'LIKE', '%'.'football'.'%')
})
->get()
->toArray();
So, here we can get the only those Mathes that has the Team that has the name contains football.
Few suggestion for you as seems you are new in Laravel:
Model name should be singular instead of plural, so the model class Matchs should be Match. Your name for team's model is Team is correct.
Avoid using toArray() because you won't need it. When you call get() it will return object of collection which more readable and powerful then array in most cases.
The code I suggested to use the like using whereHas will only work if you have propery defined your team relation in your Matchs class. So, defining your relationships in model is also important. If you do so, you don't even need the for loop and all those where in other model in that loop. You can do it in one query with all the relationships.

laravel get data without applying casts

I am doing
Model::get()->toArray()
to get all the data from my table but the model has a cast on the dates.
protected $casts = ['date' => 'datetime:D, M d Y'];
I want to be able to get all the data without applying the cast and just the original datetime format. Is there a way to control when the cast is applied.
Laravel 7+
As Sam mentioned for Laravel 7+ you can use:
$model->getRawOriginal('created_at')
You can get all attributes as they are, by using
Model::get()->transform(function ($item) {
return $item->getOriginal();
}))->toArray();
Also can use getOriginal() as
$model->getOriginal('created_at')
on any model to get the original value whenever it's needed.
Note : getOriginal() will include all the $hidden attributes of the model.
getOriginal('date') and getRawOriginal('date') return the unmodified values !
If you want to get the current value without cast, you can use getAttributes()['date']

Laravel treating decimal as string

Im trying to make the next eloquent query
$result = $result->where('money','>=',(float)$moneyFilter);
The money column in my database its DECIMAL(11,2), when I run the query it returns an empty array, when I go over php artisan tinker and see the column money, it's a string value "11.1".
I would like to filter the $result collection to have values over $moneyFilter.
Thanks
You need to define in your model which fields need to be cast to a primitive attribute.
protected $casts = ['my_decimal' => 'float'];
There is a really good explanation here:
https://mattstauffer.com/blog/laravel-5.0-eloquent-attribute-casting/
Also there is an explanation in the docs:
https://laravel.com/docs/5.5/eloquent-mutators#attribute-casting

How to set field for ::create in Laravel?

I use this method to create new row in DB:
$input = $request->all();
return Recipient::create([$input]);
How I can add additional field to $input with an value?
I tried:
$input["user_id"] = Auth::id();
But when I display query INSERT, I can not see field user_id
The problem here is that you probably don't set $fillable property in Recipient model. You should add user_id there:
$fillable = [ ..., 'user_id'];
However merging input is usually not the best way to deal with such things. If you have set relationships properly, it should be possible to do something like this:
Auth::user()->recipients()->create($request->all());
Update
Like #Marcin Nabialek said: add 'user_id' to the $fillable array. And, his solution is cleaner.
Merge
The method merge is what you're looking for: Merge new input into the current request's input array.
$request->merge(['user_id' => Auth::user()->id]);
Recipient::create($request->all());
See the api documentation here: https://laravel.com/api/5.2/Illuminate/Http/Request.html#method_merge
I'm still not sure what exactly you are looking for. Suppose you have 2-3 fields user_id, title, content. For inserting into the database you need to do following:
$input = new Recipient(['title'=>'You title', 'content'=>'Your content']);
$input->save();
It will save two fields with the incremented user_id.
Bro, You're using wrong method,
Try this one:
$input["user_id"] =Auth::user()->id;

Get distinct dates from json array joomla

My component saves json array in database :
so i want to get distinct dates from all the fields.
database field contains values like this :
a:3:{i:0;s:16:"2013-02-24 00:00";i:1;s:16:"2013-02-23 00:00";i:2;s:16:"2013-02-22 00:00";}
What you have there is serialized data, not json encoded. I don't believe there is a way to grab just the dates out of the database using a mysql query (hence most people recommending that you don't store data in a serialized or even a json form).
You would want to grab the data from the database maybe like so (with the $query variable being the query you need to get data from the database. Since I have no idea what your database looks like, I'm not going to write the query)
$rows = JFactory::getDbo()->setQuery($query)->loadObjectList();
foreach ($rows as $row) {
$dates = unserialize($row->date_column);
// do something with the $dates variable, which is now an array of the three dates.
}

Resources