Facade   A
last analyzed

Complexity

Total Complexity 7

Size/Duplication

Total Lines 77
Duplicated Lines 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
wmc 7
eloc 16
c 1
b 1
f 0
dl 0
loc 77
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A getContainer() 0 3 1
A __callStatic() 0 16 3
A setContainer() 0 11 3
1
<?php
2
3
namespace Flawlol\Facade\Abstract;
4
5
use Flawlol\Facade\Exception\ContainerIsAlreadySetException;
6
use Flawlol\Facade\Exception\ContainerIsNotSetException;
7
use Flawlol\Facade\Interface\FacadeInterface;
8
use Symfony\Component\DependencyInjection\ContainerInterface;
9
10
/**
11
 * Abstract class Facade.
12
 *
13
 * This abstract class provides a base implementation for a facade that interacts with a container.
14
 */
15
abstract class Facade implements FacadeInterface
16
{
17
    /**
18
     * @var ContainerInterface|null The container instance.
19
     */
20
    protected static ?ContainerInterface $container = null;
21
22
    /**
23
     * Get the container instance.
24
     *
25
     * @return ContainerInterface|null The container instance or null if not set.
26
     */
27
    public static function getContainer(): ?ContainerInterface
28
    {
29
        return self::$container;
30
    }
31
32
    /**
33
     * Set the container instance.
34
     *
35
     * @param ?ContainerInterface $container The container instance to set.
36
     *
37
     * @throws ContainerIsAlreadySetException If the container is already set.
38
     *
39
     * @return void
40
     */
41
    public static function setContainer(?ContainerInterface $container): void
42
    {
43
        if (null === $container) {
44
            throw new \InvalidArgumentException('Container cannot be null');
45
        }
46
47
        if (null !== self::$container) {
48
            throw new ContainerIsAlreadySetException('Container is already set');
49
        }
50
51
        self::$container = $container;
52
    }
53
54
    /**
55
     * Handle dynamic, static calls to the object.
56
     *
57
     * @param string $method The method name being called.
58
     * @param array  $args   The arguments passed to the method.
59
     *
60
     * @throws ContainerIsNotSetException If the container is not set.
61
     * @throws \BadMethodCallException    If the method does not exist on the service.
62
     *
63
     * @return mixed The result of the method call.
64
     */
65
    public static function __callStatic(string $method, array $args): mixed
66
    {
67
        if (null === self::$container) {
68
            throw new ContainerIsNotSetException('Container is not set');
69
        }
70
71
        $static = static::class;
72
        $accessor = $static::getFacadeAccessor();
73
74
        $service = self::$container->get($accessor);
75
76
        if (!method_exists($service, $method)) {
77
            throw new \BadMethodCallException(sprintf('Method %s does not exist', $method));
78
        }
79
80
        return call_user_func_array([$service, $method], $args);
81
    }
82
83
    /**
84
     * Get the facade accessor.
85
     *
86
     * This method should be implemented by the concrete facade class to return the key
87
     * used to retrieve the service from the container.
88
     *
89
     * @return string The facade accessor key.
90
     */
91
    abstract protected static function getFacadeAccessor(): string;
92
}
93