plugin icon indicating copy to clipboard operation
plugin copied to clipboard

[Bug]: Helper phpDocs for date objects should be CarbonInterface|null not Carbon|null

Open SlyDave opened this issue 1 year ago • 8 comments

Bug description

When using the helper code generator, it writes the @property for date and datetime cast properties to be Carbon|null, rather than CarbonInterface|null - this means phpstan and other static analysers throw up errors when you're using CarbonImmutable or custom Date classes set via Date::use() extending CarbonInterface

Plugin version

8.1.2.233

Operating system

Windows

Steps to reproduce


use Carbon\Carbon;
use Carbon\CarbonImmutable;
use Carbon\CarbonInterface;

class MyModel extends Model {

    protected $fillable = ['date_at'];

    protected $casts = ['date_at' => 'datetime'];

    public function setDate(CarbonInterface $date) {
        $this->date_at = $date;
    }
}

$model = new MyModel();
$model->setDate(CarbonImmutable::now());
$model->setDate(Carbon::now());
  • Run generate helper code
  • Run phpstan (I ran it at level 8, but I think this triggers at 5 onwards)

phpstan: Property App\Models\MyModel::$date_at (Carbon\Carbon|null) does not accept Carbon\CarbonInterface.

This also errors if you force Laravel to use Immutable Dates by default:

use Carbon\CarbonImmutable;
use Illuminate\Support\Facades\Date;

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        Date::use(CarbonImmutable::class);
    }
}

Relevant log output

No response

SlyDave avatar Mar 07 '24 11:03 SlyDave

Hello. Laravel Idea analyzes service providers and understands Date::use call. So, it should work.

adelf avatar Mar 07 '24 12:03 adelf

Interestingly, if I delete the helper code, the types are correct:

image

SlyDave avatar Mar 07 '24 12:03 SlyDave

Hello. Laravel Idea analyzes service providers and understands Date::use call. So, it should work.

Unfortunately, it does not, if you set it to Carbon it works for Carbon but not CarbonInterface. It does however work if you set it to CarbonImmutable (as in that instance you wouldn't want to accept CarbonInterface)

The generated helper file is missing the \Carbon\CarbonInterface as you can see in example above when I delete the helper files.

SlyDave avatar Mar 07 '24 12:03 SlyDave

Well, if you put Date::use(CarbonInterface::class); to your service provider, it will change all date fields to use CarbonInterface. But it doesn't make sense, right? We can fix that by setting in the settings "Date class to use". What do you think?

adelf avatar Mar 07 '24 17:03 adelf

erm... You can't do Date::use(CarbonInterface::class);, it's an interface... Laravel won't be able to instantiate it when creating new models, A concrete implementation is required (at least something that resolves to one, be that a class-string, callback or a factory, all of which are supported, see src/Illuminate/Support/DateFactory.php L122 )

SlyDave avatar Mar 07 '24 17:03 SlyDave

That's why I wrote "But it doesn't make sense, right?")

adelf avatar Mar 07 '24 17:03 adelf

Well indeed! - more that it's fundamentally not possible, vs not making sense, but tamato, tomato ! :P

We can fix that by setting in the settings "Date class to use". What do you think?

That would be one way to resolve the issue, telling laravel-idea what date model is in use. However, given Date::use() exists, it can be read, if it isn't provided, the default can be assumed (\Carbon\Carbon|\Carbon\CarbonInterface|\Illuminate\Support\Carbon) and retain the normal detection to see if null needs to be added.

SlyDave avatar Mar 07 '24 17:03 SlyDave

Jep, have the same problem...

LWlook avatar Aug 22 '24 00:08 LWlook

New setting. I hope it will be enough. The update will be released soon.

Image

adelf avatar Mar 20 '25 15:03 adelf

10.1 is released.

adelf avatar Mar 24 '25 13:03 adelf