Completed
Push — master ( 67caf0...bdc372 )
by Dmitry
13:07 queued 04:28
created

framework/base/Theme.php (2 issues)

Labels
Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * @link http://www.yiiframework.com/
4
 * @copyright Copyright (c) 2008 Yii Software LLC
5
 * @license http://www.yiiframework.com/license/
6
 */
7
8
namespace yii\base;
9
10
use Yii;
11
use yii\helpers\FileHelper;
12
13
/**
14
 * Theme represents an application theme.
15
 *
16
 * When [[View]] renders a view file, it will check the [[View::theme|active theme]]
17
 * to see if there is a themed version of the view file exists. If so, the themed version will be rendered instead.
18
 *
19
 * A theme is a directory consisting of view files which are meant to replace their non-themed counterparts.
20
 *
21
 * Theme uses [[pathMap]] to achieve the view file replacement:
22
 *
23
 * 1. It first looks for a key in [[pathMap]] that is a substring of the given view file path;
24
 * 2. If such a key exists, the corresponding value will be used to replace the corresponding part
25
 *    in the view file path;
26
 * 3. It will then check if the updated view file exists or not. If so, that file will be used
27
 *    to replace the original view file.
28
 * 4. If Step 2 or 3 fails, the original view file will be used.
29
 *
30
 * For example, if [[pathMap]] is `['@app/views' => '@app/themes/basic']`,
31
 * then the themed version for a view file `@app/views/site/index.php` will be
32
 * `@app/themes/basic/site/index.php`.
33
 *
34
 * It is possible to map a single path to multiple paths. For example,
35
 *
36
 * ```php
37
 * 'pathMap' => [
38
 *     '@app/views' => [
39
 *         '@app/themes/christmas',
40
 *         '@app/themes/basic',
41
 *     ],
42
 * ]
43
 * ```
44
 *
45
 * In this case, the themed version could be either `@app/themes/christmas/site/index.php` or
46
 * `@app/themes/basic/site/index.php`. The former has precedence over the latter if both files exist.
47
 *
48
 * To use a theme, you should configure the [[View::theme|theme]] property of the "view" application
49
 * component like the following:
50
 *
51
 * ```php
52
 * 'view' => [
53
 *     'theme' => [
54
 *         'basePath' => '@app/themes/basic',
55
 *         'baseUrl' => '@web/themes/basic',
56
 *     ],
57
 * ],
58
 * ```
59
 *
60
 * The above configuration specifies a theme located under the "themes/basic" directory of the Web folder
61
 * that contains the entry script of the application. If your theme is designed to handle modules,
62
 * you may configure the [[pathMap]] property like described above.
63
 *
64
 * For more details and usage information on Theme, see the [guide article on theming](guide:output-theming).
65
 *
66
 * @property string $basePath The root path of this theme. All resources of this theme are located under this
67
 * directory.
68
 * @property string $baseUrl The base URL (without ending slash) for this theme. All resources of this theme
69
 * are considered to be under this base URL.
70
 *
71
 * @author Qiang Xue <[email protected]>
72
 * @since 2.0
73
 */
74
class Theme extends Component
75
{
76
    /**
77
     * @var array the mapping between view directories and their corresponding themed versions.
78
     * This property is used by [[applyTo()]] when a view is trying to apply the theme.
79
     * [Path aliases](guide:concept-aliases) can be used when specifying directories.
80
     * If this property is empty or not set, a mapping [[Application::basePath]] to [[basePath]] will be used.
81
     */
82
    public $pathMap;
83
84
    private $_baseUrl;
85
86
87
    /**
88
     * @return string the base URL (without ending slash) for this theme. All resources of this theme are considered
89
     * to be under this base URL.
90
     */
91 3
    public function getBaseUrl()
92
    {
93 3
        return $this->_baseUrl;
94
    }
95
96
    /**
97
     * @param string $url the base URL or [path alias](guide:concept-aliases) for this theme. All resources of this theme are considered
98
     * to be under this base URL.
99
     */
100 4
    public function setBaseUrl($url)
101
    {
102 4
        $this->_baseUrl = $url === null ? null : rtrim(Yii::getAlias($url), '/');
103 4
    }
104
105
    private $_basePath;
106
107
    /**
108
     * @return string the root path of this theme. All resources of this theme are located under this directory.
109
     * @see pathMap
110
     */
111 5
    public function getBasePath()
112
    {
113 5
        return $this->_basePath;
114
    }
115
116
    /**
117
     * @param string $path the root path or [path alias](guide:concept-aliases) of this theme. All resources of this theme are located
118
     * under this directory.
119
     * @see pathMap
120
     */
121 4
    public function setBasePath($path)
122
    {
123 4
        $this->_basePath = Yii::getAlias($path);
124 4
    }
125
126
    /**
127
     * Converts a file to a themed file if possible.
128
     * If there is no corresponding themed file, the original file will be returned.
129
     * @param string $path the file to be themed
130
     * @return string the themed file, or the original file if the themed version is not available.
131
     * @throws InvalidConfigException if [[basePath]] is not set
132
     */
133 6
    public function applyTo($path)
134
    {
135 6
        $pathMap = $this->pathMap;
136 6
        if (empty($pathMap)) {
137 2
            if (($basePath = $this->getBasePath()) === null) {
138 1
                throw new InvalidConfigException('The "basePath" property must be set.');
139
            }
140 1
            $pathMap = [Yii::$app->getBasePath() => [$basePath]];
141
        }
142 5
        $path = FileHelper::normalizePath($path);
143 5
        foreach ($pathMap as $from => $tos) {
144 5
            $from = FileHelper::normalizePath(Yii::getAlias($from)) . DIRECTORY_SEPARATOR;
0 ignored issues
show
It seems like \Yii::getAlias($from) targeting yii\BaseYii::getAlias() can also be of type boolean; however, yii\helpers\BaseFileHelper::normalizePath() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
145 5
            if (strpos($path, $from) === 0) {
146 5
                $n = strlen($from);
147 5
                foreach ((array) $tos as $to) {
148 5
                    $to = FileHelper::normalizePath(Yii::getAlias($to)) . DIRECTORY_SEPARATOR;
0 ignored issues
show
It seems like \Yii::getAlias($to) targeting yii\BaseYii::getAlias() can also be of type boolean; however, yii\helpers\BaseFileHelper::normalizePath() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
149 5
                    $file = $to . substr($path, $n);
150 5
                    if (is_file($file)) {
151 5
                        return $file;
152
                    }
153
                }
154
            }
155
        }
156
157 1
        return $path;
158
    }
159
160
    /**
161
     * Converts a relative URL into an absolute URL using [[baseUrl]].
162
     * @param string $url the relative URL to be converted.
163
     * @return string the absolute URL
164
     * @throws InvalidConfigException if [[baseUrl]] is not set
165
     */
166 2
    public function getUrl($url)
167
    {
168 2
        if (($baseUrl = $this->getBaseUrl()) !== null) {
169 1
            return $baseUrl . '/' . ltrim($url, '/');
170
        }
171
172 1
        throw new InvalidConfigException('The "baseUrl" property must be set.');
173
    }
174
175
    /**
176
     * Converts a relative file path into an absolute one using [[basePath]].
177
     * @param string $path the relative file path to be converted.
178
     * @return string the absolute file path
179
     * @throws InvalidConfigException if [[basePath]] is not set
180
     */
181 2
    public function getPath($path)
182
    {
183 2
        if (($basePath = $this->getBasePath()) !== null) {
184 1
            return $basePath . DIRECTORY_SEPARATOR . ltrim($path, '/\\');
185
        }
186
187 1
        throw new InvalidConfigException('The "basePath" property must be set.');
188
    }
189
}
190