TITAN-UZ

TITAN-UZ

С нами с 27 февраля 2014; Место в рейтинге пользователей: #56
Death_Unlimited
01 октября 2017, 17:08
1
0
В общем благодаря помощи Константина Ильина написал, а если быть точнее «намучал» я сниппет для обработки MIGx полей) Просьба не судить строго так как это мой первый сниппет, да и в PHP я силен на уровне чтения документации и просмотра видео уроков в процессе написания кода. А хотя можете и строго судить))

Сниппет предназначен для использования синтаксиса Fenom в чанках, если Fenom не используется то getImageList справится лучше, хотя надеюсь что благодаря парсеру pdoTools этот сниппет будет работать быстрее.

<?php 

//$docid - id документа, если не задано берем id текущего документа
//$tvname - поле MIGx
//$tv_in - поле вложенного MIGx
//$chunk - чанк или @INLINE
//$chunk_in - чанк для вывода вложенного MIGX

if (empty($docid)) {
	$docid = $modx->resource->get('id');
}
$pdo = $modx->getService('pdoTools');
$tv = $modx->getObject('modResource',$docid);
$tv = $tv->getTVValue($tv_name);
$rows = json_decode($tv,1);
if (is_array($rows)) {		//без этого почему то reset() key() им подобные и даже сам цикл ругались что
				//в $rows не массив, подозреваю что из-за того что массив содержит json
				//строку вложенного MIGx
	reset($rows);
	$_first = key($rows);
	end($rows);
	$_last = key($rows);
	$total = count($rows);
	foreach ($rows as $key => $row) {
		$row['idx'] = $key+1;
		$row['total'] = $total;
		if ($key === $_first)
			$row['_first'] = 1;
		if ($key === $_last)
			$row['_last'] = 1;
		if ($key % 2)
			$row['_alt'] = 1;
		if(!empty($tv_in) && !empty($row[$tv_in])) {
			$subArr = $modx->fromJSON($row[$tv_in]);
			if (is_array($subArr)) {		//аналогичная причина что и выше, плюс дополнительная 
								//проверка вдруг у нас тут обычное поле
				reset($subArr);
				$sub_first = key($subArr);
				end($subArr);
				$sub_last = key($subArr);
				$sub_total = count($subArr);
				foreach ($subArr as $keySub => $subRow) {
					$subRow['idx'] = $keySub+1;
					$subRow['total'] = $sub_total;
					if ($keySub === $sub_first)
						$subRow['_first'] = 1;
					if ($keySub === $sub_last)
						$subRow['_last'] = 1;
					if ($keySub % 2)
						$subRow['_alt'] = 1;
					$row[$tv_in] = '';
					if (empty($chunk_in)) {
						$row[$tv_in] .= '<pre>' . $pdo->getChunk('', $subRow) . '</pre>';
					} else {
						$preout = $pdo->getChunk($chunk_in, $subRow, false);
						$row[$tv_in] .= $pdo->fastProcess($preout); //без знака конкатенации "." перед "=" выведет только последний элемент!
					}
				}
			}
		}
		if (empty($chunk)) {
			$output .= '<pre>' . $pdo->getChunk('', $row) . '</pre>';
		} else {
			$html = $pdo->getChunk($chunk, $row, false);
			$output .= $pdo->fastProcess($html); //без знака конкатенации "." перед "=" выведет только последний элемент!
		}
	}
}
//echo number_format(microtime(true) - $modx->startTime, 4), 's\<br\>';
//echo number_format(memory_get_usage() / 1048576, 4), 'mb\<br\>';

//return print_r($rows);
return $output;
Вызывается он вот так вот:

{'@FILE snippets/migX.php' | snippet : [
'tv_name'=>'migx_tv',		//главное MIGx поле
'tv_in'=>'migx_in_tv',		//вложенное MIGx поле
'chunk'=>'@FILE chunks/chunk.html',	//чанк для вывода главного MIGx в котором будет содержаться уже обработанный chunk_in
'chunk_in'=>'@INLINE {$in_migx_in_tv}']}	//чанк для вложенного MIGx поля в котором выводим поля вложенного MIGx(извиняюсь за тавтологию)
Естественно вызывать сниппет можно как вашей душе угодно, так же как и вложенный чанк вызывать из файла, вроде проблем не было. @INLINE тут просто для примера. В главном чанке просто вызываем вложенный MIGx и у нас на его место подставляется обработанный chunk_in в таком виде в каком вы его задали, с выводом полей вложенного MIGx.

Буду рад если укажите на мои ошибки или способы улучшить сниппет.

P.S. Еще раз спасибо кто помогал мне в написании сего сниппета.
А так же буду благодарен доброму человеку который объяснит для чего в:
$pdo->getChunk($chunk, $row, false);
параметр false? Потому как сам я этой информации не нашел к сожалению((
так же думаю неплохо было бы добавить и мое совместное решение в шапку, если автор объявится естественно.
Игорь Терентьев
06 сентября 2017, 21:04
1
0
Вот так вроде тоже должно работать:

<img class="pull-left" src="{("upload/" ~ $tvimage) | phpthumbon : 'w=280&h=210&zc=0&f=jpg&q=80'}" alt="{$pagetitle}">
Александр Янк
01 августа 2017, 12:16
1
0
Вы знаете, решил углубиться в fenom, оказалось очень приятным делом, а главное удобным:
Раньше я использовал такую конструкцию условий:
[[[[*id:eq=`[[++site_start]]`:then=`$slider`:else=`--`]]]]
А сейчас использую такою:
{if $_modx->resource.id == 1}
    {include 'slider'}
{/if}
намного понятнее и понятнее.

Даже разбивка на чанки приносит удовольствие:
{include 'header'}
тут я два раза кликаю и легко заменяю название
[[$header]]
а на старом мне надо было выделить слово без знака доллара!
Гриборий
01 июля 2017, 18:26
2
+1
$resources = $modx->getCollection('modResource', [
    'class_key' => 'msProduct'
    ]);
foreach ($resources as $res) {
    $res->save();
}
Проще, конечно, через «консоль» запускать.
Борис
29 мая 2017, 17:07
1
0
Большое спасибо Владимиру, решили проблему с помощью фенома и плейсхолдера (&totalVar total).

косок условия из чанка обертки проектов:
{if $_modx->getPlaceholder('total_1') == 2}
{set $myclass = "col-md-6 col-sm-12"}
{elseif $_modx->getPlaceholder('total_1') == 3}
{set $myclass = "col-md-4 col-sm-6"}
{elseif $_modx->getPlaceholder('total_1') == 4}
{set $myclass = "col-md-3 col-sm-6"}
{elseif $_modx->getPlaceholder('total_1') == 6}
{set $myclass = "col-md-4 col-sm-6"}
{else}
{set $myslass = "col-md-3 col-sm-6"}
{/if}
Так же для 3го проекта использовался отдельный чанк с таким условием:
{if $_modx->getPlaceholder('total_1') == 4}
{set $myclass = "col-md-3 col-sm-6"}
{elseif $_modx->getPlaceholder('total_1') == 5}
{set $myclass = "col-md-6 col-sm-12"}
{elseif $_modx->getPlaceholder('total_1') == 6}
{set $myclass = "col-md-4 col-sm-6"}
{else}
{set $myclass = "col-md-4 col-sm-6"}
{/if}
А чанк вывода всех проектов где происходит непосредственно сам подресурс:
[[!pdoResources?
		&parents=`[[*id]]`
		&depth=`0`
		&tpl=`tpl.project`
		&tpl_3=`tpl.p3th`
		&includeTVs=`img,plan`
		&processTVs=`1`
		&totalVar=`total_1`
		]]
Роман Ильин
09 мая 2017, 09:24
2
0
Спасибо!

Нашел еще такой короткий вариант:
{$imgurl | phpthumbon : "w=556&h=376&zc=1&q=61"}

Небольшой вопрос вдогонку. Как в Fenom сделать конкатенацию строк?
Andrei D.
10 апреля 2017, 11:08
3
0
ну или эпичней
<?php
$id = $modx->resource->get('id');
$depth .= count($modx->getParentIds($id));
$level = 'level_';
$chunk = $modx->getOption($level.''.$depth,$scriptProperties, '');
if (preg_match('/^@INLINE/',$chunk)) {
    return substr($chunk, 7);
}
* на всякий тоже можно оставить
} else {
      return $modx->getChunk($chunk);
}


[[!hi?
&level_1=`@INLINE hi`
&level_2=`@INLINE hello`
&level_3=`@INLINE good`
]]
Максим Кузнецов
09 апреля 2017, 13:08
3
+2
Вообще, для сео это совсем не критично, т.к:
— если вам необходимо добавить страницы пользователей в sitemap, то это можно сделать в рамках pdoUsers
— если вам необходимы динамичные заголовки и мета-теги, то можно сделать примерно так:

1. В плагине создаем плейсхолдер user_id

2. В мета-тегах проверяем его наличие:
{block 'meta'}
	{var $user_id = $_modx->getPlaceholder('user_id')} 

	{if $user_id | length > 0}
		{var $user_name = $_modx->getPlaceholder('user_name')}
		{var $pagetitle = $user_name ~ ' / Профиль пользователя'}
	
		<title>{$pagetitle ~' :: '~ $_modx->config.site_name}</title>
		...
	{else}
		{parent}
		//обычный набор мета-тегов
	{/if}
{/block}
— надеюсь логика понятна..)

Что же до примера со вторым вариантом, то примерно вот так:

1. Создание страницы пользователя (тикетом)
<?php
	if ($modx->event->name == 'OnUserActivate') {
		if ($user) {
			if ($profile = $user->getOne('Profile')) {
				$user_id = $user->get('id');
				$fullname = $profile->get('fullname');

				/* Можно распределять пользователей в зависимости от их группы */
				if ($user->isMember('Users')) {
					//указываем родителя и шаблон
					$parent = 21;
					$template = 28;
				}
	
				if (isset($parent)) {	
					//Дополнительно может потребоваться проверка на то, создана ли уже страница для пользователя 
					//(на случай, если у вас возможна повторная активация-деактивация пользотвалея 
					$page = $modx->getObject('modResource', array(
						'parent' => $parent,
						'createdby' => $user_id
					));
		
					if (!$page) {
						/* Формируем 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();
					}
				}
			}
		}
	}

2. Синхронизируем данные (в одну сторону — от пользователя к странице). Соответственно, если есть потребность редактировать поля пользователя из админки через его страницу, потребуется еще один плагин.
<?php
	if ($modx->event->name == 'OnUserFormSave' && $mode != 'new') {
		if ($user) {
			if ($profile = $user->getOne('Profile')) {
				$user_id = $user->get('id');

				if ($user->isMember('Users')) {
					$parent = 21;
				}
				
				if (isset($parent)) {
					//Ищем страницу пользователя
					$page = $modx->getObject('modResource', array(
						'parent' => $parent,
						'createdby' => $user_id
					));
					
					if ($page) {
						$extended = $profile->get('extended');
						
						//Обновляем дефолтное поле страницы
						$page->set('pagetitle', $profile->get('fullname'));
						
						//Обновляем тв-поле
						if (isset($extended['phone'])) {
							$page->setTVValue('user_phone', $extended['phone']);
						}

						//Дополнить требуемыми полями по вкусу %)
					
						$page->save();
					}
				}
			}
		}
	}
Николай
01 апреля 2017, 14:48
4
+1
Постарался чуть более универсальное решение написать для тех случаев, когда обратный слеш нужен не только для папок, но и для документов.

Те. сайт/категория/товар/
<?php
if ($modx->context->key == 'mgr') {return;}
$uri=$_SERVER['REQUEST_URI'];
if (substr($uri, -1) != '/' && $uri != '/' && !strpos($uri, '?')&& !strpos($uri, '.')) {
	$url = $modx->getOption('site_url');
	if(substr($url, -1)=='/'){
		$url=substr($url, 0, -1);
	}
	$url .= $uri.'/';
	$modx->sendRedirect($url,array('responseCode' => 'HTTP/1.1 301 Moved Permanently'));
}
Василий Столейков
14 марта 2017, 08:58
2
+3
Мне требуется указать родительский ресурс, но на английской версии у родителя другой id следовательно выводится русское меню на англ контексте.
{* В зависимости от контекста указываем нужного родителя *}
{if $_modx->context.key == 'web'}
    {set $parent = 12}
{else}
    {set $parent = 12}
{/if}

{* в параметрах вызова указываем переменную $parent:  *}
    'parent' => $parent,

можно ли через fenom проверить, является ли исходный ресурс контейнером или нет?
конечно, если исходный имеется ввиду текущий, то:
{if $_modx->resource.isfolder == 1}
контейнер
{else}
не контейнер
{/if}
Если в чанке меню, то просто $isfolder