<?php if (!defined('PmWiki')) exit();
/*  Copyright 2006 Patrick R. Michaud (pmichaud@pobox.com),
    Copyright 2007 Thomas Bley (thomas.bley@simple-groupware.de)
    This file is part of PmWiki; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published
    by the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.  See pmwiki.php for full details.
*/

// TODO add option for clean urls (enablepathinfo=1)
// TODO handle permission attribute change:
// page: remove page from cache
// group: remove group from cache
// sitewide permission change possible ?

// TODO handle delete page, rename page

// TODO implement: dependency check
// read authentication triggered by $NoHTMLCache < 2 ?


// INSTALLTION
/*
0) copy staticcaches.php to <pmwiki-dir>/scripts/

1) edit config.php, add:
$StaticPageCacheDir = 'cache.s';
$EnablePathInfo = 0; // clean URLs not (yet) supported
$EnableStaticHTMLCache = 1; // active caching
$EnableStaticHTMLPages = "/Main\..+/"; // only cache pages in the Main group [or]
$EnableStaticHTMLPages = ""; // cache all pages
// if enabled, disable static cache for a page with (:static off:)

2) edit scrips/stdconfig.php, replace:
$pagename = ResolvePageName($pagename);
with:
$pagename = ResolvePageName($pagename);
include_once("$FarmD/scripts/staticcaches.php");

3) edit/add .htaccess:
# If charset needs to be UTF-8
AddCharset UTF-8 .html
# activate engine, only cache get request, make sure mod_rewrite is loaded in httpf.conf
# no clean urls, EnablePathInfo = 0
RewriteEngine On
RewriteCond %{REQUEST_METHOD} ^GET$
# absolute path to file, adapt pmwiki/ if necessary
RewriteCond %{DOCUMENT_ROOT}/pmwiki/cache.s/s_%{QUERY_STRING}.html -f
RewriteRule pmwiki.php cache.s/s_%{QUERY_STRING}.html [QSA,L]
*/


if (!$EnableStaticHTMLCache
        || !isset($EnableStaticHTMLPages)
    || empty($StaticPageCacheDir)) {
        return;
}
        
$EditFunctions[] = "scUpdateCache";

if (count($_POST) > 0
    || count($_GET) > 1
    || (count($_GET) == 1 && empty($_GET['n']))) {
        return;
}
if ($EnableStaticHTMLPages and !preg_match($EnableStaticHTMLPages,$pagename)) return;

$LastStaticModTime = 0;
foreach ($WikiLibDirs as $dir) {
  $page = $dir->pagefile($pagename);
  if ($page and file_exists($page)) {
    $LastStaticModTime = filemtime($page);
    break;
  }
}
if ($LastStaticModTime == 0) return;

Markup('static','directives','/\\(:static\\s(.*?):\\)/ei',"scCacheConfig('$1')");

mkdirp($StaticPageCacheDir);
$StaticPageCacheFile = scBuildCacheFile($pagename);
if (!file_exists($StaticPageCacheFile) || @filemtime($StaticPageCacheFile) < $LastStaticModTime) {
  $HandleActions["browse"] = "scHandleStaticBrowse";
}

function scCacheConfig($params) {
  // (:static on/off dependency regexp:)
  $params = explode(" ",$params);
  if ($params[0]=="off") $EnableStaticHTMLCache = 0;
  // echo $params[1];
  // TODO handle dependencies
}

function scBuildCacheFile($pagename) {
  global $StaticPageCacheDir;
  return "$StaticPageCacheDir/s_n=$pagename.html";
}
function scRemoveCacheFile($pagename) {
  global $DefaultGroup, $DefaultName;
  @unlink(scBuildCacheFile($pagename));
  if ($pagename == $DefaultGroup.".".$DefaultName) {
        @unlink(scBuildCacheFile(""));
  }
}
function scPutCacheFile($pagename,$out) {
  global $DefaultGroup, $DefaultName;
  $StaticPageCacheFile = scBuildCacheFile($pagename);
  if ($fp = @fopen("$StaticPageCacheFile,new", "x")) {
    fwrite($fp,"<!-- static-cached -->".$out);
        fclose($fp);
    rename("$StaticPageCacheFile,new", $StaticPageCacheFile);
        if ($pagename == $DefaultGroup.".".$DefaultName) {
          copy($StaticPageCacheFile,scBuildCacheFile(""));
        }
  }
}

function scUpdateCache($pagename, &$page, &$new) {
  global $IsPagePosted;
  if ($IsPagePosted) {
    scRemoveCacheFile($pagename);
          // TODO remove dependencies, hanle delete page, rename page
  }
}

function scHandleStaticBrowse($pagename, $auth='read') {
  global $EnableStaticHTMLCache, $NoHTMLCache;

  ob_start();
  HandleBrowse($pagename,$auth);
  $out = ob_get_contents();
  ob_end_flush();

  scRemoveCacheFile($pagename);
  if ($EnableStaticHTMLCache and $NoHTMLCache < 2 and $out > '') {
    scPutCacheFile($pagename,$out);
  }
}