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

NullableMapping::resolveValue()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 34
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 5

Importance

Changes 0
Metric Value
dl 0
loc 34
ccs 16
cts 16
cp 1
rs 8.439
c 0
b 0
f 0
cc 5
eloc 18
nc 5
nop 2
crap 5
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
 *
8
 * @license GPL-3.0
9
 *
10
 * @author Gerrit Addiks <[email protected]>
11
 */
12
13
namespace Addiks\RDMBundle\Mapping;
14
15
use Addiks\RDMBundle\Mapping\MappingInterface;
16
use Doctrine\DBAL\Schema\Column;
17
use Addiks\RDMBundle\Mapping\NullableMappingInterface;
18
use Addiks\RDMBundle\Hydration\HydrationContextInterface;
19
use Addiks\RDMBundle\Exception\InvalidMappingException;
20
use Symfony\Component\DependencyInjection\ContainerInterface;
21
22
final class NullableMapping implements NullableMappingInterface
23
{
24
25
    /**
26
     * @var MappingInterface
27
     */
28
    private $innerMapping;
29
30
    /**
31
     * @var Column|null
32
     */
33
    private $dbalColumn;
34
35
    /**
36
     * @var string
37
     */
38
    private $origin;
39
40 15
    public function __construct(
41
        MappingInterface $innerMapping,
42
        Column $dbalColumn = null,
43
        string $origin = "undefined"
44
    ) {
45 15
        $this->innerMapping = $innerMapping;
46 15
        $this->dbalColumn = $dbalColumn;
47 15
        $this->origin = $origin;
48 15
    }
49
50 1
    public function getDBALColumn(): ?Column
51
    {
52 1
        return $this->dbalColumn;
53
    }
54
55 1
    public function getInnerMapping(): MappingInterface
56
    {
57 1
        return $this->innerMapping;
58
    }
59
60 1
    public function describeOrigin(): string
61
    {
62 1
        return $this->origin;
63
    }
64
65 3
    public function collectDBALColumns(): array
66
    {
67
        /** @var array<Column> $dbalColumns */
68 3
        $dbalColumns = array();
69
70 3
        foreach ($this->innerMapping->collectDBALColumns() as $dbalColumn) {
71
            /** @var Column $dbalColumn */
72
73 2
            $dbalColumn = clone $dbalColumn;
74 2
            $dbalColumn->setNotnull(false);
75
76 2
            $dbalColumns[] = $dbalColumn;
77
        }
78
79 3
        if ($this->dbalColumn instanceof Column) {
80 1
            $dbalColumns[] = $this->dbalColumn;
81
        }
82
83 3
        return $dbalColumns;
84
    }
85
86 8
    public function getDeterminatorColumnName(): ?string
87
    {
88
        /** @var string|null $columnName */
89 8
        $columnName = null;
90
91 8
        if ($this->dbalColumn instanceof Column) {
92 6
            $columnName = $this->dbalColumn->getName();
93
        }
94
95 8
        return $columnName;
96
    }
97
98 4
    public function resolveValue(
99
        HydrationContextInterface $context,
100
        array $dataFromAdditionalColumns
101
    ) {
102
        /** @var mixed|null $value */
103 4
        $value = null;
104
105
        /** @var string|null $columnName */
106 4
        $columnName = $this->getDeterminatorColumnName();
107
108 4
        if (empty($columnName)) {
109
            /** @var array<Column> $columns */
110 2
            $columns = $this->collectDBALColumns();
111
112 2
            if (empty($columns)) {
113 1
                throw new InvalidMappingException(sprintf(
114 1
                    "Nullable mapping needs at least one column (or subcolumn) in %s!",
115 1
                    $this->origin
116
                ));
117
            }
118
119 1
            $columnName = array_values($columns)[0]->getName();
120
        }
121
122 3
        if (array_key_exists($columnName, $dataFromAdditionalColumns)
123 3
        && $dataFromAdditionalColumns[$columnName]) {
124 2
            $value = $this->innerMapping->resolveValue(
125 2
                $context,
126 2
                $dataFromAdditionalColumns
127
            );
128
        }
129
130 3
        return $value;
131
    }
132
133 3
    public function revertValue(
134
        HydrationContextInterface $context,
135
        $valueFromEntityField
136
    ): array {
137
        /** @var array<scalar> $data */
138 3
        $data = array();
139
140 3
        if (!is_null($valueFromEntityField)) {
141
            /** @var string|null $columnName */
142 3
            $columnName = $this->getDeterminatorColumnName();
143
144 3
            $data = $this->innerMapping->revertValue(
145 3
                $context,
146 3
                $valueFromEntityField
147
            );
148
149 3
            if (!empty($columnName) && !array_key_exists($columnName, $data)) {
150 1
                $data[$columnName] = true;
151
            }
152
        }
153
154 3
        return $data;
155
    }
156
157 1
    public function assertValue(
158
        HydrationContextInterface $context,
159
        array $dataFromAdditionalColumns,
160
        $actualValue
161
    ): void {
162 1
    }
163
164 1
    public function wakeUpMapping(ContainerInterface $container): void
165
    {
166 1
        $this->innerMapping->wakeUpMapping($container);
167 1
    }
168
169
}
170