Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Carbon Objects don't work with Datatables when using getCreatedAtAttribute #3160

Closed
sgtcoder opened this issue Jul 17, 2024 · 6 comments
Closed

Comments

@sgtcoder
Copy link

Summary of problem or feature request

When overriding the getter for the created_at on the model level, the column will display [object object] rather than the formatted datetime. By default, created_at passes as a Carbon object so it can be used in other areas and by being able to call ->format on it. The only work around I found for this is doing an editColumn and then formatting it from there. It just seems tedious that Datatables doesn't support Carbon objects.

Code snippet of problem

public function getCreatedAtAttribute()
    {
        return now()->parse($this->attributes['created_at'])->setTimezone('America/New_York');
    }

System details

  • Operating System
    AlmaLinux 8.7
  • PHP Version
    8.2
  • Laravel Version
    10
  • Laravel-Datatables Version
    10
@yajra
Copy link
Owner

yajra commented Jul 20, 2024

It seems related to this issue: #3156, I will try to fix it when I get the chance. Please do not hesitate to submit a PR if you can. Thanks!

@sgtcoder
Copy link
Author

I ended up making a Trait to use in the model for the time being, it's working pretty well

<?php

namespace App\Traits;

use \Illuminate\Support\Carbon;
use DateTimeInterface;
use Date;
use InvalidArgumentException;

trait UserTimezoneAware
{
    /**
     * Return a timestamp as DateTime object.
     *
     * @param  mixed  $value
     * @return \Illuminate\Support\Carbon
     */
    protected function asDateTime($value)
    {
        $timezone = get_user_timezone();

        // If this value is already a Carbon instance, we shall just return it as is.
        // This prevents us having to re-instantiate a Carbon instance when we know
        // it already is one, which wouldn't be fulfilled by the DateTime check.
        if ($value instanceof CarbonInterface) {
            return Date::instance($value)->timezone($timezone);
        }

        // If the value is already a DateTime instance, we will just skip the rest of
        // these checks since they will be a waste of time, and hinder performance
        // when checking the field. We will just return the DateTime right away.
        if ($value instanceof DateTimeInterface) {
            return new Carbon(
                $value->format('Y-m-d H:i:s.u'),
                $timezone
            );
        }

        // If this value is an integer, we will assume it is a UNIX timestamp's value
        // and format a Carbon object from this timestamp. This allows flexibility
        // when defining your date fields as they might be UNIX timestamps here.
        if (is_numeric($value)) {
            return Carbon::createFromTimestamp($value)->timezone($timezone);
        }

        // If the value is in simply year, month, day format, we will instantiate the
        // Carbon instances from that format. Again, this provides for simple date
        // fields on the database, while still supporting Carbonized conversion.
        if ($this->isStandardDateFormat($value)) {
            return Carbon::createFromFormat('Y-m-d', $value)->startOfDay()->timezone($timezone);
        }

        // Finally, we will just assume this date is in the format used by default on
        // the database connection and use that format to create the Carbon object
        // that is returned back out to the developers after we convert it here.
        try {
            $date = Carbon::createFromFormat(
                str_replace('.v', '.u', $this->getDateFormat()),
                $value
            )->timezone($timezone);
        } catch (InvalidArgumentException) {
            $date = false;
        }

        return $date ?: Date::parse($value);
    }
}

@yajra
Copy link
Owner

yajra commented Aug 17, 2024

I tried adding the getter and it is serialized just fine.

Before processing on https://github.com/yajra/laravel-datatables/blob/master/src/Utilities/Helper.php#L204:

array:18 [▼ // vendor/yajra/laravel-datatables-oracle/src/Utilities/Helper.php:209
  "id" => 1
  "name" => "Elaina Russel"
  "username" => null
  "email" => "joanne.jenkins@example.com"
  "email_verified_at" => "2024-08-17T03:21:35.000000Z"
  "two_factor_confirmed_at" => null
  "current_team_id" => null
  "profile_photo_path" => null
  "last_login_at" => null
  "password_changed_at" => null
  "blocked_at" => null
  "must_change_password" => false
  "can_be_impersonated" => true
  "created_at" => Illuminate\Support\Carbon @1723864896 {#1828 ▼
    #endOfTime: false
    #startOfTime: false
    #constructedObjectId: "00000000000007240000000000000000"
    -clock: null
    #localMonthsOverflow: null
    #localYearsOverflow: null
    #localStrictModeEnabled: null
    #localHumanDiffOptions: null
    #localToStringFormat: null
    #localSerializer: null
    #localMacros: null
    #localGenericMacros: null
    #localFormatFunction: null
    #localTranslator: null
    #dumpProperties: array:3 [▶]
    #dumpLocale: null
    #dumpDateProperties: null
    date: 2024-08-16 23:21:36.0 America/New_York (-04:00)
  }
  "updated_at" => "2024-08-17T03:21:36.000000Z"
  "created_by" => null
  "updated_by" => null
  "profile_photo_url" => "https://ui-avatars.com/api/?name=E+R&color=056EE9&background=F0F9FF"
]

After processing:

array:18 [▼ // routes/web.php:18
  "id" => 1
  "name" => "Elaina Russel"
  "username" => null
  "email" => "joanne.jenkins@example.com"
  "email_verified_at" => "2024-08-17T03:21:35.000000Z"
  "two_factor_confirmed_at" => null
  "current_team_id" => null
  "profile_photo_path" => null
  "last_login_at" => null
  "password_changed_at" => null
  "blocked_at" => null
  "must_change_password" => false
  "can_be_impersonated" => true
  "created_at" => "2024-08-16 23:21:36"
  "updated_at" => "2024-08-17T03:21:36.000000Z"
  "created_by" => null
  "updated_by" => null
  "profile_photo_url" => "https://ui-avatars.com/api/?name=E+R&amp;color=056EE9&amp;background=F0F9FF"
]

Please elaborate on the issue, I might be missing something.

Thanks!

@yajra
Copy link
Owner

yajra commented Aug 17, 2024

Whoops, I was testing using the latest version with #3163. Can you update your version and advise if the PR resolves this issue? Thanks!

Copy link

This issue is stale because it has been open for 30 days with no activity. Remove stale label or comment or this will be closed in 7 days.

@github-actions github-actions bot added the stale label Sep 17, 2024
Copy link

This issue was closed because it has been inactive for 7 days since being marked as stale.

@github-actions github-actions bot locked and limited conversation to collaborators Oct 9, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants