<?php if (!defined('PmWiki')) exit();
# vim: set ts=4 sw=4 et:
##
##        File: PageConfig.php
##     Version: 2008-06-01
##      Status: alpha
##      Author: Peter Bowers
## Create Date: May 10, 2008
##   Copyright: 2008, Peter Bowers
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License, Version 2, as
## published by the Free Software Foundation.
## http://www.gnu.org/copyleft/gpl.html
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##

$RecipeInfo['PageConfig']['Version'] = '2008-06-01';
define(PageConfig, true);

SDV($PCPages, array("$SiteAdminGroup.PageConfig"));
SDV($PCRuleList, array('if', 'comment', 'linebreaks'));
SDV($PCDbg, false);
SDV($PCIncludeDir, "$FarmD/cookbook");
SDV($PCValidVars, array());

# Must load this to have the 'if' markup rule available
include_once('scripts/stdmarkup.php');

foreach ($PCPages as $pn) {
	$page = RetrieveAuthPage($pn, 'read', false);
    if ($PCDbg) echo "Before pre-processing: $page[text]<br>\n";
    $x = $page['text']; 
    foreach ($PCRuleList as $rule) {
        $p = $MarkupTable[$rule]['pat'];
        $r = $MarkupTable[$rule]['rep'];
        #$x = preg_replace($p,$r,$x); 
        if ($p{0} == '/') $x=preg_replace($p,$r,$x); 
        elseif (strstr($x,$p)!==false) $x=eval($r);
    }
    if ($PCDbg) echo "After pre-processing: $x<br>\n";
    foreach (explode("\n", $x) as $k => $line) {
        # Get rid of comments (# at the beginning of a line or after whitespace)
        $line = preg_replace("/(?:^|\s)\s*#.*$/", "", $line);
        # If the line is empty skip it
        if (preg_match("/^\s*$/", $line)) continue;
        # If the line doesn't match our syntax then print error and skip it
        if (!preg_match("/^\s*((?:(?:include\s*\(\w+\.php\)|set\s*\([\w$\[\]]+,\s*(?:\S+|\"[^\"]+\")\s*\))(?:\s*[,;]\s*)?)+)\s*$/", $line, $m)) {
            $k++;  // just for display purposes - line numbers are 1-based
            PCError("PageConfig SYNTAX ERROR: $pn(line $k): $line");
            continue;
        }
        $acts = $m[1];
        if ($PCDbg) echo "PageConfig: Processing \"$line\" (actions=$acts)<br>\n";
        if (!preg_match_all("/(?:(?P<include>(?:include|require)(?:_once)?)\s*\((?P<file>\w+\.php)\)|(?P<set>set)\s*\(\\$?(?P<var>\w+)(?P<vararr>\[(?P<vararridx>\w*)\])?\s*,\s*(?P<val>\S+|\"[^\"]+\")\s*\))(?:\s*[,;]\s*)?/", $acts, $m, PREG_SET_ORDER)) {
            PCError("PageConfig Internal Error: action=$acts");
            continue;
        }
        if ($PCDbg) print_r($m);
        if ($PCDbg) echo "<br>\n";
        foreach ($m as $act) {
            #print_r($act);
            #echo "<br>\n";
            if ($act['include']) {
                ##
                ## INCLUDE
                ##
                $file = '';
                foreach ((array)$PCIncludeDir as $dir)
                    if (file_exists("$dir/$act[file]"))
                        $file = "$dir/$act[file]";
                if ($file) {
                    if ($PCDbg) echo "Including $act[file]<br>\n";
                    switch ($act['include']) {
                    case 'include':
                        include($file);
                        break;
                    case 'require':
                        require($file);
                        break;
                    case 'require_once':
                        require_once($file);
                        break;
                    default:  // include_once()
                        include_once($file);
                        break;
                    }
                } else {
                    PCError("ERROR: Cannot include $act[file].  File does not exist.");
                }
            } elseif ($act['set']) {
                ##
                ## SET
                ##
                if ($act['val']{0} == '"' && substr($act['val'], -1) == '"')
                    $act['val'] = substr($act['val'], 1, strlen($act['val'])-2);
                if ($PCDbg) echo "Setting $act[var] to $act[val]<br>\n";
                $SetOK = false;
                if (is_array($PCValidVars)) {
                    # array of all valid values
                    if ($ValidVars = $PCValidVars[$act['var']]) {
                        if (is_array($ValidVars)) {
                            if ($PCDbg) echo "SET: Array<br>\n";
                            if (in_array($act['val'], $ValidVars))
                                $SetOK = true;
                        } elseif ($ValidVars === true) {
                            if ($PCDbg) echo "SET: TRUE<br>\n";
                            $SetOK = true;
                        } elseif (is_string($ValidVars) && $ValidVars[0] == '/' && preg_match($ValidVars, $act['val'])) 
                            $SetOK = true;
                    }
                } elseif ($PCValidVars === true) $SetOK = true;
                if ($SetOK) {
                    if ($act['vararr']) 
                        $GLOBALS[$act['var']][$act['vararridx']] = $act['val'];
                    else $GLOBALS[$act['var']] = $act['val'];
                } else {
                    PCError("PageConfig: Assignment not allowed. VAR=$act[var], VAL=$act[val]");
                }
            }
        }
    }
}

function PCError($errmsg)
{
    echo $errmsg . "<br>\n";
}

# Now unset everything so we don't have accidental globals hanging about
unset($k, $pn, $page, $line, $m, $acts, $act, $x, $p, $r, $file, $dir, $SetOK);
unset($ValidVars);