Minishop2 сломалась кастомная стоимость в заказе

Здравствуйте.
Имеется самописный механизм формирования цены товара: т.е. в зависимости от размера, наличия дополнительных ингредиентов и т.п. цена меняется.
После обновления minishop до последней версии случилась следующая беда: Механизм ценообразования также прекрасно работает, в корзину товар попадает с нужной ценой, на странице оформления заказа тоже сумма соответствует ожиданиям… но в заказе приходит цена по умолчанию (т.е. совсем не то что хотелось бы).
Подскажите куда копать.
Игорь
20 ноября 2022, 12:05
modx.pro
736
0

Комментарии: 15

Артур Шевченко
20 ноября 2022, 12:49
0
Если использовался кастомный класс обработки заказа, надо его подключить заново.
    Игорь
    20 ноября 2022, 13:06
    0
    да, кастомный класс обработки заказа используется… а что значит «подключить заново»?… что-то в консоли прописать?
        Игорь
        20 ноября 2022, 14:07
        0
        сделал, не помогло (
          Артур Шевченко
          20 ноября 2022, 14:23
          0
          А точно класс подключен, проверили?
            Игорь
            20 ноября 2022, 14:28
            0
            да, точно подключен (когда я вне что-то пытаюсь поменять — сайт падает… :)… )
            myorderhandler.class.php
            <?php
            	if(!class_exists('msOrderInterface')) {
            	require_once dirname(dirname(dirname(__FILE__))) . '/model/minishop2/msorderhandler.class.php';
            }
            	class myOrderHandler extends msOrderHandler { 
            
            	public function getCost($with_cart = true, $only_cost = false)
                {
                    $response = $this->ms2->invokeEvent('msOnBeforeGetOrderCost', array(
                        'order' => $this,
                        'cart' => $this->ms2->cart,
                        'with_cart' => $with_cart,
                        'only_cost' => $only_cost,
                    ));
                    if (!$response['success']) {
                        return $this->error($response['message']);
                    }
            
                    $cart = $this->ms2->cart->status();
                    $cost = $with_cart
                        ? $cart['total_cost']
                        : 0;
            
                    /** @var msDelivery $delivery */
                    if (!empty($this->order['delivery']) && $delivery = $this->modx->getObject('msDelivery',
                            $this->order['delivery'])
                    ) {
                        $cost = $delivery->getCost($this, $cost);
                        $deliveryCost = $delivery->getCost($this, 0);//Добавил переменную где получаем price доставки
                    }
            
                    /** @var msPayment $payment */
                    if (!empty($this->order['payment']) && $payment = $this->modx->getObject('msPayment',
                            $this->order['payment'])
                    ) {
                        $cost = $payment->getCost($this, $cost);
                    }
            
                    $response = $this->ms2->invokeEvent('msOnGetOrderCost', array(
                        'order' => $this,
                        'cart' => $this->ms2->cart,
                        'with_cart' => $with_cart,
                        'only_cost' => $only_cost,
                        'cost' => $cost,
                    ));
                    if (!$response['success']) {
                        return $this->error($response['message']);
                    }
                    $cost = $response['data']['cost'];
            
                    return $only_cost
                        ? $cost
                        : $this->success('', array('cost' => $cost, 'delivery_cost'=>$deliveryCost));
                }
            
              
            	/**
                 * Returns id for current customer. If customer is not exists, registers him and returns id.
                 *
                 * @return integer $id
                 */
            
            	
                public function getCustomerId()
                { //эту функцию переписываем частично
                    $customer = null;
            
              
                    $response = $this->ms2->invokeEvent('msOnBeforeGetOrderCustomer', array(
                        'order' => $this->ms2->order,
                        'customer' => &$customer,
                    ));
                    if (!$response['success']) {
                        return $response['message'];
                    }
            
                    if (!$customer) {
                        $data = $this->ms2->order->get();
            			
                        $email = isset($data['email']) ? $data['email'] : '';
                        $receiver = isset($data['receiver']) ? $data['receiver'] : '';
                        $phone = isset($data['phone']) ? $data['phone'] : '';
                        $user_group = isset($data['group']) ? $data['group'] : '111';
            			//$this->modx->log(modX::LOG_LEVEL_ERROR, $user_group);
                        if (empty($receiver)) {
                            $receiver = $email
                                ? substr($email, 0, strpos($email, '@'))
                                : ($phone
                                    ? preg_replace('#[^0-9]#', '', $phone)
                                    : uniqid('user_', false));
                        }
                        if (empty($email)) {
                            $email = $receiver . '@' . $this->modx->getOption('http_host');
                        }
            
                        if ($this->modx->user->isAuthenticated()) {
                            $profile = $this->modx->user->Profile;
                            if (!$profile->get('email')) {
                                $profile->set('email', $email);
                                $profile->save();
                            }
                            $customer = $this->modx->user;
                        } else {
                            $c = $this->modx->newQuery('modUser');
                            $c->leftJoin('modUserProfile', 'Profile');
                            $filter = array('username' => $email, 'OR:Profile.email:=' => $email);
                            if (!empty($phone)) {
                                $filter['OR:Profile.phone:='] = $phone;
                            }
                            $c->where($filter);
                            $c->select('modUser.id');
                            if (!$customer = $this->modx->getObject('modUser', $c)) {
            					$pass=md5(rand());
                                $customer = $this->modx->newObject('modUser', array('username' => $email, 'password' => $pass));
                                $profile = $this->modx->newObject('modUserProfile', array(
                                    'email' => $email,
                                    'fullname' => $receiver,
                                    'phone' => $phone
                                ));
                                $customer->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);
                                $customer->addMany($setting);
                                if (!$customer->save()) {
                                    $customer = null;
                                }else if (!empty($user_group) && !empty($_POST['group'])){
            						if($customer->joinGroup('Users')){
            							$url=$this->modx->getOption('site_url');
            							$name=$this->modx->getOption('site_name');
            							$subjectTheme='Вы зарегистрировались на сайте '.$name;
            							$bodyTheme='<html><body><p>Здравствуйте, '.$data['receiver'].'!</p><p>Сделав заказ, вы зарегистрировались на сайте <a href="'.$url.'">'.$name.'</a>. Ваши данные для входа:</p><p>Логин: '.$email.'</p><p>Пароль: '.$pass.'</p><p>Изменить пароль можно в личном кабинете</p></body></html>';
            							//$sent = $customer->sendEmail($bodyTheme, array('subject' => $subjectTheme));
            							$sent = $this->ms2->sendEmail($email,$subjectTheme,$bodyTheme);
            							if ($sent){
            								$this->modx->log(modX::LOG_LEVEL_ERROR, $sent);
            							}
            						}else{
            							$this->modx->log(modX::LOG_LEVEL_ERROR, 'Какая та ошибка с добавлением в группу, письмо не отправлено');
            						}
            					}else if ($groups = $this->modx->getOption('ms2_order_user_groups', null, false)) {
                                    $groups = array_map('trim', explode(',', $groups));
                                    foreach ($groups as $group) {
                                        $customer->joinGroup($group);
                                    }
                                }
                            }else if (!empty($user_group) && !empty($_POST['group'])){
            					$profile=$customer->getOne('Profile');
            					if ($profile->get('logincount') > 0){
            						$length = 8;
            						$olduser = $customer;
            						$pass=$olduser->generatePassword($length);
            						$olduser->toArray();
            						$olduser->set('password',$pass);
            						$olduser->save();
            						if ($olduser->joinGroup('Users')){
            							$url=$this->modx->getOption('site_url');
            							$name=$this->modx->getOption('site_name');
            							$subjectTheme='Вы зарегистрировались на сайте '.$name;
            							$bodyTheme='<html><body><p>Здравствуйте, '.$data['receiver'].'!</p><p>Сделав очередной заказ, вы подвердили регистрацию на сайте <a href="'.$url.'">'.$name.'</a>. Ваши данные для входа:</p><p>Логин: '.$email.'</p><p>Пароль: '.$pass.'</p><p>Изменить пароль можно в личном кабинете</p></body></html>';
            							//$pdo = $this->modx->getService('pdoFetch'); // можно переделать на чанк при желании
            							//$message = $pdo->getChunk('@FILE chunks/email/user.register.tpl', array('username' => $username, 'password' => $pass));
            							$sent = $this->ms2->sendEmail($email,$subjectTheme,$bodyTheme);
            							//Мгновенная авторизация на сайте без набора пароля, кому надо раскомментируйте
            							//$olduser->addSessionContext('web');
            							if ($sent){
            								$this->modx->log(modX::LOG_LEVEL_ERROR, $sent);
            							}
            						}else{
            							$this->modx->log(modX::LOG_LEVEL_ERROR, 'Какая та ошибка с добавлением в группу, письмо не отправлено');
            						}
            					}
            					
            				}
                        }
                    }
            
                    $response = $this->ms2->invokeEvent('msOnGetOrderCustomer', array(
                        'order' => $this->ms2->order,
                        'customer' => &$customer,
                    ));
                    if (!$response['success']) {
                        return $response['message'];
                    }
            
                    return $customer instanceof modUser
                        ? $customer->get('id')
                        : 0;
                }
            
            	public function submit($data = array())
                { //в этой меняем вызов функции getCustomerId под свою, ранее исправленную
                    $response = $this->ms2->invokeEvent('msOnSubmitOrder', array(
                        '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 = array();
                    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->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(array(
                        '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, array(
                        'user_id' => $user_id,
                        'createdon' => $createdon,
                    )));
                    $order->addOne($address);
            
                    // Adding products
                    $cart = $this->ms2->cart->get();
                    $products = array();
                    foreach ($cart as $v) {
                        if ($tmp = $this->modx->getObject('msProduct', array('id' => $v['id']))) {
                            $name = $tmp->get('pagetitle');
                        } else {
                            $name = '';
                        }
                        /** @var msOrderProduct $product */
                        $product = $this->modx->newObject('msOrderProduct');
                        $product->fromArray(array_merge($v, array(
                            'product_id' => $v['id'],
                            'name' => $name,
                            'cost' => $v['price'] * $v['count'],
                        )));
                        $products[] = $product;
                    }
                    $order->addMany($products);
            
                    $response = $this->ms2->invokeEvent('msOnBeforeCreateOrder', array(
                        'msOrder' => $order,
                        'order' => $this,
                    ));
                    if (!$response['success']) {
                        return $this->error($response['message']);
                    }
            
                    if ($order->save()) {
                        $response = $this->ms2->invokeEvent('msOnCreateOrder', array(
                            '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'] = array();
                        }
                        $_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, array('msorder' => $order->get('id')));
            }
            
                        // Reload order object after changes in changeOrderStatus method
                        $order = $this->modx->getObject('msOrder', array('id' => $order->get('id')));
            
                        /** @var msPayment $payment */
                        if ($payment = $this->modx->getObject('msPayment',
                            array('id' => $order->get('payment'), 'active' => 1))
                        ) {
                            $response = $payment->send($order);
                            if ($this->config['json_response']) {
                                @session_write_close();
                                exit(is_array($response) ? json_encode($response) : $response);
                            } else {
                                if (!empty($response['data']['redirect'])) {
                                    $this->modx->sendRedirect($response['data']['redirect']);
                                } elseif (!empty($response['data']['msorder'])) {
                                    $this->modx->sendRedirect(
                                        $this->modx->context->makeUrl(
                                            $this->modx->resource->id,
                                            array('msorder' => $response['data']['msorder'])
                                        )
                                    );
                                } else {
                                    $this->modx->sendRedirect($this->modx->context->makeUrl($this->modx->resource->id));
                                }
            
                                return $this->success();
                            }
                        } else {
                            if ($this->ms2->config['json_response']) {
                                return $this->success('', array('msorder' => $order->get('id')));
                            } else {
                                $this->modx->sendRedirect(
                                    $this->modx->context->makeUrl(
                                        $this->modx->resource->id,
                                        array('msorder' => $response['data']['msorder'])
                                    )
                                );
            
                                return $this->success();
                            }
                        }
                    }
             
                    return $this->error();
                }
            	
            	
            	
            }
              Николай Савин
              20 ноября 2022, 19:37
              0
              Обратите внимание на вот эту строчку
              require_once dirname(dirname(dirname(__FILE__))) . '/model/minishop2/msorderhandler.class.php';
              и сравните ее с тем, где расположен этот файл сейчас. Возможно ошибка в этом.
              А вообще если сайт падает, то в первую очередь нужно смотреть журнал серверных ошибок (не MODX)
                Игорь
                20 ноября 2022, 20:23
                0
                /httpdocs/core/components/minishop2/handlers/msorderhandler.class.php
                до этого стоял minishop 2.5.0 — всё работало как часы, пришлось обновить версию до 3.0.7 ради модуля подарков modstore.pro/packages/integration/msgiftcart — в результате всё плохо (
                  Игорь
                  20 ноября 2022, 20:29
                  0
                  /core/components/minishop2/model/minishop2/msorderaddress.class.php — такой файл тоже есть, он как раз ссылается на то что выше написал:
                  <?php
                  
                  if (!empty($this->modx->getOption('log_deprecated'))) {
                      $this->modx->log(
                          xPDO::LOG_LEVEL_ERROR,
                          'Deprecated: use handlers from catalog core/components/minishop2/handlers/'
                      );
                  }
                  require_once dirname(__FILE__, 3) . '/handlers/msorderhandler.class.php';
                  … мне кажется, тут дело в самом минишопе — что-то перемудрили, что стоимость берется не из корзины, а из карточки товара (
    Игорь
    21 ноября 2022, 18:25
    0
    отключил кастомный класс через консоль:
    if ($miniShop2 = $modx->getService('miniShop2')) {
        $miniShop2->removeService('order', 'myOrderHandler');
    }
    ну и в системных настройках тоже указал стандартный класс msOrderHandler
    всё равно работает не правильно, цена берется из карточки товара по умолчанию… хотя на более ранней версии того же сайта, уже с обновленным minishop все ok — ничего не могу понять (
      Николай Савин
      21 ноября 2022, 19:10
      0
      С ценой вроде никаких работ не производилось. Я не очень понял в какой момент цена берется из карточки товара.
        Игорь
        21 ноября 2022, 19:36
        0
        да глюк какой-то похоже…
        Вот сумма на странице оформления заказа: pastenow.ru/e315b9fa2f337af9beee35e031351122
        А вот уже сам заказ: pastenow.ru/c558a65674b10de60bead6ca71073c15 (цена по умолчанию из карточки товара)… самое интересное, что есть более ранняя копия сайта, уже с обновленным minishop и там нормально цены цепляются
          Николай Савин
          22 ноября 2022, 08:12
          0
          После того как товар положили в корзину его стоимость не меняется и не перезаписывается. Это если говорить про механизм из коробки.
          Предположу что в вашем случае в дело вступает какой-то плагин. В общем нужно разбираться именно внутри проекта. Не стоит грешить на разработчиков Minishop2
            Игорь
            22 ноября 2022, 11:09
            0
            да я уже понял, что дело не в Minishop, а в моих кривых руках… но разобраться пока не получилось…
            Подскажите, как удалить кастомный класс. Я сделал следующее:
            1. В консоли запустил
            if ($miniShop2 = $modx->getService('miniShop2')) {
                $miniShop2->removeService('order', 'myOrderHandler');
            }
            2. В системных настройках поменял класс на msOrderHandler.
            3. Очистил кэш
            Но в логах все равно пишет: " Could not load custom class at… /httpdocs/core/components/minishop2/custom/order/myorderhandler.class.php"
      Игорь
      22 ноября 2022, 14:33
      0
      Похоже конфликт с модулем промокодов msPromoCode2 — это он цены подтягивает
        Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
        15