Completed
Push — master ( 77cc29...840912 )
by Gerrit
10:19
created

MappingYamlDriver   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 144
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Test Coverage

Coverage 90.16%

Importance

Changes 0
Metric Value
wmc 24
lcom 1
cbo 5
dl 0
loc 144
ccs 55
cts 61
cp 0.9016
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
B loadRDMMetadataForClass() 0 28 6
A readMappings() 0 9 3
A readChoices() 0 8 2
A readServices() 0 8 2
A readOneMapping() 0 11 3
B readChoice() 0 26 4
B readService() 0 25 3
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\Common\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 3
    }
44
45 2
    public function loadRDMMetadataForClass(string $className): ?EntityMappingInterface
46
    {
47
        /** @var ?EntityMappingInterface $mapping */
0 ignored issues
show
Documentation introduced by
The doc-type ?EntityMappingInterface could not be parsed: Unknown type name "?EntityMappingInterface" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
48 2
        $mapping = null;
49
50
        /** @var array<MappingInterface> $fieldMappings */
51 2
        $fieldMappings = array();
52
53 2
        if ($this->fileLocator->fileExists($className)) {
54
            /** @var string $mappingFile */
55 2
            $mappingFile = $this->fileLocator->findMappingFile($className);
56
57 2
            if (file_exists($mappingFile)) {
58
                /** @var mixed $yaml */
59 2
                $yaml = Yaml::parse(file_get_contents($mappingFile));
60
61 2
                if (is_array($yaml) && isset($yaml[$className])) {
62 1
                    $this->readMappings($fieldMappings, $yaml[$className], $mappingFile);
63
                }
64
            }
65
        }
66
67 2
        if (!empty($fieldMappings)) {
68 1
            $mapping = new EntityMapping($className, $fieldMappings);
69
        }
70
71 2
        return $mapping;
72
    }
73
74 1
    private function readMappings(array &$fieldMappings, array $yaml, string $mappingFile): void
75
    {
76 1
        if (isset($yaml['choices'])) {
77 1
            $this->readChoices($fieldMappings, $yaml['choices'], $mappingFile);
78
        }
79 1
        if (isset($yaml['services'])) {
80 1
            $this->readServices($fieldMappings, $yaml['services'], $mappingFile);
81
        }
82 1
    }
83
84 1
    private function readChoices(array &$fieldMappings, array $servicesYaml, string $mappingFile): void
85
    {
86 1
        foreach ($servicesYaml as $fieldName => $choiceYaml) {
87
            /** @var array $yamlService */
88
89 1
            $fieldMappings[$fieldName] = $this->readChoice($choiceYaml, $fieldName, $mappingFile);
90
        }
91 1
    }
92
93 1
    private function readServices(array &$fieldMappings, array $servicesYaml, string $mappingFile): void
94
    {
95 1
        foreach ($servicesYaml as $fieldName => $serviceYaml) {
96
            /** @var array $serviceYaml */
97
98 1
            $fieldMappings[$fieldName] = $this->readService($serviceYaml, $fieldName, $mappingFile);
99
        }
100 1
    }
101
102 1
    private function readOneMapping(array $yaml, string $fieldName, string $mappingFile): ?MappingInterface
103
    {
104 1
        if (isset($yaml['choice'])) {
105
            return $this->readChoice($yaml['choice'], $fieldName, $mappingFile);
106
        }
107 1
        if (isset($yaml['service'])) {
108 1
            return $this->readService($yaml['service'], $fieldName, $mappingFile);
109
        }
110
111
        return null;
112
    }
113
114 1
    private function readChoice(array $choiceYaml, string $fieldName, string $mappingFile): ChoiceMapping
115
    {
116
        /** @var array<MappingInterface> $choiceMappings */
117 1
        $choiceMappings = array();
118
119
        /** @var string $determinatorColumnName */
120 1
        $determinatorColumnName = $fieldName;
121
122 1
        if ($choiceYaml['column']) {
123 1
            $determinatorColumnName = (string)$choiceYaml['column'];
124
        }
125
126 1
        foreach ($choiceYaml['choices'] as $determinator => $choiceYaml) {
127
            /** @var ?MappingInterface $mapping */
0 ignored issues
show
Documentation introduced by
The doc-type ?MappingInterface could not be parsed: Unknown type name "?MappingInterface" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
128 1
            $mapping = $this->readOneMapping($choiceYaml, $fieldName, $mappingFile);
129
130 1
            if ($mapping instanceof MappingInterface) {
131 1
                $choiceMappings[$determinator] = $mapping;
132
            }
133
        }
134
135 1
        return new ChoiceMapping($determinatorColumnName, $choiceMappings, sprintf(
136 1
            "in file '%s'",
137 1
            $mappingFile
138
        ));
139
    }
140
141 1
    private function readService(array $serviceYaml, string $fieldName, string $mappingFile): ServiceMapping
142
    {
143 1
        if (!isset($serviceYaml['id'])) {
144
            throw new ErrorException(sprintf(
145
                "Missing key 'id' on service-reference in file %s on field %s!",
146
                $mappingFile,
147
                $fieldName
148
            ));
149
        }
150
151
        /** @var string $serviceId */
152 1
        $serviceId = $serviceYaml['id'];
153
154
        /** @var bool $lax */
155 1
        $lax = false;
156
157 1
        if (isset($serviceYaml["lax"])) {
158 1
            $lax = (bool)$serviceYaml["lax"];
159
        }
160
161 1
        return new ServiceMapping($this->container, $serviceId, $lax, sprintf(
162 1
            "in file '%s'",
163 1
            $mappingFile
164
        ));
165
    }
166
167
}
168