Fullstack

Fullstack

С нами с 13 апреля 2017; Место в рейтинге пользователей: #123
Fullstack
08 июля 2024, 23:14
0
Да, но многие не знают об этой проблеме и самом наличии альтернативных компонентов.

Но при этом всегда обновляют компоненты у себя в /manager, когда там подсвечивается наличие обновлений (оранжевым).

И я один из них. А таких миллионы. И сайтов таких десятки или сотни тысяч.
Так что обновление необходимо. Чисто патч безопасности
Fullstack
08 июля 2024, 21:28
0
У нас (и не только) такая же проблема. Куча запросов напрямую к `/assets/components/ajaxform/action.php` каждую минуту!

Это потому что прямые вызовы этого скрипта обходят любые валидации и хуки FormIt

… потому что они прописываются лишь в вызовах сниппета, а в action.php отсутствуют. Поэтому когда отправляются нормальные запросы с реальной страницы, всё хорошо, потому что код возвращаемый сниппетом содержит все валидаторы и хуки, которые надо выполнять. А через прямой юз action.php эта логика (валидаторы и хуки) недоступны, поэтому все запросы будут отправлены на сервер без security checks.

AjaxForm просто обязаны сделать фикс этой проблемы даже вопреки нежеланию (как log4j обязан был выпустить обновление своей уязвимости), или принять чей-нибудь фиксящий pull request. Это серьезнейшая дыра в безопасности и очень серьёзная, которую они своей глупостью оставили халатно — там итак было понятно, что валидаторы с хуками будут обходиться, а они понадеялись на авось…
Fullstack
03 мая 2022, 02:04
0
Откопал настройку «phpthumb_allow_src_above_docroot», включил — заработало!
Также нужно очистить кэш MODX и затем очистить кэш браузера. Готово
Fullstack
02 мая 2022, 20:32
0
Вау! Очень круто. Правда в файлах заметил, что там вместо этой настройки используется константа
MODX_CORE_PATH . 'cache/'
, поэтому не знаю, будет ли это работать. А еще придумал несколько других вариантов, возможных благодаря симлинкам, которые хостинг как оказалось поддерживает. То есть я могу просто скопировать папку core для каждого сайта, и сослаться на нее в отправных точках (config.core.php), выбирая ее в зависимости от домена, по которому заходят. Или вообще сделать на каждом нужном сайте симлинк на assets/images (естественно при одинаковых ID надо вынести оттуда галерею ms2). Вариантов куча)
Fullstack
18 января 2022, 19:01
0
Что делать? Лог ошибок пустой

Шаблон:
{include 'head'}
{'footer' | chunk : [ 'goals_mod' => '_dom' ]}
Чанк head:
{'MinifyX' | snippet : [
    'minifyCss' => '0',
    'minifyJs' => '1',
    'registerCss' => 'placeholder',
    'registerJs' => 'placeholder',
    'cssPlaceholder' => 'min_css',
    'jsPlaceholder' => 'min_js',
    'cssSources' => '',
    'jsSources' => '
    	assets/js/script.js
    ' 
]}
Чанк footer:
{'min_js' | placeholder} | {$_modx->getPlaceholder('min_js')} | $min_js
Выводится " | | ". А при первой загрузке страницы все норм.
Fullstack
18 января 2022, 18:27
0
Теперь стало работать. Но плейсхолдеры теперь не кэшируются вообще. Никакие. При первой загрузке страницы работают, а как она закэшировалась — пропадают :(((((
Fullstack
18 января 2022, 02:08
0
Короче да. Fenom-шаблон скомпилировался и закэшировался. Меняю значение только в сниппете — шаблон реагирует так же, как и до этого, что в сниппете ни выставляй.

Видимо условие закэшировалось вместе с шаблоном с тем значением, которое попало в кэш первый раз.
Нужен некэшируемый вывод плейсхолдера, как в стандартном MODX: [[!+placeholder]]
Fullstack
18 января 2022, 01:57
0
Более того!

Задаю внутри сниппета плейсхолдер
$modx->setPlaceholder('ttt', 'b');
Вывожу его на странице:
{if $_modx->getPlaceholder('ttt') == 'a'}
    <script>alert('ttt = a');</script>
{else}
    <script>alert('ttt else');</script>
{/if}
И у меня постоянно выводится, что «ttt = a» (вместо «ttt else»),
хотя я задаю значение плейсхолдера «b», а не «a».
Fullstack
18 января 2022, 00:33
0
Блин, из-за вставленного кода в данный топик в самом его начале (в первом посте), не могу изменить этот пост… Верстка modx.pro едет.

Вставлю сюда обновленный код:

fenom.php:
<?php
	header('Content-type: text/html; charset=utf-8');
	$r = '';
	if (isset($_POST['modx'])) {
		/*function process_params($p) {
			$r = preg_replace('/\&([A-Za-z0-9а-яА-ЯёЁ_\-]+)(\r\n\t\s)?\=(\r\n\t\s)?\`(.*?)\`(.*?)/u', '\'\\1\' => \'\\4\',\\5', $p);
			return $r;
		}
		function process_chunk($m) {
			$r = '{include \''.$m[1].'\'';
			if (isset($m[2])) {
				$p = ltrim($m[2]);
				if (isset($p[0]) && $p[0] == '?')
					$r .= ' : ['.process_params(substr($p[0], 1)).']';
			}
			return $r.'}';
		}
		function process_snippet($m) {
			if (empty($m) || !isset($m[1])) return false;
			$r = '{\''.$m[1].'\' | snippet';
			if (isset($m[2])) {
				$p = ltrim($m[2]);
				if (isset($p[0]) && $p[0] == '?')
					$r .= ' : ['.process_params(substr($p[0], 1)).']';
			}
			return $r.'}';
		}
		function process_tv($m) {
			return false;
		}
		function process_link($m) {
			return false;
		}
		function process_lang($m) {
			return false;
		}
		function process_setting($m) {
			return false;
		}
		function process_placeholder($m) {
			return false;
		}
		function convert($matches) {
			$m = $matches[1];
			$r = null;
			if ($m[0] == '-')
				return '{*'.substr($m, 1).'*}';

			$r = preg_replace('/\&([a-zA-Zа-яА-ЯёЁ0-9_\-\.]+)(.*?)\=(.*?)\`(.*?)\`/u', '\'\1\'\2 => \3\'\4\',', $m);

			if ($m[0] == '+') {
				if ($m[1] == '+') $r = preg_replace_callback('/^([a-zA-Zа-яА-ЯёЁ0-9_\-\.]+)(.*?)/u', 'process_setting', substr($m, 2));
				else $r = preg_replace_callback('/^([a-zA-Zа-яА-ЯёЁ0-9_\-\.]+)(.*?)/u', 'process_placeholder', substr($m, 1));
			}
			else if ($m[0] == '*') {
				$r = preg_replace_callback('/^([a-zA-Zа-яА-ЯёЁ0-9_\-\.]+)(.*?)/u', 'process_tv', substr($m, 1));
			}
			else if ($m[0] == '%') {
				$r = preg_replace_callback('/^([a-zA-Zа-яА-ЯёЁ0-9_\-\.]+)(.*?)/u', 'process_lang', substr($m, 1));
			}
			else if ($m[0] == '~') {
				$r = preg_replace_callback('/^([a-zA-Zа-яА-ЯёЁ0-9_\-\.]+)(.*?)/u', 'process_link', substr($m, 1));
			}
			else if ($m[0] == '$') {
				$r = preg_replace_callback('/^([a-zA-Zа-яА-ЯёЁ0-9_\-\.]+)(.*?)/u', 'process_chunk', substr($m, 1));
			}
			else {
				$snippet = preg_replace_callback('/^(\!?[a-zA-Zа-яА-ЯёЁ0-9_\-\.]+)(.*?)/u', 'process_snippet', $m);
				if ($snippet) $r = $snippet;
			}

			return $r ? $r : ($m ? '[['.$m.']]' : $matches[0]);
		}
		$r = preg_replace_callback('/\[\[(.*?)\]\]/u', 'convert', $_POST['modx']);*/

		$r = $_POST['modx'];
		//$r = mb_convert_encoding($_POST['modx'], 'utf-8', mb_detect_encoding($r));

		// [[- Комментарий ]]
		$r = mb_ereg_replace('\[\[\-(.*?)\]\]', '{*\1*}', $r);
		// [[~URL]]
		$r = mb_ereg_replace('\[\[\~([0-9]+)\]\]', '{\1 | url}', $r);
		// [[%язык]]
		$r = mb_ereg_replace('\[\[\%([a-zA-Z0-9\._]+)\]\]', '{$_modx->lexicon(\'\1\')}', $r);
		// [[++системная_настройка]]
		$r = mb_ereg_replace('\[\[\+\+([a-zA-Z0-9\._]+)\]\]', '{\'\1\' | option}', $r);
		// [[+плейс.холдер]]
		$r = mb_ereg_replace('\[\[(\!)?\+([a-zA-Z0-9\._]+\.[a-zA-Z0-9\._]+)\]\]', '{$_pls[\'\2\']}', $r);
		// [[+плейсхолдер]]
		$r = mb_ereg_replace('\[\[(\!)?\+([a-zA-Z0-9\._]+)\]\]', '{$\2}', $r);
		// [[*поле_ресурса]]
		$r = mb_ereg_replace('\[\[\*([a-zA-Z0-9\._]+)\]\]', '{$_modx->resource.\1}', $r);
		// [[$чанк]]
		$r = mb_ereg_replace('\[\[\$([a-zA-Z0-9\._]+)\]\]', '{include \'\1\'}', $r);
		$r = mb_ereg_replace('\[\[\$([a-zA-Z0-9\._]+)\?', '{\'\1\' | chunk : [', $r);
		// [[сниппет]]
		$r = mb_ereg_replace('\[\[(\!)?([a-zA-Z0-9\._]+)\]\]', '{\'\1\2\' | snippet}', $r);
		$r = mb_ereg_replace('\[\[(\!)?([a-zA-Z0-9\._]+)\?', '{\'\1\2\' | snippet : [', $r);
		// &параметр=`значение`
		$r = mb_ereg_replace('\&([a-zA-Z0-9\._]+)=`?([^\[\]\&]+)`', '\'\1\' => \'\2\',', $r);
		$r = str_replace('=> \'`\'', '=> \'\'', $r);
		$r = mb_ereg_replace('\',([\r\n\s\t]+)?\]\]', '\' \1]}', $r);
		//$r = mb_ereg_replace('\=\> \'(.*?)\'\]\}', '=> \'\1\' ]}', $r);

		$r = str_replace('&', '&', $r);
	}
?><!DOCTYPE html>
<html lang="ru">
<head>
	<meta charset="utf-8">
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>MODX to Fenom</title>
	<meta name="robots" content="noindex, nofollow">
</head>
<body style="padding: 20px; margin: 0; font: 12px/normal 'SFMono-Regular','Menlo','Consolas','Liberation Mono','Courier New',monospace;">
	<style>
		textarea { width: 100%; height: 500px; font: inherit; }
	</style>
	<form action="" method="post">
		<textarea name="modx"><?php echo ''; echo str_replace('&', '&', isset($_POST['modx']) ? $_POST['modx'] :
'[[$chunk_name]]
[[$asd? ¶m=`value`]]
[[$asd?
	¶m=`Hello`
	&a_s_d=`ыфавыавыа`
]]

[[!+ph]]
[[!+place.holder]]

[[*parent]]
[[*template:is=`3`:then=`a`:else=`b`]]

[[- comment ]]

[[!uncached]]
[[cached]]
[[phpcode? ¶m=`Значение`]]
[[!snipp?
	¶m=`Привет`
	&PARAM=`Здравствуй`
]]

[[~123]]
[[%lang_var]]'); ?></textarea>
		<button type="submit">Конвертировать</button>
	</form>
	<?php
		if ($r) echo '
<hr>
<textarea>' . $r . '</textarea>';
	?>
</body>
</html>


Вместо странного символа должен быть знак & (амперсанда)
Fullstack
17 января 2022, 22:49
0
В принципе у меня начало получаться новым путем делать мой конвертер. Еще предстоят работы, но вот это уже неплохо так действует:

$r = $_POST['modx'];
//$r = mb_convert_encoding($_POST['modx'], 'utf-8', mb_detect_encoding($r));

// [[- Комментарий ]]
$r = mb_ereg_replace('\[\[\-(.*?)\]\]', '{*\1*}', $r);
// [[~URL]]
$r = mb_ereg_replace('\[\[\~([0-9]+)\]\]', '{\1 | url}', $r);
// [[++системная_настройка]]
$r = mb_ereg_replace('\[\[\+\+([a-zA-Z0-9\._]+)\]\]', '{\'\1\' | option}', $r);
// [[+плейс.холдер]]
$r = mb_ereg_replace('\[\[(\!)?\+([a-zA-Z0-9\._]+\.[a-zA-Z0-9\._]+)\]\]', '{$_pls[\'\2\']}', $r);
// [[+плейсхолдер]]
$r = mb_ereg_replace('\[\[(\!)?\+([a-zA-Z0-9\._]+)\]\]', '{$\2}', $r);
// [[$чанк]]
$r = mb_ereg_replace('\[\[\$([a-zA-Z0-9\._]+)\]\]', '{include \'\1\'}', $r);
$r = mb_ereg_replace('\[\[\$([a-zA-Z0-9\._]+)\?', '{\'\1\' | chunk : [', $r);
// &параметр=`значение`
$r = mb_ereg_replace('\&([a-zA-Z0-9\._]+)=`?([^\[\]\&]+)`', '\'\1\' => \'\2\',', $r);
$r = str_replace('=> \'`\'', '=> \'\'', $r);
$r = mb_ereg_replace('\',([\r\n\s\t]+)?\]\]', '\'\1]}', $r);
$r = mb_ereg_replace('\=\> \'(.*?)\'\]\}', '=> \'\1\' ]}', $r);

$r = str_replace('&', '&', $r);
Fullstack
17 января 2022, 21:03
0
Уже лучше, супер! Нужны маленькие доработочки:

Иногда нужны пустые параметры, они вырезаются:


Ссылки вида [[~123]] не конвертируются.

Параметры сниппетов и чанков Fenom было бы лучше конвертировать с одинарными кавычками ' вместо двойных ".

Параметры [[+modx_setting]] должны преобразовываться в {'modx_setting' | option}.

Плейсхолдеры надо не {'pholder' | placeholder}, а просто {$pholder}, но если в его имени есть точки, то {$_pls['pholder']}.

Также было бы круто, чтобы можно было вставлять целый HTML-шаблон с тегами MODX и чтобы конвертировались только они, а не вставлять каждое по отдельности

Если есть: конструкции=`условий`, то просто писать о их наличии (и номерах строк), но не блокировать все конвертирование.
Fullstack
17 января 2022, 20:24
0
Плейсы в микс-режиме это проблема, да.
Срабатывают только при первой загрузке страницы, а потом пропадают…
Fullstack
13 января 2022, 17:59
0
Круто! Единственное, он преобразует только сниппеты
Fullstack
13 января 2022, 17:57
+1
Он не на всех сайтах применим. На простых — да. А что-то более менее гибкое уже не разработаешь. Или когда стоит (особенно ребром) вопрос скорости сайта
Fullstack
09 января 2022, 03:28
0
Хотя сейчас пришла мысль, как сделать подход полегче:

1. Заменяем сначала чисто все &параметры=…
2. Потом заменяем названия сниппетов, чанков и т.д. на Fenom'овские
3. Заменяем все ]] на }

А вот с условиями надо пока подумать… О них бы просто сообщать (например номер строки), а дальше они бы уже вручную менялись. Так как их автоматизация не так уж целесообразна. Если нет условных модификаторов, то обрабатываем. Если есть условные модификаторы — пишем об этом в результате конвертации
Fullstack
21 октября 2021, 21:02
0
Не мешайте Fenom с обычным шаблонизатором, иначе от Fenom будет не оптимизация, а наоборот нагрузка (т.к. Fenom срабатывает как лишний шаблонизатор, потому что запустился стандартный)
Fullstack
27 февраля 2021, 23:06
+1
Не мог написать в «Готовые решения» из-за недостаточного рейтинга.
Но скрипт очень нужный, чтобы им не поделиться.
Просто проверьте, что тут ничего такого нет.
И переместите в нужный раздел =)
Спасибо
Fullstack
20 февраля 2021, 22:21
0
А, и для поддержки пробелов надо еще второе упоминание $_GET['tag'] заменить на
str_replace('%20', ' ', $_GET['tag'])

Получится вот такой сниппет:

if ($_GET['tag']) {
	$tag = preg_replace('/[^A-Za-zА-Яа-яЁё0-9_\- ]+/ui', '', str_replace('%20', ' ', $_GET['tag']));
    //$tag = 'tags==%' . $tag . '%';
}

return $tag;

urldecode заранее не рекомендую.
Fullstack
20 февраля 2021, 21:54
0
Для того, чтобы она была, надо убрать
&tvFilters=`[[!getTag]]`
и сделать
&where=`["CONCAT(',', TVtags.value, ',') LIKE '%,[[!getTag]],%'"]`
и добавить TV-поле с тегами (в данном примере tags) также в &includeTVs.

А в моем обезопашенном сниппете getTag закомментировать эту строчку:
// $tag = 'tags==%' . $tag . '%';
Fullstack
20 февраля 2021, 21:34
0
И привет, инъекция :)
Лучше хотя бы так
<?php

if ($_GET['tag']) {
	$tag = preg_replace('/[^A-Za-zА-Яа-яЁё0-9_\- ]+/ui', '', $_GET['tag']);
    $tag = 'tags==%' . $tag . '%';
}

return $tag;
А так тут нет проверки на точность тега (надо учитывать точные значения между запятыми у тегов)