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 EMT\Tret; |
||
4 | |||
5 | use EMT\Util; |
||
6 | |||
7 | /** |
||
8 | * Базовый класс для группы правил обработки текста |
||
9 | * Класс группы должен наследовать, данный класс и задавать |
||
10 | * в нём EMT_Tret::rules и EMT_Tret::$name |
||
11 | * |
||
12 | */ |
||
13 | abstract class AbstractTret |
||
14 | { |
||
15 | /** |
||
16 | * Набор правил в данной группе, который задан изначально |
||
17 | * Его можно менять динамически добавляя туда правила с помощью put_rule |
||
18 | * |
||
19 | * @var array |
||
20 | */ |
||
21 | public $rules; |
||
22 | public $title; |
||
23 | public $logging = false; |
||
24 | public $logs = false; |
||
25 | public $errors = false; |
||
26 | public $debug_enabled = false; |
||
27 | public $debug_info = array(); |
||
28 | public $class_names = array(); |
||
29 | public $classes = array(); |
||
30 | public $settings = array(); |
||
31 | |||
32 | private $disabled = array(); |
||
33 | private $enabled = array(); |
||
34 | private $use_layout = false; |
||
35 | private $use_layout_set = false; |
||
36 | private $class_layout_prefix = false; |
||
37 | |||
38 | protected $_text = ''; |
||
39 | |||
40 | /** |
||
41 | * Защищенные теги |
||
42 | * |
||
43 | * @todo привязать к методам из Jare_Typograph_Tool |
||
44 | */ |
||
45 | const BASE64_PARAGRAPH_TAG = 'cA==='; // p |
||
46 | const BASE64_BREAKLINE_TAG = 'YnIgLw==='; // br / (с пробелом и слэшем) |
||
47 | const BASE64_NOBR_OTAG = 'bm9icg==='; // nobr |
||
48 | const BASE64_NOBR_CTAG = 'L25vYnI=='; // /nobr |
||
49 | |||
50 | /** |
||
51 | * Типы кавычек |
||
52 | */ |
||
53 | const QUOTE_FIRS_OPEN = '«'; |
||
54 | const QUOTE_FIRS_CLOSE = '»'; |
||
55 | const QUOTE_CRAWSE_OPEN = '„'; |
||
56 | const QUOTE_CRAWSE_CLOSE = '“'; |
||
57 | |||
58 | private function log($str, $data = null) |
||
59 | { |
||
60 | if (!$this->logging) return; |
||
61 | $this->logs[] = array('info' => $str, 'data' => $data); |
||
62 | } |
||
63 | |||
64 | /** |
||
65 | * @param string $info |
||
66 | */ |
||
67 | private function error($info, $data = null) |
||
68 | { |
||
69 | $this->errors[] = array('info' => $info, 'data' => $data); |
||
70 | $this->log('ERROR: ' . $info, $data); |
||
71 | } |
||
72 | |||
73 | public function debug($place, &$after_text) |
||
74 | { |
||
75 | if (!$this->debug_enabled) return; |
||
76 | $this->debug_info[] = array( |
||
77 | 'place' => $place, |
||
78 | 'text' => $after_text, |
||
79 | ); |
||
80 | } |
||
81 | |||
82 | /** |
||
83 | * Установить режим разметки для данного Трэта если не было раньше установлено, |
||
84 | * Util::LAYOUT_STYLE - с помощью стилей |
||
85 | * Util::LAYOUT_CLASS - с помощью классов |
||
86 | * |
||
87 | */ |
||
88 | public function set_tag_layout_ifnotset($layout) |
||
89 | { |
||
90 | if ($this->use_layout_set) return; |
||
91 | $this->use_layout = $layout; |
||
92 | } |
||
93 | |||
94 | /** |
||
95 | * Установить режим разметки для данного Трэта, |
||
96 | * Util::LAYOUT_STYLE - с помощью стилей |
||
97 | * Util::LAYOUT_CLASS - с помощью классов |
||
98 | * Util::LAYOUT_STYLE|Util::LAYOUT_CLASS - оба метода |
||
99 | * |
||
100 | */ |
||
101 | public function set_tag_layout($layout = Util::LAYOUT_STYLE) |
||
102 | { |
||
103 | $this->use_layout = $layout; |
||
104 | $this->use_layout_set = true; |
||
105 | } |
||
106 | |||
107 | public function set_class_layout_prefix($prefix) |
||
108 | { |
||
109 | $this->class_layout_prefix = $prefix; |
||
110 | } |
||
111 | |||
112 | public function debug_on() |
||
113 | { |
||
114 | $this->debug_enabled = true; |
||
115 | } |
||
116 | |||
117 | public function log_on() |
||
118 | { |
||
119 | $this->debug_enabled = true; |
||
120 | } |
||
121 | |||
122 | private function getmethod($name) |
||
123 | { |
||
124 | if (!$name) return false; |
||
125 | if (!method_exists($this, $name)) return false; |
||
126 | |||
127 | return array($this, $name); |
||
128 | } |
||
129 | |||
130 | View Code Duplication | private function _pre_parse() |
|
0 ignored issues
–
show
|
|||
131 | { |
||
132 | $this->pre_parse(); |
||
133 | foreach ($this->rules as $rule) { |
||
134 | if (!isset($rule['init'])) continue; |
||
135 | $m = $this->getmethod($rule['init']); |
||
136 | if (!$m) continue; |
||
137 | call_user_func($m); |
||
138 | } |
||
139 | } |
||
140 | |||
141 | View Code Duplication | private function _post_parse() |
|
0 ignored issues
–
show
This method seems to be duplicated in 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. ![]() |
|||
142 | { |
||
143 | foreach ($this->rules as $rule) { |
||
144 | if (!isset($rule['deinit'])) continue; |
||
145 | $m = $this->getmethod($rule['deinit']); |
||
146 | if (!$m) continue; |
||
147 | call_user_func($m); |
||
148 | } |
||
149 | $this->post_parse(); |
||
150 | } |
||
151 | |||
152 | private function rule_order_sort($a, $b) |
||
153 | { |
||
154 | if ($a['order'] == $b['order']) return 0; |
||
155 | if ($a['order'] < $b['order']) return -1; |
||
156 | |||
157 | return 1; |
||
158 | } |
||
159 | |||
160 | private function apply_rule($rule) |
||
161 | { |
||
162 | $name = $rule['id']; |
||
163 | //$this->log("Правило $name", "Применяем правило"); |
||
164 | $disabled = (isset($this->disabled[$rule['id']]) && $this->disabled[$rule['id']]) || ((isset($rule['disabled']) && $rule['disabled']) && !(isset($this->enabled[$rule['id']]) && $this->enabled[$rule['id']])); |
||
165 | if ($disabled) { |
||
166 | $this->log("Правило $name", "Правило отключено" . ((isset($rule['disabled']) && $rule['disabled']) ? " (по умолчанию)" : "")); |
||
167 | |||
168 | return; |
||
169 | } |
||
170 | if (isset($rule['function']) && $rule['function']) { |
||
171 | if (!(isset($rule['pattern']) && $rule['pattern'])) { |
||
172 | View Code Duplication | if (method_exists($this, $rule['function'])) { |
|
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. ![]() |
|||
173 | $this->log("Правило $name", "Используется метод " . $rule['function'] . " в правиле"); |
||
174 | |||
175 | call_user_func(array($this, $rule['function'])); |
||
176 | |||
177 | return; |
||
178 | } |
||
179 | View Code Duplication | if (function_exists($rule['function'])) { |
|
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. ![]() |
|||
180 | $this->log("Правило $name", "Используется функция " . $rule['function'] . " в правиле"); |
||
181 | |||
182 | call_user_func($rule['function']); |
||
183 | |||
184 | return; |
||
185 | } |
||
186 | |||
187 | $this->error('Функция ' . $rule['function'] . ' из правила ' . $rule['id'] . " не найдена"); |
||
188 | |||
189 | return; |
||
190 | } else { |
||
191 | if (preg_match("/^[a-z_0-9]+$/i", $rule['function'])) { |
||
192 | View Code Duplication | if (method_exists($this, $rule['function'])) { |
|
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. ![]() |
|||
193 | $this->log("Правило $name", "Замена с использованием preg_replace_callback с методом " . $rule['function'] . ""); |
||
194 | |||
195 | $this->_text = preg_replace_callback($rule['pattern'], array($this, $rule['function']), $this->_text); |
||
196 | |||
197 | return; |
||
198 | } |
||
199 | View Code Duplication | if (function_exists($rule['function'])) { |
|
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. ![]() |
|||
200 | $this->log("Правило $name", "Замена с использованием preg_replace_callback с функцией " . $rule['function'] . ""); |
||
201 | |||
202 | $this->_text = preg_replace_callback($rule['pattern'], $rule['function'], $this->_text); |
||
203 | |||
204 | return; |
||
205 | } |
||
206 | $this->error('Функция ' . $rule['function'] . ' из правила ' . $rule['id'] . " не найдена"); |
||
207 | } else { |
||
208 | $this->_text = preg_replace_callback($rule['pattern'], create_function('$m', $rule['function']), $this->_text); |
||
209 | $this->log('Замена с использованием preg_replace_callback с инлайн функцией из правила ' . $rule['id']); |
||
210 | |||
211 | return; |
||
212 | } |
||
213 | |||
214 | return; |
||
215 | } |
||
216 | } |
||
217 | |||
218 | if (isset($rule['simple_replace']) && $rule['simple_replace']) { |
||
219 | if (isset($rule['case_sensitive']) && $rule['case_sensitive']) { |
||
220 | $this->log("Правило $name", "Простая замена с использованием str_replace"); |
||
221 | $this->_text = str_replace($rule['pattern'], $rule['replacement'], $this->_text); |
||
222 | |||
223 | return; |
||
224 | } |
||
225 | $this->log("Правило $name", "Простая замена с использованием str_ireplace"); |
||
226 | $this->_text = str_ireplace($rule['pattern'], $rule['replacement'], $this->_text); |
||
227 | |||
228 | return; |
||
229 | } |
||
230 | |||
231 | $pattern = $rule['pattern']; |
||
232 | if (is_string($pattern)) $pattern = array($pattern); |
||
233 | $eval = false; |
||
234 | foreach ($pattern as $patt) { |
||
235 | $chr = substr($patt, 0, 1); |
||
236 | $preg_arr = explode($chr, $patt); |
||
237 | if (strpos($preg_arr[count($preg_arr) - 1], "e") !== false) { |
||
238 | $eval = true; |
||
239 | break; |
||
240 | } |
||
241 | } |
||
242 | if (!$eval) { |
||
243 | $this->log("Правило $name", "Замена с использованием preg_replace"); |
||
244 | |||
245 | do { |
||
246 | $this->_text = preg_replace($rule['pattern'], $rule['replacement'], $this->_text); |
||
247 | if (!(isset($rule['cycled']) && $rule['cycled'])) break; |
||
248 | } while (preg_match($rule['pattern'], $this->_text)); |
||
249 | |||
250 | return; |
||
251 | } |
||
252 | |||
253 | $this->log("Правило $name", "Замена с использованием preg_replace_callback вместо eval"); |
||
254 | $k = 0; |
||
255 | foreach ($pattern as $patt) { |
||
256 | $repl = is_string($rule['replacement']) ? $rule['replacement'] : $rule['replacement'][$k]; |
||
257 | |||
258 | $chr = substr($patt, 0, 1); |
||
259 | $preg_arr = explode($chr, $patt); |
||
260 | if (strpos($preg_arr[count($preg_arr) - 1], "e") !== false) { // eval система |
||
261 | $preg_arr[count($preg_arr) - 1] = str_replace("e", "", $preg_arr[count($preg_arr) - 1]); |
||
262 | $patt = implode($chr, $preg_arr); |
||
263 | $this->thereplacement = $repl; |
||
264 | View Code Duplication | do { |
|
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. ![]() |
|||
265 | $this->_text = preg_replace_callback($patt, array($this, "thereplcallback"), $this->_text); |
||
266 | if (!(isset($rule['cycled']) && $rule['cycled'])) break; |
||
267 | } while (preg_match($patt, $this->_text)); |
||
268 | |||
269 | } else { |
||
270 | View Code Duplication | do { |
|
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. ![]() |
|||
271 | $this->_text = preg_replace($patt, $repl, $this->_text); |
||
272 | if (!(isset($rule['cycled']) && $rule['cycled'])) break; |
||
273 | } while (preg_match($patt, $this->_text)); |
||
274 | } |
||
275 | $k++; |
||
276 | } |
||
277 | } |
||
278 | |||
279 | /** |
||
280 | * @param string $pattern |
||
281 | * @param string $replacement |
||
282 | */ |
||
283 | protected function preg_replace_e($pattern, $replacement, $text) |
||
284 | { |
||
285 | $chr = substr($pattern, 0, 1); |
||
286 | $preg_arr = explode($chr, $pattern); |
||
287 | if (strpos($preg_arr[count($preg_arr) - 1], "e") === false) return preg_replace($pattern, $replacement, $text); |
||
288 | $preg_arr[count($preg_arr) - 1] = str_replace("e", "", $preg_arr[count($preg_arr) - 1]); |
||
289 | $patt = implode($chr, $preg_arr); |
||
290 | $this->thereplacement = $replacement; |
||
291 | |||
292 | return preg_replace_callback($patt, array($this, "thereplcallback"), $text); |
||
293 | } |
||
294 | |||
295 | private $thereplacement = ""; |
||
296 | |||
297 | private function thereplcallback($m) |
||
0 ignored issues
–
show
|
|||
298 | { |
||
299 | $x = ""; |
||
300 | eval('$x = ' . ($this->thereplacement ? $this->thereplacement : '""') . ';'); |
||
301 | |||
302 | return $x; |
||
303 | } |
||
304 | |||
305 | private function _apply($list) |
||
306 | { |
||
307 | $this->errors = array(); |
||
0 ignored issues
–
show
It seems like
array() of type array is incompatible with the declared type boolean of property $errors .
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. ![]() |
|||
308 | $this->_pre_parse(); |
||
309 | |||
310 | $this->log("Применяется набор правил", implode(",", $list)); |
||
311 | |||
312 | $rulelist = array(); |
||
313 | foreach ($list as $k) { |
||
314 | $rule = $this->rules[$k]; |
||
315 | $rule['id'] = $k; |
||
316 | $rule['order'] = isset($rule['order']) ? $rule['order'] : 5; |
||
317 | $rulelist[] = $rule; |
||
318 | } |
||
319 | //usort($rulelist, array($this, "rule_order_sort")); |
||
320 | |||
321 | foreach ($rulelist as $rule) { |
||
322 | $this->apply_rule($rule); |
||
323 | $this->debug($rule['id'], $this->_text); |
||
324 | } |
||
325 | |||
326 | $this->_post_parse(); |
||
327 | } |
||
328 | |||
329 | /** |
||
330 | * Создание защищенного тега с содержимым |
||
331 | * |
||
332 | * @see EMT_lib::build_safe_tag |
||
333 | * @param string $content |
||
334 | * @param string $tag |
||
335 | * @param array $attribute |
||
336 | * @return string |
||
337 | */ |
||
338 | protected function tag($content, $tag = 'span', $attribute = array()) |
||
339 | { |
||
340 | if (isset($attribute['class'])) { |
||
341 | $classname = $attribute['class']; |
||
342 | if ($classname == "nowrap") { |
||
343 | if (!$this->is_on('nowrap')) { |
||
344 | $tag = "nobr"; |
||
345 | $attribute = array(); |
||
346 | $classname = ""; |
||
347 | } |
||
348 | } |
||
349 | if (isset($this->classes[$classname])) { |
||
350 | $style_inline = $this->classes[$classname]; |
||
351 | if ($style_inline) $attribute['__style'] = $style_inline; |
||
352 | } |
||
353 | $classname = (isset($this->class_names[$classname]) ? $this->class_names[$classname] : $classname); |
||
354 | $classname = ($this->class_layout_prefix ? $this->class_layout_prefix : "") . $classname; |
||
355 | $attribute['class'] = $classname; |
||
356 | } |
||
357 | |||
358 | return Util::build_safe_tag($content, $tag, $attribute, |
||
359 | $this->use_layout === false ? Util::LAYOUT_STYLE : $this->use_layout); |
||
360 | } |
||
361 | |||
362 | /** |
||
363 | * Добавить правило в группу |
||
364 | * |
||
365 | * @param string $name |
||
366 | * @param array $params |
||
367 | */ |
||
368 | public function put_rule($name, $params) |
||
369 | { |
||
370 | $this->rules[$name] = $params; |
||
371 | |||
372 | return $this; |
||
373 | } |
||
374 | |||
375 | /** |
||
376 | * Отключить правило, в обработке |
||
377 | * |
||
378 | * @param string $name |
||
379 | */ |
||
380 | public function disable_rule($name) |
||
381 | { |
||
382 | $this->disabled[$name] = true; |
||
383 | unset($this->enabled[$name]); |
||
384 | } |
||
385 | |||
386 | /** |
||
387 | * Включить правило |
||
388 | * |
||
389 | * @param string $name |
||
390 | */ |
||
391 | public function enable_rule($name) |
||
392 | { |
||
393 | $this->enabled[$name] = true; |
||
394 | unset($this->disabled[$name]); |
||
395 | } |
||
396 | |||
397 | /** |
||
398 | * Добавить настройку в трет |
||
399 | * |
||
400 | * @param string $key ключ |
||
401 | * @param mixed $value значение |
||
402 | */ |
||
403 | public function set($key, $value) |
||
404 | { |
||
405 | $this->settings[$key] = $value; |
||
406 | } |
||
407 | |||
408 | /** |
||
409 | * Установлена ли настройка |
||
410 | * |
||
411 | * @param string $key |
||
412 | */ |
||
413 | View Code Duplication | public function is_on($key) |
|
0 ignored issues
–
show
This method seems to be duplicated in 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. ![]() |
|||
414 | { |
||
415 | if (!isset($this->settings[$key])) return false; |
||
416 | $kk = $this->settings[$key]; |
||
417 | |||
418 | return ((strtolower($kk) == "on") || ($kk === "1") || ($kk === true) || ($kk === 1)); |
||
419 | } |
||
420 | |||
421 | /** |
||
422 | * Получить строковое значение настройки |
||
423 | * |
||
424 | * @param unknown_type $key |
||
425 | * @return string |
||
426 | */ |
||
427 | public function ss($key) |
||
428 | { |
||
429 | if (!isset($this->settings[$key])) return ""; |
||
430 | |||
431 | return strval($this->settings[$key]); |
||
432 | } |
||
433 | |||
434 | /** |
||
435 | * Добавить настройку в правило |
||
436 | * |
||
437 | * @param string $rulename идентификатор правила |
||
438 | * @param string $key ключ |
||
439 | * @param mixed $value значение |
||
440 | */ |
||
441 | public function set_rule($rulename, $key, $value) |
||
442 | { |
||
443 | $this->rules[$rulename][$key] = $value; |
||
444 | } |
||
445 | |||
446 | /** |
||
447 | * Включить правила, согласно списку |
||
448 | * |
||
449 | * @param array $list список правил |
||
450 | * @param boolean $disable выкллючить их или включить |
||
451 | * @param boolean $strict строго, т.е. те которые не в списку будут тоже обработаны |
||
452 | */ |
||
453 | public function activate($list, $disable = false, $strict = true) |
||
454 | { |
||
455 | if (!is_array($list)) return; |
||
456 | |||
457 | foreach ($list as $rulename) { |
||
458 | if ($disable) $this->disable_rule($rulename); else $this->enable_rule($rulename); |
||
459 | } |
||
460 | |||
461 | if ($strict) { |
||
462 | foreach ($this->rules as $rulename => $v) { |
||
463 | if (in_array($rulename, $list)) continue; |
||
464 | if (!$disable) $this->disable_rule($rulename); else $this->enable_rule($rulename); |
||
465 | } |
||
466 | } |
||
467 | } |
||
468 | |||
469 | public function set_text(&$text) |
||
470 | { |
||
471 | $this->_text = & $text; |
||
472 | $this->debug_info = array(); |
||
473 | $this->logs = array(); |
||
0 ignored issues
–
show
It seems like
array() of type array is incompatible with the declared type boolean of property $logs .
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. ![]() |
|||
474 | } |
||
475 | |||
476 | /** |
||
477 | * Применить к тексту |
||
478 | * |
||
479 | * @param mixed $list - список правил, null - все правила |
||
480 | * @return string |
||
481 | */ |
||
482 | public function apply($list = null) |
||
483 | { |
||
484 | if (is_string($list)) $rlist = array($list); |
||
485 | elseif (is_array($list)) $rlist = $list; |
||
486 | else $rlist = array_keys($this->rules); |
||
487 | $this->_apply($rlist); |
||
488 | |||
489 | return $this->_text; |
||
490 | } |
||
491 | |||
492 | /** |
||
493 | * Код, выполняем до того, как применить правила |
||
494 | * |
||
495 | */ |
||
496 | public function pre_parse() |
||
497 | { |
||
498 | } |
||
499 | |||
500 | /** |
||
501 | * После выполнения всех правил, выполняется этот метод |
||
502 | * |
||
503 | */ |
||
504 | public function post_parse() |
||
505 | { |
||
506 | } |
||
507 | |||
508 | } |
||
509 |
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.