Добавить массив в плейсхолдер Решено


День добрый.
Подскажите, у меня есть несколько массивов типа:
array { 
	["value"]=> "Название параметра" 
	["count"]=> "3" 
}
array { 
	["value"]=> "Название параметра 2" 
	["count"]=> "1" 
}
array { 
	["value"]=> "Название параметра 3" 
	["count"]=> "2" 
}


Как мне их добавить в плейсхолдер, чтобы потом вывести в другом месте?
Пытался использовать
$modx->toPlaceholders();
Но либо ничего не выводит, либо только последний элемент
19 октября 2016, 22:44    Андрей   
1    409 0

Комментарии (15)

  1. Александр 20 октября 2016, 06:55 # 0
    В документации написано, что вложенные массивы не могут использоваться методом toPlaceholders.
    ...the $placeholders array can not be deeply nested. It must be a simple associative array.
    Могу только предложить пройтись по ним циклом.

    Если же у Вас в примере подразумевается несколько простых массивов, тот факт, что выводится только последний элемент логичен. Имя плейсхолдера у Вас одно и тоже, следовательно при отправке массивов в плейсхолдер — оно заменяется. Подробнее код можете написать?
    1. Андрей 20 октября 2016, 09:29 # 0
      Да, конечно.
      В общем задача такая. При заказе товаров пользователь набирает себе ряд опций (сайт мебели), из которых он комплектует себе свой товар.
      В саму корзину опции передаются нормально, а вот в письмах менеджеру и покупателю ничего не приходит. Посмотрев в сниппет msGetOrder я нашел там такой код:
      // Additional properties of product
      	$options = !is_array($row['options'])
      		? $modx->fromJSON($row['options'])
      		: $row['options'];
      	if (!empty($options) && is_array($options)) {
      		foreach ($options as $key => $value) {
      			$row['option.'.$key] = $value;
      		}
      	}
      далее выведя
      print_r($options);
      Я получил такой массив со всеми опциями:
      Array (
      	[width] => 800 
      	[depth] => 450 
      	[height] => 2000 
      	[additional_modules] => Array ( 
      		[0] => Array ( [value] => Блок ящиков ширина 40-60 см. [count] => 1 ) 
      		[1] => Array ( [count] => 0 ) 
      		[2] => Array ( [value] => Угловой элемент правый [count] => 2 ) 
      		[3] => Array ( [count] => 0 ) 
      		[4] => Array ( [count] => 0 ) 
      		[5] => Array ( [value] => Приставной элемент №3 ширина 60 см [count] => 1 ) 
      		[6] => Array ( [count] => 0 ) 
      	) 
      	[driving_filling] => Array (
      		[0] => Array ( [value] => Шкаф отделения 60+60 ширина с доп. отделением 120 см ) 
      	) 
      	[additional_equipment_cabinet] => Array ( 
      		[0] => Array ( [count] => 0 ) 
      		[1] => Array ( [value] => Шлегель [count] => 3 ) 
      		[2] => Array ( [count] => 0 ) 
      		[3] => Array ( [value] => Штанга 40-60 см. [count] => 1 ) 
      		[4] => Array ( [count] => 0 ) 
      		[5] => Array ( [count] => 0 ) 
      		[6] => Array ( [count] => 0 ) 
      		[7] => Array ( [value] => Полка 70 см. [count] => 1 ) 
      		[8] => Array ( [count] => 0 ) 
      	) 
      	[colour_housing] => Array (
      		[0] => Array ( [value] => Вудлайн мокко ) 
      	) 
      	[color_profile] => Array (
      		[0] => Array ( [value] => Шампань ) 
      	) 
      	[color_doors] => Array ( 
      		[0] => Array ( [value] => Ясень Шимо Светлый ) 
      	) 
      )
      Вот первые 3 опции (width, depth и height) получил таким образом:
      $width = $options['width'];
      $depth = $options['depth'];
      $height = $options['height'];
      
      $modx->toPlaceholder('order_width',$width);
      $modx->toPlaceholder('order_depth',$depth);
      $modx->toPlaceholder('order_height',$height);
      В итоге в письмах указываю просто плейсхолдеры и получаю нужные опции в письмах.
      А вот с остальными опциями возникают сложности. На примере одной и них:
      $additional_modules = $options['additional_modules']; // Получаю в переменную такой массив:
      [additional_modules] => Array ( 
      		[0] => Array ( [value] => Блок ящиков ширина 40-60 см. [count] => 1 ) 
      		[1] => Array ( [count] => 0 ) 
      		[2] => Array ( [value] => Угловой элемент правый [count] => 2 ) 
      		[3] => Array ( [count] => 0 ) 
      		[4] => Array ( [count] => 0 ) 
      		[5] => Array ( [value] => Приставной элемент №3 ширина 60 см [count] => 1 ) 
      		[6] => Array ( [count] => 0 ) 
      	)
      
      Здесь те опции у которых есть [value] — и были выбраны пользователем, [count] — количество. Соответственно, я далее иду по массиву циклом foreach:
      if (!empty($additional_modules) && is_array($additional_modules)) {
      		foreach ($additional_modules as $key => $innervalue) {
      			if (count($innervalue) == 2) { // Здесь я отсекаю только те массивы, которые имеют значение [value], то есть их длина равна 2
      				$c = '';
      				foreach($innervalue  as  $inner_key => $value) {
      					if ($inner_key == 'value') {
      						print_r("<pre>$value</pre>"); // А здесь я получаю в каждой итерации значение опции (Блок ящиков ширина 40-60 см., Угловой элемент правый, Приставной элемент №3 ширина 60 см)
      						$c.= $value .', ';					
      					}
      				}
      	$modx->toPlaceholders('additional_modules',$c,'my','.');
      	print_r($c);
      			}
      }
      
      }
      Вот как мне доработать код, чтобы я мог в чанке отправки письма менеджеру и покупателю вставить плейсхолдеры, чтобы вывести и опцию и ее количество? и остальные также аналогично как получить?
      1. Александр 20 октября 2016, 11:51 # +1
        if (!empty($additional_modules) && is_array($additional_modules)) {
        		foreach ($additional_modules as $key => $innervalue) {
        			if (count($innervalue) == 2) {
        				$c = '';
        				foreach($innervalue  as  $inner_key => $value) {
        					if ($inner_key == 'value') { //зачем отсекать по значению, если отсекли уже по кол-ву значений выше
        						print_r("<pre>$value</pre>"); //Это рабочий вариант с print_r ?
        						$c.= $value .', ';					
        					}
        				}
        	$modx->toPlaceholders('additional_modules',$c,'my','.');
        	print_r($c);
        			}
        }
        
        }
        Мой вариант:
        /* Тут подразумевается, что pdoTools уже подключен,
        $pdo = $modx->getService('pdoTools');
        */
        $tpl = "optionsTpl"; /*Указываем чанк, который обрабатывает цикл со значениями, 
        например чанк с содержимым "<li>[[+value]] в количестве [[+count]] шт.</li>" выведет нам:
        <li>Блок ящиков ширина 40-60 см. в количестве 1 шт.</li>
        */
        $c = '';
        if (!empty($additional_modules) && is_array($additional_modules)) {
        		foreach ($additional_modules as $key => $innervalue) {
        			if (count($innervalue) == 2) {
        				$c .= $pdo->getChunk($tpl, $innervalue); //Выводим все значения массива в вышеупомянутый чанк
        			}
        		}
        }
        return $c;
        Подробнее про getChunk
        1. Андрей 20 октября 2016, 12:13 # 0
          Спасибо, Александр. Ваш код, при вставке его в msGetOrder выводит все правильно, но на странице: Спасибо, что вы сделали заказ..." А как мне его подвязать именно к тому, чтобы мне на почту приходила эта информация. То есть к чанкам tpl.msEmail.new.manager и tpl.msEmail.new.user?
          1. Александр 20 октября 2016, 12:30 # +1
            Не знаю, откуда Вы это вызываете, но там, где идет установка плейсхолдеров:
            $modx->toPlaceholder('order_width',$width);
            $modx->toPlaceholder('order_depth',$depth);
            $modx->toPlaceholder('order_height',$height);
            допишите:
            $pdo = $modx->getService('pdoTools');
            $tpl = "optionsTpl";
            $c = '';
            if (!empty($additional_modules) && is_array($additional_modules)) {
            		foreach ($additional_modules as $key => $innervalue) {
            			if (count($innervalue) == 2) {
            				$c .= $pdo->getChunk($tpl, $innervalue);
            			}
            		}
            }
            $modx->toPlaceholder('order_options',$c);
            Увы, я с работой miniShop очень слабо знаком. Дал бы более дельный совет, если бы работал с ним.

            Далее в шаблоне указываете например:
            <ul>[[+order_options]]</ul>
            И система зарендерит Вам:
            <ul>
            <li>Блок ящиков ширина 40-60 см. в количестве 2 шт.</li>
            <li>Угловой элемент правый 2 шт.</li>
            <li>Приставной элемент №3 ширина 60 см 1 шт.</li>
            и т.д.
            </ul>
            1. Андрей 20 октября 2016, 12:43 # 0
              Во, огонь… все работает. Спасибо Вам огромное!
      2. Сергей Шлоков 20 октября 2016, 15:40 # 0
        Метод toPlaceholders() как раз предназначен для многомерных массивов. Я в своё время подробно писал про эти методы.
        1. Александр 21 октября 2016, 09:32 # 0
          Я не исключаю такой вариант, сам не проверял, спорить не стану. Процитировал офф доку, и ссылку на нее дал.
          1. Сергей Шлоков 21 октября 2016, 09:42 # 0
            Процитировал офф доку, и ссылку на нее дал.
            Процитировал доку про метод setPlaceholders(), ссылку дал на метод toPlaceholder(), а разговор вёл про toPlaceholders(). Как говорится «Бац-бац и мимо».
            1. Андрей 21 октября 2016, 09:53 # 0
              Сергей, я как раз по Вашей инструкции пытался делать, но неправильно))
              1. Сергей Шлоков 21 октября 2016, 09:57 # 0
                Это не инструкция, а перевод официальной документации.
                Неправильный перевод или пытался сделать неправильно?
                1. Андрей 21 октября 2016, 09:58 # 0
                  Пытался сделать неправильно…
              2. Александр 21 октября 2016, 09:56 # 0
                Не думал, что разница в этом столь многозначительна. Смотрел, что работает с массивами, и случайно клацнул не на ту вкладку (когда вставлял ссылку здесь). В любом случае старался помочь человеку, и вроде как получилось…
                1. Андрей 21 октября 2016, 09:57 # 0
                  Да, Вам большое спасибо. Все получилось, благодаря Вашей помощи.
        2. Константин Ильин 20 октября 2016, 07:31 # 0
          Как написал Александр, массив должен быть одномерным, т.е.
          /*array { 
          	["value"]=> "Название параметра" 
          	["count"]=> "3" 
          }*/
          array { 
          	["Название параметра"]=> "3" 
          }
          
          /*array { 
          	["value"]=> "Название параметра 2" 
          	["count"]=> "3" 
          }*/
          array { 
          	["Название параметра 2"]=> "3" 
          }
          
          Если несколько массивов, то лучше их объединить и передать в toPlaceholders
          $arrOne = array ( 
          	"placeholderOne" => "3" 
          );
          $arrTwo = array (
          	"placeholderTwo" => "5" 
          );
          $array = array_merge($arrOne,$arrTwo);
          $modx->toPlaceholders($array);
          
          //также можно указать любой префикс
          $modx->toPlaceholders($array, 'my.');
          
          Вы должны авторизоваться, чтобы оставлять комментарии.