Passed
Pull Request — master (#58)
by Dmitriy
02:38
created

DefaultController::preview()   A

Complexity

Conditions 6
Paths 5

Size

Total Lines 28
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 17
c 2
b 0
f 0
dl 0
loc 28
ccs 0
cts 16
cp 0
rs 9.0777
cc 6
nc 5
nop 2
crap 42
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Yii\Gii\Controller;
6
7
use Psr\Http\Message\ResponseInterface;
8
use Yiisoft\DataResponse\DataResponse;
9
use Yiisoft\DataResponse\DataResponseFactoryInterface;
10
use Yiisoft\Http\Status;
11
use Yiisoft\RequestModel\Attribute\Query;
12
use Yiisoft\Validator\RulesDumper;
13
use Yiisoft\Validator\RulesProvider\AttributesRulesProvider;
14
use Yiisoft\Yii\Gii\CodeFile;
15
use Yiisoft\Yii\Gii\CodeFileWriter;
16
use Yiisoft\Yii\Gii\Exception\InvalidGeneratorCommandException;
17
use Yiisoft\Yii\Gii\Generator\CommandHydrator;
18
use Yiisoft\Yii\Gii\GeneratorCommandInterface;
19
use Yiisoft\Yii\Gii\GeneratorInterface;
20
use Yiisoft\Yii\Gii\GiiInterface;
21
use Yiisoft\Yii\Gii\Request\GeneratorRequest;
22
23
final class DefaultController
24
{
25
    public function __construct(private DataResponseFactoryInterface $responseFactory)
26
    {
27
    }
28
29
    public function list(GiiInterface $gii): ResponseInterface
30
    {
31
        $generators = $gii->getGenerators();
32
33
        return $this->responseFactory->createResponse([
34
            'generators' => array_map($this->serializeGenerator(...), array_values($generators)),
0 ignored issues
show
Bug introduced by
A parse error occurred: Syntax error, unexpected ')' on line 34 at column 67
Loading history...
35
        ]);
36
    }
37
38
    private function serializeGenerator(GeneratorInterface $generator): array
39
    {
40
        /**
41
         * @psalm-var $commandClass class-string<GeneratorCommandInterface>
42
         */
43
        $commandClass = $generator::getCommandClass();
44
45
        $dataset = new AttributesRulesProvider($commandClass);
46
        $rules = $dataset->getRules();
47
        $dumpedRules = (new RulesDumper())->asArray($rules);
48
        $hints = $commandClass::getHints();
49
        $labels = $commandClass::getAttributeLabels();
50
        $attributes = [];
51
52
        foreach ($dumpedRules as $attributeName => $rules) {
53
            $attributes[$attributeName] = [
54
                'hint' => $hints[$attributeName] ?? null,
55
                'label' => $labels[$attributeName] ?? null,
56
                'rules' => $rules,
57
            ];
58
        }
59
60
        return [
61
            'id' => $generator::getId(),
62
            'name' => $generator::getName(),
63
            'description' => $generator::getDescription(),
64
            'commandClass' => $commandClass,
65
            'attributes' => $attributes,
66
            //            'templatePath' => $generator->getTemplatePath(),
67
            //            'templates' => $generator->getTemplates(),
68
            'directory' => $generator->getDirectory(),
69
        ];
70
    }
71
72
    public function get(GeneratorRequest $request): ResponseInterface
73
    {
74
        $generator = $request->getGenerator();
75
76
        return $this->responseFactory->createResponse(
77
            $this->serializeGenerator($generator)
78
        );
79
    }
80
81
    public function generate(
82
        GeneratorRequest $request,
83
        CodeFileWriter $codeFileWriter,
84
        CommandHydrator $commandHydrator
85
    ): ResponseInterface {
86
        $generator = $request->getGenerator();
87
        $command = $commandHydrator->hydrate($generator::getCommandClass(), $request->getBody());
88
        $answers = $request->getAnswers();
89
        try {
90
            $files = $generator->generate($command);
91
        } catch (InvalidGeneratorCommandException $e) {
92
            return $this->createErrorResponse($e);
93
        }
94
        $params = [];
95
        $results = [];
96
        // TODO: get answers from the request
97
        $answers = [];
98
        foreach ($files as $file) {
99
            $answers[$file->getId()] = true;
100
        }
101
        $params['hasError'] = !$codeFileWriter->write($command, $files, $answers, $results);
102
        $params['results'] = $results;
103
        return $this->responseFactory->createResponse($params);
104
    }
105
106
    public function preview(
107
        GeneratorRequest $request,
108
        CommandHydrator $commandHydrator,
109
        #[Query('file')] ?string $file = null
110
    ): ResponseInterface {
111
        $generator = $request->getGenerator();
112
        $command = $commandHydrator->hydrate($generator::getCommandClass(), $request->getBody());
113
114
        try {
115
            $files = $generator->generate($command);
116
        } catch (InvalidGeneratorCommandException $e) {
117
            return $this->createErrorResponse($e);
118
        }
119
        if ($file === null) {
120
            return $this->responseFactory->createResponse([
121
                'files' => array_map($this->serializeCodeFile(...), $files),
122
                // todo: fix showing operations' keys. they are skipped because of serialization numerical arrays
123
                'operations' => CodeFile::OPERATIONS_MAP,
124
            ]);
125
        }
126
127
        foreach ($files as $generatedFile) {
128
            if ($generatedFile->getId() === $file) {
129
                $content = $generatedFile->preview();
130
                return $this->responseFactory->createResponse(
131
                    ['content' => $content ?: 'Preview is not available for this file type.']
132
                );
133
            }
134
        }
135
136
        return $this->responseFactory->createResponse(
137
            ['message' => "Code file not found: $file"],
138
            Status::UNPROCESSABLE_ENTITY
139
        );
140
    }
141
142
    public function diff(
143
        GeneratorRequest $request,
144
        CommandHydrator $commandHydrator,
145
        #[Query('file')] string $file
146
    ): ResponseInterface {
147
        $generator = $request->getGenerator();
148
        $command = $commandHydrator->hydrate($generator::getCommandClass(), $request->getBody());
149
150
        try {
151
            $files = $generator->generate($command);
152
        } catch (InvalidGeneratorCommandException $e) {
153
            return $this->createErrorResponse($e);
154
        }
155
156
        foreach ($files as $generatedFile) {
157
            if ($generatedFile->getId() === $file) {
158
                return $this->responseFactory->createResponse(['diff' => $generatedFile->diff()]);
159
            }
160
        }
161
        return $this->responseFactory->createResponse(
162
            ['message' => "Code file not found: $file"],
163
            Status::UNPROCESSABLE_ENTITY
164
        );
165
    }
166
167
    private function createErrorResponse(InvalidGeneratorCommandException $e): DataResponse
168
    {
169
        return $this->responseFactory->createResponse(
170
        // TODO: fix
171
            ['errors' => $e->getResult()->getErrorMessagesIndexedByAttribute()],
172
            Status::UNPROCESSABLE_ENTITY
173
        );
174
    }
175
176
    private function serializeCodeFile(CodeFile $file): array
177
    {
178
        return [
179
            'id' => $file->getId(),
180
            'content' => $file->getContent(),
181
            'operation' => $file->getOperation(),
182
            'path' => $file->getPath(),
183
            'relativePath' => $file->getRelativePath(),
184
            'type' => $file->getType(),
185
            'preview' => $file->preview(),
186
        ];
187
    }
188
}
189