Passed
Pull Request — master (#1045)
by
unknown
19:48 queued 09:50
created

Proxy::create()   B

Complexity

Conditions 11
Paths 6

Size

Total Lines 66
Code Lines 37

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 36
CRAP Score 11.0176

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 37
c 1
b 0
f 0
dl 0
loc 66
ccs 36
cts 38
cp 0.9474
rs 7.3166
cc 11
nc 6
nop 3
crap 11.0176

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Spiral\Core\Internal;
6
7
use Spiral\Core\ContainerScope;
8
use Spiral\Core\Internal\Proxy\ProxyClassRenderer;
9
10
/**
11
 * @internal
12
 */
13
final class Proxy
14
{
15
    /** @var array<class-string, object> */
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<class-string, object> at position 2 could not be parsed: Unknown type name 'class-string' at position 2 in array<class-string, object>.
Loading history...
16
    private static array $cache = [];
17
18
    /**
19
     * @template TClass of object
20
     * @param \ReflectionClass<TClass> $type
21
     * @return TClass
0 ignored issues
show
Bug introduced by
The type Spiral\Core\Internal\TClass was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
22
     */
23 14
    public static function create(
24
        \ReflectionClass $type,
25
        \Stringable|string|null $context,
26
        \Spiral\Core\Attribute\Proxy $attribute,
27
    ): object {
28 14
        $interface = $type->getName();
29
30
        // Use the container where the proxy was created
31 14
        $attachContainer = $attribute->attachContainer;
32
33 14
        $cacheKey = \sprintf(
34 14
            '%s%s%s',
35 14
            $interface,
36 14
            $attachContainer ? '[attached]' : '',
37 14
            $attribute->proxyOverloads ? '[magic-calls]' : '',
38 14
        );
39
40 14
        if (!\array_key_exists($cacheKey, self::$cache)) {
41 4
            $n = 0;
42
            do {
43
                /** @var class-string<TClass> $className */
44 4
                $className = \sprintf(
45 4
                    '%s\%s SCOPED PROXY%s',
46 4
                    $type->getNamespaceName(),
47 4
                    $type->getShortName(),
48 4
                    $n++ > 0 ? " {$n}" : ''
49 4
                );
50 4
            } while (\class_exists($className));
51
52
            try {
53 4
                $classString = ProxyClassRenderer::renderClass(
54 4
                    $type,
55 4
                    $className,
56 4
                    $attribute->proxyOverloads,
57 4
                    $attachContainer,
58 4
                );
59
60 4
                eval($classString);
0 ignored issues
show
introduced by
The use of eval() is discouraged.
Loading history...
61
            } catch (\Throwable $e) {
62
                throw new \Error("Unable to create proxy for `{$interface}`: {$e->getMessage()}", 0, $e);
63
            }
64
65 4
            $instance = new $className();
66 4
            (static fn () => $instance::$__container_proxy_alias = $interface)->bindTo(null, $instance::class)();
67
68
            // Store in cache without context
69 4
            self::$cache[$cacheKey] = $instance;
70
        } else {
71
            /** @var TClass $instance */
72 10
            $instance = self::$cache[$cacheKey];
73
        }
74
75 14
        if ($context !== null || $attachContainer) {
76 14
            $instance = clone $instance;
77 14
            (static function () use ($instance, $context, $attachContainer): void {
78
                // Set the Current Context
79
                /** @see \Spiral\Core\Internal\Proxy\ProxyTrait::$__container_proxy_context */
80 14
                $context === null or $instance->__container_proxy_context = $context;
81
82
                // Set the Current Scope Container
83
                /** @see \Spiral\Core\Internal\Proxy\ProxyTrait::__container_proxy_container */
84 14
                $attachContainer and $instance->__container_proxy_container = ContainerScope::getContainer();
85 14
            })->bindTo(null, $instance::class)();
86
        }
87
88 14
        return $instance;
89
    }
90
}
91