Создаём ZIP архив средствами MODX

Случается так, что на сайте надо запаковать какую-то папку, а по некоторым причинам сделать это невозможно затруднительно. Предлагаю вариант, который практически не требует ничего, кроме MODX и доступа в бек-энд.

В xPDO есть класс xPDOZip, который умеет запаковывать/распаковывать архивы. К сожалению, в самом MODX его функциональность задействована ровно наполовину — распаковать ZIP архив мы можем, а вот запаковать папку в архив не имеем возможности. Предлагаю решение!

Решение

Воспользовавшись этим классом мы можем запаковать в архив любую папку на сайте. Если сайт не очень много весит, то получится и весь сайт заархивировать.

$zippath = MODX_BASE_PATH . 'site.zip';
$dirpath = MODX_BASE_PATH;

if ($zipClass = $modx->loadClass('compression.xPDOZip', XPDO_CORE_PATH, true, true)) {
    if ($zip = new $zipClass($modx, $zippath, array('create' => true, 'overwrite' => true))) {
        @unlink($zippath);
        $result = $zip->pack($dirpath);
        print_r($result);
    }
}

Если запустить данный код из компонента Console (спасибо, Николай) или ещё как-нибудь, то в корне сайта будет создан архив site.zip со всеми файлами сайта.

К сожалению, класс xPDOZip не поддерживает возможность исключения файлов по маске, поэтому, если вам не надо паковать какие-то типы файлов (например, .jpg, .png) или папку core/cache, что само по себе естественно, то на данный момент этого сделать невозможно. Я уже отправил PR в xPDO с добавлением такой возможности, но пока не знаю, примут ли…
Павел Гвоздь
13 декабря 2016, 01:00
modx.pro
17
5 030
+13
Поблагодарить автора Отправить деньги

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

Воеводский Михаил
13 декабря 2016, 05:01
0
Павел, если запускать из консоли, то снимается ограничение на суммарный объем файлов?
    Павел Гвоздь
    13 декабря 2016, 05:15
    +3
    Да, Михаил, полагаю, что однозначно. Ибо загвоздка с запаковкой больших сайтов именно в том, что не хватает времени на выполнение.
      Воеводский Михаил
      13 декабря 2016, 05:41
      +1
      Тогда однозначно нужное решение и еще более нужный PR. И прекрасно стыкуется со следующей нашей разработкой.
Fi1osof
13 декабря 2016, 05:13
+4
Павел, в качестве эксперимента:
Ext.getCmp('source-tree-1').on('append', function(tree, parent, node, index){
  console.log(node);
  node.attributes.menu.items.push({
    text: "ZIP",
    handler: function(node){
      console.log(this);
      console.log(node);
    }
    ,scope: this
  });
});
Добавляет новый пункт контекстного меню joxi.ru/Y2LjLVES9wy54r
Минус в том, что срабатывает только когда элементы подгружаются. Если в момент навешивания события элементы уже есть, то они будут без допэлемента. Но если вовремя вклиниться, то ОК будет.
Конечно получать по айдишнику не круто, лучше через менеджер компонентов брать или типа того (есть, к примеру, поиск по типу компонентов). Это так, набросок.

А вообще, еще лучше слать PR, функционал нужный и должен быть в ядре.

    Павел Гвоздь
    13 декабря 2016, 13:10
    +1
    Понимаю, что лучше слать PR в ядро с таким функционалом. И я пытался, честно. Но оказалось, что править надо много всего, а временем на это не располагаю на данный момент, поэтому оставил эту затею до лучших времён.
      Fi1osof
      13 декабря 2016, 14:30
      +1
      Да, со временем беда.
    Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
    7