Артур Шевченко

Артур Шевченко

С нами с 24 мая 2019; Место в рейтинге пользователей: #3
Отправить деньги
28 января 2021, 13:58
0
Сразу оговорюсь это говнокод, а то придут старшие товарищи и начнут тапками меня закидывать. Использовать на свой страх и риск, но у меня работает.
Ссылка имеет вид domain.ru/smeta?order_id=183
На этой странице вызывается сниппет getOrder
{set $order = '!getOrder' | snippet:[
    'order_id' => $.get.order_id
]}
Сниппет возвращает массив, посмотреть что внутри можно так
{$order | print_r}
Сам сниппет выглядит так
<?php
if(!$order_id){return false;}
$pdoTools = $modx->getService('pdoTools');
$orderFields = array('id','num', 'createdon', 
                    'updatedon', 'cart_cost', 
                    'delivery_cost', 'comment', 
                    'status', 'cost');
$orderProductFields = array('id','product_id', 
                            'name', 'count', 
                            'price', 'cost', 'options');
                        
$addressFields = array('city', 'street',
                        'receiver', 'phone',
                        'comment');
$output = array(
    'meta' => [],
    'address' => [],
    'products' => []
    );

$order = $modx->getObject('msOrder', $order_id);
if($order){        
    //заполняем массив основных данных заказа
    for($i = 0; $i < count($orderFields); $i++){
        $output['meta'][$orderFields[$i]] = $order->get($orderFields[$i]); 
    }
    
    //вычисляем срок выполнения заказа
    $output['meta']['duration'] = ceil($output['meta']['cost'] / $modx->getOption('base_cost'));
            
    //заполняем адрес и дополнительные данные
    $address = $order->getOne('Address');
    $properties = $address->get('properties');
    for($i = 0; $i < count($addressFields); $i++){
        if($addressFields[$i] != 'properties'){
            $output['address'][$addressFields[$i]] = $address->get($addressFields[$i]); 
        }else{
            foreach($properties as $name => $prop){
                $output['address'][$name] = $prop; 
            }
        }
    }
    //заполняем продукты
    $products = $order->getMany('Products');
    if($products){
        foreach($products as $key => $product){
            for($i = 0; $i < count($orderProductFields); $i++){
                $output['products'][$key][$orderProductFields[$i]] = $product->get($orderProductFields[$i]); 
            }
        }  
    }
    
    
    //$modx->log(1, 'OUTPUT getUserOrder ' . print_r($output, 1));
    
    if($tpl){
        return $pdoTools->getChunk($tpl, $output);
    }
    //$modx->log(1, print_r($output,1));
    return $output;
}else{
    return false;
}
После вызова сниппет идёт такой код
{if $order}
<p class="h-6"><span class="text-orange">Номер заказа:</span> {$order['meta']['num']}</p>
<p class="h-6"><span class="text-orange">Дата заказа:</span> {$order['meta']['createdon'] | date: 'd.m.Y H:i:s'}</p>
<p class="h-6"><span class="text-orange">Имя заказчика:</span> {$order['address']['receiver']}</p>
{if $_modx->isAuthenticated('mgr') || $.get.admin}
<p class="h-6"><span class="text-orange">Телефон заказчика:</span> <a class="service-link" href="tel:{$order['address']['phone'] | replace:'-':'' }">{$order['address']['phone'] | replace:'-':'' }</a></p>
{/if}
<p class="h-6"><span class="text-orange">Общая стоимость:</span> <span class="jsTotalOrderCost">{$order['meta']['cost']}</span> руб.</p>
<p class="h-6"><span class="text-orange">Срок выполнения:</span> <span class="jsOrderDuration">{$order['meta']['duration']}</span> дн.</p>
<p class="h-6 mb-0"><span class="text-orange">Перечень включенных в состав услуг 
 <small class="small">(в стоимость услуг входит стоимость платных дополнений)</small></span></p>
    {if $_modx->isAuthenticated('mgr') || $.get.admin}
        <div class="pl-0" id="orderWrap">
        {if $order['products']}    
        {set $i = 1}    
        {foreach $order['products'] as $key => $product}
            {set $description = $product['product_id'] | resource: 'desc'}
            {set $introtext = $product['product_id'] | resource: 'introtext'}
            {set $add_cost = $product['product_id'] | resource: 'add_cost'}
            {set $weight = $product['product_id'] | resource: 'weight'}
            {$_modx->parseChunk('@FILE chunks/shop/editOrderProduct.html', [
                'description' => $product['options']['desc']?:$description,
                'introtexxt' => $introtext,
                'index' => $i,
                'add_cost' => $add_cost,
                'price' => $product['price'],
                'weight' => $weight,
                'count' => $product['count'],
                'name' => $product['options']['name']?:$product['name'],
                'cost' => $product['cost'],
                'id' => $product['id'],
                'options' => $product['options'],
                'order_id' => $.get.order_id,
                'total_cost' => $order['meta']['cost'],
                'product_id' => $product['product_id']
            ])}
            {set $i = $i + 1}
        {/foreach}
        {else}
        <p class="h-6 my-3 text-red">Необходимо добавить услуги!</p>
        {/if}
        </div>
         <p class="h-5 mt-3 mb-3">Найти услугу</p>
        {'!AjaxForm' | snippet: [
            'snippet' => 'searchResources',
            'tpl' => '@FILE chunks/shop/editOrderProductTpl.html',
            'form' => '@FILE chunks/forms/searchForm.html',
            'fieldsForSearch' => 'pagetitle,longtitle,menutitle',
            'validate' => 'query:required:minLength=^3^',
            'placeholderPrefix' =>'find.'
        ]}
        <div id="productList"></div>
        <p class="h-5 mt-3 mb-0">Добавить услугу</p>
        <form class="row py-3 jsProductRow border-gray-bottom jsAddForm">
            <div class="jsCommonFields">
                <input type="hidden" name="weight" value="1">
                <input type="hidden" name="order_id" value="{$.get.order_id}">
                <input type="hidden" name="total_cost" value="{$order['meta']['cost']}">
                <input type="hidden" name="action" value="editOrder">
            </div>
            <input type="hidden" name="product_id" value="130">
            <div class="col-lg-7 col-md-5 col-6 mb-md-0 mb-3 d-flex flex-column justify-content-center align-items-start">
                <label class="label-text par mb-0 w-100">
                    <input type="text" class="input pr-1" name="name" placeholder="{130 | resource: 'pagetitle'}" value="" required>
                </label>
            </div>
            <div class="col-lg-1 col-md-2 col-6 mb-md-0 mb-3 d-flex justify-content-center align-items-center">
                <label class="label-text par mb-0">
                    <input type="number" class="input pr-1" min="1" name="count" value="1">
                </label>
            </div>
            <div class="col-lg-2 col-md-3 col-6 d-flex justify-content-center align-items-center">
                <label class="label-text par mb-0">
                    <input type="text" class="input pr-1" name="price" placeholder="Цена" value="" required>
                </label>
            </div>
            <div class="col-lg-2 col-md-2 col-6 d-flex justify-content-center align-items-center">
                <button class="btn btn-orange btn-cart" type="submit">
                    <i class="fa fa-cart-plus"></i>
                </button>
            </div>
            <div class="col-12 order-5 mt-3">
                <label class="label-text par mb-0">
                    <textarea name="options[desc]" class="textarea w-100" rows="4" placeholder="Описание"></textarea>
                </label>
            </div>
        </form>
    {else}
     <ul class="pl-0">
    {foreach $order['products'] as $key => $product}
        {set $description = $product['product_id'] | resource: 'description'}
        {set $introtext = $product['product_id'] | resource: 'introtext'}
        {set $add_cost = $product['product_id'] | resource: 'add_cost'}
        <li class="row py-3 jsProductRow border-gray-bottom">
            <input type="hidden" name="id" value="{$id}">
            <div class="col-lg-7 col-md-5 col-6 d-flex flex-column justify-content-center align-items-start">
                <span class="par service-link mb-3">{$product['options']['name']?:$product['name']}</span>
                <small class="small">{$product['options']['desc']?:$description}</small>
                {if $add_cost}
                    {if $id == 45}
                    <small class="small text-red">*стоимость шаблона: {$add_cost} руб.</small>
                    {else}
                    <small class="small text-red">*стоимость дополнения: {$add_cost} руб.</small>
                    {/if}
                {/if}
            </div>
            <div class="col-lg-1 col-md-1 col-6 d-flex justify-content-center align-items-center">
                <span class="price text-orange h-6">{$product['count']} шт.</span>
            </div>
            <div class="col-lg-2 col-md-3 col-6 d-flex justify-content-center align-items-center">
                    <span class="text-orange h-6">{$product['price']} руб.</span>
            </div>
            <div class="col-lg-2 col-md-3 col-6 d-flex justify-content-center align-items-center">
                <span class="text-orange h-6">{$product['cost']} руб.</span>
            </div>
        </li>
    {/foreach}
    </ul>
    {/if}
{else}
<p class="h-4 text-center">Заказ с id = {$.get.order_id} не существует в системе</p>
{/if}
<div class="row">
        <div class="col-lg-3 offset-lg-3 col-sm-6 mt-3">
        <div class="btn-wrap">
            <a href="/" class="btn btn-no-bg w-100">На Главную</a>
        </div>
    </div>
    <div class="col-lg-3 col-sm-6 mt-3">
        <div class="btn-wrap">
            <a href="{9 | url}" class="btn btn-no-bg w-100">К Услугам</a>
        </div>
    </div>
</div>
Каждый товар выводится в форму редактирования, а под всеми товарами есть форма добавления нового и форма поиска
editOrderProduct.htm выглядит так
<form class="row py-3 jsProductRow border-gray-bottom jsEditForm" name="product-{$id}" id="product-{$id}">
    <input type="hidden" name="id" value="{$id}">
    <input type="hidden" name="weight" value="{$weight}">
    <input type="hidden" name="order_id" value="{$order_id}">
    <input type="hidden" name="total_cost" value="{$total_cost}">
    <input type="hidden" name="action" value="editOrder">
    <input type="hidden" name="price" value="{$price}">
    <input type="hidden" name="options[addcost]" value="{$add_cost | number: '0': '.': ''}">
    <input type="hidden" name="product_id" value="{$product_id}">
    <div class="col-lg-7 col-md-5 col-6 d-flex flex-column justify-content-center align-items-start">
        <span class="par service-link">{$index}. {$name}</span>
        {if $introtext}
        <small class="small">{$introtext}</small>
        {/if}
        {if $add_cost}
        {if $id == 45}
        <small class="small text-red">*стоимость шаблона: {$add_cost} руб.</small>
        {else}
        <small class="small text-red">*стоимость дополнения: {$add_cost} руб.</small>
        {/if}
        {/if}
    </div>
    <div class="col-lg-1 col-md-1 col-6 d-flex justify-content-center align-items-center">
        <label class="label-text par mb-0">
            <input type="number" class="input pr-1" min="0" name="count" value="{$count}">
        </label>
    </div>
    <div class="col-lg-2 col-md-3 col-6 d-flex justify-content-center align-items-center">
        <span class="text-orange h-6">{$price} руб.</span>
    </div>
    <div class="col-lg-2 col-md-3 col-6 d-flex justify-content-center align-items-center">
        <span class="text-orange h-6">{$cost} руб.</span>
    </div>
    <div class="col-12 order-5 mt-3">
        <label class="label-text par mb-0">
            <textarea name="options[desc]" class="textarea w-100" rows="4" placeholder="Описание">{$description}</textarea>
        </label>
    </div>
</form>
Как отправить запрос на сервер думаю разберётесь, в заметке про поиск это есть. Ну и собственно сам сниппет editOrder
<?php
if(!isset($_POST['order_id'])){
    $modx->log(1,'EditOrder: Не передан идентификатор заказа');
    return false;
}
//$modx->log(1, print_r($_POST,1));
$res = [];
$tpl = '@FILE chunks/shop/editOrderProduct.html';
$order = $modx->getObject('msOrder', $_POST['order_id']);
if(isset($_POST['id'])){
    $product = $modx->getObject('msOrderProduct', $_POST['id']);
    $productCost = $_POST['price'] * $_POST['count'] + $_POST['options']['addcost'];
    $totalWeight = $_POST['weight'] + $order->get('weight') - $product->get('weight');
    $totalCost = $order->get('cost') + $productCost - $product->get('cost')  - $_POST['options']['addcost'];
    if($_POST['count'] > 0){
        $product->set('count', $_POST['count']);
	    $product->set('cost', $_POST['price'] * $_POST['count']);
	    if($_POST['options']['desc']){
	        $options = $product->get('options');
	        $options['desc'] = $_POST['options']['desc'];
	        $product->set('options', $options);
	    }
	    $product->save();
    }else{
        $totalWeight = $_POST['weight'] - $product->get('weight');
        $totalCost = $order->get('cost') - $product->get('cost');
        $product->remove();
        
    }
}else{
    $product = $modx->newObject('msOrderProduct');
    $data = $_POST;
    $data['cost'] = $_POST['price'] * $_POST['count'] + $_POST['options']['addcost'];
    $totalWeight = $_POST['weight'] * $_POST['count'] + $order->get('weight');
    $totalCost = $order->get('cost') + $data['cost'];
    $product->fromArray($data);
    $product->save();
}
	    
$order->set('cost', $totalCost);
$order->set('cart_cost', $totalCost);
$order->set('weight', $totalWeight);
$order->set('updatedon', date('Y-m-d H:i:s'));
$order->save();

if($totalCost){
    $pdoTools = $modx->getService('pdoTools');
    $products = $order->getMany('Products');
    $i = 1;
    foreach($products as $product){
        $options = $product->get('options');
        $resource = $modx->getObject('modResource', $product->get('product_id'));
        $desc = $options['desc']?:$resource->get('description');
        $name = $options['name']?:$product->get('name');
          
        $productData = array(
                'description' => $desc,
                'introtexxt' => $resource->get('introtext'),
                'index' => $i,
                'add_cost' => $resource->get('add_cost'),
                'price' => $product->get('price'),
                'weight' => $product->get('weight'),
                'count' => $product->get('count'),
                'name' => $name,
                'cost' => $product->get('cost') + $resource->get('add_cost'),
                'id' => $product->get('id'),
                'options' => $options,
                'order_id' => $_POST['order_id'],
                'product_id' => $resource->get('id')
            );
        
        if(isset($tpl)){
            $res['orderProducts'] .= $pdoTools->getChunk($tpl, $productData);
        }else{
            $res['orderProducts'][] = $productData;
        }
        $i++;
    }
}
else{
    $res['orderProducts'] = '<p class="h-6 my-3 text-red">Необходимо добавить услуги!</p>';
}       
$res['total_cost'] = $totalCost;
$res['duration'] = ceil($totalCost / $modx->getOption('base_cost'));

return json_encode($res);
Если интересует добавление товаров, то вот сниппет addToOrder
<?php
	    $res = [];
	    $order = $modx->getObject('msOrder', $_POST['order_id']);
	    
	    $product = $modx->newObject('msOrderProduct');
	    $data = $_POST;
	    //$modx->log(1, print_r($_POST,1));
	    $data['cost'] = $_POST['price'] * $_POST['count'];
	    $totalWeight = $_POST['weight'] * $_POST['count'] + $order->get('weight');
	    $totalCost = $order->get('cost') + $data['cost'] + $data['options']['addcost'];
	    $product->fromArray($data);
	    $product->save();
	    
	    $order->set('cost', $totalCost);
	    $order->set('cart_cost', $totalCost);
	    $order->set('weight', $totalWeight);
	    $order->set('updatedon', date('Y-m-d H:i:s'));
	    $order->save();
	    
	    $pdoTools = $modx->getService('pdoTools');
	    $products = $order->getMany('Products');
	    $i = 1;
        foreach($products as $product){
            $options = $product->get('options');
            $resource = $modx->getObject('modResource', $_POST['product_id']);
            $res['orderProducts'] .= $pdoTools->getChunk('@FILE chunks/shop/editOrderProduct.html', array(
                    'description' => $options['desc']?:$resource->get('description'),
                    'introtexxt' => $resource->get('introtext'),
                    'index' => $i,
                    'add_cost' => $resource->get('add_cost'),
                    'price' => $product->get('price'),
                    'weight' => $product->get('weight'),
                    'count' => $product->get('count'),
                    'name' => $options['name']?:$product->get('name'),
                    'cost' => $product->get('cost'),
                    'id' => $product->get('id'),
                    'options' => $options,
                    'order_id' => $_POST['order_id'],
                    'total_cost' => $totalCost,
                    'product_id' => $resource->get('id')
                ));
                $i++;
        }
        $res['total_cost'] = $totalCost;
        $res['duration'] = ceil($totalCost / $modx->getOption('base_cost'));
        $res = json_encode($res);
        return $res;
28 января 2021, 11:31
0
А вы проверяли переменные перед запуском runSnippet, в $image точно корректная строка?
28 января 2021, 10:51
0
А где взять старое значение? Изменение делает пользователь, сохраняет и только потом срабатывает плагин.
28 января 2021, 00:27
0
Я проверил это код в консоли, всё сработало, может ошибка не в нём?
26 января 2021, 22:15
0
1.не могут оплатить, т.к. под рукой нет карты, Сбербанка онлайн и так далее
2.не могут оплатить, т.к. что-то пошло не так (номер не тот ввел, денег нет на карте, еще что-то)
3.передумывают платить онлайн, решают, что выберут другой вариант оплаты
Для первых двух кейсов в письме клиенту есть ссылка на оплату. А третий на мой взгляд достаточно редкий. Собственно по этой причине готовых решений и нет, если вам ссылки на оплату недостаточно и вы непременно хотите как-то иначе обрабатывать ошибку оплаты или отказ от неё, придётся заморочиться.
26 января 2021, 20:51
0
Я думаю надо переопределить метод submit вот в этом файле core/components/minishop2/model/minishop2/msorderhandler.class.php Как это сделать написано тут

Возможно так же стоит изучить эту страницу
26 января 2021, 16:11
0
и всё таки, если мне нужно получить html, вызывать сниппет вы говорите не стоит, вот так можно
$pdoTools->getChunk($tpl, $data);
26 января 2021, 15:21
0
Я так понял хорошей и единственно верной практикой, если я хочу свой велосипед, является написание компонента с классами, процессорами и коннекторами. так?
100мб можно сократить до одного, если прервать инциализацию modx
Где прервать? И как с помощью die()?
На код не влияет, а на восприятие людьми, еще менее знающими чем ты — еще как.
Согласен. Предупреждение написал.
26 января 2021, 15:06
0
У вас вывод с пагинацией?
26 января 2021, 15:05
0
А мой ответ типа не ответ? Или я по-вашему мертв?)))
26 января 2021, 14:01
0
Вообще без обид, меня никто не учил как правильно, делаю как могу, против конструктивной критики ничего не имею, поэтому спасибо. И несколько вопросов.
Во первых вызывая сниппет — ты проходишь полный цикл инициализации MODX, тебе нужно отдать очень простые результаты зачем тебе полностью инициализировать modx?
Что значит «полный цикл инициализации MODX» и что в этом страшного, если на странице зачастую вызывается несколько сниппетов?

Зачем вызывать сниппет msProducts? Почему бы не использовать pdoFetch например и не задействовать парсер modx?
Я понимаю, что это, скажем так, неоптимальное решение, но другой вариант это
$pdoTools->getChunk($tpl, $data);
А как без использования парсера? Мне же html нужен, а не сырые данные, или JS'ом вставлять?

А что до названия, ну «Сделай Сам» или «Мой способ реализации бла-бла» так по-моему без разницы, на код это не влияет)))
26 января 2021, 00:10
0
{'pdoResources' | snippet: [
    'parents' => 0,
    'includeTVs'  => 'multiSelectTVname'
    'where' => ['multiSelectTVname:LIKE' => '%Белый%']
]}
25 января 2021, 17:24
0
Что не так с Minioshop2 в этом плане?
С ним всё в порядке, сегодня проверял хостинг Beget, почта менеджера такая же name@domain.ru.от Яндекса. Обычно такое бывает по вине хостера, уточните есть ли ограничения на отправку писем, проверьте какой адрес стоит в emailsender, настройки minishop2 проверьте чтобы отправка была включена у нужного статуса, чтобы в шаблонах не было ошибок, в логах посмотрите, может там ошибки есть.
25 января 2021, 15:02
0
Славно, что разобрались.
25 января 2021, 14:56
0
Где вы эти два сниппета вызываете, на странице товара?
25 января 2021, 14:54
+2
Не знаю баг это или фича, но отсутствие подписи к полю в админке на вывод не влияет, проверено. Покажите код который выводит данные.