Passed
Push — master ( 491d8e...9b8ef9 )
by Gerrit
03:23
created

EntityMapping::collectDBALColumns()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 20
ccs 9
cts 9
cp 1
rs 9.6
c 0
b 0
f 0
cc 3
nc 2
nop 0
crap 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;
12
13
use Addiks\RDMBundle\Mapping\MappingInterface;
14
use Addiks\RDMBundle\Mapping\EntityMappingInterface;
15
use Doctrine\DBAL\Schema\Column;
16
use Addiks\RDMBundle\Mapping\ObjectMapping;
17
use Webmozart\Assert\Assert;
18
use Addiks\RDMBundle\Hydration\HydrationContextInterface;
19
use Symfony\Component\DependencyInjection\ContainerInterface;
20
use Doctrine\ORM\EntityManagerInterface;
21
use ReflectionClass;
22
use Addiks\RDMBundle\Hydration\HydrationContext;
23
use ErrorException;
24
use ReflectionProperty;
25
use ReflectionObject;
26
27
final class EntityMapping implements EntityMappingInterface
28
{
29
30
    /**
31
     * @var class-string
32
     */
33
    private $className;
34
35
    /**
36
     * @var array<MappingInterface>
37
     */
38
    private $fieldMappings = array();
39
40
    /** @var array<Column>|null */
41
    private $dbalColumnsCache;
42
43
    /** @param class-string $className */
0 ignored issues
show
Documentation introduced by
The doc-type class-string could not be parsed: Unknown type name "class-string" 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...
44 29
    public function __construct(string $className, array $fieldMappings)
45
    {
46 29
        $this->className = $className;
47
48 29
        foreach ($fieldMappings as $fieldName => $fieldMapping) {
49
            /** @var MappingInterface $fieldMapping */
50
51 28
            Assert::isInstanceOf($fieldMapping, MappingInterface::class);
52
53 28
            $this->fieldMappings[$fieldName] = $fieldMapping;
54
        }
55 29
    }
56
57 3
    public function getEntityClassName(): string
58
    {
59 3
        return $this->className;
60
    }
61
62 1
    public function getDBALColumn(): ?Column
63
    {
64 1
        return null;
65
    }
66
67 1
    public function getClassName(): string
68
    {
69 1
        return $this->className;
70
    }
71
72 12
    public function getFieldMappings(): array
73
    {
74 12
        return $this->fieldMappings;
75
    }
76
77 1
    public function describeOrigin(): string
78
    {
79 1
        return $this->className;
80
    }
81
82 6
    public function collectDBALColumns(): array
83
    {
84 6
        if (is_null($this->dbalColumnsCache)) {
85
            /** @var array<Column> $additionalColumns */
86 6
            $additionalColumns = array();
87
88 6
            foreach ($this->fieldMappings as $fieldMapping) {
89
                /** @var MappingInterface $fieldMapping */
90
91 6
                $additionalColumns = array_merge(
92 6
                    $additionalColumns,
93 6
                    $fieldMapping->collectDBALColumns()
94
                );
95
            }
96
97 6
            $this->dbalColumnsCache = $additionalColumns;
98
        }
99
100 6
        return $this->dbalColumnsCache;
101
    }
102
103 1
    public function getFactory(): ?CallDefinitionInterface
104
    {
105 1
        return null;
106
    }
107
108 1
    public function getSerializer(): ?CallDefinitionInterface
109
    {
110 1
        return null;
111
    }
112
113 1
    public function getId(): ?string
114
    {
115 1
        return null;
116
    }
117
118 1
    public function getReferencedId(): ?string
119
    {
120 1
        return null;
121
    }
122
123 1
    public function resolveValue(
124
        HydrationContextInterface $context,
125
        array $dataFromAdditionalColumns
126
    ) {
127
        /** @var array<string, mixed> $entityData */
128 1
        $entityData = array();
129
130
        /** @var MappingInterface $fieldMapping */
131 1
        foreach ($this->fieldMappings as $fieldName => $fieldMapping) {
132 1
            $entityData[$fieldName] = $fieldMapping->resolveValue($context, $dataFromAdditionalColumns);
133
        }
134
135 1
        return $entityData;
136
    }
137
138 3
    public function revertValue(
139
        HydrationContextInterface $context,
140
        $valueFromEntityField
141
    ): array {
142
        /** @var array<string, mixed> $additionalData */
143 3
        $additionalData = array();
144
145
        /** @var object|null $entity */
146 3
        $entity = $valueFromEntityField;
147
148 3
        if (is_object($entity)) {
149 2
            $reflectionObject = new ReflectionObject($entity);
0 ignored issues
show
Unused Code introduced by
$reflectionObject is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
150
151 2
            $reflectionClass = new ReflectionClass($this->className);
152
153
            /** @var MappingInterface $fieldMapping */
154 2
            foreach ($this->fieldMappings as $fieldName => $fieldMapping) {
155
156
                /** @var ReflectionClass $concreteReflectionClass */
157 2
                $concreteReflectionClass = $reflectionClass;
158
159 2
                while (is_object($concreteReflectionClass) && !$concreteReflectionClass->hasProperty($fieldName)) {
160
                    $concreteReflectionClass = $concreteReflectionClass->getParentClass();
161
                }
162
163 2
                if (!is_object($concreteReflectionClass)) {
164
                    throw new ErrorException(sprintf(
165
                        "Property '%s' does not exist on object of class '%s'!",
166
                        $fieldName,
167
                        $this->className
168
                    ));
169
                }
170
171
                /** @var ReflectionProperty $reflectionProperty */
172 2
                $reflectionProperty = $concreteReflectionClass->getProperty($fieldName);
173 2
                $reflectionProperty->setAccessible(true);
174
175
                /** @var mixed $valueFromEntityField */
176 2
                $valueFromEntityField = null;
177
178 2
                if ($reflectionProperty->isInitialized($entity)) {
179 2
                    $valueFromEntityField = $reflectionProperty->getValue($entity);
180
                }
181
182 2
                $additionalData = array_merge(
183 2
                    $additionalData,
184 2
                    $fieldMapping->revertValue($context, $valueFromEntityField)
185
                );
186
            }
187
        }
188
189 3
        return $additionalData;
190
    }
191
192 1
    public function assertValue(
193
        HydrationContextInterface $context,
194
        array $dataFromAdditionalColumns,
195
        $actualValue
196
    ): void {
197 1
    }
198
199 2
    public function wakeUpMapping(ContainerInterface $container): void
200
    {
201 2
        foreach ($this->fieldMappings as $fieldMapping) {
202
            /** @var MappingInterface $fieldMapping */
203
204 2
            $fieldMapping->wakeUpMapping($container);
205
        }
206 2
    }
207
208
}
209