Completed
Push — master ( a59172...19cc7f )
by Andrii
02:47
created

Theme   A

Complexity

Total Complexity 35

Size/Duplication

Total Lines 213
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Test Coverage

Coverage 0%

Importance

Changes 6
Bugs 1 Features 1
Metric Value
wmc 35
c 6
b 1
f 1
lcom 1
cbo 5
dl 0
loc 213
ccs 0
cts 140
cp 0
rs 9

15 Methods

Rating   Name   Duplication   Size   Complexity  
A getView() 0 8 2
A setView() 0 4 1
A init() 0 14 2
B compilePathMap() 0 24 4
C substituteVars() 0 24 7
A isVar() 0 4 2
A calcExp() 0 12 2
A buildThemedViewPaths() 0 6 1
A findParentPaths() 0 14 3
A getReflection() 0 8 2
A setSettings() 0 4 1
A getSettings() 0 13 3
A calcSettingsClass() 0 4 1
A findSettingsClass() 0 6 2
A getDetailedTheme() 0 7 2
1
<?php
2
/**
3
 * Theme Manager for Yii2
4
 *
5
 * @link      https://github.com/hiqdev/yii2-thememanager
6
 * @package   yii2-thememanager
7
 * @license   BSD-3-Clause
8
 * @copyright Copyright (c) 2015-2017, HiQDev (http://hiqdev.com/)
9
 */
10
11
namespace hiqdev\thememanager;
12
13
use ReflectionClass;
14
use Yii;
15
use yii\helpers\ArrayHelper;
16
17
/**
18
 * Theme class.
19
 */
20
class Theme extends \yii\base\Theme implements \hiqdev\yii2\collection\ItemWithNameInterface
21
{
22
    use GetManagerTrait;
23
24
    /**
25
     * @var string theme name
26
     */
27
    public $name;
28
29
    /**
30
     * @var string theme label
31
     */
32
    public $label;
33
34
    /**
35
     * @var array assets to be registered for this theme
36
     */
37
    public $assets = [];
38
39
    private $_view;
40
41
    /**
42
     * Returns the view object that can be used to render views or view files.
43
     * The [[render()]] and [[renderFile()]] methods will use
44
     * this view object to implement the actual view rendering.
45
     * If not set, it will default to the "view" application component.
46
     *
47
     * @return \yii\web\View the view object that can be used to render views or view files
48
     */
49
    public function getView()
50
    {
51
        if ($this->_view === null) {
52
            $this->_view = $this->getManager()->getView();
53
        }
54
55
        return $this->_view;
56
    }
57
58
    /**
59
     * Sets the view object to be used.
60
     *
61
     * @param View $view the view object that can be used to render views or view files
62
     */
63
    public function setView($view)
64
    {
65
        $this->_view = $view;
66
    }
67
68
    public $pathMap = [];
69
70
    /**
71
     * Getter for pathMap.
72
     */
73
    public function init()
74
    {
75
        parent::init();
76
        if (!is_array($this->pathMap)) {
77
            $this->pathMap = [];
78
        }
79
80
        $this->pathMap = $this->compilePathMap(ArrayHelper::merge([
81
            '$themedViewPaths' => $this->buildThemedViewPaths(),
82
            '$themedWidgetPaths' => '$themedViewPaths/widgets',
83
            Yii::$app->viewPath => '$themedViewPaths',
84
            __DIR__ . '/widgets/views' => '$themedWidgetPaths',
85
        ], $this->getManager()->pathMap, $this->pathMap));
86
    }
87
88
    public function compilePathMap($map)
89
    {
90
        $map = $this->substituteVars($map);
91
92
        $themeSubpath = '/src/themes/' . $this->name;
93
94
        $res = [];
95
        foreach ($map as $from => &$tos) {
96
            $tos = array_reverse(array_unique(array_values($tos)));
97
            $new = [];
98
            foreach ($tos as $to) {
99
                $to = Yii::getAlias($to);
100
                $alt = preg_replace('#(.*)/src/views(.*)$#', '${1}'.$themeSubpath.'${2}', $to);
101
                if ($alt) {
102
                    $new[] = $alt;
103
                }
104
                $new[] = $to;
105
            }
106
            #$res[Yii::getAlias($from)] = $new;
0 ignored issues
show
Unused Code Comprehensibility introduced by
65% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
107
            $res[Yii::getAlias($from)] = array_values(array_filter($new, 'file_exists'));
108
        }
109
110
        return array_filter($res);
111
    }
112
113
    public function substituteVars($vars)
114
    {
115
        $proceed = true;
116
        while ($proceed) {
117
            $proceed = false;
118
            foreach ($vars as $key => $exp) {
119
                if ($this->isVar($exp)) {
120
                    $value = $this->calcExp($exp, $vars);
121
                    if (isset($value)) {
122
                        $vars[$key] = $value;
123
                        $proceed = true;
124
                    }
125
                }
126
            }
127
        }
128
129
        foreach (array_keys($vars) as $key) {
130
            if ($this->isVar($key)) {
131
                unset($vars[$key]);
132
            }
133
        }
134
135
        return $vars;
136
    }
137
138
    public function isVar($name)
139
    {
140
        return is_string($name) && (strncmp($name, '$', 1) === 0);
141
    }
142
143
    public function calcExp($exp, $vars)
144
    {
145
        $pos = strpos($exp, '/');
146
        if ($pos === false) {
147
            return $vars[$exp];
148
        }
149
        list($name, $suffix) = explode('/', $exp, 2);
150
151
        return array_map(function ($a) use ($suffix) {
152
            return "$a/$suffix";
153
        }, $vars[$name]);
154
    }
155
156
    public function buildThemedViewPaths()
157
    {
158
        return array_map(function ($a) {
159
            return "$a/views";
160
        }, $this->findParentPaths());
161
    }
162
163
    public function findParentPaths()
164
    {
165
        $dirs = [];
166
        $ref = $this->getReflection();
167
        for ($depth = 0; $depth < 10; ++$depth) {
168
            $dirs[] = dirname($ref->getFileName());
169
            $ref = $ref->getParentClass();
170
            if (__CLASS__ === $ref->name) {
171
                break;
172
            }
173
        }
174
175
        return $dirs;
176
    }
177
178
    protected $_reflection;
179
180
    public function getReflection()
181
    {
182
        if (!$this->_reflection) {
183
            $this->_reflection = new ReflectionClass($this);
184
        }
185
186
        return $this->_reflection;
187
    }
188
189
    private $_settings;
190
191
    /**
192
     * @param string $settings theme settings model class name or config
193
     */
194
    public function setSettings($settings)
195
    {
196
        $this->_settings = $settings;
197
    }
198
199
    public function getSettings()
200
    {
201
        if (!is_object($this->_settings)) {
202
            if (!$this->_settings) {
203
                $this->_settings = static::findSettingsClass(get_called_class());
204
            }
205
            $data = $this->getManager()->getThemeSettings();
206
            $this->_settings = Yii::createObject($this->_settings);
207
            $this->_settings->load($data);
208
        }
209
210
        return $this->_settings;
211
    }
212
213
    public static function calcSettingsClass($class)
214
    {
215
        return substr($class, 0, strrpos($class, '\\')) . '\\models\\Settings';
216
    }
217
218
    public static function findSettingsClass($class)
219
    {
220
        $res = static::calcSettingsClass($class);
221
222
        return class_exists($res) ? $res : static::findSettingsClass(get_parent_class($class));
223
    }
224
225
    public function getDetailedTheme()
226
    {
227
        $localDetailedTheme = str_replace('\Theme', '\DetailedTheme',  get_called_class());
228
        $class = class_exists($localDetailedTheme) ? $localDetailedTheme : DetailedTheme::class;
229
230
        return new $class($this);
231
    }
232
}
233