Массовая обработка документов MODx
В MODx, к сожалению, нет инструментов для массовой обработки документов. Например, можно легко перемещать документ с дочерней структурой, но нельзя переместить несколько разных документов одновременно. Или, скажем, требуется изменить шаблон всем документам раздела, или отключить кеширование целой ветви в структуре. Как быть? Сидеть и перетыкивать галочки полутысяче документов? Нет! Ведь все эти галочки — это просто поля в БД, всё можно автоматизировать. Даже с нуля скрипт для перебора пишется за десяток-другой-третий минут, т. е. это быстрее, проще, надежнее и интереснее, чем руками перебирать сотню-другую документов. А с этим постом всё сводится вообще к минутам.
Моё решение состоит из двух частей: автоподключатор и автоперебиратор :)
Заранее прошу прощения за оформление кода, как доделаю сайт, возьмусь и за это.
Автоподключатор — это код, который вытаскивает данные о БД из конфигурационного файла MODx и устанавливает соединение с БД где бы скрипт не лежал (в пределах хостинга, разумеется). Всё полностью автоматически.
Читаем конфигурацию в массив строк:
// качаем файл настроек
$lines = file($_SERVER[’DOCUMENT_ROOT’] . ’manager/includes/config.inc.php’,
FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
if (!$lines)
die (’check path to config.inc.php’);
Красный фрагмент — это то, что не должно работать в PHP 4, фрагмент надо будет стереть. Возможно, что при этом придется обтримить строки или еще как-то доделать скрипт.
Перебираем и выполняем нужные строки, получаем инициализированные параметры:
// съедаем данные
foreach ($lines as $line_num => $line)
{ if (strpos($line, ’rror_reporting’))
break;
if (strpos($line, ’tab’))
eval ($line);
if (strpos($line, ’dbase’))
eval (str_replace(’`’, ’’, $line));
}
Подключаемся к БД:
// подключаемся
$link = mysql_connect($database_server, $database_user, $database_password);
if (!$link)
die(’Could not connect: ’ . mysql_error());
$db_selected = mysql_select_db($dbase, $link);
if (!$db_selected)
die (’Can’t use ’ . $dbase . ’ : ’ . mysql_error());
echo «Connection OK.»;
Вот и всё. Написано не ахти, но работает универсально, стабильно и полностью само. Копируем код в скрипт и кладем на хостинг с MODx, получаем автоконнект с БД.
Автоперебиратор — это код, который рекурсивно перелопачивает документы в MODx совершая с ними некоторые действия. На входе только идэшник документа-корня. Перебираются все дочерние документы, и дочерние этих дочерних и т.д. Соответствующая рекурсивная функция:
// функция перебора
function do_something ($id)
{ GLOBAL $link;
$req = «UPDATE modx_site_content SET cacheable=0 WHERE parent=» . $id;
$res = mysql_query($req, $link);
if ($res)
{ $req = «SELECT id FROM modx_site_content WHERE isfolder=1 AND parent=» . $id;
$res = mysql_query($req, $link);
while ($row = mysql_fetch_array($res))
do_something($row[0]);
}
else
die(mysql_error());
}
Этот пример отключает кеширование. С документом-корнем изменения не происходят, перебираются только дочерние. Само действие выделено зеленым, если надо делать что-то отличное от отключения кеширования, то изменяем именно зеленый фрагмент. Если углубляться в структуру не требуется, то можно отключить селект.
Начало работы — вызов обработки корня, закрытие соединения и сообщение об окончании:
//поехали
do_something(14);
mysql_close($link);
echo ’All done’;
Внимание! Рекомендую бэкапить БД перед обработкой, мне не удалось что-либо сломать, но я не исключаю такой возможности :) Также рекомендую не торопиться, а продумывать изменения в БД. И последний совет, рабочий скрипт лучше прерывать в самом начале каким-нибудь exit(); пока не используется, а то можно неудачно запустить его в неподходящий момент. Заодно будете перепроверять скрипт когда он вдруг будет не срабатывать :)
Естественно, можно использовать автоподключатор для каких-то других целей вплоть до создания бэкдоров, и автоперебиратор сам по себе также для чего угодно, например, его можно засунуть в сниппет. На базе этого примера вообще много чего интересного можно собрать ;)
P.S. Конечно, иногда можно обойтись и вовсе одиночным запросом к БД, но это уже совсем другая история.
