1 | <?php |
||||
2 | /** |
||||
3 | * @link https://www.yiiframework.com/ |
||||
4 | * @copyright Copyright (c) 2008 Yii Software LLC |
||||
5 | * @license https://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|null 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), '/'); |
|||
0 ignored issues
–
show
introduced
by
![]() It seems like
Yii::getAlias($url) can also be of type false ; however, parameter $string of rtrim() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
103 | } |
||||
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 | } |
||||
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 | 7 | public function applyTo($path) |
|||
134 | { |
||||
135 | 7 | $pathMap = $this->pathMap; |
|||
136 | 7 | if (empty($pathMap)) { |
|||
137 | 2 | if (($basePath = $this->getBasePath()) === null) { |
|||
0 ignored issues
–
show
|
|||||
138 | 1 | throw new InvalidConfigException('The "basePath" property must be set.'); |
|||
139 | } |
||||
140 | 1 | $pathMap = [Yii::$app->getBasePath() => [$basePath]]; |
|||
141 | } |
||||
142 | 6 | $path = FileHelper::normalizePath($path); |
|||
143 | 6 | foreach ($pathMap as $from => $tos) { |
|||
144 | 6 | $from = FileHelper::normalizePath(Yii::getAlias($from)) . DIRECTORY_SEPARATOR; |
|||
0 ignored issues
–
show
It seems like
Yii::getAlias($from) can also be of type false ; however, parameter $path of yii\helpers\BaseFileHelper::normalizePath() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
145 | 6 | if (strpos($path, $from) === 0) { |
|||
146 | 6 | $n = strlen($from); |
|||
147 | 6 | foreach ((array) $tos as $to) { |
|||
148 | 6 | $to = FileHelper::normalizePath(Yii::getAlias($to)) . DIRECTORY_SEPARATOR; |
|||
149 | 6 | $file = $to . substr($path, $n); |
|||
150 | 6 | if (is_file($file)) { |
|||
151 | 5 | return $file; |
|||
152 | } |
||||
153 | } |
||||
154 | } |
||||
155 | } |
||||
156 | |||||
157 | 2 | 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) { |
|||
0 ignored issues
–
show
|
|||||
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) { |
|||
0 ignored issues
–
show
|
|||||
184 | 1 | return $basePath . DIRECTORY_SEPARATOR . ltrim($path, '/\\'); |
|||
185 | } |
||||
186 | |||||
187 | 1 | throw new InvalidConfigException('The "basePath" property must be set.'); |
|||
188 | } |
||||
189 | } |
||||
190 |