Как вернуть старую кнопку "Уничтожить ресурсы" в MODX

Полезно для тех кого не устраивает менеджер для удаления ресурсов, начиная с версии 2.7:
Оказалось довольно просто: создаем плагин returnKilButton
И два события OnManagerPageBeforeRender и OnResourceToolbarLoad




Код плагина
<?php
/**
 * Created by Andrey Stepanenko.
 * User: webnitros
 * Date: 10.01.2019
 * Time: 12:36
 */
switch ($modx->event->name) {
    case 'OnManagerPageBeforeRender':
        if ($modx->hasPermission('purge_deleted')) {
            $modx->controller->addHtml('<script>Ext.onReady(function() {
                var tree = Ext.getCmp("modx-resource-tree");
                tree.emptyRecycleBin = function() {
                    MODx.msg.confirm({
                        title: _("empty_recycle_bin")
                        ,text: _("empty_recycle_bin_confirm")
                        ,url: MODx.config.connector_url
                        ,params: {
                            action: "resource/emptyRecycleBin"
                        }
                        ,listeners: {
                            "success":{fn:function() {
                                Ext.select("div.deleted",this.getRootNode()).remove();
                                MODx.msg.status({
                                    title: _("success")
                                    ,message: _("empty_recycle_bin_emptied")
                                });
                                var trashButton = this.getTopToolbar().findById("emptifier");
                                trashButton.disable();
                                trashButton.setTooltip(_("empty_recycle_bin") + " (0)");
                                this.fireEvent("emptyTrash");
                            },scope:this}
                        }
                    });
                }
                tree.deleteDocument = function(itm,e) {
                        var node = this.cm.activeNode;
                        var id = node.id.split("_");id = id[1];
                        var pagetitle = node.ui.textNode.innerText;
                        MODx.msg.confirm({
                            title: pagetitle ? _("resource_delete") + " " + pagetitle : _("resource_delete")
                            ,text: _("resource_delete_confirm")
                            ,url: MODx.config.connector_url
                            ,params: {
                                action: "resource/delete"
                                ,id: id
                            }
                            ,listeners: {
                                "success": {fn:function(data) {
                                    var trashButton = this.getTopToolbar().findById("emptifier");
                                    if (trashButton) {
                                        if (data.object.deletedCount == 0) {
                                            trashButton.disable();
                                        } else {
                                            trashButton.enable();
                                        }
                    
                                        trashButton.setTooltip(_("empty_recycle_bin") + " (" + data.object.deletedCount + ")");
                                    }
                    
                                    var n = this.cm.activeNode;
                                    var ui = n.getUI();
                    
                                    ui.addClass("deleted");
                                    n.cascade(function(nd) {
                                        nd.getUI().addClass("deleted");
                                    },this);
                                    Ext.get(ui.getEl()).frame();
                                },scope:this}
                            }
                        });
                    }
            });</script>');
        }
        break;
    case 'OnResourceToolbarLoad': // ПРИОРИТЕТ 1000
        if ($modx->hasPermission('purge_deleted')) {

            /* @var array $items */
            if (count($items) > 0) {
                foreach ($items as $k => $item) {
                    if ($item['cls'] == 'tree-trash') {
                        unset($items[$k]);
                        break;
                    }
                }

                $deletedResources = $modx->getCount('modResource', array('deleted' => 1));
                $items[] = array(
                    'id' => 'emptifier',
                    'cls' => 'tree-trash',
                    'tooltip' => $modx->lexicon('empty_recycle_bin') . " ({$deletedResources})",
                    'disabled' => ($deletedResources == 0) ? true : false,
                    'handler' => 'this.emptyRecycleBin',
                );
                exit($modx->toJSON($modx->error->success('', array_values($items))));
            }
        }
        break;
}
Так же плагин добавлени в мою сборку siteDev

И опубликовал в modstore
modstore.pro/packages/utilities/returnkillbutton
Андрей Степаненко
10 января 2019, 09:37
modx.pro
1
591
+6
Поблагодарить автора Отправить деньги

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

Павел Гвоздь
10 января 2019, 10:34
0
Эх, ещё бы убрать эту простыню кода с главной под кат…
Василий Наумкин
10 января 2019, 11:37
0
modstore.pro/service/packages/returnkilbutton

В логе
PHP warning: Illegal string offset 'cls'
но работает, так что одобрил. Просьба исправить это warning.
    Андрей Степаненко
    10 января 2019, 11:50
    0
    Поправил
      Руслан Алеев
      10 января 2019, 12:02
      0
      Здравствуйте, создайте issue на github для MODX, если будет время, возможно действительно стоит ввести настройку в MODX для выбора «быстрого уничтожения ресурсов» или «менеджера удаления ресурсов».
Баха Волков
10 января 2019, 12:43
0
Андрей, в modstore думаю у тебя опечатка «returnKilButton», да и в топике тоже, одной палочки не хватает :)
Leonid Krylov
10 января 2019, 13:18
+2
Лого!
    Иван Климчук
    10 января 2019, 13:58
    +1
    Двоякие ощущения после прочитанного. Сначала многие ныли, что неудобно что все сразу удаляется, сейчас попытка вернуть кнопку обратно. У меня вопрос: а зачем вам MODX 3, если и так хорошо и ничего не нужно менять?
      Андрей Степаненко
      10 января 2019, 14:09
      0
      Работает очень не удобно.
      Пытался удалить 4500 ресурсов, довольно трудно сделать это через менеджер.
      Еще до этого надо было удалить 1 ресурс, но не хочу я переходить куда то для этого действия.

      еще баг сегодня обнаружил.
      modx.pro/news/16963#comment-105981
      Хотя пару дней назад мне показалось что я сам поставил ресурс который не хотел удалять на удаление.

      Мне вот даже ситуации не представляется где бы помог менеджер для удаления. Сколько раз пытался удалять, ну достаточно того что и так все удалялось.
        Fi1osof
        10 января 2019, 14:23
        0
        А зачем удалять старое, чтобы добавить новое? Нельзя к старому добавить новое? А пользователи решат чем пользоваться.
          Андрей Степаненко
          10 января 2019, 14:33
          0
          там пересечение по id элемента. При возврате количества удаленных ресурсов на ajax
            Fi1osof
            10 января 2019, 14:44
            0
            По-моему, так себе причина. ExtJS там хоть и старый, но и в нем есть инструменты чтобы подписаться на результаты выполнения запросов. Наверняка тот же Ajax.listeners решает. А подход «Я могу сделать лучше, но удалю ка я то, что до этого работало» — не очень круто.

            UPD: То есть если два компонента зависят от какого-то состояния, то не надо для них отдельные запросы делать, а сделать один и подписать их оба на него.
              Андрей Степаненко
              10 января 2019, 14:53
              0
              Есть ещё круче решение: Деактивировать плагин))
                Fi1osof
                10 января 2019, 15:12
                0
                Да я сейчас не про плагин. В 2.7.0 я не работал еще, но как я понял из последних публикаций, появился новый механизм удаления ресурсов в замен старой кнопки. Вот я и говорю, что если и было желание новое сто-то сделать, то надо было старое не удалять. То есть я про ядро, а не сторонние решения.
                  Андрей Степаненко
                  10 января 2019, 15:19
                  0
                  Полностью поддерживаю, надо сделать оба варианта.
                    Андрей Степаненко
                    11 января 2019, 18:45
                    0
                    Еще бы до конца понять работу события: OnResourceToolbarLoad
                    Почему оно так устроено что нужно обязательно прервать процесс через exit.
                    Было бы круче если бы items как передавался в массив так и возвращался обратно.
                    Получается работать будет только один процесс, либо тот кто его остановит.
                      Fi1osof
                      11 января 2019, 21:29
                      0
                      Я не могу сказать наверняка, так как давно уже в админке не лазил, но пара мыслей есть:

                      1. Вы делаете неправильно. Вот пример: forums.modx.com/thread/87107/adding-icon-to-the-resource-toolbar
                      Там возвращают через return $this->modx->error->success('',$items);
                      Посмотрите в эту сторону.
                      2. Не вижу у вас где именно вы объявляете переменную $items. Полагаю нигде. В этом тоже может быть засада. MODX не всегда корректно использует ссылки на объекты. В результате передается не объект, а его копия, и теряется связь с оригиналом.
                      Попробуйте вот так: $items = & $scriptProperties['items']; и добавляйте уже в него.

                      А exit в вашем случае для того, чтобы отдать контент. Плагины просто так контент не отдают, простые print и print_r в них просто записываются в логи MODX и все.
                        Сергей Шлоков
                        12 января 2019, 08:51
                        0
                        Извиняюсь, что вмешиваюсь. Говоря про объекты ты имеешь ввиду объекты PHP или параметры плагина?
                        MODX не всегда корректно использует ссылки на объекты. В результате передается не объект, а его копия, и теряется связь с оригиналом.
                        Если объекты PHP, то уверен, что ты просто оговорился.
                          Fi1osof
                          12 января 2019, 13:50
                          0
                          Нет, я говорю именно про ссылки на объекты PHP.
                          modPlugin расширяет класс modElement. При выполнении там выполняется extract($scriptProperties, EXTR_SKIP); То есть все переданные параметры из общего массива экстрактятся в отдельные переменные. Это и позволяет в плагинах работать с переменными без объявления их, типа как в коде выше с переменной $items, которая нигде не объявлялась.
                          Но проблема в том, что при экспорте используется параметр EXTR_SKIP. При таком экспорте переменных создаются именно новые сущности, а не просто передается ссылки на существующие переменные. В этом и проблема.
                          Чтобы было понятней, вот пример:
                          MODX создал переменную $items=[$item1, $item2] и отправляет в ивент параметром. Ивент нашел 3 плагина и начинает по порядку их выполнять с передачей в них этой переменной.
                          В первый плагин переменная пришла с двумя элементами. Вы добавляете туда еще элемент $items[] = $item; и у вас тут 3 элемента. ОК, выполняется второй плагин. Как вы думаете, сколько там будет элементов в $items? Если думаете, что 3, то думаете неправильно. Для первого плагина $items — локальная переменная, никак не связанная с исходным элементов $itesm. То есть в первом плагине стало 3 элемента, а во втором (и далее) все те же 2.
                          Чтобы такого не произошло, надо или добавлять так: $scriptProperties['items'][] = $item; или создать свою связанную переменную $items = & $scriptProperties['items']; и работать уже с ней, как со ссылкой. Вот тогда можно выполнять несколько плагинов.

                          P.S. если бы они использовали EXTR_REFS вместо EXTR_SKIP, то экспортировались бы сразу ссылки и проблемы не было бы. Я даже где-то писал об этом давно (может даже тикет создавал или PR), но результата не было.
                            Сергей Шлоков
                            12 января 2019, 14:53
                            0
                            Ни секунды не сомневался, что ты знаешь матчасть. Поэтому и спросил, что ты имеешь ввиду. И то, что ты описал верно для всего, кроме объектов. В самой первой ссылке в твоем комменте есть пример с функцией, демонстрирующий специфику объектов. Я в своё время разбирал это отличие. Поэтому, если ты передашь объект, то передастся не копия, а указатель на объект. И твой пример не сработает.

                            Я, кстати, тоже несколько раз порывался сделать PR с EXTR_REFS, но забил. Простейшие изменения принимаются годами, а тут даже надеяться не на что. С этим нужно разбираться, а у них ни времени ни желания нету, а возможно и знаний.
                            Fi1osof
                            12 января 2019, 15:18
                            0
                            Да, я с тобой тут во всем согласен. В своем тексте я под объектами подразумевал любые передаваемые нескалярные переменные, конкретно в этом случае массив $items. Просто за два года работы с JS я перестал между ними делать особые отличия, потому что в JS массив — это производная от объекта, и по сути тоже объект.
                            ([]) instanceof Object
                            true
                            Array instanceof Object
                            true
                            Поэтому для себя давно уже опускаю разделение одних на других. В данном случае мне правильней было говорить именно про массивы.
                            Сергей Шлоков
                            12 января 2019, 14:58
                            0
                            Весь код MODX пестрит таким
                            function __construct(modX &$modx) {
                                    $this->modx= & $modx;
                            }
                            Т.е. разработчики MODX не знают как работают объекты и ссылки. Описанный выше код я считаю опасным. Ибо при изменении $this->modx глобальный объект $modx тоже измениться. А если убрать ссылки, то даже если сделать так $this->modx = null, глобальный объект останется невредимым.
          Баха Волков
          10 января 2019, 15:15
          +1
          Менеджер удаления и вправду отличное решение, особенно для менеджеров. Но оставить возможность прямого удаления как по мне было бы хорошим решением, например, в виде контекстного меню
          Eugene Generalov
          10 января 2019, 16:21
          0
          Самый бессмысленный компонент в модсторе.
          В менеджере кнопочку «Уничтожить всё» религия не позволяет нажимать?
          Удобнее видеть всё элементы на удаление в одном месте. Так как товары по-умолчанию в ms2 не отображаются в дереве элементов.
            Андрей Степаненко
            10 января 2019, 16:29
            0
            4000 товаров пробовал удалить?
              Eugene Generalov
              10 января 2019, 16:45
              0
              Так может лучше было сделать так, чтоб эта кнопка удаляла всё не только то что на сейчас отображается, или без отображения этой «портянки»? Так сказать улучшить то что уже есть, а не возвращаться к старому?
          Александр Мельник
          10 января 2019, 19:32
          0
          Боремся с «улучшениями» )))
            Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
            31