Fenom вместо getImageList MIGx

Есть обработка MIGx полей через Fenom с условиями:
{set $rows = json_decode($_modx->resource.tv_name, true)}
{foreach $rows as $_list $row}
	{if $_last==1}
		'какойто коТ'
	{/if}
{/foreach}
Все замечательно работает, но если мне к примеру помимо _last нужны поля idx, _alt, _first и прочее, как быть в таком случае? Неужели без getImageList все же не обойтись?

Решение
{set $rows = json_decode($_modx->resource.migx_tv, true)}
{set $idx = 0}
{foreach $rows as $idxArr => $row}
	{set $row['idx'] = $idx++} {* idx от созданной переменной с инкриментом*}
	{set $row['idxForeach'] = $row@index} {* idx от foreach*}
	{*set $idxMIGX = $row['MIGX_id']*} {* idx от MIGX*}
	{if $row@first} 
		{set $row['_first'] = 'first item'}
	{/if}
	{if $row@last} 
		{set $row['_last'] = 'last item'}
	{/if}
	{if !($idx % 2)}
		{set $row['_alt'] = 'odd item'}
	{/if}
	{$row | print_r}
{/foreach}
Владислав
29 сентября 2017, 15:22
modx.pro
8
8 836
-2

Комментарии: 48

Виталий Серый
30 сентября 2017, 00:44
0
В документации есть примеры, @index, @first, @last должны подойти.
    Владислав
    30 сентября 2017, 05:22
    -3
    Ну выведите тогда таким способом поле [[+idx]] из MIGx) При чем тут итерации цикла foreach и MIGx? Я не идиот и документацию прочитал, и не нашел там ничего связанного с выводом MIGx. [[+idx]] [[+_last]] [[+_first]] [[+MIGx_id]] это поля MIGx, и к циклу не имеют никакого отношения.
    [MIGX_id] =>
    [_alt] =>
    [_first] =>
    [_last] =>
    [idx] =>
    [property.tvname] =>
    [property.tpl] =>
    [property.docid] =>
    Вот эти поля мне нужны к примеру, после Fenom модификатора json_decode все они теряются непонятно куда, остается только [MIGX_id]. _alt _first _last теряются потому что в PHP имя переменной не может начинаться с _, а вот idx почему теряется? И как к этим полям добраться? Еще раз повторюсь, итерации цикла FOREACH здесь совершенно не при чем, то что итерации имеют схожее название last и first с полями _last и _first, здесь совершенно не при чем.
      Арсений
      30 сентября 2017, 09:15
      0
      я уж извиняюсь, но это разве не очевидно? все эти плейсхолдеры формируются в сниппете getImageList, и в изначальном массиве просто не существуют. Если есть необходимость создайте их в foreach.
      это как пытаться вилкой суп есть и кричать «Почему, плядь, без ложки не обойтись? обязательно ложку брать?»
        Владислав
        30 сентября 2017, 11:03
        -2
        Еще один умник, тогда объясните мне почему
        {foreach $rows as $_list $row}
        	{if $_last==1}
        		'какойто коТ'
        	{/if}
        {/foreach}
        работает и выводит именно поле _last?? Ведь я его нигде не создавал, никак не объявлял. Значит _last в исходном массиве все таки существует, так ведь? И idx точно так же)) И более того, значения у них такие же как если бы я через getImageList их вывел. Прямо какая-то магия ей богу, ахахах)
          Владислав
          30 сентября 2017, 11:09
          0
          Прошу удалить этот коммент, действительно Арсений был прав. Видимо бессонная ночь сменившаяся утром повлияла)
        Владислав
        30 сентября 2017, 05:37
        0
        Более того, если я сделаю вот так вот:
        {foreach $rows as $row idx=$idx _last=$last _first=$first}
        {/foreach}
        То Fenom даже не скомпилит ничего, выдав в логе ошибку, потому как цикл foreach не имеет никаких idx, а так же _last и _first. Читайте внимательно вопрос в следующий раз, и в документацию меня не надо носом тыкать, прежде чем сюда прийти и написать вопрос я документацию просмотрел. Выше я немного неточно написал, со знака подчеркивания имя переменной может начинаться в PHP, это с цифры не может. Но это не объясняет куда деваются эти нужные поля.
          Владислав
          30 сентября 2017, 05:49
          0
          Более того, сама документация содержит ошибку:
          {foreach $rows [as [$row =>] $value] [index=$index] [first=$first] [last=$last]}
          на что в логах идет вот такое вот:
          (ERROR @ C:\OSPanel\domains\...\core\components\pdotools\model\pdotools\pdotools.class.php : 942) Unexpected token '[' in expression, expect ']' in file:chunks/mainpage.html line 120, near '{foreach $rows [as [' <- there in 4ba5073397f1dfc38c3f61ec40ca030d line 1, near '{include 'file:chunks/mainpage.html'' <- there
          [2017-09-30 05:48:00]
            Владислав
            30 сентября 2017, 06:09
            0
            {foreach $rows as $_last => $row}
            Так как в таком вот случае $_last выводится, то смею предположить что idx, _last _alt и прочее это ничто иное как ключи массива, но в таком случае как их получить? Да еще и так чтобы они работали все в пределах итераций одного цикла. Потому как вот так вот:
            {foreach $rows as $_last => $row}
            {foreach $rows as $idx => $row}
            	{$idx}{$_last} //и тут мы к примеру просто выводим их
            {/foreach}
            {/foreach}
            Работает, но у нас получается цикл в цикле, а соотсветственно если я так буду обрабатывать массив с полями MIGx, то я их получу во столько раз больше сколько значений может иметь к примеру _last. То есть при первом прохождении массива мы получим _last = 0, во втором цикле выведутся все записи исходя из того сколько у нас их там есть, так как idx это порядковый номер записи. Во второй итерации первого цикла _last = 1, оно и имеет то всего два значения, точнее даже не 0 и 1, а true и false как я понимаю. И второй цикл во второй итерации первого цикла также выведет все записи. В итоге мы имеем два круга вывода записей.
            Владислав
            30 сентября 2017, 06:25
            -2
            Доступные плейсхолдеры в шаблоне вывода getImageList
            Ключ 	Описание
            [[+fieldname]] 	Подставьте вместо 'fieldname' заданное вами значение поля
            [[+idx]] 	Индекс текущего элемента. Начинается всегда с 1
            [[+_first]] 	Содержит 1 если это первый элемент
            [[+_last]] 	Возвращает 1 если это последний элемент
            [[+_alt]] 	Возвращает 1 для каждого второго элемента
            [[+total]] 	Возвращает общее кол-во элементов, можно заменить 'total' настройкой &totalVar
            [[+property.name]] 	Можно использовать любые переданные параметры. К примеру если вы указали &docid=`20`, то [[+property.docid]] вернет 20
            Добавлю сюда немного инфы о MIGx, а то опять какой нибудь умник ворвется крича что «цикл foreach тебя спасет». Все что я хочу, это добиться средствами Fenom такого же полного функционала вывода MIGx полей как и при стандартном синтаксисе MODx, не более. То бишь чтобы можно было использовать поле idx где и когда мне захочется, или поле _alt, или к примеру получить общее количество элементов опять же когда и где угодно(в MIGx это поле [[+total]] по умолчанию). Но что-то я подозреваю что придется писать свой сниппет для всего этого дела.
              Константин Ильин
              30 сентября 2017, 11:18
              2
              +1
              Зачем сниппет писать, если можно пару строчек взять из getImageList ну или просто применить свои навыки программирования, благо феном позволяет все на месте писать.

              умник ворвется крича что «цикл foreach тебя спасет»
              А как еще можно пройтись по массиву?

              Если зайти в сниппет getImageList можно найти такие строчки
              .....
              $fields['_alt'] = $idx % 2;
              $idx++;
              $fields['_first'] = $idx == 1 ? true : '';
              $fields['_last'] = $idx == $limit ? true : '';
              $fields['idx'] = $idx;
              .....
              Надо просто применить их на феноме:
              {set $rows = json_decode($_modx->resource.migx_tv, true)}
              {set $idx = 0}
              {foreach $rows as $idxArr => $row}
                  {set $row['idx'] = $idx++} {* idx от созданной переменной с инкриментом*}
                  {set $row['idxForeach'] = $row@index} {* idx от foreach*}
                  {*set $idxMIGX = $row['MIGX_id']*} {* idx от MIGX*}
                  {if $row@first} 
                      {set $row['_first'] = 'first item'}
                  {/if}
                  {if $row@last} 
                      {set $row['_last'] = 'last item'}
                  {/if}
                  {if !($idx % 2)}
                      {set $row['_alt'] = 'odd item'}
                  {/if}
                  {$row | print_r}
              {/foreach}
                Владислав
                30 сентября 2017, 11:39
                +1
                Вот за это спасибо)) Мозги не варят уже просто, а тут еще минуса ставят всякие) Извиняюсь если что перед всеми кто участвовал в дискуссии, не высыпаюсь я последнее время, туплю в общем и потому такие недопонимания.
                  Константин Ильин
                  30 сентября 2017, 11:54
                  -1
                  Не за что!
                  Ну минуса справедливые ведь) Вы просто тут какой-то «неадекват» развели) Еще и умниками «всех» называете))
                    Владислав
                    30 сентября 2017, 11:58
                    0
                    умник ворвется крича что «цикл foreach тебя спасет»
                    Это вообще сарказмом было, но не суть, по поводу неадкватства, ну хз я просто человек такой. В жизни я весьма адекватен, просто слишком много сарказма. Еще раз прошу прощения за свое поведение, ведь не могут же знать люди что я пошутил на самом то деле))

                    А массив если изощряться еще и циклом «for» можно перебрать если мне память не изменяет) На самом деле да, ошибка моя. Для теста было создано всего два элемента MIGx и поэтому
                    {set $rows = json_decode($_modx->resource.tv_name, true)}
                    {foreach $rows as $_list $row}
                    	{if $_last==1}
                    		'какойто коТ'
                    	{/if}
                    {/foreach}
                    такое проканало как говорится) Отсюда и сделал поспешные выводы что _last и прочие поля все таки есть в массиве просто их съедает по какой-то причине модификатор «json_decode».
                      Константин Ильин
                      30 сентября 2017, 12:10
                      0
                      Ну я поэтому и взял в кавычки неадекват)

                      for и foreach это конечно понятно, просто у вас так прозвучало, что мол должен существовать другой метод, без циклов)

                      Главное разобрались!
                      Бывает у многих и я этим грешил, спать надо Сергей)
                Виталий Серый
                30 сентября 2017, 12:12
                +1
                Спасибо за реакцию.
                В очередной раз убеждаюсь, что стоит тихо почитывать документацию, Василия, Николая, Сергея, Илью, Ивана, Павла, Михаила, Евгения, Боба, Марка и иже с ними, читать код, самостоятельно экспериментировать и вникать.
                И плевать на подобные вопросы, обсосанные уж много раз и в конечном счете с единственным посылом — «сделайте всю работу за меня».
                  Владислав
                  30 сентября 2017, 12:26
                  -1
                  Ой да ладно Вам тут, можно подумать никогда не было таких ситуаций когда бьетесь над чем нибудь, а воз и ныне там. Или мне на коленях тут еще поползать попресмыкаться, попросил же прощения уже.
                    Виталий Серый
                    30 сентября 2017, 12:45
                    +2
                    Не надо пресмыкаться, надо спокойней реагировать, не более.
                    Если не сложно, решение Константина было бы неплохо поместить в сам пост, чтобы проще было искать.
                  Death_Unlimited
                  01 октября 2017, 07:59
                  0
                  Подскажите пожалуйста что я делаю не так, написал сниппет, потому как предложенное здесь решение не совсем меня удовлетворяет, но через сниппет выводятся только значения последнего элемента.
                  <?php 
                  
                  //$docid - id документа, если не задано берем id текущего документа
                  //$tvname - поле MIGx
                  //$chunk - чанк или @INLINE
                  
                  if (empty($docid)) {
                  	$docid = $modx->resource->get('id');
                  }
                  
                  $tv = $modx->getObject('modResource',$docid);
                  
                  $tv = $tv->getTVValue($tvname);
                  
                  $rows = $modx->fromJSON($tv);
                  
                  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;
                  
                  	$pdo = $modx->getService('pdoTools');
                  
                  	if (empty($chunk)) {
                  		$output = '<pre>' . $pdo->getChunk('', $row) . '</pre>';
                  	} else {
                  		$output = $pdo->getChunk($chunk, $row, false);
                  
                  		//$output = $pdo->fastProcess($output);
                  	}
                  }
                  
                  
                  
                  
                  //return print_r($placeholder);
                  
                  return $output;
                  А еще вопрос, будет ли таким способом кешироваться чанк задаваемый в параметре chunk в виде файла?
                    Константин Ильин
                    01 октября 2017, 09:17
                    +1
                    $output = $pdo->getChunk($chunk, $row, false);
                    Вы каждый раз переписывайте значение $output, а не «соединяете» с предыдущим. Нужно делать конкатенацию результата.
                    вот так:
                    $output .= $pdo->getChunk($chunk, $row, false);
                    На счет кеширования точно сказать не могу, но насколько я понимаю кешируется сниппет и все что в нем, если вызывать его кешированным.
                      Death_Unlimited
                      01 октября 2017, 09:25
                      0
                      Спасибо, так тоже работает, ниже нашел решение через echo, но думаю что ваш вариант предпочтительнее)
                        Death_Unlimited
                        01 октября 2017, 10:28
                        0
                        Премного извиняюсь, но не подскажете что делать если нужно так же обрабатывать еще и вложенные поля migx? То есть допустим есть MIGx поле 'tv_name1' и в него вложено 'tv_name2'. Массив получается имеет вот такой вот вид:
                        Array (     [MIGX_id] => 1     [title_name] => "значение"     [address] => "значение"     [tv_name2] => 
                        	[{"MIGX_id":"1","youtube_video":"значение"}]
                        [idx] => 1     [total] => 4     [_first] => 1 )
                          Константин Ильин
                          01 октября 2017, 11:33
                          0
                          нужен вложенный foreach
                          $subArr = json_decode($row['tv_name2'],1);

                          эту строчку лучше вынести за foreach, т.к. лучше один раз присвоить переменной, чем каждый раз обращаться.
                          $pdo = $modx->getService('pdoTools');
                            Death_Unlimited
                            01 октября 2017, 12:08
                            0
                            эту строчку лучше вынести за foreach, т.к. лучше один раз присвоить переменной, чем каждый раз обращаться.
                            Да не досмотрел, спасибо.
                            нужен вложенный foreach
                            ну об этом тоже подумал, только вот а выводить потом как, не могу просто додуматься как в $output потом еще и с вложенного цикла вывести плейсхолдеры вложенного массива.
                              Константин Ильин
                              01 октября 2017, 12:31
                              +1
                              Самое простое это создать еще один чанк и готовить вывод заранее, а потом выводить в основном [[+subMIGX]]

                              foreach ($rows as $key => $row) {
                              
                                  .......
                              
                                  if(!empty($row['tv_name2'])){
                                      $subArr = json_decode($row['tv_name2'],1);
                              
                                      foreach ($subArr as $keySub => $rowSub) {
                                          $row['subMIGX'] .= $pdo->getChunk($chunk, $rowSub, false);
                                      }
                                  }
                                  
                                 .......
                              }
                                Death_Unlimited
                                01 октября 2017, 13:12
                                0
                                Хм, даже не думал что так можно, в принципе сейчас чутка подправлю код для того чтобы и второй чанк можно было задавать и выложу сюда, вдруг кому пригодится. Спасибо за решение со вторым чанком)
                              Death_Unlimited
                              01 октября 2017, 15:02
                              0
                              что-то быстрые правки у меня перешли в отлавливание ошибок, при чем ошибки в самом начале кода сниппета вида
                              PHP warning: reset() expects parameter 1 to be array, null given
                              
                              PHP warning: key() expects parameter 1 to be array, null given
                              и т.д. То есть $rows = $modx->fromJSON($tv); не массив, потом попробовал $rows = json_decode($tv,1); ошибки не исчезли. Сделал проверку
                              $rows = json_decode($tv,1);
                              
                              if (is_array($rows)) {
                              	echo 'это массив';
                              }else{
                              	echo 'это не массив';
                              }
                              
                              reset($rows);
                              
                              $_first = key($rows);
                              Говорит что массив но ошибки говорят иное)) Не пойму что не так?

                              Хотя код работает нормально не смотря на эти PHP warning.
                        Death_Unlimited
                        01 октября 2017, 09:22
                        0
                        Сам нашел решение:
                        <?php 
                        
                        //$docid - id документа, если не задано берем id текущего документа
                        //$tvname - поле MIGx
                        //$chunk - чанк или @INLINE
                        
                        if (empty($docid)) {
                        	$docid = $modx->resource->get('id');
                        }
                        
                        $tv = $modx->getObject('modResource',$docid);
                        
                        $tv = $tv->getTVValue($tvname);
                        
                        $rows = $modx->fromJSON($tv);
                        
                        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;
                        
                        	$pdo = $modx->getService('pdoTools');
                        
                        	if (empty($chunk)) {
                        		$output = '<pre>' . $pdo->getChunk('', $row) . '</pre>';
                        	} else {
                        		$output = $pdo->getChunk($chunk, $row, false);
                        
                        		//$output = $pdo->fastProcess($output);
                        	}
                        
                        	echo $output;
                        
                        }
                        Просто return надо поменять на echo и поместить в цикл.
                          Илья Уткин
                          01 октября 2017, 14:41
                          2
                          +4
                          АААААА… не надо return менять на echo…

                          // ...
                          $output = array();
                          foreach ($rows as $key => $row) {
                                  // ...
                          	$pdo = $modx->getService('pdoTools');
                          	if (empty($chunk)) {
                          		$output[] = '<pre>' . $pdo->getChunk('', $row) . '</pre>';
                          	} else {
                          		$output[] = $pdo->getChunk($chunk, $row, false);
                          	}
                          }
                          return implode(PHP_EOL, $output);
                            Death_Unlimited
                            01 октября 2017, 15:16
                            0
                            Выше человек мне уже вариант с конкатенацией подсказал)

                            Кстати:
                            $pdo->getChunk($chunk, $row, false);
                            Что устанавливает параметр false для getChunk и на что он влияет? нагуглить эту информацию что-то я не смог.

                            И если не составит не можете подсказать почему после
                            $rows = $modx->fromJSON($tv);
                            
                            reset($rows);
                            
                            $_first = key($rows);
                            в логи MODx сыпит ошибки вида
                            (ERROR @ C:\OSPanel\domains\...\core\cache\includes\elements\modsnippet\d66c42d1602cc2b078b0a95f7e22d5ae.include.cache.php : 31)
                            PHP warning: reset() expects parameter 1 to be array, null given
                            ... //и так на все что я пытаюсь сделать с $rows
                            Хотя $rows на самом деле является массивом и проходит проверку is_array, и сам код отрабатывает нормально?
                          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? Потому как сам я этой информации не нашел к сожалению((
                          так же думаю неплохо было бы добавить и мое совместное решение в шапку, если автор объявится естественно.
                            Алексей Карташов
                            01 октября 2017, 18:14
                            +1
                            Ты что-то слишком перемудрил.
                            Вот, делает всё, что тебе надо, и даже больше:

                            <?php
                            /**
                             * @type modX $modx
                             * @type pdoTools $pdoTools
                             * @type array $scriptProperties
                             *
                             * @type array $data
                             * @type string $migxtv
                             * @type int $id
                             * @type string $chunk
                             * @type int $returnData
                             */
                            
                            //$data - произвольный массив данных для рендера (может быть json-строкой). Если валиден, $migxtv игнорируется.
                            //$migxtv - если $data не указан или null, то можно задать имя MIGx-tv.
                            //$id - id документа, если не задано, то id текущего документа
                            //$chunk
                            //$returnData - вместо рендера просто вернуть массив данных (или NULL, если данные получить не удалось)
                            
                            $data = $scriptProperties['data'];
                            $migxtv = $scriptProperties['migxtv'];
                            $id = $scriptProperties['id'];
                            $chunk = $scriptProperties['chunk'];
                            $returnData = intval($scriptProperties['returnData']);
                            
                            if (is_string($data) && !empty(trim($data))) {
                              $data = $modx->fromJSON($data);
                            }
                            
                            if (!is_array($data) && !empty($migxtv)) {
                              $resource = $modx->resource;
                              if (!empty($id)) {
                                $resource = $modx->getObject('modResource', $id);
                              }
                            
                              $tvValue = $resource->getTVValue($migxtv);
                              if ($tvValue) {
                                $data = $modx->fromJSON($tvValue);
                              }
                            }
                            
                            if ($returnData) { return $data; }
                            if (!is_array($data)) { return ''; }
                            
                            $pdoTools = $modx->getService('pdoTools');
                            
                            $output = '';
                            $idx = 0;
                            $total = count($data);
                            foreach ($data as $key => $row) {
                              $row['_idx'] = ++$idx;
                              $row['_key'] = $key; // здесь может строка, а не индекс в массиве
                              $row['_total'] = $total;
                            
                              $row['_first'] = false;
                              $row['_last'] = false;
                              $row['_even'] = false;
                              $row['_odd'] = false;
                            
                              if ($idx === 1) {
                                $row['_first'] = true;
                              } else
                              if ($idx === $total) {
                                $row['_last'] = true;
                              }
                              if ($idx % 2 === 0) {
                                $row['_even'] = true;
                              } else {
                                $row['_odd'] = true;
                              }
                            
                              if (empty($chunk)) {
                                $output .= '<pre>' . $pdoTools->getChunk('', $row) . '</pre>';
                              } else {
                                $output .= $pdoTools->getChunk($chunk, $row, false);
                              }
                            }
                            
                            return $pdoTools->fastProcess($output);
                              Death_Unlimited
                              01 октября 2017, 19:12
                              0
                              А вложенный MIGx? В чанке второй раз запускать этот снипет и им через data выводить? И если под:
                              даже больше:
                              вы имеете в виду то что все символы json строки вложенного MIGx переводятся в нижний регистр, то согласен) А у меня к примеру во втором MIGx ссылка на видео youtube регистрозависимая, и как теперь ее выводить?

                              [{" migx_id":"1","youtube_video":"h1yhmaktori"},{"migx_id":"2","youtube_video":"asddasdsa2312312"}]
                              Еще и какой-то пробел появился перед migx_id.

                              Сейчас в чанке через data попробую, может тогда все нормально будет.
                                Алексей Карташов
                                01 октября 2017, 19:51
                                0
                                В чанке второй раз запускать этот снипет и им через data выводить?
                                Ну да, почему нет?

                                все символы json строки вложенного MIGx переводятся в нижний регистр
                                ненене! ничего никуда принудительно не переводится.

                                вы имеете в виду то что
                                Я имею в виду, что этому сниппету можно скормить:
                                — обычный массив,
                                — json-строку,
                                — название migx'ового tv, в значении которого тоже лежит обычный json.

                                И данные можно:
                                — отрендерить,
                                — вернуть как есть в виде обычного массива, чтобы потом делать с ними другие непотребства.

                                Т.е. для примера:
                                этот снипет у вас называется data.renderer, а у документа с id равным 123 в значении migx'овой tv с названием tv.migx лежит вот такой json:
                                [{
                                  "migx_id": "1",
                                  "key1": "value1",
                                  "innerJson": [{
                                    "migx_id": "1",
                                    "key2": "зАбОрЧиК"
                                  }, {
                                    "migx_id": "2",
                                    "key2": "ЗаБоРчИк"
                                  }]
                                }, {
                                  "migx_id": "2",
                                  "key1": "value2",
                                  "innerJson": [{
                                    "migx_id": "1",
                                    "key2": "AbCdEf"
                                  }, {
                                    "migx_id": "2",
                                    "key2": "aBcDeF"
                                  }]
                                }]

                                Тогда вот такой вызов сниппета:
                                <ul>
                                {'data.renderer' | snippet : [
                                  'id' => '123',
                                  'migxtv' => 'tv.migx',
                                  'chunk' => '@INLINE
                                  <li>
                                    <p>{$_idx}. <span>{$key1}</span></p>
                                    <ul>
                                {'data.renderer' | snippet : [
                                  'data' => $innerJson,
                                  'chunk' => '@INLINE <li><span>{$migx_id}</span> <span>{$key2}</span></li>'
                                ]}
                                    </ul>
                                  </li>
                                  ']}
                                <ul>
                                возможно ещё в вызове вложенного сниппета надо кавычки поэкранировать

                                Вернёт вот такой результат:
                                <ul>
                                  <li>
                                    <p>1. <span>value1</span></p>
                                    <ul>
                                      <li><span>1</span> <span>зАбОрЧиК</span></li>
                                      <li><span>2</span> <span>ЗаБоРчИк</span></li>
                                    </ul>
                                  </li>
                                  <li>
                                    <p>2. <span>value2</span></p>
                                    <ul>
                                      <li><span>1</span> <span>AbCdEf</span></li>
                                      <li><span>2</span> <span>aBcDeF</span></li>
                                    </ul>
                                  </li>
                                </ul>

                                В чанке доступны:
                                $_idx — порядковый номер
                                $_total — сколько строк всего
                                $_first — это понятно
                                $_last — это тоже
                                $_even — чётная строка
                                $_odd — нечётная строка
                                  Death_Unlimited
                                  01 октября 2017, 20:02
                                  0
                                  Не прочел этого сообщения прежде чем предыдущее написать, сейчас попробую еще раз, отпишусь если не отрублюсь за клавиатурой))
                                    Death_Unlimited
                                    01 октября 2017, 20:20
                                    0
                                    Прошу прощения за дурацкий наверное вопрос, но вот такой вот формат экранирования кавычек в Fenom сработает?
                                    {\'migxFenom\' | snippet : [
                                    \'data\'=>\'video\',
                                    \'chunk\'=>\'@INLINE тут код\'
                                    ]}
                                      Алексей Карташов
                                      01 октября 2017, 20:21
                                      0
                                      ну, по логике, должен) но я вложенные inline-чанки не тестировал, может там как-то и по другому надо
                                        Death_Unlimited
                                        01 октября 2017, 20:34
                                        0
                                        Что-то вообще ничего не выводит, и логи пустые даже не знаю куда смотреть.
                                        Видимо:
                                        if (!is_array($data)) { return ''; }
                                        Скину полностью сюда содержимое чанка, он тестовый так что особо не пугайтесь)

                                        {'migxFenom' | snippet : [
                                        'migxtv'=>'migx_video_slider',
                                        'chunk'=>'@INLINE 
                                        						<li>
                                        {\'migxFenom\' | snippet : [
                                        \'data\'=>\'video\',
                                        \'chunk\'=>\'@INLINE 
                                        							<a class="fancybox fancybox.iframe video" href="https://www.youtube.com/watch?v={$youtube_video}"><img src="https://i1.ytimg.com/vi/{$youtube_video}/mqdefault.jpg" alt=""></a>
                                        							<span>{$title_name}
                                        <i>{$address}</i></span>\'
                                        ]}
                                        						</li>']}
                                        br скушивает))
                                          Алексей Карташов
                                          01 октября 2017, 20:36
                                          0
                                          для теста пропишите в сниппете перед этой строкой вот это:
                                          var_dump($data);
                                            Death_Unlimited
                                            01 октября 2017, 20:47
                                            0
                                            Да нет, вроде бы как массив, правда какой-то странный:
                                            array(4) { [0]=> array(4) { ["MIGX_id"]=> string(1) "1"
                                            ["title_name"]=> string(25) "клиент Михаил"
                                            ["address"]=> string(67) "деревня"
                                            ["video"]=> string(98) "[{"MIGX_id":"1","youtube_video":"H1yHmaKTOrI"},
                                            {"MIGX_id":"2","youtube_video":"asddasdsa2312312"}]" } }
                                            переносы строк если что это уже я тут сделал. Обычно массив же в () таких скобках выводится.

                                            Зато сейчас вижу что действительно, никуда регистр символов во втором MIGx не делся))
                                              Death_Unlimited
                                              01 октября 2017, 21:09
                                              0
                                              В общем дело не в экранированиии, попытался во втором вызове вынести вывод в файловый чанк, то же самое. Скорей всего if (!is_array($data)) { return ''; }, я со своим снипетом тоже чутка помучался, правда у меня ошибки сыпались хотя бы в лог, а тут просто ничего не выводит. Кстати если поменять на if (!is_array($data)) { return var_dump($data); } то вывод NULL, а вот так вот if (!is_array($data)) { return print_r($data); } выводит 1. И я не знаю как вы, а я наверное спать уже, утро вечера удалее как говорится) Так что спокойной ночи вам, завтра со свежими идеями лучше продолжать.
                                                Death_Unlimited
                                                01 октября 2017, 21:20
                                                0
                                                Так в общем это мой косяк, засыпаю видать уже)) Ошибок понаделал просто капец, перед уходом только увидел, все работает спасибо огромное)
                                                {\'migxFenom\' | snippet : [
                                                \'data\'=>\'video\',		//что я пытался сюда передать сам не знаю))
                                                \'chunk\'=>\'@INLINE
                                      Death_Unlimited
                                      01 октября 2017, 19:28
                                      0
                                      Нет, к сожалению если в чанке в data задать тег вложенного поля MIGx, то на выходе получаем вообще ничего. А так спасибо, если вы не против я некоторые моменты возьму на доработку своего сниппета)
                                    Алексей Ерохин
                                    01 октября 2017, 17:50
                                    -1
                                    Третий параметр это fastMode
                                    Быстрый режим обработки чанков. Все необработанные теги (условия, сниппеты и т.п.) будут вырезаны.
                                      Алексей Ерохин
                                      01 октября 2017, 17:54
                                      -1
                                      А зачем вы используете fastProcess? getChunk вызывает process или fastProcess, в зависимости, как раз. от fastMode
                                        Death_Unlimited
                                        01 октября 2017, 18:11
                                        0
                                        Вот в этой теме цитирую

                                        Cyrax_02 11 декабря 2013, 14:31 # 0
                                        Учитывая, что время работы парсера в сабжевых тестах не учитывается, получаем:

                                        1)

                                        $modx->pdoTools->getChunk($chunkName, array_merge($placeholders, $modx->placeholders), false);

                                        // время: X сек (чанк обрабатывается полностью)
                                        2)

                                        $modx->pdoTools->getChunk($chunkName, $placeholders, false);

                                        // время: 0.5X сек + время обработки $modx->placeholders парсером modx (чанк обрабатывается полностью)
                                        3)

                                        $modx->pdoTools->getChunk($chunkName, $placeholders, true);

                                        // время: 0.2X сек (вложенные чанки и прочие теги не обрабатываются)
                                        4)

                                        $html = $modx->pdoTools->getChunk($chunkName, $placeholders, false);
                                        $html = $modx->pdoTools->fastProcess($html);

                                        // время: 0,5X (чанк обрабатывается полностью)
                                        тестировали как я понял скорость обработки, ну я и глядя на самые маленькие цифры по обработке и с условием что «чанк обрабатывается полностью» и скопипастил оттуда этот кусок кода, при сознаюсь чем даже толком не разобравшись во всех тонкостях. Но как видите:
                                        $html = $modx->pdoTools->getChunk($chunkName, $placeholders, false);
                                        	$html = $modx->pdoTools->fastProcess($html);
                                        
                                        	// время: 0,5X (чанк обрабатывается полностью)
                                          Death_Unlimited
                                          01 октября 2017, 18:14
                                          0
                                          Кстати уже и косяк нашел.

                                          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);
                                          }
                                            TITAN-UZ
                                            01 марта 2019, 21:09
                                            0
                                            Встав пожалуйста окончательный код
                                        R2m0x94 (Vasily)
                                        09 апреля 2020, 19:47
                                        0
                                        Исходя из решения сделал подсчёт 3-x тв с изображениями, если кому-то пригодится. Так как права у всех разные, поэтому столько тв в чанке сниппета pdoPage.
                                        {set $image = $_pls['tv.image']}
                                            {if $image != ''}{set $image = 1}{/if}
                                            {set $rows = $_pls['tv.img']}
                                            {set $owrs = $_pls['tv.getimg']}
                                            
                                            {set $idx = 0}
                                            {foreach $owrs as $idxArr => $owr}
                                                {set $owr['idx'] = $idx++} {* idx от созданной переменной с инкриментом*}
                                                {set $row['idxForeach'] = $row@index} {* idx от foreach*}
                                                {set $idxArr = $idxArr ~ $idxArr}
                                            {/foreach}
                                            {if $idxArr != ''}{set $idxArr = $idx}{else}{set $idxArr = 0}{/if}
                                            
                                            {foreach $rows as $idF => $row}
                                                {set $owr['idx'] = $idx++} {* idx от созданной переменной с инкриментом*}
                                                {set $row['idxForeach'] = $row@index} {* idx от foreach*}
                                                {set $idF = $idF ~ $idF}
                                            {/foreach}
                                            {if $idF != ''}{set $idF = $idx}{else}{set $idF = 0}{/if}
                                            {set $total = $image + $idF + $idxArr}
                                        Если у кого-то есть решение, как оптимизировать код, чтобы он стал меньше, то сочту за честь
                                          Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
                                          48