Passed
Pull Request — master (#58)
by Dmitriy
13:49
created

TemplateRuleHandler::validate()   B

Complexity

Conditions 9
Paths 8

Size

Total Lines 42
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 13.2714

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 26
dl 0
loc 42
ccs 15
cts 24
cp 0.625
rs 8.0555
c 2
b 0
f 0
cc 9
nc 8
nop 3
crap 13.2714
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Yii\Gii\Validator;
6
7
use RuntimeException;
8
use Yiisoft\Aliases\Aliases;
9
use Yiisoft\Validator\DataSet\ObjectDataSet;
10
use Yiisoft\Validator\Exception\UnexpectedRuleException;
11
use Yiisoft\Validator\Result;
12
use Yiisoft\Validator\RuleHandlerInterface;
13
use Yiisoft\Validator\ValidationContext;
14
use Yiisoft\Yii\Gii\GeneratorCommandInterface;
15
use Yiisoft\Yii\Gii\GeneratorInterface;
16
use Yiisoft\Yii\Gii\GiiInterface;
17
use Yiisoft\Yii\Gii\ParametersProvider;
18
19
final class TemplateRuleHandler implements RuleHandlerInterface
20
{
21 3
    public function __construct(
22
        private Aliases $aliases,
23
        private GiiInterface $gii,
24
        private ParametersProvider $parametersProvider,
25
    ) {
26
    }
27
28
    /**
29
     * Validates the template selection.
30
     * This method validates whether the user selects an existing template
31
     * and the template contains all required template files as specified in {@see requiredTemplates()}.
32
     *
33
     * @param string $value
34
     */
35 3
    public function validate(mixed $value, object $rule, ValidationContext $context): Result
36
    {
37 3
        if (!$rule instanceof TemplateRule) {
38
            throw new UnexpectedRuleException(TemplateRule::class, $rule);
39
        }
40 3
        $result = new Result();
41
42 3
        if ($value === 'default') {
43 1
            return $result;
44
        }
45 2
        $command = $context->getDataSet();
46 2
        if (!$command instanceof ObjectDataSet || !$command->getObject() instanceof GeneratorCommandInterface) {
47
            throw new RuntimeException('Unsupported dataset class.');
48
        }
49 2
        $generator = $this->getGenerator($command);
50 2
        $templates = $this->parametersProvider->getTemplates($generator::getId());
51
52 2
        if ($templates === []) {
53
            return $result;
54
        }
55 2
        if (!isset($templates[$value])) {
56 2
            $result->addError(
57
                message: 'Template "{template}" does not exist. Known templates: {templates}',
58
                parameters: [
59 2
                    'template' => $value,
60 2
                    'templates' => implode(', ', array_keys($templates)),
61
                ],
62
            );
63 2
            return $result;
64
        }
65
66
        $templatePath = $templates[$value];
67
        foreach ($generator->getRequiredTemplates() as $template) {
68
            if (!is_file($this->aliases->get($templatePath . '/' . $template))) {
69
                $result->addError(
70
                    message: 'Unable to find the required code template file "{template}".',
71
                    parameters: ['template' => $template],
72
                );
73
            }
74
        }
75
76
        return $result;
77
    }
78
79 2
    private function getGenerator(ObjectDataSet $dataSet): GeneratorInterface
80
    {
81 2
        foreach ($this->gii->getGenerators() as $generator) {
82 2
            if ($generator::getCommandClass() === $dataSet->getObject()::class) {
83 2
                return $generator;
84
            }
85
        }
86
        throw new RuntimeException('Unknown generator');
87
    }
88
}
89