Денис Чубенко

Денис Чубенко

С нами с 02 марта 2017; Место в рейтинге пользователей: #611
Илья Уткин
31 октября 2017, 11:22
3
+1
Я обычно как-то так делаю:

@EVAL return $modx->runSnippet('pdoResources', array(
	'parents' => 64,
	'limit' => 0,
	'tpl' => '@INLINE {$pagetitle}=={$id}',
	'outputSeparator' => '||',
	'sortby' => '{"menuindex":"ASC"}'
  ));
Илья Уткин
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);
Павел Гвоздь
18 сентября 2017, 22:35
1
0
У Александра в коде ошибка. Он не обозначил метод, с которым работаем… Видимо не проверял код. В данном случае это «crm.lead.add».

1) Вот это положить в assets/b24/bxresthandler.class.php:
<?php
class bxRestHandler
{
    public $url;
    public $config = array();
    /** @var modX $modx */
    protected $modx;
    
    /**
     * @param modX  $modx
     * @param array $config
     */
    public function __construct(modX &$modx, array $config = array())
    {
        $this->modx = &$modx;
        $this->config = &$config;
        $this->url = $this->config['url'] ?: $this->modx->getOption('bx24_resturl');
    }
    
    /**
     * @param string $action
     * @param array  $data
     * @param string $method
     */
    public function request($action, array $data = array(), $method = 'GET')
    {
        if (empty($this->url)) {
            return $this->failure('Empty url');
        }
        
        $curl = curl_init();
        curl_setopt_array($curl, array(
            CURLOPT_URL => $this->url . $action,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_SSL_VERIFYHOST => false,
            CURLOPT_POST => ($method == 'POST'),
            CURLOPT_POSTFIELDS => http_build_query($data),
        ));
        $response = curl_exec($curl);
        if ($errno = curl_errno($curl)) {
            $result = $this->failure('Bad request', array(
                'errorCode' => $errno,
                'errorMessage' => curl_error($curl),
            ));
        } else {
            if ($response = $this->modx->fromJSON($response)) {
                if (empty($response['error']) && empty($response['error_description'])) {
                    $result = $this->success('', $response);
                } else {
                    $result = $this->failure(($response['error_description'] ?: $response['error']), $response);
                }
            } else {
                $result = $this->failure('Bad JSON string');
            }
        }
        curl_close($curl);
        
        return $result;
    }
    
    /**
     * @param string $message
     * @param array  $data
     *
     * @return array
     */
    public function success($message = '', $data = array())
    {
        return array(
            'success' => true,
            'message' => $message,
            'data' => $data,
        );
    }

    /**
     * @param string $message
     * @param array  $data
     *
     * @return array
     */
    public function failure($message = '', $data = array())
    {
        return array(
            'success' => false,
            'message' => $message,
            'data' => $data,
        );
    }
}

2) Создать настройку bx24_resturl с УРЛом вебхука.

3) Создать сниппет-хук для FormIt bx24FormItHook:
<?php
if (!$bx = $modx->getService('bxresthandler', 'bxRestHandler', MODX_ASSETS_PATH . 'b24/', array(
    'url' => $modx->getOption('bx24_resturl'),
))) {
    return;
}
if (!is_object($hook)) {
    return;
}
$data = $hook->getValues();
if (!empty($data['form'])) {
    $bx->request('crm.lead.add', array(
        'fields' => array(
            'TITLE' => $data['form'],
            'COMMENTS' => $data['comment'] ?: '',
            
            // Контакт
            'NAME' => $data['name'],
            'PHONE' => array(array(
                'VALUE' => $data['phone'],
                'VALUE_TYPE' => 'WORK',
            )),
            'EMAIL' => array(array(
                'VALUE' => $data['email'],
                'VALUE_TYPE' => 'WORK',
            )),
            'ADDRESS_CITY' => $data['city'] ?: '',
            
            //
            'SOURCE_ID' => $data['source_id'], // ID источника
            'ASSIGNED_BY_ID' => 56, // ID ответственного
        ),
    ));
}

4) Вызывать примерно так:
{'!AjaxForm' | snippet :[
    'snippet' => 'FormIt',
    'hooks' => 'email,bx24FormItHook',
    'form' => 'tpl.AjaxForm.example',
]}

5) Чанк tpl.AjaxForm.example содержит форму с полями, которые используются в сниппете-хуке bx24FormItHook:
<input type="hidden" name="form" value="Контакты">
<input type="text" name="name" value="">
<input type="text" name="phone" value="">
<input type="text" name="email" value="">
<input type="text" name="city" value="">
<textarea name="comment"></textarea>
Александр
06 сентября 2017, 05:40
1
+1
Может кому пригодиться, исправленный метод getCost:

public function getCost($with_cart = true, $only_cost = false) {
		$response = $this->ms2->invokeEvent('msOnBeforeGetOrderCost', array(
			'order' => $this,
			'cart' => $this->ms2->cart,
			'with_cart' => $with_cart,
			'only_cost' => $only_cost,
		));
		if (!$response['success']) {return $this->error($response['message']);}

		$cart = $this->ms2->cart->status();
		$cost = $with_cart
			? $cart['total_cost']
			: 0;

        $add_price = 0;
         
		/* @var msDelivery $delivery */
		if (!empty($this->order['delivery']) && $delivery = $this->modx->getObject('msDelivery', $this->order['delivery'])) {
			//$cost = $delivery->getCost($this, $cost);
			$add_price += $delivery->getCost($this, $cost) - $cost;
			$deliveryCost = $delivery->getCost($this, 0);
			
		    //	$deliveryCost = $delivery->getCost($this, 0);//Добавил переменную где получаем price доставки
		}

		/* @var msPayment $payment */
		if (!empty($this->order['payment']) && $payment = $this->modx->getObject('msPayment', $this->order['payment'])) {
			
			 $add_price += $payment->getCost($this, $cost) - $cost;
			//$cost = $payment->getCost($this, $cost);
		}
        
        $cost += $add_price;
         
		$response = $this->ms2->invokeEvent('msOnGetOrderCost', array(
			'order' => $this,
			'cart' => $this->ms2->cart,
			'with_cart' => $with_cart,
			'only_cost' => $only_cost,
			'cost' => $cost
		));
		if (!$response['success']) {return $this->error($response['message']);}
		$cost = $response['data']['cost'];

		return $only_cost
			? $cost
			: $this->success('', array('cost' => $cost, 'delivery_cost'=>$deliveryCost));//Добавил deliveryCost
	}
Наумов Алексей
28 апреля 2017, 20:08
1
+2
См.

// get the max iterations tags are processed before processing is terminated 
$maxIterations= (integer) $modx->getOption('parser_max_iterations', null, 10);
 
// parse all cacheable tags first 
$modx->getParser()->processElementTags('', $content, false, false, '[[', ']]', array(), $maxIterations);
 
// parse all non-cacheable and remove unprocessed tags 
$modx->getParser()->processElementTags('', $content, true, true, '[[', ']]', array(), $maxIterations);
думаю, что параметры функции сами найдете
Алексей Ерохин
27 марта 2017, 13:07
6
0
$options = array();
$translit = $modx->getOption('friendly_alias_translit', $options, 'russian');
$translitClass = $modx->getOption('friendly_alias_translit_class', $options, 'translit.modTransliterate');
$translitClassPath = $modx->getOption('friendly_alias_translit_class_path', $options, $modx->getOption('core_path', $options, MODX_CORE_PATH) . 'components/');
$modx->getService('translit', $translitClass, $translitClassPath, $options);
$transliteratedtext = $modx->translit->translate($text, $translit);
Володя
06 сентября 2016, 14:13
2
0
можно было просто задействовать механизм создания/ обновления через процессоры…

вот так можно как вы хотели
// получаем продукт
$product = $modx->getObject('msProduct', array(
  'id' => 135
));

// получаем его опции
$options = $product->loadData()->get('options');

// добавляем какие то свои, например цвет
$options['color'][] = 'серобармалиновый';
$options['color'][] = 'серобармалиновый2';
$options['color'][] = 'синий';

// устанавливаем значения
foreach ($options as $k => $v) {
    if (is_array($v)) {
        $v = array_unique($v);
    }
    $product->set($k, $v);
}

// сохраняем изменения
$product->save();
DocentBF
25 июня 2016, 20:36
4
+4
Можно переписать метод mSearch2.handleSort или подключить к mFilter2 cвой скрипт фронтенда или переопределить метод в другом js файле, например как-то так:
if (typeof(mSearch2) !== "undefined") {
mSearch2.initialized = false;
mSearch2.handleSort = function() {
    var params = this.Hash.get();
    if (params.sort) {
            var sorts = params.sort.split(mse2Config.values_delimeter);
            for (var i = 0; i < sorts.length; i++) {
                var tmp = sorts[i].split(mse2Config.method_delimeter);
                if (tmp[0] && tmp[1]) {
                    $('#mse2_sort option[data-sort="' + tmp[0] + '"][value="' + tmp[1] + '"]').attr('selected', 'selected').trigger('change');
                }
            }
        }
        $(document).off('click', this.options.sort_link);
        $(document).on('change', '#mse2_sort', function() {
            var selected = $(this).find('option:selected');
            var sort = selected.data('sort');
            sort += mse2Config.method_delimeter + selected.val();
            mse2Config.sort = (sort != mse2Config.start_sort) ? sort : '';
            var params = mSearch2.getFilters();
            mSearch2.Hash.set(params);
            mSearch2.load(params);
        });
    }
    mSearch2.initialize('body');
}
а select представить например так:
<select id="mse2_sort">
    <option value="asc" data-sort="resource|pagetitle">по умолчанию</option>
    <option value="asc" data-sort="ms|price">по возрастанию цены</option>
    <option value="desc" data-sort="ms|price">по убыванию цены</option>
</select>
Сергей Шлоков
23 апреля 2016, 11:10
5
+3
Я для себя сделал такой плагин. Сильно не заморачивался. Просто скопировал код из Ace.
<?php
switch ($modx->event->name) {
    case 'OnDocFormPrerender':
        if (!$modx->controller->resourceArray) {
            return;
        }
        $field = 'modx-resource-introtext';
        $mimeType = $modx->getObject('modContentType', $modx->controller->resourceArray['content_type'])->get('mime_type');
        if ($mimeType == 'text/html' && $modx->getOption('pdotools_fenom_parser')) {
            $mimeType = 'text/x-smarty';
        }
		$modxTags = 1;
		$script = "MODx.ux.Ace.replaceComponent('$field', '$mimeType', $modxTags);";
		$script .= "MODx.ux.Ace.replaceTextAreas(Ext.query('.modx-richtext'));";
		$modx->controller->addHtml('<script>Ext.onReady(function() {' . $script . '});</script>');
        break;
    default:
        return;
}
Безнос Евгений
22 марта 2016, 00:54
2
0
Разобрался в чем дело) У вас видимо кастомный класс msorderhandler.class.php
Я добавил свой класс наследовал его от msOrderHandler и переопределил метод getCost() добавил в код пару строчек смотри комментарии:
public function getCost($with_cart = true, $only_cost = false) {
		$response = $this->ms2->invokeEvent('msOnBeforeGetOrderCost', array(
			'order' => $this,
			'cart' => $this->ms2->cart,
			'with_cart' => $with_cart,
			'only_cost' => $only_cost,
		));
		if (!$response['success']) {return $this->error($response['message']);}

		$cart = $this->ms2->cart->status();
		$cost = $with_cart
			? $cart['total_cost']
			: 0;

		/* @var msDelivery $delivery */
		if (!empty($this->order['delivery']) && $delivery = $this->modx->getObject('msDelivery', $this->order['delivery'])) {
			$cost = $delivery->getCost($this, $cost);
			$deliveryCost = $delivery->getCost($this, 0);//Добавил переменную где получаем price доставки
		}

		/* @var msPayment $payment */
		if (!empty($this->order['payment']) && $payment = $this->modx->getObject('msPayment', $this->order['payment'])) {
			$cost = $payment->getCost($this, $cost);
		}
        
		$response = $this->ms2->invokeEvent('msOnGetOrderCost', array(
			'order' => $this,
			'cart' => $this->ms2->cart,
			'with_cart' => $with_cart,
			'only_cost' => $only_cost,
			'cost' => $cost
		));
		if (!$response['success']) {return $this->error($response['message']);}
		$cost = $response['data']['cost'];

		return $only_cost
			? $cost
			: $this->success('', array('cost' => $cost, 'delivery_cost'=>$deliveryCost));//Добавил deliveryCost
	}
Далее добавил скрипт на страницу заказа:
miniShop2.Order.deliveryCost = '#ms2_delivery_cost';

miniShop2.Callbacks.Order.getcost.response.success = function(response) {

    var rdc = response.data['delivery_cost'];

    if(rdc) $(miniShop2.Order.deliveryCost, miniShop2.Order.order).text(miniShop2.Utils.formatPrice(rdc));
    else $(miniShop2.Order.deliveryCost, miniShop2.Order.order).text('0');
}

miniShop2.Callbacks.Order.getcost.response.error = function(response) {

    var cost = response.data['cost'];

    $(miniShop2.Order.orderCost).text(miniShop2.Utils.formatPrice(cost));
    $(miniShop2.Order.deliveryCost, miniShop2.Order.order).text('0');
}

miniShop2.Callbacks.Order.add.response.success = function(response) {
     miniShop2.Order.getcost();
    }
и в чанке tpl.msOrder.outer вставил span
<span id="deliveryprice">Стоимость доставки: <span id="ms2_delivery_cost"></span> руб.</span>
При таком раскладе placeholder [[+delivery_cost]] ненужен, я думаю что такого placeholdera в ms2 нет. delivery_cost есть в схеме БД (core/components/minishop2/model/schema/minishop2.mysql.schema.xml) ms2 больше ни где не видел)