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

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

С нами с 01 июля 2013; Место в рейтинге пользователей: #27
Максим Кузнецов
07 февраля 2017, 15:40
0
switch ($modx->event->name) как правило используется для плагинов, содержащих в себе несколько событий. В таком случае проверку на родителя лучше делать ВНУТРИ, т.к. в некоторых событиях родителя может не быть в принципе.

В случае, если у вас плагин срабатывает только на одно событие, то делать проверку можно параллельно:
if ($modx->event->name == 'OnDocFormSave' && $resource->get('parent') == "14") {
	//...
}
Максим Кузнецов
07 февраля 2017, 15:11
0
Главная страница -> настройки -> заморозить url (включить и выставить что-нибудь в духе index.php)

(для выборки больших объемов страниц любых лишних операций лучше избегать)
Максим Кузнецов
06 февраля 2017, 10:00
+1
Это и есть весь код сниппета. Используется так:
[[+age:имя_сниппета]]

В вашем примере будет как-то так:
[[+tv.birthday:ages:имя_сниппета]]
Или так:
[[!имя_сниппета? &input=`[[+tv.birthday:ages]]`]]
Максим Кузнецов
06 февраля 2017, 06:52
1
+2
$cases = array(2, 0, 1, 1, 1, 2);
$titles = array('год', 'года', 'лет');
			
return $titles[($input % 100 > 4 && $input % 100 < 20) ? 2 : $cases[min($input % 10, 5)]];
Максим Кузнецов
05 февраля 2017, 22:38
0
//однозначным числам будет дописываться 0 перед значением
{$idx | length == 1 ? '0' ~ $idx : $idx}

(дополнение pdoTools должно быть выше версии 2.0, если не ошибаюсь)
Максим Кузнецов
05 февраля 2017, 22:34
0
В чанке arena_item укажите в нужном месте [[+idx]]
Максим Кузнецов
05 февраля 2017, 19:45
+2
Вы можете реализовать сборный sitemap.
Максим Кузнецов
01 февраля 2017, 16:59
+2
Так никто ничего не знает..)

По факту — внутренний баланс можно реализовать через 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.
Максим Кузнецов
30 января 2017, 16:55
+1
Да не за что..)

Видимо, я все-таки не совсем корректно понял задачу — мне казалось, что ресурсы дублируются во все контексты, т.к. у них потенциально могут быть разные подданные для каждого города. Если же у вас все данные одинаковые и редактировать страницы-дубли никто не будет, то правильнее вообще было бы не плодить лишних страниц, а воспользоваться кастомной маршрутизацией, которая перехватывала бы событие OnPageNotFound и отображала бы страницу-оригинал, доступную по адресу с идентификатором города.
Максим Кузнецов
30 января 2017, 16:41
+1
Понял. Ну, плагин выше и не будет плодить в базу дубли контента, он по-прежнему будет один у web'a — у остальных же поле будет очищаться при сохранении.

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

А сниппет, на мой взгляд, уместнее вынести непосредственно в шаблон:
[[*context_key:is=`web`:then=`[[*content]]`:else=`[[!OriginalFields?&id=`[[*original_id]]`&field=`content`]]`]]
Максим Кузнецов
30 января 2017, 16:16
+2
Если у вас есть единый контент для всех связанных ресуров, содержимое которого хранится у ресурса 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', '')
		}
	}
}
Максим Кузнецов
30 января 2017, 16:09
+1
… если честно, не совсем понимаю, о каком открытии страницы идет речь.

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

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

По поводу переменных для самописного сниппета — все параметры вида &param=`value` по-умолчанию доступны внутри сниппета в виде переменных $param.
Максим Кузнецов
30 января 2017, 15:29
+2
$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;
Максим Кузнецов
29 января 2017, 00:42
+1
С вашей задачей может помочь fenom — воспользуйтесь json_decode для tv-поля, после чего при помощи foreach сформируйте необходимый вид отображения
Максим Кузнецов
26 января 2017, 14:46
+2
По умолчанию сниппет выше — не сможет. Чтобы смог, нужно расширить его так, как описано в статье по ссылке.
Максим Кузнецов
26 января 2017, 13:37
+2
Многим лучше вызывать не getObject на каждый ресурс, а один раз getCollection, после чего сформировать результат циклом по ключу полученного массива.