'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.= "
\n" : "> \n"). " \n". " \n". " \n". ($place ? "\n" : ""); foreach($opt as $key => $arg) if(!is_array($arg)) $out.= " \n"; return Keep($out); } //}}} Markup('foxform','directives','/\(:fox\\s+([\\w]+)\\s?(#\\w+)*\\s*(.*?)\\s*:\)/e',"FoxFormMarkup(\$pagename, PSS('$1'), PSS('$2'), PSS('$3'))"); # Creates the HTML code for delete links {[foxdelline]}, {[foxdelrange]} # and delete butons {[foxdelline button]} and {[foxdelrange button]} function FoxDeleteMarkup($pagename, $key='dummy', $targetname="", $range, $type, $label) { global $ScriptUrl, $EnablePathInfo, $EnableFoxDeleteMsg, $FoxDeleteMsg, $FoxDeleteSummaryMsg; if ($targetname=="") $targetname = $pagename; $TargetPageUrl = PUE(($EnablePathInfo) ? "$ScriptUrl/$targetname" : "$ScriptUrl?n=$targetname"); # javascript delete message dialogue if($EnableFoxDeleteMsg==true) $onclick = "onclick='return confirm(\"{$FoxDeleteMsg}\")'"; else $onclick = ""; if($label=='') $label = '$[Delete]'; if($type=='button') { # delete button return FmtPageName("
", $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