Completed
Push — master ( c89067...3b0f09 )
by Hong
04:25
created

StaticAccessTrait::getContainer()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 0
1
<?php
2
3
/**
4
 * Phoole (PHP7.2+)
5
 *
6
 * @category  Library
7
 * @package   Phoole\Di
8
 * @copyright Copyright (c) 2019 Hong Zhang
9
 */
10
declare(strict_types=1);
11
12
namespace Phoole\Di\Util;
13
14
use Phoole\Di\Container;
15
use Phoole\Di\Exception\LogicException;
16
use Phoole\Di\Exception\RuntimeException;
17
use Psr\Container\NotFoundExceptionInterface;
18
use Phoole\Di\Exception\UnresolvedClassException;
19
20
/**
21
 * StaticAccessTrait
22
 *
23
 * Static facade extension
24
 *
25
 * ```php
26
 * $cache = Container::cache();
27
 * $obj = Container::create(MyClass::class);
28
 * ```
29
 *
30
 * @package Phoole\Di
31
 */
32
trait StaticAccessTrait
33
{
34
    /**
35
     * @var Container[]
36
     */
37
    protected static $containers = [];
38
39
    /**
40
     * Mostly for getting an anonymous object by its classname.
41
     *
42
     * - dependency in constructor is resolved automatically
43
     * - 'di.before' & 'di.after' methods executed on this object
44
     *
45
     * @param  string|callable|object $className  object or classname
46
     * @param  array                  $arguments  constructor arguments if any
47
     * @return object
48
     */
49
    public static function create($className, array $arguments = []): object
50
    {
51
        return self::getContainer()->newInstance(
0 ignored issues
show
Bug introduced by
The method newInstance() cannot be called from this context as it is declared protected in class Phoole\Di\Util\ContainerTrait.

This check looks for access to methods that are not accessible from the current context.

If you need to make a method accessible to another context you can raise its visibility level in the defining class.

Loading history...
52
            ['class' => $className, 'args' => $arguments]
53
        );
54
    }
55
56
    /**
57
     * Get object by its id in a STATIC way
58
     *
59
     * ```php
60
     * $cache = Container::cache();
61
     * $logger = Container::logger();
62
     * ```
63
     *
64
     * @param  string $name       service id
65
     * @param  array  $arguments  if object is an invokable
66
     * @return object
67
     * @throws NotFoundExceptionInterface  No entry was found for **this** identifier.
68
     * @throws LogicException              if container not instantiated
69
     * @throws UnresolvedClassException    if parameter not resolved
70
     * @throws RuntimeException            if invokable goes wrong
71
     */
72
    public static function __callStatic($name, $arguments): object
73
    {
74
        $object = self::getContainer()->get($name);
75
        try {
76
            // invokable object
77
            if (!empty($arguments) && is_callable($object)) {
78
                return $object($arguments);
79
            }
80
            return $object;
81
        } catch (\Throwable $e) {
82
            throw new RuntimeException($e->getMessage());
83
        }
84
    }
85
86
    /**
87
     * @return Container
88
     * @throws LogicException     if container not instantiated
89
     */
90
    protected static function getContainer(): Container
91
    {
92
        $containerClass = get_called_class();
93
        if (!isset(self::$containers[$containerClass])) {
94
            throw new LogicException("unInitialized container $containerClass");
95
        }
96
        return self::$containers[$containerClass];
97
    }
98
99
    /**
100
     * @param  Container $container
101
     */
102
    protected static function setContainer(Container $container)
103
    {
104
        self::$containers[get_class($container)] = $container;
105
    }
106
}