Passed
Pull Request — master (#58)
by Alexander
05:15 queued 02:40
created

DefaultController::generate()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 19
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

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