1 | <?php |
||||
2 | |||||
3 | namespace BeyondCode\ErdGenerator; |
||||
4 | |||||
5 | use Illuminate\Database\Eloquent\Model as EloquentModel; |
||||
6 | use Illuminate\Filesystem\Filesystem; |
||||
7 | use Illuminate\Support\Collection; |
||||
8 | use Illuminate\Support\Str; |
||||
9 | use PhpParser\Node\Stmt\Class_; |
||||
10 | use PhpParser\Node\Stmt\Namespace_; |
||||
11 | use PhpParser\NodeTraverser; |
||||
12 | use PhpParser\NodeVisitor\NameResolver; |
||||
13 | use PhpParser\ParserFactory; |
||||
14 | use ReflectionClass; |
||||
15 | |||||
16 | class ModelFinder |
||||
17 | { |
||||
18 | |||||
19 | /** @var Filesystem */ |
||||
20 | protected $filesystem; |
||||
21 | |||||
22 | public function __construct(Filesystem $filesystem) |
||||
23 | { |
||||
24 | $this->filesystem = $filesystem; |
||||
25 | } |
||||
26 | |||||
27 | public function getModelsInDirectory(string $directory): Collection |
||||
28 | { |
||||
29 | $files = config('erd-generator.recursive') ? |
||||
30 | $this->filesystem->allFiles($directory) : |
||||
31 | $this->filesystem->files($directory); |
||||
32 | |||||
33 | $ignoreModels = array_filter(config('erd-generator.ignore', []), 'is_string'); |
||||
34 | $whitelistModels = array_filter(config('erd-generator.whitelist', []), 'is_string'); |
||||
35 | |||||
36 | $collection = Collection::make($files)->filter(function ($path) { |
||||
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||||
37 | return Str::endsWith($path, '.php'); |
||||
38 | })->map(function ($path) { |
||||
39 | return $this->getFullyQualifiedClassNameFromFile($path); |
||||
40 | })->filter(function (string $className) { |
||||
41 | return !empty($className) |
||||
42 | && is_subclass_of($className, EloquentModel::class) |
||||
43 | && ! (new ReflectionClass($className))->isAbstract(); |
||||
44 | }); |
||||
45 | |||||
46 | if(!count($whitelistModels)) { |
||||
47 | return $collection->diff($ignoreModels)->sort(); |
||||
0 ignored issues
–
show
$ignoreModels of type array is incompatible with the type Illuminate\Contracts\Support\Arrayable expected by parameter $items of Illuminate\Support\Collection::diff() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
48 | } |
||||
49 | |||||
50 | return $collection->filter(function (string $className) use ($whitelistModels) { |
||||
51 | return in_array($className, $whitelistModels); |
||||
52 | }); |
||||
53 | } |
||||
54 | |||||
55 | protected function getFullyQualifiedClassNameFromFile(string $path): string |
||||
56 | { |
||||
57 | $factory = new ParserFactory(); |
||||
58 | $parser = method_exists($factory, 'createForHostVersion') |
||||
59 | ? $factory->createForHostVersion() |
||||
60 | : $factory->create(ParserFactory::PREFER_PHP7); |
||||
0 ignored issues
–
show
The method
create() does not exist on PhpParser\ParserFactory . Did you maybe mean createForNewestSupportedVersion() ?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed. ![]() |
|||||
61 | |||||
62 | $traverser = new NodeTraverser(); |
||||
63 | $traverser->addVisitor(new NameResolver()); |
||||
64 | |||||
65 | $code = file_get_contents($path); |
||||
66 | |||||
67 | $statements = $parser->parse($code); |
||||
68 | $statements = $traverser->traverse($statements); |
||||
0 ignored issues
–
show
It seems like
$statements can also be of type null ; however, parameter $nodes of PhpParser\NodeTraverser::traverse() does only seem to accept array , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
69 | |||||
70 | // get the first namespace declaration in the file |
||||
71 | $root_statement = collect($statements)->first(function ($statement) { |
||||
0 ignored issues
–
show
$statements of type array is incompatible with the type Illuminate\Contracts\Support\Arrayable expected by parameter $value of collect() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
72 | return $statement instanceof Namespace_; |
||||
73 | }); |
||||
74 | |||||
75 | if (! $root_statement) { |
||||
76 | return ''; |
||||
77 | } |
||||
78 | |||||
79 | return collect($root_statement->stmts) |
||||
80 | ->filter(function ($statement) { |
||||
81 | return $statement instanceof Class_; |
||||
82 | }) |
||||
83 | ->map(function (Class_ $statement) { |
||||
84 | return $statement->namespacedName->toString(); |
||||
0 ignored issues
–
show
The method
toString() does not exist on null .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed. ![]() |
|||||
85 | }) |
||||
86 | ->first() ?? ''; |
||||
87 | } |
||||
88 | } |
||||
89 |