Skip to content

Commit

Permalink
Auto register ide-helper hook using Package Discovery (#215)
Browse files Browse the repository at this point in the history
* Auto register ide-helper hook

* Update EloquentHasManyDeepServiceProvider.php

This package should not be installed on a production environment, therefore we don't need to check it.

* Update EloquentHasManyDeepServiceProvider to  implement DeferrableProvider

Ensures the hook is only registered after the ModelsCommand is called.

* Refactoring

---------

Co-authored-by: Jonas Staudenmeir <[email protected]>
  • Loading branch information
daniel-de-wit and staudenmeir authored Dec 4, 2023
1 parent dfcc1a9 commit 9d9aa83
Show file tree
Hide file tree
Showing 5 changed files with 210 additions and 5 deletions.
75 changes: 70 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -661,11 +661,76 @@ class Comment extends Model

### IDE Helper

If you are using [barryvdh/laravel-ide-helper](https://github.com/barryvdh/laravel-ide-helper), this package provides
a [model hook](https://github.com/barryvdh/laravel-ide-helper#model-hooks) that will correctly add relations when
generating the type hints. To get the correct type hints, in
the [ide-helper.php](https://github.com/barryvdh/laravel-ide-helper/blob/master/config/ide-helper.php) config file,
add `\Staudenmeir\EloquentHasManyDeep\IdeHelper\DeepRelationsHook::class` to the `model_hooks` array.
If you are using [barryvdh/laravel-ide-helper](https://github.com/barryvdh/laravel-ide-helper), this package provides a model hook that will correctly add relations when generating the type hints.
The model hook is **enabled by default** using [Package Discovery](https://laravel.com/docs/packages#package-discovery).

To enable it manually, add [model hook](https://github.com/barryvdh/laravel-ide-helper#model-hooks) to the model_hooks array.

```php
// File: config/ide-helper.php

/*
|--------------------------------------------------------------------------
| Models hooks
|--------------------------------------------------------------------------
|
| Define which hook classes you want to run for models to add custom information
|
| Hooks should implement Barryvdh\LaravelIdeHelper\Contracts\ModelHookInterface.
|
*/

'model_hooks' => [
\Staudenmeir\EloquentHasManyDeep\IdeHelper\DeepRelationsHook::class,
],
```

To disable the model hook you have 3 options:

- [Disable using .env](#disable-using-env)
- [Disable using config](#disable-using-config)
- [Disable by option out of Package Discovery](#disable-by-opting-out-of-package-discovery)

#### Disable using .env
Update your `.env` file to include:

```dotenv
ELOQUENT_HAS_MANY_DEEP_IDE_HELPER_ENABLED=false
```

#### Disable using config
Publish the config and disable the setting directly:

```
php artisan vendor:publish --tag=eloquent-has-many-deep
```

```php
// File: config/eloquent-has-many-deep.php

/*
|--------------------------------------------------------------------------
| IDE Helper
|--------------------------------------------------------------------------
|
| Automatically register the model hook to receive correct type hints
|
*/
'ide_helper_enabled' => false,
```

#### Disable by opting out of Package Discovery
Update your `composer.json` with the following:

```json
"extra": {
"laravel": {
"dont-discover": [
"staudenmeir/eloquent-has-many-deep"
]
}
},
```

## Contributing

Expand Down
8 changes: 8 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"illuminate/pagination": "^10.0",
"korridor/laravel-has-many-merged": "^1.0",
"mockery/mockery": "^1.6",
"orchestra/testbench": "^8.13",
"phpstan/phpstan": "^1.10",
"phpunit/phpunit": "^10.1",
"staudenmeir/eloquent-eager-limit": "^1.8",
Expand All @@ -35,6 +36,13 @@
"Tests\\": "tests/"
}
},
"extra": {
"laravel": {
"providers": [
"Staudenmeir\\EloquentHasManyDeep\\Providers\\EloquentHasManyDeepServiceProvider"
]
}
},
"minimum-stability": "dev",
"prefer-stable": true,
"config": {
Expand Down
15 changes: 15 additions & 0 deletions config/eloquent-has-many-deep.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

declare(strict_types=1);

return [
/*
|--------------------------------------------------------------------------
| IDE Helper
|--------------------------------------------------------------------------
|
| Automatically register the model hook to receive correct type hints
|
*/
'ide_helper_enabled' => env('ELOQUENT_HAS_MANY_DEEP_IDE_HELPER_ENABLED', true),
];
59 changes: 59 additions & 0 deletions src/Providers/EloquentHasManyDeepServiceProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

namespace Staudenmeir\EloquentHasManyDeep\Providers;

use Barryvdh\LaravelIdeHelper\Console\ModelsCommand;
use Illuminate\Contracts\Support\DeferrableProvider;
use Illuminate\Support\ServiceProvider;
use Staudenmeir\EloquentHasManyDeep\IdeHelper\DeepRelationsHook;

class EloquentHasManyDeepServiceProvider extends ServiceProvider implements DeferrableProvider
{
public function boot(): void
{
$this->publishConfig();
}

public function register(): void
{
$this->registerConfig();

$this->registerIdeHelperHook();
}

public function provides(): array
{
return [
ModelsCommand::class,
];
}

protected function registerIdeHelperHook(): void
{
/** @var \Illuminate\Contracts\Config\Repository $config */
$config = $this->app->get('config');

if (!$config->get('eloquent-has-many-deep.ide_helper_enabled')) {
return;
}

$config->set('ide-helper.model_hooks', array_merge([
DeepRelationsHook::class,
], $config->get('ide-helper.model_hooks', [])));
}

protected function publishConfig(): void
{
$this->publishes([
__DIR__ . '/../../config/eloquent-has-many-deep.php' => config_path('eloquent-has-many-deep.php'),
], 'eloquent-has-many-deep');
}

protected function registerConfig(): void
{
$this->mergeConfigFrom(
__DIR__ . '/../../config/eloquent-has-many-deep.php',
'eloquent-has-many-deep',
);
}
}
58 changes: 58 additions & 0 deletions tests/Providers/EloquentHasManyDeepServiceProviderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

declare(strict_types=1);

namespace Tests\Providers;

use Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider;
use Orchestra\Testbench\TestCase;
use Staudenmeir\EloquentHasManyDeep\IdeHelper\DeepRelationsHook;
use Staudenmeir\EloquentHasManyDeep\Providers\EloquentHasManyDeepServiceProvider;

class EloquentHasManyDeepServiceProviderTest extends TestCase
{
protected function getPackageProviders($app): array
{
return [
IdeHelperServiceProvider::class,
EloquentHasManyDeepServiceProvider::class,
];
}

public function testAutoRegistrationOfModelHook(): void
{
$this->app->loadDeferredProvider(IdeHelperServiceProvider::class);
$this->app->loadDeferredProvider(EloquentHasManyDeepServiceProvider::class);

/** @var \Illuminate\Contracts\Config\Repository $config */
$config = $this->app->get('config');

$this->assertContains(
DeepRelationsHook::class,
$config->get('ide-helper.model_hooks'),
);
}

/**
* @test
* @define-env usesIdeHelperDisabledInConfig
*/
public function testDisabledRegistrationOfModelHookFromConfig(): void
{
$this->app->loadDeferredProvider(IdeHelperServiceProvider::class);
$this->app->loadDeferredProvider(EloquentHasManyDeepServiceProvider::class);

/** @var \Illuminate\Contracts\Config\Repository $config */
$config = $this->app->get('config');

$this->assertNotContains(
DeepRelationsHook::class,
$config->get('ide-helper.model_hooks'),
);
}

protected function usesIdeHelperDisabledInConfig($app): void
{
$app['config']->set('eloquent-has-many-deep.ide_helper_enabled', false);
}
}

0 comments on commit 9d9aa83

Please sign in to comment.