Всего 125 653 комментария

Артем
03 марта 2021, 20:09
+2
Как человек, написавший на MODX большой сервис (65+ кастомных таблиц), настоятельно не рекомендую брать CMS для сервисов. В один момент она просто начнет мешать и замедлять разработку и вместо того, чтобы писать логику сервиса, ты будешь пытаться приспособить эту CMS к твоим задачам и писать костыли.

Достаточно понимать, что xPDO не умеет в банальные UNION, более того, она даже мешает выполнять запросы, в которых есть UNION.
Максим
03 марта 2021, 13:56
0
Главный аргумент в пользу MODx в настоящий момент — срочность в переносе ручного труда в веб-сервис, так как объем работы увеличивается почти с каждой неделей. MODx был бы временным решением.
Надежда на готовые решения на MODx хотя бы по 1-му и 2-му пунктам.
В ином случае по любому придется делать веб-сервис с нуля.
Наумов Алексей
03 марта 2021, 13:39
+1
И правда, зачем вам для такой задачи modx? я б не рискнул, закопаетесь…
Юрий
03 марта 2021, 13:24
+1
Александр, хотел бы Вам посоветовать не использовать cms для управления бизнес процессами, она немного не для этого.
Да, Modx гибкая система, но на данный момент уже устаревшая, все это можно на ней реализовать, но поддерживать эту реализацию…
Точнее не костыли, которые придётся написать для этого, не всякий возьмётся.
Я бы Вам посоветовал, взглянуть в просторы интернета, там существует много готовых систем, может какая-то сможет подойти для ваших задач. Если нет, то лучше рассмотреть вариант написания системы с нуля, в принципе с вашими задачами может справится фронт на VUE или REACT, бакенд может быть любой, например firebase, hasura, strapi или куча ещё всяких. В этом случае Вы не будете привязаны к узкому кругу разработчиков modx.
Роман
03 марта 2021, 09:37
+1
Иван можешь время поправить 5 марта в 24 часовой формат, а то я подумал, что все плавно перетекает на 6 марта. =)
Иван Бочкарев
03 марта 2021, 05:08
0
А я то думаю кто на Украинский начал активно переводить. ?
Артур Шевченко
02 марта 2021, 23:51
+2
Нет, но автор же говорит что сделал, а динамическую не сделал, надо же понять что не сделано, а что сделано зачем переделывать, если работает??
Евгений Webinmd
02 марта 2021, 22:08
0
доп реверсы — это понятно что?
Артур Шевченко
02 марта 2021, 21:51
0
динамическую карту изображений
Что за зверь такой?
Артур Шевченко
02 марта 2021, 21:50
0
Решение есть. Надо искать ошибку.
Сергей Карпович
02 марта 2021, 17:29
0
Всем привет. Вопрос.
Если у меня есть товары с модификациями и без, как настроить учет остатков?
Для всех товаров создать модификацию Остаток, без изменения цены?
Или создать обычную опцию, и ее как то привязать к msOptionsPrice2, что бы был учет остатков?
Руслан
02 марта 2021, 17:23
0
и в самом компоненте есть небольшая недоработка по работе с заказом в админке(этот функционал не был изначально в задумке, но позже на скорую руку добавил) так как реализована работа с монетами авторизованного пользователя то при записи заказа в админке используются монеты авторизованного в админке, там всего несколько строк изменений, но я выкатить это не могу так как среда разработки была на винде, а сейчас я на маке и тупо нет возможности плюс не приобрел ещё лицензию на PHPSTORM на котором реализовывал компонент.
здесь теперь реализовано от ИД пользователя из заказа
файл:

новое содержимое файла:
<?php

class msrpcMain {
    /** @var modX $modx */
    public $modx;
    /** @var array $config */
    public $config;

    public function __construct(&$modx, $config = array()) {
        $this->modx = &$modx;
        $this->config = array(
            'css_url' => $this->modx->getOption('msrpc_css_url', null, MODX_ASSETS_URL.'components/msreferralprogramcoin/styles/main.css'),
            'js_url' => $this->modx->getOption('msrpc_js_url', null, MODX_ASSETS_URL.'components/msreferralprogramcoin/js/web/msrpcincluder.js'),
            'connector_url' => $this->modx->getOption('msrpc_connector_url', null, MODX_ASSETS_URL.'components/msreferralprogramcoin/connector.php'),
            'name_coin' => trim($this->modx->getOption('msrpc_name_bonus_coin',null, 'Coin')),
            'default_pr_payroll' => (int)$this->modx->getOption('msrpc_default_pr_payroll_coins',null, 0),
            'pr_cart_paid' => (int)$this->modx->getOption('msrpc_max_pr_cart_paid_by_coins',null, 0),
            'statuses_for_inc' => $this->modx->getOption('msrpc_order_statuses_for_inc_coins',null, 0),
            'statuses_for_dec' => $this->modx->getOption('msrpc_order_statuses_for_dec_coins',null, 0),
            'ratio_of_coins' => (int)$this->modx->getOption('msrpc_ratio_of_coins',null, 1),
            'welcome_coins' => (int)$this->modx->getOption('msrpc_welcome_coins_for_registration',null, 0),
            'welcome_coins_if' => (int)$this->modx->getOption('msrpc_welcome_coins_if_promocode',null, 0)
        );
        $this->config = array_merge($this->config, $config);

        $this->config['css_url'] = str_replace('[[+cssBasePath]]', MODX_ASSETS_URL.'components/msreferralprogramcoin/styles/', $this->config['css_url']);
        $this->config['js_url'] = str_replace('[[+jsBasePath]]', MODX_ASSETS_URL.'components/msreferralprogramcoin/js/', $this->config['js_url']);
        $this->config['connector_url'] = str_replace('[[+assetsBasePath]]', MODX_ASSETS_URL.'components/msreferralprogramcoin/', $this->config['connector_url']);
        $this->config['name_coin'] = iconv_strlen($this->config['name_coin']) < 1 ? 'Coin' : $this->config['name_coin'];
        $this->config['promo_prefix'] = mb_strtoupper(iconv_substr($this->config['name_coin'], 0, 1));
        $this->config['promo_suffix'] = 'R';
        $this->config['ratio_of_coins'] = !$this->config['ratio_of_coins'] ? 1 : $this->config['ratio_of_coins'];
        $this->config['default_pr_payroll'] = !$this->config['default_pr_payroll'] ? 0 : $this->config['default_pr_payroll'];
        $this->config['pr_cart_paid'] = !$this->config['pr_cart_paid'] ? 0 : $this->config['pr_cart_paid'];
        $this->config['welcome_coins'] = !$this->config['welcome_coins'] ? 0 : $this->config['welcome_coins'];
        $this->config['welcome_coins_if'] = !$this->config['welcome_coins_if'] ? 0 : $this->config['welcome_coins_if'];

        $this->includeCssAndJs();

        $this->modx->addPackage('msreferralprogramcoin', MODX_CORE_PATH.'components/msreferralprogramcoin/model/');
    }

    public function includeCssAndJs() {
        if ($this->modx->context->key != 'mgr') {
            $this->modx->regClientCSS($this->config['css_url']);
            $this->modx->regClientScript($this->config['js_url']);
        }
    }

    public function loadLexicons() {
        $this->modx->lexicon->load('msreferralprogramcoin:default');
        if ($this->modx->context->key == 'mgr') {
            $this->modx->lexicon->load('msreferralprogramcoin:menu');
        }
    }

    public function OnUserSave($uid) {
        if (!$uid || !$this->config['welcome_coins']) return;
        /** @var msrpcHandPayroll $handPayroll */
        $handPayroll = $this->modx->newObject('msrpcHandPayroll');
        $handPayroll->set('user_id', $uid);
        $handPayroll->set('payroll', $this->config['welcome_coins']);
        $handPayroll->set('createdby', $uid);
        $handPayroll->set('createdon', time());
        if (!$handPayroll->save()) {
            $this->modx->log(modX::LOG_LEVEL_ERROR, '[msrpcMain] - Not save welcome coins for user ID '.$uid);
        }
    }

    public function OnUserBeforeSave($promo) {
        $referrer_promocode = iconv_substr(trim($promo), 1);
        if (empty($referrer_promocode)) {
            return 0;
        }
        $timestamp_1 = stristr($referrer_promocode, 'R');
        $referrer_id = (int)trim(stristr($referrer_promocode, 'R', true));
        $timestamp_2 = trim(iconv_substr($timestamp_1, 1));
        if (!$timestamp_1 || !$referrer_id || !(int)$timestamp_2 || iconv_strlen($timestamp_2) !== 2) {
            return 0;
        }
        $query = $this->modx->newQuery('modUser', array('id' => $referrer_id));
        $query->select(array(
            'modUser.createdon as createdon'
        ));
        $query->prepare();
        $query->stmt->execute();

        /** @var array[] $Users */
        $users = $query->stmt->fetchAll(PDO::FETCH_ASSOC);

        if (!count($users) || $timestamp_2 !== substr($users[0]['createdon'],-2)) {
            return 0;
        }

        return (int)$referrer_id;
    }

    public function msOnBeforeSaveOrder(msOrder $msOrder, $payCoins)
    {
        $delivery_cost = $msOrder->get('delivery_cost');
        $oid = 0;
        if ($msOrder->id){
            $oid = $msOrder->id;
            $payCoins = $msOrder->msrpc_payroll_dec;
        }
        $products = $msOrder->getMany('Products');
        $payroll = 0;
        $total_cost = 0;
        $pr_payroll = $this->config['default_pr_payroll'];
        if ($this->modx->user->id) {
            $query = $this->modx->newQuery('modUser', array('id' => $msOrder->user_id));
            $query->select(array(
                'modUser.msrpc_pr_payroll as pr_payroll'
            ));
            $query->prepare();
            $query->stmt->execute();
            /** @var array[] $modUsers */
            $modUsers = $query->stmt->fetchAll(PDO::FETCH_ASSOC);
            if (count($modUsers) && $modUsers[0]['pr_payroll']) {
                $pr_payroll = (int)$modUsers[0]['pr_payroll'];
            }
        }
        /** @var msOrderProduct $product */
        foreach ($products as $product) {
            $total_cost += $product->get('price') * $product->get('count');
            if (!$this->modx->getObject('modResource', $product->product_id)->msrpc_check) continue;
            $payroll += (($product->get('price') * $product->get('count')) / 100) * $pr_payroll;
        }
        $payroll = (int)round($payroll * $this->config['ratio_of_coins'],0);
        $msOrder->set('msrpc_payroll_inc', $payroll);
        if ($this->modx->user->id && $payCoins) {
            $balance = 0;
            $query = $this->modx->newQuery('msrpcHandPayroll', array('user_id' => $msOrder->user_id));
            $query->groupby('msrpcHandPayroll.user_id');
            $query->select(array(
                'SUM(msrpcHandPayroll.payroll) as payroll'
            ));
            $query->prepare();
            $query->stmt->execute();
            $rows = $query->stmt->fetchAll(PDO::FETCH_ASSOC);
            foreach ($rows as $row) {
                $balance += (int)$row['payroll'];
            }
            $query = $this->modx->newQuery('msOrder', array(
                'id:!=' => $oid,
                'user_id' => $msOrder->user_id,
                'status:IN'=> explode(',', $this->modx->getOption('msrpc_order_statuses_for_inc_coins',null, 0))
            ));
            $query->groupby('msOrder.user_id');
            $query->select(array(
                'SUM(msOrder.msrpc_payroll_inc) as payroll'
            ));
            $query->prepare();
            $query->stmt->execute();
            $rows = $query->stmt->fetchAll(PDO::FETCH_ASSOC);
            foreach ($rows as $row) {
                $balance += (int)$row['payroll'];
            }
            $query = $this->modx->newQuery('msOrder', array(
                'id:!=' => $oid,
                'user_id' => $msOrder->user_id,
                'status:IN'=> explode(',', $this->modx->getOption('msrpc_order_statuses_for_dec_coins',null, 0))
            ));
            $query->groupby('msOrder.user_id');
            $query->select(array(
                'SUM(msOrder.msrpc_payroll_dec) as payroll'
            ));
            $query->prepare();
            $query->stmt->execute();
            $rows = $query->stmt->fetchAll(PDO::FETCH_ASSOC);
            foreach ($rows as $row) {
                $balance -= (int)$row['payroll'];
            }
            if (!$balance) return;
            $forPayCost = ($total_cost/100)*$this->config['pr_cart_paid'];
            $forPayCoins = (int)round($forPayCost * $this->config['ratio_of_coins'], 0);
            $forPayCostB = (int)round($balance / $this->config['ratio_of_coins'], 0);
            $msOrder->set('msrpc_payroll_dec', min($balance, $forPayCoins));
            $msOrder->set('cost', $total_cost-min($forPayCostB, $forPayCost)+$delivery_cost);
            $msOrder->set('cart_cost', $total_cost-min($forPayCostB, $forPayCost));
        }
    }

    public function OnMODXInit() {
        $this->modx->map['modResource']['fields']['msrpc_check'] = 0;
        $this->modx->map['modResource']['fieldMeta']['msrpc_check'] = array(
            'dbtype' => 'tinyint',
            'precision' => '1',
            'attributes' => 'unsigned',
            'phptype' => 'boolean',
            'null' => false,
            'default' => 0
        );
        $this->modx->loadClass('modUser');
        $this->modx->map['modUser']['fields']['msrpc_referrer_id'] = 0;
        $this->modx->map['modUser']['fieldMeta']['msrpc_referrer_id'] = array(
            'dbtype' => 'int',
            'precision' => 10,
            'attributes' => 'unsigned',
            'phptype' => 'integer',
            'null' => false,
            'default' => 0
        );
        $this->modx->map['modUser']['fields']['msrpc_pr_payroll'] = 0;
        $this->modx->map['modUser']['fieldMeta']['msrpc_pr_payroll'] = array(
            'dbtype' => 'tinyint',
            'precision' => '2',
            'attributes' => 'unsigned',
            'phptype' => 'integer',
            'null' => false,
            'default' => 0
        );
        $this->modx->loadClass('msOrder');
        $this->modx->map['msOrder']['fields']['msrpc_payroll_inc'] = 0;
        $this->modx->map['msOrder']['fieldMeta']['msrpc_payroll_inc'] = array(
            'dbtype' => 'int',
            'precision' => 10,
            'attributes' => 'unsigned',
            'phptype' => 'integer',
            'null' => false,
            'default' => 0
        );
        $this->modx->map['msOrder']['fields']['msrpc_payroll_dec'] = 0;
        $this->modx->map['msOrder']['fieldMeta']['msrpc_payroll_dec'] = array(
            'dbtype' => 'int',
            'precision' => 10,
            'attributes' => 'unsigned',
            'phptype' => 'integer',
            'null' => false,
            'default' => 0
        );
    }
}
Руслан
02 марта 2021, 16:55
0
Там много, что может быть, от ошибки при записи кеша админки до отсутствия какого-то модуля на php нужного для выполнения скрипта или вообще просто скрипты MODX в твоём браузере не хотят работать.
Стоит начать с того чтобы зайти через другой браузер попробовать.
Да, и лог ошибок можно посмотреть, может там что есть.
Руслан
02 марта 2021, 16:40
0
Кирилл, привет, только зашел сюда :)
без TV всё работает?
передал по твшкам спецу так как сам твшки не пользую я больше по бэку
Владимир Тельнов
02 марта 2021, 15:02
0
Есть проблема в компоненте. Возможно баг, возможно просто не продумано.

Допустим заказ в населенный пункт «Волжский». таких городов и сел может быть много. Может быть даже штук 20. Т.е. в выпадающем списке можно даже не найти нужный пункт иди не доскролить до него.

На сайте https://shiptor.ru/calculate выглядит это вот так


Поиск можно уточнить так «Волжский пос»


Или можно уточнить указав регион «Волжский ниж»


Но компонент msShiptor так не умеет. Он понимает только прямой запрос «Волжский»
То есть многие клиенты не смог найти свой населенный пункт и не смогут сделать заказ.



Как быть?
Артем
02 марта 2021, 14:05
0
Артур, спасибо за подсказку. Пожалуй так и сделаю, возможно я просто лишнего надумал себе) Буду рад, если вы мне поможете с ещё одним вопросом
Сергей
02 марта 2021, 12:08
0
Еще важный момент Адрес для запросов нужно использовать не merchant.roboxchange.com/Index.aspx, а auth.robokassa.ru/Merchant/Index.aspx