mysql point columns casted as MatanYadaev\EloquentSpatial\Objects\Point are type hinted as Geometry
vazaha-nl opened this issue · 1 comments
Versions:
- ide-helper Version: v2.13.0
- Laravel Version: v10.25.2
- PHP Version: 8.2.11
Question:
I have a mysql table containing a point (for coordinates) column. In the corresponding model I cast this column to the Matan\Yadaev\EloquentSpatial\Objects\Point
class from https://github.com/MatanYadaev/laravel-eloquent-spatial.
protected $casts = [
'location' => Point::class,
];
When I generate the docblocks using ide-helper, the property gets type hinted as follows:
* @property \MatanYadaev\EloquentSpatial\Objects\Geometry|null $location
I would expect:
* @property \MatanYadaev\EloquentSpatial\Objects\Point|null $location
The Point class is a subclass of Geometry. But only the Point class has public latitude
and longitude
properties, which my IDE now doesn't know about.
Is it possible in some way to enforce that the $location property is type hinted as Point i/o Geometry? I tried editing the ide_helper config file, adding:
'interfaces' => [
MatanYadaev\EloquentSpatial\Objects\Geometry::class => MatanYadaev\EloquentSpatial\Objects\Point::class,
],
but that doesn't seem to work. Also tried the other way around.
So I did some further research myself and I found the cause, and also a workaround. The cause is not a bug in my opinion but just a result of how things work in ide-worker and how things are implemented in the EloquentSpatial lib.
The cause is that the Point::class
cast is resolved to Geometry::class
because all share the same Cast class, \MatanYadaev\EloquentSpatial\GeometryCast
. The get()
method has Geometry|null
as return value, see https://github.com/MatanYadaev/laravel-eloquent-spatial/blob/master/src/GeometryCast.php#L34. And that return type is used to get the correct type. See https://github.com/barryvdh/laravel-ide-helper/blob/master/src/Console/ModelsCommand.php#L1379
The workaround is to add the following to the type_overrides
array in config/ide-helper.php
:
'type_overrides' => [
// ...
'\MatanYadaev\EloquentSpatial\Objects\Geometry|null' => '\MatanYadaev\EloquentSpatial\Objects\Point|null',
],
and now it works, for my limited case. This is a hack because it only works as long as I don't use any of the other Geometry
subclasses (like fe Polygon
) as eloquent cast, because all other subclasses will be resolved to Point
which would be even more wrong.
I wouldn't know a better solution and I even doubt whether this is solvable at all for all cases.