This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace Arrilot\BitrixBlade; |
||
4 | |||
5 | use Bitrix\Main\Config\Configuration; |
||
6 | use ErrorException; |
||
7 | use Illuminate\Container\Container; |
||
8 | use Illuminate\Contracts\View\Factory; |
||
9 | use RuntimeException; |
||
10 | |||
11 | class BladeProvider |
||
12 | { |
||
13 | /** |
||
14 | * Path to a folder view common view can be stored. |
||
15 | * |
||
16 | * @var string |
||
17 | */ |
||
18 | protected static $baseViewPath; |
||
19 | |||
20 | /** |
||
21 | * Local path to blade cache storage. |
||
22 | * |
||
23 | * @var string |
||
24 | */ |
||
25 | protected static $cachePath; |
||
26 | |||
27 | /** |
||
28 | * View factory. |
||
29 | * |
||
30 | * @var Factory |
||
31 | */ |
||
32 | protected static $viewFactory; |
||
33 | |||
34 | /** |
||
35 | * Service container factory. |
||
36 | * |
||
37 | * @var Container |
||
38 | */ |
||
39 | protected static $container; |
||
40 | |||
41 | /** |
||
42 | * Register blade engine in Bitrix. |
||
43 | */ |
||
44 | public static function register() |
||
45 | { |
||
46 | $bitrixConfig = Configuration::getValue('bitrix-blade'); |
||
47 | $baseViewPath = isset($bitrixConfig['baseViewPath']) ? $bitrixConfig['baseViewPath'] : 'local/views'; |
||
48 | $cachePath = isset($bitrixConfig['cachePath']) ? $bitrixConfig['cachePath'] : 'local/cache/blade'; |
||
49 | |||
50 | static::$baseViewPath = static::isAbsolutePath($baseViewPath) ? $baseViewPath : $_SERVER['DOCUMENT_ROOT'].'/'.$baseViewPath; |
||
51 | static::$cachePath = static::isAbsolutePath($cachePath) ? $cachePath : $_SERVER['DOCUMENT_ROOT'].'/'.$cachePath; |
||
52 | static::instantiateServiceContainer(); |
||
53 | static::instantiateViewFactory(); |
||
54 | static::registerBitrixDirectives(); |
||
55 | |||
56 | global $arCustomTemplateEngines; |
||
57 | $arCustomTemplateEngines['blade'] = [ |
||
58 | 'templateExt' => ['blade'], |
||
59 | 'function' => 'renderBladeTemplate', |
||
60 | ]; |
||
61 | } |
||
62 | |||
63 | protected static function isAbsolutePath($path) |
||
64 | { |
||
65 | return $path && ($path[0] === DIRECTORY_SEPARATOR || preg_match('~\A[A-Z]:(?![^/\\\\])~i', $path) > 0); |
||
66 | } |
||
67 | |||
68 | /** |
||
69 | * Get view factory. |
||
70 | * |
||
71 | * @return Factory |
||
72 | */ |
||
73 | public static function getViewFactory() |
||
74 | { |
||
75 | return static::$viewFactory; |
||
76 | } |
||
77 | |||
78 | /** |
||
79 | * @return BladeCompiler |
||
80 | */ |
||
81 | public static function getCompiler() |
||
82 | { |
||
83 | return static::$container['blade.compiler']; |
||
84 | } |
||
85 | |||
86 | /** |
||
87 | * Clear all compiled view files. |
||
88 | */ |
||
89 | public static function clearCache() |
||
90 | { |
||
91 | $path = static::$cachePath; |
||
92 | |||
93 | if (!$path) { |
||
94 | throw new RuntimeException('Cache path is empty'); |
||
95 | } |
||
96 | |||
97 | $success = true; |
||
98 | foreach (glob("{$path}/*") as $view) { |
||
99 | try { |
||
100 | if (!@unlink($view)) { |
||
101 | $success = false; |
||
102 | } |
||
103 | } catch (ErrorException $e) { |
||
104 | $success = false; |
||
105 | } |
||
106 | } |
||
107 | |||
108 | return $success; |
||
109 | } |
||
110 | |||
111 | /** |
||
112 | * Update paths where blade tries to find additional views. |
||
113 | * |
||
114 | * @param string $templateDir |
||
115 | */ |
||
116 | public static function addTemplateFolderToViewPaths($templateDir) |
||
117 | { |
||
118 | $finder = Container::getInstance()->make('view.finder'); |
||
119 | |||
120 | $currentPaths = $finder->getPaths(); |
||
121 | $newPaths = [$_SERVER['DOCUMENT_ROOT'].$templateDir]; |
||
122 | |||
123 | // Полностью перезаписывать пути нельзя, иначе вложенные компоненты + include перестанут работать. |
||
124 | $newPaths = array_values(array_unique(array_merge($newPaths, $currentPaths))); |
||
125 | if (!in_array(static::$baseViewPath, $newPaths)) { |
||
126 | $newPaths[] = static::$baseViewPath; |
||
127 | } |
||
128 | |||
129 | // Необходимо очистить внутренний кэш ViewFinder-а |
||
130 | // Потому что иначе если в родительском компоненте есть @include('foo'), то при вызове @include('foo') из дочернего, |
||
131 | // он не будет искать foo в дочернем, а сразу подключит foo из родительского компонента |
||
132 | $finder->flush(); |
||
133 | |||
134 | $finder->setPaths($newPaths); |
||
135 | } |
||
136 | |||
137 | /** |
||
138 | * Undo addTemplateFolderToViewPaths |
||
139 | * |
||
140 | * @param string $templateDir |
||
141 | */ |
||
142 | public static function removeTemplateFolderFromViewPaths($templateDir) |
||
143 | { |
||
144 | $finder = Container::getInstance()->make('view.finder'); |
||
145 | $currentPaths = $finder->getPaths(); |
||
146 | $finder->setPaths(array_diff($currentPaths, [$_SERVER['DOCUMENT_ROOT'].$templateDir] )); |
||
147 | |||
148 | // Необходимо очистить внутренний кэш ViewFinder-а |
||
149 | // Потому что иначе если в дочернем компоненте есть @include('foo'), то при вызове @include('foo') в родительском |
||
150 | // после подключения дочернего, |
||
151 | // он не будет искать foo в родительском, а сразу подключит foo из дочернего компонента |
||
152 | $finder->flush(); |
||
153 | } |
||
154 | |||
155 | /** |
||
156 | * Instantiate service container if it's not instantiated yet. |
||
157 | */ |
||
158 | protected static function instantiateServiceContainer() |
||
159 | { |
||
160 | $container = Container::getInstance(); |
||
161 | |||
162 | if (!$container) { |
||
163 | $container = new Container(); |
||
164 | Container::setInstance($container); |
||
165 | } |
||
166 | |||
167 | static::$container = $container; |
||
168 | } |
||
169 | |||
170 | /** |
||
171 | * Instantiate view factory. |
||
172 | */ |
||
173 | protected static function instantiateViewFactory() |
||
174 | { |
||
175 | static::createDirIfNotExist(static::$baseViewPath); |
||
176 | static::createDirIfNotExist(static::$cachePath); |
||
177 | |||
178 | $viewPaths = [ |
||
179 | static::$baseViewPath, |
||
180 | ]; |
||
181 | $cache = static::$cachePath; |
||
182 | |||
183 | $blade = new Blade($viewPaths, $cache, static::$container); |
||
184 | |||
185 | static::$viewFactory = $blade->view(); |
||
186 | static::$viewFactory->addExtension('blade', 'blade'); |
||
187 | } |
||
188 | |||
189 | /** |
||
190 | * Create dir if it does not exist. |
||
191 | * |
||
192 | * @param string $path |
||
193 | */ |
||
194 | protected static function createDirIfNotExist($path) |
||
195 | { |
||
196 | if (!file_exists($path)) { |
||
197 | $mask = umask(0); |
||
198 | mkdir($path, 0777, true); |
||
199 | umask($mask); |
||
200 | } |
||
201 | } |
||
202 | |||
203 | /** |
||
204 | * Register bitrix directives. |
||
205 | */ |
||
206 | protected static function registerBitrixDirectives() |
||
207 | { |
||
208 | $compiler = static::getCompiler(); |
||
209 | |||
210 | $endIf = function () { |
||
211 | return '<?php endif; ?>'; |
||
212 | }; |
||
213 | |||
214 | $compiler->directive('bxComponent', function ($expression) { |
||
215 | $expression = rtrim($expression, ')'); |
||
216 | $expression = ltrim($expression, '('); |
||
217 | |||
218 | return '<?php $APPLICATION->IncludeComponent('.$expression.'); ?>'; |
||
219 | }); |
||
220 | |||
221 | $compiler->directive('block', function ($expression) { |
||
222 | $expression = rtrim($expression, ')'); |
||
223 | $expression = ltrim($expression, '('); |
||
224 | |||
225 | return '<?php ob_start(); $__bx_block = ' . $expression . '; ?>'; |
||
226 | }); |
||
227 | |||
228 | $compiler->directive('endblock', function () { |
||
229 | return '<?php $APPLICATION->AddViewContent($__bx_block, ob_get_clean()); ?>'; |
||
230 | }); |
||
231 | |||
232 | $compiler->directive('lang', function ($expression) { |
||
233 | return '<?= Bitrix\Main\Localization\Loc::getMessage('.$expression.') ?>'; |
||
234 | }); |
||
235 | |||
236 | $compiler->directive('auth', function () { |
||
237 | return '<?php if($USER->IsAuthorized()): ?>'; |
||
238 | }); |
||
239 | $compiler->directive('guest', function () { |
||
240 | return '<?php if(!$USER->IsAuthorized()): ?>'; |
||
241 | }); |
||
242 | $compiler->directive('admin', function () { |
||
243 | return '<?php if($USER->IsAdmin()): ?>'; |
||
244 | }); |
||
245 | $compiler->directive('csrf', function ($name = 'sessid') { |
||
246 | $name = !empty($name) ? $name : 'sessid'; |
||
247 | $name = trim($name, '"'); |
||
248 | $name = trim($name, "'"); |
||
249 | return '<input type="hidden" name="'.$name.'" value="<?= bitrix_sessid() ?>" />'; |
||
250 | }); |
||
251 | |||
252 | $compiler->directive('endauth', $endIf); |
||
253 | $compiler->directive('endguest', $endIf); |
||
254 | $compiler->directive('endadmin', $endIf); |
||
255 | |||
256 | static::registerHermitageDirectives($compiler); |
||
0 ignored issues
–
show
|
|||
257 | } |
||
258 | |||
259 | /** |
||
260 | * @param BladeCompiler $compiler |
||
261 | */ |
||
262 | private static function registerHermitageDirectives($compiler) |
||
263 | { |
||
264 | $simpleDirectives = [ |
||
265 | 'actionAddForIBlock' => 'addForIBlock', |
||
266 | ]; |
||
267 | View Code Duplication | foreach ($simpleDirectives as $directive => $action) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
268 | $compiler->directive($directive, function ($expression) use ($action) { |
||
269 | $expression = rtrim($expression, ')'); |
||
270 | $expression = ltrim($expression, '('); |
||
271 | return '<?php \Arrilot\BitrixHermitage\Action::' . $action . '($template, ' . $expression . '); ?>'; |
||
272 | }); |
||
273 | } |
||
274 | |||
275 | $echoDirectives = [ |
||
276 | 'actionEditIBlockElement' => 'editIBlockElement', |
||
277 | 'actionDeleteIBlockElement' => 'deleteIBlockElement', |
||
278 | 'actionEditAndDeleteIBlockElement' => 'editAndDeleteIBlockElement', |
||
279 | |||
280 | 'actionEditIBlockSection' => 'editIBlockSection', |
||
281 | 'actionDeleteIBlockSection' => 'deleteIBlockSection', |
||
282 | 'actionEditAndDeleteIBlockSection' => 'editAndDeleteIBlockSection', |
||
283 | |||
284 | 'actionEditHLBlockElement' => 'editHLBlockElement', |
||
285 | 'actionDeleteHLBlockElement' => 'deleteHLBlockElement', |
||
286 | 'actionEditAndDeleteHLBlockElement' => 'editAndDeleteHLBlockElement', |
||
287 | ]; |
||
288 | View Code Duplication | foreach ($echoDirectives as $directive => $action) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
289 | $compiler->directive($directive, function ($expression) use ($action) { |
||
290 | $expression = rtrim($expression, ')'); |
||
291 | $expression = ltrim($expression, '('); |
||
292 | return '<?= \Arrilot\BitrixHermitage\Action::' . $action . '($template, ' . $expression . '); ?>'; |
||
293 | }); |
||
294 | } |
||
295 | } |
||
296 | |||
297 | /** |
||
298 | * @return string|null |
||
299 | */ |
||
300 | public static function getCachePath() |
||
301 | { |
||
302 | return static::$cachePath; |
||
303 | } |
||
304 | } |
||
305 |
Let’s assume you have a class which uses late-static binding:
}
The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the
getSomeVariable()
on that sub-class, you will receive a runtime error:In the case above, it makes sense to update
SomeClass
to useself
instead: