Compare commits

...
24 Commits
Author SHA1 Message Date
Barry vd. Heuvel 0a8e5436d4 Merge pull request #615 from nthachus/1.11
Update to release v1.11.7
2018-01-31 15:16:07 +01:00
Thach Nguyen 7c81b6388e Use class PhpReflection directly from Nette Framework instead of library parse-use-statements 2018-01-31 21:11:02 +07:00
Thach Nguyen 66d6e3df01 Highlight code syntax on README document 2018-01-31 20:10:23 +07:00
Thach Nguyen 1080504a78 - Improve MetaCommand to allow to ignore some abstract names
- Auto-correct `Method` FQN type name if missing first \
- Implement unit-tests
2018-01-31 19:53:24 +07:00
Thach Nguyen 647b8ff0d1 Reuse library "phpdocumentor/reflection-docblock" instead of "barryvdh/reflection-docblock" 2018-01-29 16:26:01 +07:00
Thach Nguyen 07e35d808c No need PhpDocSignatureInspection for _ide_helper when method doc-comment is empty 2018-01-27 03:48:06 +07:00
Thach Nguyen a44572676a Improve Method class to reduce generated filesize, and correct FQN types of phpDoc, and support case-insensitive @inheritdoc 2018-01-27 03:27:07 +07:00
Thach Nguyen e6f7ca7433 Re-format source code of Alias class 2018-01-27 03:21:47 +07:00
Thach Nguyen 042d341b65 Re-format source code of Generator class 2018-01-27 03:21:08 +07:00
Thach Nguyen 501ef7045a Re-format source code of GeneratorCommand 2018-01-27 03:19:47 +07:00
Thach Nguyen 31e6479ee6 Re-format source code of ModelsCommand 2018-01-27 03:18:56 +07:00
Thach Nguyen c0f4a497f9 Improve MetaCommand to support injection like ArrayAccess 2018-01-26 22:49:42 +07:00
Thach Nguyen 00604a2431 Correct spelling for README document 2018-01-26 21:28:15 +07:00
Thach Nguyen ff18d80849 Add required composer dependencies such as illuminate/config, illuminate/view 2018-01-26 21:27:54 +07:00
Ahsan Amin 52ea63b5de Replaced the reflection-docblock with version of barryvdh (#497) 2017-04-27 15:28:29 +02:00
Barry vd. Heuvel 7b263ffbce Update composer.json 2015-06-07 15:09:17 +02:00
Barry vd. Heuvel 8f4ea3c100 Merge pull request #206 from montogeek/patch-1
Update readme.md
2015-05-07 07:30:27 +02:00
Fernando Montoya 3c348e7140 Update readme.md 2015-05-06 22:17:08 -05:00
Barry vd. Heuvel 2f90dbdfce Use 5.3 syntax 2015-03-17 16:11:01 +01:00
Barry vd. Heuvel 74935df8a1 Supress FQN warning 2015-03-17 10:14:07 +01:00
Barry vd. Heuvel b6fdfe0df7 Tweak abstracts 2015-03-17 09:06:21 +01:00
Barry vd. Heuvel 99cebb5566 Tweak @noinspection 2015-03-17 09:01:22 +01:00
Barry vd. Heuvel 692b223e94 5.3 array syntax
Fixes #183
2015-03-16 18:22:03 +01:00
Barry vd. Heuvel f321828778 Update readme 2015-03-16 14:57:14 +01:00
17 changed files with 1462 additions and 1090 deletions
+1 -1
View File
@@ -1,3 +1,3 @@
/vendor
composer.lock
.idea
.idea/
+26
View File
@@ -0,0 +1,26 @@
language: php
php:
- 5.4
- 5.5
- 5.6
- hhvm
matrix:
include:
- php: 5.3
dist: precise
allow_failures:
- php: hhvm
fast_finish: true
cache:
directories:
- vendor
- $HOME/.composer/cache
before_script:
- travis_retry composer self-update
- travis_retry composer install --no-interaction --no-suggest --no-progress
script:
- vendor/bin/phpunit
+6 -2
View File
@@ -11,14 +11,18 @@
],
"require": {
"php": ">=5.3.0",
"illuminate/config": "4.x",
"illuminate/support": "4.x",
"illuminate/console": "4.x",
"illuminate/filesystem": "4.x",
"phpdocumentor/reflection-docblock": "2.0.x",
"illuminate/database": "4.x",
"illuminate/view": "4.x",
"phpdocumentor/reflection-docblock": "^2.0.4",
"symfony/class-loader": "~2.3"
},
"require-dev": {
"doctrine/dbal": "~2.3"
"doctrine/dbal": "~2.3",
"phpunit/phpunit": "~4.0"
},
"suggest": {
"doctrine/dbal": "Load information from the database about models for phpdocs (~2.3)"
+18
View File
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.0/phpunit.xsd"
backupGlobals="false"
backupStaticAttributes="false"
bootstrap="vendor/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false">
<testsuites>
<testsuite name="Package Test Suite">
<directory suffix=".php">./tests/</directory>
</testsuite>
</testsuites>
</phpunit>
+62 -38
View File
@@ -7,7 +7,7 @@
_Checkout [this Laracasts video](https://laracasts.com/series/how-to-be-awesome-in-phpstorm/episodes/15) for a quick introduction/explanation!_
This packages generates a file that your IDE can understand, so it can provide accurate autocompletion. Generation is done, based on the files in your project, so they are alway up-to-date.
This packages generates a file that your IDE can understand, so it can provide accurate autocompletion. Generation is done, based on the files in your project, so they are always up-to-date.
If you don't want to generate it, you can add a pre-generated file to the root folder of your laravel project. (But this isn't as up-to-date as self generated files)
* Generated version: https://gist.github.com/barryvdh/5227822
@@ -18,45 +18,60 @@ Note: You do need CodeIntel for Sublime Text: https://github.com/SublimeCodeInte
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 ann `Illuminate\Events\Dispatcher` object, so with the meta file you can call `app('events')` and it will autocomplete the Dispatcher methods.
php artisan ide-helper:meta
app('events')->fire();
\App::make('events')->..
```bash
php artisan ide-helper:meta
```
```php
app('events')->fire();
\App::make('events')->fire();
Pre-generated example: https://gist.github.com/barryvdh/bb6ffc5d11e0a75dba67
/** @var \Illuminate\Foundation\Application $app */
$app->make('events')->fire();
```
Pre-generated example: https://gist.github.com/barryvdh/bb6ffc5d11e0a75dba67
> Note: This is only available in the `@dev` stability, until a new release is tagged.
> Note: You might need to restart PhpStorm and make sure `.phpstorm.meta.php` is indexed.
### Automatic phpDoc generation for Laravel Facades
Require this package with composer using the following command:
composer require barryvdh/laravel-ide-helper ~1.11
```bash
composer require barryvdh/laravel-ide-helper ~1.11
```
After updating composer, add the ServiceProvider to the providers array in app/config/app.php
After updating composer, add the ServiceProvider to the providers array in `app/config/app.php`
'Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider',
```php
'Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider',
```
You can now re-generate the docs yourself (for future updates) in artisan
php artisan ide-helper:generate
```bash
php artisan ide-helper:generate
```
Note: bootstrap/compiled.php has to be cleared first, so run `php artisan clear-compiled` before generating (and `php artisan optimize` after..)
You can configure your composer.json to do this after each commit:
"scripts":{
"post-update-cmd":[
"php artisan clear-compiled",
"php artisan ide-helper:generate",
"php artisan optimize"
]
},
```json
"scripts":{
"post-update-cmd":[
"php artisan clear-compiled",
"php artisan ide-helper:generate",
"php artisan optimize"
]
},
```
You can also publish the config-file to change implementations (ie. interface to specific class) or set defaults for --helpers or --sublime.
php artisan config:publish barryvdh/laravel-ide-helper
```bash
php artisan config:publish barryvdh/laravel-ide-helper
```
The generator tries to identify the real class, but if it cannot be found, you can define it in the config file.
@@ -68,7 +83,7 @@ The Illuminate/Support/helpers.php is already set-up, but you can add/remove you
### Automatic phpDocs for Models
> **Note:** Since v1.10 you need to require `doctrine/dbal: ~2.3` in your own composer.json.
> **Note:** Since v1.10 you need to require `doctrine/dbal: ~2.3` in your own composer.json.
If you don't want to write your properties yourself, you can use the command `ide-helper:models` to generate
phpDocs, based on table columns, relations and getters/setters. You can write the comments directly to your Model file, using the `--write (-W)` option. By default, you are asked to overwrite or write to a separate file (\_ide\_helper\_models.php) (You can force No with `--nowrite (-N)`).
@@ -76,34 +91,43 @@ Please make sure to backup your models, before writing the info.
It should keep the existing comments and only append new properties/methods. The existing phpdoc is replaced, or added if not found.
With the `--reset (-R)` option, the existing phpdocs are ignored, only the newly found columns/relations are saved as phpdocs.
php artisan ide-helper:models Post
/**
* An Eloquent Model: 'Post'
*
* @property integer $id
* @property integer $author_id
* @property string $title
* @property string $text
* @property \Carbon\Carbon $created_at
* @property \Carbon\Carbon $updated_at
* @property-read \User $author
* @property-read \Illuminate\Database\Eloquent\Collection|\Comment[] $comments
*/
```bash
php artisan ide-helper:models Post
```
```php
/**
* An Eloquent Model: 'Post'
*
* @property integer $id
* @property integer $author_id
* @property string $title
* @property string $text
* @property \Carbon\Carbon $created_at
* @property \Carbon\Carbon $updated_at
* @property-read \User $author
* @property-read \Illuminate\Database\Eloquent\Collection|\Comment[] $comments
*/
```
By default, models in app/models are scanned. The optional argument tells what models to use (also outside app/models).
php artisan ide-helper:models Post User
```bash
php artisan ide-helper:models Post User
```
You can also scan a different directory, using the --dir option (relative from the base path):
php artisan ide-helper:models --dir="app/workbench/name/package/models" --dir="app/src/Model"
```bash
php artisan ide-helper:models --dir="app/workbench/name/package/models" --dir="app/src/Model"
```
You can publish the config file (`php artisan config:publish barryvdh/laravel-ide-helper`) and set the default directories.
Models can be ignored using the --ignore (-I) option
php artisan ide-helper:models --ignore="Post,User"
```bash
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`)
+287 -284
View File
@@ -1,284 +1,287 @@
<?php
/**
* Laravel IDE Helper Generator
*
* @author Barry vd. Heuvel <[email protected]>
* @copyright 2014 Barry vd. Heuvel / Fruitcake Studio (http://www.fruitcakestudio.nl)
* @license http://www.opensource.org/licenses/mit-license.php MIT
* @link https://github.com/barryvdh/laravel-ide-helper
*/
namespace Barryvdh\LaravelIdeHelper;
class Alias
{
protected $alias;
protected $facade;
protected $extends = null;
protected $classType = 'class';
protected $short;
protected $namespace = '__root';
protected $root = null;
protected $classes = array();
protected $methods = array();
protected $usedMethods = array();
protected $valid = false;
protected $magicMethods = array();
protected $interfaces = array();
/**
* @param string $alias
* @param string $facade
* @param array $magicMethods
* @param array $interfaces
*/
public function __construct($alias, $facade, $magicMethods = array(), $interfaces = array())
{
$this->alias = $alias;
$this->magicMethods = $magicMethods;
$this->interfaces = $interfaces;
// Make the class absolute
$facade = '\\' . ltrim($facade, '\\');
$this->facade = $facade;
$this->detectRoot();
if ((!$this->isTrait() && $this->root)) {
$this->valid = true;
} else {
return;
}
$this->addClass($this->root);
$this->detectNamespace();
$this->detectClassType();
if($facade === '\Illuminate\Database\Eloquent\Model'){
$this->usedMethods = array('decrement', 'increment');
}
}
/**
* Add one or more classes to analyze
*
* @param array|string $classes
*/
public function addClass($classes)
{
$classes = (array)$classes;
foreach ($classes as $class) {
if (class_exists($class) || interface_exists($class)) {
$this->classes[] = $class;
}else{
echo "Class not exists: $class\r\n";
}
}
}
/**
* Check if this class is valid to process.
* @return bool
*/
public function isValid()
{
return $this->valid;
}
/**
* Get the classtype, 'interface' or 'class'
*
* @return string
*/
public function getClasstype()
{
return $this->classType;
}
/**
* Get the class which this alias extends
*
* @return null|string
*/
public function getExtends()
{
return $this->extends;
}
/**
* Get the Alias by which this class is called
*
* @return string
*/
public function getAlias()
{
return $this->alias;
}
/**
* Return the short name (without namespace)
*/
public function getShortName(){
return $this->short;
}
/**
* Get the namespace from the alias
*
* @return string
*/
public function getNamespace()
{
return $this->namespace;
}
/**
* Get the methods found by this Alias
*
* @return array
*/
public function getMethods()
{
$this->addMagicMethods();
$this->detectMethods();
return $this->methods;
}
/**
* Detect the namespace
*/
protected function detectNamespace()
{
if (strpos($this->alias, '\\')) {
$nsParts = explode('\\', $this->alias);
$this->short = array_pop($nsParts);
$this->namespace = implode('\\', $nsParts);
}else{
$this->short = $this->alias;
}
}
/**
* Detect the class type
*/
protected function detectClassType()
{
//Some classes extend the facade
if (interface_exists($this->facade)) {
$this->classType = 'interface';
$this->extends = $this->facade;
} else {
$this->classType = 'class';
if (class_exists($this->facade)) {
$this->extends = $this->facade;
}
}
}
/**
* Get the real root of a facade
*
* @return bool|string
*/
protected function detectRoot()
{
$facade = $this->facade;
try {
//If possible, get the facade root
if (method_exists($facade, 'getFacadeRoot')) {
$root = get_class($facade::getFacadeRoot());
} else {
$root = $facade;
}
//If it doesn't exist, skip it
if (!class_exists($root) && !interface_exists($root)) {
return;
}
$this->root = $root;
//When the database connection is not set, some classes will be skipped
} catch (\PDOException $e) {
$this->error(
"PDOException: " . $e->getMessage() . "\nPlease configure your database connection correctly, or use the sqlite memory driver (-M). Skipping $facade."
);
} catch (\Exception $e) {
$this->error("Exception: " . $e->getMessage() . "\nSkipping $facade.");
}
}
/**
* Detect if this class is a trait or not.
*
* @return bool
*/
protected function isTrait()
{
// Check if the facade is not a Trait
if (function_exists('trait_exists') && trait_exists($this->facade)) {
return true;
}
return false;
}
/**
* Add magic methods, as defined in the configuration files
*/
protected function addMagicMethods()
{
foreach($this->magicMethods as $magic => $real){
list($className, $name) = explode('::', $real);
if(!class_exists($className) && !interface_exists($className)){
continue;
}
$method = new \ReflectionMethod($className, $name);
$class = new \ReflectionClass($className);
if(!in_array($method->name, $this->usedMethods)){
if($class !== $this->root){
$this->methods[] = new Method($method, $this->alias, $class, $magic, $this->interfaces);
}
$this->usedMethods[] = $magic;
}
}
}
/**
* Get the methods for one or multiple classes.
*
* @return string
*/
protected function detectMethods()
{
foreach ($this->classes as $class) {
$reflection = new \ReflectionClass($class);
$methods = $reflection->getMethods(\ReflectionMethod::IS_PUBLIC);
if ($methods) {
foreach ($methods as $method) {
if (!in_array($method->name, $this->usedMethods)) {
// Only add the methods to the output when the root is not the same as the class.
// And don't add the __*() methods
if ($this->extends !== $class && substr($method->name, 0, 2) !== '__') {
$this->methods[] = new Method($method, $this->alias, $reflection, $method->name, $this->interfaces);
}
$this->usedMethods[] = $method->name;
}
}
}
}
}
/**
* Output an error.
*
* @param string $string
* @return void
*/
protected function error($string)
{
echo $string . "\r\n";
}
}
<?php
/**
* Laravel IDE Helper Generator
*
* @author Barry vd. Heuvel <[email protected]>
* @copyright 2014 Barry vd. Heuvel / Fruitcake Studio (http://www.fruitcakestudio.nl)
* @license http://www.opensource.org/licenses/mit-license.php MIT
* @link https://github.com/barryvdh/laravel-ide-helper
*/
namespace Barryvdh\LaravelIdeHelper;
class Alias
{
protected $alias;
protected $facade;
protected $extends = null;
protected $classType = 'class';
protected $short;
protected $namespace = '__root';
protected $root = null;
protected $classes = array();
protected $methods = array();
protected $usedMethods = array();
protected $valid = false;
protected $magicMethods = array();
protected $interfaces = array();
/**
* @param string $alias
* @param string $facade
* @param array $magicMethods
* @param array $interfaces
*/
public function __construct($alias, $facade, $magicMethods = array(), $interfaces = array())
{
$this->alias = $alias;
$this->magicMethods = $magicMethods;
$this->interfaces = $interfaces;
// Make the class absolute
$facade = '\\' . ltrim($facade, '\\');
$this->facade = $facade;
$this->detectRoot();
if ((!$this->isTrait() && $this->root)) {
$this->valid = true;
} else {
return;
}
$this->addClass($this->root);
$this->detectNamespace();
$this->detectClassType();
if ($facade === '\Illuminate\Database\Eloquent\Model') {
$this->usedMethods = array('decrement', 'increment');
}
}
/**
* Add one or more classes to analyze
*
* @param array|string $classes
*/
public function addClass($classes)
{
$classes = (array)$classes;
foreach ($classes as $class) {
if (class_exists($class) || interface_exists($class)) {
$this->classes[] = $class;
} else {
$this->error('Class not exists: ' . $class);
}
}
}
/**
* Check if this class is valid to process.
* @return bool
*/
public function isValid()
{
return $this->valid;
}
/**
* Get the classType, 'interface' or 'class'
*
* @return string
*/
public function getClassType()
{
return $this->classType;
}
/**
* Get the class which this alias extends
*
* @return null|string
*/
public function getExtends()
{
return $this->extends;
}
/**
* Get the Alias by which this class is called
*
* @return string
*/
public function getAlias()
{
return $this->alias;
}
/**
* Return the short name (without namespace)
*
* @return string
*/
public function getShortName()
{
return $this->short;
}
/**
* Get the namespace from the alias
*
* @return string
*/
public function getNamespace()
{
return $this->namespace;
}
/**
* Get the methods found by this Alias
*
* @return array|Method[]
*/
public function getMethods()
{
$this->addMagicMethods();
$this->detectMethods();
return $this->methods;
}
/**
* Detect the namespace
*/
protected function detectNamespace()
{
if (strpos($this->alias, '\\')) {
$nsParts = explode('\\', $this->alias);
$this->short = array_pop($nsParts);
$this->namespace = implode('\\', $nsParts);
} else {
$this->short = $this->alias;
}
}
/**
* Detect the class type
*/
protected function detectClassType()
{
//Some classes extend the facade
if (interface_exists($this->facade)) {
$this->classType = 'interface';
$this->extends = $this->facade;
} else {
$this->classType = 'class';
if (class_exists($this->facade)) {
$this->extends = $this->facade;
}
}
}
/**
* Get the real root of a facade
*
* @return bool|string
*/
protected function detectRoot()
{
$facade = $this->facade;
try {
//If possible, get the facade root
if (method_exists($facade, 'getFacadeRoot')) {
$root = get_class($facade::getFacadeRoot());
} else {
$root = $facade;
}
//If it doesn't exist, skip it
if (!class_exists($root) && !interface_exists($root)) {
return;
}
$this->root = $root;
//When the database connection is not set, some classes will be skipped
} catch (\PDOException $e) {
$this->error(
'PDOException: ' . $e->getMessage() . "\nPlease configure your database connection correctly, or use the sqlite memory driver (-M). Skipping $facade."
);
} catch (\Exception $e) {
$this->error('Exception: ' . $e->getMessage() . "\nSkipping $facade.");
}
}
/**
* Detect if this class is a trait or not.
*
* @return bool
*/
protected function isTrait()
{
// Check if the facade is not a Trait
if (function_exists('trait_exists') && trait_exists($this->facade)) {
return true;
}
return false;
}
/**
* Add magic methods, as defined in the configuration files
*/
protected function addMagicMethods()
{
foreach ($this->magicMethods as $magic => $real) {
list($className, $name) = explode('::', $real);
if (!class_exists($className) && !interface_exists($className)) {
continue;
}
$method = new \ReflectionMethod($className, $name);
$class = new \ReflectionClass($className);
if (!in_array($method->name, $this->usedMethods)) {
if ($class !== $this->root) {
$this->methods[] = new Method($method, $this->alias, $class, $magic, $this->interfaces);
}
$this->usedMethods[] = $magic;
}
}
}
/**
* Get the methods for one or multiple classes.
*
* @return string
*/
protected function detectMethods()
{
foreach ($this->classes as $class) {
$reflection = new \ReflectionClass($class);
$methods = $reflection->getMethods(\ReflectionMethod::IS_PUBLIC);
if ($methods) {
foreach ($methods as $method) {
if (!in_array($method->name, $this->usedMethods)) {
// Only add the methods to the output when the root is not the same as the class.
// And don't add the __*() methods
if ($this->extends !== $class && substr($method->name, 0, 2) !== '__') {
$this->methods[] = new Method($method, $this->alias, $reflection, $method->name, $this->interfaces);
}
$this->usedMethods[] = $method->name;
}
}
}
}
}
/**
* Output an error.
*
* @param string $string
* @return void
*/
protected function error($string)
{
echo $string . "\r\n";
}
}
+10 -24
View File
@@ -17,7 +17,6 @@ use Illuminate\Filesystem\Filesystem;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
/**
* A command to generate autocomplete information for your IDE
*
@@ -27,16 +26,12 @@ class GeneratorCommand extends Command
{
/**
* The console command name.
*
* @var string
* {@inheritdoc}
*/
protected $name = 'ide-helper:generate';
/**
* The console command description.
*
* @var string
* {@inheritdoc}
*/
protected $description = 'Generate a new IDE Helper file.';
@@ -51,18 +46,14 @@ class GeneratorCommand extends Command
protected $onlyExtend;
/**
* {@inheritdoc}
*
* @param \Illuminate\Config\Repository $config
* @param \Illuminate\Filesystem\Filesystem $files
* @param \Illuminate\View\Factory $view
*/
public function __construct(
ConfigRepository $config,
Filesystem $files, /* Illuminate\View\Factory */
$view
) {
public function __construct(ConfigRepository $config, Filesystem $files, $view) {
$this->config = $config;
$this->files = $files;
$this->view = $view;
@@ -95,7 +86,6 @@ class GeneratorCommand extends Command
$this->useMemoryDriver();
}
$helpers = '';
if ($this->option('helpers') || ($this->config->get('laravel-ide-helper::include_helpers'))) {
foreach ($this->config->get('laravel-ide-helper::helper_files', array()) as $helper) {
@@ -133,9 +123,7 @@ class GeneratorCommand extends Command
}
/**
* Get the console command arguments.
*
* @return array
* {@inheritdoc}
*/
protected function getArguments()
{
@@ -149,19 +137,17 @@ class GeneratorCommand extends Command
}
/**
* Get the console command options.
*
* @return array
* {@inheritdoc}
*/
protected function getOptions()
{
$format = $this->config->get('laravel-ide-helper::format');
return array(
array('format', "F", InputOption::VALUE_OPTIONAL, 'The format for the IDE Helper', $format),
array('helpers', "H", InputOption::VALUE_NONE, 'Include the helper files'),
array('memory', "M", InputOption::VALUE_NONE, 'Use sqlite memory driver'),
array('sublime', "S", InputOption::VALUE_NONE, 'DEPRECATED: Use different style for SublimeText CodeIntel'),
array('format', 'F', InputOption::VALUE_OPTIONAL, 'The format for the IDE Helper', $format),
array('helpers', 'H', InputOption::VALUE_NONE, 'Include the helper files'),
array('memory', 'M', InputOption::VALUE_NONE, 'Use sqlite memory driver'),
array('sublime', 'S', InputOption::VALUE_NONE, 'DEPRECATED: Use different style for SublimeText CodeIntel'),
);
}
+61 -30
View File
@@ -17,21 +17,18 @@ use Symfony\Component\Console\Input\InputOption;
* A command to generate phpstorm meta data
*
* @author Barry vd. Heuvel <[email protected]>
* @property \Illuminate\Container\Container $laravel
*/
class MetaCommand extends Command {
/**
* The console command name.
*
* @var string
* {@inheritdoc}
*/
protected $name = 'ide-helper:meta';
protected $filename = '.phpstorm.meta.php';
/**
* The console command description.
*
* @var string
* {@inheritdoc}
*/
protected $description = 'Generate metadata for PhpStorm';
@@ -40,22 +37,25 @@ class MetaCommand extends Command {
/** @var \Illuminate\View\Factory */
protected $view;
protected $methods = [
'\Illuminate\Foundation\Application::make',
'\Illuminate\Container\Container::make',
'\App::make',
'app',
];
protected $methods = array(
//'\Illuminate\Foundation\Application::make',
'new \Illuminate\Container\Container',
'\Illuminate\Container\Container::make',
'\App::make',
'app',
);
/**
* {@inheritdoc}
*
* @param \Illuminate\Filesystem\Filesystem $files
* @param \Illuminate\View\Factory $view
* @param \Illuminate\Container\Container $app
*/
public function __construct($files, $view) {
$this->files = $files;
$this->view = $view;
public function __construct($app)
{
$this->laravel = $app;
$this->files = $app['files'];
$this->view = $app['view'];
parent::__construct();
}
@@ -66,26 +66,33 @@ class MetaCommand extends Command {
*/
public function fire()
{
$filename = $this->option('filename');
$bindings = array_flip($this->getAppAliases());
$exclude = $this->option('exclude');
if (!empty($exclude)) {
$exclude = '/' . str_replace('\|', '|', preg_quote($exclude, '/')) . '/';
}
$bindings = array();
foreach ($this->getAbstracts() as $abstract) {
if (!empty($exclude) && preg_match($exclude, $abstract))
continue;
foreach ($this->laravel->getBindings() as $abstract => $options) {
try {
$concrete = $this->laravel->make($abstract);
if (is_object($concrete)) {
$bindings[$abstract] = get_class($concrete);
}
}catch (\Exception $e) {
$this->error("Cannot make $abstract: ".$e->getMessage());
} catch (\Exception $e) {
$this->error("Cannot make $abstract: " . $e->getMessage());
}
}
$content = $this->view->make('laravel-ide-helper::meta', [
'bindings' => $bindings,
'methods' => $this->methods,
])->render();
asort($bindings);
$content = $this->view->make('laravel-ide-helper::meta', array(
'bindings' => $bindings,
'methods' => $this->methods,
))->render();
$filename = $this->option('filename');
$written = $this->files->put($filename, $content);
if ($written !== false) {
@@ -96,14 +103,38 @@ class MetaCommand extends Command {
}
/**
* Get the console command options.
* Get a list of abstracts from the Laravel Application.
*
* @return array
*/
protected function getAbstracts()
{
return array_keys($this->laravel->getBindings());
}
/**
* Get a list of aliases from the Laravel Application.
*
* @return array
*/
protected function getAppAliases()
{
static $aliasProp;
if (!isset($aliasProp)) {
$aliasProp = new \ReflectionProperty('Illuminate\Container\Container', 'aliases');
$aliasProp->setAccessible(true);
}
return $aliasProp->getValue($this->laravel);
}
/**
* {@inheritdoc}
*/
protected function getOptions()
{
return array(
array('filename', 'F', InputOption::VALUE_OPTIONAL, 'The path to the meta file', $this->filename),
array('exclude', 'E', InputOption::VALUE_OPTIONAL, 'Laravel bindings to exclude (e.g. "bar.|.foo")'),
);
}
}
+46 -64
View File
@@ -18,28 +18,24 @@ use Symfony\Component\ClassLoader\ClassMapGenerator;
use phpDocumentor\Reflection\DocBlock;
use phpDocumentor\Reflection\DocBlock\Context;
use phpDocumentor\Reflection\DocBlock\Tag;
use phpDocumentor\Reflection\DocBlock\Serializer as DocBlockSerializer;
/**
* A command to generate autocomplete information for your IDE
*
* @author Barry vd. Heuvel <[email protected]>
* @property \Illuminate\Container\Container $laravel
*/
class ModelsCommand extends Command
{
/**
* The console command name.
*
* @var string
* {@inheritdoc}
*/
protected $name = 'ide-helper:models';
protected $filename = '_ide_helper_models.php';
/**
* The console command description.
*
* @var string
* {@inheritdoc}
*/
protected $description = 'Generate autocompletion for models';
@@ -49,6 +45,20 @@ class ModelsCommand extends Command
protected $dirs = array();
protected $reset;
/** @var \Illuminate\Filesystem\Filesystem */
protected $files;
/**
* {@inheritdoc}
*
* @param \Illuminate\Container\Container $app
*/
public function __construct($app)
{
$this->laravel = $app;
$this->files = $app['files'];
parent::__construct();
}
/**
* Execute the console command.
@@ -69,10 +79,7 @@ class ModelsCommand extends Command
//If filename is default and Write is not specified, ask what to do
if (!$this->write && $filename === $this->filename && !$this->option('nowrite')) {
if ($this->confirm(
"Do you want to overwrite the existing model files? Choose no to write to $filename instead? (Yes/No): "
)
) {
if ($this->confirm("Do you want to overwrite the existing model files? Choose no to write to $filename instead? (Yes/No): ")) {
$this->write = true;
}
}
@@ -80,7 +87,7 @@ class ModelsCommand extends Command
$content = $this->generateDocs($model, $ignore);
if (!$this->write) {
$written = \File::put($filename, $content);
$written = $this->files->put($filename, $content);
if ($written !== false) {
$this->info("Model information was written to $filename");
} else {
@@ -89,11 +96,8 @@ class ModelsCommand extends Command
}
}
/**
* Get the console command arguments.
*
* @return array
* {@inheritdoc}
*/
protected function getArguments()
{
@@ -103,9 +107,7 @@ class ModelsCommand extends Command
}
/**
* Get the console command options.
*
* @return array
* {@inheritdoc}
*/
protected function getOptions()
{
@@ -121,8 +123,6 @@ class ModelsCommand extends Command
protected function generateDocs($loadModels, $ignore = '')
{
$output = "<?php
/**
* An helper file for your Eloquent Models
@@ -164,7 +164,7 @@ class ModelsCommand extends Command
$this->comment("Loading model '$name'");
if (!$reflectionClass->IsInstantiable()) {
if (!$reflectionClass->isInstantiable()) {
throw new \Exception($name . ' is not instantiable.');
}
@@ -177,7 +177,7 @@ class ModelsCommand extends Command
$this->getPropertiesFromMethods($model);
$output .= $this->createPhpDocs($name);
} catch (\Exception $e) {
$this->error("Exception: " . $e->getMessage() . "\nCould not analyze class $name.");
$this->error('Exception: ' . $e->getMessage() . "\nCould not analyze class $name.");
}
}
@@ -190,10 +190,8 @@ class ModelsCommand extends Command
}
return $output;
}
protected function loadModels()
{
$models = array();
@@ -259,7 +257,7 @@ class ModelsCommand extends Command
$comment = $column->getComment();
$this->setProperty($name, $type, true, true, $comment);
$this->setMethod(
Str::camel("where_" . $name),
Str::camel('where_' . $name),
'\Illuminate\Database\Query\Builder|\\' . get_class($model),
array('$value')
);
@@ -275,21 +273,13 @@ class ModelsCommand extends Command
$methods = get_class_methods($model);
if ($methods) {
foreach ($methods as $method) {
if (Str::startsWith($method, 'get') && Str::endsWith(
$method,
'Attribute'
) && $method !== 'getAttribute'
) {
if (Str::startsWith($method, 'get') && Str::endsWith($method, 'Attribute') && $method !== 'getAttribute') {
//Magic get<name>Attribute
$name = Str::snake(substr($method, 3, -9));
if (!empty($name)) {
$this->setProperty($name, null, true, null);
}
} elseif (Str::startsWith($method, 'set') && Str::endsWith(
$method,
'Attribute'
) && $method !== 'setAttribute'
) {
} elseif (Str::startsWith($method, 'set') && Str::endsWith($method, 'Attribute') && $method !== 'setAttribute') {
//Magic set<name>Attribute
$name = Str::snake(substr($method, 3, -9));
if (!empty($name)) {
@@ -321,22 +311,14 @@ class ModelsCommand extends Command
$begin = strpos($code, 'function(');
$code = substr($code, $begin, strrpos($code, '}') - $begin + 1);
foreach (array(
'hasMany',
'belongsToMany',
'hasOne',
'belongsTo',
'morphTo',
'morphMany',
'morphToMany'
) as $relation) {
foreach (array('hasMany', 'belongsToMany', 'hasOne', 'belongsTo', 'morphTo', 'morphMany', 'morphToMany') as $relation) {
$search = '$this->' . $relation . '(';
if ($pos = stripos($code, $search)) {
$code = substr($code, $pos + strlen($search));
$arguments = explode(',', substr($code, 0, strpos($code, ');')));
//Remove quotes, ensure 1 \ in front of the model
$returnModel = $this->getClassName($arguments[0], $model);
if ($relation === "belongsToMany" or $relation === 'hasMany' or $relation === 'morphMany' or $relation === 'morphToMany') {
if ($relation === 'belongsToMany' or $relation === 'hasMany' or $relation === 'morphMany' or $relation === 'morphToMany') {
//Collection or array of models (because Collection is Arrayable)
$this->setProperty(
$method,
@@ -363,14 +345,14 @@ class ModelsCommand extends Command
* @param bool|null $write
* @param string|null $comment
*/
protected function setProperty($name, $type = null, $read = null, $write = null, $comment='')
protected function setProperty($name, $type = null, $read = null, $write = null, $comment = '')
{
if (!isset($this->properties[$name])) {
$this->properties[$name] = array();
$this->properties[$name]['type'] = 'mixed';
$this->properties[$name]['read'] = false;
$this->properties[$name]['write'] = false;
$this->properties[$name]['comment'] = (string) $comment;
$this->properties[$name]['comment'] = (string)$comment;
}
if ($type !== null) {
$this->properties[$name]['type'] = $type;
@@ -398,10 +380,9 @@ class ModelsCommand extends Command
*/
protected function createPhpDocs($class)
{
$reflection = new \ReflectionClass($class);
$namespace = $reflection->getNamespaceName();
$classname = $reflection->getShortName();
$className = $reflection->getShortName();
$originalDoc = $reflection->getDocComment();
if ($this->reset) {
@@ -417,10 +398,11 @@ class ModelsCommand extends Command
$properties = array();
$methods = array();
foreach ($phpdoc->getTags() as $tag) {
/* @var Tag|Tag\PropertyTag|Tag\MethodTag $tag */
$name = $tag->getName();
if ($name == "property" || $name == "property-read" || $name == "property-write") {
if ($name == 'property' || $name == 'property-read' || $name == 'property-write') {
$properties[] = $tag->getVariableName();
} elseif ($name == "method") {
} elseif ($name == 'method') {
$methods[] = $tag->getMethodName();
}
}
@@ -450,47 +432,46 @@ class ModelsCommand extends Command
$phpdoc->appendTag($tag);
}
$serializer = new DocBlockSerializer();
$serializer = new DocBlock\Serializer();
$serializer->getDocComment($phpdoc);
$docComment = $serializer->getDocComment($phpdoc);
if ($this->write) {
$filename = $reflection->getFileName();
$contents = \File::get($filename);
$contents = $this->files->get($filename);
if ($originalDoc) {
$contents = str_replace($originalDoc, $docComment, $contents);
} else {
$needle = "class {$classname}";
$replace = "{$docComment}\nclass {$classname}";
$needle = "class {$className}";
$replace = "{$docComment}\nclass {$className}";
$pos = strpos($contents, $needle);
if ($pos !== false) {
$contents = substr_replace($contents, $replace, $pos, strlen($needle));
}
}
if (\File::put($filename, $contents)) {
if ($this->files->put($filename, $contents)) {
$this->info('Written new phpDocBlock to ' . $filename);
}
}
$output = "namespace {$namespace}{\n{$docComment}\n\tclass {$classname} {}\n}\n\n";
$output = "namespace {$namespace}{\n{$docComment}\n\tclass {$className} {}\n}\n\n";
return $output;
}
/**
* Get the parameters and format them correctly
*
* @param $method
* @param \ReflectionMethod $method
* @return array
*/
public function getParameters($method)
{
//Loop through the default values for paremeters, and make the correct output string
$params = array();
//Loop through the default values for parameters, and make the correct output string
$paramsWithDefault = array();
foreach ($method->getParameters() as $param) {
$paramStr = '$' . $param->getName();
$params[] = $paramStr;
if ($param->isOptional()) {
$default = $param->getDefaultValue();
if (is_bool($default)) {
@@ -508,6 +489,7 @@ class ModelsCommand extends Command
}
$paramsWithDefault[] = $paramStr;
}
return $paramsWithDefault;
}
@@ -529,6 +511,6 @@ class ModelsCommand extends Command
return substr($className, 0, $end);
}
return "\\" . ltrim(trim($className, " \"'"), "\\") ;
return '\\' . ltrim(trim($className, ' "\''), '\\');
}
}
+244 -234
View File
@@ -1,235 +1,245 @@
<?php
/**
* Laravel IDE Helper Generator
*
* @author Barry vd. Heuvel <[email protected]>
* @copyright 2014 Barry vd. Heuvel / Fruitcake Studio (http://www.fruitcakestudio.nl)
* @license http://www.opensource.org/licenses/mit-license.php MIT
* @link https://github.com/barryvdh/laravel-ide-helper
*/
namespace Barryvdh\LaravelIdeHelper;
use Illuminate\Foundation\AliasLoader;
use Illuminate\Config\Repository as ConfigRepository;
use Symfony\Component\Console\Output\OutputInterface;
class Generator
{
/** @var \Illuminate\Config\Repository */
protected $config;
/** @var \Illuminate\View\Factory */
protected $view;
/** @var \Symfony\Component\Console\Output\OutputInterface */
protected $output;
protected $extra = array();
protected $magic = array();
protected $interfaces = array();
protected $helpers;
/**
* @param \Illuminate\Config\Repository $config
* @param \Illuminate\View\Factory $view
* @param \Symfony\Component\Console\Output\OutputInterface $output
* @param string $helpers
*/
public function __construct(ConfigRepository $config,
/* Illuminate\View\Factory */ $view,
OutputInterface $output = null,
$helpers = ''
) {
$this->config = $config;
$this->view = $view;
// Find the drivers to add to the extra/interfaces
$this->detectDrivers();
$this->extra = array_merge($this->extra, $this->config->get('laravel-ide-helper::extra'));
$this->magic = array_merge($this->magic, $this->config->get('laravel-ide-helper::magic'));
$this->interfaces = array_merge($this->interfaces, $this->config->get('laravel-ide-helper::interfaces'));
// Make all interface classes absolute
foreach ($this->interfaces as &$interface) {
$interface = '\\' . ltrim($interface, '\\');
}
$this->helpers = $helpers;
}
/**
* Generate the helper file contents;
*
* @param string $format The format to generate the helper in (php/json)
* @return string;
*/
public function generate($format = 'php')
{
// Check if the generator for this format exists
$method = 'generate'.ucfirst($format).'Helper';
if (method_exists($this, $method)) {
return $this->$method();
}
return $this->generatePhpHelper();
}
public function generatePhpHelper()
{
$app = app();
return $this->view->make('laravel-ide-helper::ide-helper')
->with('namespaces', $this->getNamespaces())
->with('helpers', $this->helpers)
->with('version', $app::VERSION)
->render();
}
public function generateJsonHelper()
{
$classes = array();
foreach ($this->getNamespaces() as $aliases) {
foreach($aliases as $alias) {
$functions = array();
foreach ($alias->getMethods() as $method) {
$functions[$method->getName()] = '('. $method->getParamsWithDefault().')';
}
$classes[$alias->getAlias()] = array(
'functions' => $functions,
);
}
}
$flags = JSON_FORCE_OBJECT;
if (defined('JSON_PRETTY_PRINT')) {
$flags |= JSON_PRETTY_PRINT;
}
return json_encode(array(
'php' => array(
'classes' => $classes,
),
), $flags);
}
protected function detectDrivers()
{
try{
<?php
/**
* Laravel IDE Helper Generator
*
* @author Barry vd. Heuvel <[email protected]>
* @copyright 2014 Barry vd. Heuvel / Fruitcake Studio (http://www.fruitcakestudio.nl)
* @license http://www.opensource.org/licenses/mit-license.php MIT
* @link https://github.com/barryvdh/laravel-ide-helper
*/
namespace Barryvdh\LaravelIdeHelper;
use /** @noinspection PhpUndefinedNamespaceInspection,PhpUndefinedClassInspection */Illuminate\Foundation\AliasLoader;
use Illuminate\Config\Repository as ConfigRepository;
use Symfony\Component\Console\Output\OutputInterface;
class Generator
{
/** @var \Illuminate\Config\Repository */
protected $config;
/** @var \Illuminate\View\Factory */
protected $view;
/** @var \Symfony\Component\Console\Output\OutputInterface */
protected $output;
protected $extra = array();
protected $magic = array();
protected $interfaces = array();
protected $helpers;
/**
* @param \Illuminate\Config\Repository $config
* @param \Illuminate\View\Factory $view
* @param \Symfony\Component\Console\Output\OutputInterface $output
* @param string $helpers
*/
public function __construct(ConfigRepository $config, $view, OutputInterface $output = null, $helpers = '')
{
$this->config = $config;
$this->view = $view;
// Find the drivers to add to the extra/interfaces
$this->detectDrivers();
$this->extra = array_merge($this->extra, $this->config->get('laravel-ide-helper::extra'));
$this->magic = array_merge($this->magic, $this->config->get('laravel-ide-helper::magic'));
$this->interfaces = array_merge($this->interfaces, $this->config->get('laravel-ide-helper::interfaces'));
// Make all interface classes absolute
foreach ($this->interfaces as &$interface) {
$interface = '\\' . ltrim($interface, '\\');
}
$this->helpers = $helpers;
}
/**
* Generate the helper file contents;
*
* @param string $format The format to generate the helper in (php/json)
* @return string;
*/
public function generate($format = 'php')
{
// Check if the generator for this format exists
$method = 'generate' . ucfirst($format) . 'Helper';
if (method_exists($this, $method)) {
return $this->$method();
}
return $this->generatePhpHelper();
}
public function generatePhpHelper()
{
$app = app();
return $this->view->make('laravel-ide-helper::ide-helper')
->with('namespaces', $this->getNamespaces())
->with('helpers', $this->helpers)
->with('version', $app::VERSION)
->render();
}
public function generateJsonHelper()
{
$classes = array();
foreach ($this->getNamespaces() as $aliases) {
foreach ($aliases as $alias) {
$functions = array();
foreach ($alias->getMethods() as $method) {
$functions[$method->getName()] = '(' . $method->getParamsWithDefault() . ')';
}
$classes[$alias->getAlias()] = array(
'functions' => $functions,
);
}
}
$flags = JSON_FORCE_OBJECT;
if (defined('JSON_PRETTY_PRINT')) {
$flags |= JSON_PRETTY_PRINT;
}
return json_encode(array(
'php' => array(
'classes' => $classes,
),
), $flags);
}
protected function detectDrivers()
{
try {
if (class_exists('Auth') && is_a('Auth', '\Illuminate\Support\Facades\Auth', true)) {
$class = get_class(\Auth::driver());
$this->extra['Auth'] = array($class);
$this->interfaces['\Illuminate\Auth\UserProviderInterface'] = $class;
}
}catch (\Exception $e) {}
try{
if (class_exists('DB') && is_a('DB', '\Illuminate\Support\Facades\DB', true)) {
$class = get_class(\DB::connection());
$this->extra['DB'] = array($class);
$this->interfaces['\Illuminate\Database\ConnectionInterface'] = $class;
}
}catch (\Exception $e) {}
try{
if (class_exists('Cache') && is_a('Cache', '\Illuminate\Support\Facades\Cache', true)) {
$driver = get_class(\Cache::driver());
$store = get_class(\Cache::getStore());
$this->extra['Cache'] = array($driver, $store);
$this->interfaces['\Illuminate\Cache\StoreInterface'] = $store;
}
}catch (\Exception $e) {}
try{
if (class_exists('Queue') && is_a('Queue', '\Illuminate\Support\Facades\Queue', true)) {
$class = get_class(\Queue::connection());
$this->extra['Queue'] = array($class);
$this->interfaces['\Illuminate\Queue\QueueInterface'] = $class;
}
}catch (\Exception $e) {}
try{
if (class_exists('SSH') && is_a('SSH', '\Illuminate\Support\Facades\SSH', true)){
$class = get_class(\SSH::connection());
$this->extra['SSH'] = array($class);
$this->interfaces['\Illuminate\Remote\ConnectionInterface'] = $class;
}
}catch (\Exception $e) {}
}
/**
* Find all namespaces/aliases that are valid for us to render
*
* @return array
*/
protected function getNamespaces()
{
$namespaces = array();
// Get all aliases
foreach (AliasLoader::getInstance()->getAliases() as $name => $facade) {
$magicMethods = array_key_exists($name, $this->magic) ? $this->magic[$name] : array();
$alias = new Alias($name, $facade, $magicMethods, $this->interfaces);
if ($alias->isValid()) {
//Add extra methods, from other classes (magic static calls)
if (array_key_exists($name, $this->extra)) {
$alias->addClass($this->extra[$name]);
}
$namespace = $alias->getNamespace();
if (!isset($namespaces[$namespace])) {
$namespaces[$namespace] = array();
}
$namespaces[$namespace][] = $alias;
}
}
return $namespaces;
}
/**
* Get the driver/connection/store from the managers
*
* @param $alias
* @return array|bool|string
*/
public function getDriver($alias)
{
try {
if ($alias == "Auth") {
$driver = \Auth::driver();
} elseif ($alias == "DB") {
$driver = \DB::connection();
} elseif ($alias == "Cache") {
$driver = get_class(\Cache::driver());
$store = get_class(\Cache::getStore());
return array($driver, $store);
} elseif ($alias == "Queue") {
$driver = \Queue::connection();
} else {
return false;
}
return get_class($driver);
} catch (\Exception $e) {
$this->error("Could not determine driver/connection for $alias.");
return false;
}
}
/**
* Write a string as error output.
*
* @param string $string
* @return void
*/
protected function error($string)
{
if($this->output){
$this->output->writeln("<error>$string</error>");
}else{
echo $string . "\r\n";
}
}
}
/** @noinspection PhpUndefinedClassInspection */
$class = get_class(\Auth::driver());
$this->extra['Auth'] = array($class);
$this->interfaces['\Illuminate\Auth\UserProviderInterface'] = $class;
}
} catch (\Exception $e) {}
try {
if (class_exists('DB') && is_a('DB', '\Illuminate\Support\Facades\DB', true)) {
/** @noinspection PhpUndefinedClassInspection */
$class = get_class(\DB::connection());
$this->extra['DB'] = array($class);
$this->interfaces['\Illuminate\Database\ConnectionInterface'] = $class;
}
} catch (\Exception $e) {}
try {
if (class_exists('Cache') && is_a('Cache', '\Illuminate\Support\Facades\Cache', true)) {
/** @noinspection PhpUndefinedClassInspection */
$driver = get_class(\Cache::driver());
/** @noinspection PhpUndefinedClassInspection */
$store = get_class(\Cache::getStore());
$this->extra['Cache'] = array($driver, $store);
$this->interfaces['\Illuminate\Cache\StoreInterface'] = $store;
}
} catch (\Exception $e) {}
try {
if (class_exists('Queue') && is_a('Queue', '\Illuminate\Support\Facades\Queue', true)) {
/** @noinspection PhpUndefinedClassInspection */
$class = get_class(\Queue::connection());
$this->extra['Queue'] = array($class);
$this->interfaces['\Illuminate\Queue\QueueInterface'] = $class;
}
} catch (\Exception $e) {}
try {
if (class_exists('SSH') && is_a('SSH', '\Illuminate\Support\Facades\SSH', true)) {
/** @noinspection PhpUndefinedClassInspection */
$class = get_class(\SSH::connection());
$this->extra['SSH'] = array($class);
$this->interfaces['\Illuminate\Remote\ConnectionInterface'] = $class;
}
} catch (\Exception $e) {}
}
/**
* Find all namespaces/aliases that are valid for us to render
*
* @return array|Alias[][]
*/
protected function getNamespaces()
{
$namespaces = array();
// Get all aliases
/** @noinspection PhpUndefinedClassInspection */
foreach (AliasLoader::getInstance()->getAliases() as $name => $facade) {
$magicMethods = array_key_exists($name, $this->magic) ? $this->magic[$name] : array();
$alias = new Alias($name, $facade, $magicMethods, $this->interfaces);
if ($alias->isValid()) {
//Add extra methods, from other classes (magic static calls)
if (array_key_exists($name, $this->extra)) {
$alias->addClass($this->extra[$name]);
}
$namespace = $alias->getNamespace();
if (!isset($namespaces[$namespace])) {
$namespaces[$namespace] = array();
}
$namespaces[$namespace][] = $alias;
}
}
return $namespaces;
}
/**
* Get the driver/connection/store from the managers
*
* @param $alias
* @return array|bool|string
*/
public function getDriver($alias)
{
try {
if ($alias == 'Auth') {
/** @noinspection PhpUndefinedClassInspection */
$driver = \Auth::driver();
} elseif ($alias == 'DB') {
/** @noinspection PhpUndefinedClassInspection */
$driver = \DB::connection();
} elseif ($alias == 'Cache') {
/** @noinspection PhpUndefinedClassInspection */
$driver = get_class(\Cache::driver());
/** @noinspection PhpUndefinedClassInspection */
$store = get_class(\Cache::getStore());
return array($driver, $store);
} elseif ($alias == 'Queue') {
/** @noinspection PhpUndefinedClassInspection */
$driver = \Queue::connection();
} else {
return false;
}
return get_class($driver);
} catch (\Exception $e) {
$this->error("Could not determine driver/connection for $alias.");
return false;
}
}
/**
* Write a string as error output.
*
* @param string $string
* @return void
*/
protected function error($string)
{
if ($this->output) {
$this->output->writeln("<error>$string</error>");
} else {
echo $string . "\r\n";
}
}
}
+18 -47
View File
@@ -15,20 +15,19 @@ use Barryvdh\LaravelIdeHelper\Console\MetaCommand;
use Barryvdh\LaravelIdeHelper\Console\ModelsCommand;
use Barryvdh\LaravelIdeHelper\Console\GeneratorCommand;
/**
* @property \Illuminate\Container\Container $app
*/
class IdeHelperServiceProvider extends ServiceProvider
{
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
* {@inheritdoc}
*/
protected $defer = true;
/**
* Bootstrap the application events.
*
* @return void
* {@inheritdoc}
*/
public function boot()
{
@@ -36,9 +35,7 @@ class IdeHelperServiceProvider extends ServiceProvider
}
/**
* Register the service provider.
*
* @return void
* {@inheritdoc}
*/
public function register()
{
@@ -49,60 +46,34 @@ class IdeHelperServiceProvider extends ServiceProvider
);
$this->app['command.ide-helper.models'] = $this->app->share(
function () {
return new ModelsCommand();
function ($app) {
return new ModelsCommand($app);
}
);
$this->app['command.ide-helper.meta'] = $this->app->share(
function ($app) {
return new MetaCommand($app['files'], $app['view']);
}
function ($app) {
return new MetaCommand($app);
}
);
$this->commands('command.ide-helper.generate', 'command.ide-helper.models', 'command.ide-helper.meta');
}
/**
* Get the services provided by the provider.
*
* @return array
* {@inheritdoc}
*/
public function provides()
{
return array('command.ide-helper.generate', 'command.ide-helper.models');
return array('command.ide-helper.generate', 'command.ide-helper.models', 'command.ide-helper.meta');
}
/**
* Register the package's component namespaces.
*
* @param string $package
* @param string $namespace
* @param string $path
* @return void
* {@inheritdoc}
*/
public function package($package, $namespace = null, $path = null)
protected function getAppViewPath($package, $namespace = null)
{
// Is it possible to register the config?
if (method_exists($this->app['config'], 'package')) {
$this->app['config']->package($package, $path.'/config', $namespace);
} else {
// Load the config for now..
$config = $this->app['files']->getRequire($path .'/config/config.php');
foreach($config as $key => $value){
$this->app['config']->set($namespace.'::'.$key, $value);
}
}
// Register view files
$appView = $this->app['path']."/views/packages/{$package}";
if ($this->app['files']->isDirectory($appView))
{
$this->app['view']->addNamespace($namespace, $appView);
}
$this->app['view']->addNamespace($namespace, $path.'/views');
return $this->app['path'] . "/views/packages/{$package}";
}
}
+332 -311
View File
@@ -1,311 +1,332 @@
<?php
/**
* Laravel IDE Helper Generator
*
* @author Barry vd. Heuvel <[email protected]>
* @copyright 2014 Barry vd. Heuvel / Fruitcake Studio (http://www.fruitcakestudio.nl)
* @license http://www.opensource.org/licenses/mit-license.php MIT
* @link https://github.com/barryvdh/laravel-ide-helper
*/
namespace Barryvdh\LaravelIdeHelper;
use phpDocumentor\Reflection\DocBlock;
use phpDocumentor\Reflection\DocBlock\Context;
use phpDocumentor\Reflection\DocBlock\Tag;
use phpDocumentor\Reflection\DocBlock\Tag\ReturnTag;
use phpDocumentor\Reflection\DocBlock\Tag\ParamTag;
use phpDocumentor\Reflection\DocBlock\Serializer as DocBlockSerializer;
class Method
{
/** @var \phpDocumentor\Reflection\DocBlock */
protected $phpdoc;
/** @var \ReflectionMethod */
protected $method;
protected $output = '';
protected $name;
protected $namespace;
protected $params = array();
protected $params_with_default = array();
protected $interfaces = array();
protected $return = null;
/**
* @param \ReflectionMethod $method
* @param string $alias
* @param string $class
* @param string|null $methodName
* @param array $interfaces
*/
public function __construct(\ReflectionMethod $method, $alias, $class, $methodName = null, $interfaces = array())
{
$this->method = $method;
$this->interfaces = $interfaces;
$this->name = $methodName ?: $method->name;
$this->namespace = $method->getDeclaringClass()->getNamespaceName();
//Create a DocBlock and serializer instance
$this->phpdoc = new DocBlock($method, new Context($this->namespace));
//Normalize the description and inherit the docs from parents/interfaces
try {
$this->normalizeParams($this->phpdoc);
$this->normalizeReturn($this->phpdoc);
$this->normalizeDescription($this->phpdoc);
} catch (\Exception $e) {}
//Get the parameters, including formatted default values
$this->getParameters($method);
//Make the method static
$this->phpdoc->appendTag(Tag::createInstance('@static', $this->phpdoc));
//Reference the 'real' function in the declaringclass
$declaringClass = $method->getDeclaringClass();
$this->declaringClassName = '\\' . ltrim($declaringClass->name, '\\');
$this->root = '\\' . ltrim($class->getName(), '\\');
}
/**
* Get the class wherein the function resides
*
* @return string
*/
public function getDeclaringClass()
{
return $this->declaringClassName;
}
/**
* Return the class from which this function would be called
*
* @return string
*/
public function getRoot()
{
return $this->root;
}
/**
* Get the docblock for this method
*
* @param string $prefix
* @return mixed
*/
public function getDocComment($prefix = "\t\t")
{
$serializer = new DocBlockSerializer(1, $prefix);
return $serializer->getDocComment($this->phpdoc);
}
/**
* Get the method name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Get the parameters for this method
*
* @param bool $implode Wether to implode the array or not
* @return string
*/
public function getParams($implode = true)
{
return $implode ? implode(', ', $this->params) : $this->params;
}
/**
* Get the parameters for this method including default values
*
* @param bool $implode Wether to implode the array or not
* @return string
*/
public function getParamsWithDefault($implode = true)
{
return $implode ? implode(', ', $this->params_with_default) : $this->params_with_default;
}
/**
* Get the description and get the inherited docs.
*
* @param DocBlock $phpdoc
*/
protected function normalizeDescription(DocBlock $phpdoc)
{
//Get the short + long description from the DocBlock
$description = $phpdoc->getText();
//Loop through parents/interfaces, to fill in {@inheritdoc}
if (strpos($description, '{@inheritdoc}') !== false) {
$inheritdoc = $this->getInheritDoc($this->method);
$inheritDescription = $inheritdoc->getText();
$description = str_replace('{@inheritdoc}', $inheritDescription, $description);
$phpdoc->setText($description);
$this->normalizeParams($inheritdoc);
$this->normalizeReturn($inheritdoc);
//Add the tags that are inherited
$inheritTags = $inheritdoc->getTags();
if ($inheritTags) {
/** @var Tag $tag */
foreach ($inheritTags as $tag) {
$tag->setDocBlock();
$phpdoc->appendTag($tag);
}
}
}
}
/**
* Normalize the parameters
*
* @param DocBlock $phpdoc
*/
protected function normalizeParams(DocBlock $phpdoc)
{
//Get the return type and adjust them for beter autocomplete
$paramTags = $phpdoc->getTagsByName('param');
if ($paramTags) {
/** @var ParamTag $tag */
foreach($paramTags as $tag){
// Convert the keywords
$content = $this->convertKeywords($tag->getContent());
$tag->setContent($content);
// Get the expanded type and re-set the content
$content = $tag->getType() . ' ' . $tag->getVariableName() . ' ' . $tag->getDescription();
$tag->setContent(trim($content));
}
}
}
/**
* Normalize the return tag (make full namespace, replace interfaces)
*
* @param DocBlock $phpdoc
*/
protected function normalizeReturn(DocBlock $phpdoc)
{
//Get the return type and adjust them for beter autocomplete
$returnTags = $phpdoc->getTagsByName('return');
if ($returnTags) {
/** @var ReturnTag $tag */
$tag = reset($returnTags);
// Get the expanded type
$returnValue = $tag->getType();
// Replace the interfaces
foreach($this->interfaces as $interface => $real){
$returnValue = str_replace($interface, $real, $returnValue);
}
// Set the changed content
$tag->setContent($returnValue . ' ' . $tag->getDescription());
$this->return = $returnValue;
}else{
$this->return = null;
}
}
/**
* Convert keywwords that are incorrect.
*
* @param string $string
* @return string
*/
protected function convertKeywords($string)
{
$string = str_replace('\Closure', 'Closure', $string);
$string = str_replace('Closure', '\Closure', $string);
$string = str_replace('dynamic', 'mixed', $string);
return $string;
}
/**
* Should the function return a value?
*
* @return bool
*/
public function shouldReturn()
{
if($this->return !== "void" && $this->method->name !== "__construct"){
return true;
}
return false;
}
/**
* Get the parameters and format them correctly
*
* @param $method
* @return array
*/
public function getParameters($method)
{
//Loop through the default values for paremeters, and make the correct output string
$params = array();
$paramsWithDefault = array();
foreach ($method->getParameters() as $param) {
$paramStr = '$' . $param->getName();
$params[] = $paramStr;
if ($param->isOptional()) {
$default = $param->isDefaultValueAvailable() ? $param->getDefaultValue() : null;
if (is_bool($default)) {
$default = $default ? 'true' : 'false';
} elseif (is_array($default)) {
$default = 'array()';
} elseif (is_null($default)) {
$default = 'null';
} elseif (is_int($default)) {
//$default = $default;
} else {
$default = "'" . trim($default) . "'";
}
$paramStr .= " = $default";
}
$paramsWithDefault[] = $paramStr;
}
$this->params = $params;
$this->params_with_default = $paramsWithDefault;
}
/**
* @param \ReflectionMethod $reflectionMethod
* @return DocBlock
*/
protected function getInheritDoc($reflectionMethod)
{
$parentClass = $reflectionMethod->getDeclaringClass()->getParentClass();
//Get either a parent or the interface
if ($parentClass) {
$method = $parentClass->getMethod($reflectionMethod->getName());
} else {
$method = $reflectionMethod->getPrototype();
}
if ($method) {
$namespace = $method->getDeclaringClass()->getNamespaceName();
$phpdoc = new DocBlock($method, new Context($namespace));
if (strpos($phpdoc->getText(), '{@inheritdoc}') !== false) {
//Not at the end yet, try another parent/interface..
return $this->getInheritDoc($method);
} else {
return $phpdoc;
}
}
}
}
<?php
/**
* Laravel IDE Helper Generator
*
* @author Barry vd. Heuvel <[email protected]>
* @copyright 2014 Barry vd. Heuvel / Fruitcake Studio (http://www.fruitcakestudio.nl)
* @license http://www.opensource.org/licenses/mit-license.php MIT
* @link https://github.com/barryvdh/laravel-ide-helper
*/
namespace Barryvdh\LaravelIdeHelper;
use phpDocumentor\Reflection\DocBlock;
use phpDocumentor\Reflection\DocBlock\Context;
use phpDocumentor\Reflection\DocBlock\Tag;
use phpDocumentor\Reflection\DocBlock\Tag\ReturnTag;
class Method
{
/** @var \phpDocumentor\Reflection\DocBlock */
protected $phpdoc;
/** @var \ReflectionMethod */
protected $method;
protected $name;
protected $namespace;
protected $params = array();
protected $params_with_default = array();
protected $interfaces = array();
protected $return = null;
/**
* @param \ReflectionMethod $method
* @param string $alias
* @param \ReflectionClass $class
* @param string|null $methodName
* @param array $interfaces
*/
public function __construct(\ReflectionMethod $method, $alias, $class, $methodName = null, $interfaces = array())
{
$this->method = $method;
$this->interfaces = $interfaces;
$this->name = $methodName ?: $method->name;
$declaringClass = $method->getDeclaringClass();
$this->namespace = $declaringClass->getNamespaceName();
//Create a DocBlock and serializer instance
$this->phpdoc = new DocBlock($method, new Context($this->namespace, static::getUseStatements($declaringClass)));
//Normalize the description and inherit the docs from parents/interfaces
try {
$this->normalizeReturnTags($this->phpdoc);
$this->normalizeDescription($this->phpdoc);
} catch (\Exception $e) {}
//Get the parameters, including formatted default values
$this->getParameters($method);
//Make the method static
//$this->phpdoc->appendTag(Tag::createInstance('@static', $this->phpdoc));
//Reference the 'real' function in the declaringClass
$this->declaringClassName = '\\' . ltrim($declaringClass->name, '\\');
$this->root = '\\' . ltrim($class->getName(), '\\');
}
/**
* Get the class wherein the function resides
*
* @return string
*/
public function getDeclaringClass()
{
return $this->declaringClassName;
}
/**
* Return the class from which this function would be called
*
* @return string
*/
public function getRoot()
{
return $this->root;
}
/**
* Get the docblock for this method
*
* @param string $prefix
* @param bool $trim
* @return string
*/
public function getDocComment($prefix = "\t\t", $trim = false)
{
$serializer = new DocBlock\Serializer(1, $prefix);
$str = $serializer->getDocComment($this->phpdoc);
if ($trim) {
$str = preg_replace(array('/\s+$/m', '#^(\s*/\*\*[\r\n])(?:\s*\*[\r\n])+#u', '#(?:[\r\n]\s*\*)+([\r\n]\s*\*/)$#u'), array('', '$1', '$1'), $str);
}
return $str;
}
/**
* Get the method name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Checks whether the method is deprecated
*
* @return bool
*/
public function isDeprecated()
{
return $this->phpdoc->hasTag('deprecated');
}
/**
* Get the declared parameters for this method
*
* @return array
*/
public function getDocParams()
{
return $this->phpdoc->getTagsByName('param');
}
/**
* Get the parameters for this method
*
* @param bool $implode Whether to implode the array or not
* @return string|array
*/
public function getParams($implode = true)
{
return $implode ? implode(', ', $this->params) : $this->params;
}
/**
* Get the parameters for this method including default values
*
* @param bool $implode Whether to implode the array or not
* @return string|array
*/
public function getParamsWithDefault($implode = true)
{
return $implode ? implode(', ', $this->params_with_default) : $this->params_with_default;
}
/**
* Get the description and get the inherited docs.
*
* @param DocBlock $phpdoc
*/
protected function normalizeDescription(DocBlock $phpdoc)
{
//Get the short + long description from the DocBlock
$description = $phpdoc->getText();
//Loop through parents/interfaces, to fill in {@inheritdoc}
if (stripos($description, '{@inheritdoc}') !== false && ($inheritdoc = $this->getInheritDoc($this->method))) {
$inheritDescription = $inheritdoc->getText();
$description = str_ireplace('{@inheritdoc}', $inheritDescription, $description);
$phpdoc->setText($description);
$this->normalizeReturnTags($inheritdoc);
//Add the tags that are inherited
foreach ($inheritdoc->getTags() as $tag) {
$tag->setDocBlock();
$phpdoc->appendTag($tag);
}
}
}
/**
* Normalize the return tag (make full namespace, replace interfaces)
*
* @param DocBlock $phpdoc
*/
protected function normalizeReturnTags(DocBlock $phpdoc)
{
static $typeProp;
if (!isset($typeProp)) {
$typeProp = new \ReflectionProperty('phpDocumentor\Reflection\DocBlock\Tag\ReturnTag', 'type');
$typeProp->setAccessible(true);
}
$this->return = null;
//Get the return type and adjust them for better autocomplete
foreach ($phpdoc->getTags() as $tag) {
if ($tag instanceof ReturnTag) {
// Convert the keywords
$typeValue = static::convertKeywords($typeProp->getValue($tag));
$typeProp->setValue($tag, $typeValue);
// Get the expanded type
$typeValue = $tag->getType();
// Replace the interfaces
if (preg_match('/\bReturnTag$/', get_class($tag))) {
foreach ($this->interfaces as $interface => $real) {
$typeValue = preg_replace('/(^|\|)' . preg_quote($interface, '/') . '\b/', $real, $typeValue);
}
$this->return = $typeValue;
}
// Re-set the type
$typeProp->setValue($tag, $typeValue);
$tag->setDescription($tag->getDescription());
}
}
}
/**
* Convert keywords that are incorrect.
*
* @param string $string
* @return string
*/
protected static function convertKeywords($string)
{
$types = explode('|', $string);
foreach ($types as &$type) {
if ($type === 'Closure')
$type = '\Closure';
elseif ($type === 'dynamic')
$type = 'mixed';
elseif (strrpos($type, '\\') && $type[0] !== '\\' && (class_exists($type) || interface_exists($type)))
$type = '\\' . $type;
}
return implode('|', $types);
}
/**
* Should the function return a value?
*
* @return bool|int
*/
public function shouldReturn()
{
if ($this->return !== 'void' && $this->method->name !== '__construct') {
return isset($this->return) ? true : 1;
}
return false;
}
/**
* Get the parameters and format them correctly
*
* @param \ReflectionMethod $method
* @return void
*/
public function getParameters($method)
{
//Loop through the default values for parameters, and make the correct output string
$params = array();
$paramsWithDefault = array();
foreach ($method->getParameters() as $param) {
$paramStr = '$' . $param->getName();
$params[] = $paramStr;
if ($param->isOptional()) {
$default = $param->isDefaultValueAvailable() ? $param->getDefaultValue() : null;
if (is_bool($default)) {
$default = $default ? 'true' : 'false';
} elseif (is_array($default)) {
$default = 'array()';
} elseif (is_null($default)) {
$default = 'null';
} elseif (is_int($default)) {
//$default = $default;
} else {
$default = "'" . trim($default) . "'";
}
$paramStr .= " = $default";
}
$paramsWithDefault[] = $paramStr;
}
$this->params = $params;
$this->params_with_default = $paramsWithDefault;
}
/**
* @param \ReflectionMethod $reflectionMethod
* @return DocBlock|null
*/
protected function getInheritDoc($reflectionMethod)
{
$parentClass = $reflectionMethod->getDeclaringClass()->getParentClass();
//Get either a parent or the interface
if ($parentClass) {
$method = $parentClass->getMethod($reflectionMethod->getName());
} else {
$method = $reflectionMethod->getPrototype();
}
if ($method) {
$namespace = $method->getDeclaringClass()->getNamespaceName();
$phpdoc = new DocBlock($method, new Context($namespace, static::getUseStatements($method->getDeclaringClass())));
if (stripos($phpdoc->getText(), '{@inheritdoc}') !== false) {
//Not at the end yet, try another parent/interface..
return $this->getInheritDoc($method);
} else {
return $phpdoc;
}
}
return null;
}
protected static function getUseStatements(\ReflectionClass $class)
{
try {
return PhpReflection::getUseStatements($class);
} catch (\Exception $e) {
return array();
}
}
}
+166
View File
@@ -0,0 +1,166 @@
<?php namespace Barryvdh\LaravelIdeHelper;
/**
* PHP reflection helpers.
*
* This file is part of the Nette Framework (https://nette.org)
* Copyright (c) 2004 David Grudl (https://davidgrudl.com)
*
* @see https://github.com/nette/di/blob/v2.4/src/DI/PhpReflection.php
*/
class PhpReflection
{
/**
* Expands class name into full name.
*
* @param string $name
* @param \ReflectionClass $rc
* @return string full name
* @throws \InvalidArgumentException
*/
public static function expandClassName($name, \ReflectionClass $rc)
{
$lower = strtolower($name);
if (empty($name)) {
throw new \InvalidArgumentException('Class name must not be empty.');
} elseif (self::isBuiltinType($lower)) {
return $lower;
} elseif ($lower === 'self' || $lower === 'static' || $lower === '$this') {
return $rc->getName();
} elseif ($name[0] === '\\') { // fully qualified name
return ltrim($name, '\\');
}
$uses = self::getUseStatements($rc);
$parts = explode('\\', $name, 2);
if (isset($uses[$parts[0]])) {
$parts[0] = $uses[$parts[0]];
return implode('\\', $parts);
} elseif ($rc->inNamespace()) {
return $rc->getNamespaceName() . '\\' . $name;
} else {
return $name;
}
}
/**
* @param \ReflectionClass
* @return array of [alias => class]
*/
public static function getUseStatements(\ReflectionClass $class)
{
static $cache = array();
if (!isset($cache[$name = $class->getName()])) {
if ($class->isInternal() || !($code = @file_get_contents($class->getFileName()))) {
$cache[$name] = array();
} else {
$cache = self::parseUseStatements($code, $name) + $cache;
}
}
return $cache[$name];
}
/**
* @param string
* @return bool
*/
public static function isBuiltinType($type)
{
return in_array(strtolower($type), array('string', 'int', 'float', 'bool', 'array', 'callable'), true);
}
/**
* Parses PHP code.
*
* @param string $code
* @param string $forClass
* @return array of [class => [alias => class, ...]]
*/
public static function parseUseStatements($code, $forClass = null)
{
$tokens = token_get_all($code);
$namespace = $class = $classLevel = $level = null;
$res = $uses = array();
while ($token = current($tokens)) {
next($tokens);
switch (is_array($token) ? $token[0] : $token) {
case T_NAMESPACE:
$namespace = ltrim(self::fetch($tokens, array(T_STRING, T_NS_SEPARATOR)) . '\\', '\\');
$uses = array();
break;
case T_CLASS:
case T_INTERFACE:
case PHP_VERSION_ID < 50400 ? -1 : T_TRAIT:
if ($name = self::fetch($tokens, T_STRING)) {
$class = $namespace . $name;
$classLevel = $level + 1;
$res[$class] = $uses;
if ($class === $forClass) {
return $res;
}
}
break;
case T_USE:
while (!$class && ($name = self::fetch($tokens, array(T_STRING, T_NS_SEPARATOR)))) {
$name = ltrim($name, '\\');
if (self::fetch($tokens, '{')) {
while ($suffix = self::fetch($tokens, array(T_STRING, T_NS_SEPARATOR))) {
if (self::fetch($tokens, T_AS)) {
$uses[self::fetch($tokens, T_STRING)] = $name . $suffix;
} else {
$tmp = explode('\\', $suffix);
$uses[end($tmp)] = $name . $suffix;
}
if (!self::fetch($tokens, ',')) {
break;
}
}
} elseif (self::fetch($tokens, T_AS)) {
$uses[self::fetch($tokens, T_STRING)] = $name;
} else {
$tmp = explode('\\', $name);
$uses[end($tmp)] = $name;
}
if (!self::fetch($tokens, ',')) {
break;
}
}
break;
case T_CURLY_OPEN:
case T_DOLLAR_OPEN_CURLY_BRACES:
case '{':
$level++;
break;
case '}':
if ($level === $classLevel) {
$class = $classLevel = null;
}
$level--;
}
}
return $res;
}
private static function fetch(&$tokens, $take)
{
$res = null;
while ($token = current($tokens)) {
list($token, $s) = is_array($token) ? $token : array($token, $token);
if (in_array($token, (array)$take, true)) {
$res .= $s;
} elseif (!in_array($token, array(T_DOC_COMMENT, T_WHITESPACE, T_COMMENT), true)) {
break;
}
next($tokens);
}
return $res;
}
}
+46 -39
View File
@@ -1,39 +1,46 @@
<?= '<?php' ?>
/**
* An helper file for Laravel 4, to provide autocomplete information to your IDE
* Generated for Laravel <?= $version ?> on <?= date("Y-m-d") ?>.
*
* @author Barry vd. Heuvel <[email protected]>
* @see https://github.com/barryvdh/laravel-ide-helper
*/
<?php foreach($namespaces as $namespace => $aliases): ?>
namespace <?= $namespace == '__root' ? '' : $namespace ?>{
<?php if($namespace == '__root'): ?>
exit("This file should not be included, only analyzed by your IDE");
<?= $helpers ?>
<?php endif; ?>
<?php foreach($aliases as $alias): ?>
<?= $alias->getClassType() ?> <?= $alias->getShortName() ?> <?= $alias->getExtends() ? 'extends ' . $alias->getExtends() : '' ?>{
<?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 endforeach; ?>
}
<?php endforeach; ?>
<?= '<?php' ?>
/**
* An helper file for Laravel 4, to provide autocomplete information to your IDE
* Generated for Laravel <?= $version ?> on <?= date('Y-m-d') ?>.
*
* @author Barry vd. Heuvel <[email protected]>
* @see https://github.com/barryvdh/laravel-ide-helper
*/
<?php foreach ($namespaces as $namespace => $aliases/* @var \Barryvdh\LaravelIdeHelper\Alias[] $aliases */): ?>
namespace <?= $namespace == '__root' ? '' : $namespace ?>{
<?php if ($namespace == '__root'): ?>
exit('This file should not be included, only analyzed by your IDE');
<?= $helpers ?>
<?php endif; ?>
<?php foreach ($aliases as $alias): ?>
<?php if (($cBase = class_basename($alias->getExtends())) != $alias->getExtends() && $cBase != $alias->getShortName()): ?>
/** @noinspection PhpUnnecessaryFullyQualifiedNameInspection */
<?php endif; ?>
<?= $alias->getClassType() ?> <?= $alias->getShortName() ?> <?= $alias->getExtends() ? 'extends ' . $alias->getExtends() : '' ?>{
<?php foreach ($alias->getMethods() as $method): ?>
<?php if (($nParams = count($method->getDocParams())) > count($mParams = $method->getParamsWithDefault(false))): ?>
/** @noinspection PhpDocSignatureInspection */
<?php endif; ?>
<?php if ($docComment = str_replace("/**\n\t\t */", '', trim($method->getDocComment("\t\t", true)))): ?>
<?= $docComment ?>
<?php endif; ?>
public static function <?= $method->getName() ?>(<?= ($docComment && $nParams < count($mParams)) ? '/** @noinspection PhpDocSignatureInspection */' . implode(', /** @noinspection PhpDocSignatureInspection */', $mParams) : $method->getParamsWithDefault() ?>){
<?php if ($method->getDeclaringClass() !== $method->getRoot()): ?>
//Method inherited from <?= $method->getDeclaringClass() ?>
<?php endif; ?>
/** @noinspection PhpUnnecessaryFullyQualifiedNameInspection,PhpDynamicAsStaticMethodCallInspection<?= ($method->shouldReturn() === 1 ? ',PhpVoidFunctionResultUsedInspection' : '') . ($method->isDeprecated() ? ',PhpDeprecationInspection' : '') ?> */
<?= $method->shouldReturn() ? 'return ' : '' ?><?= $method->getRoot() ?>::<?= $method->getName() ?>(<?= $method->getParams() ?>);
}
<?php endforeach; ?>
}
<?php endforeach; ?>
}
<?php endforeach; ?>
+18 -16
View File
@@ -1,20 +1,22 @@
<?= '<?php' ?> namespace PHPSTORM_META {
/**
* PhpStorm Meta file, to provide autocomplete information for PhpStorm
* Generated on <?= date("Y-m-d") ?>.
*
* @author Barry vd. Heuvel <[email protected]>
* @see https://github.com/barryvdh/laravel-ide-helper
* @noinspection PhpUnusedLocalVariableInspection
* @noinspection PhpIllegalArrayKeyTypeInspection
*/
$STATIC_METHOD_TYPES = [
<?php foreach($methods as $method): ?>
<?= $method ?>('') => [
<?php foreach($bindings as $abstract => $class): ?>
'<?= $abstract ?>' instanceof \<?= $class ?>,
<?php endforeach ?> ],
/**
* PhpStorm Meta file, to provide autocomplete information for PhpStorm
* Generated on <?= date('Y-m-d') ?>.
*
* @author Barry vd. Heuvel <[email protected]>
* @see https://github.com/barryvdh/laravel-ide-helper
*/
/** @noinspection PhpIllegalArrayKeyTypeInspection,PhpUnusedLocalVariableInspection,PhpUnnecessaryFullyQualifiedNameInspection */
$STATIC_METHOD_TYPES = array(
<?php foreach ($methods as $method): ?>
<?= strpos($method, 'new ') === 0 ? $method : $method . '(\'\')' ?> => array(
<?php foreach ($bindings as $abstract => $class): ?>
<?= var_export($abstract, true) ?> instanceof \<?= $class ?>,
<?php endforeach ?>
];
),
<?php endforeach ?>
);
}
+38
View File
@@ -0,0 +1,38 @@
<?php namespace Barryvdh\LaravelIdeHelper;
class MethodTest extends \PHPUnit_Framework_TestCase
{
/**
* @expectedException \PHPUnit_Framework_Error
* @expectedExceptionMessage Argument 1 passed to
*/
public function testConstructorWithoutMethod()
{
new Method(null, null, null);
}
public function testConstructor()
{
$method = new \ReflectionMethod('PHPUnit_Framework_TestCase', 'getMock');
$object = new Method($method, null, new \ReflectionClass(get_class($this)));
$this->assertSame('\PHPUnit_Framework_TestCase', $object->getDeclaringClass());
$this->assertSame('\\' . get_class($this), $object->getRoot());
$this->assertSame('getMock', $object->getName());
$prop = new \ReflectionProperty(get_class($object), 'namespace');
$prop->setAccessible(true);
$this->assertSame('', $prop->getValue($object));
$this->assertFalse($object->isDeprecated());
$this->assertCount($method->getNumberOfParameters(), $object->getDocParams());
$doc = $object->getDocComment('', true);
$this->assertContains("\n * " . '@param array|null $methods', $doc);
$this->assertContains("\n * " . '@return \PHPUnit_Framework_MockObject_MockObject', $doc);
$this->assertContains("\n * " . '@throws \PHPUnit_Framework_Exception', $doc);
$this->assertTrue($object->shouldReturn());
}
}
+83
View File
@@ -0,0 +1,83 @@
<?php namespace Barryvdh\LaravelIdeHelper;
class ServiceProviderTest extends \PHPUnit_Framework_TestCase
{
/** @var \PHPUnit_Framework_MockObject_MockObject|\Illuminate\Container\Container */
protected $app;
/** @var IdeHelperServiceProvider */
protected $provider;
static function makeAppMock(\PHPUnit_Framework_TestCase $testCase)
{
$app = $testCase->getMock('Illuminate\Container\Container', array('make', 'bind'));
$fs = $testCase->getMock('Illuminate\Filesystem\Filesystem', null);
$config = $testCase->getMock('Illuminate\Config\Repository', array('get', 'set', 'package'), array(), '', false);
$events = $testCase->getMock('Illuminate\Events\Dispatcher', array('listen'), array($app));
$view = $testCase->getMock('Illuminate\View\Factory', array('addNamespace'), array(), '', false);
$app->expects($testCase->any())->method('make')->willReturnMap(array(
array('files', array(), $fs),
array('config', array(), $config),
array('events', array(), $events),
array('view', array(), $view),
array('path', array(), __DIR__),
));
return $app;
}
/**
* {@inheritdoc}
*/
protected function setUp()
{
$this->app = static::makeAppMock($this);
/** @noinspection PhpParamsInspection */
$this->provider = new IdeHelperServiceProvider($this->app);
}
public function testDeferred()
{
$this->assertTrue($this->provider->isDeferred());
}
public function testProvides()
{
$this->assertEquals(array('command.ide-helper.generate', 'command.ide-helper.models', 'command.ide-helper.meta'), $this->provider->provides());
}
public function testRegister()
{
$this->app->expects($this->exactly(3))->method('bind')->withConsecutive(
array('command.ide-helper.generate', $this->isType(\PHPUnit_Framework_Constraint_IsType::TYPE_CALLABLE), $this->isFalse()),
array('command.ide-helper.models', $this->isType(\PHPUnit_Framework_Constraint_IsType::TYPE_CALLABLE), $this->isFalse()),
array('command.ide-helper.meta', $this->isType(\PHPUnit_Framework_Constraint_IsType::TYPE_CALLABLE), $this->isFalse())
);
/** @var \PHPUnit_Framework_MockObject_MockObject|\Illuminate\Events\Dispatcher $events */
$events = $this->app['events'];
$events->expects($this->once())->method('listen')->with('artisan.start', $this->callback(function ($listener) {
$params = print_r(array('commands' => array('command.ide-helper.generate', 'command.ide-helper.models', 'command.ide-helper.meta')), true);
return strpos(preg_replace('/^\s+/mu', '', print_r($listener, true)), preg_replace('/^\s+/mu', '', $params));
}), 0);
$this->provider->register();
}
public function testBoot()
{
$path = realpath(__DIR__ . '/../src');
/** @var \PHPUnit_Framework_MockObject_MockObject|\Illuminate\Config\Repository $config */
$config = $this->app['config'];
$config->expects($this->once())->method('package')->with('barryvdh/laravel-ide-helper', $path . '/config', 'laravel-ide-helper');
/** @var \PHPUnit_Framework_MockObject_MockObject|\Illuminate\View\Factory $view */
$view = $this->app['view'];
$view->expects($this->once())->method('addNamespace')->with('laravel-ide-helper', $path . '/views');
$this->provider->boot();
}
}