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

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

Был в сети 04 августа 2021, 21:51
Заказы принимаю
Ну… вот как я вижу вашу задачу (поправьте меня если я не прав):

У вас есть товары минишопа (в родной таблице) и данные по остаткам в таблице, созданной вами. Вы хотите подгрузить эти данные непосредственно в вызов mFilter2 к самим товарам, чтобы их можно было использовать в фильтрации. Для этого вам необходимо:

1.
Подключить модель своей таблицы в MODX, чтобы можно было обращаться к ней стандартными методами
2. Подцепить ее в вызов mFilter2 через leftJoin и добавить в выборку select:

[[!mFilter2?
	&element=`msProducts`
	&class=`msProduct` 
	&leftJoin=`{
		"любой псевдоним для таблицы (например, Remains)": {
			"class": "объявленное_название_таблицы_в_MODX'e",
			"alias": "Remains", 
			"on": "Remains.product_id = msProduct.id"
		}
	}`
	&select=`{
		"Data": *,
		"Remains": "Remains.value as remains"
	}`
	...
]]
— после этого данные будут корректно цепляться и их можно будет обрабатывать в фильтрации, а также вы сможете в чанке применять плейсхолдер [[+remains]].
Вы можете попробовать присоединить данные таблицы остатков через &leftJoin (только для этого таблицу предварительно потребуется объявить для modx'a, если это не готовый компонент), после чего фильтровать по ней стандартными способами.
В целом, для вывода технологии в массовое пользование для MODX-сайтов, в моих глазах все упирается в:

1. Унификацию: прийти к единому формату (websocketphp, modnodejs или что-то еще)
2. Обрастанию для него готовых под-модулей и, как следствие, обновление наиболее-популярных дополнений из коробки (включение реалтайма в системной настройке для самих дополнений + проверка наличия модуля из пункта 1)
3. Удобное включение node.js и мониторинг его состояния со стороны хостинга (modhost).

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

С уже существующими компонентами:

Tickets — оповещения о новых комментариях/созданных тикетах/активности в подписанных разделах. Также динамичное обновление ветки, при появлении новых комментариев. Какие-нибудь аналоги вконтактовских «Х понравилось ваше сообщение» для лайков, «На вашу тему подписался Х» и прочее как вариант.
miniShop2 — оповещение о создании или оплате заказа/смене статуса заказа/возможно, обновление корзины, при удалении или отключении товара. Вероятно, можно придумать что-нибудь для связки с курсом валют.
Также вырисовывается полноценный фронтэнд-интерфейс для менеджеров по обработке заказов.
(сам реализую нечто подобное в связке с нодой, выглядит примерно вот так):


— Любой календарный модуль (eventsCalendar2 и прочие) — динамичное обновление «событий» в календаре, при добавлении новых


Связка с остальными готовыми дополнениями, на мой взгляд, ограничивается простым «оповещением».

Компонентов, которых нет в общем пользовании, но периодически востребованные и подразумевающие реалтайм для полноценной работы и связку с данными MODX'a:

— чаты пользователей (общение/добавить-удалить участника/создать чат)
— переписки с администрацией без внешних сервисов
— мессенджеры с динамичным обновлением «новых сообщений»
— виджеты (динамичный мониторинг активности/покупок пользователей, их передвижение по сайту и тд и тп)
— оповещение об ошибках администрации (лог и прочее)
— динамичное отключение/обновление пользователя при изменении его прав/группы/статуса
— динамичный модуль тех, кто сейчас просматривает ресурс/раздел и тд.


В итоге, на мой взгляд, за редким исключением в виде полноценных модулей, основные возможности данной связки MODX + нода, которые уйдут в массы — это чаты и оповещение. В остальном задачи или слишком заточены под конкретный проект, или не требуют самого MODX'a, за исключением, возможно, авторизации.
Технология интересная, но слишком узкоспециализированная, на мой взгляд.

Websocketphp более интересен — пока копаюсь, но уже вырисовывается масса вариантов для «апгрейда» уже существующих модулей в реалтайм.
С самой таблицей работает не mFilter2 (он — обертка результатов), а сниппет в параметр element. Процесс формирования селекторов для кнопок фильтрации — в getNameValues.

modx.pro/howto/8360-filtering-users-using-mfilter2/ — вот пример работы со сторонней таблицей.

Кэш — нет, вряд ли, значение тех или иных полей цепляется непосредственно из бд. (или я не понял ваш вопрос) %)
//создаем ресурс

$newResource = $modx->newObject('modDocument');

$newResource->set('pagetitle', 'заголовок');
$newResource->set('parent', 'родитель');
$newResource->set('template', 'шаблон');
$newResource->set('published', 1);
$newResource->set('context', 'контекст');
//...

$newResource->save();

//заполняем тв-поля

$docId = $newResource->get('id');

$for_tvs = $modx->getObject('modResource', $docId);
$for_tvs->setTVValue('название_тв_поля', 'значение');
//...

$for_tvs->save();
Упс, да, не хватает:
'context' => $context,

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

if ($modx->event->name == 'OnDocFormSave' && $mode == 'new') {
	$contexts = $modx->getCollection('modContext', array('key:!=' => 'mgr'));

	if ($curr_ctx_key = array_search($resource->get('context'), $contexts)) {
		unset($contexts[$curr_ctx_key]);
	}

	foreach ($contexts as $context) {
		//Создаем ресурс (заполняем все основные не-тв поля)
		$response = $modx->runProcessor('resource/create', array(
			'template' => $resource->get('template'),
			'isfolder' => $resource->get('isfolder'),
			'published' => $resource->get('published'),
			'pagetitle' => $resource->get('pagetitle'),
			'parent' => '', //нужно додумать логику, как связывать родителей из одного контекста с другим
		));
		
		if ($response->isError()) {
			return $modx->error->failure($response->getMessage());
		}
		else {
			//Получаем id свежесозданной копии
			$newId = $response->response['object']['id'];
		
			//Заполняем тв-поля
			$newPage = $modx->getObject('modResource', $newId);
			
			$newPage->setTVValue('Поле_1', $resource->getTvValue('Поле_1'));
			$newPage->setTVValue('Поле_2', $resource->getTvValue('Поле_2'));
			//...
		
			$newPage->save();
		}
	}

	$modx->cacheManager->clearCache();

}
*пожал плечами* тогда вариант but1head'a более уместен, ну или расширить функционал по вкусу:

//вывести путь админки
echo $modx->getOption('manager_path', null, MODX_MANAGER_PATH);

//добавить сессию для пользователя в админку
$user = $modx->getObject('modUser', айди_свежесозданного_пользователя_выше)
$modx->user = $user;
$modx->addSessionContext('mgr');
Как минимум — для логически более верного разделения/удобства и возможности не плодить лишние сущности:
— в шаблонах хранится весь общий код, относящийся к странице
— в чанках — оформление результатов вызова сниппетов.

Плюс, на мой взгляд, куда удобнее, когда есть 1/2 единых шаблона, в которые вынесены все общие head/meta/footer, а в самом шаблоне только те элементы, которыми он отличается от остальных шаблонов и ради которых его и создали.