des1gner

des1gner

С нами с 09 февраля 2019; Место в рейтинге пользователей: #1088
Павел Романов
04 мая 2024, 13:27
2
+3
Так вроде, пошустрее будет ):
$sql = "
    SELECT tvr.value, tv.caption
    FROM {$modx->getTableName('modTemplateVarResource')} tvr
    LEFT JOIN {$modx->getTableName('modTemplateVar')} tv
    ON tv.id = tvr.tmplvarid 
    WHERE tvr.contentid = {$id} AND tv.category = {$category}
";
$q = $modx->prepare($sql);
$q->execute();
$resources = $q->fetchAll(PDO::FETCH_ASSOC);
foreach($resources as $resource){
    $out .= $modx->getChunk($tpl, $resource);
}
return $out;

В чанке [[+caption]] и [[+value]]:
<div class="item-parent">
    <div class="row">
        <div class="col-9 pr-0">
            <span class="caption">[[+caption]]:</span>
            <div class="item-bg" data-rating="[[+value]]"></div>
        </div>
        <div class="col-3">
            <span class="rating">[[+value]]/10</span>
        </div>
    </div>
</div>

Кстати, верный ID категории можно узнать в Элементы » Категории.
Артур Шевченко
10 августа 2021, 07:33
1
0
Давайте рассуждать. Чтобы было легче идём сюда. Событие msOnBeforeSaveOrder как-то связано с сохранением заказа, учитывая задачу, пользователя надо бы оповестить о том, что выбрав доставку он теряет скидки и хорошо бы показать сколько он в итоге должен заплатить. На этапе сохранения заказа это сделать невозможно. Однако, если присмотреться к списку событий внимательно, то можно заметить, что порядок событий в нём точно такой же в каком они происходят при совершении покупки. И тогда становится очевидным, что перед сохранением заказа происходит ещё много событий. Какое же из них выбрать? Я думаю то, которое как-то связано со стоимостью заказа, ведь в конечном итоге меняется именно она. Я бы начал с msOnBeforeGetOrderCost, в него передается экземпляр класса корзина и экземпляр класса заказ. Из второго объекта получаем способ доставки, если это не самовывоз делаем так
if($order->get('delivery') != 1){
    $tmp = $cart->get();
    foreach($tmp as $k => $v){
        $product = $modx->getObject('modResource', array('class_key' => 'msProduct', 'id' => $v['id']));
        $tmp[$k][$v]['price'] = $product->get('price');
    }
 } else{
    // скидки надо возвращать, если выбран самовывоз
}
$cart->set($tmp);
Код выше это, конечно, не окончательное решение, а просто для направления мысли.
Сергей
24 февраля 2019, 16:40
1
+3
Я всегда объясняю так: Что такое сайт? — это палатка с шаурмой в чистом поле. Даже если у неё будет крутая вывеска (дизайн), реально вкусная шаурма (функционал), все равно вы не продадите ни одной шаурмы потому что к ней нет дороги.
И тут уже можно играть как хочешь. Например обьяснить что ты программист и отвечаешь только за сооружение каркаса палатки, или ты ещё дизайнер, или строитель дорог. И естественно каждый этап работ стоит денег, и что за 5-7 тыс он получит просто палатку в поле. После таких аналогий как правило клиент проникает к вам с доверием и реально понимает за что он платит.
Работает в 99%, пользуйтесь или придумайте свою аналогию))
Alexey Medvedev
17 марта 2018, 17:54
1
0
Благодарю Павла за доступ к сайту для устранения проблемы.

// Обратите внимание, что прописано в параметре basePath источника файла
$source = $modx->getObject('sources.modMediaSource', 1); 
$source->initialize();
function getFilesList($dir, $source)
{
    $files = [];
    $childrens = $source->getContainerList($dir);
    foreach ($childrens as $container) {
        if ($container['type'] == 'dir') {
            $files = array_merge($files, getFilesList($container['pathRelative'], $source));
            continue;
        }
        if ($container['type'] == 'file') {
            $file_path_info = pathinfo($container['pathRelative']);
            $ext = strtolower($file_path_info['extension']);
            if ( in_array($ext, array('jpeg', 'jpg', 'png', 'pdf')) ) {
    
                if (in_array($ext, array('jpeg', 'jpg', 'png'))) {
                    $type = 'image/jpeg';
                }
    
                if ($ext == 'pdf') {
                    $type = 'application/pdf';
                }
    
                $file = array(
                    'type'         => $type,
                    'name'         => $file_path_info['basename'],
                    'dir'          => $file_path_info['dirname'],
                    'pathRelative' => $container['pathRelative'],
                    'error'        => 0
                );
            
                $files[] = $file;
            }
        }
    }
    return $files;
}

$allFiles = getFilesList('uploads/', $source); // Укажите папку вместо 'uploads/'
$tinyCompressorDefaultPath = MODX_CORE_PATH . 'components/tinycompressor/model/tinycompressor/';

$compressor = $modx->getService('tinycompressor', 'tinyCompressor', $tinyCompressorDefaultPath);
foreach ($allFiles as $file) {
	$data = array($file); // Передавать надо массив
	// Если "Источник файла" (Source) не является корнем сайта, 
	// то явно укажите это перед переменной $file['dir'], иначе файл не будет найден. 
	// Например, 'assets/' . $file['dir'] . '/'
	$compressor->compression($data, $file['dir'] . '/'); //source не ставить, иначе рискуете потерять связи, так как будет переименование файла 
}
Андрей
17 февраля 2018, 12:41
1
+3
Сначала нужно destroy делать, а после заново инициализацию.

https://github.com/OwlCarousel2/OwlCarousel2/issues/1861 — вот тут пример есть:

$("#partial").load(url, function () {
	$('#partial').trigger('destroy.owl.carousel');
		$("#partial").owlCarousel({
			items: 1,
			margin: 10,
			nav: false
		});
	return false;
});
Наумов Алексей
01 февраля 2018, 16:46
4
+4
hook для Formit, отсылает сообщения через sms.ru, вызываем перед хуком email:

Предварительно создаем настройки
sms_ru_api_id — api ключ, который дадут при регистрации на сайте
manager_phone — номер телефона получателя

<?php
// API id
$api_id = $modx->getOption('sms_ru_api_id', null, null);
if(empty($api_id)) {
    $modx->log(xPDO::LOG_LEVEL_ERROR,'SMS.RU hook: empty API ID!.');
    // так как это hook, то даже в случае неудачи возвращаем true
    return true;
}

// Support phone number
$phone = $modx->getOption('manager_phone', null, null);
if(empty($phone)) {
    // так как это hook, то даже в случае неудачи возвращаем true
    return true;
}

$ch = curl_init("https://sms.ru/sms/send");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_POSTFIELDS, array(

    "api_id"        =>  $api_id,
    "to"            =>  $phone,
    "text"      =>  "ТЕКСТ СООБЩЕНИЯ",

));
$body = curl_exec($ch);
curl_close($ch);

return true;
Михаил
20 декабря 2017, 06:34
2
0
<?php

switch($modx->event->name){
    case 'msOnBeforeAddToCart':
        $tmp = $cart->get();
    
        
        if(!empty($tmp)){
            $modx->event->output('Больше одного товара нельзя');
        }
        
        break;
        
    case 'msOnChangeInCart':
        
        $tmp = $cart->get();
        $tmp[$key]['count'] = 1;
        $cart->set($tmp);
        
        $modx->event->output('Количество только 1');
        
        break;
}
gruzoveek
15 октября 2017, 19:38
1
0
В общем принцип такой:
шаг 1. создаю каталог с товарами, товары в нем — это упаковки, задаю им цены.
шаг 2. создаю дополнительные поля товара, как это делается — тут неоднократно писалось на сайте. поля такие: ID коробки и Кол-во данного товара на единицу упаковки, т.е. вместимость. У всех товаров, у которых предполагается упаковка, заполняю эти поля.
шаг 3. создается плагин на события
'msOnAddToCart': // получает $key и $cart
'msOnChangeInCart': // получает $key, $count и $cart
'msOnRemoveFromCart': // получает $key и $cart
в плагине получаю массив коробок из известного мне каталога.

Потом из переменной $cart методом get() получаю содержимое корзины $tmp = $cart->get();, пробегаю по товарам в цикле и там смотрю, каков id коробки и параметр вместимости товара и сколько этого товара в заказе, таким образом высчитываю сколько и каких коробок надо для такого количества товара.

Тут есть нюанс: если до этого момента коробок в заказе не было (например при событии msOnAddToCart) то нужно напрямую добавлять в заказ коробки методом $cart->add($box_id); а если коробка уже была в заказе, например при изменении количества товара в корзине (msOnChangeInCart и msOnRemoveFromCart) то тут уже работаем с $tmp, меняя только count для коробок, и по итогу перезаписываем корзину его содержимым: $cart->set($tmp);
Владимир
25 апреля 2017, 15:46
2
+1
Файл assets/components/tinymcerte/js/mgr/tinymcerte.js

После (у меня это 29 строка)
this.cfg.file_browser_callback = this.loadBrowser;
добавить
this.cfg.valid_elements = '*[*]';
Роман Садоян
19 октября 2016, 21:15
4
0
Ага, понял, в общем вот такой код у меня работает:

switch ($modx->event->name) {

  case 'msOnSubmitOrder':
    $orderData = $order->get();
    $status = $order->ms2->cart->status();
// Здесь я получаю минимальную стоимость из системной настройки
    $mincost = $modx->getOption('ms2_payment_rsb_mincost');
    if(!$mincost){
      $mincost = 3000;
    }
    if($status['total_cost'] < $mincost)
    {
      $message = "Минимальная сумма для подачи заявки равна: ".$mincost;
      $data = array('success' => false, 'message' => $message);
      return $modx->event->output($message);
    }
}
Сейчас уже не вспомню зачем я записываю в $data такой массив.
Но minishop подхватывает это уведомление и выводит ошибку, при этом форма не отправляется.