phplaravellaravel-10phpstan

PHPStan error - Property App\Models\Report::$succeeded_at (Carbon\Carbon|null) does not accept int|null


I am using PHPStan within a Laravel 10 app and have set this to quite a high level (good practice I guess) - I have run into a few errors and i'm trying to figure out the best way to resolve them.

 ------ ------------------------------------------------------------------------------------------ 
  Line   app/Actions/Reports/SetReportStatusAction.php                                             
 ------ ------------------------------------------------------------------------------------------ 
  17     Property App\Models\Report::$succeeded_at (Carbon\Carbon|null) does not accept int|null.  
<?php

declare(strict_types=1);

namespace App\Actions\Reports;

use App\Models\Report;
use Stripe\Reporting\ReportRun;

class SetReportStatusAction
{
    public function __invoke(Report $report): void
    {
        /** @var ReportRun $stripeObject */
        $stripeObject = $report->getStripeObject();
        $report->status = $stripeObject->status;
        $report->succeeded_at = $stripeObject->succeeded_at ?? null;
    }
}

Report.php

<?php

namespace App\Models;

// use statements hidden from view

class Report extends Model implements Transitionable
{
    use HasFactory, HasStates, HasStripeObject;

    protected $fillable = [
        'stripe_id',
        'report_type',
        'status',
        'parameters',
        'expires_at',
        'succeeded_at',
    ];

    protected $casts = [
        'parameters' => 'json',
        'expires_at' => 'datetime',
        'succeeded_at' => 'datetime',
    ];
}

The data succeeded_at comes from a webhook event and will be in the format similar to this - a timestamp

"succeeded_at": 1706786551

Expected outcome - PHPStan to detect no errors with the two files in question

Actual outcome - Recieve a phpstan error 'Property App\Models\Report::$succeeded_at (Carbon\Carbon|null) does not accept int|null.'


Solution

  • you should be able to fix it by converting the succeeded_at as Carbon date

    $report->succeeded_at = $stripeObject->succeeded_at ? 
        \Carbon\Carbon::createFromTimestamp($stripeObject->succeeded_at) : null;
    

    or cast your succeeded_at attribute as timestamp not datetime

    protected $casts = [
        'parameters' => 'json',
        'expires_at' => 'datetime',
        'succeeded_at' => 'timestamp',
    ];