Completed
Push — master ( 4eea1d...c89067 )
by Hong
04:28
created

ContainerTrait::matchClass()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.9666
c 0
b 0
f 0
cc 3
nc 3
nop 1
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\Config\ConfigAwareTrait;
15
use Psr\Container\ContainerInterface;
16
use Phoole\Base\Reference\ReferenceTrait;
17
18
/**
19
 * ContainerTrait
20
 *
21
 * @package Phoole\Di
22
 */
23
trait ContainerTrait
24
{
25
    use FactoryTrait;
26
    use ReferenceTrait;
27
    use ConfigAwareTrait;
28
29
    /**
30
     * delegator for object lookup
31
     *
32
     * @var ContainerInterface
33
     */
34
    protected $delegator;
35
36
    /**
37
     * object pool
38
     *
39
     * @var array
40
     */
41
    protected $objects;
42
43
    /**
44
     * @var string[]
45
     */
46
    protected $classNames = [];
47
48
    /**
49
     * service definition prefix
50
     *
51
     * @var string
52
     */
53
    protected $prefix = 'di.service.';
54
55
    /**
56
     * common prefix
57
     *
58
     * @var string
59
     */
60
    protected $common = 'di.common';
61
62
    /**
63
     * Reload all service definitions
64
     *
65
     * @return void
66
     */
67
    protected function reloadAll(): void
68
    {
69
        $this->objects = [];
70
71
        // some predefined objects
72
        $this->objects['config'] = $this->getConfig();
73
        $this->objects['container'] = $this->delegator;
74
75
        // do the job
76
        $settings = &($this->getConfig()->getTree())->get('');
77
        $this->deReference($settings);
78
    }
79
80
    /**
81
     * Get the instance
82
     *
83
     * @param  string $id
84
     * @return object
85
     */
86
    protected function getInstance(string $id): object
87
    {
88
        // get new object
89
        if ('@' === substr($id, -1)) {
90
            return $this->newInstance($id);
91
        }
92
93
        // check the pool for shared object
94
        if (!isset($this->objects[$id])) {
95
            $object = $this->newInstance($id);
96
            $this->objects[$id] = $object;
97
            $this->classNames[get_class($object)] = $object;
98
        }
99
100
        return $this->objects[$id];
101
    }
102
103
    /**
104
     * creaet a new instance
105
     *
106
     * @param  string $id
107
     * @return object
108
     */
109
    protected function newInstance(string $id): object
110
    {
111
        $def = $this->getConfig()->get($this->getRawId($id));
112
        $obj = $this->fabricate($def);
113
        $this->executeCommon($obj);
114
        return $obj;
115
    }
116
117
    /**
118
     * get the raw id as defined in $config
119
     *
120
     * @param  string $id
121
     * @return string
122
     */
123
    protected function getRawId(string $id): string
124
    {
125
        return $this->prefix . explode('@', $id, 2)[0];
126
    }
127
128
    /**
129
     * execute common methods for newed objects
130
     *
131
     * @param  object $object
132
     * @return void
133
     */
134
    protected function executeCommon(object $object): void
135
    {
136
        if ($this->getConfig()->has($this->common)) {
137
            foreach ($this->getConfig()->get($this->common) as $line) {
138
                list($runner, $arguments) = $this->fixMethod($object, (array) $line);
139
                $this->executeCallable($runner, $arguments);
140
            }
141
        }
142
    }
143
144
    /**
145
     * Try find a service in the definition
146
     *
147
     * @param  string $id
148
     * @return bool
149
     */
150
    protected function hasDefinition(string $id): bool
151
    {
152
        return $this->getConfig()->has($this->getRawId($id));
153
    }
154
155
    /**
156
     * @param  string $className
157
     * @return object|null
158
     */
159
    protected function matchClass(string $className): ?object
160
    {
161
        foreach ($this->classNames as $class => $object) {
162
            if (is_a($className, $class, TRUE)) {
163
                return $object;
164
            }
165
        }
166
        return NULL;
167
    }
168
169
    /**
170
     * {@inheritDoc}
171
     */
172
    protected function getReference(string $name)
173
    {
174
        return $this->delegator->get($name);
175
    }
176
}