Passed
Pull Request — master (#58)
by Dmitriy
07:04 queued 04:25
created

DefaultController   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 94
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

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