Completed
Push — master ( 18736d...65af3f )
by Oleg
04:42 queued 21s
created

ConfigGenerator::getCurrentConfig()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3.0261

Importance

Changes 0
Metric Value
cc 3
eloc 7
nc 3
nop 0
dl 0
loc 13
rs 10
c 0
b 0
f 0
ccs 6
cts 7
cp 0.8571
crap 3.0261

1 Method

Rating   Name   Duplication   Size   Complexity  
A ConfigGenerator::addUses() 0 8 3
1
<?php
2
declare(strict_types=1);
3
4
namespace SlayerBirden\DFCodeGeneration\Generator\Config;
5
6
use Nette\PhpGenerator\PhpFile;
7
use Nette\PhpGenerator\PhpLiteral;
8
use Nette\PhpGenerator\PhpNamespace;
9
use Nette\PhpGenerator\PsrPrinter;
10
use SlayerBirden\DFCodeGeneration\Generator\Config\Code\CodeFeederInterface;
11
use SlayerBirden\DFCodeGeneration\Generator\DataProvider\DataProviderInterface;
12
use SlayerBirden\DFCodeGeneration\Generator\GeneratorInterface;
13
use SlayerBirden\DFCodeGeneration\Util\ArrayUtils;
14
15
final class ConfigGenerator implements GeneratorInterface
16
{
17
    /**
18
     * @var DataProviderInterface
19
     */
20
    private $dataProvider;
21
    /**
22
     * @var ConfigPartInterface[]
23
     */
24
    private $parts;
25
    /**
26
     * @var CodeFeederInterface
27
     */
28
    private $codeFeeder;
29
    /**
30
     * @var CurrentConfigProviderInterface
31
     */
32
    private $currentConfigProvider;
33
34 10
    public function __construct(
35
        DataProviderInterface $dataProvider,
36
        CodeFeederInterface $codeFeeder,
37
        CurrentConfigProviderInterface $currentConfigProvider,
38
        ConfigPartInterface ...$parts
39
    ) {
40 10
        $this->dataProvider = $dataProvider;
41 10
        $this->parts = $parts;
42 10
        $this->codeFeeder = $codeFeeder;
43 10
        $this->currentConfigProvider = $currentConfigProvider;
44 10
    }
45
46 10
    public function generate(): string
47
    {
48 10
        $invoke = [];
49
50 10
        $file = new PhpFile();
51 10
        $file->setStrictTypes();
52 10
        $file->addComment('This file is generated by SlayerBirden\DFCodeGeneration');
53 10
        $namespace = $file->addNamespace($this->getConfigNamespace());
54 10
        $class = $namespace->addClass('ConfigProvider');
55 10
        $class->setFinal();
56
57 10
        foreach ($this->parts as $configPart) {
58 10
            $invoke[$configPart->getCode()] = $configPart->getConfig();
59
        }
60
61 10
        $invoke = ArrayUtils::merge($this->currentConfigProvider->getCurrentConfig($this->getClassName()), $invoke);
62 10
        $this->currentConfigProvider->setCurrentConfig($this->getClassName(), $invoke);
63 10
        $this->addUses($invoke, $namespace);
64 10
        $this->codeFeeder->feed($invoke, $class, $namespace);
65
66 10
        return (new PsrPrinter())->printFile($file);
67
    }
68
69 10
    public function getClassName(): string
70
    {
71 10
        return $this->getConfigNamespace() . '\\ConfigProvider';
72
    }
73
74 10
    private function getConfigNamespace(): string
75
    {
76 10
        return $this->dataProvider->provide()['config_namespace'];
77
    }
78
79 10
    private function addUses(array $config, PhpNamespace $phpNamespace): void
80
    {
81 10
        foreach ($config as $key => $value) {
82 10
            $this->checkRecord($key, $phpNamespace);
83 10
            if (is_array($value)) {
84 10
                $this->addUses($value, $phpNamespace);
85
            } else {
86 10
                $this->checkRecord($value, $phpNamespace);
87
            }
88
        }
89 10
    }
90
91
    /**
92
     * @param mixed $record
93
     * @param PhpNamespace $phpNamespace
94
     */
95 10
    private function checkRecord($record, PhpNamespace $phpNamespace): void
96
    {
97
        // order is important - first check records with ::class
98
        // only after that records just with backslash
99 10
        if (is_string($record) && (strpos($record, '::class') !== false)) {
100 10
            $phpNamespace->addUse(str_replace('::class', '', $record));
101 10
        } elseif (is_string($record) && (strpos($record, '\\') !== false)) {
102 10
            if (strpos($record, ':\\') !== false) {
103
                // don't add use if this is not a class name
104 6
                return;
105
            }
106 10
            $phpNamespace->addUse($record);
107 10
        } elseif (($record instanceof PhpLiteral) && (strpos((string)$record, '::class') !== false)) {
108 10
            $phpNamespace->addUse(str_replace('::class', '', (string)$record));
109
        }
110 10
    }
111
112 10
    public function getFileName(): string
113
    {
114 10
        return sprintf('src/%s/ConfigProvider.php', $this->dataProvider->provide()['moduleName']);
115
    }
116
}
117