Богдан · 21 декабря 2018, 13:03 Переделанные под шаблонизатор Fenom + Bootstrap 4 + FontAwesome 5 стандартные чанки Tickets, вдруг кому пригодятся: github.com/frkba/Tickets-fenom-chunks-FontAwesome-5 Новые дополнения и их версии / Tickets 1.9.3 52 +3 1
Виталий · 17 декабря 2018, 18:10 Если я перепешу фунцию в этом файле, то при обновлении она опять перепишется? function getUsetIP(){ $ip = $_SERVER['REMOTE_ADDR']; if ( !empty( $_SERVER["HTTP_CF_CONNECTING_IP"])){ $ip = $_SERVER['HTTP_CF_CONNECTING_IP']; }elseif( !empty($_SERVER['HTTP_X_REAL_IP'])){ $ip = $_SERVER['HTTP_X_REAL_IP']; }elseif( !empty($_SERVER['HTTP_CLIENT_IP'])){ $ip = $_SERVER['HTTP_CLIENT_IP']; }elseif( !empty( $_SERVER['HTTP_X_FORWARDED_FOR'])){ $ip = $_SERVER['HTTP_X_FORWARDED_FOR']; $commapos = strrpos( $ip , ',' ); $ip = trim( substr( $ip , $commapos ? $commapos + 1 : 0 )); } return $ip; } Новые дополнения и их версии / [siteStatistics] ip, referer и user-agent 34 0 1
Андрей · 17 октября 2018, 10:47 Примерно так должно работать if ($modx->event->name == 'OnDocFormSave') { if ($resource->template != 5) { // id шаблона с товаром return; } // получаем id выбранных в TV продуктов $tv = $resource->getTVValue('имя_tv_с_чекбоксами'); if (empty($tv)) { return; } $ids = explode($tv, ','); // получаем сами продукты $products = $modx->getCollection('msProduct', [ 'id:IN' => $ids ]); if ($products) { $prices = []; // получаем цены для выбранных продуктов foreach ($products as $product) { $prices[] = $product->get('price'); } // получаем минимальную цену $min_price = min($prices); if ($min_price) { // сохраняем цену для товара $resource->set('price', $min_price); $resource->save(); } } } Вопросы / Цена товара в зависимости от выбранного ТВ [решено] 8 +1 1
Максим Кузнецов · 07 ноября 2017, 12:29 На fenom-е посимпатичнее будет: {foreach $_modx->resource.pagetitle | split : ' ' as $pagetitle_word} {if $pagetitle_word | length > 3} {var $words[] = $pagetitle_word} {/if} {/foreach} {set $random_word_position = rand(1, $words| length)} {set $random_word = $words[$random_word_position - 1]} {$_modx->runSnippet('!msProducts', [ 'parent' => $_modx->resource.parent, 'resources' => -$_modx->resource.id, 'where' => '{ "pagetitle:LIKE": "%' ~ $random_word ~ '%" }', ... ])} Готовые решения / modRelation - Похожие товары для minishop2 и pdoTools 40 +6 5
Николай Каленников · 16 мая 2017, 17:46 CKEditor на фронтенде тоже неплохо подключается. Деактивируем в настройках MarkItUp, текстовое поле в чанке <textarea class="form-control" placeholder="[[%ticket_content]]" name="content" id="content" rows="40"></textarea> подключаем скрипт на странице <script src="/assets/components/ckeditor/ckeditor.js"></script><script>CKEDITOR.replace('content');</script>Загруженные картинки просто перетаскиваются в текст. Заказчики с MarkItUp никак не дружат. Для разработчиков / Как подружить Tickets и TinyMCE 22 0 2
Василий Наумкин · 06 января 2016, 09:04 Я бы написал плагин на событие сохранения комментария: if ($modx->event->name == 'OnBeforeCommentSave') { if (stripos($_POST['text'], 'b-nosov.blogspot') !== false) { $modx->event->output('Хватит спамить!'); } }Email очень просто изменить, поэтому лучше проверять текст комментария на спамерскую ссылку. Вопросы / Как заблокировать незарегенного пользователя? 8 +2 4
Денис Райх · 18 ноября 2015, 11:50 Вдруг моя поделка кому-нибудь будет полезна. Ниже приведен код сниппета и его чанков оформления. Сниппет возвращает список заказов конкретного пользователя вместе с товарами заказа и оформляет вывод в чанки. На вход сниппет принимает параметры: 'user' => Пользователь, чьи заказы выводим; 'tpl' => Чанк оформления элемента списка заказов; 'tplWrapper' => Чанк оформления оболочки списка заказов; 'tplProducts' => Чанк оформления элемента списка продуктов в заказе; 'tplEmpty' => Чанк оформления пустого результата; Код сниппета «getUserOrders»: <?php if(!isset($user) || ($user === 0)) { return '<p>Ошибка! Идентификатор пользователя не определён.</p>'; } //Задаём значения чанков оформления по-умолчанию if(!isset($tpl)){ $tpl = 'tpl.profile.orders_list.row'; } if(!isset($tplWrapper) || ($tplWrapper === '')){ $tplWrapper = 'tpl.profile.orders_list.wrapper'; } if(!isset($tplProducts) || ($tplProducts === '')){ $tplProducts = 'tpl.profile.orders_list.products.row'; } if(!isset($tplEmpty) || ($tplEmpty === '')){ $tplEmpty = 'tpl.profile.orders_list.empty'; } if(!isset($idx)){ $idx = 1; } //Формируем запрос к БД $q = $modx->newQuery('msOrder'); $q->select( array ( 'msOrder.id', 'msOrder.num', 'msOrder.createdon', 'msOrder.cost', 'msOrder.status', 'op.product_id', 'op.name', 'op.price', 'op.count' ) ); $q->where(array('msOrder.user_id' => $user)); $q->sortby('msOrder.id','DESC'); $q->leftJoin('msOrderProduct','op', 'msOrder.id = op.order_id'); $query = $q->prepare(); $query->execute(); $orders = $query->fetchAll(PDO::FETCH_ASSOC); if (count($orders) === 0) { $result = $modx->getChunk('tpl.profile.orders_list.empty'); return $result; } //Инициализируем переменные для обработки результата выборки $orders_unique = array(); $count = 0; foreach ($orders as $o) { //Т.к. в результате выборки дублируется информация по заказам с несколькими товарами - //перед выводом избавляемся от дубликатов //Если ID последнего элемента в обработанном списке заказов не совпадает с ID обрабатываемого заказа, либо это первый шаг, //то формируем новый элемент обработанного массива, запихивая туда данные выборки if (($o['id'] != $orders_unique[$count - 1]['order_id']) || ($count === 0)) { $orders_unique[$count] = array ( 'order_id' => $o['id'], 'order_num' => $o['num'], 'order_createdon' => $o['createdon'], 'order_status' => $o['status'], 'order_total_cost' => $o['cost'] ); //Т.к. товаров в заказе может быть несколько - инициализируем поле order_products, как массив $orders_unique[$count]['order_products'][] = array ( 'product_id' => $o['product_id'], 'product_name' => $o['name'], 'product_price' => $o['price'], 'product_count' => $o['count'], 'product_cost' => $o['price'] * $o['count'] ); $count++; } //В случае, если мы наткнулись на дубликат заказа, то просто дополняем массив 'order_products' последнего элемента обработанного списка else { $orders_unique[$count - 1]['order_products'][] = array ( 'product_id' => $o['product_id'], 'product_name' => $o['name'], 'product_price' => $o['price'], 'product_count' => $o['count'], 'product_cost' => $o['price'] * $o['count'] ); } } //Вывод отладочной информации по формируемому массиву, если потребуется /*$res = print_r($orders_unique, 1); echo '<div class="ord-lst-wrap"><pre>'; echo $res; echo '</pre></div>';*/ //Оформляем массив с отфильтрованными дубликатами foreach ($orders_unique as $o_u) { $products_list = ''; //Обрабатываем каждый элемент массива товаров в заказе foreach($o_u['order_products'] as $o_p) { $product_data = array ( 'product_id' => $o_p['product_id'], 'product_name' => $o_p['product_name'], 'product_price' => $o_p['product_price'], 'product_count' => $o_p['product_count'], 'product_cost' => $o_p['product_cost'] ); if ($tplProducts !== '') { $products_list .= $modx->getChunk($tplProducts, $product_data); } //В случае, если шаблон оформления товара не задан - выводим массив доступных плейсхолдеров вместе с содержимым else { $products_list .= '<pre>'.print_r($product_data, 1).'</pre>'; } } $order_data = array ( 'order_num' => $o_u['order_num'], 'order_createdon' => $o_u['order_createdon'], 'order_total_cost' => $o_u['order_total_cost'], 'order_status' => $o_u['order_status'], 'order_products' => $products_list, 'idx' => $idx ); if ($tpl !== '') { $output .= $modx->getChunk($tpl, $order_data); } //В случае, если шаблон оформления заказа не задан - выводим массив доступных плейсхолдеров вместе с содержимым else { $output .= '<pre>'.print_r($order_data, 1).'</pre>'; } $idx++; } $result = $modx->getChunk($tplWrapper, array ( 'output' => $output, 'orders_total' => count($orders_unique) ) ); return $result;Содержимое чанка 'tpl.profile.orders_list.wrapper': <!-- tpl.profile.orders_list.wrapper--> <div class="pure-g ord-lst-wrap"> <div class="pure-u-1"> <div class="pure-g ord-lst-body"> [[+output]] </div> </div> <div class="pure-u-1"> <p>Всего заказов: [[+orders_total]]</p> </div> </div> <!-- /tpl.profile.orders_list.wrapper-->Содержимое чанка 'tpl.profile.orders_list.row': <!-- tpl.profile.orders_list.row --> <div class="pure-g ord-lst-item" id="order-list-item-[[+idx]]"> <div class="pure-u-1"> <div class="pure-g"> <div class="pure-u-6-24"><span>Номер:[[+order_num]]</span></div> <div class="pure-u-6-24"><span>Дата:[[+order_createdon]]</span></div> <div class="pure-u-6-24"><span class="center">Стомость:[[+order_total_cost]] руб.</span></div> <div class="pure-u-6-24"><span class="center">Статус:[[+order_status]]</span></div> </div> </div> <div class="pure-u-1"> <div class="pure-g ord-prod-wrap"> <div class="pure-u-1"> <div class="pure-u-2-24"><span>ID товара</span></div> <div class="pure-u-12-24"><span>Наименование</span></div> <div class="pure-u-3-24"><span>Цена</span></div> <div class="pure-u-3-24"><span>Количество</span></div> <div class="pure-u-4-24"><span>Итого</span></div> </div> <div class="pure-u-1 ord-prod-lst"> [[+order_products]] </div> </div> </div> </div> <!-- /tpl.profile.orders_list.row -->Содержимое чанка 'tpl.profile.orders_list.products.row': <!-- tpl.profile.orders_list.products.row --> <div class="pure-g order-products-item"> <div class="pure-u-2-24"><span>[[+product_id]]</span></div> <div class="pure-u-12-24"><span>[[+product_name]]</span></div> <div class="pure-u-3-24"><span>[[+product_price]] руб.</span></div> <div class="pure-u-3-24"><span>[[+product_count]]</span></div> <div class="pure-u-4-24"><span>[[+product_cost]] руб.</span></div> </div> <!-- /tpl.profile.orders_list.products.row -->Содержимое чанка 'tpl.profile.orders_list.empty': <!-- tpl.profile.orders_list.empty --> <div class="pure-g ord-lst-empty-wrap"> <div class="pure-u-1"> <p>Вы не сделали ни одного заказа.</p> </div> </div> <!-- /tpl.profile.orders_list.empty -->Вызов сниппета на странице:{$_modx->runSnippet('!getUserOrders',[ 'user' => $_modx->user.id, ])} Вопросы / Дублирование результатов запроса после leftJoin 3 0 1
Wassi Wassinen · 10 января 2015, 15:55 Я немного поразмышлял на тему медалей и прочих званий. По сути, это просто реализовать с помощью стилей. В большинстве случаев, все эти приблуды отображаются на странице пользователя и даются за достижение каких-то показателей. Допустим, за каждые сто заметок. Пишем простой снипет, который делит количество статей этого пользователя на сто и в зависимости от результата отдает html сущности, которые отображаются на странице пользователя как медали, короны и что угодно. Краудфандинг / Отображение страницы пользователя 68 0 1
Василий Наумкин · 20 октября 2014, 16:10 msProducts сразу выбирает картинки, если указан &includeImages и точно так же позволяет указывать prepareSnippet. Используй его и картинки уже будут в $row. Вообще, посмотри, что сейчас там есть: echo '<pre>';print_r($row);die; Вопросы / Работа с prepareSnippet 23 0 1
UiCMPGenerator дополнение для создания пакетов Ближе к сентябрю, основная загвоздка это создание нормальной документации и видео обзора, а так пакет как бы уже готов
Checkbox для модального окна Они не отключены, они платные, чтобы писали только те, кому действительно очень надо. Когда бесплатно люди начинают думать, что я им должен.
[SendIt 2.6.0] Анализ поведения пользователя для защиты от спама (невидимая капча)... Здравствуйте. Делаю личный кабинет на Sendit и со сбросом пароля возникли проблемы. Можете подсказать, в чем ошибка? Список вопросов в одноименном разделе на modx.pro пока пуст, и,...
Minishop + честный знак (продажа маркированной продукции) В нашем случае мы решили убрать всю логику по маркировке сайта.
MiniShop3 - Не выводятся товары дополнительных категорий @SYAN ваша указанная проблема исправлена еще до версии 1.2.3 @Павлик Мышкин завел: github.com/modx-pro/MiniShop3/issues/480 github.com/modx-pro/MiniShop3/issues/481Исправим в б...
MobileDetect 2.0.0-pl функция "планшеты как стандартные браузеры не работает" в 2.1.0-pl баг исправлен
msImportExport не сохраняет родителя по умолчанию Компонент не понимает кирилические домены при загрузку фото. пример: Error download. Url : https://антаресдвери.рф/upload/iblock/a50/a50b2ef45305a3c18f6e298f1e134880.jpg. Message...
Email очень просто изменить, поэтому лучше проверять текст комментария на спамерскую ссылку.
Ниже приведен код сниппета и его чанков оформления.
Сниппет возвращает список заказов конкретного пользователя вместе с товарами заказа и оформляет вывод в чанки.
На вход сниппет принимает параметры:
'user' => Пользователь, чьи заказы выводим;
'tpl' => Чанк оформления элемента списка заказов;
'tplWrapper' => Чанк оформления оболочки списка заказов;
'tplProducts' => Чанк оформления элемента списка продуктов в заказе;
'tplEmpty' => Чанк оформления пустого результата;
Код сниппета «getUserOrders»:
Содержимое чанка 'tpl.profile.orders_list.wrapper':
Содержимое чанка 'tpl.profile.orders_list.row':
Содержимое чанка 'tpl.profile.orders_list.products.row':
Содержимое чанка 'tpl.profile.orders_list.empty':
Вызов сниппета на странице:
Используй его и картинки уже будут в $row. Вообще, посмотри, что сейчас там есть: