Николай

Николай

Был в сети 06 октября 2025, 10:48
Заказы принимаю
В данном случае тебе поставили дверь с замком и замок вроде как закрыт, но оказалось что его легко можно взломать.
Сломать можно много замков обычной монтировкой. Гостов на замки нет (наверное), а раз нет прописанных норм, стало быть все другие оценки качества чисто субъективные и никакой ответственности за них не предусмотрено.
Взял и купил шаблон, поставил и в душе не чувствую что там нужно где-то и что-то обновить. Я что, разработчик?
Это как рассуждать, типа, я взял и купил запчасть на авто, решил поставить, я что автослесарь? Нет не автослесарь, но будешь ставить на свой страх и риск. И некому будет претензии предъявлять, что на ней не было инструкции по установке, не было специнструмента, никто не сказал про метки и т.д.
Я продолжу писать что шаблоны ультрона хлам всратый и рекомендую клиентам не покупать эти шаблоны.
Чисто по логике, чтобы не быть пиз.... голословным, нужно как-то аргументировать, желательно по пунктам. Поэтому, взрослые ребята стараются впустую не молоть языком. Хотя бы потому-что понимают, что это крайности, и чем ниже уровень в решении споров, тем дороже итоговая цена конфликта. Ну то есть, когда ты излил душу, выговорился как следует, но нажил врагов, потратил время, испортил настроение себе и окружающим, а в итоге не добился никакого результата. А хуже когда ещё и получил в ответку. Кстати, сайт ultron существует с 2016 года, за 4 года аналогов больше не припомню, не то чтобы не хлам, а хоть каких-нибудь.
Почему, просто когда было указано на проблему это одно, а дальше обсуждение начало плавно скатываться в хейт и угрозы судами. Считаю, что рамки должны быть определённые. Кстати, как-то мне попадался сайт от ультрона на доработку, не мелкую. Не помню точно что там было, но каких-то негативных ощущений, как тут выше писалось, я не испытал. Большинство подобных сайтов не требует постоянных доработок. Поэтому, за 3-5 тыс. готовое решение с неплохим дизайном вариант вполне себе. В любом случае заниматься адаптацией будет разработчик, больше некому, нужны компетенции, поэтому проверка актуальности дополнений на его совести в том числе.
При желании этого ИПшника можно по судам затаскать (правда у нас в РФ суды это такая себе инстанция).
Да это вообще чушь. Если я оставлю двери своей квартиры открытыми, то отвечать будет тот, кто залез в квартиру и вынес имущество, а не я за свою беспечность. А судьям до наших MODXов и тёрок вокруг него пофигу, есть законы, есть судебная практика. Короче, человек не может отвечать за действия третьих лиц. Вот если он сам воспользуется уязвимостью, и будет лазить на клиентские сайты, то другой вопрос. И вообще, какой-то тухлый базар пошёл. Человек когда-то сделал сборки 100 лет назад как он считал нужным, как ему казалось правильным. Они рабочие, про уязвимости он мог не знать, но даже если бы знал, подобные вопросы решаются только самим разработчиком в рабочем порядке, на его усмотрение. Когда у него появится время и/или желание, вопрос чисто этики, репутации и т.д. Принудить или обязать его никто не может. Да и галерея эта сторонний компонент. А вот напор в попытках потопить коллегу характеризует скорее не его, а тех кто это делает, ну и сообщество в целом. Лично я не стал бы опускаться до того, чтобы перемывать кому-то кости таким образом. Тем более в деле которое не стоит выеденного яйца. Видать в мире MODX совсем глухо стало, что разрабы от скуки начали друг друга гнобить за свои поделки))
modExtra.grid.Items = function (config) {
    config = config || {};

    Ext.applyIf(config, {
        .....
        remoteSort: true,
        enableDragDrop: true,
        ddGroup: 'modextra-grid-dd',
        ddAction: 'mgr/item/sort',
        ....
    });

    modExtra.grid.Items.superclass.constructor.call(this, config);
    ......
    if (config.enableDragDrop && config.ddAction) {
        this.on('render', function(grid) {
            grid._initDD(config);
        });
    }
};
Ext.extend(modExtra.grid.Items, MODx.grid.Grid, {
    .......
    _initDD: function (config) {
        var grid = this;
        var el = grid.getEl();

        new Ext.dd.DropTarget(el, {
            ddGroup: grid.ddGroup,
            notifyDrop: function (dd, e, data) {
                var store = grid.getStore();
                var target = store.getAt(dd.getDragData(e).rowIndex).id;
                var sources = [];
                if (data.selections.length < 1 || data.selections[0].id == target) {
                    return false;
                }
                for (var i in data.selections) {
                    if (!data.selections.hasOwnProperty(i)) {
                        continue;
                    }
                    var row = data.selections[i];
                    sources.push(row.id);
                }

                el.mask(_('loading'), 'x-mask-loading');
                MODx.Ajax.request({
                    url: config.url,
                    params: {
                        action: config.ddAction,
                        sources: Ext.util.JSON.encode(sources),
                        target: target,
                    },
                    listeners: {
                        success: {
                            fn: function () {
                                el.unmask();
                                grid.refresh();
                                if (typeof(grid.reloadTree) == 'function') {
                                    sources.push(target);
                                    grid.reloadTree(sources);
                                }
                            }, scope: grid
                        },
                        failure: {
                            fn: function () {
                                el.unmask();
                            }, scope: grid
                        },
                    }
                });
            },
        });
    }
});

Ext.reg('modextra-grid-items', modExtra.grid.Items);

Оставил только то, что drag&drop касается. На месте точек другой код, не относящийся к сортировке. Собственно на процессор mgr/item/sort отправляются данные строк какие перемещаем. И в процессоре уже надо будет производить работу по сортировке. Тут уже много разных алгоритмов может быть.
IDx это menuindex. menuindex товару ставится максимальный относительно других товаров этой категории, а не относительно всех товаров. То есть товары из разных категорий могут иметь один и тот же menuindex, а значит сортировка как в админке не получится. Можно или компонентом этим воспользоваться, чтобы расставлять сортировку в категориях индивидуально, либо расставить menuindex товарам глобально, например скриптом:

<?php

function updateMenuIndex($id) {
    global $menuindex, $modx;
    
    $childsIds = $modx->getChildIds($id,1,array('context' => 'web'));                   
    if(!count($childsIds)) return;
    
    $q = $modx->newQuery('modResource');
    $q->where( ['id:IN' => $childsIds] ); 
    $q->sortby('menuindex', 'ASC');
    
    $result = $modx->getIterator('modResource', $q);
    
    foreach($result as $key=>$res) {
        $menuindex++;

        $res->set('menuindex', $menuindex);
        $res->save();
        //echo "$menuindex - {$res->pagetitle} ({$res->id})<br>";
        
        updateMenuIndex($res->get('id'));
    }
}

updateMenuIndex(0);        // id родителя в параметре
return "menuindex обновлены у $menuindex ресурсов";

А потом отсортировать товары по menuindex.
Да этот файл описывает класс miniShop2.grid.OrderProducts, в нём есть метод updateOrderProduct, который при открытии окна редактирования товара делает запрос в процессор mgr/orders/product/get. Можно расширить класс miniShop2.grid.OrderProducts, переписав в нём метод updateOrderProduct. Для этого создаём плагин на событие msOnManagerCustomCssJs, в плагине код:

<?php

if($modx->event->name == 'msOnManagerCustomCssJs') {
    $modx->controller->addLastJavascript(MODX_ASSETS_URL . 'mgr/js/orders.js');
}
Этот код подключает js-файл к админке для минишоповских страниц.

Код orders.js:

Ext.override(miniShop2.grid.OrderProducts, {
    // копируем целиком оригинальный метод, меняем путь к процессору в action на свой
    updateOrderProduct: function (btn, e, row) {
            .......
            MODx.Ajax.request({
            url: miniShop2.config['connector_url'],
            params: {
                action: 'mgr/orders/product/customget',
                id: id
            },
            .......
    },
});

Если раньше путь процессору был mgr/orders/product/get, то меняем, допустим, на mgr/orders/product/customget, а в папке с процессорами core/components/minishop2/processors/mgr/orders/product/ создаём копию оригинального процессора (get.class.php) с названием customget.class.php, и меняем там что нужно.