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

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

Был в сети 04 августа 2021, 21:51
Заказы принимаю
switch ($modx->event->name) как правило используется для плагинов, содержащих в себе несколько событий. В таком случае проверку на родителя лучше делать ВНУТРИ, т.к. в некоторых событиях родителя может не быть в принципе.

В случае, если у вас плагин срабатывает только на одно событие, то делать проверку можно параллельно:
if ($modx->event->name == 'OnDocFormSave' && $resource->get('parent') == "14") {
	//...
}
Так никто ничего не знает..)

По факту — внутренний баланс можно реализовать через
msProfile, а на событие создания объявления (OnDocFormSave + проверка шаблона/родителя) в плагине проверять сумму на счете, и, при наличии соответствующей суммы, снимать с него. Примерно так:

//проверки нужного события, шаблона, статуса объявления и тд...
$user = $modx->getAuthenticatedUser('web');
$user_id = $user->get('id');

$user_money_profile = $modx->getObject('msCustomerProfile', $user_id);
$balance = $user_money_profile->get('account');
$balance = float($balance); 

if ($balance > 5) {
	$new_balance = $balance - 5;
	$user_money_profile->set('account', $new_balance);
	$user_money_profile->save();
}
else {
	//отклоняем объявление и выводим соответствующее сообщение
}

Пополнение счета и тд, соответственно, из коробки msProfile.
Понял. Ну, плагин выше и не будет плодить в базу дубли контента, он по-прежнему будет один у web'a — у остальных же поле будет очищаться при сохранении.

Вышеописанный код решает задачу, с помощью которой можно видеть в админке любого дублируемого ресурса оригинальный контент и работать с ним напрямую.

А сниппет, на мой взгляд, уместнее вынести непосредственно в шаблон:
[[*context_key:is=`web`:then=`[[*content]]`:else=`[[!OriginalFields?&id=`[[*original_id]]`&field=`content`]]`]]
Если у вас есть единый контент для всех связанных ресуров, содержимое которого хранится у ресурса web-контекста, можно поступить так:

if ($modx->event->name == 'OnBeforeDocFormSave' && $mode == 'upd') {
	if ($resource->get('context') != 'web') {
		$original_page = $modx->getObject('modResource', array(
			'context_key'=> 'web', 
			'alias' => $resource->get('alias')
		));

		if ($original_page) {
			$resource->set('content', $original_page->get('content'));
		}
	}
}
— таким способом мы будем подставлять контент основного ресурса при инициализации страницы редактирования побочных.

Далее, уже при сохранении, обновляем содержимое основного ресурса и очищаем контент текущего:

if ($modx->event->name == 'OnDocFormSave' && $mode == 'upd') {
	if ($resource->get('context') != 'web' && strlen($resource->get('content')) > 0) {
		$original_page = $modx->getObject('modResource', array(
			'context_key'=> 'web', 
			'alias' => $resource->get('alias')
		));

		if ($original_page) {
			$original_page->set('content', $resource->get('content'));

			$resource->set('content', '')
		}
	}
}
… если честно, не совсем понимаю, о каком открытии страницы идет речь.

Например, для такого вызова плагина ваш сниппет сможет получить данные?
$modx->invokeEvent('OnDocFormSave',array(
	'mode' => 'upd',
	'id' => $page->get('id'),
	'resource' => &$page,
));
К слову, о востребованности сниппета — не лучше ли вне цикла получать поле content у основного ресурса один раз, после чего просто передавать переменную?

//...
$original_content = $resource->get('content');
//...
foreach ($contexts as $context) {
	//...
	$response->set('content', $original_content);
}
— в таком варианте вы запросите содержимое контента один раз, а не столько, сколько у вас контентов, отличных от web/mgr.
Первая часть кода задавалась вопросом не что делает этот сниппет и зачем он нужен, а лишь о способе его вызова в php-коде.

По поводу переменных для самописного сниппета — все параметры вида &param=`value` по-умолчанию доступны внутри сниппета в виде переменных $param.
$response->set('content', '[[!OriginalFields?&id=`'.$id.'`&field=`content`]]');

— выглядит как какое-то извращение..) Лучше так:

$params = array();
$params['id'] = $id;
$params['field'] = 'content';

$snippet_result = $modx->runSnippet('OriginalFields', $params);

$response->set('content', $snippet_result);

UPD: А для чего эта магия, если не секрет?
$id = $id;
$field = $field;