Skip to content

Commit

Permalink
Add more metadata (#1646)
Browse files Browse the repository at this point in the history
* Add more metadata

* composer fix-style

* Parse .env

* composer fix-style

* Check if .env exists

---------

Co-authored-by: laravel-ide-helper <laravel-ide-helper@users.noreply.github.com>
  • Loading branch information
barryvdh and laravel-ide-helper authored Dec 30, 2024
1 parent cffcd07 commit f838156
Show file tree
Hide file tree
Showing 5 changed files with 213 additions and 34 deletions.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@
"orchestra/testbench": "^9.2",
"phpunit/phpunit": "^10.5",
"spatie/phpunit-snapshot-assertions": "^4 || ^5",
"vimeo/psalm": "^5.4"
"vimeo/psalm": "^5.4",
"vlucas/phpdotenv": "^5"
},
"suggest": {
"illuminate/events": "Required for automatic helper generation (^6|^7|^8|^9|^10|^11)."
Expand Down
42 changes: 42 additions & 0 deletions php-templates/auth.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

return collect(Illuminate\Support\Facades\Gate::abilities())
->map(function ($policy, $key) {
$reflection = new ReflectionFunction($policy);

$policyClass = null;

if (get_class($reflection->getClosureThis()) === Illuminate\Auth\Access\Gate::class) {
$vars = $reflection->getClosureUsedVariables();

if (isset($vars['callback'])) {
[$policyClass, $method] = explode('@', $vars['callback']);

$reflection = new ReflectionMethod($policyClass, $method);
}
}
return [
'key' => $key,
'uri' => $reflection->getFileName(),
'policy_class' => $policyClass,
'lineNumber' => $reflection->getStartLine(),
];
})
->merge(
collect(Illuminate\Support\Facades\Gate::policies())->flatMap(function ($policy, $model) {
$methods = (new ReflectionClass($policy))->getMethods();

return collect($methods)->map(function (ReflectionMethod $method) use ($policy) {
return [
'key' => $method->getName(),
'uri' => $method->getFileName(),
'policy_class' => $policy,
'lineNumber' => $method->getStartLine(),
];
})->filter(function ($ability) {
return !in_array($ability['key'], ['allow', 'deny']);
});
}),
)
->values()
->groupBy('key');
64 changes: 64 additions & 0 deletions php-templates/middleware.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

return collect(app("Illuminate\Contracts\Http\Kernel")->getMiddlewareGroups())
->merge(app("Illuminate\Contracts\Http\Kernel")->getRouteMiddleware())
->map(function ($middleware, $key) {
$result = [
'class' => null,
'uri' => null,
'startLine' => null,
'parameters' => null,
'groups' => [],
];

if (is_array($middleware)) {
$result['groups'] = collect($middleware)->map(function ($m) {
if (!class_exists($m)) {
return [
'class' => $m,
'uri' => null,
'startLine' => null,
];
}

$reflected = new ReflectionClass($m);
$reflectedMethod = $reflected->getMethod('handle');

return [
'class' => $m,
'uri' => $reflected->getFileName(),
'startLine' =>
$reflectedMethod->getFileName() === $reflected->getFileName()
? $reflectedMethod->getStartLine()
: null,
];
})->all();

return $result;
}

$reflected = new ReflectionClass($middleware);
$reflectedMethod = $reflected->getMethod('handle');

$result = array_merge($result, [
'class' => $middleware,
'uri' => $reflected->getFileName(),
'startLine' => $reflectedMethod->getStartLine(),
]);

$parameters = collect($reflectedMethod->getParameters())
->filter(function ($rc) {
return $rc->getName() !== 'request' && $rc->getName() !== 'next';
})
->map(function ($rc) {
return $rc->getName() . ($rc->isVariadic() ? '...' : '');
});

if ($parameters->isEmpty()) {
return $result;
}

return array_merge($result, [
'parameters' => $parameters->implode(','),
]);
});
15 changes: 13 additions & 2 deletions resources/views/meta.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,19 @@
<?php endif ?>

<?php if (isset($expectedArguments)) : ?>
<?php foreach ($expectedArguments as $function => $arguments) : ?>
<?php foreach ($arguments as $index => $argumentSet) : ?>
<?php foreach ($expectedArguments as $arguments) : ?>
<?php
$classes = isset($arguments['class']) ? (array) $arguments['class'] : [null];
$index = $arguments['index'] ?? 0;
$argumentSet = $arguments['argumentSet'];
$functions = [];
foreach ($classes as $class) {
foreach ((array) $arguments['method'] as $method) {
$functions[] = '\\' . ($class ? ltrim($class, '\\') . '::' : '') . $method . '()';
}
}
?>
<?php foreach ($functions as $function) : ?>
expectedArguments(<?= $function ?>, <?= $index ?>, argumentsSet('<?= $argumentSet ?>'));
<?php endforeach; ?>
<?php endforeach; ?>
Expand Down
123 changes: 92 additions & 31 deletions src/Console/MetaCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
namespace Barryvdh\LaravelIdeHelper\Console;

use Barryvdh\LaravelIdeHelper\Factories;
use Dotenv\Parser\Entry;
use Dotenv\Parser\Parser;
use Illuminate\Console\Command;
use Illuminate\Contracts\Config\Repository;
use Illuminate\Contracts\View\Factory;
Expand Down Expand Up @@ -68,9 +70,7 @@ class MetaCommand extends Command
protected $configMethods = [
'\config()',
'\Illuminate\Config\Repository::get()',
'\Illuminate\Config\Repository::set()',
'\Illuminate\Support\Facades\Config::get()',
'\Illuminate\Support\Facades\Config::set()',
];

protected $userMethods = [
Expand Down Expand Up @@ -202,59 +202,105 @@ protected function registerClassAutoloadExceptions(): callable
protected function getExpectedArgumentSets()
{
return [
'auth' => $this->loadTemplate('auth')->keys()->filter()->toArray(),
'configs' => $this->loadTemplate('configs')->pluck('name')->filter()->toArray(),
'middleware' => $this->loadTemplate('middleware')->keys()->filter()->toArray(),
'routes' => $this->loadTemplate('routes')->pluck('name')->filter()->toArray(),
'views' => $this->loadTemplate('views')->pluck('key')->filter()->map(function ($value) {
return (string) $value;
})->toArray(),
'translations' => $this->loadTemplate('translations')->filter()->keys()->toArray(),
'env' => $this->getEnv(),
];
}

protected function getExpectedArguments()
{
return [
'\config()' => [
0 => 'configs',
[
'class' => '\Illuminate\Support\Facades\Gate',
'method' => [
'has',
'allows',
'denies',
'check',
'any',
'none',
'authorize',
'inspect',
],
'argumentSet' => 'auth',
],
'\Illuminate\Config\Repository::get()' => [
0 => 'configs',
[
'class' => ['\Illuminate\Support\Facades\Route', '\Illuminate\Support\Facades\Auth'],
'method' => ['can', 'cannot'],
'argumentSet' => 'auth',
],
'\Illuminate\Config\Repository::set()' => [
0 => 'configs',
[
'method' => 'config',
'argumentSet' => 'configs',
],
'\Illuminate\Support\Facades\Config::get()' => [
0 => 'configs',
[
'class' => ['\Illuminate\Config\Repository', '\Illuminate\Support\Facades\Config'],
'method' => [
'get',
'getMany',
'set',
'string',
'integer',
'boolean',
'float',
'array',
'prepend',
'push',
],
'argumentSet' => 'configs',
],
'\Illuminate\Support\Facades\Config::set()' => [
0 => 'configs',
[
'class' => ['\Illuminate\Support\Facades\Route', '\Illuminate\Routing\Router'],
'method' => ['middleware', 'withoutMiddleware'],
'argumentSet' => 'middleware',
],
'\route()' => [
0 => 'routes',
[
'method' => ['route', 'to_route', 'signedRoute'],
'argumentSet' => 'routes',
],
'\Illuminate\Support\Facades\Route::get()' => [
0 => 'routes',
[
'class' => [
'\Illuminate\Support\Facades\Redirect',
'\Illuminate\Support\Facades\URL',
'\Illuminate\Routing\Redirector',
'\Illuminate\Routing\UrlGenerator',
],
'method' => ['route', 'signedRoute', 'temporarySignedRoute'],
'argumentSet' => 'routes',
],
'\Illuminate\Routing\Router::get()' => [
0 => 'routes',
[
'method' => 'view',
'argumentSet' => 'views',
],
'\view()' => [
0 => 'views',
[
'class' => ['\Illuminate\Support\Facades\View', '\Illuminate\View\Factory'],
'method' => 'make',
'argumentSet' => 'views',
],
'\Illuminate\Support\Facades\View::make()' => [
0 => 'views',
[
'method' => ['__', 'trans'],
'argumentSet' => 'translations',
],
'\Illuminate\View\Factory::make()' => [
0 => 'views',
[
'class' => ['\Illuminate\Contracts\Translation\Translator'],
'method' => ['get'],
'argumentSet' => 'translations',
],
'\__()' => [
0 => 'translations',
[
'method' => 'env',
'argumentSet' => 'env',
],
'\trans()' => [
0 => 'translations',
],
'\Illuminate\Contracts\Translation\Translator::get()' => [
0 => 'translations',
[
'class' => '\Illuminate\Support\Env',
'method' => 'get',
'argumentSet' => 'env',
],
];
}
Expand Down Expand Up @@ -290,6 +336,21 @@ protected function getOptions()
];
}

protected function getEnv()
{
$envPath = base_path('.env');
if (!file_exists($envPath)) {
return [];
}

$parser = new Parser();
$entries = $parser->parse(file_get_contents($envPath));

return collect($entries)->map(function (Entry $entry) {
return $entry->getName();
});
}

/**
* Remove our custom autoloader that we pushed onto the autoload stack
*
Expand Down

0 comments on commit f838156

Please sign in to comment.