Полезные методы 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
modx.pro
25
3 375
+24

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

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, ну как? Удобно?
                        R2m0x94 (Vasily)
                        06 апреля 2020, 09:51
                        0
                        Добрый день, как устранить предупреждения исходя из логов? Ошибка постоянно повторяется в журнале:
                        [2020-04-06 09:38:40] (ERROR @ /..../core/xpdo/cache/xpdocachemanager.class.php : 522) PHP warning: closedir(): supplied resource is not a valid Directory resource
                        [2020-04-06 09:38:40] (ERROR @ /..../core/xpdo/cache/xpdocachemanager.class.php : 514) PHP warning: unlink(/..../core/cache/db/objects/modSnippet/7f9b2119f1e00b7ae4b3f2fe555fb5b7.cache.php): Нет такого файла или каталога
                        В 514 строке '7f9b2119f1e00b7ae4b3f2fe555fb5b7' постоянно меняется название, с чем это может быть связано?
                          Евгений Лазарев
                          26 октября 2020, 16:00
                          0
                          Тот же вопрос интересует. Валятся эти ошибки.
                            R2m0x94 (Vasily)
                            26 октября 2020, 19:03
                            0
                            Да ошибки так и не ушли, пока решил просто комментарием вывода этой ошибки в лог, но это не решение проблемы. Конечно можно отключить кэширование бд, но это тоже не решение проблемы. Если только частичное, но вопрос до сих пор ещё активный
                              Евгений Лазарев
                              26 октября 2020, 19:12
                              0
                              Название меняется поскольку в кеше создается уникальным. Я ПРИМЕРНО понимаю, что кэшируется сниппет/чанк/плагин, создается файл — но при этом он не создается и пишется в БД с сылкой на этот исполнительный файл, позже при заходе на страницу к примеру по запросу БД берется информация об исполнительном файле, его нет, и происходит процедура удаления старых данных но их нет и поэтому ошибка и «создаются» новые и все по кругу. Ребят может кто в курсе этой проблемы?
                                R2m0x94 (Vasily)
                                26 октября 2020, 21:15
                                0
                                Нет, он создаётся на время запроса, затем чистится и отследить сложно, поэтому в лог попадает последующий запрос, который кешируется и пишется в лог, потому что его уже нет и создался новый. Тут вариант допиливать инструкцию или комментировать например дописать условия отработки в лог
                                  ewal
                                  19 мая 2022, 16:17
                                  0
                                  Удалось решить эту проблему??????? Такая же байда.
                                    R2m0x94 (Vasily)
                                    19 мая 2022, 18:29
                                    0
                                    Да, вроде log_level стояло значение 3 (INFO), исправил на 1 (ERROR) и всё прошло. Так как INFO это просто оповещение информации о том, что кэш-файл был удалён с сервера.
                          Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
                          30