, Copyright 2007. ## LICENSE: You can redistribute this software 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. ####################################### ### FILE MGMT ### ####################################### // Watch out for directives, they are not blocked here. function ZAPXcreate($value) { global $msg, $ZAParray, $pagename; if ($value == "") return; $createbody = ZAPtemplate('create'); if ($createbody == false) { $createbody = $ZAParray['createbody']; $createbody = str_replace('\n', "\n", $createbody); $createbody = preg_replace('/\\{\\$\\$(\\w+)\\}/e', 'ZAPfieldreplace("$1", $ZAParray)', $createbody); } // Do I need to be able to create multiple pages? That's a problem for using the target page syntax. // Really I don't think this is necessary... $p = explode(",", $value); foreach($p as $pp) { $pp = ZAPpageshortcuts($pp); if (ZAPauth($pagename, $pp, 'Targets') == false) ZAPabort("create_target" . str_replace(".", "_", $pp), "You are not authorized to create page $pp. "); if (! PageExists($pp)) ZAPsave($pp, '', $createbody, 'Pages have been created. '); else $msg["exists_$pp"] = "Page $pp already exists. Could not be created. "; } return $value; } // Do I want delete or destroy? Can't you delete by just editing page content to word delete? // This is cool for deleting entire groups. What about allowing for other delete patterns? function ZAPXdelete($value) { if ($value == "") return; global $msg, $pagename; if (substr($value, 0, 6) == "group=") { $g = substr($value, 6); $p = ListPages("/^$g\./"); } else $p = explode(",", $value); foreach($p as $pp) { $pp = ZAPpageshortcuts($pp); if(!PageExists($pp)) { $msg["not_exist_$pp"] = "Page $pp does not exist. "; continue; } elseif (ZAPauth($pagename, $pp, 'Targets') == false) ZAPabort("delete_target" . str_replace(".", "_", $pp), "You are not authorized to delete page $pp. "); else ZAPsave($pp, '', 'delete', 'Pages have been deleted. '); } return $value; } function ZAPXrename($value) { if ($value == "") return; global $pagename, $WorkDir, $msg; $p = explode("|", $value); if (substr($p[0], 0, 6) == "group=") { $g = substr($p[0], 6); $pp = ListPages("/^$g\./"); } else $pp = explode(",", $p[0]); $temppagename = $pagename; foreach($pp as $old) { $old = ZAPpageshortcuts($old); $pagename = $old; $new = ZAPpageshortcuts($p[1]); if ((ZAPauth($pagename, $old, 'Targets') == false) || (ZAPauth($pagename, $new, 'Targets') == false)) ZAPabort('rename_target', "You are not authorized to rename $old. "); if (!PageExists($new)) $x = rename("$WorkDir//$old", "$WorkDir//$new"); else $msg["exists_$old"] = "File $new already exists. "; if(!$x) $msg["not_renamed_$old"] = "File $old could not be renamed. "; if($x) $msg["renamed_$old"] = "File $old renamed. "; } $pagename = $temppagename; return $value; } $Conditions['exists'] = 'PageExists($condparm)'; $Conditions['gexists'] = 'GroupExists($condparm)'; function GroupExists($x) { $c = count(ListPages("/^$x\./")); if ($c != 0) return true; return false; } $Conditions['pagefmt'] = 'CheckFmt($condparm, "page")'; $Conditions['namefmt'] = 'CheckFmt($condparm, "name")'; function CheckFmt($x, $y) { global $pagename; if (($y == 'page') && ($x == FmtPageName('$FullName', $x))) return true; if (($y == 'name') && ($x == PageVar(MakePageName($pagename, $x), '$Name'))) return true; return false; } ####################################### ### PAGE EDITING ### ####################################### function ZAPXreplace($value) { global $msg, $ZAParray, $pagename, $EnableZAPsiteReplace; $find = substr($value, 0, strpos($value, "|")); $replace = substr($value, strpos($value, "|") + 1); if (isset($ZAParray['replacepage'])) { // Be careful here buddy, you could use this to replace text on entire site--including Site.AuthUser page... // Perhaps require EnableZAPsiteEdit so can be used with EnableZAPsiteReplace to replace all but Site pages... if ($ZAParray['replacepage'] == "site") $replacepage = ListPages(""); elseif (substr($ZAParray['replacepage'], 0, 6) == "group=") { $g = substr($ZAParray['replacepage'], 6); $replacepage = ListPages("/^$g\./"); } else $replacepage = explode(",", $ZAParray['replacepage']); } else $replacepage[0] = $pagename; foreach ($replacepage as $r) { if (! PageExists($r)) continue; // This variable needs to be documented. Allows replacement on any page. Dangerous... // Need to really think through how the permissions on this command should work. if ($EnableZAPsiteReplace != true) { if (ZAPauth($pagename, $r, 'Targets') == false) ZAPabort("replace_target" . str_replace(".", "_", $r), "You are not authorized to replace text on page $r. "); } $oldpage = ReadPage($r); if (strpos(" $oldpage[text]", $find)) { $newpage = $oldpage; $newpage['text'] = str_replace($find, $replace, $newpage['text']); UpdatePage($r, $oldpage, $newpage); $msg['replace_success'] = "Text replaced on page $r. "; } } return value; } function ZAPXedit($value, $field) { global $msg, $pagename, $ZAParray; $p = $value; if ($p == "") $p = $pagename; if (strpos($p, "#ID")) { $a = "[[" . substr($p, strpos($p, "#ID")) . "]]"; $p = substr($p, 0, strpos($p, "#ID")); } else $a = ''; $p = ZAPpageshortcuts($p); if (ZAPauth($pagename, $p, 'Targets') == false) ZAPabort('edit', "You are not authorized to edit this page. "); $editbody = ZAPtemplate('edit'); if ($editbody == false) { $editbody = $ZAParray['editbody']; $editbody = preg_replace('/\\{\\$\\$(\\w+)\\}/e', 'ZAPfieldreplace("$1", $ZAParray)', $editbody); $editbody = str_replace('\n', "\n", $editbody); } $oldpage = ReadPage($p); $newpage = $oldpage; if ($a != '') { $source = $oldpage['text']; if (strpos($source, $a) == false) ZAPabort('edit_nosection', "Edit section not found"); $before = substr($source, 0, strpos($source, $a)); $source = substr($source, strlen($before) + 4); if (strpos($source, "[[#ID")) $after = substr($source, strpos($source, "[[#ID")); if ($editbody == '') $a = ''; } $source = $editbody; $newpage['text'] = $before . $a . $source . $after; UpdatePage($p, $oldpage, $newpage); $msg['edit_success'] = "Edit changes saved. "; return $value; } ## A simple marker used for appending and prepending page insertions. Markup('zapmarker', 'inline', '/\(:zap:\)/', ''); function ZAPXinsert($value, $field) { global $msg, $pagename, $ZAParray; if (strpos($value, "(") !== false) { $p = substr($value, 0, strpos($value, "(")); $flags = substr($value, strpos(" $value", "("), - 1); } else $p = $value; if ($p == "") $p = $pagename; $p = ZAPpageshortcuts($p); if (ZAPauth($pagename, $p, 'Targets') == false) ZAPabort('insert', "You are not authorized to insert to this page. "); if (isset($ZAParray['id'])) $a = "[[#ID$ZAParray[id]]]\n"; else $a = ''; if ((isset($ZAParray['id'])) && (!isset($ZAParray['deletelink']))) $ZAParray['deletelink'] = "(:zaplink key=ID$ZAParray[id] label=delete:)(:zap edit=$pagename#ID$ZAParray[id] ID$ZAParray[id]:)"; $insertbody = ZAPtemplate('insert'); if ($insertbody == false) { $insertbody = $ZAParray['insertbody']; $insertbody = preg_replace('/\\{\\$\\$(\\w+)\\}/e', 'ZAPfieldreplace("$1", $ZAParray)', $insertbody); $insertbody = str_replace('\n', "\n", $insertbody); } if ($a != '') $insertbody = $a . $insertbody; $oldpage = ReadPage($p); $newpage = $oldpage; $source = $oldpage['text']; if ($flags != '') { if (strpos(" $flags", "top")) $source = "$insertbody\n$source"; elseif (strpos(" $flags", "prepend")) $source = str_replace('(:zap:)', "(:zap:)\n$insertbody", $source); elseif (strpos(" $flags", "append")) $source = str_replace('(:zap:)', "$insertbody\n(:zap:)", $source); else $source = "$source\n$insertbody"; } if ((strpos(" $flags", 'sort')) || (strpos(" $flags", 'trim'))) { if (strpos(" $source", "[[#ID")) $separator = "[[#ID"; else $separator = "\n"; $editlist = explode ($separator, $source); if (strpos(" $flags", 'sort')) { natcasesort($editlist); $editlist = array_unique($editlist); } if (strpos(" $flags", 'trim')) { $trim = substr($flags, strpos($flags, 'trim=') + 5); if (strpos($trim, ',')) $trim = substr($trim, 0, strpos($flags, ',')); if ($separator == '[[#ID') $trim = $trim + 1; if (count($editlist) > $trim) $editlist = array_slice($editlist, 0, $trim ); } $source = implode($separator, $editlist); } $newpage['text'] = $source; UpdatePage($p, $oldpage, $newpage); $msg['insert_success'] = "Page insertion saved. "; return $value; } $MarkupExpr['source'] = 'MkExpExtSource($args[0])'; function MkExpExtSource($p) { global $pagename, $HandleAuth; // You won't need the closing textarea in the new textarea input markup. // You could put a (: :) kind of markup here that is used to do the equivalent of keep... // For ex: {(source (:Group.Name:))}--which theoretically if doesn't conflict with ME function would unescape Group.Name // Could not be entered into a PTV because would be escaped. Have to deal with markup order stuff... if (substr($p, 0, 1) != "+") $t = ""; if ($p == '') $p = $pagename; if (strpos($p, "#ID") !== false) { $a = "[[" . substr($p, strpos($p, "#ID")) . "]]"; $p = substr($p, 0, strpos($p, "#ID")); } if (! CondAuth($p, $HandleAuth['source'])) return ''; $page = ReadPage($p); $source = $page['text']; if ($a != '') { $source = substr($source, strpos(" $source", $a) - 1); if (strpos(substr($source,5), "[[#ID")) $source = substr($source, 0, strpos(substr($source,5), "[[#ID") + 5); } // Yeah! Getting rid of this stuff... if ($t != "") return Keep(substr($source, strlen($a))); return Keep(substr("$source$t", strlen($a))); } // Big markup order problem here. Need to be able to render markup on output--so can put page variables in directive. // Also probably need a different delimiter, like ::, or a way to escape line breaks. That might be much better. // But then you have problems when you bring it back into a text box unless you unescape it back... Markup('zapsections', '<{$var}', '/\(:sectionlist (.*?):\)/e', 'SectionList("$1")'); function SectionList($x) { $args = ParseArgs($x); $data = substr(stripslashes($args['data']), 1, -1); $template = substr(stripslashes($args['fmt']), 1, -1); // Double check this to make sure it's working right. if ((! CondAuth($data, 'read')) || (! CondAuth($template, 'read'))) return ''; $template = ReadPage($template); $template = $template['text']; $data = ReadPage($data); $sections = explode("[[#ID", $data['text']); unset($sections[0]); foreach ($sections as $i => $section) { $sectionarray = ''; $lines = explode("\n", $section); $id = substr($line[0], 0, strpos($line[0], "]]")); $sectionarray['id'] = $id; foreach ($lines as $line) { // Shouldn't the delimiter for this be something used less often? Like field:: value or field= value? if (strpos($line, ": ") !== false) { $f = substr($line, 0, strpos($line, ": ")); $v = substr($line, strpos($line, ": ") + 2); $sectionarray[$f] = $v; } } $out[$i] = preg_replace('/\\{\\$\\$(\\w+)\\}/e', 'ZAPfieldreplace("$1", $sectionarray)', $template); return $out[$i]; } if (!is_array($out)) return ''; return implode('', $out); return ''; } ####################################### ### MEMBER MGMT ### ####################################### SDV($ZAPcrypt, 'zapcrypt'); function ZAPXlogin($value) { global $pagename, $ZAParray, $msg, $ZAPcrypt; $logingroup = ZAPconfig('Profiles', 'Profiles', 'Site.ZAPConfig'); $member = MakePageName($pagename, "$logingroup.$ZAParray[Member]"); $membername = substr($member, strlen($logingroup) + 1); if (($value == "auto") && (! PageExists($member))) { AuthUserId($pagename, $membername); $msg['login_success'] = "You have been successfully logged in. "; } else { $pass1 = ZAPconfig('Password', '', $member); $pass2 = $ZAParray['Password']; if (preg_match('/(^[0-9]+$)/', $pass1)) $pass2 = ZAPencode($pass2); if ((strlen($pass1) == 13) && (substr($pass1, 0, 2) == substr($ZAPcrypt, 0, 2))) $pass2 = crypt($pass2, $ZAPcrypt); if (($pass1 == $pass2) && ($pass1 != '')) { AuthUserId($pagename, $membername); $msg['login_success'] = "You have been successfully logged in as $membername."; } else ZAPabort('login_fail', "Incorrect member name or password."); } $m = ZAPconfig('Memberships', 'Memberships', 'Site.ZAPConfig'); $groups = ListPages("/^".$m."\./"); foreach ($groups as $group) { if (($group == "$m.RecentChanges") || (substr($group, strlen($m) + 1, 5) == 'Group')) continue; $p = ReadPage($group); $content = $p['text']; $groupname = "@" . substr($group, strlen($m) + 1); if (strpos(" \n$content\n", "\n$membername\n")) SessionAuth($pagename, array('authlist' => array($groupname => 1))); } return $value; } function ZAPXregister($value) { global $pagename, $ZAParray, $ZAPcrypt; if (!isset($ZAParray['Member'])) ZAPabort('register_no_member', "Member field required. "); if ($ZAParray['Member'] == "") ZAPabort('register_member_blank', "Please enter a member name. "); $logingroup = ZAPconfig('Profiles', 'Profiles', 'Site.ZAPConfig'); $member = MakePageName($pagename, "$logingroup.$ZAParray[Member]"); if (PageExists($member)) ZAPabort('register_member_exists', "Member name already taken. Please try again. "); if (!isset($ZAParray['Password'])) ZAPabort('register_no_pass', "Password field required. "); if ($ZAParray['Password'] == "") ZAPabort('register_pass_blank', "No password entered. Please try again. "); if ($ZAParray['loginfmt'] == "encrypt") $ZAParray['Password'] = crypt($ZAParray['Password'], $ZAPcrypt); elseif ($ZAParray['loginfmt'] != "plaintext") { $ZAParray['Password'] = ZAPencode($ZAParray['Password']); $ZAParray['Email'] = ZAPencode($ZAParray['Email']); } ZAPsave($member, $value, '', 'Member account created. '); return $value; } function ZAPXgroup($value, $field) { global $pagename, $msg; if ($value == '') return ''; if (strlen($field) < 7) return $value; if (substr($value, 0, 1) == "!") { $private = "!"; $value = substr($value, 1); } $value = trim($value); $value = trim($value, "\x7f..\xff\x0..\x1f"); $p = ZAPconfig('Memberships', 'Memberships', 'Site.ZAPConfig') . "." . substr($field,6); $oldgroup = ReadPage($p); $newgroup = $oldgroup; $current = str_replace("\n", ",", $newgroup['text']); if ((substr($value, 0, 1) == "+") || (substr($value, 0, 1) == "-")) { $out = ZAPcsv($value, $current); } else $out = ZAPcsv($value); $newgroup['text'] = str_replace(",", "\n", $out); UpdatePage($p, $oldgroup, $newgroup); $msg['group_success'] = "Your group memberships have been updated."; return $value; } $MarkupExpr['grouplist'] = 'ZAPMgrouplist($args[0], $args[1])'; function ZAPMgrouplist($g, $fmt) { $p = ZAPconfig('Memberships', 'Memberships', 'Site.ZAPConfig') . "." . $g; if ((! PageExists($p)) || (! CondAuth($p, 'read'))) return ''; $l = ReadPage($p); $list = str_replace("\n", ",", $l['text']); return MkExpExtList($list, $fmt); } $Conditions['group_exists'] = 'PageExists(ZAPconfig("Memberships", "Memberships", "Site.ZAPConfig") . ".$condparm")'; $Conditions['group_member'] = 'GroupMember($condparm)'; function GroupMember($x) { $args = ParseArgs($x); if (isset($args['group'])) $g = $args['group']; else $g = $args[''][0]; if (isset($args['member'])) $m = $args['member']; else $m = $args[''][1]; $group = ZAPconfig('Memberships', 'Memberships', 'Site.ZAPConfig') . ".$g"; $p = ReadPage($group); $content = $p['text']; if (strpos(" \n$content\n", "\n$m\n")) return true; return false; } ####################################### ### CODE/DECODE ### ####################################### // Note: should there be some obstacle to deciphering? It's not too terribly hard to extract the ZAPcode key... // Should rename the command to encode, to match decode... SDV($ZAPcode, '0'); function ZAPXencode($value) { global $ZAParray; $f = explode(",", $value); foreach ($f as $ff) { $ff = trim($ff); $ZAParray[$ff] = ZAPencode($ZAParray[$ff]); } return $value; } // Can only decode something on same page or $name = $authid. Admins can decode anything. // Do I need to add read permission checking to this? $MarkupExpr['decode'] = 'ZAPMdecode($args[0])'; function ZAPMdecode($p) { global $pagename; if ($p == '') return ''; $n = substr($pagename, strpos($pagename, ".") + 1); $p = PageTextVar($pagename, $p); if ((CondAuth($pagename, "admin")) || ($GLOBALS[AuthId] == $n)) $p = ZAPdecode($p); else $p = false; return $p; } function ZAPdecode($value) { global $ZAPcode; $c = - 1; for ($i = 0; $i <= strlen($ZAPcode) - 1; $i++) $code[$i] = substr($ZAPcode, $i, 1); $value = substr(chunk_split($value, 2, "-"), 0, - 1); $ch = explode("-", $value); foreach ($ch as $in) { $c = $c + 1; if ($c > strlen($ZAPcode) - 1) $c = $c - strlen($ZAPcode); $in = intval("$in"); if ($in < $code[$c]) $in = $in + 100; $out .= chr($in - $code[$c] + 32); } return $out; } function ZAPencode($value) { global $ZAPcode; $c = - 1; for ($i = 0; $i <= strlen($ZAPcode) - 1; $i++) $code[$i] = substr($ZAPcode, $i, 1); for ($i = 0; $i <= strlen($value) - 1; $i++) { $c = $c + 1; if ($c > strlen($ZAPcode) - 1) $c = $c - strlen($ZAPcode); $ch = ord(substr($value, $i, 1)) + $code[$c] - 32; if ($ch >= 100 ) $ch = $ch - 100; if ($ch < 10) $ch = "0" . "$ch"; $out .= "$ch"; } return $out; } ####################################### ### UPLOADS ATTR ### ####################################### function ZAPXupload($value, $field) { global $ZAParray, $pagename; if ($ZAParray['upname'] == "") ZAPabort('upload_no_filename', "Missing file name. Could not be uploaded. "); if ($field != "upload") return $value; ## from PmWiki's upload.php script global $UploadVerifyFunction, $UploadFileFmt, $LastModFile, $EnableUploadVersions, $Now; $auth = 'upload'; $page = RetrieveAuthPage($pagename, $auth, true, READPAGE_CURRENT); if (!$page) Abort("?cannot upload to $pagename"); $uploadfile = $_FILES['uploadfile']; $upname = $_REQUEST['upname']; if ($upname=='') $upname=$uploadfile['name']; $upname = MakeUploadName($pagename,$upname); if (!function_exists($UploadVerifyFunction)) Abort('?no UploadVerifyFunction available'); $filepath = FmtPageName("$UploadFileFmt/$upname",$pagename); $result = $UploadVerifyFunction($pagename,$uploadfile,$filepath); if ($result=='') { $filedir = preg_replace('#/[^/]*$#','',$filepath); mkdirp($filedir); if (IsEnabled($EnableUploadVersions, 0)) @rename($filepath, "$filepath,$Now"); if (!move_uploaded_file($uploadfile['tmp_name'],$filepath)) { Abort("?cannot move uploaded file to $filepath"); return $value; } fixperms($filepath,0444); if ($LastModFile) { touch($LastModFile); fixperms($LastModFile); } $result = "upresult=success"; } if ($ZAParray['nextpage'] != $pagename) return $value; else Redirect($pagename,"{\$PageUrl}?action=upload&uprname=$upname&$result"); return $value; } // I wonder if these next two functions should be made more extensible. Seems kind of hardcoded. function ZAPXattr($value, $field) { global $msg, $pagename, $ZAParray; if ($value == '') $value = $pagename; if (ZAPauth($pagename, $value, 'Targets') == false) ZAPabort('attr_target', "You are not authorized to modify these attributes. "); $oldpage = ReadPage($value); $newpage = $oldpage; foreach ($ZAParray as $f => $v) { if ((CondAuth($ZAParray['datapage'], "attr")) && (substr($f, 0, 6) == 'passwd')) { $newpage[$f] = $v; $msg['passwd_updated'] = substr($f, 6) . " password has been updated. "; } if (($f == 'title') || ($f == 'keywords') || ($f == 'description')) { if (strpos($newpage[text], "(:$f ") != false) $newpage['text'] = preg_replace('/\\(:'.$f.' (.*?):\\)/s', "(:$f $v:)", $newpage['text']); else $newpage['text'] = $newpage['text'] . "\n(:$f $:)"; $msg['attr_updated'] = "Page $f has been updated. "; } } UpdatePage($value, $oldpage, $newpage); return $value; } $FmtPV['$Keywords'] = 'MkExpExtAttr("keywords", $pagename)'; $FmtPV['$PasswdRead'] = 'MkExpExtAttr("passwdread", $pagename)'; $FmtPV['$PasswdEdit'] = 'MkExpExtAttr("passwdedit", $pagename)'; function MkExpExtAttr($attr, $page) { global $pagename; if ((!CondAuth($pagename, "admin")) && (substr($attr, 0, 6) == "passwd")) return; if (($attr == 'keywords') || (substr($attr, 0, 6) == "passwd")) { if ($page == '') $page = $pagename; $page = ReadPage($page); return $page[$attr]; } return ''; } ####################################### ### GRADE COMMAND ### ####################################### function ZAPXgrade($value, $field) { if (substr($field, -3) == "fmt") return $value; global $ZAParray, $pagename; $quiz = substr($field, 6); $quizarray = $ZAParray; foreach ($quizarray as $f => $v) { if (($f == $quiz . "_fmt") || ($f == $quiz . "_total")) continue; if (strpos($v, ",")) { $vv = explode(",", $v); $v = array_sum($vv); } if (substr($f, 0, strlen($quiz)) == $quiz) { if (strpos($v, "|")) { $ZAParray[$f] = substr($v, strpos($v, "|") + 1); $v = substr($v, 0, strpos($v, "|") + 1); } $sum = $sum + $v; } } $ZAParray[$field] = floor(100 * $sum / $ZAParray[$quiz . "_total"]); if (isset($ZAParray[$field . "fmt"])) { $g = explode(",", $ZAParray[$quiz . "_fmt"]); foreach ($g as $gg) { if ($ZAParray[$field] >= substr($gg, 0, strpos($gg, "="))) { $ZAParray[$field . "fmt"] = substr($gg, strpos($gg, "=") + 1); } else break; } } return $ZAParray[$field]; } ####################################### ### PHP MATH WIKI ### ####################################### // Check to make sure comparable to functions in ME recipe // No error trapping possible it seems... SDV($ZAPphp, 'substr,strpos,strtotime,strftime,time,date,crypt,rand,strlen,strtolower,strtoupper,ucfirst,ucwords'); function ZAPXphp($value, $field) { global $ZAPphp, $ZAParray; $command = substr($value, 0, strpos($value, "|")); $value = substr($value, strpos($value, "|") + 1); if (strpos($value, ")")) ZAPabort('php', "Invalid submission for field \"$field\". "); $c = explode(",", $ZAPphp); if (in_array($command, $c)) eval("\$value = $command($value);"); return $value; } $FmtPV['$Now'] = "'" . time() . "'"; $FmtPV['$ReturnLink'] = "'" . substr($_SERVER[HTTP_REFERER], strpos($_SERVER[HTTP_REFERER], "?n=") + 3) . "'"; $FmtPV['$Browser'] = "'" . $_SERVER[HTTP_USER_AGENT] . "'"; $FmtPV['$IPAddress'] = "'" . $_SERVER[REMOTE_ADDR] . "'"; $FmtPV['$DomainName'] = "'" . $_SERVER[SERVER_NAME] . "'"; SDV($ZAPmath, "/^[-+*\\/% ()0-9.]+$/"); function ZAPXmath($value, $field) { global $ZAParray, $ZAPmath; // Seems you could add some functions by defining a few, doing an array string replacement of various codes, // check the pattern, replace the stuff and then evaluate. if (! preg_match($ZAPmath, $value)) ZAPabort('math', "Invalid numeric input. "); eval("\$r = $value;"); return $r; } $MarkupExpr['math'] = 'MkExpExtMath($args[0])'; function MkExpExtMath($p) { global $ZAPmath; if ($p == '') return; // Why not add a math function which could be shared for both this and the one above... Esp if making more complex if (!preg_match($ZAPmath, $p)) return; eval("\$r = $p;"); return $r; } // This needs to be replaced with the (:: ::) markup to evaluate directives. Much cleaner and cooler. $MarkupExpr['wiki'] = 'MkExpExtWiki(preg_replace($rpat, $rrep, $params))'; SDV($MkExpExtDirectives, 'table,tableend,cell,cellnr,include,if,pagelist,input,messages,redirect,title'); SDV($MkExpExtZap, false); function MkExpExtWiki($p) { global $MkExpExtDirectives, $MkExpExtZap; $p = substr($p, 1); $c = substr($p, 0, strpos($p, " ")); $p = substr($p, strpos($p, " ")); $pmlist = explode(",", $MkExpExtDirectives); if (in_array($c, $pmlist)) return stripslashes("(:$c $p:)"); if ((substr($c, 0, 3) == 'zap') && ($MkExpExtZap == true)) return stripslashes("(:$c $p:)"); return false; } ####################################### ### COUNT THREAD CAPTCHA ### ####################################### $MarkupExpr['count'] = 'MkExpExtCount($args[0], $args[1])'; SDV($MkExpExtExclude, 'RecentChanges,GroupHeader,GroupFooter,GroupAttributes,SideBar,SideMenu'); function MkExpExtCount($g, $x) { global $MkExpExtExclude, $pagename; if ($g == '') $g = substr($pagename, 0, strpos($pagename, ".")); if ($x != '') $MkExpExtExclude .= "," . $x; $count = count(ListPages("/^$g\./")); if (substr($MkExpExtExclude, -3) == "all") return $count; $ex = explode(",", $MkExpExtExclude); foreach($ex as $exx) { if (PageExists("$g.$exx")) $count = $count - 1; } return $count; } $MarkupExpr['thread'] = 'MkExpExtThread($args[0])'; function MkExpExtThread($g) { global $ZAPthreadstart, $pagename; if ($g == '') $g = substr($pagename, 0, strpos($pagename, ".")); return ZAPthread($g); } // random or rand? Is strpos in there already? $MarkupExpr['strpos'] = 'strpos($args[0], $args[1])'; $MarkupExpr['random'] = 'rand($args[0], $args[1])'; $FmtPV['$Captcha'] = "'" . rand(1000,9999) . "'"; ####################################### ### LIST MGMT STUFF ### ####################################### $MarkupExpr['list'] = 'MkExpExtList($args[0], $args[1])'; function MkExpExtList($l, $x) { if ($l == '') return; $ll = explode(",", $l); $xx = explode("^", $x); foreach($ll as $lll) $list .= str_replace('{item}', $lll, $xx[0]) . $xx[1]; $list = substr($list, 0, - strlen($xx[1])); return $list; } // It would be nice to combine these next two conidtions into one. // If a page is given (no "," and 1 "."), it would be a line on a page // If a CSV list given (or no "." for one item lists) check as if a CSV $Conditions['inlist'] = 'InList($condparm)'; function InList($x) { global $pagename; $xx = explode("|", $x); if(!isset($xx[2])) $xx[2] = $pagename; $l = explode(",", PageTextVar($xx[2], $xx[1])); foreach ($l as $ll) { if (strcmp($ll, $xx[0]) == 0) return true; } return false; } $Conditions['innewslist'] = 'InNewsList($condparm)'; function InNewsList($x) { global $pagename; $xx = explode(" ", $x); $NewsList = ReadPage(ZAPconfig('Newslist', 'NewsList', 'Site.ZAPConfig') . ".$xx[0]"); $l = explode("\n", $NewsList['text']); foreach ($l as $ll) { if (strcmp($ll, $xx[1]) == 0) return true; } return false; } ####################################### ### MAIL MODULE ### ####################################### SDV($ZAPmailmode, false); function ZAPXemail($value, $field) { global $pagename, $ZAParray, $ZAPmailmode, $msg; if ($ZAPmailmode != true) $msg['mailmode'] = "ZAPmail is currently in test mode. "; if ((!isset($ZAParray[emailfrom])) || ($ZAParray[emailfrom] == "")) ZAPabort('email_return', "No return address entered. Email not sent. "); if ((!isset($ZAParray[emailsubject])) || ($ZAParray[emailsubject] == "")) ZAPabort('email_subject', "No email subject entered. Email not sent. "); $ZAParray['email'] = "{$$email}"; $emailbody = ZAPtemplate('email'); if ($emailbody == false) $emailbody = $ZAParray['emailbody']; if ($emailbody == '') ZAPabort('email_body', "No message found. Email not sent. "); if ($field == 'email') { $emails = $value; $newslist = str_replace(",", "\n", $emails); } // I still want to make profile merging possible -- either here or in scheduler... if (($field == 'email_list') || ($field == 'email_members')) { if ($field == 'email_list') $msg['email_list_upgrade'] = "Please upgrade email_list to email_members. "; $emails = $value; foreach (explode(",", $emails) as $i => $ii) { $getemail[$i] = PageTextVar(ZAPconfig('EmailList', 'Profiles', 'Site.ZAPConfig') . ".$ii", "Email"); if (preg_match('/(^[0-9]+$)/', $getemail[$i])) $getemail[$i] = ZAPdecode($getemail[$i]); } $emails = implode(",", $getemail); $newslist = str_replace(",", "\n", $emails); } if ($field == 'email_news') { if (!PageExists(ZAPconfig('Newslist', 'NewsList', 'Site.ZAPConfig') . ".$value")) ZAPabort('email_no_list', "Mailing list $value not found. Mail not sent."); $newslist = ReadPage(ZAPconfig('Newslist', 'NewsList', 'Site.ZAPConfig') . ".$value"); $newslist = $newslist['text']; $emails = str_replace("\n", ",", $emails); } if (isset($ZAParray['emailstart'])) { if (!isset($ZAParray['emailthrottle'])) $ZAParray['emailthrottle'] = "600"; if (!isset($ZAParray['emailbatch'])) $ZAParray['emailbatch'] = "25"; if ($ZAParray['emailstart'] == '') $ZAParray['emailstart'] = time(); if ($ZAParray['emailstart'] - time() > 40000000) ZAPabort('email_schedule', "Invalid start time. Newsletter not sent. "); $emailqueue = $newslist . "\n\n^$ZAParray[emailbatch]^$ZAParray[emailthrottle]^$ZAParray[emailstart]^$ZAParray[emailfrom]^$ZAParray[emailsubject]^\n\n$emailbody"; ZAPsave(ZAPconfig('NewsQueue', 'NewsQueue', 'Site.ZAPConfig') . ".$ZAParray[emailstart]", '', $emailqueue); $msg['email_queue'] = "Message sent to queue. "; return; } else { $address = explode(",", $emails); foreach($address as $i => $to) { if (! ereg("^.+@.+\..+$", $to)) $msg["email_invalid_$i"] = "Invalid email address: $to "; else { $mergedbody = str_replace("{email}", $to, $emailbody); if ($ZAPmailmode != true) $msg["email_success_$i"] = "<>Mail sent to $to <> $mergedbody "; else { mail($to, $ZAParray[emailsubject], $mergedbody, "From: $ZAParray[emailfrom]"); $msg["email_success_$i"] = "Email successfully sent to $to. "; } } } } return $value; } Markup('zapmail', '>{$var}', '/\(:zapmail(.*?):\)/ei', "ZAPmailqueue('$1')"); function ZAPmailqueue($x) { global $WorkDir, $WikiDir, $ZAPmailmode; if(is_dir("lock")) return; @ignore_user_abort(true); mkdir("lock"); $g = ZAPconfig('NewsQueue', 'NewsQueue', 'Site.ZAPConfig'); $t = time(); $lp = ListPages("/^$g\\.\\d/"); foreach($lp as $p) { $pn = substr($p, strpos($p, ".") + 1); if($pn < $t) { $oldqueue = ReadPage($p); $newqueue = $oldqueue; $n = explode("^", $oldqueue[text]); $list = substr($n[0], 0, -2); $to = explode("\n", $list); $batch = $n[1]; $throttle = $n[2]; $id = $n[3]; $from = $n[4]; $subject = $n[5]; $body = substr(str_replace("%0a", "\n", $n[6]), 2); $count = 0; $oldlog = ReadPage("$g.LOG-$id"); $newlog = $oldlog; if ($newlog['text'] == "") $newlog['text'] = "Subject: $subject\n\nSent: " . strftime("%c", $id) . "\n\n"; while($count < $batch) { if (! isset($to[$count])) break; if (ereg("^.+@.+\..+$", $to[$count])) { if ($ZAPmailmode == true) { $mergedbody = str_replace("{$$email}", "$to[$count]", $body); mail($to[$count], $subject, $mergedbody, "From: $from"); } $newlog[text] .= "SENT " . $to[$count] . " at " . strftime("%c", time()) . " \\\\\n"; } $count = $count + 1; } if (count($to) > $batch) { $to = array_slice($to, $batch); $n[0] = implode("\n", $to) . "\n\n"; $newqueue[text] = implode("^", $n); $pp = bcadd($pn, $throttle); $page = "$g.$pp"; UpdatePage($page, $oldqueue, $newqueue); } else $newlog['text'] .= "\n\nSending Complete!"; $page = "$g.LOG-$id"; UpdatePage($page, $oldlog, $newlog); $WikiDir->delete("$p"); } } rmdir("lock"); return; } ####################################### ### SHOPPING CART ### ####################################### Markup('zapcart', ' \n\n"; $orderhead = $ZAPorderhead; $in = array('$itemlabel', '$itemqty', '$iteminfo', '$itemname', '$itemprice', '$itemcost'); $cart = explode("(:", $contents); foreach ($cart as $item) { $itemlabel = substr($item, 0, strpos($item, ":")); $itemqty = substr($item, strpos($item, ': ') + 2, strpos($item, ':)') - strpos($item, ': ') - 2); if(!is_numeric($itemqty)) continue; $iteminfo = ZAPconfig($itemlabel, '', "Site.ZAPCart"); if ($iteminfo == '') continue; $itemname = substr($iteminfo, 0, strpos($iteminfo, "|")); $itemprice = substr($iteminfo, strpos($iteminfo, "|") + 1); $itemcost = $itemqty * $itemprice; $itemcost = number_format($itemcost, 2); $itemlist .= ",$itemlabel"; $costlist .= ",$itemprice"; $out = array($itemlabel, $itemqty, $iteminfo, $itemname, $itemprice, $itemcost); if ($flag == 'order') $orderrows .= str_replace($in, $out, $ZAPorderrows) . "\n"; else $orderrows .= str_replace($in, $out, $ZAPconfirmrows) . "\n"; } if ($orderrows == "") return $error[no_items]; $itemlist = substr($itemlist, 1); $FmtPV['$itemlist'] = "'" . $itemlist . "'"; $costlist = substr($costlist, 1); $in = array('$itemlist', '$costlist', '$usorder', '$subtotal', '$shipping', '$total'); $out = array($itemlist, $costlist, $_POST['usorder'], ZAPconfig('subtotal', '', $o), ZAPconfig('shipping', '', $o), ZAPconfig('total', '', $o)); if ($flag == 'order') $orderfoot .= str_replace($in, $out, $ZAPorderfoot); else $orderfoot .= str_replace($in, $out, $ZAPconfirmfoot); return "$orderhead$orderrows$orderfoot"; } else return "
There was an error processing your order.
"; return $error[invalid_form]; } SDV($ZAPorderhead, ''); SDV($ZAPorderrows, ''); SDV($ZAPconfirmrows, ''); SDV($ZAPorderfoot, '
$itemname at$$itemprice
$itemname $itemqtyat$$itemprice $$itemcost
Subtotal
U.S. Order?
Yes No
Shipping & Handling
'); SDV($ZAPconfirmfoot, 'Subtotal $subtotal Shipping & Handling $shipping Total $total '); function ZAPpay($x) { global $PubDirUrl; if ($x == '') $img = "$PubDirUrl/paypal.gif"; else $img = "$PubDirUrl/" . substr($x, 1); return ""; } function ZAPpaypal($x) { global $ZAPpaypal, $ScriptUrl; $arg = ParseArgs($x); if ($arg['total'] == '') $arg['total'] = $_POST['total']; if (substr($arg['total'], 0, 1) == "$") $arg['total'] = substr($arg['total'], 1); $arg['total'] = str_replace('/', '.', $arg['total']); $in = array('$email', '$returnurl', '$id', '$amount'); $out = array($arg['email'], "$ScriptUrl?n=$arg[returnurl]", $arg['id'], $arg['total']); $paypal .= str_replace($in, $out, $ZAPpaypal); return $paypal; } SDV($ZAPpaypal, '
Please Be Patient


While we contact PayPal
'); SDV($ZAPcalculate, "function calculate() { var items = document.paypal.itemlist.value; item_a = Array(); item_a = items.split(','); var costs = document.paypal.costlist.value; cost_a = Array(); cost_a = costs.split(','); var x=0; var xsub=0; var xship=0; var xtotal=0; var xamount=0; for (i=0; i=100) && (xintl==0)) { xship = 0.00; document.paypal.shipping.value='Free'; } if (xintl==10) { xship = parseInt(xsub) * 20 / 100; if (xship<10) {xship=10} xship = currency(xship); shipstring = '$' + xship; document.paypal.shipping.value=shipstring; } return xship; }");