Алексей Суслов
С нами с 21 июля 2016; Место в рейтинге пользователей: #320AMO CRM - решение бага с получением токена авторизации.
Первое получение токена авторизации к компоненте AMO CRM пожалуй самый распространенная проблема, с которой сталкиваются все пользователи компонента.
Да действительно механизм первого подключения сайта к AMO CRM получился неудачным, еще на стадии архитектуры. Когда-нибудь я обязательно выпущу обновление, а пока хотел бы поделиться скриптом упрощающим жизнь.
Да действительно механизм первого подключения сайта к AMO CRM получился неудачным, еще на стадии архитектуры. Когда-нибудь я обязательно выпущу обновление, а пока хотел бы поделиться скриптом упрощающим жизнь.
Еще немного про сессии MODX, компонент smartSessions
Всем привет!
Небольшая предыстория
Когда я на свой VPS сервер закинул очередной более-менее крупный сайт (в базе около 25 тыс. товаров), у меня начались проблемы с нехваткой памяти, mysql ее нещадно отъедал.
В процессе оптимизации я начал понимать, что у половины сайтов в базе большую часть объема занимает пресловутая таблица modx_sessions, где, как известно, лежат сессии посетителей.
Но… почему? У сайта посещаемость 150-200 человек в сутки, сессии хранятся 7 дней (да, я проверил, они действительно очищаются), но в таблице почему-то 200000 записей, хотя по логике вещей должно быть 200*7=1400+. Реальность расходится с теорией не на 5-10%, а в десятки раз!
В итоге таблица весит полгигабайта, сайтов штук 10, каждому дай памяти, вот VPS и падает периодически… непорядок!
Небольшая предыстория
Когда я на свой VPS сервер закинул очередной более-менее крупный сайт (в базе около 25 тыс. товаров), у меня начались проблемы с нехваткой памяти, mysql ее нещадно отъедал.
В процессе оптимизации я начал понимать, что у половины сайтов в базе большую часть объема занимает пресловутая таблица modx_sessions, где, как известно, лежат сессии посетителей.
Но… почему? У сайта посещаемость 150-200 человек в сутки, сессии хранятся 7 дней (да, я проверил, они действительно очищаются), но в таблице почему-то 200000 записей, хотя по логике вещей должно быть 200*7=1400+. Реальность расходится с теорией не на 5-10%, а в десятки раз!
В итоге таблица весит полгигабайта, сайтов штук 10, каждому дай памяти, вот VPS и падает периодически… непорядок!
Как вывести ссылку на оплату на странице успешного заказа?
Здравствуйте. Хочу немного переделать логику оформления заказа. Мне нужно чтобы при выборе онлайн-оплаты не происходил редирект на платежный сервис сразу, а сначала был переход на страницу Спасибо за заказ. И уже на этой странице я бы выводил пользователю линк для оплаты.
Я так понимаю, что нужно расширить класс msOrderHandler для того, чтобы убрать редирект. Но вот каким образом в чанке tpl.msGetOrder вывести ссылку на оплату? Подскажете?
Решение:
Для того, чтобы при выборе любого способа оплаты не было редиректа на платёжную систему необходимо расширить класс заказа . Код нового класса:
Я так понимаю, что нужно расширить класс msOrderHandler для того, чтобы убрать редирект. Но вот каким образом в чанке tpl.msGetOrder вывести ссылку на оплату? Подскажете?
Решение:
Для того, чтобы при выборе любого способа оплаты не было редиректа на платёжную систему необходимо расширить класс заказа . Код нового класса:
<?php
if (!class_exists('msOrderInterface')) {
require_once MODX_CORE_PATH . 'components/minishop2/model/minishop2/msorderhandler.class.php';
}
class appOrderHandler extends msOrderHandler implements msOrderInterface
{
/** @var modX $modx */
public $modx;
/** @var miniShop2 $ms2 */
public $ms2;
/** @var array $config */
public $config;
/** @var array $order */
protected $order;
function __construct(miniShop2 & $ms2, array $config = [])
{
parent::__construct($ms2, $config);
//$this->modx->log(1, print_r('__construct', 1));
}
/**
* @param array $data
*
* @return array|string
*/
public function submit($data = [])
{
$response = $this->ms2->invokeEvent('msOnSubmitOrder', [
'data' => $data,
'order' => $this,
]);
if (!$response['success']) {
return $this->error($response['message']);
}
if (!empty($response['data']['data'])) {
$this->set($response['data']['data']);
}
$response = $this->getDeliveryRequiresFields();
if ($this->ms2->config['json_response']) {
$response = json_decode($response, true);
}
if (!$response['success']) {
return $this->error($response['message']);
}
$requires = $response['data']['requires'];
$errors = [];
foreach ($requires as $v) {
if (!empty($v) && empty($this->order[$v])) {
$errors[] = $v;
}
}
if (!empty($errors)) {
return $this->error('ms2_order_err_requires', $errors);
}
$user_id = $this->ms2->getCustomerId();
if (empty($user_id) || !is_int($user_id)) {
return $this->error(is_string($user_id) ? $user_id : 'ms2_err_user_nf');
}
$cart_status = $this->ms2->cart->status();
$delivery_cost = $this->getCost(false, true);
$cart_cost = $this->getCost(true, true) - $delivery_cost;
$createdon = date('Y-m-d H:i:s');
/** @var msOrder $order */
$order = $this->modx->newObject('msOrder');
$order->fromArray([
'user_id' => $user_id,
'createdon' => $createdon,
'num' => $this->getNum(),
'delivery' => $this->order['delivery'],
'payment' => $this->order['payment'],
'cart_cost' => $cart_cost,
'weight' => $cart_status['total_weight'],
'delivery_cost' => $delivery_cost,
'cost' => $cart_cost + $delivery_cost,
'status' => 0,
'context' => $this->ms2->config['ctx'],
]);
// Adding address
/** @var msOrderAddress $address */
$address = $this->modx->newObject('msOrderAddress');
$address->fromArray(array_merge($this->order, [
'user_id' => $user_id,
'createdon' => $createdon,
]));
$order->addOne($address);
// Adding products
$cart = $this->ms2->cart->get();
$products = [];
foreach ($cart as $v) {
if ($tmp = $this->modx->getObject('msProduct', ['id' => $v['id']])) {
$name = $tmp->get('pagetitle');
} else {
$name = '';
}
/** @var msOrderProduct $product */
$product = $this->modx->newObject('msOrderProduct');
$product->fromArray(array_merge($v, [
'product_id' => $v['id'],
'name' => $name,
'cost' => $v['price'] * $v['count'],
]));
$products[] = $product;
}
$order->addMany($products);
$response = $this->ms2->invokeEvent('msOnBeforeCreateOrder', [
'msOrder' => $order,
'order' => $this,
]);
if (!$response['success']) {
return $this->error($response['message']);
}
if ($order->save()) {
$response = $this->ms2->invokeEvent('msOnCreateOrder', [
'msOrder' => $order,
'order' => $this,
]);
if (!$response['success']) {
return $this->error($response['message']);
}
$this->ms2->cart->clean();
$this->clean();
if (empty($_SESSION['minishop2']['orders'])) {
$_SESSION['minishop2']['orders'] = [];
}
$_SESSION['minishop2']['orders'][] = $order->get('id');
// Trying to set status "new"
$response = $this->ms2->changeOrderStatus($order->get('id'), 1);
if ($response !== true) {
return $this->error($response, ['msorder' => $order->get('id')]);
} else {
if ($this->ms2->config['json_response']) {
return $this->success('', ['msorder' => $order->get('id')]);
} else {
$this->modx->sendRedirect(
$this->modx->context->makeUrl($this->modx->resource->id, ['msorder' => $response['data']['msorder']])
);
return $this->success();
}
}
}
return $this->error();
}
}
msOptions не отрабатывает с первого раза
Добрый день, не могу понять, почему
[[!msOptions? name=`using` &tpl=`msOptionTpl` &product=`[[*id]]`]]
в шаблоне с чанком msOptionTpl{foreach $options as $name => $values}
<label for="option_{$name}">{('ms2_product_' ~ $name) | lexicon}:</label>
<div name="options[{$name}]" id="option_{$name}" class="value">
{foreach $values as $value}
<span value="{$value}">{$value}</span>
{/foreach}
</div>
{/foreach}
на сайте отрабатывает не с первой загрузки страницы, а только после повторного обновления страницы (F5). Есть соображения? Спасибо. Fenom вместо getImageList MIGx
Есть обработка MIGx полей через Fenom с условиями:
Решение
{set $rows = json_decode($_modx->resource.tv_name, true)}
{foreach $rows as $_list $row}
{if $_last==1}
'какойто коТ'
{/if}
{/foreach}
Все замечательно работает, но если мне к примеру помимо _last нужны поля idx, _alt, _first и прочее, как быть в таком случае? Неужели без getImageList все же не обойтись?Решение
{set $rows = json_decode($_modx->resource.migx_tv, true)}
{set $idx = 0}
{foreach $rows as $idxArr => $row}
{set $row['idx'] = $idx++} {* idx от созданной переменной с инкриментом*}
{set $row['idxForeach'] = $row@index} {* idx от foreach*}
{*set $idxMIGX = $row['MIGX_id']*} {* idx от MIGX*}
{if $row@first}
{set $row['_first'] = 'first item'}
{/if}
{if $row@last}
{set $row['_last'] = 'last item'}
{/if}
{if !($idx % 2)}
{set $row['_alt'] = 'odd item'}
{/if}
{$row | print_r}
{/foreach}
minishop2 Баг: Такое изображение уже есть в галере
Загружаю картинки в галерею товаров. Выдаёт ошибку
Причем все картинки разные. Пробовал на нескольких сайтах, минишоп последней версии.
Вот эти файлы, можете попробовать их загрузить. Скачать
Подскажите пожалуйста, что можно сделать. Ведь картинки то разные.
PS: Было бы класнcо сделать системную настройку, которая отключает эту проверку.
Такое изображение уже есть в галерее товара.
http://prntscr.com/fhdgvhПричем все картинки разные. Пробовал на нескольких сайтах, минишоп последней версии.
Вот эти файлы, можете попробовать их загрузить. Скачать
Подскажите пожалуйста, что можно сделать. Ведь картинки то разные.
PS: Было бы класнcо сделать системную настройку, которая отключает эту проверку.
Регистрационные данные на почту клиента, miniShop2
Появилась задача: после заказа клиентом товаров в интернет-магазине, реализованном на miniShop2, высылать регистрационные данные (логин/пароль) на указанную почту клиента. Из коробки почему то такого функционала нет, хотя регистрация проходит. Получается так, что пользователь после оформления заказа даже и не подозревает что только что зарегистрировался на сайте. Как-то это не правильно. Собственно отсюда и появилась такая задача.
Загрузка заказов ms2, Tikets на стартовой странице
При сравнении «специализированных» cms для интернет магазинов и minishop заметил общую тенденцию у первых выводить при входе в админку список заказов. После недолгой переписки с замечательным исполнителем Павлом Гвоздем возникло такое замечательное и гениальное по простоте решение:
заходим в настройки системы, далее в фильтре по ключу отыскиваем 2 значения:
1. welcome_action меняем с welcome на mgr/orders
2. welcome_namespace с core на minishop2
и вуаля на чистом клиенте отображается список заказов, очень удобно
заходим в настройки системы, далее в фильтре по ключу отыскиваем 2 значения:
1. welcome_action меняем с welcome на mgr/orders
2. welcome_namespace с core на minishop2
и вуаля на чистом клиенте отображается список заказов, очень удобно
Добавление своих полей в форму заказа [обновлено]
При разработке нескольких проектов, возникала необходимость в получении дополнительных данных от покупателей, а полей в miniShop2 ограниченное количество. Поиск готового решения результата не дал, поэтому предлагаю свой вариант.
Решение обновлено, убраны правки исходного кода минишопа, теперь при обновлении ничего не затрется, изменены ключи у полей
Решалось это следующим образом:
1. Добавлялись необходимые поля, для примера взяты тип плательщика, название организации и инн.
2. Добавлялся плагин срабатывающий при сохранении заказа и при подключении js минишопа в админке.
3. Редактировались настройки и записи словарей.
Более подробно далее
Решение обновлено, убраны правки исходного кода минишопа, теперь при обновлении ничего не затрется, изменены ключи у полей
Решалось это следующим образом:
1. Добавлялись необходимые поля, для примера взяты тип плательщика, название организации и инн.
2. Добавлялся плагин срабатывающий при сохранении заказа и при подключении js минишопа в админке.
3. Редактировались настройки и записи словарей.
Более подробно далее
msProducts + все изображения товара CONCAT
Ребята) есть задача выводить 10 популярных товаров со всеми изображениями выбранных товаров
Вызывать сниппет msGallery в количестве 10 раз не предлагать)
Взял на основу стандартный SQL который формируется при вызове сниппета
Вызывать сниппет msGallery в количестве 10 раз не предлагать)
Взял на основу стандартный SQL который формируется при вызове сниппета
{set $popularProducts = $_modx->runSnippet('!msProducts', [
'parents' => 0,
'tpl' => 'tpl.popular.products.row',
'limit' => ($limit?$limit:4),
'includeThumbs' => '120x90,360x270',
'where' => [
'Data.popular' => 1
],
'showLog' => 1
])}
{$popularProducts?:'К сожалению популярных продуктов не найдено.'}
Мною был взят сформированный SQL, добавлен CONCAT и вроде на выходе то, что нужно, но как это все подружить со сниппетом не представляю.