1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace BeyondCode\ErdGenerator; |
4
|
|
|
|
5
|
|
|
use ReflectionClass; |
6
|
|
|
use Illuminate\Console\Command; |
7
|
|
|
use phpDocumentor\GraphViz\Graph; |
8
|
|
|
use Illuminate\Support\Collection; |
9
|
|
|
use BeyondCode\ErdGenerator\Model as GraphModel; |
10
|
|
|
|
11
|
|
|
class GenerateDiagramCommand extends Command |
12
|
|
|
{ |
13
|
|
|
const FORMAT_TEXT = 'text'; |
14
|
|
|
|
15
|
|
|
const DEFAULT_FILENAME = 'graph'; |
16
|
|
|
|
17
|
|
|
/** |
18
|
|
|
* The console command name. |
19
|
|
|
* |
20
|
|
|
* @var string |
21
|
|
|
*/ |
22
|
|
|
protected $signature = 'generate:erd {filename?} {--format=png}'; |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* The console command description. |
26
|
|
|
* |
27
|
|
|
* @var string |
28
|
|
|
*/ |
29
|
|
|
protected $description = 'Generate ER diagram.'; |
30
|
|
|
|
31
|
|
|
/** @var ModelFinder */ |
32
|
|
|
protected $modelFinder; |
33
|
|
|
|
34
|
|
|
/** @var RelationFinder */ |
35
|
|
|
protected $relationFinder; |
36
|
|
|
|
37
|
|
|
/** @var Graph */ |
38
|
|
|
protected $graph; |
39
|
|
|
|
40
|
|
|
/** @var GraphBuilder */ |
41
|
|
|
protected $graphBuilder; |
42
|
|
|
|
43
|
|
|
public function __construct(ModelFinder $modelFinder, RelationFinder $relationFinder, GraphBuilder $graphBuilder) |
44
|
|
|
{ |
45
|
|
|
parent::__construct(); |
46
|
|
|
|
47
|
|
|
$this->relationFinder = $relationFinder; |
48
|
|
|
$this->modelFinder = $modelFinder; |
49
|
|
|
$this->graphBuilder = $graphBuilder; |
50
|
|
|
} |
51
|
|
|
|
52
|
|
|
public function handle() |
53
|
|
|
{ |
54
|
|
|
$models = $this->getModelsThatShouldBeInspected(); |
55
|
|
|
|
56
|
|
|
$this->info("Found {$models->count()} models."); |
57
|
|
|
$this->info("Inspecting model relations."); |
58
|
|
|
|
59
|
|
|
$bar = $this->output->createProgressBar($models->count()); |
60
|
|
|
|
61
|
|
|
$models->transform(function ($model) use ($bar) { |
62
|
|
|
$bar->advance(); |
63
|
|
|
return new GraphModel( |
64
|
|
|
$model, |
65
|
|
|
(new ReflectionClass($model))->getShortName(), |
66
|
|
|
$this->relationFinder->getModelRelations($model) |
67
|
|
|
); |
68
|
|
|
}); |
69
|
|
|
|
70
|
|
|
$graph = $this->graphBuilder->buildGraph($models); |
71
|
|
|
|
72
|
|
|
if ($this->option('format') === self::FORMAT_TEXT) { |
73
|
|
|
$this->info($graph->__toString()); |
74
|
|
|
return; |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
$graph->export($this->option('format'), $this->getOutputFileName()); |
|
|
|
|
78
|
|
|
|
79
|
|
|
$this->info(PHP_EOL); |
80
|
|
|
$this->info('Wrote diagram to ' . $this->getOutputFileName()); |
81
|
|
|
} |
82
|
|
|
|
83
|
|
|
protected function getOutputFileName(): string |
84
|
|
|
{ |
85
|
|
|
return $this->argument('filename') ?: |
86
|
|
|
static::DEFAULT_FILENAME . '.' . $this->option('format'); |
87
|
|
|
} |
88
|
|
|
|
89
|
|
|
protected function getModelsThatShouldBeInspected(): Collection |
90
|
|
|
{ |
91
|
|
|
$directories = config('erd-generator.directories'); |
92
|
|
|
|
93
|
|
|
$modelsFromDirectories = $this->getAllModelsFromEachDirectory($directories); |
94
|
|
|
|
95
|
|
|
return $modelsFromDirectories; |
96
|
|
|
} |
97
|
|
|
|
98
|
|
|
protected function getAllModelsFromEachDirectory(array $directories): Collection |
99
|
|
|
{ |
100
|
|
|
return collect($directories) |
101
|
|
|
->map(function ($directory) { |
102
|
|
|
return $this->modelFinder->getModelsInDirectory($directory)->all(); |
103
|
|
|
}) |
104
|
|
|
->flatten(); |
105
|
|
|
} |
106
|
|
|
} |
107
|
|
|
|
This check looks at variables that are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.