Максим Кузнецов

Максим Кузнецов

Был в сети 04 августа 2021, 21:51
Заказы принимаю
На fenom-е посимпатичнее будет:

{foreach $_modx->resource.pagetitle | split : ' ' as $pagetitle_word}
	{if $pagetitle_word | length > 3}
		{var $words[] = $pagetitle_word}
	{/if}
{/foreach}

{set $random_word_position = rand(1, $words| length)}
{set $random_word = $words[$random_word_position - 1]}

{$_modx->runSnippet('!msProducts', [
	'parent' => $_modx->resource.parent,
	'resources' => -$_modx->resource.id,
	'where' => '{
		"pagetitle:LIKE": "%' ~ $random_word ~ '%"
	}',
	...
])}
*пожал плечами* В данной задаче нельзя выиграть во всем сразу — весь вопрос в том, что для вас в приоритете:

— если вам критично сохранить исходную логику подсчета просмотров (которая, как уже ответил
выше Сергей, скорее визиты), то можно записывать результат в отдельное поле по крону и выводить его значение, или же кэшировать сниппет. Но это не спасет от разбухания базы

— если критично уменьшить размер БД, то можно попробовать создавать для каждого тикета лишь по 1 записи, в которой будут перечислены id всех пользователей, которые просмотрели тикет. Но в таком случае отпадут гостевые просмотры.

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

Как вариант — по крону пробегаться по tickets_views, считая count на данный момент и, перенеся полученный результат в отдельное поле, очищать таблицу. При последующих срабатываниях — приплюсовывать результат.
Да, к слову по вышестоящему коду — на случай, если у вас на сайте подразумевается возможность повторной активации (активация-деактивация-активация), нужно сделать дополнительную проверку на существование ресурса.
Примерно так:

<?php
	if ($modx->event->name == 'OnUserActivate') {
		if ($user) {
			if ($profile = $user->getOne('Profile')) {
				$user_id = $user->get('id');
				$fullname = $profile->get('fullname');

				$parent = 'айди_раздела_с_тикетами';
				$template = 'шаблон';
				
				if (isset($parent)) {
					/* Формируем uri по айди автора */
					$parent_alias = $modx->getObject('modDocument', $parent)->get('alias');
					$parent_alias .= '/' . $user_id;
					
					$ticket = $modx->newObject('modDocument');
					
					$ticket->set('parent', $parent);
					$ticket->set('template', $template);
					$ticket->set('class_key', 'Ticket');
					$ticket->set('show_in_tree', 0);
					$ticket->set('published', 1);
					$ticket->set('author', $user_id);
					$ticket->set('createdby', $user_id);
					$ticket->set('pagetitle', $fullname);
					$ticket->set('uri_override', 1);
					$ticket->set('uri', $parent_alias);
					$ticket->set('alias', $user_id);

					$ticket->save();
				}
			}
		}
	}
Предложенные выше способы (обернуть плейсхолдер результатов в условие) не будут нормально работать динамически, до перезагрузки страницы со сформированным гет-параметром.

Можете попробовать сделать сниппет-обертку для вызываемого в mFilter2 сниппета, который будет проверять наличие гет-параметров. В случае нахождения гет-параметра — передавать все scriptProperties в вызываемый сниппет, в противном случае возвращать пустоту.

Другой способ — расширить родной класс фильтрации, сформировав в нем нужные условия.