From 3151019947141731640a51c9447320fb47fb7e51 Mon Sep 17 00:00:00 2001 From: "Barry vd. Heuvel" Date: Tue, 5 Aug 2014 20:06:07 +0200 Subject: [PATCH 1/7] Use PSR-4 --- composer.json | 4 ++-- .../GeneratorCommand.php | 2 +- .../LaravelIdeHelper => Console}/ModelsCommand.php | 2 +- .../IdeHelperServiceProvider.php | 13 +++++++------ 4 files changed, 11 insertions(+), 10 deletions(-) rename src/{Barryvdh/LaravelIdeHelper => Console}/GeneratorCommand.php (99%) mode change 100755 => 100644 rename src/{Barryvdh/LaravelIdeHelper => Console}/ModelsCommand.php (99%) rename src/{Barryvdh/LaravelIdeHelper => }/IdeHelperServiceProvider.php (79%) diff --git a/composer.json b/composer.json index 7afbad3..f598a4a 100644 --- a/composer.json +++ b/composer.json @@ -24,8 +24,8 @@ "doctrine/dbal": "Load information from the database about models for phpdocs (~2.3)" }, "autoload": { - "psr-0": { - "Barryvdh\\LaravelIdeHelper": "src/" + "psr-4": { + "Barryvdh\\LaravelIdeHelper\\": "src" } }, "extra": { diff --git a/src/Barryvdh/LaravelIdeHelper/GeneratorCommand.php b/src/Console/GeneratorCommand.php old mode 100755 new mode 100644 similarity index 99% rename from src/Barryvdh/LaravelIdeHelper/GeneratorCommand.php rename to src/Console/GeneratorCommand.php index e1e1d55..eb75cab --- a/src/Barryvdh/LaravelIdeHelper/GeneratorCommand.php +++ b/src/Console/GeneratorCommand.php @@ -8,7 +8,7 @@ * @link https://github.com/barryvdh/laravel-ide-helper */ -namespace Barryvdh\LaravelIdeHelper; +namespace Barryvdh\LaravelIdeHelper\Console; use Illuminate\Console\Command; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputArgument; diff --git a/src/Barryvdh/LaravelIdeHelper/ModelsCommand.php b/src/Console/ModelsCommand.php similarity index 99% rename from src/Barryvdh/LaravelIdeHelper/ModelsCommand.php rename to src/Console/ModelsCommand.php index e9f700a..03a6bdb 100644 --- a/src/Barryvdh/LaravelIdeHelper/ModelsCommand.php +++ b/src/Console/ModelsCommand.php @@ -8,7 +8,7 @@ * @link https://github.com/barryvdh/laravel-ide-helper */ -namespace Barryvdh\LaravelIdeHelper; +namespace Barryvdh\LaravelIdeHelper\Console; use Illuminate\Console\Command; use Illuminate\Support\Str; diff --git a/src/Barryvdh/LaravelIdeHelper/IdeHelperServiceProvider.php b/src/IdeHelperServiceProvider.php similarity index 79% rename from src/Barryvdh/LaravelIdeHelper/IdeHelperServiceProvider.php rename to src/IdeHelperServiceProvider.php index 6448c08..3e267d8 100644 --- a/src/Barryvdh/LaravelIdeHelper/IdeHelperServiceProvider.php +++ b/src/IdeHelperServiceProvider.php @@ -11,6 +11,8 @@ namespace Barryvdh\LaravelIdeHelper; use Illuminate\Support\ServiceProvider; +use Barryvdh\LaravelIdeHelper\Console\GeneratorCommand; +Use Barryvdh\LaravelIdeHelper\Console\ModelsCommand; class IdeHelperServiceProvider extends ServiceProvider { @@ -28,7 +30,7 @@ class IdeHelperServiceProvider extends ServiceProvider { */ public function boot() { - $this->package('barryvdh/laravel-ide-helper'); + $this->app['config']->package('barryvdh/laravel-ide-helper', __DIR__ . '/config'); } /** @@ -38,18 +40,17 @@ class IdeHelperServiceProvider extends ServiceProvider { */ public function register() { - - $this->app['command.ide-helper.generate'] = $this->app->share(function($app) + $this->app['command.ide-helper.generate'] = $this->app->share(function() { return new GeneratorCommand; }); - $this->commands('command.ide-helper.generate'); - $this->app['command.ide-helper.models'] = $this->app->share(function($app) + $this->app['command.ide-helper.models'] = $this->app->share(function() { return new ModelsCommand(); }); - $this->commands('command.ide-helper.models'); + + $this->commands('command.ide-helper.generate', 'command.ide-helper.models'); } /** From 8193fa0763fda0bbc633fe569952a1ff4c77382a Mon Sep 17 00:00:00 2001 From: "Barry vd. Heuvel" Date: Wed, 6 Aug 2014 00:02:00 +0200 Subject: [PATCH 2/7] Big refactor --- src/Alias.php | 241 +++++++++++++++ src/Console/GeneratorCommand.php | 507 +++++-------------------------- src/Console/ModelsCommand.php | 239 +++++++++------ src/Generator.php | 130 ++++++++ src/IdeHelperServiceProvider.php | 84 ++--- src/Method.php | 246 +++++++++++++++ src/config/config.php | 0 src/views/ide-helper.php | 36 +++ 8 files changed, 913 insertions(+), 570 deletions(-) create mode 100644 src/Alias.php create mode 100644 src/Generator.php create mode 100644 src/Method.php mode change 100755 => 100644 src/config/config.php create mode 100644 src/views/ide-helper.php diff --git a/src/Alias.php b/src/Alias.php new file mode 100644 index 0000000..e5d989c --- /dev/null +++ b/src/Alias.php @@ -0,0 +1,241 @@ + + * @copyright 2013 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 $namespace = '__root'; + protected $root = null; + protected $classes = array(); + protected $methods = array(); + protected $used_methods = array(); + protected $valid = false; + + public function __construct($alias, $facade) + { + $this->alias = $alias; + + // 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(); + + + } + + /** + * 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; + } + } + + } + + /** + * 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; + } + + /** + * 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->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); + } + } + + /** + * 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)) { + $this->error("Class $this->root is not found."); + 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; + } + + /** + * 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->used_methods)) { + // Only add the methods to the output when the root is not the same as the facade. + // And don't add the __*() methods + if ($this->facade !== $this->root && substr($method->name, 0, 2) !== '__') { + $this->methods[] = new Method($method, $this->alias, $reflection); + } + $this->used_methods[] = $method->name; + } + } + } + } + } + + // Helper class to log errors + protected function error($msg) + { + echo $msg . "\r\n"; + } + +} diff --git a/src/Console/GeneratorCommand.php b/src/Console/GeneratorCommand.php index eb75cab..50812e8 100644 --- a/src/Console/GeneratorCommand.php +++ b/src/Console/GeneratorCommand.php @@ -9,7 +9,11 @@ */ namespace Barryvdh\LaravelIdeHelper\Console; + +use Barryvdh\LaravelIdeHelper\Generator; +use Illuminate\Config\Repository as ConfigRepository; use Illuminate\Console\Command; +use Illuminate\Filesystem\Filesystem; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputArgument; use Illuminate\Foundation\AliasLoader; @@ -17,12 +21,14 @@ 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 */ -class GeneratorCommand extends Command { +class GeneratorCommand extends Command +{ /** * The console command name. @@ -38,12 +44,38 @@ class GeneratorCommand extends Command { */ protected $description = 'Generate a new IDE Helper file.'; + /** @var \Illuminate\Config\Repository */ + protected $config; + + /** @var \Illuminate\Filesystem\Filesystem */ + protected $files; + + /** @var \Illuminate\View\Factory */ + protected $view; + protected $extra; protected $onlyExtend; protected $helpers; protected $magic; + /** + * + * @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 + ) { + $this->config = $config; + $this->files = $files; + $this->view = $view; + parent::__construct(); + } + /** * Execute the console command. * @@ -51,43 +83,55 @@ class GeneratorCommand extends Command { */ public function fire() { - if (file_exists($compiled = base_path().'/bootstrap/compiled.php')){ - $this->error('Error generating IDE Helper: first delete bootstrap/compiled.php (php artisan clear-compiled)'); - }else{ + if (file_exists($compiled = base_path() . '/bootstrap/compiled.php')) { + $this->error( + 'Error generating IDE Helper: first delete bootstrap/compiled.php (php artisan clear-compiled)' + ); + } else { $filename = $this->argument('filename'); - - if($this->option('memory')){ + + if ($this->option('memory')) { $this->useMemoryDriver(); } - - $this->extra = \Config::get('laravel-ide-helper::extra'); - $this->magic = \Config::get('laravel-ide-helper::magic'); - if( $this->option('helpers') || (\Config::get('laravel-ide-helper::include_helpers') )){ - $this->helpers = \Config::get('laravel-ide-helper::helper_files'); - }else{ - $this->helpers = array(); + $extra = $this->config->get('laravel-ide-helper::extra'); + $magic = $this->config->get('laravel-ide-helper::magic'); + $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) { + if (file_exists($helper)) { + $helpers .= str_replace(array(''), '', $this->files->get($helper)); + } + } + } else { + $helpers = ''; } - $content = $this->generateDocs(); - - $written = \File::put($filename, $content); - - if($written !== false){ + $generator = new Generator($this->view, $extra, $magic, $helpers); + $output = $generator->generate(); + + + $written = $this->files->put($filename, $output); + + if ($written !== false) { $this->info("A new helper file was written to $filename"); - }else{ + } else { $this->error("The helper file could not be created at $filename"); } - } + } } - protected function useMemoryDriver(){ + protected function useMemoryDriver() + { //Use a sqlite database in memory, to avoid connection errors on Database facades - \Config::set('database.connections.sqlite',array( - 'driver' => 'sqlite', + $this->config->set( + 'database.connections.sqlite', + array( + 'driver' => 'sqlite', 'database' => ':memory:', - )); - \Config::set('database.default', 'sqlite'); + ) + ); + $this->config->set('database.default', 'sqlite'); } /** @@ -98,7 +142,12 @@ class GeneratorCommand extends Command { protected function getArguments() { return array( - array('filename', InputArgument::OPTIONAL, 'The path to the helper file', \Config::get('laravel-ide-helper::filename')), + array( + 'filename', + InputArgument::OPTIONAL, + 'The path to the helper file', + $this->config->get('laravel-ide-helper::filename') + ), ); } @@ -116,410 +165,4 @@ class GeneratorCommand extends Command { ); } - /** - * Generate the docs for all facades in the AliasLoader - * - * @return string - */ - protected function generateDocs(){ - - $aliasLoader = AliasLoader::getInstance(); - - $outputString = " - */\n\n"; - $output['__root'] = "\texit('Only to be used as an helper for your IDE');\n\n"; - - //Get all aliases - $aliases = $aliasLoader->getAliases(); - - foreach($aliases as $alias => $facade){ - //Check if the facade is not a Trait - if(function_exists('trait_exists') && trait_exists($facade)){ - continue; - } - $facade = '\\'.ltrim($facade, '\\'); - $root = $this->getRoot($facade); - if(!$root){ - continue; - } - - try{ - if (strpos($alias, '\\')){ - $nsParts = explode('\\', $alias); - $alias = array_pop($nsParts); - $ns = implode('\\', $nsParts); - } else { - $ns = '__root'; - } - if (!isset($output[$ns])) $output[$ns] = ''; - - //Some classes extend the facade - if(interface_exists($facade)){ - $output[$ns] .= "\tinterface $alias extends $facade{\n"; - }elseif(class_exists($facade)){ - $output[$ns] .= "\tclass $alias extends $facade{\n"; - }else{ - $output[$ns] .= "\tclass $alias{\n"; - } - - $usedMethods = array(); - - //Only add the methods to the output when the root is not the same as the facade. - $addOutput = ($root !== $facade); - $output[$ns] .= $this->getMethods($root, $alias, $usedMethods, $addOutput); - - - $driver = $this->getDriver($alias); - if($driver){ - $output[$ns] .= $this->getMethods($driver, $alias, $usedMethods); - } - - //Add extra methods, from other classes (magic static calls) - if(array_key_exists($alias, $this->extra)){ - $output[$ns] .= $this->getMethods($this->extra[$alias], $alias, $usedMethods); - } - - //Add extra methods, from other classes (magic static calls) - if(array_key_exists($alias, $this->magic)){ - $output[$ns] .= $this->addMagicMethods($this->magic[$alias], $alias, $usedMethods); - } - - - $output[$ns] .= "\t}\n"; - - }catch(\Exception $e){ - $this->error("Exception: ".$e->getMessage()."\nCould not analyze $root."); - } - - } - - //Include the helper file, if requested - if(!empty($this->helpers)){ - foreach($this->helpers as $helper){ - if (file_exists($helper)){ - $output['__root'] .= str_replace(array(''), '', \File::get($helper)); - } - } - } - - foreach ($output as $ns => $body){ - if ($ns == '__root'){ - $ns = ''; - } - $outputString .= "namespace $ns{\n"; - $outputString .= $body; - $outputString .= "}\n\n"; - } - - return $outputString; - } - - /** - * Get the real root of a facade - * - * @param $facade - * @return bool|string - */ - protected function getRoot($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)){ - $this->error("Class $root is not found."); - return false; - } - - return $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."); - return false; - }catch(\Exception $e){ - $this->error("Exception: ".$e->getMessage()."\nSkipping $facade."); - return false; - } - - } - - /** - * 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; - } - } - - /** - * Get the methods for one or multiple classes. - * - * @param $classes - * @param $alias - * @param $usedMethods - * @param bool $addOutput - * @return string - */ - protected function getMethods($classes, $alias, &$usedMethods, $addOutput = true){ - if(!is_array($classes)){ - $classes = array($classes); - } - $output = ''; - foreach($classes as $class){ - if(!class_exists($class) && !interface_exists($class)){ - continue; - } - $reflection = new \ReflectionClass($class); - - $methods = $reflection->getMethods(\ReflectionMethod::IS_PUBLIC); - if($methods) - { - foreach ($methods as $method) - { - if(!in_array($method->name, $usedMethods)){ - if( $addOutput){ - $output .= $this->parseMethod($method, $alias, $reflection); - } - $usedMethods[] = $method->name; - } - } - } - } - return $output; - } - - /** - * Get the methods for one or multiple magic methods. - * - * @param $methods - * @param $alias - * @param $usedMethods - * @param bool $addOutput - * @return string - */ - protected function addMagicMethods($methods, $alias, &$usedMethods, $addOutput = true){ - $output = ''; - foreach($methods 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, $usedMethods)){ - if( $addOutput){ - $output .= $this->parseMethod($method, $alias, $class, $magic); - } - $usedMethods[] = $method->name; - } - - - $usedMethods[] = $magic; - - } - return $output; - } - - /** - * @param \ReflectionMethod $method - * @param string $alias - * @param $class - * @param null $methodName - * @return string - */ - protected function parseMethod($method, $alias, $class, $methodName = null){ - $output = ''; - - // Don't add the __clone() functions - if($method->name === '__clone'){ - return $output; - } - $methodName = $methodName ?: $method->name; - - $namespace = $method->getDeclaringClass()->getNamespaceName(); - - //Create a DocBlock and serializer instance - $phpdoc = new DocBlock($method, new Context($namespace)); - $serializer = new DocBlockSerializer(1, "\t\t"); - - //Normalize the description and inherit the docs from parents/interfaces - try{ - $this->normalizeDescription($phpdoc, $method); - }catch(\Exception $e){ - $this->info("Cannot normalize method $alias::$methodName.."); - } - - //Correct the return values - $returnValue = $this->getReturn($phpdoc); - - //Get the parameters, including formatted default values - list($params, $paramsWithDefault) = $this->getParameters($method); - - //Make the method static - $phpdoc->appendTag(Tag::createInstance('@static', $phpdoc)); - - //Write the output, using the DocBlock serializer - $output .= $serializer->getDocComment($phpdoc) ."\n\t\t public static function ".$methodName."("; - - $output .= implode($paramsWithDefault, ", "); - $output .= "){\n"; - - //Only return when not a constructor and not void. - $return = ($returnValue && $returnValue !== "void" && $method->name !== "__construct") ? 'return' : ''; - - //Reference the 'real' function in the declaringclass - $declaringClass = $method->getDeclaringClass(); - $declaringClassName = '\\'.ltrim($declaringClass->name, '\\'); - $root = '\\'.ltrim($class->getName(), '\\'); - - if($declaringClass->name != $root){ - $output .= "\t\t\t//Method inherited from $declaringClassName\n"; - } - - $output .= "\t\t\t$return $root::"; - - //Write the default parameters in the function call - $output .= $method->name."(".implode($params, ", ").");\n"; - $output .= "\t\t }\n\n"; - - return $output; - } - - /** - * Get the description and get the inherited docs. - * - * @param $phpdoc - * @param $method - */ - protected function normalizeDescription(&$phpdoc, $method){ - //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($method); - $inheritDescription = $inheritdoc->getText(); - - $description = str_replace('{@inheritdoc}', $inheritDescription, $description); - $phpdoc->setText($description); - - //Add the tags that are inherited - $inheritTags = $inheritdoc->getTags(); - if($inheritTags){ - foreach($inheritTags as $tag){ - $tag->setDocBlock(); - $phpdoc->appendTag($tag); - } - } - } - } - - /** - * Make some changes to the return types, if needed. - * - * @param $phpdoc - * @return string|null - */ - protected function getReturn($phpdoc){ - //Get the return type and adjust them for beter autocomplete - $returnTags = $phpdoc->getTagsByName('return'); - if($returnTags){ - /** @var $tag */ - $tag = reset($returnTags); - $returnValue = $tag->getType(); - }else{ - $returnValue = null; - } - return $returnValue; - } - - /** - * 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->getDefaultValue(); - 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; - } - return array($params, $paramsWithDefault); - } - - /** - * @param \ReflectionMethod $reflectionMethod - * @return string - */ - 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){ - $phpdoc = new DocBlock($method); - if(strpos($phpdoc->getText(), '{@inheritdoc}') !== false ){ - //Not at the end yet, try another parent/interface.. - return $this->getInheritDoc($method); - }else{ - return $phpdoc; - } - } - } - } diff --git a/src/Console/ModelsCommand.php b/src/Console/ModelsCommand.php index 03a6bdb..5f26a2a 100644 --- a/src/Console/ModelsCommand.php +++ b/src/Console/ModelsCommand.php @@ -25,7 +25,8 @@ use phpDocumentor\Reflection\DocBlock\Serializer as DocBlockSerializer; * * @author Barry vd. Heuvel */ -class ModelsCommand extends Command { +class ModelsCommand extends Command +{ /** * The console command name. @@ -49,7 +50,6 @@ class ModelsCommand extends Command { protected $reset; - /** * Execute the console command. * @@ -59,25 +59,31 @@ class ModelsCommand extends Command { { $filename = $this->option('filename'); $this->write = $this->option('write'); - $this->dirs = array_merge($this->laravel['config']->get('laravel-ide-helper::model_locations'), $this->option('dir')); + $this->dirs = array_merge( + $this->laravel['config']->get('laravel-ide-helper::model_locations'), + $this->option('dir') + ); $model = $this->argument('model'); $ignore = $this->option('ignore'); $this->reset = $this->option('reset'); //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->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): " + ) + ) { $this->write = true; } } $content = $this->generateDocs($model, $ignore); - if(!$this->write){ + if (!$this->write) { $written = \File::put($filename, $content); - if($written !== false){ + if ($written !== false) { $this->info("Model information was written to $filename"); - }else{ + } else { $this->error("Failed to write model information to $filename"); } } @@ -113,7 +119,8 @@ class ModelsCommand extends Command { ); } - protected function generateDocs($loadModels, $ignore = ''){ + protected function generateDocs($loadModels, $ignore = '') + { $output = "loadModels(); - }else{ + } else { $models = array(); - foreach($loadModels as $model){ + foreach ($loadModels as $model) { $models = array_merge($models, explode(',', $model)); } } $ignore = explode(',', $ignore); - foreach($models as $name){ - if(in_array($name, $ignore)){ + foreach ($models as $name) { + if (in_array($name, $ignore)) { $this->comment("Ignoring model '$name'"); continue; - }else{ + } else { $this->comment("Loading model '$name'"); } $this->properties = array(); $this->methods = array(); - if(class_exists($name)){ + if (class_exists($name)) { try { // handle abstract classes, interfaces, ... $reflectionClass = new \ReflectionClass($name); if (!$reflectionClass->IsInstantiable()) { throw new \Exception($name . ' is not instanciable.'); - }elseif(!$reflectionClass->isSubclassOf('Illuminate\Database\Eloquent\Model')){ + } elseif (!$reflectionClass->isSubclassOf('Illuminate\Database\Eloquent\Model')) { $this->comment("Class '$name' is not a model"); continue; } $model = new $name(); - if($hasDoctrine){ + if ($hasDoctrine) { $this->getPropertiesFromTable($model); } $this->getPropertiesFromMethods($model); $output .= $this->createPhpDocs($name); - }catch(\Exception $e){ - $this->error("Exception: ".$e->getMessage()."\nCould not analyze class $name."); + } catch (\Exception $e) { + $this->error("Exception: " . $e->getMessage() . "\nCould not analyze class $name."); } - }else{ + } else { $this->error("Class $name does not exist"); } } - - if(!$hasDoctrine){ - $this->error("Warning: 'doctrine/dbal: ~2.3' is required to load database information. Please require that in your composer.json and run 'composer update'."); + + if (!$hasDoctrine) { + $this->error( + "Warning: 'doctrine/dbal: ~2.3' is required to load database information. Please require that in your composer.json and run 'composer update'." + ); } return $output; @@ -183,12 +192,13 @@ class ModelsCommand extends Command { } - protected function loadModels(){ + protected function loadModels() + { $models = array(); - foreach($this->dirs as $dir){ + foreach ($this->dirs as $dir) { $dir = base_path() . '/' . $dir; - if(file_exists($dir)){ - foreach(ClassMapGenerator::createMap($dir) as $model=> $path){ + if (file_exists($dir)) { + foreach (ClassMapGenerator::createMap($dir) as $model => $path) { $models[] = $model; } } @@ -201,21 +211,22 @@ class ModelsCommand extends Command { * * @param \Illuminate\Database\Eloquent\Model $model */ - protected function getPropertiesFromTable($model){ + protected function getPropertiesFromTable($model) + { $table = $model->getConnection()->getTablePrefix() . $model->getTable(); $schema = $model->getConnection()->getDoctrineSchemaManager($table); $schema->getDatabasePlatform()->registerDoctrineTypeMapping('enum', 'string'); $columns = $schema->listTableColumns($table); - if($columns){ + if ($columns) { foreach ($columns as $column) { $name = $column->getName(); - if(in_array($name, $model->getDates())){ + if (in_array($name, $model->getDates())) { $type = '\Carbon\Carbon'; - }else{ - $type = $column->getType()->getName(); - switch($type){ + } else { + $type = $column->getType()->getName(); + switch ($type) { case 'string': case 'text': case 'date': @@ -245,7 +256,11 @@ class ModelsCommand extends Command { $this->setProperty($name, $type, true, true); - $this->setMethod(Str::camel("where_".$name), '\Illuminate\Database\Query\Builder|\\'.get_class($model), array('$value')); + $this->setMethod( + Str::camel("where_" . $name), + '\Illuminate\Database\Query\Builder|\\' . get_class($model), + array('$value') + ); } } } @@ -253,33 +268,42 @@ class ModelsCommand extends Command { /** * @param \Illuminate\Database\Eloquent\Model $model */ - protected function getPropertiesFromMethods($model){ + protected function getPropertiesFromMethods($model) + { $methods = get_class_methods($model); - if($methods){ - foreach($methods as $method){ - if(Str::startsWith($method, 'get') && Str::endsWith($method, 'Attribute') && $method !== 'getAttribute'){ + if ($methods) { + foreach ($methods as $method) { + if (Str::startsWith($method, 'get') && Str::endsWith( + $method, + 'Attribute' + ) && $method !== 'getAttribute' + ) { //Magic getAttribute - $name = Str::snake(substr($method, 3, -9)); - if(!empty($name)){ + $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 setAttribute - $name = Str::snake(substr($method, 3, -9)); - if(!empty($name)){ + $name = Str::snake(substr($method, 3, -9)); + if (!empty($name)) { $this->setProperty($name, null, null, true); } - }elseif(Str::startsWith($method, 'scope') && $method !== 'scopeQuery'){ + } elseif (Str::startsWith($method, 'scope') && $method !== 'scopeQuery') { //Magic setAttribute - $name = Str::camel(substr($method, 5)); - if(!empty($name)){ + $name = Str::camel(substr($method, 5)); + if (!empty($name)) { $reflection = new \ReflectionMethod($model, $method); $args = $this->getParameters($reflection); //Remove the first ($query) argument array_shift($args); - $this->setMethod($name, '\\'.$reflection->class, $args); + $this->setMethod($name, '\\' . $reflection->class, $args); } - }elseif(!method_exists('Eloquent', $method) && !Str::startsWith($method, 'get')){ + } elseif (!method_exists('Eloquent', $method) && !Str::startsWith($method, 'get')) { //Use reflection to inspect the code, based on Illuminate/Support/SerializableClosure.php $reflection = new \ReflectionMethod($model, $method); @@ -288,24 +312,37 @@ class ModelsCommand extends Command { $file->seek($reflection->getStartLine() - 1); $code = ''; - while ($file->key() < $reflection->getEndLine()) - { - $code .= $file->current(); $file->next(); + while ($file->key() < $reflection->getEndLine()) { + $code .= $file->current(); + $file->next(); } $begin = strpos($code, 'function('); $code = substr($code, $begin, strrpos($code, '}') - $begin + 1); - foreach(array('hasMany', 'belongsToMany', 'hasOne', 'belongsTo', 'morphTo', 'morphMany', 'morphToMany') as $relation){ - $search = '$this->'.$relation.'('; - if($pos = stripos($code, $search)){ + 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, stripos($code, ')'))); //Remove quotes, ensure 1 \ in front of the model - $returnModel = "\\".ltrim(trim($arguments[0], " \"'"), "\\"); - if($relation === "belongsToMany" or $relation === 'hasMany' or $relation === 'morphMany' or $relation === 'morphToMany'){ + $returnModel = "\\" . ltrim(trim($arguments[0], " \"'"), "\\"); + if ($relation === "belongsToMany" or $relation === 'hasMany' or $relation === 'morphMany' or $relation === 'morphToMany') { //Collection or array of models (because Collection is Arrayable) - $this->setProperty($method, '\Illuminate\Database\Eloquent\Collection|'.$returnModel.'[]', true, null); - }else{ + $this->setProperty( + $method, + '\Illuminate\Database\Eloquent\Collection|' . $returnModel . '[]', + true, + null + ); + } else { //Single model is returned $this->setProperty($method, $returnModel, true, null); } @@ -323,26 +360,28 @@ class ModelsCommand extends Command { * @param bool|null $read * @param bool|null $write */ - protected function setProperty($name, $type = null, $read = null, $write = null){ - if(!isset($this->properties[$name])){ + protected function setProperty($name, $type = null, $read = null, $write = null) + { + if (!isset($this->properties[$name])) { $this->properties[$name] = array(); $this->properties[$name]['type'] = 'mixed'; $this->properties[$name]['read'] = false; $this->properties[$name]['write'] = false; } - if($type !== null){ + if ($type !== null) { $this->properties[$name]['type'] = $type; } - if($read !== null){ + if ($read !== null) { $this->properties[$name]['read'] = $read; } - if($write !== null){ + if ($write !== null) { $this->properties[$name]['write'] = $write; } } - protected function setMethod($name, $type = '', $arguments=array()){ - if(!isset($this->methods[$name])){ + protected function setMethod($name, $type = '', $arguments = array()) + { + if (!isset($this->methods[$name])) { $this->methods[$name] = array(); $this->methods[$name]['type'] = $type; $this->methods[$name]['arguments'] = $arguments; @@ -353,55 +392,56 @@ class ModelsCommand extends Command { * @param string $class * @return string */ - protected function createPhpDocs($class){ + protected function createPhpDocs($class) + { $reflection = new \ReflectionClass($class); $namespace = $reflection->getNamespaceName(); $classname = $reflection->getShortName(); $originalDoc = $reflection->getDocComment(); - if($this->reset){ + if ($this->reset) { $phpdoc = new DocBlock('', new Context($namespace)); - }else{ + } else { $phpdoc = new DocBlock($reflection, new Context($namespace)); } - if(!$phpdoc->getText()){ + if (!$phpdoc->getText()) { $phpdoc->setText($class); } $properties = array(); $methods = array(); - foreach($phpdoc->getTags() as $tag){ + foreach ($phpdoc->getTags() as $tag) { $name = $tag->getName(); - if($name == "property" || $name == "property-read" || $name == "property-write"){ - $properties[] =$tag->getVariableName(); - }elseif($name == "method"){ + if ($name == "property" || $name == "property-read" || $name == "property-write") { + $properties[] = $tag->getVariableName(); + } elseif ($name == "method") { $methods[] = $tag->getMethodName(); } } - foreach($this->properties as $name => $property){ + foreach ($this->properties as $name => $property) { $name = "\$$name"; - if(in_array($name, $properties)){ + if (in_array($name, $properties)) { continue; } - if($property['read'] && $property['write']){ + if ($property['read'] && $property['write']) { $attr = 'property'; - }elseif($property['write']){ + } elseif ($property['write']) { $attr = 'property-write'; - }else{ + } else { $attr = 'property-read'; } $tag = Tag::createInstance("@{$attr} {$property['type']} {$name}", $phpdoc); $phpdoc->appendTag($tag); } - foreach($this->methods as $name => $method){ - if(in_array($name, $methods)){ + foreach ($this->methods as $name => $method) { + if (in_array($name, $methods)) { continue; } - $arguments = implode(', ',$method['arguments']); + $arguments = implode(', ', $method['arguments']); $tag = Tag::createInstance("@method static {$method['type']} {$name}({$arguments}) ", $phpdoc); $phpdoc->appendTag($tag); } @@ -411,21 +451,21 @@ class ModelsCommand extends Command { $docComment = $serializer->getDocComment($phpdoc); - if($this->write){ + if ($this->write) { $filename = $reflection->getFileName(); $contents = \File::get($filename); - if($originalDoc){ + if ($originalDoc) { $contents = str_replace($originalDoc, $docComment, $contents); - }else{ + } else { $needle = "class {$classname}"; $replace = "{$docComment}\nclass {$classname}"; - $pos = strpos($contents,$needle); + $pos = strpos($contents, $needle); if ($pos !== false) { - $contents = substr_replace($contents,$replace,$pos,strlen($needle)); + $contents = substr_replace($contents, $replace, $pos, strlen($needle)); } } - if(\File::put($filename, $contents)){ - $this->info('Written new phpDocBlock to '.$filename); + if (\File::put($filename, $contents)) { + $this->info('Written new phpDocBlock to ' . $filename); } } @@ -439,25 +479,26 @@ class ModelsCommand extends Command { * @param $method * @return array */ - public function getParameters($method){ + 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(); + $paramStr = '$' . $param->getName(); $params[] = $paramStr; if ($param->isOptional()) { $default = $param->getDefaultValue(); - if(is_bool($default)){ - $default = $default? 'true':'false'; - }elseif(is_array($default)){ + if (is_bool($default)) { + $default = $default ? 'true' : 'false'; + } elseif (is_array($default)) { $default = 'array()'; - }elseif(is_null($default)){ + } elseif (is_null($default)) { $default = 'null'; - }elseif(is_int($default)){ + } elseif (is_int($default)) { //$default = $default; - }else{ - $default = "'".trim($default)."'"; + } else { + $default = "'" . trim($default) . "'"; } $paramStr .= " = $default"; } diff --git a/src/Generator.php b/src/Generator.php new file mode 100644 index 0000000..74aced3 --- /dev/null +++ b/src/Generator.php @@ -0,0 +1,130 @@ + + * @copyright 2013 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; + +class Generator +{ + + /** @var \Illuminate\View\Factory */ + protected $view; + + protected $extra; + protected $magic; + protected $helpers; + + /** + * @param \Illuminate\View\Factory $view + * @param array $extra + * @param array $magic + * @param string $helpers + */ + public function __construct( /* Illuminate\View\Factory */ + $view, + $extra = array(), + $magic = array(), + $helpers = '' + ) { + $this->view = $view; + $this->extra = $extra; + $this->magic = $magic; + $this->helpers = $helpers; + } + + /** + * Generate the helper file contents; + * + * @return string; + */ + public function generate() + { + return $this->view->make('laravel-ide-helper::ide-helper') + ->with('namespaces', $this->getNamespaces()) + ->with('helpers', $this->helpers) + ->render(); + + } + + /** + * 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) { + $alias = new Alias($name, $facade); + + if ($alias->isValid()) { + + $driver = $this->getDriver($name); + if ($driver) { + $alias->addClass($driver); + } + + //Add extra methods, from other classes (magic static calls) + if (array_key_exists($name, $this->extra)) { + $alias->addClass($this->extra[$name]); + } + + //Add extra methods, from other classes (magic static calls) + if (array_key_exists($name, $this->magic)) { + $alias->addClass($this->magic[$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; + } + } + +} diff --git a/src/IdeHelperServiceProvider.php b/src/IdeHelperServiceProvider.php index 3e267d8..53edefb 100644 --- a/src/IdeHelperServiceProvider.php +++ b/src/IdeHelperServiceProvider.php @@ -12,55 +12,61 @@ namespace Barryvdh\LaravelIdeHelper; use Illuminate\Support\ServiceProvider; use Barryvdh\LaravelIdeHelper\Console\GeneratorCommand; +use Barryvdh\LaravelIdeHelper\Console\Generator2Command; Use Barryvdh\LaravelIdeHelper\Console\ModelsCommand; -class IdeHelperServiceProvider extends ServiceProvider { +class IdeHelperServiceProvider extends ServiceProvider +{ - /** - * Indicates if loading of the provider is deferred. - * - * @var bool - */ - protected $defer = true; + /** + * Indicates if loading of the provider is deferred. + * + * @var bool + */ + protected $defer = true; - /** - * Bootstrap the application events. - * - * @return void - */ - public function boot() - { - $this->app['config']->package('barryvdh/laravel-ide-helper', __DIR__ . '/config'); - } + /** + * Bootstrap the application events. + * + * @return void + */ + public function boot() + { + $this->package('barryvdh/laravel-ide-helper', 'laravel-ide-helper', __DIR__); + } - /** - * Register the service provider. - * - * @return void - */ - public function register() - { - $this->app['command.ide-helper.generate'] = $this->app->share(function() - { - return new GeneratorCommand; - }); + /** + * Register the service provider. + * + * @return void + */ + public function register() + { - $this->app['command.ide-helper.models'] = $this->app->share(function() - { + $this->app['command.ide-helper.generate'] = $this->app->share( + function ($app) { + return new GeneratorCommand($app['config'], $app['files'], $app['view']); + } + ); + + + $this->app['command.ide-helper.models'] = $this->app->share( + function () { return new ModelsCommand(); - }); + } + ); $this->commands('command.ide-helper.generate', 'command.ide-helper.models'); - } + } - /** - * Get the services provided by the provider. - * - * @return array - */ - public function provides() - { + /** + * Get the services provided by the provider. + * + * @return array + */ + public function provides() + { return array('command.ide-helper.generate', 'command.ide-helper.models'); - } + } } diff --git a/src/Method.php b/src/Method.php new file mode 100644 index 0000000..2e7989b --- /dev/null +++ b/src/Method.php @@ -0,0 +1,246 @@ + + * @copyright 2013 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\Serializer as DocBlockSerializer; + +class Method +{ + + protected $output = ''; + protected $name; + protected $namespace; + protected $phpdoc; + protected $params = array(); + protected $params_with_default = array(); + + public function __construct($method, $alias, $class, $methodName = null) + { + + $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->normalizeDescription($method); + } catch (\Exception $e) { + $this->info("Cannot normalize method $alias::$methodName.."); + } + + //Get the parameters, including formatted default values + $this->getParameters($method); + + //Make the method static + $this->phpdoc->appendTag(Tag::createInstance('@static', $this->phpdoc)); + + //Correct the return values + $returnValue = $this->getReturn(); + //Only return when not a constructor and not void. + $this->return = ($returnValue && $returnValue !== "void" && $method->name !== "__construct"); + + //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; + } + + /** + * Should the function return a value? + * + * @return bool + */ + public function shouldReturn() + { + return $this->return; + } + + /** + * 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(', ', $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(', ', $this->params_with_default); + } + + /** + * Get the description and get the inherited docs. + * + * @param $method + */ + protected function normalizeDescription($method) + { + //Get the short + long description from the DocBlock + $description = $this->phpdoc->getText(); + + //Loop through parents/interfaces, to fill in {@inheritdoc} + if (strpos($description, '{@inheritdoc}') !== false) { + $inheritdoc = $this->getInheritDoc($method); + $inheritDescription = $inheritdoc->getText(); + + $description = str_replace('{@inheritdoc}', $inheritDescription, $description); + $this->phpdoc->setText($description); + + //Add the tags that are inherited + $inheritTags = $inheritdoc->getTags(); + if ($inheritTags) { + foreach ($inheritTags as $tag) { + $tag->setDocBlock(); + $this->phpdoc->appendTag($tag); + } + } + } + } + + /** + * Make some changes to the return types, if needed. + * + * @return string|null + */ + protected function getReturn() + { + //Get the return type and adjust them for beter autocomplete + $returnTags = $this->phpdoc->getTagsByName('return'); + if ($returnTags) { + /** @var $tag */ + $tag = reset($returnTags); + $returnValue = $tag->getType(); + } else { + $returnValue = null; + } + return $returnValue; + } + + /** + * 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->getDefaultValue(); + 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 string + */ + 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) { + $phpdoc = new DocBlock($method); + if (strpos($phpdoc->getText(), '{@inheritdoc}') !== false) { + //Not at the end yet, try another parent/interface.. + return $this->getInheritDoc($method); + } else { + return $phpdoc; + } + } + } + +} diff --git a/src/config/config.php b/src/config/config.php old mode 100755 new mode 100644 diff --git a/src/views/ide-helper.php b/src/views/ide-helper.php new file mode 100644 index 0000000..6b15543 --- /dev/null +++ b/src/views/ide-helper.php @@ -0,0 +1,36 @@ + + +/** + * An helper file for Laravel 4, to provide autocomplete information to your IDE + * Generated with https://github.com/barryvdh/laravel-ide-helper + * + * @author Barry vd. Heuvel + */ + + $aliases): ?> + +namespace { + + + + + + getClassType() ?> getAlias() ?> getExtends() ? 'extends ' . $alias->getExtends() : '' ?>{ + getMethods() as $method): ?> + + getDocComment()) ?> + + public static function getName() ?>(getParamsWithDefault() ?>){ + //Method inherited from getDeclaringClass() ?> + + shouldReturn() ? 'return ': '' ?>getRoot() ?>::getName() ?>(getParams() ?>); + } + + + } + + + +} + + From f29e6037c04633c3dd0d182e0f3b6dfb91b5f606 Mon Sep 17 00:00:00 2001 From: "Barry vd. Heuvel" Date: Wed, 6 Aug 2014 12:29:26 +0200 Subject: [PATCH 3/7] Work on interfaces --- src/Alias.php | 6 ++++-- src/Console/GeneratorCommand.php | 8 ++------ src/Generator.php | 20 +++++++++++--------- src/Method.php | 17 ++++++++++++----- src/config/config.php | 3 +++ 5 files changed, 32 insertions(+), 22 deletions(-) diff --git a/src/Alias.php b/src/Alias.php index e5d989c..f5aa274 100644 --- a/src/Alias.php +++ b/src/Alias.php @@ -23,10 +23,12 @@ class Alias protected $methods = array(); protected $used_methods = array(); protected $valid = false; + protected $interfaces = array(); - public function __construct($alias, $facade) + public function __construct($alias, $facade, $interfaces = array()) { $this->alias = $alias; + $this->interfaces = $interfaces; // Make the class absolute $facade = '\\' . ltrim($facade, '\\'); @@ -223,7 +225,7 @@ class Alias // Only add the methods to the output when the root is not the same as the facade. // And don't add the __*() methods if ($this->facade !== $this->root && substr($method->name, 0, 2) !== '__') { - $this->methods[] = new Method($method, $this->alias, $reflection); + $this->methods[] = new Method($method, $this->alias, $reflection, $this->interfaces); } $this->used_methods[] = $method->name; } diff --git a/src/Console/GeneratorCommand.php b/src/Console/GeneratorCommand.php index 50812e8..1e05a63 100644 --- a/src/Console/GeneratorCommand.php +++ b/src/Console/GeneratorCommand.php @@ -53,10 +53,7 @@ class GeneratorCommand extends Command /** @var \Illuminate\View\Factory */ protected $view; - protected $extra; protected $onlyExtend; - protected $helpers; - protected $magic; /** @@ -94,8 +91,7 @@ class GeneratorCommand extends Command $this->useMemoryDriver(); } - $extra = $this->config->get('laravel-ide-helper::extra'); - $magic = $this->config->get('laravel-ide-helper::magic'); + $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) { @@ -107,7 +103,7 @@ class GeneratorCommand extends Command $helpers = ''; } - $generator = new Generator($this->view, $extra, $magic, $helpers); + $generator = new Generator($this->config, $this->view, $helpers); $output = $generator->generate(); diff --git a/src/Generator.php b/src/Generator.php index 74aced3..04d967e 100644 --- a/src/Generator.php +++ b/src/Generator.php @@ -15,6 +15,8 @@ use Illuminate\Config\Repository as ConfigRepository; class Generator { + /** @var \Illuminate\Config\Repository */ + protected $config; /** @var \Illuminate\View\Factory */ protected $view; @@ -24,21 +26,21 @@ class Generator protected $helpers; /** + * @param \Illuminate\Config\Repository $config * @param \Illuminate\View\Factory $view - * @param array $extra - * @param array $magic * @param string $helpers */ - public function __construct( /* Illuminate\View\Factory */ - $view, - $extra = array(), - $magic = array(), + public function __construct(ConfigRepository $config, + /* Illuminate\View\Factory */ $view, $helpers = '' ) { + $this->config = $config; $this->view = $view; - $this->extra = $extra; - $this->magic = $magic; + $this->extra = $this->config->get('laravel-ide-helper::extra'); + $this->magic = $this->config->get('laravel-ide-helper::magic'); + $this->interfaces = $this->config->get('laravel-ide-helper::interfaces'); $this->helpers = $helpers; + } /** @@ -66,7 +68,7 @@ class Generator // Get all aliases foreach (AliasLoader::getInstance()->getAliases() as $name => $facade) { - $alias = new Alias($name, $facade); + $alias = new Alias($name, $facade, $this->interfaces); if ($alias->isValid()) { diff --git a/src/Method.php b/src/Method.php index 2e7989b..e93e7b0 100644 --- a/src/Method.php +++ b/src/Method.php @@ -24,11 +24,12 @@ class Method protected $phpdoc; protected $params = array(); protected $params_with_default = array(); + protected $interfaces = array(); - public function __construct($method, $alias, $class, $methodName = null) + public function __construct($method, $alias, $class, $interfaces = array()) { - - $this->name = $methodName ?: $method->name; + $this->interfaces = $interfaces; + $this->name = $method->name; $this->namespace = $method->getDeclaringClass()->getNamespaceName(); //Create a DocBlock and serializer instance @@ -38,7 +39,7 @@ class Method try { $this->normalizeDescription($method); } catch (\Exception $e) { - $this->info("Cannot normalize method $alias::$methodName.."); + $this->info("Cannot normalize method $alias::{$this->name}.."); } //Get the parameters, including formatted default values @@ -173,12 +174,18 @@ class Method //Get the return type and adjust them for beter autocomplete $returnTags = $this->phpdoc->getTagsByName('return'); if ($returnTags) { - /** @var $tag */ + /** @var Tag $tag */ $tag = reset($returnTags); $returnValue = $tag->getType(); + + foreach($this->interfaces as $interface => $real){ + $returnValue = str_replace($interface, $real, $returnValue); + } + $tag->setContent($returnValue); } else { $returnValue = null; } + return $returnValue; } diff --git a/src/config/config.php b/src/config/config.php index 89b3dad..6925516 100644 --- a/src/config/config.php +++ b/src/config/config.php @@ -70,6 +70,9 @@ return array( 'alert' => 'Monolog\Logger::addAlert', 'emergency' => 'Monolog\Logger::addEmergency', ) + ), + 'interfaces' => array( + '\Illuminate\Auth\UserInterface' => '\User', ) ); From 27ffcb883c9488dbe36fd95836972fcc8859036e Mon Sep 17 00:00:00 2001 From: "Barry vd. Heuvel" Date: Wed, 6 Aug 2014 12:41:20 +0200 Subject: [PATCH 4/7] Tweak inhereting --- src/views/ide-helper.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/views/ide-helper.php b/src/views/ide-helper.php index 6b15543..71c6d12 100644 --- a/src/views/ide-helper.php +++ b/src/views/ide-helper.php @@ -20,8 +20,10 @@ namespace { getDocComment()) ?> - public static function getName() ?>(getParamsWithDefault() ?>){ + public static function getName() ?>(getParamsWithDefault() ?>){getDeclaringClass() !== $method->getRoot()): ?> + //Method inherited from getDeclaringClass() ?> + shouldReturn() ? 'return ': '' ?>getRoot() ?>::getName() ?>(getParams() ?>); } From 8dcc74a95f0eade39832f16e8d93ce8026b10160 Mon Sep 17 00:00:00 2001 From: "Barry vd. Heuvel" Date: Wed, 6 Aug 2014 13:04:52 +0200 Subject: [PATCH 5/7] Add magic methods --- src/Alias.php | 39 +++++++++++++++++++++++++++++++-------- src/Generator.php | 9 ++------- src/Method.php | 4 ++-- 3 files changed, 35 insertions(+), 17 deletions(-) diff --git a/src/Alias.php b/src/Alias.php index f5aa274..051fff2 100644 --- a/src/Alias.php +++ b/src/Alias.php @@ -16,18 +16,20 @@ class Alias protected $alias; protected $facade; protected $extends = null; - protected $classTYpe = 'class'; + protected $classType = 'class'; protected $namespace = '__root'; protected $root = null; protected $classes = array(); protected $methods = array(); - protected $used_methods = array(); + protected $usedMethods = array(); protected $valid = false; + protected $magicMethods = array(); protected $interfaces = array(); - public function __construct($alias, $facade, $interfaces = array()) + public function __construct($alias, $facade, $magicMethods = array(), $interfaces = array()) { $this->alias = $alias; + $this->magicMethods = $magicMethods; $this->interfaces = $interfaces; // Make the class absolute @@ -61,6 +63,8 @@ class Alias foreach ($classes as $class) { if (class_exists($class) || interface_exists($class)) { $this->classes[] = $class; + }else{ + echo "Class not exists: $class\r\n"; } } @@ -122,6 +126,7 @@ class Alias */ public function getMethods() { + $this->addMagicMethods(); $this->detectMethods(); return $this->methods; @@ -207,6 +212,24 @@ class Alias return false; } + 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. * @@ -221,13 +244,13 @@ class Alias $methods = $reflection->getMethods(\ReflectionMethod::IS_PUBLIC); if ($methods) { foreach ($methods as $method) { - if (!in_array($method->name, $this->used_methods)) { - // Only add the methods to the output when the root is not the same as the facade. + 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->facade !== $this->root && substr($method->name, 0, 2) !== '__') { - $this->methods[] = new Method($method, $this->alias, $reflection, $this->interfaces); + if ($this->extends !== $class && $method->name !== '__clone') { + $this->methods[] = new Method($method, $this->alias, $reflection, $method->name, $this->interfaces); } - $this->used_methods[] = $method->name; + $this->usedMethods[] = $method->name; } } } diff --git a/src/Generator.php b/src/Generator.php index 04d967e..7931cf7 100644 --- a/src/Generator.php +++ b/src/Generator.php @@ -40,7 +40,6 @@ class Generator $this->magic = $this->config->get('laravel-ide-helper::magic'); $this->interfaces = $this->config->get('laravel-ide-helper::interfaces'); $this->helpers = $helpers; - } /** @@ -68,7 +67,8 @@ class Generator // Get all aliases foreach (AliasLoader::getInstance()->getAliases() as $name => $facade) { - $alias = new Alias($name, $facade, $this->interfaces); + $magicMethods = array_key_exists($name, $this->magic) ? $this->magic[$name] : array(); + $alias = new Alias($name, $facade, $magicMethods, $this->interfaces); if ($alias->isValid()) { @@ -82,11 +82,6 @@ class Generator $alias->addClass($this->extra[$name]); } - //Add extra methods, from other classes (magic static calls) - if (array_key_exists($name, $this->magic)) { - $alias->addClass($this->magic[$name]); - } - $namespace = $alias->getNamespace(); if (!isset($namespaces[$namespace])) { $namespaces[$namespace] = array(); diff --git a/src/Method.php b/src/Method.php index e93e7b0..f751b5b 100644 --- a/src/Method.php +++ b/src/Method.php @@ -26,10 +26,10 @@ class Method protected $params_with_default = array(); protected $interfaces = array(); - public function __construct($method, $alias, $class, $interfaces = array()) + public function __construct($method, $alias, $class, $methodName = null, $interfaces = array()) { $this->interfaces = $interfaces; - $this->name = $method->name; + $this->name = $methodName ?: $method->name; $this->namespace = $method->getDeclaringClass()->getNamespaceName(); //Create a DocBlock and serializer instance From 70ab315092f7aa911fb3f6e02d05193a3416a02c Mon Sep 17 00:00:00 2001 From: "Barry vd. Heuvel" Date: Wed, 6 Aug 2014 17:02:21 +0200 Subject: [PATCH 6/7] Detect interfaces/drivers --- src/Generator.php | 69 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 59 insertions(+), 10 deletions(-) diff --git a/src/Generator.php b/src/Generator.php index 7931cf7..684ff84 100644 --- a/src/Generator.php +++ b/src/Generator.php @@ -21,8 +21,9 @@ class Generator /** @var \Illuminate\View\Factory */ protected $view; - protected $extra; - protected $magic; + protected $extra = array(); + protected $magic = array(); + protected $interfaces = array(); protected $helpers; /** @@ -36,9 +37,13 @@ class Generator ) { $this->config = $config; $this->view = $view; - $this->extra = $this->config->get('laravel-ide-helper::extra'); - $this->magic = $this->config->get('laravel-ide-helper::magic'); - $this->interfaces = $this->config->get('laravel-ide-helper::interfaces'); + + // 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')); $this->helpers = $helpers; } @@ -56,6 +61,55 @@ class Generator } + protected function detectDrivers() + { + try{ + if (class_exists('Cache')) { + $class = get_class(\Auth::driver()); + $this->extra['Auth'] = array($class); + $this->interfaces['\Illuminate\Auth\UserProviderInterface'] = $class; + } + }catch (\Exception $e) {} + + try{ + if (class_exists('DB')) { + $class = get_class(\DB::connection()); + $this->extra['DB'] = array($class); + $this->interfaces['\Illuminate\Database\ConnectionInterface'] = $class; + } + }catch (\Exception $e) {} + + try{ + if (class_exists('Cache')) { + $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')) { + $class = get_class(\Queue::connection()); + $this->extra['Queue'] = array($class); + $this->interfaces['\Illuminate\Queue\QueueInterface'] = $class; + } + }catch (\Exception $e) {} + + try{ + if (class_exists('SSH')){ + $class = get_class(\SSH::connection()); + $this->extra['SSH'] = array($class); + $this->interfaces['\Illuminate\Remote\ConnectionInterface'] = $class; + } + }catch (\Exception $e) {} + + // Make all interface classes absolute + foreach ($this->interfaces as &$interface) { + $interface = '\\' . ltrim($interface, '\\'); + } + } + /** * Find all namespaces/aliases that are valid for us to render * @@ -72,11 +126,6 @@ class Generator if ($alias->isValid()) { - $driver = $this->getDriver($name); - if ($driver) { - $alias->addClass($driver); - } - //Add extra methods, from other classes (magic static calls) if (array_key_exists($name, $this->extra)) { $alias->addClass($this->extra[$name]); From e9bc9347cc4683fcdcda00f8185943586ec643e7 Mon Sep 17 00:00:00 2001 From: "Barry vd. Heuvel" Date: Wed, 6 Aug 2014 19:27:22 +0200 Subject: [PATCH 7/7] Cleanup --- composer.json | 4 ++-- src/Alias.php | 32 +++++++++++++++++++++----------- src/Console/GeneratorCommand.php | 16 +++++----------- src/Generator.php | 24 +++++++++++++++++++++--- src/IdeHelperServiceProvider.php | 4 +--- src/Method.php | 32 ++++++++++++++++++++++++-------- 6 files changed, 74 insertions(+), 38 deletions(-) diff --git a/composer.json b/composer.json index f598a4a..9a8abcc 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "barryvdh/laravel-ide-helper", "description": "Laravel IDE Helper, generates correct PHPDocs for all Facade classes, to improve auto-completion.", - "keywords": ["laravel", "autocomplete", "phpstorm", "netbeans", "sublime", "codeintel", "phpdoc"], + "keywords": ["laravel", "autocomplete", "ide", "helper", "phpstorm", "netbeans", "sublime", "codeintel", "phpdoc"], "license": "MIT", "authors": [ { @@ -30,7 +30,7 @@ }, "extra": { "branch-alias": { - "dev-master": "1.10-dev" + "dev-master": "1.11-dev" } } } diff --git a/src/Alias.php b/src/Alias.php index 051fff2..c77be4a 100644 --- a/src/Alias.php +++ b/src/Alias.php @@ -3,7 +3,7 @@ * Laravel IDE Helper Generator * * @author Barry vd. Heuvel - * @copyright 2013 Barry vd. Heuvel / Fruitcake Studio (http://www.fruitcakestudio.nl) + * @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 */ @@ -26,6 +26,12 @@ class Alias 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; @@ -67,7 +73,6 @@ class Alias echo "Class not exists: $class\r\n"; } } - } /** @@ -129,7 +134,6 @@ class Alias $this->addMagicMethods(); $this->detectMethods(); return $this->methods; - } /** @@ -191,11 +195,9 @@ class Alias $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."); } - } /** @@ -212,8 +214,11 @@ class Alias return false; } - protected function addMagicMethods(){ - + /** + * 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)){ @@ -230,6 +235,7 @@ class Alias } } } + /** * Get the methods for one or multiple classes. * @@ -257,10 +263,14 @@ class Alias } } - // Helper class to log errors - protected function error($msg) + /** + * Output an error. + * + * @param string $string + * @return void + */ + protected function error($string) { - echo $msg . "\r\n"; + echo $string . "\r\n"; } - } diff --git a/src/Console/GeneratorCommand.php b/src/Console/GeneratorCommand.php index 1e05a63..7c40046 100644 --- a/src/Console/GeneratorCommand.php +++ b/src/Console/GeneratorCommand.php @@ -3,7 +3,7 @@ * Laravel IDE Helper Generator * * @author Barry vd. Heuvel - * @copyright 2013 Barry vd. Heuvel / Fruitcake Studio (http://www.fruitcakestudio.nl) + * @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 */ @@ -16,11 +16,7 @@ use Illuminate\Console\Command; use Illuminate\Filesystem\Filesystem; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputArgument; -use Illuminate\Foundation\AliasLoader; -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 @@ -103,11 +99,9 @@ class GeneratorCommand extends Command $helpers = ''; } - $generator = new Generator($this->config, $this->view, $helpers); - $output = $generator->generate(); - - - $written = $this->files->put($filename, $output); + $generator = new Generator($this->config, $this->view, $this->getOutput(), $helpers); + $content = $generator->generate(); + $written = $this->files->put($filename, $content); if ($written !== false) { $this->info("A new helper file was written to $filename"); diff --git a/src/Generator.php b/src/Generator.php index 684ff84..b68f81f 100644 --- a/src/Generator.php +++ b/src/Generator.php @@ -3,7 +3,7 @@ * Laravel IDE Helper Generator * * @author Barry vd. Heuvel - * @copyright 2013 Barry vd. Heuvel / Fruitcake Studio (http://www.fruitcakestudio.nl) + * @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 */ @@ -12,6 +12,7 @@ namespace Barryvdh\LaravelIdeHelper; use Illuminate\Foundation\AliasLoader; use Illuminate\Config\Repository as ConfigRepository; +use Symfony\Component\Console\Output\OutputInterface; class Generator { @@ -21,6 +22,9 @@ class Generator /** @var \Illuminate\View\Factory */ protected $view; + /** @var \Symfony\Component\Console\Output\OutputInterface */ + protected $output; + protected $extra = array(); protected $magic = array(); protected $interfaces = array(); @@ -29,10 +33,12 @@ class Generator /** * @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; @@ -58,7 +64,6 @@ class Generator ->with('namespaces', $this->getNamespaces()) ->with('helpers', $this->helpers) ->render(); - } protected function detectDrivers() @@ -123,7 +128,6 @@ class Generator 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) @@ -173,4 +177,18 @@ class Generator } } + /** + * Write a string as error output. + * + * @param string $string + * @return void + */ + protected function error($string) + { + if($this->output){ + $this->output->writeln("$string"); + }else{ + echo $string . "\r\n"; + } + } } diff --git a/src/IdeHelperServiceProvider.php b/src/IdeHelperServiceProvider.php index 53edefb..f9cd2db 100644 --- a/src/IdeHelperServiceProvider.php +++ b/src/IdeHelperServiceProvider.php @@ -3,7 +3,7 @@ * Laravel IDE Helper Generator * * @author Barry vd. Heuvel - * @copyright 2013 Barry vd. Heuvel / Fruitcake Studio (http://www.fruitcakestudio.nl) + * @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 */ @@ -42,14 +42,12 @@ class IdeHelperServiceProvider extends ServiceProvider */ public function register() { - $this->app['command.ide-helper.generate'] = $this->app->share( function ($app) { return new GeneratorCommand($app['config'], $app['files'], $app['view']); } ); - $this->app['command.ide-helper.models'] = $this->app->share( function () { return new ModelsCommand(); diff --git a/src/Method.php b/src/Method.php index f751b5b..1ff0186 100644 --- a/src/Method.php +++ b/src/Method.php @@ -3,7 +3,7 @@ * Laravel IDE Helper Generator * * @author Barry vd. Heuvel - * @copyright 2013 Barry vd. Heuvel / Fruitcake Studio (http://www.fruitcakestudio.nl) + * @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 */ @@ -17,16 +17,24 @@ use phpDocumentor\Reflection\DocBlock\Serializer as DocBlockSerializer; class Method { + /** @var \phpDocumentor\Reflection\DocBlock */ + protected $phpdoc; protected $output = ''; protected $name; protected $namespace; - protected $phpdoc; protected $params = array(); protected $params_with_default = array(); protected $interfaces = array(); - public function __construct($method, $alias, $class, $methodName = null, $interfaces = array()) + /** + * @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->interfaces = $interfaces; $this->name = $methodName ?: $method->name; @@ -39,7 +47,7 @@ class Method try { $this->normalizeDescription($method); } catch (\Exception $e) { - $this->info("Cannot normalize method $alias::{$this->name}.."); + $this->error("Cannot normalize method $alias::{$this->name}.."); } //Get the parameters, including formatted default values @@ -57,8 +65,6 @@ class Method $declaringClass = $method->getDeclaringClass(); $this->declaringClassName = '\\' . ltrim($declaringClass->name, '\\'); $this->root = '\\' . ltrim($class->getName(), '\\'); - - } /** @@ -121,7 +127,7 @@ class Method */ public function getParams($implode = true) { - return implode(', ', $this->params); + return $implode ? implode(', ', $this->params) : $this->params; } /** @@ -132,7 +138,7 @@ class Method */ public function getParamsWithDefault($implode = true) { - return implode(', ', $this->params_with_default); + return $implode ? implode(', ', $this->params_with_default) : $this->params_with_default; } /** @@ -250,4 +256,14 @@ class Method } } + /** + * Output an error. + * + * @param string $string + * @return void + */ + protected function error($string) + { + echo $string . "\r\n"; + } }