MappingYamlDriver::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 6
ccs 3
cts 3
cp 1
crap 1
rs 10
1
<?php
2
/**
3
 * Copyright (C) 2018 Gerrit Addiks.
4
 * This package (including this file) was released under the terms of the GPL-3.0.
5
 * You should have received a copy of the GNU General Public License along with this program.
6
 * If not, see <http://www.gnu.org/licenses/> or send me a mail so i can send you a copy.
7
 * @license GPL-3.0
8
 * @author Gerrit Addiks <[email protected]>
9
 */
10
11
namespace Addiks\RDMBundle\Mapping\Drivers;
12
13
use ErrorException;
14
use Doctrine\Persistence\Mapping\Driver\FileLocator;
15
use Symfony\Component\Yaml\Yaml;
16
use Addiks\RDMBundle\Mapping\Drivers\MappingDriverInterface;
17
use Addiks\RDMBundle\Mapping\EntityMappingInterface;
18
use Addiks\RDMBundle\Mapping\MappingInterface;
19
use Addiks\RDMBundle\Mapping\EntityMapping;
20
use Addiks\RDMBundle\Mapping\ServiceMapping;
21
use Addiks\RDMBundle\Mapping\ChoiceMapping;
22
use Symfony\Component\DependencyInjection\ContainerInterface;
23
24
final class MappingYamlDriver implements MappingDriverInterface
25
{
26
27
    /**
28
     * @var FileLocator
29
     */
30
    private $fileLocator;
31
32
    /**
33
     * @var ContainerInterface
34
     */
35
    private $container;
36
37 3
    public function __construct(
38
        ContainerInterface $container,
39
        FileLocator $fileLocator
40
    ) {
41 3
        $this->container = $container;
42 3
        $this->fileLocator = $fileLocator;
43
    }
44
45
    /** @param class-string $className */
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string.
Loading history...
46 2
    public function loadRDMMetadataForClass(string $className): ?EntityMappingInterface
47
    {
48
        /** @var ?EntityMappingInterface $mapping */
49 2
        $mapping = null;
50
51
        /** @var array<MappingInterface> $fieldMappings */
52 2
        $fieldMappings = array();
53
54 2
        if ($this->fileLocator->fileExists($className)) {
55
            /** @var string $mappingFile */
56 2
            $mappingFile = $this->fileLocator->findMappingFile($className);
57
58 2
            if (file_exists($mappingFile)) {
59
                /** @var mixed $yaml */
60 2
                $yaml = Yaml::parse(file_get_contents($mappingFile));
61
62 2
                if (is_array($yaml) && isset($yaml[$className])) {
63 1
                    $this->readMappings($fieldMappings, $yaml[$className], $mappingFile);
64
                }
65
            }
66
        }
67
68 2
        if (!empty($fieldMappings)) {
69 1
            $mapping = new EntityMapping($className, $fieldMappings);
70
        }
71
72 2
        return $mapping;
73
    }
74
75 1
    private function readMappings(array &$fieldMappings, array $yaml, string $mappingFile): void
76
    {
77 1
        if (isset($yaml['choices'])) {
78 1
            $this->readChoices($fieldMappings, $yaml['choices'], $mappingFile);
79
        }
80 1
        if (isset($yaml['services'])) {
81 1
            $this->readServices($fieldMappings, $yaml['services'], $mappingFile);
82
        }
83
    }
84
85 1
    private function readChoices(array &$fieldMappings, array $servicesYaml, string $mappingFile): void
86
    {
87 1
        foreach ($servicesYaml as $fieldName => $choiceYaml) {
88
            /** @var array $yamlService */
89
90 1
            $fieldMappings[$fieldName] = $this->readChoice($choiceYaml, $fieldName, $mappingFile);
91
        }
92
    }
93
94 1
    private function readServices(array &$fieldMappings, array $servicesYaml, string $mappingFile): void
95
    {
96 1
        foreach ($servicesYaml as $fieldName => $serviceYaml) {
97
            /** @var array $serviceYaml */
98
99 1
            $fieldMappings[$fieldName] = $this->readService($serviceYaml, $fieldName, $mappingFile);
100
        }
101
    }
102
103 1
    private function readOneMapping(array $yaml, string $fieldName, string $mappingFile): ?MappingInterface
104
    {
105 1
        if (isset($yaml['choice'])) {
106
            return $this->readChoice($yaml['choice'], $fieldName, $mappingFile);
107
        }
108 1
        if (isset($yaml['service'])) {
109 1
            return $this->readService($yaml['service'], $fieldName, $mappingFile);
110
        }
111
112
        return null;
113
    }
114
115 1
    private function readChoice(array $choiceYaml, string $fieldName, string $mappingFile): ChoiceMapping
116
    {
117
        /** @var array<MappingInterface> $choiceMappings */
118 1
        $choiceMappings = array();
119
120
        /** @var string $determinatorColumnName */
121 1
        $determinatorColumnName = $fieldName;
122
123 1
        if ($choiceYaml['column']) {
124 1
            $determinatorColumnName = (string)$choiceYaml['column'];
125
        }
126
127 1
        foreach ($choiceYaml['choices'] as $determinator => $choiceYaml) {
128
            /** @var ?MappingInterface $mapping */
129 1
            $mapping = $this->readOneMapping($choiceYaml, $fieldName, $mappingFile);
130
131 1
            if ($mapping instanceof MappingInterface) {
132 1
                $choiceMappings[$determinator] = $mapping;
133
            }
134
        }
135
136 1
        return new ChoiceMapping($determinatorColumnName, $choiceMappings, sprintf(
137
            "in file '%s'",
138
            $mappingFile
139
        ));
140
    }
141
142 1
    private function readService(array $serviceYaml, string $fieldName, string $mappingFile): ServiceMapping
143
    {
144 1
        if (!isset($serviceYaml['id'])) {
145
            throw new ErrorException(sprintf(
146
                "Missing key 'id' on service-reference in file %s on field %s!",
147
                $mappingFile,
148
                $fieldName
149
            ));
150
        }
151
152
        /** @var string $serviceId */
153 1
        $serviceId = $serviceYaml['id'];
154
155
        /** @var bool $lax */
156 1
        $lax = false;
157
158 1
        if (isset($serviceYaml["lax"])) {
159 1
            $lax = (bool)$serviceYaml["lax"];
160
        }
161
162 1
        return new ServiceMapping($this->container, $serviceId, $lax, sprintf(
163
            "in file '%s'",
164
            $mappingFile
165
        ));
166
    }
167
168
}
169