'all', //dummy entry so permissions will be checked!
'$SiteGroup.*' => 'none',
'$SiteAdminGroup.*' => 'none',
'PmWiki.*' => 'none',
'*.GroupFooter' => 'none',
'*.GroupHeader' => 'none',
'*.GroupAttributes' => 'none',
// examples of page permission patterns:
//'*.*' => 'all', // all Fox actions allowed on all pages
//'Comments.*' => 'add,delete', // adding and deleting posts in Comments group
//'Comments.{$Group}-{$Name}' => 'add,delete', // adding and deleting posts in comments group for pages with name Group-Name
//'*.{$Name}-Comment' => 'add', // adding posts for pages with -Comment suffix
//'{$FullName}-Talk' => 'add', // adding posts for pages in current group with -Talk suffix
// the following patterns for 'current page' and 'current group' could be exploited to post to edit protected pages
//'{$Group}.{$Name}' => 'add', // adding to current page
//'{$Group}.*' => 'add', // adding to pages in current group
));
// Search path for fox.css files, if any.
SDV($FoxPubListFmt, array (
"pub/fox/fox.css" => "$PubDirUrl/fox/fox.css",
"$FarmD/pub/fox/fox.css" => "$FarmPubDirUrl/fox/fox.css" ));
# load special styles for delete button and links and for message classes
foreach((array)$FoxPubListFmt as $k=>$v) {
if (file_exists(FmtPageName($k,$pagename))) {
$HTMLHeaderFmt['fox'][] =
"\n";
break;
}
}
$pagename = ResolvePageName($pagename);
## Creates the HTML code for the (:fox name [placement] [parameters]:) directive
function FoxFormMarkup($pagename, $name, $place="", $opt ) {
$PageUrl = PageVar($pagename, '$PageUrl');
$opt = ParseArgs($opt);
if($opt['redirect']) { $opt['redir'] = $opt['redirect']; unset($opt['redirect']);}
if ($opt['formcheck']) $javacheck = FoxFormCheck($opt['formcheck']);
else $javacheck = '';
$out = $javacheck;
$out.= "
", $targetname);
}
else
# delete link which works with and without javascript:
return FmtPageName("{$label}",$targetname);
} //}}}
Markup('foxdelete','directives','/\{\[foxdel(line|range) ?(|button)\\s+(\\w+)\\s+(.*?)\\s+(.*?)\\s*\]}/e',
"Keep(FoxDeleteMarkup(\$pagename, PSS('$3'), PSS('$4'), '$1', '$2', PSS('$5')))");
# Creates the HTML code for (:foxtemplate "templatestring":) as hidden input form field
# $template is the template string
function FoxTemplateMarkup($template) {
$template = str_replace('"', '', $template);
return '';
} //}}}
Markup('foxtemplate','[=','/\(:foxtemplate\\s+(.*)\\s*:\)/e',"Keep(FoxTemplateMarkup(PSS('$1')))");
# create hidden HTML input tags for template and target pages, for foxpost and foxcopy markup
function FoxPostMarkup($pagename, $n, $arg) {
if ($n=="post") { $from = 'template'; $to = 'target'; }
if ($n=="copy") { $from = 'foxcopyfrom'; $to = 'foxcopyto'; }
$arg = ParseArgs($arg,'(?>([\\w-]+\\.?[\\w-]+\\#?\\#?[\\w-]+\\.?\\.?\\#?[\\w-]*)(?:=>|[=:]))');
foreach (array_keys($arg) as $k=>$v)
if($k>0) { $i=$k-1; $out .= ''; }
foreach (array_values($arg) as $k=>$v)
if($k>0) { $i=$k-1; $out .= ''; }
return $out;
}
Markup('foxpost','directives','/\(:fox(post|copy)\\s+(.*?):\)/ei',"Keep(FoxPostMarkup(\$pagename, PSS('$1'), PSS('$2')))");
# (:foxend name:)
Markup('foxendform','directives','/\(:foxend(\\s[\\w]+):\)/', "");
# (:foxprepend:) and (:foxappend:) just vanish because they are only used later in FoxAddEntry
Markup('foxaprepend','directives','/\(:fox(ap|pre)pend\\s*(.*?)\\s*:\)/','');
# (:foxallow:) for string check
Markup('foxallow','directives','/\(:foxallow\\s*(.*?)\\s*:\)/','');
# #foxbegin# and #foxend# invisible markers
Markup('foxentry',' '') return;
if (@$_REQUEST['foxtemptext']) {
if ($_SESSION["FoxTempPageText"] > '') $new['text'] = $_SESSION["FoxTempPageText"];
return;
}
} //}}}
## add action foxpost
$HandleActions['foxpost']='FoxHandlePost';
## Main post function. Insert text into page
function FoxHandlePost($pagename) {
global $FoxDebug, $InputValues;
//get arguments from POST and GET
$fx = FoxRequestArgs($_POST);
//store current values to redisplay, in case we abort.
foreach ($fx as $k=>$v)
$InputValues[$k] = $v;
//use foxpage as abort target.
if(isset($fx['foxpage']))
$pagename = $fx['foxpage'];
//refuse n=pagename submissions
if(isset($_POST['n']))
FoxAbort($pagename,"\$[ERROR: 'n' is not a legal field name.]");
//initialise
$basename = $targetname = $pagename;
//preprocess fields with FoxFilter, which calls external filter functions
if (isset($fx['foxfilter']))
$fx = FoxFilter($pagename, $fx);
//make foxgroup input suitable for group name, add foxgrouptitle to preserve original input
if (isset($fx['foxgroup'])) {
$fx['foxgrouptitle'] = $fx['foxgroup'];
$fx['foxgroup'] = FoxWikiWord($fx['foxgroup']);
}
//do {$$var} field substitutions
$fx = FoxFieldSubstitutions($pagename, $fx);
//check if current page should be target
if (!isset($fx['newedit']) && !isset($fx['target']))
if (isset($fx['template']) || isset($fx['foxtemplate']))
$fx['target'] = $pagename;
//process special fields which could be arrays or lists for making arrays
$special = array('target', 'template', 'ptvtarget', 'ptvfields', 'pagecheck');
foreach ((array)$special as $n) {
if(isset($fx[$n])) {
if(!is_array($fx[$n]))
$fx[$n] = explode(",", $fx[$n]);
foreach ($fx[$n] as $t=>$v)
$fx[$n.'['.$t.']'] = $v;
}
}
//create $targtemp array: target=>template
if (isset($fx['target'])) {
foreach ($fx['target'] as $i=>$t)
$targtemp[$t] = $fx['template'][$i];
//add ptvtargets to target->template array
if (isset($fx['ptvtarget'])) {
foreach ((array)$fx['ptvtarget'] as $ptg) {
if (in_array($ptg, $fx['target'])) continue;
$targtemp[$ptg] = 'none';
}
}
}
//do ptv_ field renaming
$fx = FoxPTVPreProcess($pagename, $fx);
//check various security restrictions
FoxSecurityCheck($pagename, $fx);
//foxcopy=1: set foxcopy array
if (!isset($fx['foxcopyto']) && $fx['foxcopy']==1) {
$fx['foxcopyto'] = $fx['target'];
$fx['foxcopyfrom'] = $fx['template'];
}
//set $basename for redirect
if (isset($fx['redir'])) {
if($fx['redir']==1) {
//for redir=1 use first target
if (isset($fx['target']))
$basename = FoxGroupName($pagename, $fx, $fx['target'][0]);
else if (isset($fx['foxcopyto']))
$basename = FoxGroupName($pagename, $fx, $fx['foxcopyto'][0]);
}
else $basename = FoxGroupName($pagename, $fx, $fx['redir']);
}
if (isset($fx['urlfmt'])) $urlfmt = $fx['urlfmt'];
else $urlfmt = '$PageUrl';
//DEBUG//
if($FoxDebug) {
?> $tplname) {
//DEBUG// echo " TARG-TEMP>".$tgt.">".$tplname;
//set target pagename
$targetname = FoxGroupName($pagename, $fx, $tgt);
//load template
$template = FoxLoadTemplate($pagename, $tplname, $fx);
FoxAddEntry($pagename, $targetname, $template, $fx);
}
}
//open page to edit using newedit value, or jump to existing page
if(isset($fx['newedit'])) {
if($fx['template']) $tplname = end($fx['template']);
$template = FoxLoadTemplate($pagename, $tplname, $fx['template'], $fx);
$targetname = FoxGroupName($pagename, $fx, $fx['newedit']);
if(PageExists($targetname)) Redirect($targetname); //jump to existing page
FoxNewEdit($pagename, $targetname, $template, $fx);
}
//FoxMessage($pagename, "Operation was successful");
Redirect($basename, $urlfmt);
} //}}}
## check 'foxgroup' and set targetname,
function FoxGroupName($pagename, $fx, $name) {
global $FoxDebug; if($FoxDebug) echo " GROUPNAME>$name"; //DEBUG//
if(isset($fx['foxgroup'])) $group = $fx['foxgroup'];
else { $tname = MakePageName($pagename, $name);
return $tname;
}
if (isset($fx['target']) || isset($fx['foxcopyto'])) {
// handle 'escaped' target name: ignore foxgroup
if($name{0}=="\\") {
$name = str_replace("\\","",$name);
$tname = MakePageName($pagename, $name);
}
else {
$name = FoxWikiWord($name);
$tname = "$group.$name";
}
}
if (isset($fx['newedit'])) {
$name = FoxWikiWord($fx['newedit']);
$tname = "$group.$name";
}
return $tname;
} //}}}
## add a new entry
function FoxAddEntry($pagename, $targetname, $template, $fx) {
global $FoxDebug; if($FoxDebug) echo " ADDENTRY>"; //DEBUG//
global $FoxAuth, $EnableBlocklist;
// permission check
Lock(2);
$page = RetrieveAuthPage($targetname, $FoxAuth, true);
FoxPagePermissionCheck($pagename, 'add', $targetname, $page, $fx);
$newpage = $page;
# create new entries from $fx
$addstring = FoxTemplateEngine($targetname, $template, $fx, '', 'FoxAddEntry'); //decode the template
# placing $addstring into the page text
$foxname = $fx['foxname'];
// Handle the special names #top and #bottom
if($fx['foxplace']=='#top') { $newpage['text'] = $addstring."\n".$page['text']; }
elseif($fx['foxplace']=='#bottom') { $newpage['text'] = $page['text']."\n".$addstring; }
// Handle locations specified by 'fox prepend' and 'fox append'
else {
$textrows = explode("\n",$page['text']);
// Handle the special names #prepend or #append
// Look for (:foxappend ... or (:foxprepend ... and append or prepend the $
if(isset($fx['foxplace'])) $fp = $fx['foxplace'];
else $fp = '#bottom'; //set default for placement
if($fp=='#top'||$fp=='#bottom'||$fp=='#append'||$fp=='#prepend') $fplace = "";
else $fplace = ' '.$fp;
$formstart = '(:fox '.$foxname;
$formend = '(:foxend '.$foxname;
$app = '(:foxappend '.$foxname.$fplace.':)';
$pre = '(:foxprepend '.$foxname.$fplace.':)';
foreach ($textrows as $nr => $line) {
if(strstr($line,$formend) AND $fp=='#prepend') { $done=1; $textrows[$nr] = "$line\n".$addstring; break; }
if(strstr($line,$formstart) AND $fp=='#append') { $done=1; $textrows[$nr] = $addstring."\n$line"; break; }
if(strstr($line,$pre)) { $done=1; $textrows[$nr] = "$line\n".$addstring; break; }
if(strstr($line,$app)) { $done=1; $textrows[$nr] = $addstring."\n$line"; break; }
}
if($done==1) {
$text = implode("\n",$textrows);
$newpage['text'] = $text;
}
else { $newpage['text'] = $page['text']."\n".$addstring; } //default: append to bottom
}
// update any PTVs
if(isset($fx['ptvtarget']))
$newpage['text'] = FoxPTVUpdate($pagename, $fx, $newpage['text'] );
// save page
$FoxEditFunctions = array('ReplaceOnSave', 'SaveAttributes', 'PostPage', 'PostRecentChanges');
if($EnableBlocklist) array_unshift($FoxEditFunctions, 'CheckBlocklist');
UpdatePage($targetname, $page, $newpage, $FoxEditFunctions);
Lock(0);
return '';
} //}}}
## newedit opens page in the edit form
function FoxNewEdit($pagename, $targetname, $template, $fx) {
global $FoxDebug; if($FoxDebug) echo " NEWEDIT> "; //DEBUG//
$urlfmt = '$PageUrl?action=edit';
if (@$fx['template'] OR @$fx['foxtemplate']) {
// permission check
FoxPagePermissionCheck($pagename, 'newedit', $targetname, '', $fx);
// merging fields and template, put into Session var for use with ?action=edit&foxtemptext=1
@session_start();
$_SESSION["FoxTempPageText"] = FoxTemplateEngine($targetname, $template, $fx, '', 'FoxNewEdit');
// add special template marker before redirecting to edit
$urlfmt.= '&foxtemptext=1';
}
Redirect($targetname, $urlfmt); // open new page to edit
} //}}}
## copy template to target without template var substitutions
function FoxCopyPage($pagename, $fx, $targetname='', $tplname='') {
global $FoxDebug; if($FoxDebug) echo " COPY> "; //DEBUG//
global $FoxAuth;
$fx['foxcopy-flag'] = 1;
foreach($fx['foxcopyto'] as $k=>$tgt) {
if(!isset($fx['foxcopyfrom'][$k]))
FoxAbort($pagename, " ERROR: No Template!");
$template = FoxLoadTemplate($pagename, $fx['foxcopyfrom'][$k], $fx);
$targetname = FoxGroupName($pagename, $fx, $tgt);
// check permission, open target page
$page = RetrieveAuthPage($targetname, $FoxAuth, true);
FoxPagePermissionCheck($pagename, 'copy', $targetname, $page, $fx);
$text = $page['text'];
//check for section to replace with template
if (strstr($tgt,'#')) {
$sect = RetrieveAuthSection($pagename, $tgt, '', $FoxAuth);
$s = strlen($sect);
$t = strpos($text, $sect);
$above = substr($text,0,$t);
$b = $t + $s;
$below = substr($text,$b);
$text = $above."\n".$template."\n".$below;
}
//replace all since no section
else $text = $template;
//save target page
$newpage = $page;
$newpage['text'] = $text;
UpdatePage($targetname, $page, $newpage);
}
unset($fx['foxcopy-flag']);
//FoxMessage($pagename, "Copy Successful");
return '';
} //}}}
## get template from template page, #section, or (:foxtemplate 'string':)
function FoxLoadTemplate($pagename, $tplname, $fx) {
global $FoxDebug; if($FoxDebug) echo " TEMPLATE>$tplname"; //DEBUG//
global $FoxTemplatePageFmt;
//first check if no template is wanted
if(!isset($fx['foxcopy-flag']))
if($fx['template'][0]==="0" OR $fx['foxtemplate']==="" OR $tplname=='none')
return "";
//determine template page
if($fx['template']) {
$tplast = end($fx['template']); }
$tplist = array($tplname, $tplast, $FoxTemplatePageFmt);
foreach ((array)$tplist as $n) {
$tplpage = MakePageName($pagename, $n);
if(!$tplname) $tplname = $n;
if (PageExists($tplpage)) break;
}
//load template page
$page = ReadPage($tplpage, READPAGE_CURRENT);
if ($page)
//TextSection will process any section passed, or the whole page
$template = trim(TextSection($page['text'], $tplname),"\r\n");
//try to load template from (:foxtemplate "templatestring":)
if (!$template && $fx['foxtemplate'])
$template = html_entity_decode(stripmagic($fx['foxtemplate']));
//if all failed abort
if (!$template) {
FoxAbort($pagename, "NO TEMPLATE! Template page or string is missing! ");
}
return $template;
} //}}}
# Processes $template provided and inserts the values of $fx array.
# $linekeyseed is an optional parameter that allows the caller to specify a seed for the linekey
# that is used to identify the range in the delete-action.
# The engine returns a string with the new entries. If no markup of the form {$$name[]}
# is present in the template, the array will contain exactly one entry, where the usual text substitutions have
# been performed.
# If a {$$name[]} markup is present, $fx['name'] has to be an array. For each element of $fx['name'],
# one entry is found in the array, where all the other fields are replicated, but {name[]} is substituted
# by each element of $fx['name'].
# If more than one markups {$$name[]} are present, the outcome is undefined...
#
function FoxTemplateEngine($pagename, $template, $fx, $linekeyseed=NULL, $caller = '') {
global $FoxDebug; if($FoxDebug) echo " ENGINE> "; //DEBUG//
global $EnablePostDirectives, $EnableFoxBreakPage, $FoxPostsPerPage, $FoxBreakPageFmt, $Now;
if($template=="") return '';
// create the data to be added, from template and variables
$string = $template;
//replace \n by newlines
$string = preg_replace('/\\\\n/',"\n",$string);
// replace {$$(timestamp)} with Unix timestamp now
$string = preg_replace('/\\{\\$\\$\\(timestamp\\)\\}/e',"\$Now",$string);
// replace {$$(date:fmt)}
$string = preg_replace('/\\{\\$\\$\\(date[:\\s]+(.*?)\\)\\}/e',"date(PSS('$1'))",$string);
//replace {$$(strftime:fmt)}
$string = preg_replace('/\\{\\$\\$\\(strftime[:\\s]+(.*?)\\)\\}/e',"strftime(PSS('$1'))",$string);
//prevent posting of directives (: ... :)
if ($EnablePostDirectives==false) $fx = preg_replace('/\\(:/', "(:", $fx );
//replace {$$name} fields with values
$string = preg_replace("/\\{\\$\\$([A-Za-z][-_:.\\w]*)\\}/e","stripmagic(\$fx[PSS('$1')])",$string);
//reiterate through array of {$$name[]}
if(preg_match('/\\{\\$\\$([A-Za-z][-_:.\\w]*)\\[\\]\\}/', $string, $m)) {
list($x, $name) = $m;
$result = Array();
foreach((array)$_POST[$name] as $val)
if ($val) $result[] = preg_replace("/\\{\\$\\$([A-Za-z][-_:.\\w\\[\\]]*)\\}/", $val, $string);
}
else {
//replace {$$$...} with {$$...} for posting of forms with replacement vars
$string = preg_replace("/(\\{)(\\$)(\\$\\$[A-Za-z\\(][-_:.\\w\\[\\]\\)\\s]*\\})/","$1$3",$string);
$result = Array($string);
}
//create a unique linekeyseed, if necessary
if ($linekeyseed==NULL) $linekeyseed=time().'a'.rand(0,100000);
foreach ($result as $index => $entry) {
$linekey = $linekeyseed.'b'.$index;
//adding linekey + pagename to any foxdelete markup for unique id
$entry = str_replace('{[foxdelline button',"{[foxdelline button $linekey {\$FullName} ",$entry); // Add linekey to delete statements
$entry = str_replace('{[foxdelline',"{[foxdelline $linekey {\$FullName} ",$entry); // for link-delete
$entry = str_replace('{[foxdelrange button',"{[foxdelrange button $linekey {\$FullName} ",$entry); // Add linekey to delete statements
$entry = str_replace('{[foxdelrange',"{[foxdelrange $linekey {\$FullName} ", $entry); // for link-delete
$entry = str_replace('#foxbegin#',"#foxbegin $linekey#",$entry); //Add line-key to delete marker
$entry = str_replace('#foxend#',"#foxend $linekey#",$entry); // Add line-key to delete marker
$result[$index] = $entry;
}
return implode("\n",$result);
} //}}}
## get arguments from POST or GET
function FoxRequestArgs( $fx = NULL) {
if (is_null($fx)) $fx = array_merge($_GET, $_POST);
foreach ($fx as $name=>$value) {
if(is_array($value))
foreach($value as $k=>$val)
$fx[$name][$k] = stripmagic($val);
else $fx[$name] = stripmagic($value);
}
return $fx;
} //}}}
## call external filter functions
SDV($FoxFilterFunctions, array());
function FoxFilter($pagename, $fx) {
global $FoxDebug; if($FoxDebug) echo " FILTER> "; //DEBUG//
global $FoxFilterFunctions;
//get filter keynames
$fx['foxfilter'] = preg_split("/[\s,|]+/", $fx['foxfilter'], -1, PREG_SPLIT_NO_EMPTY);
foreach($fx['foxfilter'] as $f) {
$ffn = $FoxFilterFunctions[$f];
if (function_exists($ffn) ) {
// use specific filter
if(is_callable($ffn, false, $callable_name)) {
$fx = $callable_name($pagename, $fx);
if(!$fx) Redirect($pagename); // Filter is telling us to abort;
}
}
}
return $fx;
} //}}}
## substitute any {$$var} in fields with values
function FoxFieldSubstitutions($pagename, $fx) {
global $FoxDebug; if($FoxDebug) echo " SUBST>"; //DEBUG//
//check all fields for substitutions
foreach($fx as $name => $value) {
# Skip known ones:
if (preg_match('/^(n|foxpage|action|foxname|foxplace|foxfields|template|foxtemplate)$/i', $name)) continue;
# replace {$$name} fields with values
$fx[$name] = $value = preg_replace("/\\{\\$\\$([A-Za-z][-_:.\\w\\[\\]]*)\\}/e","stripmagic(\$fx[PSS('$1')])",$value);
# evaluate markup expressions
$fx[$name] = $value = preg_replace("/^\\{\\$\\$(\\(\\w+\\b.*?\\))\\}$/e", "MarkupExpression(\$pagename, PSS('$1'))", $value);
}
return $fx;
} //}}}
## create NAME fields from ptv_NAME fields and add NAME to ptvfields array
function FoxPTVPreProcess($pagename, $fx) {
global $FoxDebug; if($FoxDebug) echo " PTVPRE>"; //DEBUG//
foreach($fx as $n => $v) {
if(substr($n,0,4)=="ptv_") {
$n = substr($n,4);
$fx[':ptvfields'][] = $n;
$fx[$n] = $v;
}
}
return $fx;
} //}}}
## update page text variables
function FoxPTVUpdate($pagename, $fx, $text ) {
global $FoxDebug; if($FoxDebug) echo " PTVUPDATE>"; //DEBUG//
global $PageTextVarPatterns;
//PTVs to check
if(is_array($fx['ptvfields']))
foreach($fx['ptvfields'] as $n) $update[$n] = $fx[$n];
else $update = $fx; //use all fields to look for PTVs
//look through PTV patterns and replace matches
foreach($PageTextVarPatterns as $pat) {
if (!preg_match_all($pat, $text, $match, PREG_SET_ORDER)) continue;
foreach($match as $m) {
$var = $m[2]; if (!@$update[$var]) continue;
$val = $update[$var];
if (!preg_match('/s[eimu]*$/', $pat))
$val = str_replace("\n", ' ', $val);
$text = str_replace($m[0], $m[1].$val.$m[4], $text);
}
}
return $text;
} //}}}
## Delete one line or range of lines
$HandleActions['foxdelete']='FoxHandleDelete';
function FoxHandleDelete($pagename) {
global $FoxAuth;
$args = FoxRequestArgs();
# delete permission set by $FoxAuth
$page = RetrieveAuthPage($pagename, $FoxAuth, true);
FoxPagePermissionCheck($pagename, 'delete', $pagename, $page, $fx);
if (!$page) FoxAbort($pagename, "ERROR: Cannot read $page! ");
$newpage = $page;
if(isset($args['linekey'])) $key = $args['linekey']; # Retrieve the line-key
# trim text and add newline so the following regexes also work for the last line
$text = rtrim($page['text'])."\n";
$old = $text;
# Remove the line containing the delete statement with the provided line-key (if it exists)
$text = preg_replace('/^.*\\{\\[foxdelline(| button)? '.$key.' .*\\n/m',"",$text);
# Remove the range containing the delrange statement with the provided line-key (if it exists)
$text = preg_replace('/#foxbegin '.$key.'#.*?\\{\\[foxdelrange(| ?button) '.$key.' .*?#foxend '.$key.'#.*?\n/s',"",$text);
if($old==$text)
FoxAbort($pagename, "ERROR: Delete action was unsuccessful! ");
# Remove the added newline character (or any whitespace from the end)
$text = rtrim($text);
# save page
$newpage['text'] = $text;
UpdatePage($pagename, $page, $newpage);
# set up page redirection, cater for deletelink ($_GET)
if(@$args['base']) $pagename = $args['base'];
Redirect($pagename);
} //}}}
## check page posting permissions
function FoxPagePermissionCheck($pagename, $type, $targetname, $page, $fx) {
global $FoxDebug; if($FoxDebug) echo " PERMISSION>$targetname";
global $FoxConfigPageFmt, $FoxPagePermissions, $FoxAuth;
// get name patterns from FoxConfig page
$Name = PageVar($pagename, '$Name');
$Group = PageVar($pagename, '$Group');
$pn = FmtPageName($FoxConfigPageFmt, $pagename);
$fpage = ReadPage($pn, READPAGE_CURRENT);
if($fpage && preg_match_all("/^\\s*([\\*\\w][^\\s:]*):\\s*(.*)/m",$fpage['text'], $matches, PREG_SET_ORDER)) {
foreach($matches as $m) $FoxPagePermissions[$m[1]] = $m[2];
}
// name check for type against $FoxPagePermissions
$pnames = array();
foreach($FoxPagePermissions as $n => $t) {
if(strstr($t,'-'.$type)||strstr($t,'none')) { $pnames[$n]='-'.$n; continue; }
if(strstr($t,$type)||strstr($t,'all')) $pnames[$n]=$n;
}
$pnames = FmtPageName(implode(',',$pnames),$pagename);
if($pnames=='') $pnames = '-';
$namecheck = (boolean)MatchPageNames($targetname,$pnames);
// string check against string patterns
$strcheck = 0;
if(PageExists($targetname)) {
$strcheck = (boolean)( preg_match("/\\(:fox(prepend|append|allow)/", $page['text']) OR
preg_match("/\\(:fox ".$fx['foxname']." (#prepend|#append|#top|#bottom)/", $page['text']) );
}
if($namecheck==0 && $strcheck==0) FoxAbort($pagename, "PERMISSION DENIED to $type on $targetname!");
else return '';
} //}}}
## check access code, captcha, new page exists, and required fields
function FoxSecurityCheck($pagename, $fx) {
global $FoxDebug; if($FoxDebug) echo " SECURITY>";
global $FoxAuth, $FoxNameFmt, $EnableAccessCode, $EnablePostCaptchaRequired;
// if enabled check for access code match
if($EnableAccessCode AND (!(isset($fx['access'])&&($fx['access']==$fx['accesscode'])))) {
FoxAbort($pagename, "ERROR: Missing or wrong Access Code!");
}
// if enabled check for Captcha code (captcha.php is required)
if($EnablePostCaptchaRequired AND !IsCaptcha()) {
FoxAbort($pagename, "ERROR: Missing or wrong Captcha Code!");
}
// check pagecheck: if pagecheck page names exists already
if(isset($fx['pagecheck'])) {
// pagecheck=1 checks all target pages
if($fx['pagecheck'][0]==1)
$fx['pagecheck'] = $fx['target'];
foreach ($fx['pagecheck'] as $pt) {
$page = MakePageName($pagename, $pt);
if($pagename==$page) FoxAbort($pagename, "ERROR: You are not allowed to post to this page!");
if(PageExists($page) AND in_array($pt, $fx['target']))
FoxAbort($pagename, "Sorry, page \"$pt\" exists already. Please choose another page name.");
}
}
// check for 'post' from submit button and refuse empty textarea named 'text'
// ToDo: expand this to check array of mandatory fields ???
if (!isset($fx['post']) OR (isset($fx['text']) AND $fx['text']=="")) {
FoxAbort($pagename, "ERROR: No text or missing post!");
}
return $fx;
} //}}}
## make a WikiWord out of a string
function FoxWikiWord($str) {
global $FoxDebug; if($FoxDebug) echo " WIKIWORD> "; //DEBUG//
global $MakePageNamePatterns;
$str = preg_replace('/[#?].*$/', '', $str);
$nm = preg_replace(array_keys($MakePageNamePatterns),
array_values($MakePageNamePatterns), $str);
return $nm;
} //}}}
# display message (not functioning as yet)
function FoxMessage($pagename, $msg) {
global $MessagesFmt;
$MessagesFmt[] = "
$[$msg]
";
HandleBrowse($pagename);
} //}}}
## abort by displaying error message and retuning to page
function FoxAbort($pagename, $msg) {
global $MessagesFmt;
$MessagesFmt[] = "
$[$msg]
";
HandleBrowse($pagename);
exit;
} //}}}
## build javascript for simple validation that required fields have values
function FoxFormCheck($formcheck) {
$reqfields = preg_split("/[\s,|]+/", $formcheck, -1, PREG_SPLIT_NO_EMPTY);
$out = "
";
return $out;
} //}}}
## provide {$AccessCode} page variable:
$FmtPV['$AccessCode'] = rand(100, 999);
## add page variable {$FoxPostCount}, counts message items per page
$FmtPV['$FoxPostCount'] = 'FoxStringCount($pn,"#foxbegin")';
function FoxStringCount($pagename,$find) {
$page = ReadPage($pagename, READPAGE_CURRENT);
$n = substr_count($page['text'], $find);
// if ($n==0) return ''; #suppressing 0
return $n;
}
///EOF