Passed
Pull Request — master (#120)
by
unknown
02:31
created

GenerateDiagramCommand   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 124
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 54
c 2
b 0
f 0
dl 0
loc 124
rs 10
wmc 12

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A handle() 0 51 5
A getTextOutputFileName() 0 3 2
A getModelsThatShouldBeInspected() 0 7 1
A getAllModelsFromEachDirectory() 0 7 1
A getOutputFileName() 0 4 2
1
<?php
2
3
namespace BeyondCode\ErdGenerator;
4
5
use BeyondCode\ErdGenerator\Model as GraphModel;
6
use Illuminate\Console\Command;
7
use Illuminate\Support\Collection;
8
use phpDocumentor\GraphViz\Graph;
9
use ReflectionClass;
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} {--text-output : Output as text file instead of image} {--structured : Generate structured text output for AI models}';
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
    /**
53
     * @throws \phpDocumentor\GraphViz\Exception
54
     */
55
    public function handle()
56
    {
57
        $models = $this->getModelsThatShouldBeInspected();
58
59
        $this->info("Found {$models->count()} models.");
60
        $this->info("Inspecting model relations.");
61
62
        $bar = $this->output->createProgressBar($models->count());
63
64
        $models->transform(function ($model) use ($bar) {
65
            $bar->advance();
66
            return new GraphModel(
67
                $model,
68
                (new ReflectionClass($model))->getShortName(),
69
                $this->relationFinder->getModelRelations($model)
70
            );
71
        });
72
73
        // If structured text output is requested, generate it
74
        if ($this->option('structured')) {
75
            $textOutput = $this->graphBuilder->generateStructuredTextRepresentation($models);
76
            $outputFileName = $this->getTextOutputFileName();
77
            file_put_contents($outputFileName, $textOutput);
78
            $this->info(PHP_EOL);
79
            $this->info('Wrote structured text diagram to ' . $outputFileName);
80
            return;
81
        }
82
83
        $graph = $this->graphBuilder->buildGraph($models);
84
85
        if ($this->option('text-output') || $this->option('format') === self::FORMAT_TEXT) {
86
            $textOutput = $graph->__toString();
87
            
88
            // If text-output option is set, write to file
89
            if ($this->option('text-output')) {
90
                $outputFileName = $this->getTextOutputFileName();
91
                file_put_contents($outputFileName, $textOutput);
92
                $this->info(PHP_EOL);
93
                $this->info('Wrote text diagram to ' . $outputFileName);
94
                return;
95
            }
96
            
97
            // Otherwise just output to console
98
            $this->info($textOutput);
99
            return;
100
        }
101
102
        $graph->export($this->option('format'), $this->getOutputFileName());
103
104
        $this->info(PHP_EOL);
105
        $this->info('Wrote diagram to ' . $this->getOutputFileName());
106
    }
107
108
    protected function getOutputFileName(): string
109
    {
110
        return $this->argument('filename') ?:
111
            static::DEFAULT_FILENAME . '.' . $this->option('format');
112
    }
113
114
    protected function getTextOutputFileName(): string
115
    {
116
        return $this->argument('filename') ?: static::DEFAULT_FILENAME . '.txt';
117
    }
118
119
    protected function getModelsThatShouldBeInspected(): Collection
120
    {
121
        $directories = config('erd-generator.directories');
122
123
        $modelsFromDirectories = $this->getAllModelsFromEachDirectory($directories);
124
125
        return $modelsFromDirectories;
126
    }
127
128
    protected function getAllModelsFromEachDirectory(array $directories): Collection
129
    {
130
        return collect($directories)
0 ignored issues
show
Bug introduced by
$directories 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 ignore-type  annotation

130
        return collect(/** @scrutinizer ignore-type */ $directories)
Loading history...
131
            ->map(function ($directory) {
132
                return $this->modelFinder->getModelsInDirectory($directory)->all();
133
            })
134
            ->flatten();
135
    }
136
}
137