Test Failed
Push — upgrade-psr ( 3d23e3...7af4e6 )
by Sergei
17:47 queued 14:42
created

StateResetter::getType()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 1
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 3
ccs 0
cts 0
cp 0
crap 6
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Di;
6
7
use Closure;
8
use InvalidArgumentException;
9
use Psr\Container\ContainerInterface;
10
11
use function get_class;
12
use function gettype;
13
use function is_int;
14
use function is_object;
15
16
/**
17
 * State resetter allows resetting state of the services that are currently stored in the container and have "reset"
18
 * callback defined. The reset should be triggered after each request-response cycle in case you build long-running
19 4
 * applications with tools like [Swoole](https://www.swoole.co.uk/) or [RoadRunner](https://roadrunner.dev/).
20
 */
21 4
final class StateResetter
22 4
{
23
    /**
24 4
     * @var Closure[]|self[]
25
     */
26 4
    private array $resetters = [];
27 4
    private ContainerInterface $container;
28 2
29 2
    /**
30
     * @param ContainerInterface $container Container to reset.
31 4
     */
32
    public function __construct(ContainerInterface $container)
33 4
    {
34
        $this->container = $container;
35 4
    }
36
37 4
    /**
38 4
     * Reset the container.
39 4
     */
40 2
    public function reset(): void
41 2
    {
42
        foreach ($this->resetters as $resetter) {
43 4
            if ($resetter instanceof self) {
44 4
                $resetter->reset();
45
                continue;
46 4
            }
47
            $resetter($this->container);
48
        }
49
    }
50
51
    /**
52
     * @param Closure[]|self[] $resetters Array of reset callbacks. Each callback has access to the private and
53
     * protected properties of the service instance, so you can set initial state of the service efficiently
54
     * without creating a new instance.
55
     */
56
    public function setResetters(array $resetters): void
57
    {
58
        $this->resetters = [];
59
        foreach ($resetters as $serviceId => $callback) {
60
            if (is_int($serviceId)) {
61
                if (!$callback instanceof self) {
62
                    throw new InvalidArgumentException(sprintf(
63
                        'State resetter object should be instance of "%s", "%s" given.',
64
                        self::class,
65
                        $this->getType($callback)
66
                    ));
67
                }
68
                $this->resetters[] = $callback;
69
                continue;
70
            }
71
72
            if (!$callback instanceof Closure) {
73
                throw new InvalidArgumentException(
74
                    'Callback for state resetter should be closure in format ' .
75
                    '`function (ContainerInterface $container): void`. ' .
76
                    'Got "' . $this->getType($callback) . '".'
77
                );
78
            }
79
80
            /** @var mixed $instance */
81
            $instance = $this->container->get($serviceId);
82
            if (!is_object($instance)) {
83
                throw new InvalidArgumentException(
84
                    'State resetter supports resetting objects only. Container returned ' . gettype($instance) . '.'
85
                );
86
            }
87
88
            $this->resetters[] = $callback->bindTo($instance, get_class($instance));
89
        }
90
    }
91
92
    /**
93
     * @param mixed $variable
94
     */
95
    private function getType($variable): string
96
    {
97
        return is_object($variable) ? get_class($variable) : gettype($variable);
98
    }
99
}
100