mirror of
https://github.com/barryvdh/laravel-ide-helper.git
synced 2026-08-18 01:57:13 +00:00
support Castables (#1287)
This commit is contained in:
@@ -9,6 +9,7 @@ All notable changes to this project will be documented in this file.
|
|||||||
|
|
||||||
### Added
|
### Added
|
||||||
- Add support for cast types `decimal:*`, `encrypted:*`, `immutable_date`, `immutable_datetime`, `custom_datetime`, and `immutable_custom_datetime` [#1262 / miken32](https://github.com/barryvdh/laravel-ide-helper/pull/1262)
|
- Add support for cast types `decimal:*`, `encrypted:*`, `immutable_date`, `immutable_datetime`, `custom_datetime`, and `immutable_custom_datetime` [#1262 / miken32](https://github.com/barryvdh/laravel-ide-helper/pull/1262)
|
||||||
|
- Add support for custom casts that using `Castable` [#1287 / binotaliu](https://github.com/barryvdh/laravel-ide-helper/pull/1287)
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- Fix recursively searching for `HasFactory` and `Macroable` traits [\#1216 / daniel-de-wit](https://github.com/barryvdh/laravel-ide-helper/pull/1216)
|
- Fix recursively searching for `HasFactory` and `Macroable` traits [\#1216 / daniel-de-wit](https://github.com/barryvdh/laravel-ide-helper/pull/1216)
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ use Composer\Autoload\ClassMapGenerator;
|
|||||||
use Doctrine\DBAL\Exception as DBALException;
|
use Doctrine\DBAL\Exception as DBALException;
|
||||||
use Doctrine\DBAL\Types\Type;
|
use Doctrine\DBAL\Types\Type;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Contracts\Database\Eloquent\Castable;
|
||||||
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
|
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
|
||||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||||
@@ -366,6 +367,9 @@ class ModelsCommand extends Command
|
|||||||
} elseif (Str::startsWith($type, 'encrypted:')) {
|
} elseif (Str::startsWith($type, 'encrypted:')) {
|
||||||
$type = Str::after($type, ':');
|
$type = Str::after($type, ':');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$params = [];
|
||||||
|
|
||||||
switch ($type) {
|
switch ($type) {
|
||||||
case 'encrypted':
|
case 'encrypted':
|
||||||
$realType = 'mixed';
|
$realType = 'mixed';
|
||||||
@@ -412,6 +416,9 @@ class ModelsCommand extends Command
|
|||||||
$type = strtok($type, ':');
|
$type = strtok($type, ':');
|
||||||
$realType = class_exists($type) ? ('\\' . $type) : 'mixed';
|
$realType = class_exists($type) ? ('\\' . $type) : 'mixed';
|
||||||
$this->setProperty($name, null, true, true);
|
$this->setProperty($name, null, true, true);
|
||||||
|
|
||||||
|
$params = strtok(':');
|
||||||
|
$params = $params ? explode(',', $params) : [];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -419,6 +426,7 @@ class ModelsCommand extends Command
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$realType = $this->checkForCastableCasts($realType, $params);
|
||||||
$realType = $this->checkForCustomLaravelCasts($realType);
|
$realType = $this->checkForCustomLaravelCasts($realType);
|
||||||
$realType = $this->getTypeOverride($realType);
|
$realType = $this->getTypeOverride($realType);
|
||||||
$this->properties[$name]['type'] = $this->getTypeInModel($model, $realType);
|
$this->properties[$name]['type'] = $this->getTypeInModel($model, $realType);
|
||||||
@@ -1141,9 +1149,9 @@ class ModelsCommand extends Command
|
|||||||
*
|
*
|
||||||
* @return null|string
|
* @return null|string
|
||||||
*/
|
*/
|
||||||
protected function getReturnTypeFromDocBlock(\ReflectionMethod $reflection)
|
protected function getReturnTypeFromDocBlock(\ReflectionMethod $reflection, \Reflector $reflectorForContext = null)
|
||||||
{
|
{
|
||||||
$phpDocContext = (new ContextFactory())->createFromReflector($reflection);
|
$phpDocContext = (new ContextFactory())->createFromReflector($reflectorForContext ?? $reflection);
|
||||||
$context = new Context(
|
$context = new Context(
|
||||||
$phpDocContext->getNamespace(),
|
$phpDocContext->getNamespace(),
|
||||||
$phpDocContext->getNamespaceAliases()
|
$phpDocContext->getNamespaceAliases()
|
||||||
@@ -1260,6 +1268,32 @@ class ModelsCommand extends Command
|
|||||||
return $keyword;
|
return $keyword;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function checkForCastableCasts(string $type, array $params = []): string
|
||||||
|
{
|
||||||
|
if (!class_exists($type) || !interface_exists(Castable::class)) {
|
||||||
|
return $type;
|
||||||
|
}
|
||||||
|
|
||||||
|
$reflection = new \ReflectionClass($type);
|
||||||
|
|
||||||
|
if (!$reflection->implementsInterface(Castable::class)) {
|
||||||
|
return $type;
|
||||||
|
}
|
||||||
|
|
||||||
|
$cast = call_user_func([$type, 'castUsing'], $params);
|
||||||
|
|
||||||
|
if (is_string($cast) && !is_object($cast)) {
|
||||||
|
return $cast;
|
||||||
|
}
|
||||||
|
|
||||||
|
$castReflection = new ReflectionObject($cast);
|
||||||
|
|
||||||
|
$methodReflection = $castReflection->getMethod('get');
|
||||||
|
|
||||||
|
return $this->getReturnTypeFromReflection($methodReflection) ??
|
||||||
|
$this->getReturnTypeFromDocBlock($methodReflection, $reflection);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $type
|
* @param string $type
|
||||||
* @return string|null
|
* @return string|null
|
||||||
|
|||||||
+33
@@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts;
|
||||||
|
|
||||||
|
use Illuminate\Contracts\Database\Eloquent\Castable;
|
||||||
|
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
|
||||||
|
|
||||||
|
class CastableReturnsAnonymousCaster implements Castable
|
||||||
|
{
|
||||||
|
public static function castUsing(array $arguments)
|
||||||
|
{
|
||||||
|
return new class() implements CastsAttributes {
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
* @return CastedProperty
|
||||||
|
*/
|
||||||
|
public function get($model, string $key, $value, array $attributes)
|
||||||
|
{
|
||||||
|
return new CastedProperty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function set($model, string $key, $value, array $attributes)
|
||||||
|
{
|
||||||
|
// TODO: Implement set() method.
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts;
|
||||||
|
|
||||||
|
use Illuminate\Contracts\Database\Eloquent\Castable;
|
||||||
|
|
||||||
|
class CastableReturnsCustomCaster implements Castable
|
||||||
|
{
|
||||||
|
public static function castUsing(array $arguments)
|
||||||
|
{
|
||||||
|
return CustomCasterWithDocblockReturn::class;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,6 +4,8 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Models;
|
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Models;
|
||||||
|
|
||||||
|
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CastableReturnsAnonymousCaster;
|
||||||
|
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CastableReturnsCustomCaster;
|
||||||
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CustomCasterWithDocblockReturn;
|
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CustomCasterWithDocblockReturn;
|
||||||
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CustomCasterWithDocblockReturnFqn;
|
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CustomCasterWithDocblockReturnFqn;
|
||||||
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CustomCasterWithNullablePrimitiveReturn;
|
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CustomCasterWithNullablePrimitiveReturn;
|
||||||
@@ -31,6 +33,8 @@ class CustomCast extends Model
|
|||||||
'casted_property_with_param' => CustomCasterWithParam::class . ':param',
|
'casted_property_with_param' => CustomCasterWithParam::class . ':param',
|
||||||
'casted_property_with_static_return_docblock' => SelfCastingCasterWithStaticDocblockReturn::class,
|
'casted_property_with_static_return_docblock' => SelfCastingCasterWithStaticDocblockReturn::class,
|
||||||
'casted_property_with_this_return_docblock' => SelfCastingCasterWithThisDocblockReturn::class,
|
'casted_property_with_this_return_docblock' => SelfCastingCasterWithThisDocblockReturn::class,
|
||||||
|
'casted_property_with_castable' => CastableReturnsCustomCaster::class,
|
||||||
|
'casted_property_with_anonymous_cast' => CastableReturnsAnonymousCaster::class,
|
||||||
'extended_casted_property_with_static_return_docblock' => ExtendedSelfCastingCasterWithStaticDocblockReturn::class,
|
'extended_casted_property_with_static_return_docblock' => ExtendedSelfCastingCasterWithStaticDocblockReturn::class,
|
||||||
'extended_casted_property_with_this_return_docblock' => ExtendedSelfCastingCasterWithThisDocblockReturn::class,
|
'extended_casted_property_with_this_return_docblock' => ExtendedSelfCastingCasterWithThisDocblockReturn::class,
|
||||||
'casted_property_with_static_return_docblock_and_param' => SelfCastingCasterWithStaticDocblockReturn::class . ':param',
|
'casted_property_with_static_return_docblock_and_param' => SelfCastingCasterWithStaticDocblockReturn::class . ':param',
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Models;
|
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Models;
|
||||||
|
|
||||||
|
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CastableReturnsAnonymousCaster;
|
||||||
|
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CastableReturnsCustomCaster;
|
||||||
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CustomCasterWithDocblockReturn;
|
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CustomCasterWithDocblockReturn;
|
||||||
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CustomCasterWithDocblockReturnFqn;
|
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CustomCasterWithDocblockReturnFqn;
|
||||||
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CustomCasterWithNullablePrimitiveReturn;
|
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CustomCasterWithNullablePrimitiveReturn;
|
||||||
@@ -34,6 +36,8 @@ use Illuminate\Database\Eloquent\Model;
|
|||||||
* @property ExtendedSelfCastingCasterWithStaticDocblockReturn $extended_casted_property_with_static_return_docblock
|
* @property ExtendedSelfCastingCasterWithStaticDocblockReturn $extended_casted_property_with_static_return_docblock
|
||||||
* @property ExtendedSelfCastingCasterWithThisDocblockReturn $extended_casted_property_with_this_return_docblock
|
* @property ExtendedSelfCastingCasterWithThisDocblockReturn $extended_casted_property_with_this_return_docblock
|
||||||
* @property SelfCastingCasterWithStaticDocblockReturn $casted_property_with_static_return_docblock_and_param
|
* @property SelfCastingCasterWithStaticDocblockReturn $casted_property_with_static_return_docblock_and_param
|
||||||
|
* @property \Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CastedProperty $casted_property_with_castable
|
||||||
|
* @property \Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CastedProperty $casted_property_with_anonymous_cast
|
||||||
* @property \Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CastedProperty $cast_without_property
|
* @property \Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CastedProperty $cast_without_property
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|CustomCast newModelQuery()
|
* @method static \Illuminate\Database\Eloquent\Builder|CustomCast newModelQuery()
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|CustomCast newQuery()
|
* @method static \Illuminate\Database\Eloquent\Builder|CustomCast newQuery()
|
||||||
@@ -66,6 +70,8 @@ class CustomCast extends Model
|
|||||||
'casted_property_with_param' => CustomCasterWithParam::class . ':param',
|
'casted_property_with_param' => CustomCasterWithParam::class . ':param',
|
||||||
'casted_property_with_static_return_docblock' => SelfCastingCasterWithStaticDocblockReturn::class,
|
'casted_property_with_static_return_docblock' => SelfCastingCasterWithStaticDocblockReturn::class,
|
||||||
'casted_property_with_this_return_docblock' => SelfCastingCasterWithThisDocblockReturn::class,
|
'casted_property_with_this_return_docblock' => SelfCastingCasterWithThisDocblockReturn::class,
|
||||||
|
'casted_property_with_castable' => CastableReturnsCustomCaster::class,
|
||||||
|
'casted_property_with_anonymous_cast' => CastableReturnsAnonymousCaster::class,
|
||||||
'extended_casted_property_with_static_return_docblock' => ExtendedSelfCastingCasterWithStaticDocblockReturn::class,
|
'extended_casted_property_with_static_return_docblock' => ExtendedSelfCastingCasterWithStaticDocblockReturn::class,
|
||||||
'extended_casted_property_with_this_return_docblock' => ExtendedSelfCastingCasterWithThisDocblockReturn::class,
|
'extended_casted_property_with_this_return_docblock' => ExtendedSelfCastingCasterWithThisDocblockReturn::class,
|
||||||
'casted_property_with_static_return_docblock_and_param' => SelfCastingCasterWithStaticDocblockReturn::class . ':param',
|
'casted_property_with_static_return_docblock_and_param' => SelfCastingCasterWithStaticDocblockReturn::class . ':param',
|
||||||
|
|||||||
Reference in New Issue
Block a user