Compare commits

...
48 Commits
Author SHA1 Message Date
Barry vd. Heuvel e82de98cef Add Eloquent methods back 2017-02-22 13:27:33 +01:00
arasharg 456853be46 ignore intermediate table models (#454) 2017-02-22 08:59:06 +01:00
Barry vd. Heuvel 25c8de637d Skip eloquent
Fixes #https://github.com/barryvdh/laravel-ide-helper/issues/451
2017-02-20 13:54:53 +01:00
Emmanuel Maggion 5a841a209d Fix case (#452) 2017-02-20 11:52:55 +01:00
Barry vd. Heuvel 56660cab84 Update composer.json 2017-02-14 16:45:07 +01:00
Zimin Cao 555d3e3700 Add documentation in readme.md for Laravel Fluent methods support (#446)
* Added readme for Fluent methods

* Add readme for Laravel Fluent methods
2017-02-13 20:20:12 +01:00
Tommi Finnilae 963ead0a01 Correct Fluent helper output (#445)
'references()' and 'on()' argument names were backwards
2017-02-13 12:53:06 +01:00
Florian Lefèvre 8c306035aa Fix facades fullpath autocomplete (#441)
* Add method to retrieve namespace of extended class

* Regroup classes by namespace of the class they extends

* Restore facades shortnames

* Fix classnames used for methods declaration
2017-02-13 12:52:36 +01:00
Barry vd. Heuvel f1e93f042d Update helper.php 2017-02-03 15:05:31 +01:00
Charles Peterson 5280b47750 readme spelling (#436)
just a couple spelling fixes for the readme file.
2017-02-01 09:59:19 +01:00
Florian Lefèvre 525733122e Add facades fullpath autocomplete (#437)
* Add method to retrieve namespace of extended class

* Regroup classes by namespace of the class they extends

* Restore facades shortnames
2017-02-01 07:21:31 +01:00
Django Eijgensteijn a7fc2ec489 Sorting model docs (#424) 2017-01-05 22:20:42 +01:00
Barry vd. Heuvel 8caca941b3 Update IdeHelperServiceProvider.php 2017-01-05 10:02:31 +01:00
Barry vd. Heuvel e96943fe6f Use singleton instead of share 2017-01-05 09:58:45 +01:00
Barry vd. Heuvel df3ecb2843 Update composer.json 2016-12-09 12:13:18 +01:00
Jackey Cheung 105f14a50d Add Fluent helpers (using config option) (#404)
* add fluent option to Generator

* add fluent to helper output

* add fluent option to config

* typo
2016-11-15 09:21:23 +01:00
Barry vd. Heuvel 5fad258f5d Merge pull request #397 from ockle/scope-typehints
Scope parameter typehints
2016-10-13 09:23:59 +02:00
ockle 13e65d3885 if model scope method parameters have typehints, add them to the docblock 2016-10-12 21:53:42 +01:00
Barry vd. Heuvel 22612733a2 Merge pull request #389 from pinepain/return_type
Use accessor docblock return type to guess property type
2016-09-08 08:54:27 +02:00
Barry vd. Heuvel dc476f9736 Merge pull request #388 from KarimGeiger/master
Fix "Using $this when not in object context" bug
2016-09-07 15:05:31 +02:00
Bogdan Padalko 71cb03ca6a Use accessor docblock return type to guess property type 2016-09-06 12:24:42 +03:00
Karim Geiger abe2df5853 Fix "Using $this when not in object context" bug
This commit fixes the "Using $this when not in object context" bug for the Lumen configuration. Since the `bootstrap/app.php`-file is not in object context, and the `app` instance accessible using the `$app` variable directly, using `$this->app` will result in a fatal error.
2016-09-05 23:24:04 +02:00
Barry vd. Heuvel 2de6ab6038 Merge pull request #387 from DarkGhostHunter/master
Update readme.md
2016-09-03 00:21:49 +02:00
Italo c229335651 Update readme.md
Typos and H2
2016-09-02 19:14:12 -03:00
Italo 495361e501 Update readme.md 2016-09-02 13:44:58 -03:00
Barry vd. Heuvel 7583353915 Merge pull request #386 from dimsav/patch-1
Minor style fix in readme
2016-09-02 16:16:38 +02:00
Dimitris Savvopoulos 16c570c589 Minor style fix in readme 2016-09-02 12:50:36 +03:00
Barry vd. Heuvel 884eaeeb1a Check if getCasts() exists
Fixes #382
2016-08-26 13:37:21 +02:00
Barry vd. Heuvel b6706683b2 Merge pull request #380 from ellisio/patch-1
hotfix for type overrides
2016-08-26 13:27:42 +02:00
Andrew Ellis 6f9b90c204 hotfix for type overrides
Oops, looks like I forgot to commit one call to the new method. This is related to #377.
2016-08-25 18:53:51 -06:00
Barry vd. Heuvel e1a0f034a1 Merge pull request #377 from ellisio/type-overrides
Allow Type Overrides
2016-08-24 22:41:37 +02:00
Andrew Ellis b75f879383 uncommented defaults 2016-08-24 14:23:02 -06:00
Andrew Ellis ad800d197f and one more blank line fix for travis-ci 2016-08-19 12:39:16 -06:00
Andrew Ellis f3a3533b2d fixed blank line errors for travis-ci build 2016-08-19 12:37:17 -06:00
Andrew Ellis e938cd3a31 added missing comma 2016-08-19 12:25:22 -06:00
Andrew Ellis f8c6ec95f6 allow a user to define the type overrides 2016-08-19 12:20:34 -06:00
Barry vd. Heuvel 0a4ff969d2 Merge pull request #375 from leo108/master
add support for $casts
2016-08-19 09:26:14 +02:00
leo108 4b47c0b61c add support for $casts 2016-08-19 07:35:07 +08:00
Barry vd. Heuvel 7598293bc6 Merge pull request #372 from chrisforrence/readme-updates
README updates
2016-08-14 18:38:30 +02:00
Chris Forrence 035b14176b Add instructions on installing for development 2016-08-12 17:39:45 -04:00
Chris Forrence cb08c6ff81 Grammar-related changes 2016-08-12 17:28:25 -04:00
Barry vd. Heuvel 28af7cd19c Update composer.json 2016-07-04 13:52:48 +02:00
Barry vd. Heuvel 8f004f5d6b Merge pull request #326 from valorin/master
Allow for camel case model properties.
2016-07-04 13:45:34 +02:00
Barry vd. Heuvel da677f1ba5 Merge pull request #357 from tnorthcutt/patch-1
An --> A
2016-07-04 13:44:48 +02:00
Barry vd. Heuvel 321844d9a5 Merge pull request #361 from cnanney/patch-1
Use FQN for app() methods
2016-06-29 21:27:36 +02:00
Chris Nanney 928389d7a4 Use FQN for app() methods 2016-06-29 10:21:17 -05:00
Travis Northcutt dbfcfd66c5 An --> A 2016-06-14 07:23:16 -06:00
Stephen Rees-Carter a72cd81e5f Allow for camel case model properties. 2016-03-03 21:36:10 +11:00
9 changed files with 362 additions and 37 deletions
+4 -4
View File
@@ -11,9 +11,9 @@
], ],
"require": { "require": {
"php": ">=5.4.0", "php": ">=5.4.0",
"illuminate/support": "^5.0,<5.4", "illuminate/support": "^5.0,<5.5",
"illuminate/console": "^5.0,<5.4", "illuminate/console": "^5.0,<5.5",
"illuminate/filesystem": "^5.0,<5.4", "illuminate/filesystem": "^5.0,<5.5",
"barryvdh/reflection-docblock": "^2.0.4", "barryvdh/reflection-docblock": "^2.0.4",
"symfony/class-loader": "^2.3|^3.0" "symfony/class-loader": "^2.3|^3.0"
}, },
@@ -42,7 +42,7 @@
}, },
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "2.1-dev" "dev-master": "2.3-dev"
} }
} }
} }
+52 -3
View File
@@ -1,4 +1,4 @@
<?php <?php
return array( return array(
@@ -14,6 +14,17 @@ return array(
'filename' => '_ide_helper', 'filename' => '_ide_helper',
'format' => 'php', 'format' => 'php',
/*
|--------------------------------------------------------------------------
| Fluent helpers
|--------------------------------------------------------------------------
|
| Set to true to generate commonly used Fluent methods
|
*/
'include_fluent' => false,
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| Helper files to include | Helper files to include
@@ -71,7 +82,7 @@ return array(
'emergency' => 'Monolog\Logger::addEmergency', 'emergency' => 'Monolog\Logger::addEmergency',
) )
), ),
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| Interface implementations | Interface implementations
@@ -81,7 +92,7 @@ return array(
| are detected by the helpers, others can be listed below. | are detected by the helpers, others can be listed below.
| |
*/ */
'interfaces' => array( 'interfaces' => array(
), ),
@@ -116,4 +127,42 @@ return array(
), ),
/*
|--------------------------------------------------------------------------
| Support for camel cased models
|--------------------------------------------------------------------------
|
| There are some Laravel packages (such as Eloquence) that allow for accessing
| Eloquent model properties via camel case, instead of snake case.
|
| Enabling this option will support these packages by saving all model
| properties as camel case, instead of snake case.
|
| For example, normally you would see this:
|
| * @property \Carbon\Carbon $created_at
| * @property \Carbon\Carbon $updated_at
|
| With this enabled, the properties will be this:
|
| * @property \Carbon\Carbon $createdAt
| * @property \Carbon\Carbon $updatedAt
|
| Note, it is currently an all-or-nothing option.
|
*/
'model_camel_case_properties' => false,
/*
|--------------------------------------------------------------------------
| Property Casts
|--------------------------------------------------------------------------
|
| Cast the given "real type" to the given "type".
|
*/
'type_overrides' => array(
'integer' => 'int',
'boolean' => 'bool',
),
); );
+84 -5
View File
@@ -9,7 +9,7 @@ __For Laravel 4.x, check [version 1.11](https://github.com/barryvdh/laravel-ide-
### Complete phpDocs, directly from the source ### Complete phpDocs, directly from the source
_Checkout [this Laracasts video](https://laracasts.com/series/how-to-be-awesome-in-phpstorm/episodes/15) for a quick introduction/explanation!_ _Check out [this Laracasts video](https://laracasts.com/series/how-to-be-awesome-in-phpstorm/episodes/15) for a quick introduction/explanation!_
* [`php artisan ide-helper:generate` - phpDoc generation for Laravel Facades ](#automatic-phpdoc-generation-for-laravel-facades) * [`php artisan ide-helper:generate` - phpDoc generation for Laravel Facades ](#automatic-phpdoc-generation-for-laravel-facades)
* [`php artisan ide-helper:models` - phpDocs for models](#automatic-phpdocs-for-models) * [`php artisan ide-helper:models` - phpDocs for models](#automatic-phpdocs-for-models)
@@ -38,8 +38,27 @@ After updating composer, add the service provider to the `providers` array in `c
Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::class, Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::class,
``` ```
### Automatic phpDoc generation for Laravel Facades To install this package on only development systems, add the `--dev` flag to your composer command:
```bash
composer require --dev barryvdh/laravel-ide-helper
```
In Laravel, instead of adding the service provider in the `config/app.php` file, you can add the following code to your `app/Providers/AppServiceProvider.php` file, within the `register()` method:
```php
public function register()
{
if ($this->app->environment() !== 'production') {
$this->app->register(\Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::class);
}
// ...
}
```
This will allow your application to load the Laravel IDE Helper on non-production enviroments.
### Automatic phpDoc generation for Laravel Facades
You can now re-generate the docs yourself (for future updates) You can now re-generate the docs yourself (for future updates)
@@ -71,10 +90,10 @@ php artisan vendor:publish --provider="Barryvdh\LaravelIdeHelper\IdeHelperServic
The generator tries to identify the real class, but if it cannot be found, you can define it in the config file. The generator tries to identify the real class, but if it cannot be found, you can define it in the config file.
Some classes need a working database connection. If you do not have a default working connection, some facades will not be included. Some classes need a working database connection. If you do not have a default working connection, some facades will not be included.
You can use an in-memory SQLite driver, using the -M option. You can use an in-memory SQLite driver by adding the -M option.
You can choose to include helper files. This is not enabled by default, but you can override it with the `--helpers (-H)` option. You can choose to include helper files. This is not enabled by default, but you can override it with the `--helpers (-H)` option.
The `Illuminate/Support/helpers.php` is already set-up, but you can add/remove your own files in the config file. The `Illuminate/Support/helpers.php` is already set up, but you can add/remove your own files in the config file.
### Automatic phpDocs for models ### Automatic phpDocs for models
@@ -132,9 +151,21 @@ php artisan ide-helper:models --ignore="Post,User"
Note: With namespaces, wrap your model name in " signs: `php artisan ide-helper:models "API\User"`, or escape the slashes (`Api\\User`) Note: With namespaces, wrap your model name in " signs: `php artisan ide-helper:models "API\User"`, or escape the slashes (`Api\\User`)
### Automatic phpDocs generation for Laravel Fluent methods
If you need phpDocs support for Fluent methods in migration, for example
```php
$table->string(“somestring”)->nullable()->index();
```
After publishing vendor, simply change the `include_fluent` line your `config/ide-helper.php` file into:
```php
'include_fluent' => true,
```
And then run `php artisan ide-helper:generate` , you will now see all of the Fluent methods are recognized by your IDE now.
## PhpStorm Meta for Container instances ## PhpStorm Meta for Container instances
It's possible to generate a PhpStorm meta file, to [add support for factory design pattern](https://confluence.jetbrains.com/display/PhpStorm/PhpStorm+Advanced+Metadata). For Laravel, this means we can make PhpStorm understand what kind of object we are resolving from the IoC Container. For example, `events` will return an `Illuminate\Events\Dispatcher` object, so with the meta file you can call `app('events')` and it will autocomplete the Dispatcher methods. It's possible to generate a PhpStorm meta file to [add support for factory design pattern](https://confluence.jetbrains.com/display/PhpStorm/PhpStorm+Advanced+Metadata). For Laravel, this means we can make PhpStorm understand what kind of object we are resolving from the IoC Container. For example, `events` will return an `Illuminate\Events\Dispatcher` object, so with the meta file you can call `app('events')` and it will autocomplete the Dispatcher methods.
``` bash ``` bash
php artisan ide-helper:meta php artisan ide-helper:meta
@@ -156,6 +187,54 @@ Pre-generated example: https://gist.github.com/barryvdh/bb6ffc5d11e0a75dba67
> Note: You might need to restart PhpStorm and make sure `.phpstorm.meta.php` is indexed. > Note: You might need to restart PhpStorm and make sure `.phpstorm.meta.php` is indexed.
> Note: When you receive a FatalException about a class that is not found, check your config (for example, remove S3 as cloud driver when you don't have S3 configured. Remove Redis ServiceProvider when you don't use it). > Note: When you receive a FatalException about a class that is not found, check your config (for example, remove S3 as cloud driver when you don't have S3 configured. Remove Redis ServiceProvider when you don't use it).
## Lumen Install
This package is focused on Laravel development, but it can also be used in Lumen with some workarounds. Because Lumen works a little different, as it is like a barebone version of Laravel and the main configuration parameters are instead located in `bootstrap/app.php`, some alterations must be made.
#### Enabling Facades
While Laravel IDE Helper can generate automatically default Facades for code hinting, Lumen doesn't come with Facades activated. If you plan in using them, you must enable them under the `Create The Application` section, uncommenting this line:
```php
// $app->withFacades();
```
From there, you should be able to use the `create_alias()` function to add additional Facades into your application.
#### Adding the Service Provider
You can install Laravel IDE Helper in `app/Providers/AppServiceProvider.php`, and uncommenting this line that registers the App Service Providers so it can properly load.
```php
// $app->register(App\Providers\AppServiceProvider::class);
```
If you are not using that line, that is usually handy to manage gracefully multiple Laravel/Lumen installations, you will have to add this line of code under the `Register Service Providers` section of your `bootstrap/app.php`.
```php
if ($app->environment() !== 'production') {
$app->register(\Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::class);
}
```
After that, Laravel IDE Helper should work correctly. During the generation process, the script may throw exceptions saying that some Class(s) doesn't exist or there are some undefined indexes. This is normal, as Lumen has some default packages stripped away, like Cookies, Storage and Session. If you plan to add these packages, you will have to add them manually and create additional Facades if needed.
#### Adding Additional Facades
Currently Lumen IDE Helper doesn't take into account additional Facades created under `bootstrap/app.php` using `create_alias()`, so you need to create a `config/app.php` file and add your custom aliases under an `aliases` array again, like so:
```php
return [
'aliases' => [
'CustomAliasOne' => Example\Support\Facades\CustomAliasOne::class,
'CustomAliasTwo' => Example\Support\Facades\CustomAliasTwo::class,
//...
]
];
```
After you run ```php artisan ide-helper:generate```, it's recommended (but not mandatory) to rename `config/app.php` to something else until you have to re-generate the docs or after passing to production enviroment. Lumen 5.1+ will read this file for configuration parameters if it is present, and may overlap some configurations if it is completely populated.
### License ### License
The Laravel IDE Helper Generator is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT) The Laravel IDE Helper Generator is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT)
+60 -10
View File
@@ -7,21 +7,22 @@
* @author Barry vd. Heuvel <[email protected]> * @author Barry vd. Heuvel <[email protected]>
* @see https://github.com/barryvdh/laravel-ide-helper * @see https://github.com/barryvdh/laravel-ide-helper
*/ */
namespace {
exit("This file should not be included, only analyzed by your IDE");
}
<?php foreach($namespaces as $namespace => $aliases): ?> <?php foreach($namespaces as $namespace => $aliases): ?>
namespace <?= $namespace == '__root' ? '' : $namespace ?>{ <?php if ($namespace == '\Illuminate\Database\Eloquent'): continue; endif; ?>
<?php if($namespace == '__root'): ?> namespace <?= $namespace == '__root' ? '' : trim($namespace, '\\') ?> {
exit("This file should not be included, only analyzed by your IDE");
<?= $helpers ?>
<?php endif; ?>
<?php foreach($aliases as $alias): ?> <?php foreach($aliases as $alias): ?>
<?= $alias->getClassType() ?> <?= $alias->getShortName() ?> <?= $alias->getExtends() ? 'extends ' . $alias->getExtends() : '' ?>{ <?= $alias->getClassType() ?> <?= $alias->getExtendsClass() ?> {
<?php foreach($alias->getMethods() as $method): ?> <?php foreach($alias->getMethods() as $method): ?>
<?= trim($method->getDocComment(' ')) ?> <?= trim($method->getDocComment(' ')) ?>
public static function <?= $method->getName() ?>(<?= $method->getParamsWithDefault() ?>){<?php if($method->getDeclaringClass() !== $method->getRoot()): ?> public static function <?= $method->getName() ?>(<?= $method->getParamsWithDefault() ?>)
{<?php if($method->getDeclaringClass() !== $method->getRoot()): ?>
//Method inherited from <?= $method->getDeclaringClass() ?> //Method inherited from <?= $method->getDeclaringClass() ?>
<?php endif; ?> <?php endif; ?>
@@ -30,10 +31,59 @@ namespace <?= $namespace == '__root' ? '' : $namespace ?>{
} }
<?php endforeach; ?> <?php endforeach; ?>
} }
<?php endforeach; ?> <?php endforeach; ?>
}
<?php endforeach; ?>
namespace {
<?= $helpers ?>
<?php foreach($namespaces as $namespace => $aliases): ?>
<?php foreach($aliases as $alias): ?>
<?= $alias->getClassType() ?> <?= $alias->getShortName() ?> extends <?= $alias->getExtends() ?> {<?php if ($namespace == '\Illuminate\Database\Eloquent'): ?>
<?php foreach($alias->getMethods() as $method): ?>
<?= trim($method->getDocComment(' ')) ?>
public static function <?= $method->getName() ?>(<?= $method->getParamsWithDefault() ?>)
{<?php if($method->getDeclaringClass() !== $method->getRoot()): ?>
//Method inherited from <?= $method->getDeclaringClass() ?>
<?php endif; ?>
<?= $method->shouldReturn() ? 'return ': '' ?><?= $method->getRoot() ?>::<?= $method->getName() ?>(<?= $method->getParams() ?>);
}
<?php endforeach; ?>
<?php endif; ?>}
<?php endforeach; ?>
<?php endforeach; ?>
} }
<?php endforeach; ?> <?php if($include_fluent): ?>
namespace Illuminate\Support {
/**
* Methods commonly used in migrations
*
* @method Fluent after(string $column) Add the after modifier
* @method Fluent charset(string $charset) Add the character set modifier
* @method Fluent collation(string $collation) Add the collation modifier
* @method Fluent comment(string $comment) Add comment
* @method Fluent default(mixed $value) Add the default modifier
* @method Fluent first() Select first row
* @method Fluent index(string $name = null) Add the in dex clause
* @method Fluent on(string $table) `on` of a foreign key
* @method Fluent onDelete(string $action) `on delete` of a foreign key
* @method Fluent onUpdate(string $action) `on update` of a foreign key
* @method Fluent primary() Add the primary key modifier
* @method Fluent references(string $column) `references` of a foreign key
* @method Fluent nullable() Add the nullable modifier
* @method Fluent unique(string $name = null) Add unique index clause
* @method Fluent unsigned() Add the unsigned modifier
* @method Fluent useCurrent() Add the default timestamp value
*/
class Fluent {}
}
<?php endif ?>
+35
View File
@@ -15,6 +15,8 @@ class Alias
protected $alias; protected $alias;
protected $facade; protected $facade;
protected $extends = null; protected $extends = null;
protected $extendsClass = null;
protected $extendsNamespace = null;
protected $classType = 'class'; protected $classType = 'class';
protected $short; protected $short;
protected $namespace = '__root'; protected $namespace = '__root';
@@ -53,6 +55,7 @@ class Alias
$this->addClass($this->root); $this->addClass($this->root);
$this->detectNamespace(); $this->detectNamespace();
$this->detectClassType(); $this->detectClassType();
$this->detectExtendsNamespace();
if ($facade === '\Illuminate\Database\Eloquent\Model') { if ($facade === '\Illuminate\Database\Eloquent\Model') {
$this->usedMethods = array('decrement', 'increment'); $this->usedMethods = array('decrement', 'increment');
@@ -104,6 +107,26 @@ class Alias
{ {
return $this->extends; return $this->extends;
} }
/**
* Get the class short name which this alias extends
*
* @return null|string
*/
public function getExtendsClass()
{
return $this->extendsClass;
}
/**
* Get the namespace of the class which this alias extends
*
* @return null|string
*/
public function getExtendsNamespace()
{
return $this->extendsNamespace;
}
/** /**
* Get the Alias by which this class is called * Get the Alias by which this class is called
@@ -157,6 +180,18 @@ class Alias
$this->short = $this->alias; $this->short = $this->alias;
} }
} }
/**
* Detect the extends namespace
*/
protected function detectExtendsNamespace()
{
if (strpos($this->extends, '\\') !== false) {
$nsParts = explode('\\', $this->extends);
$this->extendsClass = array_pop($nsParts);
$this->extendsNamespace = implode('\\', $nsParts);
}
}
/** /**
* Detect the class type * Detect the class type
+1 -1
View File
@@ -47,7 +47,7 @@ class MetaCommand extends Command
'new \Illuminate\Contracts\Container\Container', 'new \Illuminate\Contracts\Container\Container',
'\Illuminate\Contracts\Container\Container::make(\'\')', '\Illuminate\Contracts\Container\Container::make(\'\')',
'\App::make(\'\')', '\App::make(\'\')',
'app(\'\')', '\app(\'\')',
]; ];
/** /**
+115 -6
View File
@@ -140,7 +140,7 @@ class ModelsCommand extends Command
$output = "<?php $output = "<?php
/** /**
* An helper file for your Eloquent Models * A helper file for your Eloquent Models
* Copy the phpDocs from this file to the correct Model, * Copy the phpDocs from this file to the correct Model,
* And remove them from this file, to prevent double declarations. * And remove them from this file, to prevent double declarations.
* *
@@ -175,7 +175,8 @@ class ModelsCommand extends Command
// handle abstract classes, interfaces, ... // handle abstract classes, interfaces, ...
$reflectionClass = new \ReflectionClass($name); $reflectionClass = new \ReflectionClass($name);
if (!$reflectionClass->isSubclassOf('Illuminate\Database\Eloquent\Model')) { if (!$reflectionClass->isSubclassOf('Illuminate\Database\Eloquent\Model')
|| $reflectionClass->isSubclassOf('Illuminate\Database\Eloquent\Relations\Pivot')) {
continue; continue;
} }
@@ -194,6 +195,10 @@ class ModelsCommand extends Command
$this->getPropertiesFromTable($model); $this->getPropertiesFromTable($model);
} }
if (method_exists($model, 'getCasts')) {
$this->castPropertiesType($model);
}
$this->getPropertiesFromMethods($model); $this->getPropertiesFromMethods($model);
$output .= $this->createPhpDocs($name); $output .= $this->createPhpDocs($name);
$ignore[] = $name; $ignore[] = $name;
@@ -211,7 +216,6 @@ class ModelsCommand extends Command
} }
return $output; return $output;
} }
@@ -229,6 +233,73 @@ class ModelsCommand extends Command
return $models; return $models;
} }
/**
* cast the properties's type from $casts.
*
* @param \Illuminate\Database\Eloquent\Model $model
*/
protected function castPropertiesType($model)
{
$casts = $model->getCasts();
foreach ($casts as $name => $type) {
switch ($type) {
case 'boolean':
case 'bool':
$realType = 'boolean';
break;
case 'string':
$realType = 'string';
break;
case 'array':
case 'json':
$realType = 'array';
break;
case 'object':
$realType = 'object';
break;
case 'int':
case 'integer':
case 'timestamp':
$realType = 'integer';
break;
case 'real':
case 'double':
case 'float':
$realType = 'float';
break;
case 'date':
case 'datetime':
$realType = '\Carbon\Carbon';
break;
case 'collection':
$realType = '\Illuminate\Support\Collection';
break;
default:
$realType = 'mixed';
break;
}
if (!isset($this->properties[$name])) {
continue;
} else {
$this->properties[$name]['type'] = $this->getTypeOverride($realType);
}
}
}
/**
* Returns the overide type for the give type.
*
* @param string $type
* @return string
*/
protected function getTypeOverride($type)
{
$typeOverrides = $this->laravel['config']->get('ide-helper.type_overrides', array());
return isset($typeOverrides[$type]) ? $typeOverrides[$type] : $type;
}
/** /**
* Load the properties from the database table. * Load the properties from the database table.
* *
@@ -307,6 +378,7 @@ class ModelsCommand extends Command
{ {
$methods = get_class_methods($model); $methods = get_class_methods($model);
if ($methods) { if ($methods) {
sort($methods);
foreach ($methods as $method) { foreach ($methods as $method) {
if (Str::startsWith($method, 'get') && Str::endsWith( if (Str::startsWith($method, 'get') && Str::endsWith(
$method, $method,
@@ -316,7 +388,9 @@ class ModelsCommand extends Command
//Magic get<name>Attribute //Magic get<name>Attribute
$name = Str::snake(substr($method, 3, -9)); $name = Str::snake(substr($method, 3, -9));
if (!empty($name)) { if (!empty($name)) {
$this->setProperty($name, null, true, null); $reflection = new \ReflectionMethod($model, $method);
$type = $this->getReturnTypeFromDocBlock($reflection);
$this->setProperty($name, $type, true, null);
} }
} elseif (Str::startsWith($method, 'set') && Str::endsWith( } elseif (Str::startsWith($method, 'set') && Str::endsWith(
$method, $method,
@@ -421,7 +495,7 @@ class ModelsCommand extends Command
$this->properties[$name]['comment'] = (string) $comment; $this->properties[$name]['comment'] = (string) $comment;
} }
if ($type !== null) { if ($type !== null) {
$this->properties[$name]['type'] = $type; $this->properties[$name]['type'] = $this->getTypeOverride($type);
} }
if ($read !== null) { if ($read !== null) {
$this->properties[$name]['read'] = $read; $this->properties[$name]['read'] = $read;
@@ -487,11 +561,18 @@ class ModelsCommand extends Command
} else { } else {
$attr = 'property-read'; $attr = 'property-read';
} }
if ($this->hasCamelCaseModelProperties()) {
$name = Str::camel($name);
}
$tagLine = trim("@{$attr} {$property['type']} {$name} {$property['comment']}"); $tagLine = trim("@{$attr} {$property['type']} {$name} {$property['comment']}");
$tag = Tag::createInstance($tagLine, $phpdoc); $tag = Tag::createInstance($tagLine, $phpdoc);
$phpdoc->appendTag($tag); $phpdoc->appendTag($tag);
} }
ksort($this->methods);
foreach ($this->methods as $name => $method) { foreach ($this->methods as $name => $method) {
if (in_array($name, $methods)) { if (in_array($name, $methods)) {
continue; continue;
@@ -545,7 +626,8 @@ class ModelsCommand extends Command
$paramsWithDefault = array(); $paramsWithDefault = array();
/** @var \ReflectionParameter $param */ /** @var \ReflectionParameter $param */
foreach ($method->getParameters() as $param) { foreach ($method->getParameters() as $param) {
$paramStr = '$' . $param->getName(); $paramClass = $param->getClass();
$paramStr = (!is_null($paramClass) ? '\\' . $paramClass->getName() . ' ' : '') . '$' . $param->getName();
$params[] = $paramStr; $params[] = $paramStr;
if ($param->isOptional() && $param->isDefaultValueAvailable()) { if ($param->isOptional() && $param->isDefaultValueAvailable()) {
$default = $param->getDefaultValue(); $default = $param->getDefaultValue();
@@ -586,4 +668,31 @@ class ModelsCommand extends Command
$model = new $className; $model = new $className;
return '\\' . get_class($model->newCollection()); return '\\' . get_class($model->newCollection());
} }
/**
* @return bool
*/
protected function hasCamelCaseModelProperties()
{
return $this->laravel['config']->get('ide-helper.model_camel_case_properties', false);
}
/**
* Get method return type based on it DocBlock comment
*
* @param \ReflectionMethod $reflection
*
* @return null|string
*/
protected function getReturnTypeFromDocBlock(\ReflectionMethod $reflection)
{
$type = null;
$phpdoc = new DocBlock($reflection);
if ($phpdoc->hasTag('return')) {
$type = $phpdoc->getTagsByName('return')[0]->getContent();
}
return $type;
}
} }
+5 -5
View File
@@ -84,6 +84,7 @@ class Generator
->with('namespaces', $this->getNamespaces()) ->with('namespaces', $this->getNamespaces())
->with('helpers', $this->helpers) ->with('helpers', $this->helpers)
->with('version', $app->version()) ->with('version', $app->version())
->with('include_fluent', $this->config->get('ide-helper.include_fluent', false))
->render(); ->render();
} }
@@ -118,7 +119,7 @@ class Generator
{ {
$defaultUserModel = config('auth.providers.users.model', config('auth.model', 'App\User')); $defaultUserModel = config('auth.providers.users.model', config('auth.model', 'App\User'));
$this->interfaces['\Illuminate\Contracts\Auth\Authenticatable'] = $defaultUserModel; $this->interfaces['\Illuminate\Contracts\Auth\Authenticatable'] = $defaultUserModel;
try { try {
if (class_exists('Auth') && is_a('Auth', '\Illuminate\Support\Facades\Auth', true)) { if (class_exists('Auth') && is_a('Auth', '\Illuminate\Support\Facades\Auth', true)) {
if (class_exists('\Illuminate\Foundation\Application')) { if (class_exists('\Illuminate\Foundation\Application')) {
@@ -182,7 +183,6 @@ class Generator
} }
} catch (\Exception $e) { } catch (\Exception $e) {
} }
} }
/** /**
@@ -200,7 +200,7 @@ class Generator
if ($facade == 'Illuminate\Support\Facades\Redis' && !class_exists('Predis\Client')) { if ($facade == 'Illuminate\Support\Facades\Redis' && !class_exists('Predis\Client')) {
continue; continue;
} }
$magicMethods = array_key_exists($name, $this->magic) ? $this->magic[$name] : array(); $magicMethods = array_key_exists($name, $this->magic) ? $this->magic[$name] : array();
$alias = new Alias($name, $facade, $magicMethods, $this->interfaces); $alias = new Alias($name, $facade, $magicMethods, $this->interfaces);
if ($alias->isValid()) { if ($alias->isValid()) {
@@ -209,7 +209,7 @@ class Generator
$alias->addClass($this->extra[$name]); $alias->addClass($this->extra[$name]);
} }
$namespace = $alias->getNamespace(); $namespace = $alias->getExtendsNamespace() ?: $alias->getNamespace();
if (!isset($namespaces[$namespace])) { if (!isset($namespaces[$namespace])) {
$namespaces[$namespace] = array(); $namespaces[$namespace] = array();
} }
@@ -246,7 +246,7 @@ class Generator
'Storage' => 'Illuminate\Support\Facades\Storage', 'Storage' => 'Illuminate\Support\Facades\Storage',
//'Validator' => 'Illuminate\Support\Facades\Validator', //'Validator' => 'Illuminate\Support\Facades\Validator',
]; ];
$facades = array_merge($facades, $this->config->get('app.aliases', [])); $facades = array_merge($facades, $this->config->get('app.aliases', []));
// Only return the ones that actually exist // Only return the ones that actually exist
+6 -3
View File
@@ -54,19 +54,22 @@ class IdeHelperServiceProvider extends ServiceProvider
$configPath = __DIR__ . '/../config/ide-helper.php'; $configPath = __DIR__ . '/../config/ide-helper.php';
$this->mergeConfigFrom($configPath, 'ide-helper'); $this->mergeConfigFrom($configPath, 'ide-helper');
$this->app['command.ide-helper.generate'] = $this->app->share( $this->app->singleton(
'command.ide-helper.generate',
function ($app) { function ($app) {
return new GeneratorCommand($app['config'], $app['files'], $app['view']); return new GeneratorCommand($app['config'], $app['files'], $app['view']);
} }
); );
$this->app['command.ide-helper.models'] = $this->app->share( $this->app->singleton(
'command.ide-helper.models',
function ($app) { function ($app) {
return new ModelsCommand($app['files']); return new ModelsCommand($app['files']);
} }
); );
$this->app['command.ide-helper.meta'] = $this->app->share( $this->app->singleton(
'command.ide-helper.meta',
function ($app) { function ($app) {
return new MetaCommand($app['files'], $app['view']); return new MetaCommand($app['files'], $app['view']);
} }