Денис · 11 декабря 2018, 19:19 Судя по исходникам просто так не выйдет. Создайте плагин и повесьте на событие OnManagerPageBeforeRender После вставьте следующий код: <?php switch ($modx->event->name) { case 'OnManagerPageBeforeRender': if($controller->config['controller'] == "mgr/orders") { if ($miniShop2 = $modx->getService('miniShop2')) { $modx->controller->addHtml('<style>.x-grid3-col-order-product-image img {width:40px;display:block;}</style>'); $modx->controller->addHtml(' <script> Ext.onReady(function(){ var originalGetColumns = miniShop2.grid.OrderProducts.prototype.getColumns; miniShop2.config["default_thumb"] = miniShop2.config["defaultThumb"]; Ext.override(miniShop2.grid.OrderProducts,{ getColumns: function () { var imgFields = [ "product_thumb", "product_image" ]; var columns = originalGetColumns.apply(this); for(var i=0; i<columns.length; i++){ if(imgFields.indexOf(columns[i]["dataIndex"]) != -1){ columns[i]["renderer"] = miniShop2.utils.renderImage; columns[i]["id"] = "order-product-image"; } } return columns; } }); }); </script> '); } } break; } Если в системной настройке ms2_order_product_fields указан product_thumb или product_image, то вы увидите уже не ссылку, а картинку. Вопросы / Вывод изображения в Заказы>Покупки (админка Minishop2) 3 +5 5
Наумов Алексей · 29 августа 2018, 11:23 Есть такое решение у меня: 1) Создаем TV changeTemplate и назначаем его категориям. 2) Создает плагин changeTemplate, на событие OnDocFormRender (код ниже) 3) Теперь в TV мы можем написать: «2» — всем дочерним ресурсам будет назначен шаблон 2 «2,3» — первый уровень дочерних ресурсов будет с шаблоном 2, второй уровень и далее — с шаблоном 3 ну и т.д., «2,3,4» 4) Но данный плагин сработает на все, в том числе и на категории, а не только на товары, если это нужно исправить — внесите изменения в код. <?php /** * ========================= * ChangeTemplate * ========================= * * Plugin for MODX Revolution * Set which template is inherited by children * documents of a certain parent document * * Author: * Marc Loehe (boundaryfunctions) * marcloehe.de * * Modified by: * Lorenzo Stanco <lorenzo.stanco@gmail.com> * Lorenzostanco.com * * Usage: * * 1. Paste this as new plugin and connect it to system event * 'OnDocFormRender'. * * 2. Assign a new TV 'changeTemplate' to each template * for which you want to define the default children template. * * 3. Set the newly created TV to input type "Text" * * 4. Open a document and in the 'changeTemplate' TV type a * comma separated list of template IDs. * * 5. Have fun! * */ // Check Event if ($modx->event->name == 'OnDocFormRender' && $mode == modSystemEvent::MODE_NEW) { $id = empty($_REQUEST['id']) ? false : $_REQUEST['id']; $id = empty($id) ? (empty($_REQUEST['parent']) ? false : $_REQUEST['parent']) : $_REQUEST['parent']; // Get current document ID if ($id) { // Document Chain $resources = array($id); // Get parent ID foreach ($modx->getParentIds($id, 10, array('context' => $_REQUEST['context_key'])) as $parentId) { if ($parentId) array_push($resources, $parentId); } // Search changeTemplate in the chain $level = 0; $childTemplates = array(); foreach ($resources as $resourceId) { $resource = $modx->getObject('modResource', $resourceId); if ($childTemplatesTV = $resource->getTVValue('changeTemplate')) { // Create template array for each tree level $childTemplates = @explode(',', $childTemplatesTV); if (empty($childTemplates)) break; foreach ($childTemplates as $k => $v) $childTemplates[$k] = intval(trim($v)); break; } $level++; } // Set template based on tree level if (!empty($childTemplates)) { $useTemplate = $childTemplates[$level]; if (!empty($useTemplate)) { // Set default template if (isset($modx->controller)) { $modx->controller->setProperty('template', $useTemplate); } else { // modX < 2.2.0 $_REQUEST['template'] = $useTemplate; } } } } } Вопросы / Разные шаблоны товара для разных категорий minishop2 5 +1 2
Наумов Алексей · 01 февраля 2018, 16:46 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; Вопросы / SMS с формы 5 +4 4
Володя · 14 декабря 2017, 16:22 в связанных комбиках слушать select и выставлять в зависимые комбики нужный параметр. listeners: { select: { fn: function (r) { this.handleChange(); }, scope: this } }Если связей много то можно навесить общую функцию и в ней выставлять нужные поля. handleChange: function (change) { var f = this.fp.getForm(); var _field1 = f.findField('field1'); var _field2 = f.findField('field2'); _field2.baseParams.param = _field1.getValue(); //перегрузить стор _field2.store.load(); } Вопросы / ExtJs и зависимые SuperBoxSelect 4 +1 2
Ilya Ev · 26 октября 2017, 18:47 в муках родился запрос, делюсь думаю будет полезно, ктото спрашивал тоже. Вроде работает 'leftJoin' => '{ "Pprice" : { "class" : "cfField", "alias" : "Pprice", "on" : "Pprice.city_id = ' ~ $_modx->getPlaceholder('cf.current_city.id') ~ ' AND Pprice.placeholder = CONCAT(\'[pre]\', msProduct.id, \'_price[/pre]\')" } }', 'select' => '{ "Pprice" : "Pprice.value" }', 'where' => '{"Pprice.value:>":"0"}'исключает все товары города у которых не выставлены цены. Остальное тоже решил. Кроме переключения города по ссылке без домена. Буду надеется автор добавит данную возможность в пакет. Новые дополнения и их версии / cityFields. Города, информация и цены для каждого 92 +1 1
Роман Ильин · 12 сентября 2017, 23:09 Сниппет для удаления старых версий: <?php /** * versionCleanX * * @author Scott Pronych, September 27, 2013 * * DESCRIPTION * * For use with VersionX to delete old content * * PROPERTIES: * * &contentType - can be resource, chunk, plugin, snippet, template, or templatevar * &maxVersions - integer value for max number of versions you would like to keep * * USAGE: * * [[!versionCleanX? &contentType=`resource` &maxVersions=`10`]] * */ $cx_type = $modx->getOption('contentType', $scriptProperties, 'resource'); $cx_max = (int) $modx->getOption('maxVersions', $scriptProperties, 5); $GLOBALS['count'] = 1; $GLOBALS['total'] = 0; $GLOBALS['deleted'] = 0; $GLOBALS['page_total'] = 0; $GLOBALS['page_deleted'] = 0; $GLOBALS['page_name'] = ''; $GLOBALS['prev_content_id'] = 0; $GLOBALS['prev_version_id'] = 0; switch ($cx_type) { case 'chunk': $name = 'name'; break; case 'plugin': $name = 'name'; break; case 'snippet': $name = 'name'; break; case 'template': $name = 'templatename'; break; case 'templatevar': $name = 'name'; break; default: $name = 'title'; $cx_type = 'resource'; } $GLOBALS['db_name'] = 'modx_versionx_' . $cx_type; function delete_row ($id) { global $modx; $query = "DELETE FROM `" . $GLOBALS['db_name'] . "` WHERE version_id = '" . $id . "'"; $result = $modx->query($query); if (!is_object($result)) return false; else { $GLOBALS['deleted']++; $GLOBALS['page_deleted']++; $GLOBALS['page_total']++; $GLOBALS['total']++; $GLOBALS['count']++; return true; } } function log_row () { $GLOBALS['data'] .= '<tr><td>' . $GLOBALS['page_name'] . '</td><td>' . $GLOBALS['page_total'] . '</td><td>' . $GLOBALS['page_deleted'] . "</td></tr>\n"; $GLOBALS['page_deleted'] = 0; $GLOBALS['page_total'] = 1; $GLOBALS['count'] = 1; } $query = "SELECT version_id, content_id, " . $name . " AS page_title FROM `" . $GLOBALS['db_name'] . "` ORDER BY content_id ASC, version_id DESC"; $GLOBALS['data'] = ''; $output = 'An error occurred: '; $versionx = $modx->query($query); if (!is_object($versionx)) { return $output . 'query error ' . print_r($modx->errorInfo(), true); } else { while($row = $versionx->fetch(PDO::FETCH_ASSOC)) { // New content_id so reset if ($prev_content_id == 0) { $prev_content_id = $row['content_id']; $prev_version_id = $row['version_id']; $GLOBALS['total']++; $GLOBALS['page_total']++; $GLOBALS['count']++; $GLOBALS['page_name'] = $row['page_title']; } elseif ($prev_content_id != $row['content_id']) { if ($GLOBALS['count'] > $cx_max) { if (!delete_row($prev_version_id)) return $output . 'deleting row for ' . $GLOBALS['page_name'] . ' Row: ' . $prev_content_id . ' ' . print_r($modx->errorInfo(), true); $GLOBALS['page_total']--; } else { $GLOBALS['total']++; $GLOBALS['count']++; } log_row(); $prev_content_id = $row['content_id']; $prev_version_id = $row['version_id']; $GLOBALS['page_name'] = $row['page_title']; } // Content count is over the max so delete previous row elseif ($GLOBALS['count'] > $cx_max) { delete_row($prev_version_id); $prev_content_id = $row['content_id']; $prev_version_id = $row['version_id']; } else { $GLOBALS['count']++; $GLOBALS['page_total']++; $GLOBALS['total']++; $prev_content_id = $row['content_id']; $prev_version_id = $row['version_id']; } } log_row(); if ($GLOBALS['data'] != '') { $output = '<h3>VersionX Cleanup for ' . $GLOBALS['db_name'] . '</h3> <p>Total records: <strong>' . $GLOBALS['total'] . '</strong> Total deleted: <strong>' . $GLOBALS['deleted'] . '</strong></p> <table class="table table-striped"> <thead> <tr> <th>Page name</th> <th>Total found</th> <th>Deleted</th> </tr> </thead> <tbody> ' . $GLOBALS['data'] . '</tbody></table> '; } else $output = 'Error: no data found.'; } $query = "OPTIMIZE TABLE `" . $GLOBALS['db_name'] . "`"; $versionx = $modx->query($query); if (!is_object($versionx)) { $output = 'Optimize error ' . print_r($modx->errorInfo(), true) . $output; } return $output; Вызывать так: [[!versionCleanX? &contentType=`resource` &maxVersions=`10`]] Вопросы / VersionX переполнил базу данных 8 +2 13
Николай Загумённов · 02 сентября 2017, 12:19 Хочу поделиться сниппетом, аналог pdoField, так как я часто пользуюсь pdoField. Сниппет getLocalizatorField <?php $sp = &$scriptProperties; $resource_id = $modx->getOption('resource_id', $sp, $modx->resource->id); $field = $modx->getOption('field', $sp, 'pagetitle'); $key = $modx->getOption('key', $sp, $modx->getOption('cultureKey')); $q = $modx->newQuery( "localizatorContent" ); $q->where( array( "`resource_id` = '" . $resource_id . "'", "`key` = '" . $key . "'" ) ); $q->select( array( $field ) ); $s = $q->prepare(); // print $q->toSQL(); die; $s->execute(); $array = $s->fetch(PDO::FETCH_ASSOC); $field_value = $array[$field]; return $field_value;Вызов: {'getLocalizatorField' | snippet : [ 'resource_id' => 20, 'field' => 'content' ]} Новые дополнения и их версии / [localizator] Мультиязычность, СЕО, автоперевод... 353 +2 2
Василий Столейков · 05 февраля 2017, 17:13 Спасибо, очень полезно на будущее! Я уже вывел логику из класса, выкинул всё лишнее и использую сниппет goo_gl следующим образом: <?php $key = '__API__'; // Ваш API ключ define('API_KEY', $key); define('API_URL', 'https://www.googleapis.com/urlshortener/v1'); // создаём cURL соединение $curl_connection = curl_init( sprintf('%s/url?key=%s', API_URL, API_KEY) ); // попросить cURL возвращать данные, а не выводить curl_setopt($curl_connection, CURLOPT_RETURNTRANSFER, true); // создадим данные для перекодировки в JSON $requestData = array( 'longUrl' => $input ); // изменим тип запроса на POST curl_setopt($curl_connection, CURLOPT_POST, true); // установим тип контента JSON curl_setopt($curl_connection, CURLOPT_HTTPHEADER, array('Content-type: application/json')); // передадим данные JSON в тело POST запроса curl_setopt($curl_connection, CURLOPT_POSTFIELDS, json_encode($requestData)); // выполним запрос $data = curl_exec($curl_connection); curl_close($curl_connection); // перекодирум и возвратим данные $response = json_decode($data, true); // return $response['longUrl']; // Длинная ссылка return $response['id']; Использую его как модификатор: {$url|goo_gl} Готовые решения / Сокращение URL goo.gl 7 0 2
Алексей Федоров · 08 января 2017, 20:48 Сталкивался)) Вот инструкция, помогает получить больше информации об источнике ошибки. Почему modx без пинка в виде правки кода это не делает понять не могу до сих пор Вопросы / Ошибка ...not be passed to makeUrl() 8 +3 2
Sergey · 15 сентября 2016, 09:40 Расписано здесь. Слегка модифицировал: public function toJSON($array) { $encoded= ''; if ( is_array($array) ) { if (!function_exists('json_encode')) { if (@ include_once (XPDO_CORE_PATH . 'json/JSON.php')) { $json = new Services_JSON(); $encoded= $json->encode($array); } } else { $encoded= json_encode($array); if (json_last_error() == JSON_ERROR_UTF8) { $array = self::arrayEncodeUTF8($array); $encoded= json_encode($array); } } } return $encoded; } public static function arrayEncodeUTF8($array) { foreach($array as $key => $value) { if (!is_array($value)) { if (is_string($value)) { json_encode($value); if (json_last_error() == JSON_ERROR_UTF8) { $array[$key] = iconv('CP1251', 'UTF-8', $value); } } } else { $array[$key] = self::arrayEncodeUTF8($value); } } return $array; } — Win,XAMPP, PHP 7 Вопросы / Не загружается список пакетов. Loading. И ничего. 8 +2 1
Возможно ли реализовать возможность предоплаты за доставку на сайте? Так ради этого мне и нужно это все, чтобы клиент платил сразу при оформлении заказа, чтобы избавить себя от мусорных заявок (когда человек оставляет заявку, а предоплату делать не ...
Редизайн сообщества На больших экранах основной текст статьи я бы сделал 18 px. Да и текст комментариев можно таким сделать. Для меня лично 16 — мелковато на больших экранах (в комментариях вообще 15 ...
MiniShop3 1.11.0 при клике на radio идет пересчет итоговой суммы в orderUI, в зависимости от способов(оплаты доставки) я так поняла. попробуй код запуска события поставить ниже чем orderUI, после
ImageOptimizer - WebP/AVIF и responsive <picture> для MODX 3 Дополнение доступно modstore.pro/packages/photos-and-files/imageoptimizer
Localizator3 для MODX 3: перевод полей и TV без отдельного context на язык, Vue 3 + PrimeV... Добавил localizator3_default_language
msInShopNotify Начиная с версии 3.0.0-beta добавлена поддержка MiniShop3 Минимальные требования: PHP 8.4 MODX 3.2 MiniShop3
MaxNotify Обновление 1.2.0-pl (03.07.2026) — добавлены уведомления о заявках FormIt через hook-сниппет `maxNotifyFormIt`; — добавлены уведомления о заявках SendIt через hook-...
[msBonus2] 1.3.0 Бонус-коды, уведомления о сгорании и совместимость с msMultiCurre... Да, планируется. Даже чуть больше, чем просто бонусная система)
Создайте плагин и повесьте на событие OnManagerPageBeforeRender
После вставьте следующий код:
Если в системной настройке ms2_order_product_fields указан product_thumb или product_image, то вы увидите уже не ссылку, а картинку.
1) Создаем TV changeTemplate и назначаем его категориям.
2) Создает плагин changeTemplate, на событие OnDocFormRender (код ниже)
3) Теперь в TV мы можем написать:
«2» — всем дочерним ресурсам будет назначен шаблон 2
«2,3» — первый уровень дочерних ресурсов будет с шаблоном 2, второй уровень и далее — с шаблоном 3
ну и т.д., «2,3,4»
4) Но данный плагин сработает на все, в том числе и на категории, а не только на товары, если это нужно исправить — внесите изменения в код.
Предварительно создаем настройки
sms_ru_api_id — api ключ, который дадут при регистрации на сайте
manager_phone — номер телефона получателя
Если связей много то можно навесить общую функцию и в ней выставлять нужные поля.
исключает все товары города у которых не выставлены цены.
Остальное тоже решил. Кроме переключения города по ссылке без домена. Буду надеется автор добавит данную возможность в пакет.
Вызывать так:
Сниппет getLocalizatorField
Вызов:
Я уже вывел логику из класса, выкинул всё лишнее и использую сниппет goo_gl следующим образом:
Использую его как модификатор:
Слегка модифицировал:
— Win,XAMPP, PHP 7