Compare commits

...
20 Commits
Author SHA1 Message Date
Markus Podar c8ebf563a0 chore: prepare 2.9.2 release (#1197) 2021-04-01 20:56:14 +02:00
Markus Podar 843067b907 Merge pull request #1196 from ahmed-aliraqi/master
Fix ide-helper:models exception if model doesn't have factory
2021-04-01 20:32:08 +02:00
Ahmed Fathy f0f7051012 formatting 2021-04-01 10:57:05 +02:00
Ahmed Fathy e1af93f43b update changelog 2021-03-31 23:10:46 +02:00
Ahmed Fathy b19b1d69ba testing 2021-03-31 23:03:55 +02:00
Ahmed Fathy 92d7f2e706 fix ide-helper:models error if model doesn't have factory 2021-03-29 23:28:18 +02:00
wimskiandlaravel-ide-helper f0c138c4fd Model hooks (#945)
* Model hooks

* composer fix-style

* Fix test for ModelHooks

Co-authored-by: laravel-ide-helper <[email protected]>
2021-03-29 20:49:09 +02:00
Markus Podar b8d5fc3663 Merge pull request #1193 from netpok/skip_generate_in_phpunit
Skip post_migrate when running tests
2021-03-23 17:47:25 +01:00
netpok df994eb767 Merge branch 'master' into skip_generate_in_phpunit 2021-03-23 09:59:38 +01:00
Markus Podar 0cae143470 Merge pull request #1192 from netpok/add_missing_changelog_entry
Add missing changelog entry for #1184
2021-03-22 20:15:17 +01:00
Balázs Váradi c2dec69d64 Remove unused import 2021-03-22 10:03:46 +01:00
Balázs Váradi dedd69e8b4 Remove already resolved issue from psalm baseline 2021-03-22 10:03:12 +01:00
Balázs Váradi 40c02c524d Add changelog entry 2021-03-22 10:02:17 +01:00
Balázs Váradi 04c1139223 Skip post_migrate when running tests 2021-03-22 09:54:32 +01:00
Balázs Váradi 172e430c12 Add missing changelog entry 2021-03-22 09:49:30 +01:00
netpok 244e936b74 Remove dead code and unused helper (#1183)
* Remove unnecessary check

* Remove helper class
2021-03-17 12:21:59 +01:00
netpok f7f7e9e65a Add default values to array_merge (#1184) 2021-03-17 11:56:50 +01:00
Barry vd. Heuvel 1a813703fe Update CHANGELOG.md 2021-03-17 10:08:59 +01:00
Markus Podar d58731cd9b Merge pull request #1178 from barryvdh/mp-release
chore: adapt for release of 2.9.1
2021-03-15 22:09:25 +01:00
Markus Podar b246d9ab23 chore: adapt for release of 2.9.1 2021-03-15 21:00:43 +01:00
15 changed files with 277 additions and 34 deletions
+15 -2
View File
@@ -2,12 +2,25 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
[Next release](https://github.com/barryvdh/laravel-ide-helper/compare/v2.9.1...master) [Next release](https://github.com/barryvdh/laravel-ide-helper/compare/v2.9.3...master)
-------------- --------------
2021-04-01, 2.9.2
-----------------
### Added
- Model hooks for adding custom information from external sources to model classes through the ModelsCommand [\#945 / wimski](https://github.com/barryvdh/laravel-ide-helper/pull/945)
### Fixed
- Fix ide-helper:models exception if model doesn't have factory [\#1196 / ahmed-aliraqi](https://github.com/barryvdh/laravel-ide-helper/pull/1196)
- Running tests triggering post_migrate hooks [\#1193 / netpok](https://github.com/barryvdh/laravel-ide-helper/pull/1193)
- Array_merge error when config is cached prior to package install [\#1184 / netpok](https://github.com/barryvdh/laravel-ide-helper/pull/1184)
2021-03-15, 2.9.1
-----------------
### Added ### Added
- Generate PHPDoc for Laravel 8.x factories [\#1074 / ahmed-aliraqi](https://github.com/barryvdh/laravel-ide-helper/pull/1074) - Generate PHPDoc for Laravel 8.x factories [\#1074 / ahmed-aliraqi](https://github.com/barryvdh/laravel-ide-helper/pull/1074)
- Add a comment to a property like table columns [\#1168 / biiiiiigmonster](https://github.com/barryvdh/laravel-ide-helper/pull/1168) - Add a comment to a property like table columns [\#1168 / biiiiiigmonster](https://github.com/barryvdh/laravel-ide-helper/pull/1168)
- Added `post_migrate` hook to run commands after a migration [\#1163 / netpol](https://github.com/barryvdh/laravel-ide-helper/pull/1163) - Added `post_migrate` hook to run commands after a migration [\#1163 / netpok](https://github.com/barryvdh/laravel-ide-helper/pull/1163)
### Fixed ### Fixed
- Error when generating helper for invokable classes [\#1124 / standaniels](https://github.com/barryvdh/laravel-ide-helper/pull/1124) - Error when generating helper for invokable classes [\#1124 / standaniels](https://github.com/barryvdh/laravel-ide-helper/pull/1124)
+43
View File
@@ -14,6 +14,9 @@ Generation is done based on the files in your project, so they are always up-to-
- [Usage](#usage) - [Usage](#usage)
- [Automatic PHPDoc generation for Laravel Facades](#automatic-phpdoc-generation-for-laravel-facades) - [Automatic PHPDoc generation for Laravel Facades](#automatic-phpdoc-generation-for-laravel-facades)
- [Automatic PHPDocs for models](#automatic-phpdocs-for-models) - [Automatic PHPDocs for models](#automatic-phpdocs-for-models)
- [Model Directories](#model-directories)
- [Ignore Models](#ignore-models)
- [Model Hooks](#model-hooks)
- [Automatic PHPDocs generation for Laravel Fluent methods](#automatic-phpdocs-generation-for-laravel-fluent-methods) - [Automatic PHPDocs generation for Laravel Fluent methods](#automatic-phpdocs-generation-for-laravel-fluent-methods)
- [Auto-completion for factory builders](#auto-completion-for-factory-builders) - [Auto-completion for factory builders](#auto-completion-for-factory-builders)
- [PhpStorm Meta for Container instances](#phpstorm-meta-for-container-instances) - [PhpStorm Meta for Container instances](#phpstorm-meta-for-container-instances)
@@ -175,6 +178,8 @@ With the `--write-mixin (-M)` option
*/ */
``` ```
#### Model Directories
By default, models in `app/models` are scanned. The optional argument tells what models to use (also outside app/models). By default, models in `app/models` are scanned. The optional argument tells what models to use (also outside app/models).
```bash ```bash
@@ -189,6 +194,8 @@ php artisan ide-helper:models --dir="path/to/models" --dir="app/src/Model"
You can publish the config file (`php artisan vendor:publish`) and set the default directories. You can publish the config file (`php artisan vendor:publish`) and set the default directories.
#### Ignore Models
Models can be ignored using the `--ignore (-I)` option Models can be ignored using the `--ignore (-I)` option
```bash ```bash
@@ -270,6 +277,42 @@ For those special cases, you can map them via the config `custom_db_types`. Exam
], ],
``` ```
#### Model Hooks
If you need additional information on your model from sources that are not handled by default, you can hook in to the
generation process with model hooks to add extra information on the fly.
Simply create a class that implements `ModelHookInterface` and add it to the `model_hooks` array in the config:
```php
'model_hooks' => [
MyCustomHook::class,
],
```
The `run` method will be called during generation for every model and receives the current running `ModelsCommand` and the current `Model`, e.g.:
```php
class MyCustomHook implements ModelHookInterface
{
public function run(ModelsCommand $command, Model $model): void
{
if (! $model instanceof MyModel) {
return;
}
$command->setProperty('custom', 'string', true, false, 'My custom property');
}
}
```
```php
/**
* MyModel
*
* @property integer $id
* @property-read string $custom
```
### Automatic PHPDocs generation for Laravel Fluent methods ### Automatic PHPDocs generation for Laravel Fluent methods
If you need PHPDocs support for Fluent methods in migration, for example If you need PHPDocs support for Fluent methods in migration, for example
+15
View File
@@ -144,6 +144,21 @@ return [
], ],
/*
|--------------------------------------------------------------------------
| 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' => [
// App\Support\IdeHelper\MyModelHook::class
],
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| Extra classes | Extra classes
-5
View File
@@ -17,9 +17,4 @@
<code>\Storage</code> <code>\Storage</code>
</UndefinedClass> </UndefinedClass>
</file> </file>
<file src="src/IdeHelperServiceProvider.php">
<TooFewArguments occurrences="1">
<code>new PhpEngine()</code>
</TooFewArguments>
</file>
</files> </files>
+38 -5
View File
@@ -11,6 +11,7 @@
namespace Barryvdh\LaravelIdeHelper\Console; namespace Barryvdh\LaravelIdeHelper\Console;
use Barryvdh\LaravelIdeHelper\Contracts\ModelHookInterface;
use Barryvdh\Reflection\DocBlock; use Barryvdh\Reflection\DocBlock;
use Barryvdh\Reflection\DocBlock\Context; use Barryvdh\Reflection\DocBlock\Context;
use Barryvdh\Reflection\DocBlock\Serializer as DocBlockSerializer; use Barryvdh\Reflection\DocBlock\Serializer as DocBlockSerializer;
@@ -279,6 +280,9 @@ class ModelsCommand extends Command
$this->getSoftDeleteMethods($model); $this->getSoftDeleteMethods($model);
$this->getCollectionMethods($model); $this->getCollectionMethods($model);
$this->getFactoryMethods($model); $this->getFactoryMethods($model);
$this->runModelHooks($model);
$output .= $this->createPhpDocs($name); $output .= $this->createPhpDocs($name);
$ignore[] = $name; $ignore[] = $name;
$this->nullableColumns = []; $this->nullableColumns = [];
@@ -336,7 +340,7 @@ class ModelsCommand extends Command
* *
* @param \Illuminate\Database\Eloquent\Model $model * @param \Illuminate\Database\Eloquent\Model $model
*/ */
protected function castPropertiesType($model) public function castPropertiesType($model)
{ {
$casts = $model->getCasts(); $casts = $model->getCasts();
foreach ($casts as $name => $type) { foreach ($casts as $name => $type) {
@@ -412,7 +416,7 @@ class ModelsCommand extends Command
* *
* @param \Illuminate\Database\Eloquent\Model $model * @param \Illuminate\Database\Eloquent\Model $model
*/ */
protected function getPropertiesFromTable($model) public function getPropertiesFromTable($model)
{ {
$table = $model->getConnection()->getTablePrefix() . $model->getTable(); $table = $model->getConnection()->getTablePrefix() . $model->getTable();
$schema = $model->getConnection()->getDoctrineSchemaManager(); $schema = $model->getConnection()->getDoctrineSchemaManager();
@@ -509,7 +513,7 @@ class ModelsCommand extends Command
/** /**
* @param \Illuminate\Database\Eloquent\Model $model * @param \Illuminate\Database\Eloquent\Model $model
*/ */
protected function getPropertiesFromMethods($model) public function getPropertiesFromMethods($model)
{ {
$methods = get_class_methods($model); $methods = get_class_methods($model);
if ($methods) { if ($methods) {
@@ -721,7 +725,7 @@ class ModelsCommand extends Command
* @param string|null $comment * @param string|null $comment
* @param bool $nullable * @param bool $nullable
*/ */
protected function setProperty($name, $type = null, $read = null, $write = null, $comment = '', $nullable = false) public function setProperty($name, $type = null, $read = null, $write = null, $comment = '', $nullable = false)
{ {
if (!isset($this->properties[$name])) { if (!isset($this->properties[$name])) {
$this->properties[$name] = []; $this->properties[$name] = [];
@@ -1093,7 +1097,14 @@ class ModelsCommand extends Command
} }
$modelName = get_class($model); $modelName = get_class($model);
$factory = get_class($modelName::factory()); $modelBaseName = class_basename($modelName);
$factory = "\Database\Factories\\{$modelBaseName}Factory";
if ($modelName::newFactory()) {
$factory = get_class($modelName::newFactory());
}
$factory = '\\' . trim($factory, '\\'); $factory = '\\' . trim($factory, '\\');
if (!class_exists($factory)) { if (!class_exists($factory)) {
@@ -1351,4 +1362,26 @@ class ModelsCommand extends Command
return $parameterName; return $parameterName;
} }
/**
* @param \Illuminate\Database\Eloquent\Model $model
* @throws \Illuminate\Contracts\Container\BindingResolutionException
* @throws \RuntimeException
*/
protected function runModelHooks($model): void
{
$hooks = $this->laravel['config']->get('ide-helper.model_hooks', []);
foreach ($hooks as $hook) {
$hookInstance = $this->laravel->make($hook);
if (!$hookInstance instanceof ModelHookInterface) {
throw new \RuntimeException(
'Your IDE helper model hook must implement Barryvdh\LaravelIdeHelper\Contracts\ModelHookInterface'
);
}
$hookInstance->run($this, $model);
}
}
} }
+11
View File
@@ -0,0 +1,11 @@
<?php
namespace Barryvdh\LaravelIdeHelper\Contracts;
use Barryvdh\LaravelIdeHelper\Console\ModelsCommand;
use Illuminate\Database\Eloquent\Model;
interface ModelHookInterface
{
public function run(ModelsCommand $command, Model $model): void;
}
+3 -3
View File
@@ -54,9 +54,9 @@ class Generator
// Find the drivers to add to the extra/interfaces // Find the drivers to add to the extra/interfaces
$this->detectDrivers(); $this->detectDrivers();
$this->extra = array_merge($this->extra, $this->config->get('ide-helper.extra')); $this->extra = array_merge($this->extra, $this->config->get('ide-helper.extra'), []);
$this->magic = array_merge($this->magic, $this->config->get('ide-helper.magic')); $this->magic = array_merge($this->magic, $this->config->get('ide-helper.magic'), []);
$this->interfaces = array_merge($this->interfaces, $this->config->get('ide-helper.interfaces')); $this->interfaces = array_merge($this->interfaces, $this->config->get('ide-helper.interfaces'), []);
// Make all interface classes absolute // Make all interface classes absolute
foreach ($this->interfaces as &$interface) { foreach ($this->interfaces as &$interface) {
$interface = '\\' . ltrim($interface, '\\'); $interface = '\\' . ltrim($interface, '\\');
-13
View File
@@ -1,13 +0,0 @@
<?php
declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper;
class Helpers
{
public static function isLaravel(): bool
{
return class_exists('Illuminate\Foundation\Application');
}
}
+1 -6
View File
@@ -19,7 +19,6 @@ use Barryvdh\LaravelIdeHelper\Listeners\GenerateModelHelper;
use Illuminate\Console\Events\CommandFinished; use Illuminate\Console\Events\CommandFinished;
use Illuminate\Contracts\Support\DeferrableProvider; use Illuminate\Contracts\Support\DeferrableProvider;
use Illuminate\Database\Events\MigrationsEnded; use Illuminate\Database\Events\MigrationsEnded;
use Illuminate\Foundation\Application;
use Illuminate\Support\ServiceProvider; use Illuminate\Support\ServiceProvider;
use Illuminate\View\Engines\EngineResolver; use Illuminate\View\Engines\EngineResolver;
use Illuminate\View\Engines\PhpEngine; use Illuminate\View\Engines\PhpEngine;
@@ -35,7 +34,7 @@ class IdeHelperServiceProvider extends ServiceProvider implements DeferrableProv
*/ */
public function boot() public function boot()
{ {
if ($this->app['config']->get('ide-helper.post_migrate', [])) { if (!$this->app->runningUnitTests() && $this->app['config']->get('ide-helper.post_migrate', [])) {
$this->app['events']->listen(CommandFinished::class, GenerateModelHelper::class); $this->app['events']->listen(CommandFinished::class, GenerateModelHelper::class);
$this->app['events']->listen(MigrationsEnded::class, function () { $this->app['events']->listen(MigrationsEnded::class, function () {
GenerateModelHelper::$shouldRun = true; GenerateModelHelper::$shouldRun = true;
@@ -120,10 +119,6 @@ class IdeHelperServiceProvider extends ServiceProvider implements DeferrableProv
{ {
$resolver = new EngineResolver(); $resolver = new EngineResolver();
$resolver->register('php', function () { $resolver->register('php', function () {
if (Helpers::isLaravel() && (int) Application::VERSION < 8) {
return new PhpEngine();
}
return new PhpEngine($this->app['files']); return new PhpEngine($this->app['files']);
}); });
$finder = new FileViewFinder($this->app['files'], [__DIR__ . '/../resources/views']); $finder = new FileViewFinder($this->app['files'], [__DIR__ . '/../resources/views']);
@@ -0,0 +1,13 @@
<?php
declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Factories\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class ModelWithoutFactory extends Model
{
use HasFactory;
}
@@ -26,6 +26,7 @@ class Test extends AbstractModelsCommand
$this->assertSame(0, $tester->getStatusCode()); $this->assertSame(0, $tester->getStatusCode());
$this->assertStringContainsString('Written new phpDocBlock to', $tester->getDisplay()); $this->assertStringContainsString('Written new phpDocBlock to', $tester->getDisplay());
$this->assertStringNotContainsString('not found', $tester->getDisplay());
$this->assertMatchesMockedSnapshot(); $this->assertMatchesMockedSnapshot();
} }
} }
@@ -4,6 +4,27 @@ declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Factories\Models; namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Factories\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
/**
* Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Factories\Models\ModelWithoutFactory
*
* @method static \Illuminate\Database\Eloquent\Builder|ModelWithoutFactory newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|ModelWithoutFactory newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|ModelWithoutFactory query()
* @mixin \Eloquent
*/
class ModelWithoutFactory extends Model
{
use HasFactory;
}
<?php
declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Factories\Models;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Factories\Factories\SimpleFactory; use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Factories\Factories\SimpleFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
@@ -0,0 +1,17 @@
<?php
declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\ModelHooks\Hooks;
use Barryvdh\LaravelIdeHelper\Console\ModelsCommand;
use Barryvdh\LaravelIdeHelper\Contracts\ModelHookInterface;
use Illuminate\Database\Eloquent\Model;
class CustomProperty implements ModelHookInterface
{
public function run(ModelsCommand $command, Model $model): void
{
$command->setProperty('custom', 'string', true, false);
}
}
@@ -0,0 +1,11 @@
<?php
declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\ModelHooks\Models;
use Illuminate\Database\Eloquent\Model;
class Simple extends Model
{
}
@@ -0,0 +1,88 @@
<?php
declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\ModelHooks;
use Barryvdh\LaravelIdeHelper\Console\ModelsCommand;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\AbstractModelsCommand;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\ModelHooks\Hooks\CustomProperty;
use Illuminate\Filesystem\Filesystem;
use Mockery;
class Test extends AbstractModelsCommand
{
protected function getEnvironmentSetUp($app)
{
parent::getEnvironmentSetUp($app);
$app['config']->set('ide-helper', [
'model_locations' => [
// This is calculated from the base_path() which points to
// vendor/orchestra/testbench-core/laravel
'/../../../../tests/Console/ModelsCommand/ModelHooks/Models',
],
'model_hooks' => [
CustomProperty::class,
],
]);
}
public function test(): void
{
$actualContent = null;
$mockFilesystem = Mockery::mock(Filesystem::class);
$mockFilesystem
->shouldReceive('get')
->andReturn(file_get_contents(__DIR__ . '/Models/Simple.php'))
->once();
$mockFilesystem
->shouldReceive('put')
->with(
Mockery::any(),
Mockery::capture($actualContent)
)
->andReturn(1) // Simulate we wrote _something_ to the file
->once();
$this->instance(Filesystem::class, $mockFilesystem);
$command = $this->app->make(ModelsCommand::class);
$tester = $this->runCommand($command, [
'--write' => true,
]);
$this->assertSame(0, $tester->getStatusCode());
$this->assertStringContainsString('Written new phpDocBlock to', $tester->getDisplay());
$expectedContent = <<<'PHP'
<?php
declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\ModelHooks\Models;
use Illuminate\Database\Eloquent\Model;
/**
* Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\ModelHooks\Models\Simple
*
* @property int $id
* @property-read string $custom
* @method static \Illuminate\Database\Eloquent\Builder|Simple newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|Simple newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|Simple query()
* @method static \Illuminate\Database\Eloquent\Builder|Simple whereId($value)
* @mixin \Eloquent
*/
class Simple extends Model
{
}
PHP;
$this->assertSame($expectedContent, $actualContent);
}
}