Реализовал первый вариант архива, все совсем просто.
Перегоняем этим скриптом статьи в HTML архив. Скрипт принимает два параметра - начало и конец диапазона id статей:
for ($id = $argv[1]; $id < $argv[2]; $id++) {
getPage($id);
}
function getPage($id) {
$dir = (int)($id/1000);
if (file_exists("archive/" . $dir . "/" . $id . ".html")) {
return;
}
echo $id . " ";
if( $curl = curl_init() ) {
curl_setopt($curl,CURLOPT_URL,"http://yoursite.com/" . $id . "-?tmpl=component&type=raw");
curl_setopt($curl,CURLOPT_RETURNTRANSFER,true);
curl_setopt($curl,CURLOPT_HEADER,false);
$data = curl_exec($curl);
$httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
if ($httpcode<200 || $httpcode>=300) return;
}
if (!file_exists("archive/" . $dir)) {
mkdir("archive/" . $dir, 0775, true);
}
$fd = fopen("archive/" . $dir . "/" . $id . ".html", 'w') or die("не удалось создать файл");
fwrite($fd, $data);
fclose($fd);
}
Архив создается директориями по 1000 файлов. Удаляем из архив те материалы, которые не нужно архивировать:
include "../configuration.php";
$config = new JConfig();
$mysqli = new mysqli($config->host, $config->user, $config->password, $config->db);
$res = $mysqli->query("SELECT id FROM " . $config->dbprefix . "content WHERE catid < 9 OR catid IN (14,15,16)");
while ($row = $res->fetch_assoc()) {
$id = $row['id'];
$dir = (int)($id/1000);
if (file_exists($file = "archive/" . $dir . "/" . $id . ".html")) {
unlink($file);
}
}
Ну и собственно работа с архивом - в самое начало главного джумловского index.php инклюдим следующий файл:
$i = strripos($_SERVER['REQUEST_URI'], "/") + 1;
$j = stripos($_SERVER['REQUEST_URI'], "-", $i);
$aid = substr($_SERVER['REQUEST_URI'], $i, $j-$i);
$dir = (int)($aid/1000);
$content = dirname(__FILE__). "/misc/archive/" . $dir . "/" . $aid . ".html";
if ($aid &&
$aid < 45000 &&
file_exists($content)) {
include_part("before");
include $content;
include_part("after");
exit;
}
function include_part($part) {
$file = $_SERVER['DOCUMENT_ROOT'] . "/templates/lightblog/comp_" . $part . "_cache.html";
if (!file_exists($file) || (time() - filemtime($file)) > 3600) {
file_put_contents($file, file_get_contents("http://" . $_SERVER['HTTP_HOST'] . "/?tmpl=comp_" . $part), LOCK_EX);
}
include $file;
}
Логика простая: вытаскиваем из url id статьи и проверяем - если она есть в архиве, берём оттуда; иначе - запускаем фреймворк.
Вокруг самой статьи есть шаблонная обертка из модулей и прочего. Делим ее на две части - до и после. И кэшируем самостоятельно с периодом 1 час. В корневой директории шаблона лежат файлы comp_before.php и comp_after.php - это код index.php шаблона до и после включения <jdoc:include type="component" />
Итого, все архивные статьи берутся с диска. Плюс 48 обращений в Joomla в сутки, чтобы обновить шаблонную обертку. Раз в месяц запускаем скрипт архивирования с нужными параметрами новых статей, и скрипт удаления материалов, которые не нужно архивировать.
Все материалы остаются (при желании) в БД, чтобы обеспечить полнотекстовый поиск.
В планах: запихать весь архив в один zip (если скорость чтения случайного файла будет приемлема), и использовать модель кэширования шаблонной обертки для активного кэширования - части обновляются тогда, когда меняются данные в базе.