Полезные методы xPDOCacheManager

Класс xPDOCacheManager реализует механизм кеширования в MODX. Кеш у нас хранится в файлах, а значит, этот класс может помочь нам в работе с файловой системой.

Чтобы иметь доступ к методам класса xPDOCacheManager, нужно получить экземпляр этого класса. Это делается одной строчкой:
$cache = $modx->getCacheManager();

xPDOCacheManager::writeFile

Первый метод поможет нам записывать данные в файл. Работает он очень просто:
$cache->writeFile(MODX_BASE_PATH . 'filename.txt', 'Текст');
В итоге в корне сайта будет создан указанный файл с нужным содержимым. Причём можно не волноваться о том, создана ли соответствующая структура папок — нужные папки будут созданы автоматически:
$cache->writeFile(MODX_BASE_PATH . 'test/folder/filename.txt', 'Текст');

Если файл уже был ранее создан, то он будет перезаписан. Если нам нужно дописать содержимое в конец файла, просто указываем третий параметр:
$cache->writeFile(MODX_BASE_PATH . 'filename.txt', 'Текст', 'a');

Причём создавать можно любые файлы, а не только текстовые:
$img = file_get_contents('https://via.placeholder.com/300');
$cache->writeFile(MODX_BASE_PATH . 'img.png', $img);

xPDOCacheManager::writeTree

Как вы поняли, кэш-менеджер умеет создавать структуру папок. Делает это метод writeTree:
$cache->writeTree(MODX_ASSETS_PATH . 'template/main/css/');

xPDOCacheManager::copyFile

Думаю, понятно, что этот метод создаёт копию файла:
$source = MODX_MANAGER_PATH . 'templates/default/images/modx-icon-color.svg';
$target = MODX_BASE_PATH . 'logo/modx-logo.svg';
$cache->copyFile($source, $target);

xPDOCacheManager::copyTree

А вот это уже бомба — метод copyTree копирует все вложенные файлы, папки, подпапки и пр.:
$source = MODX_MANAGER_PATH . 'templates/default/images/';
$target = MODX_BASE_PATH . 'logo/';
$cache->copyTree($source, $target);

xPDOCacheManager::deleteTree

Раз мы можем создавать целые структуры папок, значит, мы можем с такой же лёгкостью их удалять. Посмотрите, какие «красивые» примеры кода используются в PHP для удаления папок: PHP удалить папку с содержимым. Такой вариант мне нравится больше:
$cache->deleteTree(MODX_BASE_PATH . 'logo/', ['deleteTop' => true, 'extensions' => []]);

Если мы хотим удалить только файлы и папки внутри указанного каталога, то указываем 'deleteTop' => false. Параметр extensions нужно указывать, потому что по умолчанию будут удаляться только файлы кеша (.cache.php)

Вот, вроде бы и не много методов, но если вы будете их использовать, ваш код станет чище, логичнее и понятнее.
Илья Уткин
14 сентября 2018, 10:07
18
375
+24

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

gruzoveek
14 сентября 2018, 10:13
0
Спасибо! как раз начал делать работу с файлами, а тут и статья в тему)
Алексей
14 сентября 2018, 11:31
0
Спасибо! Весьма полезно.
Сергей Шлоков
14 сентября 2018, 13:16
+3
Обращаюсь к разработчикам.
Друзья, ответьте мне на один вопрос — как вы считаете, это нормально для кэш-менеджера имплементировать данный функционал?
    Илья Уткин
    14 сентября 2018, 13:21
    +2


    А если серьёзно — то да, это кажется не очень логичным)
      Сергей Шлоков
      14 сентября 2018, 13:34
      0
      Не корысти ради, просвещения для! :))
      Ответ-то очевиден. Просто хотелось подискутировать и потихоньку придти к новости, что в MODX3 появился FlySystem.
        Дмитрий Иванов
        14 сентября 2018, 14:05
        0
        А где сам modx3? 3 месяца назад вышла багованная тестовая версия, с тех пор новостей о нем нет, даже на modx3.org тишина.
          Баха Волков
          14 сентября 2018, 14:32
          +2
          Позвольте кое-что сказать, не совсем относится к MODX3 и к вам лично но все же:

          MODX3 насколько я знаю нуждается в тестировании, да и работа идёт. Чтобы это увидеть, нужно смотреть на гитхабе.

          Для того чтобы сидеть и говорить, будто обещали и ни… уя, нужно хотя бы помочь… Хотя бы что нибудь сделать. Я так считаю. Можете плюнуть в меня и не согласиться, ваше право.

          Я вот из-за малых знаний в back-end'е при всем желании не смог бы помочь проекту, потому и не ворчу мол зажрались, деньги собрали и ни шиша, сидят и ничего не делают… Немного повзрослев понял, что скорее моё мнение и тем более желание никого не должно волновать и скорее всего не волнует. Просто нужно пытаться самому что-то делать для улучшения своей жизни и если остается желание, силы и возможности, то делать что-то для других и всё)

          Пользуясь случаем (так как давно меня эта мысль не покидает и до сих пор стыдно) прошу прощения у Василия Наумкина за неадекватные ответы в тех. поддержке modstore.pro по поводу mSearch2 и у Ивана Климчука за комментарии на данном форуме по одному моему вопросу. Долго думал и не мог определиться как мне извиниться и тут решился. Протягиваю вам руку и надеюсь, что вы поймёте меня.
            Баха Волков
            14 сентября 2018, 14:35
            0
            Кстати, обращаюсь к вам Василий и Иван, вы в любом случае напишите или дайте знать приняли или отвергаете просьбу о прощении, а то неловко как-то будет)
            Дмитрий Иванов
            14 сентября 2018, 14:52
            +1
            Для того чтобы сидеть и говорить, будто обещали и ни… уя, нужно хотя бы помочь… Хотя бы что нибудь сделать. Я так считаю. Можете плюнуть в меня и не согласиться, ваше право.
            а с чего вы взяли, что я не помогаю? я создал далеко не один issue на гитхабе по 3 ветке, но работа все равно идет слишком медленно. Уже можно было бы выпускать новые тестовые сборки, но ничего не происходит.
              Баха Волков
              14 сентября 2018, 20:47
              0
              Позвольте кое-что сказать, не совсем относится к MODX3 и к вам лично но все же:
              Я не могу этого знать) Я не про вас
            Василий Наумкин
            14 сентября 2018, 17:25
            +1
            прошу прощения у Василия Наумкина за неадекватные ответы в тех. поддержке modstore.pro по поводу mSearch2
            Пффф, я даже не помню о чём речь, не переживай.

            Уверен, что за словом в карман я не лазил и мы весело пообщались =)
              Баха Волков
              14 сентября 2018, 20:49
              +1
              Хех, было довольно «весело» :)

              Ну и хорошо, раз нет обид!)
Pavel Zarubin
14 сентября 2018, 14:12
0
Спасибо, Илья, как всегда очень полезно!
Сергей Шлоков
14 сентября 2018, 20:07
+6
Для информации. В MODX есть специальный класс для работы с файловой системой. Он называется modFileHandler и работает с классами modFile и modDirectory. Реализация крайне убогая. Например самый первый пример из документации не работает. Т.е. создать папку у вас не получится. А как вы думаете сделано удаление директории? А вот так
$this->fileHandler->modx->getCacheManager();
return $this->fileHandler->modx->cacheManager->deleteTree($this->path, $options);
Т.е. не кеш-менеджер работает через файловый менеджер, а наоборот. Реакция одна — WTF. И подобного говнокода в ядре я встречал неоднократно. О некоторых моментах я уже писал раньше.
Если это понимаю я со своими средненькими познаниями, то что уж говорить про профи.

Заключение. Если вы ни слова не поняли, о чём тут написано, не расстраивайтесь. У вас ещё всё впереди. :)
    Евгений Борисов
    15 сентября 2018, 10:52
    +1
    Т.е. не кеш-менеджер работает через файловый менеджер, а наоборот
    А чтобы воспользоваться кеш-манагером, нужно еще и доступ к БД подтянуть
    require_once 'core/xpdo/cache/xpdocachemanager.class.php';
    require_once 'core/xpdo/xpdo.class.php';
    $xpdo = new xPDO('mysql:');
    $cache = new xPDOCacheManager($xpdo);
    $flag = $cache->writeFile(__DIR__. '/filename.txt', 'Текст');
      Сергей Шлоков
      15 сентября 2018, 13:23
      0
      Забанят нас тут ))
        Николай Савин
        16 сентября 2018, 09:05
        +1
        Тут к счастью не Иван, админом. Так что забанят только в чате
    Сергей Шлоков
    16 сентября 2018, 17:42
    0
    Решил глянуть как организована работа с сессией. И вот такое увидел в классе modUser в методе addSessionContext (другие не смотрел)
    if (!isset($_SESSION["modx.{$context}.user.token"]) || empty($_SESSION["modx.{$context}.user.token"])) {
    А вот так добавляются скрипты в классе modX
    $this->sjscripts[count($this->sjscripts)]= $src;
    У меня одного ощущение, что писал практикант? ))

    Может Евгений меня поправит, но работа с сессией имеет слабые места. Достаточно добавить в сессию один ключик и вы авторизованы в админке.В свете недавней уязвимости сделать это раз плюнуть.
    Сергей Шлоков
    16 сентября 2018, 17:45
    +1
    А ещё вот эта известная «фича»:
    if ($contextKey !== 'mgr' && !$this->user) {
        $this->user= $this->getAuthenticatedUser('mgr');
    }
    Т.е. если пользователя залогинен только в админке, то он автоматически аутентифицируется на сайте. Вот зачем? Многие уже на этом попадались.
      Aleksandr Huz
      16 сентября 2018, 17:51
      0
      Вот это реальная херня. Приходилось всегда использовать анонимную вкладку при тестировании.
Николай Савин
16 сентября 2018, 09:09
-1
Я вот не особо понимаю. А нахрена вообще нужно создавать файлы через этот класс, если можно пользоваться родными методами php?
    Сергей Шлоков
    16 сентября 2018, 17:53
    +1
    Пользоваться высокоуровневым интерфейсом удобнее. Только в этом классе этого не должно быть. Он должен работать через FileHandler.
    Как пример функция email из библиотеки modHelpers заменяет такой код
    $mail = $modx->getService('mail', 'mail.modPHPMailer');
    $mail->setHTML(true);
    
    $mail->set(modMail::MAIL_SUBJECT, $subject);
    $mail->set(modMail::MAIL_BODY, $body);
    $mail->set(modMail::MAIL_SENDER, $modx->getOption('emailsender'));
    $mail->set(modMail::MAIL_FROM, $modx->getOption('emailsender');
    $mail->set(modMail::MAIL_FROM_NAME,$modx->getOption('site_name'));
    $mail->address('to', $email);
    $mail->send();

    Правда короче и удобнее?
    Pavel Zarubin
    19 сентября 2018, 21:51
    0
    Ну к примеру чтобы избавится от проверки существует ли категория. Или чтобы в цикле не удалять папки или…
    Да вообще в статье все написано, напиши аналог метода copyTree, ну как? Удобно?