soyhuce/next-ide-helper

Laravel ide helper的强化版本

资助包维护!
soyhuce

0.19.4 2024-08-30 20:54 UTC

README

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status GitHub PHPStan Action Status Total Downloads

此包旨在成为一个易于扩展的ide-helper生成器。

它受到了barryvdh/laravel-ide-helper的优秀工作的启发。

它为Eloquent魔法(模型属性、作用域、关系等)、可宏化类的注册宏、容器实例等提供补全。

安装

您应该使用composer安装此包

composer require --dev soyhuce/next-ide-helper

您可能希望发布配置文件

php artisan vendor:publish --tag=next-ide-helper-config

您完成了!

使用

模型

命令php artisan next-ide-helper:models将生成多个元素以帮助您的ide理解您正在做什么。此包需要您有权访问已迁移的数据库。

它将为您的类添加文档注释,并创建一个_ide_models.php文件。此文件不能被包含,而只能由您的ide进行分析。

属性

该命令解析数据库中的模型属性。它们被添加到模型类的文档注释中。如果属性有类型转换,包将正确地转换属性。

/**
 * @property int $id
 * @property string $name
 * @property string $email
 * @property \Illuminate\Support\Carbon|null $email_verified_at
 * @property string $password
 * @property string|null $remember_token
 * @property \Illuminate\Support\Carbon $created_at
 * @property \Illuminate\Support\Carbon $updated_at
 */
class User extends \Illuminate\Database\Eloquent\Model
{
    // ...
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];
}

属性转换也将与自定义类型转换一起工作

use App\Email;

class EmailCast implements \Illuminate\Contracts\Database\Eloquent\CastsAttributes
{
    public function get($model, $key, $value, $attributes): Email
    {
        return new Email($value);
    }
    
    // ...
}

class User extends Model
{
    protected $casts = [
        'email' => EmailCast::class,
    ];
}

这将产生@property \App\Email $email

请注意,类型必须定义为返回类型或在get方法的文档注释中的@return

该命令还会添加来自访问器的属性作为只读属性

/**
 * @property-read string $upper_name
 */
class User extends Model
{
    public function getUpperNameAttribute(): string
    {
        return Str::upper($this->name);
    }   
}

自定义集合

如果您的模型定义了自定义集合,该命令将在模型的文档注释中添加all方法以重新定义返回类型

use \App\Collections\UserCollection;

/**
 * @method static \App\Collections\UserCollection all(array|mixed $columns = ['*'])
 */
class User extends Model
{
    public function newCollection(array $models = []): UserCollection
    {
        return new UserCollection($models);
    }
}

查询构建器

如果您的模型定义了自定义Eloquent构建器,该命令将在模型文档注释中添加一些标记。

use App\Builder\UserBuilder;
/**
 * @method static \App\Builder\UserBuilder query()
 * @mixin \App\Builder\UserBuilder
 */
class User extends Model
{
    public function newEloquentBuilder($query)
    {
        return new UserBuilder($query);
    }
}

它还将在构建器上添加一些标记以帮助您的ide

  • 基于模型属性的where子句
  • 结果值的结果
use Illuminate\Database\Eloquent\Builder;

/**
 * @method \App\Builder\UserBuilder whereId(int|string $value)
 * @method \App\Builder\UserBuilder whereName(string $value)
 * @method \App\Builder\UserBuilder whereEmail(string $value)
 * @method \App\Builder\UserBuilder whereEmailVerifiedAt(\Illuminate\Support\Carbon|string|null $value)
 * @method \App\Builder\UserBuilder wherePassword(string $value)
 * @method \App\Builder\UserBuilder whereRememberToken(string|null $value)
 * @method \App\Builder\UserBuilder whereCreatedAt(\Illuminate\Support\Carbon|string $value)
 * @method \App\Builder\UserBuilder whereUpdatedAt(\Illuminate\Support\Carbon|string $value)
 * @method \App\User create(array $attributes = [])
 * @method \Illuminate\Database\Eloquent\Collection|\App\User|null find($id, array $columns = ['*'])
 * @method \Illuminate\Database\Eloquent\Collection findMany($id, array $columns = ['*'])
 * @method \Illuminate\Database\Eloquent\Collection|\App\User findOrFail($id, array $columns = ['*'])
 * @method \App\User findOrNew($id, array $columns = ['*'])
 * @method \App\User|null first(array|string $columns = ['*'])
 * @method \App\User firstOrCreate(array $attributes, array $values = [])
 * @method \App\User firstOrFail(array $columns = ['*'])
 * @method \App\User firstOrNew(array $attributes = [], array $values = [])
 * @method \App\User forceCreate(array $attributes = [])
 * @method \Illuminate\Database\Eloquent\Collection get(array|string $columns = ['*'])
 * @method \App\User getModel()
 * @method \Illuminate\Database\Eloquent\Collection getModels(array|string $columns = ['*'])
 * @method \App\User newModelInstance(array $attributes = [])
 * @method \App\User updateOrCreate(array $attributes, array $values = [])
 * @template TModelClass
 * @extends \Illuminate\Database\Eloquent\Builder<\App\User>
 */
class UserBuilder extends Builder
{
}

如果您的模型没有定义自定义构建器,next-ide-helper:models将在_ide_models.php中创建假类,并提供文档注释以提供自动补全。

作用域

您模型的全部作用域都将作为其构建器的(在自定义查询构建器或_ide_models.php中)方法添加。

class User extends Model
{
    public function scopeWhereVerified($query, bool $verified = true): void
    {
        $query->whereNull('email_verified_at', 'and', !$verified);
    }
}

这将在您的自定义构建器上产生@method \App\Builder\UserBuilder whereVerified(bool $verified = true)

请注意,如果仅调用User::whereVerified(),您的ide可能会报错Non-static method 'whereVerified' should not be called statically, but the class has the '__magic' method.。这就是为什么我们建议您使用User::query()->...

关系

模型命令还会解析您的模型关系并提供许多补全助手。

/**
 * @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Post> $posts
 */
class User extends Model
{
    public function posts(): HasMany
    {
        return $this->hasMany(Post::class);
    }
}

class Post extends Model
{
    public function scopeWherePublished($query): void
    {
        return $query->whereNotNull('published_at');
    }
}

ide也会正确解析自定义构建器和自定义集合

Larastan友好标记

如果您使用PHPStan或Larastan,可以通过将models.larastan_friendly配置设置为true来获取有关定义集合的更多信息。

使用此配置,您将在模型中获取额外的标签

/**
 * @phpstan-method static \App\Collections\UserCollection<int, \App\Models\User> all(array|mixed $columns = ['*'])
 */
class User extends Model {}

并在您的自定义构建器中

/**
 * @phpstan-method \Illuminate\Database\Eloquent\Collection<int, \App\User>|\App\User|null find($id, array $columns = ['*'])
 * @phpstan-method \Illuminate\Database\Eloquent\Collection<int, \App\User> findMany($id, array $columns = ['*'])
 * @phpstan-method \Illuminate\Database\Eloquent\Collection<int, \App\User>|\App\User findOrFail($id, array $columns = ['*'])
 * @phpstan-method \Illuminate\Database\Eloquent\Collection<int, \App\User> get(array|string $columns = ['*'])
 * @phpstan-method \Illuminate\Database\Eloquent\Collection<int, \App\User> getModels(array|string $columns = ['*'])
 * @template TModelClass
 * @extends \Illuminate\Database\Eloquent\Builder<\App\User>
 */
class UserBuilder extends Builder {}

扩展

有时,命令无法解析或预测所有可能的解析方式。

这就是为什么这个包提供了一个自定义解析逻辑的方法,您可以在 next-ide-helper.models.extensions 配置中添加您的自定义解析器。

此包提供了一个 next-ide-helper:macros。命令解析所有注册的宏,并生成一个 _ide_macros.php 文件,该文件为 Macroable 宏提供自动完成。

例如

use Illuminate\Support\Collection;

Collection::macro('mapToUpper', function(): Collection {
    return $this->map(fn(string $item) => \Illuminate\Support\Str::upper($item));
});

多亏了 _ide_macros.php 文件,我们为 mapToUpper 方法提供了自动完成

就像 _ide_models.php 一样,_ide_macros.php 文件不应被包含,而应由您的 IDE 分析。

Phpstorm元数据

命令 php artisan next-ide-helper:meta 将生成一个 .phpstorm.meta.php 文件。它将为容器绑定和一些 Laravel 辅助函数提供自动完成。

工厂

命令 php artisan next-ide-helper:factories 将为您在工厂中添加文档块,以便正确地类型化某些方法。它还将为模型关系明确魔法方法。

例如,如果您有

class User extends Model                        
{
    public function role(): BelongsTo
    {
        return $this->belongsTo(Role::class);
    }

    public function posts(): HasMany
    {
        return $this->hasMany(Post::class);
    }
    
    public function newCollection(array $models = [])
    {
        return new UserCollection($models);
    }
}

此命令将在 UserFactory 中生成文档块

/**
 * @method \App\User createOne($attributes = [])
 * @method \App\User|\App\Collections\UserCollection create($attributes = [], ?\Illuminate\Database\Eloquent\Model $parent = null)
 * @method \App\User makeOne($attributes = [])
 * @method \App\User|\App\Collections\UserCollection make($attributes = [], ?\Illuminate\Database\Eloquent\Model $parent = null)
 * @method \App\User newModel(array $attributes = [])
 * @method \Database\Factories\UserFactory forRole($attributes = [])
 * @method \Database\Factories\UserFactory hasPosts($count = 1, $attributes = [])
 * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\User>
 */
class UserFactory extends Factory
{
    //    
}

别名

有时我们不想使用完全限定的类名,而更喜欢使用 Laravel 别名。

命令 php artisan next-ide-helper:aliases 将创建一个 IDE 可以理解的文件。

然后,它将为在您的 config/app.php 文件中定义的别名以及您使用的包中定义的别名提供自动完成、语法高亮等功能。

生成所有

您可以使用 next-ide-helper:all 生成所有 next-ide-helper 文件。

它将为您生成

  • 模型
  • Phpstorm元数据
  • 别名
  • 工厂(如果您正在使用 Laravel 8 基于类的模型工厂)

自定义应用程序引导

有时您可能希望在命令执行之前启动环境。例如,在多租户多数据库应用程序中,您需要启动您的租户连接,以便让此包解析表列。

在这种情况下,您只需创建自己的启动器并将配置包以使用它

class MultitenantBootstrapper implements \Soyhuce\NextIdeHelper\Contracts\Bootstrapper 
{
    private Tenancy $tenancy;

    public function __construct(Tenancy $tenancy)
    {
        $this->tenancy = $tenancy;    
    }

    public function bootstrap() : void
    {
        $tenant = \App\Tenant::firstOrFail();
        
        $this->tenancy->connect($tenant);
    }
}
// Note that this code is completely fictive.

现在,您只需将其添加到您的 next-ide-helper.php 配置文件中

'bootstrapper' => \App\Support\MultitenantBootstrapper::class,

您的启动器从其构造函数中受益于 Laravel 依赖注入。

文档块中的自定义内容

某些命令会重置您的文档块。如果您不想删除某些内容,必须在文档块中添加一个 @generated 标签来告诉 nest-ide-helper 在何处插入其内容。

例如

/**
 * Comment that will not be overwritten after docblock generation
 *  
 * @author John Doe
 * @package Foo Bar
 * @deprecated since 1.0.0
 * @api 
 * 
 * @generated
 * [the content generated by next-ide-helper will be inserted here]
 */
class SomeModel extends Model {}

更新日志

有关最近更改的更多信息,请参阅 更新日志

贡献

有关详细信息,请参阅 贡献

安全漏洞

有关如何报告安全漏洞的更多信息,请参阅 我们的安全策略

鸣谢

许可证

MIT 许可证(MIT)。有关更多信息,请参阅 许可文件