NullableClassEnforcer   A
last analyzed

Complexity

Total Complexity 3

Size/Duplication

Total Lines 45
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 3
eloc 22
c 1
b 0
f 0
dl 0
loc 45
rs 10

1 Method

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 32 3
1
<?php
2
3
/**
4
 * This file is part of the sj-i/typist package.
5
 *
6
 * (c) sji <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Typist;
15
16
use ReflectionClass;
17
18
/**
19
 * @template T
20
 */
21
final class NullableClassEnforcer
22
{
23
    /** @var class-string[] */
24
    private static array $registered_classes = [];
25
26
    private GeneratedClassEnforcerInterface $enforcer;
27
28
    /**
29
     * @internal
30
     * @param class-string<T> $passed_class_name
31
     * @param T|null $value
32
     * @throws \ReflectionException
33
     */
34
    public function __construct(string $passed_class_name, &$value)
35
    {
36
        $class = new ReflectionClass($passed_class_name);
37
38
        $namespace = $class->getNamespaceName();
39
        $class_name = $class->getShortName();
40
        $fully_qualified_class_name = ($namespace === '' ? '\\' : $namespace) . $class_name;
41
42
        $enforcer_name = 'Nullable' . $class_name . 'Enforcer';
43
        $enforcer_namespace = rtrim(implode('\\', [__NAMESPACE__ , $namespace]), '\\');
44
        $enforcer_interface_name = GeneratedClassEnforcerInterface::class;
45
46
        if (!isset(self::$registered_classes[$fully_qualified_class_name])) {
47
            $code = <<<TEMPLATE
48
            declare(strict_types=1);
49
            namespace {$enforcer_namespace};
50
            class {$enforcer_name} implements \\{$enforcer_interface_name}
51
            {
52
                private ?{$fully_qualified_class_name} \$value;
53
                public function __construct(?{$fully_qualified_class_name} &\$value)
54
                {
55
                    \$this->value = &\$value;
56
                }
57
            }
58
            TEMPLATE;
59
            eval($code);
60
            self::$registered_classes[$fully_qualified_class_name] = true;
61
        }
62
63
        /** @var class-string<GeneratedClassEnforcerInterface> $enforcer_fqn */
64
        $enforcer_fqn = implode('\\', [$enforcer_namespace, $enforcer_name]);
65
        $this->enforcer = new $enforcer_fqn($value);
66
    }
67
}
68