Нужна помощь перевести с фенома на php

Приветствую!
Такую конструкцию сделать на пхп
{if $packs = ($product.id | resource:"sizes")}
                              {foreach json_decode($packs, true) as $pack}
                                {if $pack.MIGX_id == $product.options.pack}
                                  {set $pack_count = $pack.count}
                                  {set $pack_type = $pack.pack_type}
                                {/if}
                              {/foreach}
                            {/if}
Подкину на кофе на юмани.
Студия Сергея Сергеевича
modx.pro
563
0

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

Артур Шевченко
21 января 2022, 21:39
0
if($id){return  array();}
$resource = $modx->getObject('modResource', $id);
$sizes = json_decode($resource->getTVValue('sizes'),1);
$result  = array();
foreach($sizes as $size){
 if ($size['MIGX_id'] == $pack){
       $result['pack_count'] = $size['count'];
       $result['pack_type'] = $size['pack_type'];
  }
}
return $result;
Вызывать как обычный сниппет с параметрами $id и $pack.Возвращает массив. Ну и код не проверял, но вроде должен работать.
    Вот шаблон для отправки письма с заказом с конструкцией на феноме
    {extends 'tpl.msEmail'}
    
    {block 'logo'}
        <a href="{$site_url}">
            <img style="{$style.logo}"
                 src="{$site_url}/assets/templates/cuptrade/public/assets/cuptrade/img/logo.jpg"
                 alt="{$site_url}"
                 width="279" height="62"/>
        </a>
    {/block}
    
    {block 'products'}
        <table style="width:90%;margin:auto;">
            <thead>
            <tr>
                <th> </th>
                <th style="{$style.th}">{'ms2_cart_title' | lexicon}</th>
                <th style="{$style.th}">{'ms2_cart_count' | lexicon}</th>
                <th style="{$style.th}">Вид тары</th>
                <th style="{$style.th}">{'ms2_cart_cost' | lexicon}</th>
            </tr>
            </thead>
            {foreach $products as $product}
                <tr>
                    <td style="{$style.th}">
                        {if $product.thumb?}
                            <img src="{$site_url}{$product.thumb}"
                                 alt="{$product.pagetitle}"
                                 title="{$product.pagetitle}"
                                 width="120" height="90"/>
                        {else}
                            <img src="{$site_url}{$assets_url}templates/cuptrade/public/assets/cuptrade/img/logo.jpg"
                                 alt="{$product.pagetitle}"
                                 title="{$product.pagetitle}"
                                 width="120"/>
                        {/if}
                    </td>
                    <td style="{$style.th}">
                        {if $product.id?}
                            <a href="{$product.id | url : ['scheme' => 'full']}"
                               style="{$style.a}">
                                {$product.name}
                            </a>
                        {else}
                            {$product.name}
                        {/if}
                        {if $product.options?}
                            <div class="small">
                                {*$product.options | join : '; '*}
                                {if $packs = ($product.id | resource:"sizes")}
                                  {foreach json_decode($packs, true) as $pack}
                                    {if $pack.MIGX_id == $product.options.pack}
                                      {set $pack_count = $pack.count}
                                      {set $pack_type = $pack.pack_type}
                                    {/if}
                                  {/foreach}
                                {/if}
                                {if $product.options.pack}<span class="option-separator">Упаковка: {$pack_type}</span>. {/if}
                                {if $opts = json_decode($product.id|resource:"opts", true)}
                                  {foreach $opts as $opt}
                                    {set $opt_prices = json_decode($opt.prices, true)}
                                    {set $opt_min_price = 0}
                                    {set $opt_max_price = 0}
                                    {set $checked = false}
                                    {foreach $opt_prices as $opt_price}
                                      {if !$opt_min_price || $opt_min_price > $opt_price.price}
                                        {set $opt_min_price = $opt_price.price}
                                      {/if}
                                      {if !$opt_max_price || $opt_max_price < $opt_price.price}
                                        {set $opt_max_price = $opt_price.price}
                                      {/if}
                                    {/foreach}
                                    {foreach $product.options.opts as $op}
                                      {if $op == $opt.MIGX_id}
                                        {set $checked = true}
                                      {/if}
                                    {/foreach}
                                    <span class="option-separator">Дополнительно: {$opt.option_type}</span>. 
                                  {/foreach}
                                {/if}
                            </div>
                        {/if}
                    </td>
                    <td style="{$style.th}">{$product.count} {'ms2_frontend_count_unit' | lexicon}</td>
                    <td style="{$style.th}">{$pack_type} </td>
                    <td style="{$style.th}">{$product.price} {'ms2_frontend_currency' | lexicon}</td>
                </tr>
            {/foreach}
            <tfoot>
            <tr>
                <th colspan="2"></th>
                <th style="{$style.th}">
                    {$total.cart_count} {'ms2_frontend_count_unit' | lexicon}
                </th>
                <!--th style="{$style.th}">
                    {$total.cart_weight} {'ms2_frontend_weight_unit' | lexicon}
                </th-->
                <th style="{$style.th}">
                    {$total.cart_cost} {'ms2_frontend_currency' | lexicon}
                </th>
            </tr>
            </tfoot>
        </table>
        <h3 style="{$style.h}{$style.h3}">
            {'ms2_frontend_order_cost' | lexicon}:
            {if $total.delivery_cost}
                {$total.cart_cost} {'ms2_frontend_currency' | lexicon} + {$total.delivery_cost}
                {'ms2_frontend_currency' | lexicon} =
            {/if}
            <strong>{$total.cost}</strong> {'ms2_frontend_currency' | lexicon}
        </h3>
    {/block}
    надо сделать чтобы в плагине добавлялось в заказ тара
    'pack_type'=>$pack_type,
    код плагина
    <?php
    
    require_once 'contacts.php';
    
    class Leads
    {
        /** @var modX $modx */
        public $modx;
        /** @var amoCRM $amoCRM */
        public $amoCRM;
        /** @var amoCRMTools $tools */
        public $tools;
    
        public $contactsController;
    
        public function __construct($modx, $amo)
        {
            $this->modx = $modx;
            $this->amoCRM = $amo;
            $this->tools = $amo->tools;
            $this->contactsController = new Contacts($this->modx, $amo);
        }
    
        public function getLeads($ids = array(), $query = array())
        {
            $leads = array();
            if (is_numeric($ids)) {
                $ids = array($ids);
            }
            $data = array('id' => $ids, 'query' => $query);
            if ($result = $this->tools->sendRequest('/api/v4/leads', $data, 'GET')) {
                foreach ($result['_embedded']['leads'] as $lead) {
                    $leads[$lead['id']] = $lead;
                }
            }
            return $leads;
        }
    
        /**
         * Убедимся что все передаваемые кастомные поля в наличии в CRM
         * Отфильтруем пустые поля
         * ПОдготовим окончательный массив передаваемых полей
         *
         * @param $data
         *
         * @return array
         */
        public function prepareOrder($data)
        {
            $order = array();
            $default_fields = $this->amoCRM->config['defaultOrderFields'];
            //Убедился в наличии кастомных полей. Дополнительные данные точно сохранятся в CRM
            $this->amoCRM->checkOrdersCustomFields(array_keys($data), $this->amoCRM->config['autoCreateOrdersCustomFields']);
    
            foreach ($data as $key => $value) {
                if ($this->amoCRM->config['skipEmptyFields'] and empty($value)) {
                    continue;
                }
                if (in_array($key, $default_fields)) {
                    $order[$key] = $value;
                } else {
                    if ($custom_field_id = $this->amoCRM->getOrdersCustomFieldId($key)) {
                        $custom_field = array(
                            'field_id' => $custom_field_id,
                            'values' => $this->amoCRM->prepareOrderCustomFieldValue($value),
                        );
                        $order['custom_fields_values'][] = $custom_field;
                    } else {
                        $order[$key] = $value;
                    }
                }
            }
            return $order;
        }
    
        /**
         * Добавление сделки в CRM
         * Или ее обновление.
         * @param array $data
         *
         * @return string|null
         */
        //Зачем в один метод засунули создание и обновление - загадка
        public function addLead($data = array())
        {
            if (empty($data['responsible_user_id'])) {
                $data['responsible_user_id'] = (int)$this->amoCRM->config['defaultResponsibleUserId'];
            }
    
            //Обновление заказа
            if (isset($data['order_id'])) {
                $data['id'] = (int)$data['order_id'];
                $data['updated_at'] = time();
                $params = [];
                $params[] = $data;
                $result = $this->tools->sendRequest('/api/v4/leads', $params, 'PATCH');
                if ($result) {
                    return $result['_embedded']['leads'][0];
                }
                return null;
            }
    
            //Новый заказ
            $params = [];
            $params[] = $data;
            $result = $this->tools->sendRequest('/api/v4/leads', $params, 'POST');
            if ($result) {
                return $result['_embedded']['leads'][0];
            }
            return null;
        }
    
        /**
         * Добавление информации о заказе.
         *
         * @param msOrder $order
         * @param bool $canHold
         *
         * @return bool|int
         */
        public function addOrder(msOrder $order, $canHold = false)
        {
            //Проверка на наличие очередей.  Если разрешены очереди процесс прерывается записью в очередь
            if ($this->tools->checkSQ($canHold)) {
                if ($this->tools->addSQTask(amoCRMTools::SQ_ACTION_ADD_ORDER, $order->get('id'))) {
                    return true;
                }
            }
    
            $goods = array();
            $i = 1;
    
            //Запрос товаров заказа + артикул
            $q = $this->modx->newQuery('msOrderProduct');
            $q->leftJoin('msProductData', 'msProductData', 'msProductData.id = msOrderProduct.product_id');
            $q->where(['order_id' => $order->get('id')]);
            $q->select(['msOrderProduct.*']);
            $q->select(['msProductData.article']);
            $q->prepare();
            $q->stmt->execute();
            $products = $q->stmt->fetchAll(PDO::FETCH_ASSOC);
    
            foreach ($products as $product) {
                //COMMENT:  Почему здесь использован лексикон?
                            
            $goods[] = $this->modx->lexicon('amocrm_order_product_row', array(
                    'idx' => $i,
                    'article' => $product['article'],
                    'name' => $product['name'],
                    'price' => $product['price'],
                    'count' => $product['count'],
                    'pack_type'=>$pack_type,
                    'cost' => $product['cost'],
                    'options' => $this->tools->multiImplode('; ', json_decode($product['options'], true)),
                    'currency' => $this->modx->lexicon('ms2_frontend_currency'),
                    'unit' => $this->modx->lexicon('ms2_frontend_count_unit'),
                ));
                $i++;
            }
    
            $profileAdditions = array();
            //Базовые поля заказа
            $fields = array(
                'name' => $this->modx->lexicon('amocrm_order_name', array('num' => $order->get('num'))),
                'price' => $order->get('cost'),
                'pipeline_id' => $this->amoCRM->config['pipeline'],  //amocrm_pipeline_id
                'date_create' => strtotime($order->get('createdon')),
            );
    
    
            //Проверяю запись о сделке по данному заказу
            //Если такая сделка уже есть - выбираю данные для последующей работы
            $link = $this->modx->getObject('amoCRMLead', array('order' => $order->get('id')));
    
            if ($link) {
                $fields['order_id'] = (int)$link->get('order_id');
                $fields['pipeline_id'] = $link->get('pipeline_id');
            }
    
            //Проверяем свойство properties в msOrder. По умолчанию оно пустое.  В каком месте записывается и зачем пока не понятно
            //Если такое свойство заполнено данными заказа, оно перезаписывает поля заказа.
            //В новом заказе не участвует
            $propElem = $this->amoCRM->config['orderPropertiesElement'];  //Название элемента в свойствах заказа -  amoCRMFields
            $orderFieldsValues = $order->toArray();
            if (isset($orderFieldsValues['properties'][$propElem]) and is_array($orderFieldsValues['properties'][$propElem])) {
                $orderFieldsValues = array_replace($orderFieldsValues, $orderFieldsValues['properties'][$propElem]);
                if (isset($orderFieldsValues['properties'][$propElem]['contactFields']) and is_array($orderFieldsValues['properties'][$propElem]['contactFields'])) {
                    $profileAdditions = $orderFieldsValues['properties'][$propElem]['contactFields'];
                }
                unset($orderFieldsValues['properties'][$propElem]);
            }
    
            //В массив данных по заказу добавляем разрешенные дополнительные поля из properties заказа.
            //В новом заказе не участвует
            foreach ($this->amoCRM->config['defaultOrderFields'] as $field) {
                if (isset($orderFieldsValues[$field]) and !empty($orderFieldsValues[$field])) {
                    $fields[$field] = $orderFieldsValues[$field];
                }
            }
    
    
            //Проверяю индивидуальные настройки для конкретных категорий товара.  По умолчанию вернет пустой массив
            $fieldsByCategory = $this->amoCRM->findCategoryPipeline($order);
            if (!$this->amoCRM->config['responsible_id_priority_category']) {
                unset($fieldsByCategory['responsible_user_id']);
            }
    
            $fields = array_merge($fields, $fieldsByCategory);
    
            //Добавляю в miniShop2 новые статусы заказа из указанной воронки
            //Делается один раз при первом подключении
            //Логика так себе. Подобные вещи нужно делать из отдельного административного интерфейса.
    
            $addMiniShopPipeline_result = $this->amoCRM->addMiniShopPipeline($fields['pipeline_id']);
    
            if (!$addMiniShopPipeline_result) {
                $this->amoCRM->log('Error adding MS2 pipeline to AmoCRM');
                return false;
            }
    
            //Получаю статус для новой сделки в указанной воронке.  По умолчанию amocrm_new_order_status_id
            $amoStatus = $this->amoCRM->getLeadStatusId($order->get('status'), $fields['pipeline_id']);
            if ($amoStatus) {
                $fields['status_id'] = $amoStatus;
            }
    
            if ($payment = $order->getOne('Payment')) {
                $paymentName = $payment->get('name');
            } else {
                $paymentName = '';
            }
    
            if ($delivery = $order->getOne('Delivery')) {
                $deliveryName = $delivery->get('name');
            } else {
                $deliveryName = '';
            }
    
            /* @TODO Продумать механизм добавления дополнительных полей без жесткого их указания в коде */
            $customFields = array(
                'goods' => implode("\n", $goods),
                'payment' => $paymentName,
                'delivery' => $deliveryName,
            );
            $customOrderFields = array();
            foreach ($this->amoCRM->tools->parseFieldsSet($this->amoCRM->config['orderFields']) as $k) {
                $v = trim($orderFieldsValues[$k]);
                if ($v) {
                    $customOrderFields[$k] = $v;
                }
            }
            if ($address = $order->getOne('Address')) {
                $prefix = $this->amoCRM->config['orderAddressFieldsPrefix'];
                foreach ($this->tools->parseFieldsSet($this->amoCRM->config['orderAddressFields']) as $k) {
                    $v = trim($address->get($k));
                    if ($v) {
                        $customFields[$prefix . $k] = $v;
                    }
                }
            }
            $customFields = array_replace($customOrderFields, $customFields);
    
            $data = $this->prepareOrder(array_replace($fields, $customFields));
            
            if (!empty($data['contact_email'])){
              $data['email'] = $data['contact_email'];
            }
    
            //Ищу и добавляю контакт к сделке
            $contact = $this->contactsController->searchContact($address->get('phone'), $data['email'] ?? null);
            if (!empty($contact)) {
                $data['_embedded']['contacts'][0]['id'] = $contact['id'];
            } else {
                //Если контакт не найден создаем принудительно
                $contact = $this->contactsController->addContact($order->User->Profile->toArray());
                if (!empty($contact)) {
                    if (is_array($contact)) {
                        $data['_embedded']['contacts'][0]['id'] = $contact['id'];
                    }
    
                    if (is_numeric($contact)) {
                        $data['_embedded']['contacts'][0]['id'] = $contact;
                    }
                }
            }
    
            //Запускам событие обработки данных перед отправкой заказа
            $response = $this->tools->invokeEvent('amocrmOnBeforeOrderSend', array(
                'lead' => $data,
                'msOrder' => $order,
                'msOrderId' => $order->get('id'),
                'amoCRM' => $this,
            ));
    
            //Поддержка старого кода
            if (isset($response['data']['lead']['custom_fields'])) {
                $custom_fields_values = $response['data']['lead']['custom_fields'];
            }
    
            if (isset($response['data']['lead']['custom_fields_values'])) {
                $custom_fields_values = $response['data']['lead']['custom_fields_values'];
            }
    
    
            if (isset($data['custom_fields_values']) && isset($custom_fields_values)) {
                foreach ($response['data']['lead']['custom_fields_values'] as $custom_field) {
                    $data['custom_fields_values'][] = $custom_field;
                }
                unset($response['data']['lead']['custom_fields_values']);
            }
    
            $data = array_replace($data, $response['data']['lead']);
    
            //Отправляю заказ в CRM
            $leadData = $this->addLead($data);
            if (!empty($leadData['id'])
                and ($lead = $this->modx->getObject('amoCRMLead', array('order' => $order->get('id')))
                    or $lead = $this->modx->newObject('amoCRMLead')
                )
            ) {
                $lead->set('order', $order->get('id'));
                $lead->set('order_id', $leadData['id']);
                $lead->set('pipeline_id', $data['pipeline_id']);
                $lead->save();
            }
    
            $this->tools->invokeEvent('amocrmOnOrderSend', array(
                'lead' => $data,
                'amoCRMLead' => $lead,
                'amoCRM' => $this,
                'amoCRMResponse' => $leadData,
            ));
    
            if ($address and $address->get('phone')) {
                if (empty($profileAdditions['phone']) and empty($profileAdditions['phone'])) {
                    $profileAdditions['phone'] = $address->get('phone');
                    $profileAdditions['телефон'] = $address->get('phone');
                }
            }
    
            foreach ($this->tools->parseFieldsSet($this->amoCRM->config['userFields']) as $field) {
                if (empty($profileAdditions[$field]) and !empty($data[$field])) {
                    $profileAdditions[$field] = $data[$field];
                }
            }
            $contactData = $this->contactsController->prepareProfile($order->get('user_id'), $profileAdditions);
            $this->contactsController->addContact($contactData, $order->get('user_id'), array($leadData['id']));
    
            return $leadData['id'];
        }
    
        public function changeOrderStatus($data)
        {
            $link = '/api/v4/leads';
            $data = [$data];
            $result = $this->tools->sendRequest($link, $data, 'PATCH');
            return $result;
        }
    
        public function changeOrderStatusInAmo($ms2OrderId, $ms2StatusId, $canHold = false)
        {
            if (defined('AMOCRM_WEBHOOK_MODE')
                or ($ms2StatusId == $this->amoCRM->config['msStatusNewOrder'] and !$this->amoCRM->config['updateOrderOnChangeStatus'])
            ) {
                return array();
            }
    
            if ($this->tools->checkSQ($canHold)) {
                $data = array(
                    'ms2OrderId' => $ms2OrderId,
                    'ms2StatusId' => $ms2StatusId,
                );
                if ($this->tools->addSQTask(amoCRMTools::SQ_ACTION_CHANGE_ORDER_STATUS, $ms2OrderId, $data)) {
                    return true;
                }
            }
    
            $result = array();
            if ($lead = $this->modx->getObject('amoCRMLead', array('order' => $ms2OrderId)) and $lead->get('order_id')) {
                $amoLeads = $this->getLeads($lead->get('order_id'));
                $amoLead = array_shift($amoLeads);
                if (!empty($amoLead['pipeline_id'])) {
                    if ($lead->get('pipeline_id') != $amoLead['pipeline_id']) {
                        $lead->set('pipeline_id', $amoLead['pipeline_id']);
                        $lead->save();
                    }
    
                    $status = $this->modx->getObject(
                        'amoCRMOrderStatus',
                        array('status' => $ms2StatusId, 'pipeline_id' => $amoLead['pipeline_id'])
                    );
    
                    if ($status) {
                        $data['id'] = $lead->get('order_id');
                        $data['last_modified'] = $lead->get('updatedon');
    
                        if (!$data['last_modified']) {
                            $data['last_modified'] = time();
                        }
    
                        $data['status_id'] = $status->get('status_id');
                        $data['pipeline_id'] = $status->get('pipeline_id');
    
                        $result = $this->changeOrderStatus($data);
                    } else {
                        $this->modx->log(xPDO::LOG_LEVEL_ERROR,
                            'Status link for MS2 status '
                            . $ms2StatusId . ' and amoCRM pipeline id ' . $amoLead['pipeline']['id']
                            . ' not found. Status in amoCRM for order ' . $ms2OrderId . ' hasn\'t changed.');
                        return array('success' => true);
                    }
                } else {
                    return array('success' => true);
                }
            } else {
                return array('success' => true);
            }
    
            return $result;
        }
    
        public function changeOrderStatusInMS2($order, $status)
        {
            if (!$this->tools->getMS2()) {
                return false;
            }
    
            $order = $this->modx->getObject('amoCRMLead', array('order_id' => $order));
            $status = $this->modx->getObject('amoCRMOrderStatus', array('status_id' => $status));
    
            if ($order && $status) {
                /** @var msOrder $msOrder */
                $msOrder = $order->getOne('Order');
    
                if ($msOrder) {
                    if (!empty($msOrder->get('status'))) {
                        return $this->tools->ms2->changeOrderStatus($msOrder->get('id'), $status->get('status'));
                    }
                }
                // Если соответствующий сделке заказ не найден, ничего не делаем и не возвращаем ошибку
                return true;
    
            } else {
                return true;
            }
        }
    }
      Значение pack получено таким образом
      $this->tools->multiImplode('; ', json_decode($product['options'], true))

      Всем спасибо, заявка закрыта.
        Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
        3