Василий Наумкин

Василий Наумкин

Был в сети 10 июня 2026, 17:44
Заказы не принимаю
А вот это я пропустил, спасибо — отключу в новых версиях обязательно.

Суть в том, что пользоваться {$_modx} можно давать кому угодно, он только для чтения, грубо говоря. Тогда как через {$modx} можно легко убить всю систему. По этой же причине и php функции отключены по умолчанию.
Ну вот мы её, наконец-то, и нашли.

У тебя файл .htaccess на 25 килобайт с десятками хитрых правил, которые нужно как-то переписать для Nginx, или забить в компонент
Redirector для MODX. После этого все редиректы вернутся и проблем с SEO больше не будет.

.htaccess работает только в Apache2, Nginx же рассчитан на более высокие нагрузки и не может себе позволить читать дополнительный файл при каждом запросе.
Опять это «к сожалению на modhost установлен nginx», как будто где-то он сегодня не установлен, или на Apache2 такого поведения нет. Приведу ответ Василия из поддержки modhost.pro:

Еще раз — какое отношение к вашей проблеме имеет хостинг? Почтайте, что ли, о ЧПУ. Её суть заключается в том, что запросы, которых реально нет на сервере отправляются на index.php с параметром.

То есть, если на сервере есть файл site.com/filename.txt, то nginx его отдаст сам. А если нет, то будет вызван
/index.php?q=/filename.txt
А дальше уже сам сайт определяет, что отдать на этот запрос — файл, редирект или 404.

Таким образом, при прямом запросе index.php?id=10 friendly urls и редиректы сервера не используются вообще. Движок получает команду показать 10ю страницу и сам её обрабатывает.

Версия MODX 2.2 при этом умела делать редиректы на канонический адрес. Новые версии, почему-то, перестали. Но каким образом за вас это должен исправлять хостинг — я отказываюсь понимать.

Откуда nginx вообще знает, какой именно адрес соответствуют 10 странице в MODX? Это знает только MODX. Ну и откуда у вас на сайте такие ссылки, чтобы к ним обращался поисковик — отдельный вопрос.

И
Покопался еще, и выяснил, что за это отвечает системная настройка request_method_strict, отключенная по умолчанию.

Правда, плагин всё равно лучше, потому что он редиректит куда надо, а настройка просто включает игнорирование неправильных запросов. Но, в любом случае, обвинять хостинг в вашей проблеме не стоит.

В плагине и правда нужно добавить проверку на $modx->context->key != 'mgr', тут я не доглядел.

P.S. Это АнтиСЕО началось с версии 2.3, насколько я могу судить. Это ж тысячи сайтов должны были просесть в выдаче.
Документация у нас открытая, можно редактировать через GitHub.

Допиши, что считаешь нужным, и пришли pull-request. Тогда эта информация добавится на сайте.

Все сетуют на плохую документацию, но никто, почему-то, не хочет её улучшать.
Ну естественно, это мега-тайна, что все ТВ выбираются с префиксом tv. по умолчанию. В документации прям нет этого параметра. includeTVs, prepareTVs, processTVs и дальше пустота.

Можно и не делать пустой &tvPrefix, но тогда, не поверишь, нужно выводить ТВ вот так:
[[+tv.name]] - MODX
{$_pls['tv.name']} - Fenom
Про вывод через точку я тебе давал ссылку еще 2 часа назад.

А вообще, можно увидеть все плейсхолдеры, если просто не указывать чанк.
Да, новый вариант вот такой:
$scriptProperties['where'] = '["
	(Ticket.parent IN ('.$parents.') OR Ticket.show_on_start = 1)
	AND Ticket.hide_on_start = 0 
	AND Ticket.ticket_rating > -2
"]';
Собственно, именно поэтому я и предпочитаю не использовать ТВ вообще. И теперь это вполне возможно, даже без miniShop2.
Ну там монструозненько было, с having и 3500 тикетов. Если интересно, вот старый страшный код:
$scriptProperties['leftJoin'] = json_encode(array(
	'Votes' => array('class' => 'TicketVote', 'on' => 'Votes.id = Ticket.id AND Votes.class = \'Ticket\''),
	'TVshow' => array('class' => 'modTemplateVarResource', 'on' => 'TVshow.contentid = Ticket.id AND TVshow.tmplvarid = 7'),
	'TVhide' => array('class' => 'modTemplateVarResource', 'on' => 'TVhide.contentid = Ticket.id AND TVhide.tmplvarid = 8'),
));
$scriptProperties['select'] = json_encode(array(
	'Votes' => 'SUM(Votes.value) as rating',
	'TVshow' => 'TVshow.value as show',
	'TVhide' => 'TVhide.value as hide',
));
$scriptProperties['having'] = '["rating > -2 OR rating IS NULL"]';
$scriptProperties['where'] = '["(Ticket.parent IN ('.$parents.') OR TVshow.value IS NOT NULL) AND TVhide.value IS NULL"]';
Прикольно, именно так уже какое-то время и фильтруются новости на главной modx.pro. Там есть 2 ТВ параметра: выводить на главной, или скрывать на главной.

При работе с ТВ запрос с фильтрацией по этим 2м ТВ выходил под 0.5 сек, сейчас — 0.06 сек. Мой плагин выглядит вот так:
<?php
switch ($modx->event->name) {
	
	case 'OnMODXInit':
		$modx->loadClass('modResource');
		$modx->map['modResource']['fields']['show_on_start'] =
		$modx->map['modResource']['fields']['hide_on_start'] = 
		$modx->map['modResource']['fields']['ticket_rating'] = 0;
		$modx->map['modResource']['fieldMeta']['show_on_start'] =
		$modx->map['modResource']['fieldMeta']['hide_on_start'] = array(
			'dbtype' => 'tinyint',
			'precision' => 1,
			'attributes' => 'unsigned',
			'phptype' => 'boolean',
			'null' => true,
			'default' => 0,
		);
		$modx->map['modResource']['fieldMeta']['ticket_rating'] = array(
			'dbtype' => 'int',
			'precision' => 10,
			'attributes' => '',
			'phptype' => 'int',
			'null' => true,
			'default' => 0,
		);
		break;
		
		case 'OnBeforeDocFormSave':
			$resource->set('show_on_start', !empty($resource->get('tv7')));
			$resource->set('hide_on_start', !empty($resource->get('tv8')));
			break;
		
		case 'OnTicketVote':
			if ($object->class == 'Ticket') {
				if ($ticket = $modx->getObject('Ticket', $object->id)) {
					$properties = $ticket->getProperties('tickets');
					$rating = !empty($properties['rating'])
						? $properties['rating']
						: 0;
					$ticket->set('ticket_rating', $rating + $object->value);
					$ticket->save();
				}
			}
			break;
}
Ка видите, там еще и сортировка по рейтингу тикетов есть — дарю! OnTicketVote был добавлен в последней версии Tickets.