Completed
Push — master ( 579af5...b29473 )
by Oleg
07:53
created

Container::loadComponent()   D

Complexity

Conditions 9
Paths 7

Size

Total Lines 30
Code Lines 17

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 30
rs 4.909
cc 9
eloc 17
nc 7
nop 2
1
<?php /** MicroContainer */
2
3
namespace Micro\Base;
4
5
/**
6
 * Container class file.
7
 *
8
 * @author Oleg Lunegov <[email protected]>
9
 * @link https://github.com/lugnsk/micro
10
 * @copyright Copyright &copy; 2013 Oleg Lunegov
11
 * @license /LICENSE
12
 * @package Micro
13
 * @subpackage Base
14
 * @version 1.0
15
 * @since 1.0
16
 */
17
class Container extends \stdClass implements IContainer
18
{
19
    /** @var array $data data */
20
    protected $data = [];
21
    /** @var array $config Configs */
22
    protected $config = [];
23
    /** @var array $components Components config */
24
    protected $components = [];
25
26
27
    /**
28
     * Load more configs from file
29
     *
30
     * @access public
31
     *
32
     * @param string $filename
33
     *
34
     * @return void
35
     */
36
    public function load($filename)
37
    {
38
        if (file_exists($filename = $this->kernel->getAppDir() . $filename)) {
39
            /** @noinspection PhpIncludeInspection */
40
            $this->config = array_merge_recursive($this->config, require $filename);
41
            $this->components = array_merge_recursive($this->components, $this->config['components']);
42
            unset($this->config['components']);
43
        }
44
    }
45
46
    /**
47
     * Is set component or option name into Container
48
     *
49
     * @access public
50
     *
51
     * @param string $name Name attribute
52
     *
53
     * @return bool
54
     */
55
    public function __isset($name)
56
    {
57
        if (array_key_exists($name, $this->config)) {
58
            return true;
59
        }
60
        if (array_key_exists($name, $this->data)) {
61
            return true;
62
        }
63
        if (array_key_exists($name, $this->components)) {
64
            return true;
65
        }
66
67
        return false;
68
    }
69
70
    /**
71
     * Get Container value
72
     *
73
     * @access public
74
     *
75
     * @param string $name element name
76
     *
77
     * @return mixed
78
     */
79
    public function __get($name = '')
80
    {
81
        if (!empty($this->config[$name])) {
82
            return $this->config[$name];
83
        }
84
85
        if (empty($this->data[$name]) && !$this->configure($name)) {
86
            return false;
87
        }
88
89
        return $this->data[$name];
90
    }
91
92
    /**
93
     * Set attribute
94
     *
95
     * @access public
96
     *
97
     * @param string $name Name attribute
98
     * @param mixed $component Component or option
99
     *
100
     * @return void
101
     */
102
    public function __set($name, $component)
103
    {
104
        $this->data[$name] = $component;
105
    }
106
107
    /**
108
     * Get component's
109
     *
110
     * @access public
111
     *
112
     * @param string|null $name name element to initialize
113
     *
114
     * @return bool
115
     */
116
    public function configure($name = null)
117
    {
118
        if (0 === count($this->components)) {
119
            return false;
120
        }
121
122
        if ($name === null) {
123
            foreach ($this->components AS $name => $options) {
124
                if (!$this->loadComponent($name, $options)) {
125
                    return false;
126
                }
127
            }
128
129
            return true;
130
        }
131
132
        if (empty($this->components[$name])) {
133
            return false;
134
        }
135
136
        if (!$this->loadComponent($name, $this->components[$name])) {
137
            return false;
138
        }
139
140
        return true;
141
    }
142
143
    /**
144
     * Load component
145
     *
146
     * @access public
147
     *
148
     * @param string $name component name
149
     * @param array $options component configs
150
     *
151
     * @return bool
152
     */
153
    public function loadComponent($name, $options)
154
    {
155
        if (empty($options['class']) || !class_exists($options['class'])) {
156
            return false;
157
        }
158
        $className = $options['class'];
159
160
        if (empty($options['arguments'])) {
161
            $this->data[$name] = new $className;
162
163
            return true;
164
        }
165
166
        /** @noinspection AlterInForeachInspection */
167
        foreach ($options['arguments'] AS $key => &$val) {
168
            if (is_string($options['arguments'][$key]) && (substr($val, 0, 1) === '@')) {
169
                if ($val === '@this') {
170
                    $val = $this;
171
                } else {
172
                    if (null === $this->{substr($val, 1)}) {
173
                        return false;
174
                    }
175
                    $val = $this->__get(substr($val, 1));
176
                }
177
            }
178
        }
179
        $this->data[$name] = new $className($options['arguments']);
180
181
        return true;
182
    }
183
}
184