Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add comments like table columns. #1168

Merged
merged 8 commits into from
Mar 15, 2021
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,33 @@ You may use the [`::withCount`](https://laravel.com/docs/master/eloquent-relatio

By default, these attributes are generated in the phpdoc. You can turn them off by setting the config `write_model_relation_count_properties` to `false`.

#### Support `@comment` based on DocBlock

In order to better support ide, relations and getters/setters can also add comments like table columns. Only based on DocBlock, use `@comment`. example:
biiiiiigmonster marked this conversation as resolved.
Show resolved Hide resolved
```php
class Users extends Model
{
/**
* @comment Get User's full name
*
* @return string
*/
public function getFullNameAttribute(): string
{
return $this->first_name . ' ' .$this->last_name ;
}
}

// => after generate models

/**
* App\Models\Users
*
* @property-read string $full_name Get User's full name
* …
*/
```

#### Dedicated Eloquent Builder methods

A new method to the eloquent models was added called `newEloquentBuilder` [Reference](https://timacdonald.me/dedicated-eloquent-model-query-builders/) where we can
Expand Down
53 changes: 45 additions & 8 deletions src/Console/ModelsCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,8 @@ protected function getPropertiesFromMethods($model)
$reflection = new \ReflectionMethod($model, $method);
$type = $this->getReturnType($reflection);
$type = $this->getTypeInModel($model, $type);
$this->setProperty($name, $type, true, null);
$comment = $this->getCommentFromDocBlock($reflection);
$this->setProperty($name, $type, true, null, $comment);
}
} elseif (
Str::startsWith($method, 'set') && Str::endsWith(
Expand All @@ -538,13 +539,16 @@ protected function getPropertiesFromMethods($model)
//Magic set<name>Attribute
$name = Str::snake(substr($method, 3, -9));
if (!empty($name)) {
$this->setProperty($name, null, null, true);
$reflection = new \ReflectionMethod($model, $method);
$comment = $this->getCommentFromDocBlock($reflection);
$this->setProperty($name, null, null, true, $comment);
}
} elseif (Str::startsWith($method, 'scope') && $method !== 'scopeQuery') {
//Magic set<name>Attribute
$name = Str::camel(substr($method, 5));
if (!empty($name)) {
$reflection = new \ReflectionMethod($model, $method);
$comment = $this->getCommentFromDocBlock($reflection);
$args = $this->getParameters($reflection);
//Remove the first ($query) argument
array_shift($args);
Expand All @@ -556,7 +560,7 @@ protected function getPropertiesFromMethods($model)
$reflection->getDeclaringClass(),
$reflection->getDeclaringClass()->getName()
);
$this->setMethod($name, $builder . '|' . $modelName, $args);
$this->setMethod($name, $builder . '|' . $modelName, $args, $comment);
}
} elseif (in_array($method, ['query', 'newQuery', 'newModelQuery'])) {
$builder = $this->getClassNameInDestinationFile($model, get_class($model->newModelQuery()));
Expand Down Expand Up @@ -608,6 +612,7 @@ protected function getPropertiesFromMethods($model)
continue;
}

$comment = $this->getCommentFromDocBlock($reflection);
// Adding constraints requires reading model properties which
// can cause errors. Since we don't need constraints we can
// disable them when we fetch the relation to avoid errors.
Expand Down Expand Up @@ -639,14 +644,16 @@ protected function getPropertiesFromMethods($model)
$method,
$collectionClassNameInModel . '|' . $relatedModel . '[]',
true,
null
null,
$comment
);
if ($this->write_model_relation_count_properties) {
$this->setProperty(
Str::snake($method) . '_count',
'int|null',
true,
false
// What kind of comments should be added to the relation count here?
);
}
} elseif ($relation === 'morphTo') {
Expand All @@ -655,7 +662,8 @@ protected function getPropertiesFromMethods($model)
$method,
$this->getClassNameInDestinationFile($model, Model::class) . '|\Eloquent',
true,
null
null,
$comment
);
} else {
//Single model is returned
Expand All @@ -664,7 +672,7 @@ protected function getPropertiesFromMethods($model)
$relatedModel,
true,
null,
'',
$comment,
$this->isRelationNullable($relation, $relationObj)
);
}
Expand Down Expand Up @@ -737,14 +745,15 @@ protected function setProperty($name, $type = null, $read = null, $write = null,
}
}

protected function setMethod($name, $type = '', $arguments = [])
protected function setMethod($name, $type = '', $arguments = [], $comment = '')
{
$methods = array_change_key_case($this->methods, CASE_LOWER);

if (!isset($methods[strtolower($name)])) {
$this->methods[$name] = [];
$this->methods[$name]['type'] = $type;
$this->methods[$name]['arguments'] = $arguments;
$this->methods[$name]['comment'] = $comment;
}
}

Expand Down Expand Up @@ -820,7 +829,11 @@ protected function createPhpDocs($class)
continue;
}
$arguments = implode(', ', $method['arguments']);
$tag = Tag::createInstance("@method static {$method['type']} {$name}({$arguments})", $phpdoc);
$tagLine = "@method static {$method['type']} {$name}({$arguments})";
if ($method['comment'] !== '') {
$tagLine .= " {$method['comment']}";
}
$tag = Tag::createInstance($tagLine, $phpdoc);
$phpdoc->appendTag($tag);
}

Expand Down Expand Up @@ -980,6 +993,30 @@ protected function getReturnType(\ReflectionMethod $reflection): ?string
return $this->getReturnTypeFromReflection($reflection);
}

/**
* Get method comment based on it DocBlock comment
*
* @param \ReflectionMethod $reflection
*
* @return null|string
*/
protected function getCommentFromDocBlock(\ReflectionMethod $reflection)
{
$phpDocContext = (new ContextFactory())->createFromReflector($reflection);
$context = new Context(
$phpDocContext->getNamespace(),
$phpDocContext->getNamespaceAliases()
);
$comment = '';
$phpdoc = new DocBlock($reflection, $context);

if ($phpdoc->hasTag('comment')) {
$comment = $phpdoc->getTagsByName('comment')[0]->getContent();
}

return $comment;
}

/**
* Get method return type based on it DocBlock comment
*
Expand Down
136 changes: 136 additions & 0 deletions tests/Console/ModelsCommand/Comment/Models/Simple.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
<?php

declare(strict_types=1);

namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Comment\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\MorphTo;

class Simple extends Model
{
/**
* There is not comment.
*
* @return string
*/
public function getNotCommentAttribute(): string
{
}

/**
* comment There is not format comment, invalid.
*
* @return string
*/
public function getFakerCommentAttribute(): string
{
}

/**
* @comment There is format comment, success.
*
* @return string
*/
public function getFormatCommentAttribute(): string
{
}

/**
* @comment There is format comment, success.
* This is second line, success too.
*
* @return string
*/
public function getFormatCommentLineTwoAttribute(): string
{
}

/**
* @comment There is format comment, success.
* @comment This is others format comment, invalid.
*
* @return string
*/
public function getManyFormatCommentAttribute(): string
{
}

/**
* @comment Set the user's first name.
* @param $value
*/
public function setFirstNameAttribute($value)
{
}

/**
* @comment Scope a query to only include active users.
*
* @param $query
* @return mixed
*/
public function scopeActive($query)
{
return $query;
}

/**
* @comment HasMany relations.
*
* @return HasMany
*/
public function relationHasMany(): HasMany
{
return $this->hasMany(Simple::class);
}

/**
* @comment MorphTo relations.
* @return MorphTo
*/
public function relationMorphTo(): MorphTo
{
return $this->morphTo();
}

/**
* @comment Others relations.
* @return HasOne
*/
public function relationHasOne(): HasOne
{
return $this->hasOne(Simple::class);
}

/**
* @comment I'm a setter
*/
public function setBothSameNameAttribute(): void
{
}

/**
* @comment I'm a getter
* @return string
*/
public function getBothSameNameAttribute(): string
{
}

/**
* @comment I'm a setter
*/
public function setBothWithoutGetterCommentAttribute(): void
{
}

/**
* @return string
*/
public function getBothWithoutGetterCommentAttribute(): string
{
}
}
24 changes: 24 additions & 0 deletions tests/Console/ModelsCommand/Comment/Test.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

declare(strict_types=1);

namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Comment;

use Barryvdh\LaravelIdeHelper\Console\ModelsCommand;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\AbstractModelsCommand;

class Test extends AbstractModelsCommand
{
public function test(): void
{
$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());
$this->assertMatchesMockedSnapshot();
}
}
Loading