Passed
Push — master ( 50749f...7b5f02 )
by Gerrit
12:36
created

EntityMapping::assertValue()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 3
crap 1
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
    /** @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...
41 29
    public function __construct(string $className, array $fieldMappings)
42
    {
43 29
        $this->className = $className;
44
45 29
        foreach ($fieldMappings as $fieldName => $fieldMapping) {
46
            /** @var MappingInterface $fieldMapping */
47
48 28
            Assert::isInstanceOf($fieldMapping, MappingInterface::class);
49
50 28
            $this->fieldMappings[$fieldName] = $fieldMapping;
51
        }
52 29
    }
53
54 3
    public function getEntityClassName(): string
55
    {
56 3
        return $this->className;
57
    }
58
59 1
    public function getDBALColumn(): ?Column
60
    {
61 1
        return null;
62
    }
63
64 1
    public function getClassName(): string
65
    {
66 1
        return $this->className;
67
    }
68
69 12
    public function getFieldMappings(): array
70
    {
71 12
        return $this->fieldMappings;
72
    }
73
74 1
    public function describeOrigin(): string
75
    {
76 1
        return $this->className;
77
    }
78
79 6
    public function collectDBALColumns(): array
80
    {
81
        /** @var array<Column> $additionalColumns */
82 6
        $additionalColumns = array();
83
84 6
        foreach ($this->fieldMappings as $fieldMapping) {
85
            /** @var MappingInterface $fieldMapping */
86
87 6
            $additionalColumns = array_merge(
88 6
                $additionalColumns,
89 6
                $fieldMapping->collectDBALColumns()
90
            );
91
        }
92
93 6
        return $additionalColumns;
94
    }
95
96 1
    public function getFactory(): ?CallDefinitionInterface
97
    {
98 1
        return null;
99
    }
100
101 1
    public function getSerializer(): ?CallDefinitionInterface
102
    {
103 1
        return null;
104
    }
105
106 1
    public function getId(): ?string
107
    {
108 1
        return null;
109
    }
110
111 1
    public function getReferencedId(): ?string
112
    {
113 1
        return null;
114
    }
115
116 1
    public function resolveValue(
117
        HydrationContextInterface $context,
118
        array $dataFromAdditionalColumns
119
    ) {
120
        /** @var array<string, mixed> $entityData */
121 1
        $entityData = array();
122
123
        /** @var MappingInterface $fieldMapping */
124 1
        foreach ($this->fieldMappings as $fieldName => $fieldMapping) {
125 1
            $entityData[$fieldName] = $fieldMapping->resolveValue($context, $dataFromAdditionalColumns);
126
        }
127
128 1
        return $entityData;
129
    }
130
131 3
    public function revertValue(
132
        HydrationContextInterface $context,
133
        $valueFromEntityField
134
    ): array {
135
        /** @var array<string, mixed> $additionalData */
136 3
        $additionalData = array();
137
138
        /** @var object|null $entity */
139 3
        $entity = $valueFromEntityField;
140
141 3
        if (is_object($entity)) {
142 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...
143
144 2
            $reflectionClass = new ReflectionClass($this->className);
145
146
            /** @var MappingInterface $fieldMapping */
147 2
            foreach ($this->fieldMappings as $fieldName => $fieldMapping) {
148
149
                /** @var ReflectionClass $concreteReflectionClass */
150 2
                $concreteReflectionClass = $reflectionClass;
151
152 2
                while (is_object($concreteReflectionClass) && !$concreteReflectionClass->hasProperty($fieldName)) {
153
                    $concreteReflectionClass = $concreteReflectionClass->getParentClass();
154
                }
155
156 2
                if (!is_object($concreteReflectionClass)) {
157
                    throw new ErrorException(sprintf(
158
                        "Property '%s' does not exist on object of class '%s'!",
159
                        $fieldName,
160
                        $this->className
161
                    ));
162
                }
163
164
                /** @var ReflectionProperty $reflectionProperty */
165 2
                $reflectionProperty = $concreteReflectionClass->getProperty($fieldName);
166 2
                $reflectionProperty->setAccessible(true);
167
168
                /** @var mixed $valueFromEntityField */
169 2
                $valueFromEntityField = $reflectionProperty->getValue($entity);
170
171 2
                $additionalData = array_merge(
172 2
                    $additionalData,
173 2
                    $fieldMapping->revertValue($context, $valueFromEntityField)
174
                );
175
            }
176
        }
177
178 3
        return $additionalData;
179
    }
180
181 1
    public function assertValue(
182
        HydrationContextInterface $context,
183
        array $dataFromAdditionalColumns,
184
        $actualValue
185
    ): void {
186 1
    }
187
188 2
    public function wakeUpMapping(ContainerInterface $container): void
189
    {
190 2
        foreach ($this->fieldMappings as $fieldMapping) {
191
            /** @var MappingInterface $fieldMapping */
192
193 2
            $fieldMapping->wakeUpMapping($container);
194
        }
195 2
    }
196
197
}
198