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

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


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

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

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

Если же у Вас в примере подразумевается несколько простых массивов, тот факт, что выводится только последний элемент логичен. Имя плейсхолдера у Вас одно и тоже, следовательно при отправке массивов в плейсхолдер — оно заменяется. Подробнее код можете написать?
    Андрей
    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);
    			}
    }
    
    }
    Вот как мне доработать код, чтобы я мог в чанке отправки письма менеджеру и покупателю вставить плейсхолдеры, чтобы вывести и опцию и ее количество? и остальные также аналогично как получить?
      Александр
      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
        Андрей
        20 октября 2016, 12:13
        0
        Спасибо, Александр. Ваш код, при вставке его в msGetOrder выводит все правильно, но на странице: Спасибо, что вы сделали заказ..." А как мне его подвязать именно к тому, чтобы мне на почту приходила эта информация. То есть к чанкам tpl.msEmail.new.manager и tpl.msEmail.new.user?
          Александр
          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>
            Андрей
            20 октября 2016, 12:43
            0
            Во, огонь… все работает. Спасибо Вам огромное!
      Сергей Шлоков
      20 октября 2016, 15:40
      0
      Метод toPlaceholders() как раз предназначен для многомерных массивов. Я в своё время подробно писал про эти методы.
        Александр
        21 октября 2016, 09:32
        0
        Я не исключаю такой вариант, сам не проверял, спорить не стану. Процитировал офф доку, и ссылку на нее дал.
          Сергей Шлоков
          21 октября 2016, 09:42
          0
          Процитировал офф доку, и ссылку на нее дал.
          Процитировал доку про метод setPlaceholders(), ссылку дал на метод toPlaceholder(), а разговор вёл про toPlaceholders(). Как говорится «Бац-бац и мимо».
            Андрей
            21 октября 2016, 09:53
            0
            Сергей, я как раз по Вашей инструкции пытался делать, но неправильно))
              Сергей Шлоков
              21 октября 2016, 09:57
              0
              Это не инструкция, а перевод официальной документации.
              Неправильный перевод или пытался сделать неправильно?
                Андрей
                21 октября 2016, 09:58
                0
                Пытался сделать неправильно…
              Александр
              21 октября 2016, 09:56
              0
              Не думал, что разница в этом столь многозначительна. Смотрел, что работает с массивами, и случайно клацнул не на ту вкладку (когда вставлял ссылку здесь). В любом случае старался помочь человеку, и вроде как получилось…
                Андрей
                21 октября 2016, 09:57
                0
                Да, Вам большое спасибо. Все получилось, благодаря Вашей помощи.
        Константин Ильин
        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.');
          Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
          15