I have the users timezone stored (there is timezone
column in the users
DB table) and I want to display all $dates
attributes on all models in the user’s timezone, if authenticated.
I'm trying to find an elegant way to do this... Ideally, when there is something like this in Blade views:
{{ $post->created_at }}
OR
{{ $post->created_at->format('h:i:s A') }}
... for authenticated users it would be automatically in their timezones.
How would you handle this?
I'm thinking about creating one trait (for example, app/Traits/UserTimezoneAware.php
) and place there accessors that will simply return Carbon::createFromFormat('Y-m-d H:i:s', $value)->timezone(auth()->user()->timezone)
if the current user is authenticated. For example:
<?php
namespace App\Traits;
use Carbon\Carbon;
trait UserTimezoneAware
{
/**
* Get the created_at in the user's timezone.
*
* @param $value
* @return mixed
*/
public function getCreatedAtAttribute($value)
{
if (auth()->check()) {
return Carbon::createFromFormat('Y-m-d H:i:s', $value)->timezone(auth()->user()->timezone);
}
return Carbon::createFromFormat('Y-m-d H:i:s', $value);
}
/**
* Get the updated_at in the user's timezone.
*
* @param $value
* @return mixed
*/
public function getUpdatedAtAttribute($value) { ... }
}
But I'm not sure if this is good or bad to do (to create these accessros for the Laravel's $dates
attributes)?
Also, models will have different attributes specified in $dates
array: for example, User
model can have:
/**
* The attributes that should be mutated to dates.
*
* @var array
*/
protected $dates = [
'created_at',
'updated_at',
'last_login_at'
];
and Post
model can have:
protected $dates = [
'created_at',
'updated_at',
'approved_at',
'deleted_at'
];
Is it possible to dynamically create accessors in trait, based on the attirbutes specified in the $dates
array of a model that uses that trait?
Or maybe there is a better way to handle this, without accessors?
Documentation https://laravel.com/docs/5.5/eloquent-mutators#date-mutators
or see https://laravel.com/docs/5.5/eloquent-mutators#attribute-casting
for make it dinamically changed format your model add this method
One way (without accessors) is to use this trait:
When using this trait, we are overriding
asDateTime($value)
defined inConcerns\HasAttributes
trait (which is used inIlluminate\Database\Eloquent\Model
).This seems to work OK, I have not yet encountered any problems.
But I'm not sure if there are any risks or potential problems when doing this (when using this trait that overrides
asDateTime
method).