diff --git a/README.md b/README.md index c26ccb2..7142569 100644 --- a/README.md +++ b/README.md @@ -121,6 +121,10 @@ By default, you are asked to overwrite or write to a separate file (`_ide_helper You can write the comments directly to your Model file, using the `--write (-W)` option, or force to not write with `--nowrite (-N)`. +Alternatively using the `--write-mixin (-M)` option will only add a mixin tag to your Model file, +writing the rest in (`_ide_helper_models.php`). +The class name will be different from the model, avoiding the IDE duplicate annoyance. + > Please make sure to back up your models, before writing the info. Writing to the models should keep the existing comments and only append new properties/methods. @@ -151,6 +155,14 @@ php artisan ide-helper:models "App\Models\Post" */ ``` +With the `--write-mixin (-M)` option +```php +/** + * … + * @mixin IdeHelperPost + */ +``` + By default, models in `app/models` are scanned. The optional argument tells what models to use (also outside app/models). ```bash diff --git a/src/Console/ModelsCommand.php b/src/Console/ModelsCommand.php index ae16152..651c041 100644 --- a/src/Console/ModelsCommand.php +++ b/src/Console/ModelsCommand.php @@ -61,6 +61,7 @@ class ModelsCommand extends Command protected $properties = []; protected $methods = []; protected $write = false; + protected $write_mixin = false; protected $dirs = []; protected $reset; protected $keep_text; @@ -96,6 +97,7 @@ class ModelsCommand extends Command { $filename = $this->option('filename'); $this->write = $this->option('write'); + $this->write_mixin = $this->option('write-mixin'); $this->dirs = array_merge( $this->laravel['config']->get('ide-helper.model_locations', []), $this->option('dir') @@ -111,6 +113,7 @@ class ModelsCommand extends Command $this->write_model_relation_count_properties = $this->laravel['config']->get('ide-helper.write_model_relation_count_properties', true); + $this->write = $this->write_mixin ? true : $this->write; //If filename is default and Write is not specified, ask what to do if (!$this->write && $filename === $this->filename && !$this->option('nowrite')) { if ( @@ -128,7 +131,7 @@ class ModelsCommand extends Command $content = $this->generateDocs($model, $ignore); - if (!$this->write) { + if (!$this->write || $this->write_mixin) { $written = $this->files->put($filename, $content); if ($written !== false) { $this->info("Model information was written to $filename"); @@ -163,6 +166,9 @@ class ModelsCommand extends Command ['dir', 'D', InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'The model dir, supports glob patterns', [], ], ['write', 'W', InputOption::VALUE_NONE, 'Write to Model file'], + ['write-mixin', 'M', InputOption::VALUE_NONE, + "Write models to {$this->filename} and adds @mixin to each model, avoiding IDE duplicate declaration warnings", + ], ['nowrite', 'N', InputOption::VALUE_NONE, 'Don\'t write to Model file'], ['reset', 'R', InputOption::VALUE_NONE, 'Remove the original phpdocs instead of appending'], ['smart-reset', 'r', InputOption::VALUE_NONE, 'Refresh the properties/methods list, but keep the text'], @@ -817,17 +823,34 @@ class ModelsCommand extends Command } $serializer = new DocBlockSerializer(); - $serializer->getDocComment($phpdoc); $docComment = $serializer->getDocComment($phpdoc); + if ($this->write_mixin) { + $phpdocMixin = new DocBlock($reflection, new Context($namespace)); + // remove all mixin tags prefixed with IdeHelper + foreach ($phpdocMixin->getTagsByName('mixin') as $tag) { + if (Str::startsWith($tag->getContent(), 'IdeHelper')) { + $phpdocMixin->deleteTag($tag); + } + } + + $mixinClassName = "IdeHelper{$classname}"; + $phpdocMixin->appendTag(Tag::createInstance("@mixin {$mixinClassName}", $phpdocMixin)); + $mixinDocComment = $serializer->getDocComment($phpdocMixin); + // remove blank lines if there's no text + if (!$phpdocMixin->getText()) { + $mixinDocComment = preg_replace("/\s\*\s*\n/", '', $mixinDocComment); + } + } if ($this->write) { + $modelDocComment = $this->write_mixin ? $mixinDocComment : $docComment; $filename = $reflection->getFileName(); $contents = $this->files->get($filename); if ($originalDoc) { - $contents = str_replace($originalDoc, $docComment, $contents); + $contents = str_replace($originalDoc, $modelDocComment, $contents); } else { - $replace = "{$docComment}\n"; + $replace = "{$modelDocComment}\n"; $pos = strpos($contents, "final class {$classname}") ?: strpos($contents, "class {$classname}"); if ($pos !== false) { $contents = substr_replace($contents, $replace, $pos, 0); @@ -838,6 +861,7 @@ class ModelsCommand extends Command } } + $classname = $this->write_mixin ? $mixinClassName : $classname; $output = "namespace {$namespace}{\n{$docComment}\n\t{$keyword}class {$classname} extends \Eloquent "; if ($interfaceNames) { diff --git a/tests/Console/ModelsCommand/GeneratePhpdocWithMixin/Models/Post.php b/tests/Console/ModelsCommand/GeneratePhpdocWithMixin/Models/Post.php new file mode 100644 index 0000000..24d6981 --- /dev/null +++ b/tests/Console/ModelsCommand/GeneratePhpdocWithMixin/Models/Post.php @@ -0,0 +1,15 @@ +app->make(ModelsCommand::class); + + $tester = $this->runCommand($command, [ + '--write-mixin' => true, + ]); + + $this->assertSame(0, $tester->getStatusCode()); + $this->assertStringContainsString('Written new phpDocBlock to', $tester->getDisplay()); + $this->assertMatchesMockedSnapshot(); + } +} diff --git a/tests/Console/ModelsCommand/GeneratePhpdocWithMixin/__snapshots__/Test__test__1.php b/tests/Console/ModelsCommand/GeneratePhpdocWithMixin/__snapshots__/Test__test__1.php new file mode 100644 index 0000000..872469a --- /dev/null +++ b/tests/Console/ModelsCommand/GeneratePhpdocWithMixin/__snapshots__/Test__test__1.php @@ -0,0 +1,188 @@ + + */ + + +namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GeneratePhpdocWithMixin\Models{ +/** + * Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GeneratePhpdocWithMixin\Models\Post + * + * @property $someProp + * @method someMethod(string $method) + * @property integer $id + * @property string|null $char_nullable + * @property string $char_not_nullable + * @property string|null $string_nullable + * @property string $string_not_nullable + * @property string|null $text_nullable + * @property string $text_not_nullable + * @property string|null $medium_text_nullable + * @property string $medium_text_not_nullable + * @property string|null $long_text_nullable + * @property string $long_text_not_nullable + * @property integer|null $integer_nullable + * @property integer $integer_not_nullable + * @property integer|null $tiny_integer_nullable + * @property integer $tiny_integer_not_nullable + * @property integer|null $small_integer_nullable + * @property integer $small_integer_not_nullable + * @property integer|null $medium_integer_nullable + * @property integer $medium_integer_not_nullable + * @property integer|null $big_integer_nullable + * @property integer $big_integer_not_nullable + * @property integer|null $unsigned_integer_nullable + * @property integer $unsigned_integer_not_nullable + * @property integer|null $unsigned_tiny_integer_nullable + * @property integer $unsigned_tiny_integer_not_nullable + * @property integer|null $unsigned_small_integer_nullable + * @property integer $unsigned_small_integer_not_nullable + * @property integer|null $unsigned_medium_integer_nullable + * @property integer $unsigned_medium_integer_not_nullable + * @property integer|null $unsigned_big_integer_nullable + * @property integer $unsigned_big_integer_not_nullable + * @property float|null $float_nullable + * @property float $float_not_nullable + * @property float|null $double_nullable + * @property float $double_not_nullable + * @property string|null $decimal_nullable + * @property string $decimal_not_nullable + * @property string|null $unsigned_decimal_nullable + * @property string $unsigned_decimal_not_nullable + * @property integer|null $boolean_nullable + * @property integer $boolean_not_nullable + * @property string|null $enum_nullable + * @property string $enum_not_nullable + * @property string|null $json_nullable + * @property string $json_not_nullable + * @property string|null $jsonb_nullable + * @property string $jsonb_not_nullable + * @property string|null $date_nullable + * @property string $date_not_nullable + * @property string|null $datetime_nullable + * @property string $datetime_not_nullable + * @property string|null $datetimetz_nullable + * @property string $datetimetz_not_nullable + * @property string|null $time_nullable + * @property string $time_not_nullable + * @property string|null $timetz_nullable + * @property string $timetz_not_nullable + * @property string|null $timestamp_nullable + * @property string $timestamp_not_nullable + * @property string|null $timestamptz_nullable + * @property string $timestamptz_not_nullable + * @property integer|null $year_nullable + * @property integer $year_not_nullable + * @property mixed|null $binary_nullable + * @property mixed $binary_not_nullable + * @property string|null $uuid_nullable + * @property string $uuid_not_nullable + * @property string|null $ipaddress_nullable + * @property string $ipaddress_not_nullable + * @property string|null $macaddress_nullable + * @property string $macaddress_not_nullable + * @property \Illuminate\Support\Carbon|null $created_at + * @property \Illuminate\Support\Carbon|null $updated_at + * @method static \Illuminate\Database\Eloquent\Builder|Post newModelQuery() + * @method static \Illuminate\Database\Eloquent\Builder|Post newQuery() + * @method static \Illuminate\Database\Eloquent\Builder|Post query() + * @method static \Illuminate\Database\Eloquent\Builder|Post whereBigIntegerNotNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereBigIntegerNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereBinaryNotNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereBinaryNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereBooleanNotNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereBooleanNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereCharNotNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereCharNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereCreatedAt($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereDateNotNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereDateNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereDatetimeNotNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereDatetimeNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereDatetimetzNotNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereDatetimetzNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereDecimalNotNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereDecimalNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereDoubleNotNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereDoubleNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereEnumNotNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereEnumNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereFloatNotNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereFloatNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereId($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereIntegerNotNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereIntegerNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereIpaddressNotNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereIpaddressNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereJsonNotNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereJsonNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereJsonbNotNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereJsonbNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereLongTextNotNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereLongTextNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereMacaddressNotNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereMacaddressNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereMediumIntegerNotNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereMediumIntegerNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereMediumTextNotNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereMediumTextNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereSmallIntegerNotNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereSmallIntegerNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereStringNotNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereStringNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereTextNotNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereTextNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereTimeNotNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereTimeNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereTimestampNotNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereTimestampNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereTimestamptzNotNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereTimestamptzNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereTimetzNotNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereTimetzNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereTinyIntegerNotNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereTinyIntegerNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereUnsignedBigIntegerNotNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereUnsignedBigIntegerNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereUnsignedDecimalNotNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereUnsignedDecimalNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereUnsignedIntegerNotNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereUnsignedIntegerNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereUnsignedMediumIntegerNotNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereUnsignedMediumIntegerNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereUnsignedSmallIntegerNotNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereUnsignedSmallIntegerNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereUnsignedTinyIntegerNotNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereUnsignedTinyIntegerNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereUpdatedAt($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereUuidNotNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereUuidNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereYearNotNullable($value) + * @method static \Illuminate\Database\Eloquent\Builder|Post whereYearNullable($value) + * @mixin \Eloquent + */ + class IdeHelperPost extends \Eloquent {} +} +