Mercurial > hg > fapweb
view msitegen.inc.php @ 1060:280de0770798
Added signature for changeset c0e21a405256
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Wed, 10 Feb 2016 16:18:46 +0200 |
parents | 0603012e99b7 |
children | 5f92fa5e683a |
line wrap: on
line source
<? // // FAPWeb - Simple Web-based Demoparty Management System // Generic and miscellaneous site support code // (C) Copyright 2012-2015 Tecnic Software productions (TNSP) // // Globals and definitions $errorSet = FALSE; $errorMsgs = array(); $statusSet = 0; $statusMsg = ""; // Value types define("VT_STR", 1); define("VT_INT", 2); define("VT_BOOL", 3); define("VT_TEXT", 4); // Validation check types define("CHK_TYPE", 1); define("CHK_ISLT", 2); define("CHK_ISGT", 3); define("CHK_ISEQ", 4); define("CHK_GTEQ", 5); define("CHK_LTEQ", 6); define("CHK_RANGE", 7); define("CHK_CUSTOM", 8); define("CHK_ARRAY_KEY", 9); define("CHK_ARRAY_VAL", 10); function stDebug($msg) { if (stGetSetting("debug")) error_log("FAPWeb[D]: ".$msg); } function stLogError($msg) { error_log("FAPWeb[E]: ".$msg); return FALSE; } function stLogSQLError($dbh, $sql) { return stLogError("SQL error '".implode("; ", $dbh->errorInfo())."' in statement: \"".$sql."\""); } function stError($msg) { global $errorSet, $errorMsgs; $errorSet = TRUE; $errorMsgs[] = $msg; return FALSE; } function stSetStatus($status, $msg) { global $statusSet, $statusMsg; $statusMsg = $msg; $statusSet = $status; } function stDumpAJAXStatusErrors() { global $errorSet, $errorMsgs, $statusSet, $statusMsg; if ($errorSet && !$statusSet) stSetStatus(902, "Error"); if ($statusSet) { header("HTTP/1.0 ".$statusSet." ".$statusMsg); header("Status: ".$statusSet." ".$statusMsg); } if ($errorSet) { echo "<h1>Following errors occured</h1>\n". "<ul>\n"; foreach ($errorMsgs as $msg) echo " <li>".chentities($msg)."</li>\n"; echo "</ul>\n"; } } function stCheckHTTPS() { return isset($_SERVER["HTTPS"]) && ($_SERVER["HTTPS"] != "" && $_SERVER["HTTPS"] != "off"); } function stSetupCacheControl() { header("Cache-Control: must-revalidate, no-store, private"); header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past } function stGetSQLSettingData($item) { switch ($item["vtype"]) { case VT_INT: return intval($item["vint"]); case VT_BOOL: return intval($item["vint"]) ? true : false; case VT_STR: return $item["vstr"]; case VT_TEXT: return $item["vtext"]; } } function stGetSettingSQL($item, $val) { global $db; switch ($item["vtype"]) { case VT_INT: return "vint=".intval($val); break; case VT_BOOL: return "vint=".($val ? "1" : "0"); break; case VT_STR: return "vstr=".$db->quote($val); break; case VT_TEXT: return "vtext=".$db->quote($val); break; default: return FALSE; } } function stReloadSettings() { global $siteSettings; if (($res = stExecSQL("SELECT * FROM settings")) !== FALSE) { foreach ($res as $item) $siteSettings[$item["key"]] = stGetSQLSettingData($item); } else die("Error fetching site settings."); } function stGetSetting($name, $default = FALSE) { global $siteSettings; if (isset($siteSettings[$name])) return $siteSettings[$name]; else if ($default !== FALSE) return $default; else { stLogError("No config value for '".$name."'"); die("No config value for '".$name."'.\n"); } } function stChkSetting($name) { global $siteSettings; return isset($siteSettings[$name]) && $siteSettings[$name]; } function dhentities($str) { return str_replace(array("<",">"), array("<", ">"), htmlentities($str, ENT_NOQUOTES, "UTF-8")); } function chentities($str) { return htmlentities($str, ENT_NOQUOTES, "UTF-8"); } function ihentities($str) { return htmlentities($str, ENT_QUOTES, "UTF-8"); } // // Helper functions for form/HTML elements // XXX/TODO .. this name/id/prefix mess needs to be cleaned up. // function stGetIDName($name, $id, $prefix = "") { return ($id != "" ? "id=\"".$prefix.$name.$id."\" " : ""). ($name != "" ? "name=\"".$prefix.$name.$id."\" " : ""); } function stGetFormCheckBoxInput($name, $id, $prefix, $checked, $label, $extra = "") { return "<input ".$extra." type=\"checkbox\" ".stGetIDName($name, $id, $prefix). ($checked ? "checked=\"checked\" " : "")." />". ($label != "" ? "<label for=\"".$prefix.$name.$id."\">".$label."</label>" : ""); } function stGetFormRadioButtonInput($name, $id, $prefix, $value, $checked, $label, $extra = "") { return "<input ".$extra." type=\"radio\" ".stGetIDName($name, $id, $prefix). ($checked ? "checked=\"checked\" " : "")." value=\"".$value."\" />". ($label != "" ? "<label for=\"".$prefix.$name.$id."\">".$label."</label>" : ""); } function stGetFormButtonInput($name, $id, $prefix, $label, $onclick = "") { return "<input type=\"button\" ".stGetIDName($name, $id, $prefix). "value=\" ".ihentities($label)." \" ". ($onclick != "" ? "onClick=\"".$onclick."\"" : "")." />"; } function stGetFormButtonElement($name, $id, $prefix, $label, $onclick = "") { return "<button class=\"button\" ".stGetIDName($name, $id, $prefix)." type=\"button\"". ($onclick != "" ? " onClick=\"".$onclick."\"" : "")."> ".chentities($label)." </button>"; } function stGetFormTextArea($rows, $cols, $name, $id, $prefix, $value, $extra = "") { return "<textarea ".$extra." ".stGetIDName($name, $id, $prefix). "rows=\"".$rows."\" cols=\"".$cols."\">". (isset($value) ? ihentities($value) : ""). "</textarea>"; } function stGetFormTextInput($size, $len, $name, $id, $prefix, $value, $extra = "") { return "<input ".$extra." type=\"text\" ".stGetIDName($name, $id, $prefix). "size=\"".$size."\" maxlength=\"".$len."\"". (isset($value) ? " value=\"".ihentities($value)."\"" : ""). " />"; } function stGetFormPasswordInput($name, $id, $prefix, $extra = "") { return "<input type=\"password\" ".stGetIDName($name, $id, $prefix)." ".$extra." />"; } function stGetFormSubmitInput($name, $label, $onclick = "") { return "<input type=\"submit\" name=\"".$name. "\" value=\" ".ihentities($label)." \" ". ($onclick != "" ? "onClick=\"".$onclick."\"" : "")." />"; } function stGetFormHiddenInput($name, $value) { return "<input type=\"hidden\" name=\"".$name. "\" value=\"".ihentities($value)."\" />"; } function stGetFormStart($name, $action = FALSE, $method = FALSE, $extra = FALSE) { $str = "<form name=\"".$name."\"". ($action !== FALSE ? " action=\"".$action."\"" : ""). " method=\"".($method !== FALSE ? $method : "post")."\"". ($extra !== FALSE ? " ".$extra : "").">\n"; if (($csrfID = stGetSessionItem("csrfID", FALSE)) !== FALSE) $str .= stGetFormHiddenInput("csrfID", $csrfID)."\n"; return $str; } function stGetFormOptionListStart($id, $indent, $outer, $size = 10, $onChange = "") { return ($outer ? $indent."<div id=\"".$id."\">\n" : ""). $indent."<select class=\"selectBox\" id=\"".$id."Sel\"". ($size > 0 ? " size=\"".$size."\"" : ""). ($onChange != "" ? " onChange=\"".$onChange."\"" : "").">\n"; } function stGetFormOptionListItem($indent, $value, $active, $name) { return $indent."<option value=\"".$value."\"". ($active ? " selected=\"selected\"" : ""). ">".str_replace(" ", " ", chentities($name))."</option>\n"; } function stGetFormOptionListEnd($indent, $outer) { return $indent."</select>\n". ($outer ? $indent."</div>\n" : ""); } function stGetFormOptionListFromArray($id, $indent, $outer, $data, $active, $size = 10, $arrIndex = 0, $onChange = "") { $str = stGetFormOptionListStart($id, $indent, $outer, $size, $onChange); foreach ($data as $key => $value) { $str .= stGetFormOptionListItem($indent." ", $key, ($key == $active), is_array($value) ? $value[$arrIndex] : $value); } return $str.stGetFormOptionListEnd($indent, $outer); } function stErrorStrF($fmt) { $argc = func_num_args(); $argv = func_get_args(); $len = strlen($fmt); $str = ""; $argn = 1; for ($pos = 0; $pos < $len; $pos++) { if ($fmt[$pos] == "%") { $pos++; if ($fmt[$pos] == "%") $str .= "%"; else { $n = intval($fmt[$pos]); if ($n >= 1 && $n < $argc) $str .= $argv[$n]; else { stLogError("Invalid stErrorStrF() format string, arg #".$n. " referenced, but only has ".$argc." arguments: '".$fmt."'\n"); return FALSE; } } } else $str .= $fmt[$pos]; } stError($str); return FALSE; } // // Check and validate one item from $_REQUEST[], based on // list of validation conditions. For example: // // stChkRequestItem("name", FALSE, // array(CHK_ISGT, VT_STR, 0, "Handle / name not given."), // array(CHK_ISGT, VT_STR, 3, "Handle / name too short, should be 3 characters or more."), // array(CHK_LTEQ, VT_STR, SET_LEN_USERNAME, "Handle / name is too long, should be less than ".SET_LEN_USERNAME." characters."), // array(CHK_RANGE, VT_STR, array(3, SET_LEN_USERNAME), "Ulululu!"), // ^- ranges specified as array of MIN and MAX values (inclusive) // // array(CHK_CUSTOM, VT_STR, function($value) { return FALSE; }, "Error! Error!"), // ^- can be any callable/anonymous function etc. // ... // function stChkRequestDataItem($type, $value, $cmp) { switch ($type) { case CHK_ISLT : return $value < $cmp; case CHK_ISGT : return $value > $cmp; case CHK_ISEQ : return $value == $cmp; case CHK_LTEQ : return $value <= $cmp; case CHK_GTEQ : return $value >= $cmp; case CHK_RANGE: if (!is_array($cmp)) return FALSE; else return ($value >= $cmp[0] && $value <= $cmp[1]); break; default: return FALSE; } } function stDoCheckRequestItem($name, &$sdata, $nindex, $argc, $argv) { if (stGetSetting("debug")) { if (!isset($_REQUEST[$name])) return stErrorStrF("Required data item '%1' not set.", $name); $data = trim($_REQUEST[$name]); } else { if (!isset($_POST[$name])) return stErrorStrF("Required data item '%1' not set.", $name); $data = trim($_POST[$name]); } $slen = strlen($data); // Go through list of validation checks for ($argn = $nindex; $argn < $argc; $argn++) { // Act according to check type $check = $argv[$argn]; switch ($check[0]) { case CHK_TYPE: // Check type of the data switch ($check[1]) { case VT_STR: if ($slen == 0) return stErrorStrF($check[2], $slen); break; case VT_INT: case VT_BOOL: if ($slen == 0 || !is_numeric($data)) return stErrorStrF($check[2], $data); else $data = intval($data); break; } break; case CHK_ISLT: case CHK_ISGT: case CHK_ISEQ: case CHK_GTEQ: case CHK_LTEQ: case CHK_RANGE: // Check length or value of the data switch ($check[1]) { case VT_STR: case VT_TEXT: // Strings get their length checked if (!stChkRequestDataItem($check[0], $slen, $check[2])) return stErrorStrF($check[3], $slen, $check[2]); break; case VT_INT: case VT_BOOL: // Integer values checked against .. value if (!stChkRequestDataItem($check[0], intval($data), $check[2])) return stErrorStrF($check[3], intval($data), $check[2]); break; } break; case CHK_ARRAY_KEY: if (!isset($check[1][$data])) return stErrorStrF($check[2], $data); break; case CHK_ARRAY_VAL: if (!in_array($data, $check[1], TRUE)) return stErrorStrF($check[2], $data); break; case CHK_CUSTOM: // Call a custom function (or closure) $func = $check[1]; if (!is_callable($func) || !$func($data)) return stErrorStrF($check[2], $data); break; } } if ($sdata !== FALSE) $sdata = $data; return TRUE; } function stChkRequestItem($name, &$sdata) { return stDoCheckRequestItem($name, $sdata, 2, func_num_args(), func_get_args()); } function stChkRequestItemFail($name, &$sdata, &$sfail) { $sres = stDoCheckRequestItem($name, $sdata, 3, func_num_args(), func_get_args()); if ($sres !== TRUE) $sfail = FALSE; return $sres; } function stTrimIfString($val) { if (is_string($val)) return trim($val); else return $val; } function stGetRequestItem($name, $default = "", $allowGet = FALSE) { if ($allowGet || stGetSetting("debug")) return isset($_REQUEST[$name]) ? stTrimIfString($_REQUEST[$name]) : $default; else return isset($_POST[$name]) ? stTrimIfString($_POST[$name]) : $default; } function stConnectSQLDBSpec($dbspec) { try { $dbh = new PDO($dbspec); } catch (PDOException $e) { stLogError("Could not connect to SQL database: ".$e->getMessage()."."); return FALSE; } return $dbh; } function stDBGetSQLParam($dbh, $type, $value) { switch ($type) { case "d": return intval($value); case "s": return $dbh->quote($value); case "b": return intval($value) ? 1 : 0; case "D": return intval(stGetRequestItem($value)); case "S": return $dbh->quote(stGetRequestItem($value)); case "Q": return $dbh->quote(stGetRequestItem($value)); case "B": return intval(stGetRequestItem($value)) ? 1 : 0; } } function stConnectSQLDB() { global $db; try { $db = new PDO(stGetSetting("sqlDB"), stGetSetting("sqlUsername", NULL), stGetSetting("sqlPassword", NULL), stGetSetting("sqlOptions", array())); } catch (PDOException $e) { stLogError("Could not connect to SQL database: ".$e->getMessage()."."); return FALSE; } $db = stConnectSQLDBSpec(stGetSetting("sqlDB")); return ($db !== false); } function stDBPrepareSQLUpdate($dbh, $table, $cond, $pairs) { $sql = array(); foreach ($pairs as $name => $attr) { $sql[] = $name."=".stDBGetSQLParam($dbh, $attr, $name); } return "UPDATE ".$table." SET ".implode(",", $sql). ($cond != "" ? " ".$cond : ""); } function stDBPrepareSQL($dbh) { $argc = func_num_args(); $argv = func_get_args(); $fmt = $argv[1]; $len = strlen($fmt); $sql = ""; $argn = 2; for ($pos = 0; $pos < $len; $pos++) { if ($fmt[$pos] == "%") { if ($argn < $argc) $sql .= stDBGetSQLParam($dbh, $fmt[++$pos], $argv[$argn++]); else { stLogError("Invalid SQL statement format string '".$fmt. "', not enough parameters specified (".$argn." of ".$argc.")"); return FALSE; } } else $sql .= $fmt[$pos]; } return $sql; } function stPrepareSQL() { global $db; $argc = func_num_args(); $argv = func_get_args(); $fmt = $argv[0]; $len = strlen($fmt); $sql = ""; $argn = 1; for ($pos = 0; $pos < $len; $pos++) { if ($fmt[$pos] == "%") { if ($argn < $argc) $sql .= stDBGetSQLParam($db, $fmt[++$pos], $argv[$argn++]); else { stLogError("Invalid SQL statement format string '".$fmt. "', not enough parameters specified (".$argn." of ".$argc.")"); return FALSE; } } else $sql .= $fmt[$pos]; } return $sql; } function stDBExecSQLInsert($dbh, $sql) { switch ($dbh->getAttribute(PDO::ATTR_DRIVER_NAME)) { case "pgsql": if (($res = stDBFetchSQLColumn($dbh, $sql." RETURNING id")) !== false) return $res; else return FALSE; default: if (stDBExecSQL($dbh, $sql) !== false) return $dbh->lastInsertId(); else return FALSE; } } function stDBExecSQL($dbh, $sql) { if (($res = $dbh->query($sql)) !== FALSE) return $res; else { stLogSQLError($dbh, $sql); stError("Oh noes! SQL error #23!"); return FALSE; } } function stDBFetchSQL($dbh, $sql) { if (($res = $dbh->query($sql)) !== FALSE) return $res->fetch(); else { stLogSQLError($dbh, $sql); stError("Oh noes! SQL error #31!"); return FALSE; } } function stDBFetchSQLColumn($dbh, $sql, $column = 0) { if (($res = $dbh->query($sql)) !== FALSE) return $res->fetchColumn($column); else { stLogSQLError($dbh, $sql); stError("Oh noes! SQL error #81!"); return FALSE; } } function stPrepareSQLUpdate($table, $cond, $pairs) { global $db; return stDBPrepareSQLUpdate($db, $table, $cond, $pairs); } function stExecSQLInsert($sql) { global $db; return stDBExecSQLInsert($db, $sql); } function stExecSQL($sql) { global $db; return stDBExecSQL($db, $sql); } function stFetchSQL($sql) { global $db; return stDBFetchSQL($db, $sql); } function stFetchSQLColumn($sql, $column = 0) { global $db; return stDBFetchSQLColumn($db, $sql, $column); } function stDBBeginTransaction($dbh = FALSE) { global $db; return stDBExecSQL(($dbh !== FALSE) ? $dbh : $db, "BEGIN TRANSACTION"); } function stDBCommitTransaction($dbh = FALSE) { global $db; return stDBExecSQL(($dbh !== FALSE) ? $dbh : $db, "COMMIT"); } function stDBGetTableSchema($dbh, $data) { $res = array(); $driver = $dbh->getAttribute(PDO::ATTR_DRIVER_NAME); foreach ($data as $col) { $tmp = array(); switch ($driver) { case "pgsql": foreach ($col as $elem) { // For Postgres, use SERIAL for autoincrement if ($elem == "AUTOINCREMENT") $tmp[1] = "SERIAL"; else $tmp[] = $elem; } break; case "mysql": foreach ($col as $elem) { if ($elem != "AUTOINCREMENT") $tmp[] = "AUTO_INCREMENT"; else $tmp[] = $elem; } break; case "sqlite": $tmp = $col; break; default: die("Don't know how to handle PDO driver '".$driver."' yet.\n"); } $res[] = implode(" ", $tmp); } return implode(", ", $res); } function stDBCreateOneTable($dbh, $name, $schema) { // echo "CREATE TABLE ".$name ." (".$schema.")\n"; return (stDBExecSQL($dbh, "CREATE TABLE ".$name." (".$schema.")") !== FALSE) ? TRUE : FALSE; } function stSubStrCmp($str, $cmp, $send = FALSE) { if ($send) return substr($str, -strlen($cmp)) == $cmp; else return substr($str, 0, strlen($cmp)) == $cmp; } function stStrChop($str, $len) { return (mb_strlen($str) > $len) ? mb_substr($str, 0, $len - 3)."..." : $str; } function stStrChopPad($str, $len) { $tmp = stStrChop($str, $len); for ($i = mb_strlen($tmp); $i < $len; $i++) $tmp .= " "; return $tmp; } $stStrAtimeData = [ [ 30*24*60*60, "month" , "months" ], [ 7*24*60*60, "week" , "weeks" ], [ 24*60*60, "day" , "days" ], [ 60*60, "hour" , "hours" ], [ 60, "minute" , "minutes" ], ]; function stStrAtime($val) { global $stStrAtimeData; $res = []; foreach ($stStrAtimeData as $data) if ($val >= $data[0]) { $tmp = $val / $data[0]; $val = $val % $data[0]; $res[] = $tmp." ".($tmp > 1 ? $data[2] : $data[1]); } return implode(", ", $res); } function cmPrintCSSLine($filename, $media = FALSE) { echo " <link rel=\"stylesheet\" href=\"".$filename. "\" type=\"text/css\" ".($media !== FALSE ? "media=\"".$media."\"": "")." />\n"; } function cmPrintPageHeader($pageTitle, $pageExtra = "", $useContents = TRUE) { global $pageCSS, $pageCSSIndex, $pageCharset, $pageAuthor, $pageCSSData, $pageUrchin; if (!isset($pageCSS)) { if (!isset($pageCSSData)) { $pageCSSData = array( "cookie" => "docscss", "prefix" => "/css/docs", ); } if (isset($_GET["css"])) { $pageCSSIndex = intval($_GET["css"]); setcookie($pageCSSData["cookie"], $pageCSSIndex, time() + 365*24*60*60, "/"); // expire in a year } else { $pageCSSIndex = isset($_COOKIE[$pageCSSData["cookie"]]) ? intval($_COOKIE[$pageCSSData["cookie"]]) : 1; } $pageCSS = $pageCSSData["prefix"].$pageCSSIndex.".css"; } echo "<!DOCTYPE html>\n". "<html>\n". "<head>\n". " <meta charset=\"".$pageCharset."\">\n". " <meta http-equiv=\"Content-type\" content=\"text/html;charset=".$pageCharset."\">\n". " <title>".strip_tags($pageTitle)."</title>\n". $pageExtra; if (is_array($pageCSS)) { foreach ($pageCSS as $uri => $media) cmPrintCSSLine($uri, $media); } else { cmPrintCSSLine($pageCSS, FALSE); } echo "</head>\n". "<body>\n"; if (isset($pageUrchin) && file_exists($pageUrchin)) require_once $pageUrchin; else if (file_exists("urchin.inc.php")) require_once "urchin.inc.php"; echo "<div id=\"messageBox\"></div>\n"; if ($useContents) echo "<div id=\"contents\">\n"; } function cmPrintPageFooter($useContents = TRUE) { if ($useContents) echo "</div>\n"; echo "</body>\n</html>\n"; } function cmQM($msg) { global $pageTranslations, $pageLang; if (isset($pageTranslations[$msg]) && isset($pageTranslations[$msg][$pageLang])) $str = $pageTranslations[$msg][$pageLang]; else $str = $msg; foreach (func_get_args() as $argn => $argv) $str = preg_replace("/\%".$argn."/", $argv, $str); return $str; } // // CLI related helper functions // // Check if we are running from commandline or not function stCheckCLIExec($fail = TRUE) { if (php_sapi_name() != "cli" || !empty($_SERVER["REMOTE_ADDR"])) { if ($fail) { header("Status: 404 Not Found"); die(); } else return TRUE; } else return FALSE; } function stCArg($index, $clip = FALSE) { global $argc, $argv; if ($index < $argc) { $str = $argv[$index]; return ($clip !== FALSE) ? substr($str, 0, $clip) : $str; } else return FALSE; } function stCArgLC($index, $clip = FALSE) { global $argc, $argv; if ($index < $argc) { $str = strtolower($argv[$index]); return ($clip !== FALSE) ? substr($str, 0, $clip) : $str; } else return FALSE; } function stYesNoPrompt($msg, $default = FALSE) { echo $msg." [".($default ? "Y/n" : "y/N")."]? "; $sprompt = strtolower(trim(fgets(STDIN))); if ($default) return ($sprompt == "n"); else return ($sprompt == "y"); } function stInputPrompt($msg, $default = FALSE, $validate = null) { $valid = FALSE; while (!$valid) { echo $msg."\n".($default !== FALSE ? "[".$default."]" : "")."> "; $sprompt = trim(fgets(STDIN)); if ($sprompt == "") $sprompt = ($default !== FALSE ? $default : ""); $valid = !is_callable($validate) || call_user_func($validate, $sprompt); } return $sprompt; } function stValidateNotEmpty($val) { if ($val == "") { echo "The value can't be empty.\n"; return FALSE; } else return TRUE; } function stGetDBMeta($dbh, $name) { if (($item = stDBFetchSQL($dbh, "SELECT * FROM dbmeta WHERE key=".$dbh->quote($name))) === FALSE) return FALSE; return stGetSQLSettingData($item); } function stSetDBMeta($dbh, $name, $value) { if (($item = stDBFetchSQL($dbh, "SELECT * FROM dbmeta WHERE key=".$dbh->quote($name))) === FALSE) return FALSE; $sql = "UPDATE dbmeta SET ".stGetSettingSQL($item, $value)." WHERE key=".$dbh->quote($name); return stDBExecSQL($dbh, $sql); } // // Global locale initialization // if (!isset($localeInited) || !$localeInited) { $localeInited = TRUE; $pageCharset = "UTF-8"; mb_internal_encoding($pageCharset); $tmp = "en_US.".strtolower(str_replace("-", "", $pageCharset)); setlocale(LC_ALL, $tmp); } ?>