ServiceMapping::wakeUpMapping()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
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;
12
13
use Addiks\RDMBundle\Hydration\HydrationContextInterface;
14
use Addiks\RDMBundle\Exception\FailedRDMAssertionException;
15
use ErrorException;
16
use Symfony\Component\DependencyInjection\ContainerInterface;
17
use ReflectionClass;
18
use Addiks\RDMBundle\Mapping\MappingInterface;
19
20
final class ServiceMapping implements MappingInterface
21
{
22
23
    /**
24
     * The service-id of the service to load for given entitiy-field.
25
     *
26
     * @var string
27
     */
28
    private $serviceId;
29
30
    /**
31
     * Set this to true if this field should not be checked for the correct service on persist.
32
     * This check is a safety-net and you should know what you are doing when you are disabling it.
33
     * You have been warned.
34
     *
35
     * @var bool
36
     */
37
    private $lax = false;
38
39
    /**
40
     * @var string
41
     */
42
    private $origin;
43
44
    /**
45
     * @var ContainerInterface
46
     */
47
    private $container;
48
49
    /**
50
     * Global flag to completely disable service-object checks for the current runtime.
51
     * This is needed for test-runs with software like behat, because there services from multiple
52
     * different executions (from different service-containers) can get mixed up.
53
     *
54
     * @var bool
55
     */
56
    private static $alwaysLax = false;
57
58 1
    public static function setAlwaysLax(bool $alwaysLax): void
59
    {
60 1
        self::$alwaysLax = $alwaysLax;
61
    }
62
63 24
    public function __construct(
64
        ContainerInterface $container,
65
        string $serviceId,
66
        bool $lax = false,
67
        string $origin = "unknown"
68
    ) {
69 24
        $this->container = $container;
70 24
        $this->serviceId = $serviceId;
71 24
        $this->lax = $lax;
72 24
        $this->origin = $origin;
73
    }
74
75 6
    public function __sleep(): array
76
    {
77
        return [
78 6
            'serviceId',
79
            'lax',
80
            'origin',
81
        ];
82
    }
83
84 1
    public function getServiceId(): string
85
    {
86 1
        return $this->serviceId;
87
    }
88
89 2
    public function isLax(): bool
90
    {
91 2
        return $this->lax;
92
    }
93
94 2
    public function describeOrigin(): string
95
    {
96 2
        return $this->origin;
97
    }
98
99 5
    public function collectDBALColumns(): array
100
    {
101 5
        return [];
102
    }
103
104 8
    public function resolveValue(
105
        HydrationContextInterface $context,
106
        array $dataFromAdditionalColumns
107
    ) {
108
        /** @var object $service */
109 8
        $service = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $service is dead and can be removed.
Loading history...
110
111 8
        if (!$this->container->has($this->serviceId)) {
112
            throw new ErrorException(sprintf(
113
                "Referenced non-existent service '%s' %s!",
114
                $this->serviceId,
115
                $this->origin
116
            ));
117
        }
118
119
        /** @var object $service */
120 8
        $service = $this->container->get($this->serviceId);
121
122 8
        return $service;
123
    }
124
125 3
    public function revertValue(
126
        HydrationContextInterface $context,
127
        $valueFromEntityField
128
    ): array {
129 3
        return []; # Nothing to revert to for static services
130
    }
131
132 5
    public function assertValue(
133
        HydrationContextInterface $context,
134
        array $dataFromAdditionalColumns,
135
        $actualValue
136
    ): void {
137 5
        if (!$this->lax && !self::$alwaysLax) {
138
            /** @var object $expectedService */
139 3
            $expectedService = $this->resolveValue($context, $dataFromAdditionalColumns);
140
141 3
            if ($expectedService !== $actualValue) {
142 2
                throw FailedRDMAssertionException::expectedDifferentService(
143 2
                    $this->serviceId,
144 2
                    new ReflectionClass($context->getEntityClass()),
145
                    $expectedService,
146
                    $actualValue
147
                );
148
            }
149
        }
150
    }
151
152 2
    public function wakeUpMapping(ContainerInterface $container): void
153
    {
154 2
        $this->container = $container;
155
    }
156
157
}
158