Что-то не то с формированием заказа через API
Доброе утро!
Вчера весь вечер провозился и так и не понял что не так: есть сниппет, который по стандартной Безумкинской схеме отрабатывает аякс-запросы, один из экшенов принимает данные о товарах, программно формирует заказ и создаёт его, но проблема в том, что не смотря на параметр json_response=true,во время выполнения
Сам заказ формируется и сохраняется нормально, если что.
Вчера весь вечер провозился и так и не понял что не так: есть сниппет, который по стандартной Безумкинской схеме отрабатывает аякс-запросы, один из экшенов принимает данные о товарах, программно формирует заказ и создаёт его, но проблема в том, что не смотря на параметр json_response=true,
$miniShop2->order->submit()
ответ не отдаётся вообще и код после этого вызова не выполняется, а по аяксу пользователю отправляется простыня с хтмл-текстом страницы, вместо json с ответом. Вот кусок кода с этим функционалом:case 'submit':
try {
$data = $_POST['data'];
$profile = $modx->user->getOne('Profile');
$scriptProperties = array(
'json_response' => true, // возвращать ответы в JSON
);
$miniShop2 = $modx->getService('miniShop2');
$miniShop2->initialize($modx->context->key,$scriptProperties);
$miniShop2->order->clean();
$miniShop2->order->add('user_id', $modx->user->id);
$miniShop2->order->add('delivery', 10);
$miniShop2->order->add('payment', 20);
$miniShop2->order->add('email', $profile->get('email'));
$miniShop2->order->add('phone', $profile->get('phone'));
$miniShop2->order->add('receiver', $profile->get('fullname'));
$miniShop2->order->add('comment', $data['comment']);
$oldcart = $miniShop2->cart->get();
$miniShop2->cart->clean();
foreach($data['items'] as $item) {
$miniShop2->cart->add($item['id'],$item['count']);
}
$res = $miniShop2->order->submit(); //в $res ничего не попадает, и код после этой строки не выполняется
//вместо этого по аяксу пользователю улетает хтмл текущей страницы.
$miniShop2->cart->set($oldcart);
} catch (Exception $e) {
$res = 'error! ' . print_r($e);
}
break;
В чём косяк может быть? Вроде судя по докам так всё должно работать. Может именно из-за аякса что-то не то?Сам заказ формируется и сохраняется нормально, если что.
Поблагодарить автора
Отправить деньги
Комментарии: 19
Добрый день, попробуйте создать заказ через процессор, я например так и делаю по аяксу.
Пример рабочего процессора:
Мы просто используем методы минишоповского класса создания заказа, и будет все точно так же как и при стандартном оформлении, даже сообщение пользователю придет.
Пример рабочего процессора:
class orderCreate extends modProcessor
{
public $name;
public $phone;
public $street;
public $building;
public $room;
public $city;
public $email;
public $user_id;
public $cost;
public $createdon;
public $object;
public $order;
/* @var pdoTools $pdo */
protected $pdo;
protected $toEmail;
protected $prod_id;
protected $ms2;
protected $alias_id;
public function initialize()
{
$this->pdo = $this->modx->getService('pdoTools');
$this->ms2 = $this->modx->getService('miniShop2');
$this->createdon = date('Y-m-d H:i:s');
$this->name = trim(htmlspecialchars($_POST['name']));
$this->phone = trim(htmlspecialchars($_POST['phone']));
$this->email = trim(htmlspecialchars($_POST['email']));
$this->city = trim(htmlspecialchars($_POST['city']));
$this->street = trim(htmlspecialchars($_POST['street']));
$this->building = trim(htmlspecialchars($_POST['building']));
$this->room = trim(htmlspecialchars($_POST['room']));
$this->prod_id = (int)trim(htmlspecialchars($_POST['id']));
if (!$this->object = $this->modx->getObject('modResource', $this->prod_id)){
return $this->failure('Такого товара не существует');
}
return parent::initialize();
}
public function process()
{
$create = $this->createOrder();
if ($create != true) {
return $this->failure($create);
}
return $this->success('Заказ успешно создан');
}
public function createOrder()
{
$order = $this->modx->newObject('msOrder');
$order->fromArray([
'num' => $this->getNum(),
'user_id' => $this->getCustomerId(),
'createdon' => $this->createdon,
'delivery' => 1,
'payment' => 1,
'email' => $this->email,
'cart_cost' => $this->object->get('price'),
'cost' => $this->object->get('price'),
'status' => 1,
'context' => 'web'
]);
$this->beforeSave($order);
if (!$order->save()) {
return 'Ошибка создания заказа';
}
$this->ms2->changeOrderStatus($order->get('id'), 1);
return true;
}
public function getCustomerId()
{
if ($this->modx->user->isAuthenticated()) {
$profile = $this->modx->user->Profile;
if (!$profile->get('email')) {
$profile->set('email', $this->email);
$profile->save();
}
$uid = $this->modx->user->id;
} else {
if ($user = $this->modx->getObject('modUser', array('username' => $this->email))) {
$uid = $user->get('id');
} elseif ($profile = $this->modx->getObject('modUserProfile', array('email' => $this->email))) {
$uid = $profile->get('internalKey');
} else {
/** @var modUser $user */
$user = $this->modx->newObject('modUser', array('username' => $this->email, 'password' => md5(rand())));
$profile = $this->modx->newObject('modUserProfile', array(
'email' => $this->email,
'fullname' => $this->name,
));
$user->addOne($profile);
/** @var modUserSetting $setting */
$setting = $this->modx->newObject('modUserSetting');
$setting->fromArray(array(
'key' => 'cultureKey',
'area' => 'language',
'value' => $this->modx->getOption('cultureKey', null, 'en', true)
),'', true);
$user->addMany($setting);
$user->save();
if ($groups = $this->modx->getOption('ms2_order_user_groups', null, false)) {
$groups = array_map('trim', explode(',', $groups));
foreach ($groups as $group) {
$user->joinGroup($group);
}
}
$uid = $user->get('id');
}
}
return $uid;
}
public function beforeSave(msOrder $order){
$addressArray = [
'receiver' => $this->name,
'phone' => $this->phone,
'email' => $this->email,
'city' => $this->city,
'street' => $this->street,
'building' => $this->building,
'room' => $this->room
];
/** @var msOrderAddress $address */
$address = $this->modx->newObject('msOrderAddress');
$address->fromArray(array_merge($addressArray, [
'user_id' => $this->getCustomerId(),
'createdon' => $this->createdon,
]));
$productArr = [];
$product = $this->modx->newObject('msOrderProduct');
$product->fromArray([
'product_id' => $this->prod_id,
'cost' => $this->object->get('price'),
'price' => $this->object->get('price'),
'name' => $this->object->get('pagetitle'),
]);
$productArr[] = $product;
$order->addOne($address);
$order->addMany($productArr);
}
/**
* Return current number of order
*
* @return string
*/
public function getNum()
{
$cur = date('ym');
$num = 0;
$c = $this->modx->newQuery('msOrder');
$c->where(array('num:LIKE' => "{$cur}%"));
$c->select('num');
$c->sortby('id', 'DESC');
$c->limit(1);
if ($c->prepare() && $c->stmt->execute()) {
$num = $c->stmt->fetchColumn();
}
if (empty($num)) {
$num = date('ym') . '/0';
}
$num = explode('/', $num);
$num = $cur . '/' . ($num[1] + 1);
return $num;
}
}
return 'orderCreate';
Лично мне так удобнее, не знаю как остальным, но решение рабочее.Мы просто используем методы минишоповского класса создания заказа, и будет все точно так же как и при стандартном оформлении, даже сообщение пользователю придет.
Ох, вот это радикальненько. А не будет проблем с правами пользователей? Это же из сниппета на пользовательской странице вызываться будет.
И всё равно хочется разобраться, почему не работает json_response. Призываю богов минишопа! @Василий Наумкин, @Володя, почему стандартный
И всё равно хочется разобраться, почему не работает json_response. Призываю богов минишопа! @Василий Наумкин, @Володя, почему стандартный
$miniShop2->order->submit()
отдаёт хтмл вместо json, как описано в топике?
Не будет, там метод создания пользователя минишопа, которому даются стандартные права user-member
вот спустя почти 4 года проблема с
Удалось кому-то решить?
$miniShop2->order->submit()
осталась.Удалось кому-то решить?
У меня так вызывается
$scriptProperties = [
'json_response' => 1,
];
/* возможно эта строчка поможет */
$miniShop2 = $modx->getService('minishop2','miniShop2', MODX_CORE_PATH . 'components/minishop2/model/minishop2/', $scriptProperties);
$miniShop2->initialize($modx->context->key, $scriptProperties);
$miniShop2->order->clean();
$miniShop2->cart->clean();
$miniShop2->cart->add($dataForm['id'],($dataForm["count"] ?: 1),$option);
/* ... */
$resp['r'] = json_decode($miniShop2->order->submit(),1);
Действительно
Вот пример:
Никак не могу решить данную проблему
$scriptProperties = ['json_response' => 1];
помогает, но в таком случае ответ приходит в виде html с содержимым {«data»: {«msorder»:15}} и полностью игнорирует построение ответа.Вот пример:
if (isset($response['success']) && $response['success'] == true) {
$result['post'] = $this->properties;
$result['response'] = $response;
$result['orderId'] = $response['data']['msorder'];
$miniShop2->cart->clean();
return $this->success('', $result);
}
и по идее, вывод должен быть таким только с наполненной data[]:{
"success": true,
"message": "",
"object": {
"post": {
"payment": "1",
"delivery": "1",
"name": "Алекс",
"email": "test@test.ru"
},
"response": {
"success": true,
"message": "",
"data": []
},
"orderId": null
},
"code": 200
}
а выведет при включенном json_response вот так:{"success":true,"message":"","data":{"msorder":53}}
Причем в html формате.Никак не могу решить данную проблему
видимо у меня так же, т.е. нужно самостоятельно получить заказ, т.к. далее у меня такой код:
$resp['r'] = $arr = json_decode($miniShop2->order->submit(),1);
if($arr['success'] && $arr["data"]["msorder"] > 0){
$msOrder = $modx->getObject('msOrder', $arr["data"]["msorder"]);
$order = $msOrder->toArray();
$resp['out'] = $pdo->parseChunk('@FILE cart/fastOrderSuccess.tpl',$arr);
}
не только 'json_response' => 1, а getService тоже смотрите параметры передаю
Не помогло, к сожалению.
Повторил ваше получение заказа и все равно тот же вывод
Даже нет ошибки из-за отсутствия такого чанка как у вас (специально решил не менять, чтобы вызвать ошибку)
Повторил ваше получение заказа и все равно тот же вывод
{"success":true,"message":"","data":{"msorder":56}}
в виде html с игнорированием вообще каких-либо конструкций вывода информации. Что само по себе очень странно.Даже нет ошибки из-за отсутствия такого чанка как у вас (специально решил не менять, чтобы вызвать ошибку)
код весь покажите тогда
там еще $pdo->… выше получаю:
$pdo = $modx->getService('pdoTools');
там еще $pdo->… выше получаю:
$pdo = $modx->getService('pdoTools');
<?php
class shopOrder2 extends shopBaseRestController
{
public $allowedMethods = array('post');
public function post()
{
// инициализируем miniShop2
$scriptProperties = [
'json_response' => 1,
];
$miniShop2 = $this->modx->getService('minishop2','miniShop2', MODX_CORE_PATH . 'components/minishop2/model/minishop2/', $scriptProperties);
// опции товара, если они необходимы
$option = array();
/*$option = array(
"option1" => "value1",
"option2" => "value2",
);*/
// инициализируем miniShop2 в текущем контексте
$miniShop2->initialize($this->modx->context->key, $scriptProperties);
$cart = $miniShop2->cart->get();
if (!count($cart)) {
$result = [
'message' => 'Корзина пуста',
'success' => false
];
return $this->failure('', $result);
}
//Получатель
$email = $this->getProperty('email');
$phone = $this->getProperty('phone');
$receiver = $this->getProperty('name');
//Дата и время доставки
//$soon = (bool)$this->getProperty('soon');
$delivery_date = $this->getProperty('delivery_date');
$delivery_time = $this->getProperty('delivery_time');
//Адрес
$street = $this->getProperty('street');
$building = $this->getProperty('building');
$room = $this->getProperty('apartment');
$entrance = $this->getProperty('entrance');
$floor = $this->getProperty('floor');
$comment = $this->getProperty('comment');
//Доставка и оплата
$payment = (int)$this->getProperty('payment');
$delivery = (int)$this->getProperty('delivery');
$miniShop2->order->add('payment', $payment);
$miniShop2->order->add('delivery', $delivery);
$miniShop2->order->add('receiver', $receiver);
$miniShop2->order->add('email', $email);
$miniShop2->order->add('phone', $phone);
$miniShop2->order->add('soon', $soon);
$miniShop2->order->add('delivery_date', $delivery_date);
$miniShop2->order->add('delivery_time', $delivery_time);
$miniShop2->order->add('street', $street);
$miniShop2->order->add('building', $building);
$miniShop2->order->add('room', $room);
$miniShop2->order->add('entrance', $entrance);
$miniShop2->order->add('floor', $floor);
$miniShop2->order->add('comment', $comment);
$result['r'] = json_decode($miniShop2->order->submit(),1);
$result['r'] = $arr = json_decode($miniShop2->order->submit(),1);
if($arr['success'] && $arr["data"]["msorder"] > 0){
$msOrder = $modx->getObject('msOrder', $arr["data"]["msorder"]);
$order = $msOrder->toArray();
$result['orderId'] = $order;
$resp['out'] = $pdo->parseChunk('@FILE cart/fastOrderSuccess.tpl',$arr);
}
$result['orderId'] = $response['data']['msorder'];
return $this->success('', $result);
}
}
у вас видимо какой-то отдельный компонент-класс и как вы его запускаете не совсем понятно, но пользуйтесь тогда для отладки, в разных участках кода
Начните с самого простого в самом начале функции post()
$this->modx->log(1, print_r($result,1));
Смотреть в Журнале ошибок в самом модх.Начните с самого простого в самом начале функции post()
$this->modx->log(1, print_r('Это я class shopOrder2 запустился',1));
если у вас журнале вообще ничего не выводит и ошибки тоже(и ошибки в серверном логе тоже нет), то скорее всего ваш класс вообще не запускается и с ним не работает modx или вы его вообще не вызываете и т.п.
все вызывается и работает (заказ то создается), если отключить json_response, то я получу ответ в том виде, который я отдаю, но без id новосозданного заказа.
Данный контроллер используется в api для построения фронта отдельно от modx
Данный контроллер используется в api для построения фронта отдельно от modx
Тут дальше только выяснять постепенно как я писал вам ранее, выводите в лог или как то логгируйте, что получаете и т.д. сам Пример(!) как у меня работает я дал, ну и в теории повторюсь вы получаете строку с заказом ее надо из json вытащить и получить заказ.
так же в вашем коде два раза вызывается $miniShop2->order->submit()
Так же вы не поменяли $modx на $this->modx
Адаптируйте мой код под ваш самостоятельно
так же в вашем коде два раза вызывается $miniShop2->order->submit()
Так же вы не поменяли $modx на $this->modx
Адаптируйте мой код под ваш самостоятельно
в итоге получилось.
Спасибо вам больше за помощь!
Спасибо вам больше за помощь!
Не за что! В чем была проблема?
Как понял, в самом компоненте, в котором работал с контроллером.
Использовал свой код + ваши подсказки и код в другом контроллере от zoomx и все сработало.
Хотя до этого и там не работало.
Использовал свой код + ваши подсказки и код в другом контроллере от zoomx и все сработало.
Хотя до этого и там не работало.
Та же самая проблема
Я так и не сборолся. В итоге вручную создал объект заказа и привязал к нему всё нужное.
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.