summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEudyptula <eitan@mosenkis.net>2009-06-17 12:17:48 -0400
committerEudyptula <eitan@mosenkis.net>2009-06-17 12:17:48 -0400
commitdd5d9233866488258b3d0c735194554e6a58ddcb (patch)
tree86aa36ecf6bf38e2eb441c13813e9ba91df61332 /frontend
parentMoved including shared/include/paths.php into shared/include/includes.php (diff)
downloadingenue-dd5d9233866488258b3d0c735194554e6a58ddcb.tar.gz
ingenue-dd5d9233866488258b3d0c735194554e6a58ddcb.tar.bz2
ingenue-dd5d9233866488258b3d0c735194554e6a58ddcb.zip
Setup basics of frontend
Diffstat (limited to 'frontend')
-rwxr-xr-xfrontend/.htaccess4
-rwxr-xr-xfrontend/config.php13
-rwxr-xr-xfrontend/functions/contenttype.php7
-rwxr-xr-xfrontend/functions/debug.php13
-rwxr-xr-xfrontend/functions/genPass.php17
-rwxr-xr-xfrontend/functions/onshutdown.php28
-rwxr-xr-xfrontend/functions/printmessage.php17
-rwxr-xr-xfrontend/functions/sql.php32
-rwxr-xr-xfrontend/functions/timetosecs.php13
-rwxr-xr-xfrontend/functions/url.php24
-rwxr-xr-xfrontend/functions/xhtmlemail.php18
-rwxr-xr-xfrontend/functions/xmlheader.php5
-rwxr-xr-xfrontend/include/constants.php19
-rwxr-xr-xfrontend/include/error_handling.php60
-rwxr-xr-xfrontend/include/footer.php33
-rw-r--r--frontend/include/header.php41
-rw-r--r--frontend/include/setup.php28
-rw-r--r--frontend/index.php80
-rwxr-xr-xfrontend/pages/404.php11
-rwxr-xr-xfrontend/pages/passthrough.php71
-rwxr-xr-xfrontend/routing.csv25
21 files changed, 559 insertions, 0 deletions
diff --git a/frontend/.htaccess b/frontend/.htaccess
new file mode 100755
index 0000000..0fa2f57
--- /dev/null
+++ b/frontend/.htaccess
@@ -0,0 +1,4 @@
+RewriteEngine On
+#RewriteRule ^(recordings/[0-9]+\.mp3)$ $1 [L]
+RewriteRule ^(tmp(/.*)?)$ $1 [L]
+RewriteRule ^(?!main.php)(.*)$ index.php?req=$1&%{QUERY_STRING}
diff --git a/frontend/config.php b/frontend/config.php
new file mode 100755
index 0000000..4003a12
--- /dev/null
+++ b/frontend/config.php
@@ -0,0 +1,13 @@
+<?php
+$conf['title']='Ingenue'; // Used in <title>
+$conf['sqlhost']='localhost'; // MySQL server
+$conf['sqluser']='soc'; // MySQL username
+$conf['sqlpass']='socpassword'; // MySQL password
+$conf['sqldb']='soc'; // MySQL database
+$conf['debug']=false; // Whether to print debugging information
+$conf['cache']=true; // Whether to enable built-in caching
+$conf['cookiename']='ingenueid'; // Name of the cookie to send for keeping sessions
+$conf['sessionlength']=1814400; // Time in seconds before sessions are purged
+$conf['timezone']=10800; // Time difference in seconds between UTC and the default timezone
+$conf['mod_rewrite']=true; // Use mod_rewrite for pretty URLs
+?>
diff --git a/frontend/functions/contenttype.php b/frontend/functions/contenttype.php
new file mode 100755
index 0000000..ab546be
--- /dev/null
+++ b/frontend/functions/contenttype.php
@@ -0,0 +1,7 @@
+<?php
+function contenttype($type) {
+ global $state;
+ header('Content-type: '.$type);
+ $state->notemplates=true;
+}
+?>
diff --git a/frontend/functions/debug.php b/frontend/functions/debug.php
new file mode 100755
index 0000000..397a95d
--- /dev/null
+++ b/frontend/functions/debug.php
@@ -0,0 +1,13 @@
+<?php
+function debug ($type, $text=null) {
+ global $state;
+ global $conf;
+ if ($conf['debug']) {
+ if ($text===null) {
+ $text=$type;
+ $type=null;
+ }
+ $state->debug[]=array($type, $text);
+ }
+}
+?>
diff --git a/frontend/functions/genPass.php b/frontend/functions/genPass.php
new file mode 100755
index 0000000..b2eeda3
--- /dev/null
+++ b/frontend/functions/genPass.php
@@ -0,0 +1,17 @@
+<?php
+// Returns an 8-character random alphanumeric string
+function genPass() {
+ $vowels='aeiou';
+ $consonants='bcdfghjklmnprstvwz';
+ $pass='';
+ while (strlen($pass)<6) {
+ $pass.=strtoupper(substr($consonants, rand(0,20), 1));
+ $pass.=substr($vowels, rand(0,4), 1);
+ $pass.=substr($consonants, rand(0,20), 1);
+ }
+ while (strlen($pass)<9) {
+ $pass.=rand(0,9);
+ }
+ return $pass;
+}
+?>
diff --git a/frontend/functions/onshutdown.php b/frontend/functions/onshutdown.php
new file mode 100755
index 0000000..f0299fa
--- /dev/null
+++ b/frontend/functions/onshutdown.php
@@ -0,0 +1,28 @@
+<?php
+function onshutdown($footerloc, $headerloc) {
+ global $state, $request, $conf, $death;
+ if (isset($state) && is_object($state) && !$state->notemplates) {
+ require_once($headerloc);
+ if ($death) {
+ echo $death;
+ }
+ require_once($footerloc);
+ } elseif (isset($conf) && isset($state) && is_object($state) && isset($request) && isset($request['ajax'])) {
+ if (isset($death)) {
+ echo '<death_message>'.$death.'</death_message>';
+ }
+ if ($conf['debug']) {
+ foreach ($state->debug as $row) {
+ list($type, $text)=$row;
+ echo '<debug>';
+ if ($type !== null) {
+ echo '<type>'.htmlentities($type).'</type>';
+ }
+ echo '<text>'.htmlentities($text).'</text>';
+ echo '</debug>';
+ }
+ }
+ echo ajaxresponsefooter();
+ }
+}
+?>
diff --git a/frontend/functions/printmessage.php b/frontend/functions/printmessage.php
new file mode 100755
index 0000000..7410ef5
--- /dev/null
+++ b/frontend/functions/printmessage.php
@@ -0,0 +1,17 @@
+<?php
+function print_message_long($type, $title, $message) {
+ return '<div class="messagebox '.$type.'"><span class="title">'.$title.'</span><span class="message">'.$message.'</span></div>';
+}
+function print_message_short($type, $message) {
+ return '<div class="messagebox '.$type.' short"><span class="message">'.$message.'</span></div>';
+}
+function print_error($title, $message=null) {
+ return $message==null?print_message_short('error', $title):print_message_long('error', $title, $message);
+}
+function print_warning($title, $message=null) {
+ return $message==null?print_message_short('warning', $title):print_message_long('warning', $title, $message);
+}
+function print_success($title, $message=null) {
+ return $message==null?print_message_short('success', $title):print_message_long('success', $title, $message);
+}
+?>
diff --git a/frontend/functions/sql.php b/frontend/functions/sql.php
new file mode 100755
index 0000000..f100413
--- /dev/null
+++ b/frontend/functions/sql.php
@@ -0,0 +1,32 @@
+<?php
+if (version_compare(PHP_VERSION, '5.0.0', '<')) die('MySQLi can only be used with PHP >= 5.0.0');
+function sql_query($q, $cache=true) {
+ global $state, $conf;
+ $result=$state->sql->query($q, $cache) or trigger_error('Query failed: "'.$q.'"', E_USER_ERROR);
+ return $result;
+}
+function sql_escape_string($string) {
+ global $state;
+ return $state->sql->real_escape_string($string);
+}
+function sql_last_insert_id() {
+ global $state;
+ return $state->sql->last_insert_id();
+}
+function sql_quick_query($query) {
+ global $state;
+ return $state->sql->quick_query($query);
+}
+function sql_count($from, $where=null) {
+ global $state;
+ return $state->sql->count($from, $where);
+}
+function sql_max($from, $of, $where=null) {
+ global $state;
+ return $state->sql->max($from, $of, $where);
+}
+function sql_min($from, $of, $where=null) {
+ global $state;
+ return $state->sql->min($from, $of, $where);
+}
+?>
diff --git a/frontend/functions/timetosecs.php b/frontend/functions/timetosecs.php
new file mode 100755
index 0000000..7cc278b
--- /dev/null
+++ b/frontend/functions/timetosecs.php
@@ -0,0 +1,13 @@
+<?php
+function timetosecs($time) {
+ if (preg_match('/^([0-9]+):([0-9]+):([0-9]+(\.[0-9]+)?)$/', $time, $match)) {
+ return(3600*$match[1]+60*$match[2]+$match[3]);
+ } elseif (preg_match('/^([0-9]+):([0-9]+(\.[0-9]+)?)$/', $time, $match)) {
+ return(60*$match[1]+$match[2]);
+ } elseif (preg_match('/^([0-9]+(\.[0-9]+)?)$/', $time, $match)) {
+ return($match[1]);
+ } else {
+ return 0;
+ }
+}
+?>
diff --git a/frontend/functions/url.php b/frontend/functions/url.php
new file mode 100755
index 0000000..2cac083
--- /dev/null
+++ b/frontend/functions/url.php
@@ -0,0 +1,24 @@
+<?php
+// Makes all URLs absolute
+function url($url='') {
+ global $conf, $S;
+ if (strlen($url) == 0) {
+ return $S['root'].($conf['mod_rewrite']?'':'/index.php');
+ } elseif (substr($url, 0, 7) == 'http://') {
+ return $url;
+ }
+ if ($conf['mod_rewrite']) {
+ return $S['root'].'/'.$url;
+ } else {
+ if (strpos($url, '?')) {
+ $q=substr($url, strpos($url, '?')+1);
+ $url=substr($url, 0, strpos($url, '?'));
+ }
+ if (strlen($url)) {
+ return $S['root'].'/index.php?req='.$url.(isset($q)?'&'.$q:'');
+ } else {
+ return $S['root'].'/index.php?'.$q;
+ }
+ }
+}
+?>
diff --git a/frontend/functions/xhtmlemail.php b/frontend/functions/xhtmlemail.php
new file mode 100755
index 0000000..753a6dc
--- /dev/null
+++ b/frontend/functions/xhtmlemail.php
@@ -0,0 +1,18 @@
+<?php
+// Sends an XHTML email with the appropriate headers and the necessary opening and closing for an XHTML document
+function xhtmlemail($to,$from,$subj,$cont,$inheads=null) {
+ global $conf;
+ if ($from===null) {
+ $from=$conf['emailfrom'];
+ }
+ $heads='MIME-Version: 1.0' . "\r\n";
+ $heads.='Content-type: text/html; charset=utf-8' . "\r\n";
+ $heads.='From: '.$from."\r\n";
+ $heads.='X-Mailer: MosBlog/'.MOSBLOG_VERSION."\r\n";
+ if ($inheads!==null) {
+ $heads.="\r\n".$inheads;
+ }
+ $cont='<?xml version="1.0" encoding="utf-8"?>'."\n".'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'."\n".'<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">'.$cont.'</html>'."\n";
+ return mail($to,$subj,$cont,$heads);
+}
+?>
diff --git a/frontend/functions/xmlheader.php b/frontend/functions/xmlheader.php
new file mode 100755
index 0000000..d52164d
--- /dev/null
+++ b/frontend/functions/xmlheader.php
@@ -0,0 +1,5 @@
+<?php
+function xmlheader() {
+ return '<?xml version="1.0" encoding="utf-8"?>';
+}
+?>
diff --git a/frontend/include/constants.php b/frontend/include/constants.php
new file mode 100755
index 0000000..fb16d89
--- /dev/null
+++ b/frontend/include/constants.php
@@ -0,0 +1,19 @@
+<?php
+define('RECIPE_CATEGORY', 'r');
+define('DISH_CATEGORY', 'd');
+define('INGREDIENT_CATEGORY', 'i');
+define('FAVORITE_RECIPE', 'R');
+define('FAVORITE_DISH', 'D');
+define('FAVORITE_MEAL', 'M');
+define('FAVORITE_TIP', 'T');
+define('FAVORITE_INGREDIENT', 'I');
+define('MODE_SET', 'set');
+define('MODE_WHERE', 'where');
+define('TYPE_CATEGORY', 'c');
+define('TYPE_RECIPE', 'r');
+define('TYPE_IMAGE', 'p');
+define('TYPE_USER', 'u');
+define('TYPE_DISH', 'd');
+define('TYPE_INGREDIENT', 'i');
+define('USER_TITLES', 'Mr. Mrs. Ms. Dr. Rabbi Rav Rabbi Dr. Rav Dr.');
+?>
diff --git a/frontend/include/error_handling.php b/frontend/include/error_handling.php
new file mode 100755
index 0000000..82f6122
--- /dev/null
+++ b/frontend/include/error_handling.php
@@ -0,0 +1,60 @@
+<?php
+function exception_handler($e) {
+ global $death;
+ $trace=array();
+ foreach ($e->getTrace() as $t) {
+ $trace[]='<b>'.$t['function'].'</b>(<b>'.htmlentities(implode(', ', $t['args'])).'</b>) at <b>'.$t['file'].'</b> line <b>'.$t['line'].'</b><br/>';
+ }
+ $trace=implode(' from<br/>', $trace);
+ $death.=print_error('Uncaught '.get_class($e).': '.$e->getMessage(), 'Thrown at:<br/>'.$trace);
+}
+set_exception_handler('exception_handler');
+// Directly copied from PHP Manual -> Language Reference -> Predefined Exceptions -> ErrorException
+function exception_error_handler($errno, $errstr, $errfile, $errline ) {
+ if ((error_reporting() & $errno) == 0) { // Don't report errors that aren't supposed to be reported
+ return;
+ }
+ global $death;
+ $errtypes=array(
+ E_ERROR => 'Fatal Error',
+ E_WARNING => 'Warning',
+ E_PARSE => 'Parse Error',
+ E_NOTICE => 'Notice',
+ E_CORE_ERROR => 'Fatal Core Error',
+ E_CORE_WARNING => 'Core Warning',
+ E_COMPILE_ERROR => 'Fatal Compile-Time Error',
+ E_COMPILE_WARNING => 'Compile-Time Warning',
+ E_USER_ERROR => 'Fatal User Error',
+ E_USER_WARNING => 'User Warning',
+ E_USER_NOTICE => 'User Notice',
+ E_STRICT => 'Strict Message',
+ E_RECOVERABLE_ERROR => 'Recoverable Fatal Error'/*,
+ // PHP 5.3.0:
+ E_DEPRECATED => 'Deprecation Notice',
+ E_USER_DEPRECATED => 'User Deprecation Notice'
+ */
+ );
+ if (isset($errtypes[$errno])) {
+ $type=$errtypes[$errno];
+ } else {
+ $type='Unknown Error';
+ }
+ $trace='';
+ foreach (debug_backtrace() as $t) {
+ if (!isset($first)) {
+ $first=false;
+ continue;
+ }
+ if (isset($t['args'])) {
+ foreach ($t['args'] as $i => $arg) {
+ if (!is_scalar($arg)) {
+ $t['args'][$i]=var_export($arg, true);
+ }
+ }
+ }
+ $trace.='from <b>'.(isset($t['function'])?(isset($t['class'])?$t['class'].$t['type']:'').$t['function'].'</b>'.(isset($t['args'])?'(<b>'.htmlentities(implode(', ', $t['args'])).'</b>)':''):(isset($t['args'])?'Included file(s) '.implode(', ', $t['args']):'')).(isset($t['file'])?' at <b>'.$t['file'].'</b>'.(isset($t['line'])?' line <b>'.$t['line'].'</b>':''):'').'<br/>';
+ }
+ $death.=print_error($type, $errstr.'<br/>'.$trace);
+}
+set_error_handler("exception_error_handler");
+?>
diff --git a/frontend/include/footer.php b/frontend/include/footer.php
new file mode 100755
index 0000000..8f1b1f1
--- /dev/null
+++ b/frontend/include/footer.php
@@ -0,0 +1,33 @@
+</div><div id="bottom" class="box">
+<?php
+global $conf, $state, $rerunscripts;
+if (isset($state->start)) {
+ $diff=round(microtime(true)-$state->start, 3);
+ echo 'Execution took '.$diff.' seconds.<br/>'."\n";
+}
+echo '&#169; Eitan Mosenkis '.date('Y').'</div>';
+if ($conf['debug']) {
+ if (isset($rerunscripts) && $rerunscripts) {
+ echo '<div id="rerunscripts">You need to rerun scripts/gensqlrowobjects.pl</div>';
+ }
+ echo '<br/><div id="debug"><div class="heading" onclick="toggledebugbox()">Debug (<span id="debugcount">'.$state->debugrow.'</span>) <span id="debugactions">[<a href="javascript:cleardebug()" id="debugclear">Clear</a>] [<a href="javascript:closedebug()" id="debugclose">X</a>]</span></div><div id="debugbox">'./*$state->debug.*/'</div></div>'."\n";
+ echo '<script type="text/javascript">
+ <!--
+ toggledebugbox();'."\n";
+ foreach ($state->debug as $row) {
+ list($type, $text)=$row;
+ $text=str_replace('"', '\"', str_replace("\r", '\\r', str_replace("\n",'\\n',$text)));
+ // $text used to have htmlentities() run on it, but that killed the SQL output tables
+ if ($type == null) {
+ echo 'debug("'.$text.'");'."\n";
+ } else {
+ echo 'debug("'.$type.'", "'.$text.'");'."\n";
+ }
+ }
+ echo 'showdebug(debugrow);
+ -->
+ </script>';
+}
+?>
+</body>
+</html>
diff --git a/frontend/include/header.php b/frontend/include/header.php
new file mode 100644
index 0000000..22c9809
--- /dev/null
+++ b/frontend/include/header.php
@@ -0,0 +1,41 @@
+<?php
+ ob_start();
+ echo xmlheader();
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<link rel="stylesheet" type="text/css" href="<?php echo url('style.css'); ?>" />
+<link rel="shortcut icon" href="<?php echo url('images/favicon.ico'); ?>" />
+<link rel="icon" href="<?php echo url('images/icon.gif'); ?>" type="image/gif" />
+<title><?php
+ echo ($S['title'] != null?$S['title'].' | ':'').$conf['title'];
+?></title>
+<?php
+# $scripts=array('GetXmlHttpObject', 'class', 'ajax', 'login', 'findpos', 'suggest', 'favorites');
+ $scripts=array('GetXmlHttpObject', 'ajax', 'login', 'recordings', 'search');
+ if ($conf['debug']) {
+ array_unshift($scripts, 'debug');
+ }
+ foreach (array_merge($S['scripts'], $scripts) as $script) {
+ echo '<script type="text/javascript" src="'.url('js/'.$script.'.js').'"></script>'."\n";
+ }
+ if (isset($S['head'])) {
+ echo $S['head'];
+ }
+?>
+</head>
+<body>
+<div id="left" class="box">
+<h2>SoC</h2>
+</div>
+<div id="top" class="box">
+Top stuff
+</div>
+<div id="main" class="box">
+<?php
+ if (isset($death)) {
+ echo $death;
+ $death='';
+ }
+?>
diff --git a/frontend/include/setup.php b/frontend/include/setup.php
new file mode 100644
index 0000000..481037c
--- /dev/null
+++ b/frontend/include/setup.php
@@ -0,0 +1,28 @@
+<?php
+if (!isset($S)) {
+ $S=array();
+}
+$S=array_merge($S, array(
+ 'request' => $_GET['req'],
+ 'notemplates' => false,
+ 'title' => null,
+ 'scripts' => array(),
+ 'debug' => null,
+ 'debugrow' => 0,
+ 'root' => null,
+ 'cookie_dir' => null,
+ 'start' => microtime(true),
+ 'sql' => null
+));
+unset($_REQUEST['req'], $_GET['req']);
+if (isset($conf['rootDir'])) { // What on Earth is going on here?
+ $cDir=substr($cDir, strpos($cDir, '/', 8)); // Cuts the http://, the domain name
+ $S['cookie_dir']=$cDir.'/';
+ $S['root']=$conf['rootDir'];
+} else {
+ $cDir=dirname($_SERVER['PHP_SELF']); // We're assumed to always be running /index.php
+ $S['cookie_dir']=$cDir;
+ $S['root']=rtrim('http://'.$_SERVER['HTTP_HOST'].($_SERVER['SERVER_PORT']==(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS']?443:80)?'':':'.$_SERVER['SERVER_PORT']).$cDir, '/');
+}
+// TODO DB init and sql_row_obj::set_pdo_obj
+?>
diff --git a/frontend/index.php b/frontend/index.php
new file mode 100644
index 0000000..90cdf66
--- /dev/null
+++ b/frontend/index.php
@@ -0,0 +1,80 @@
+<?php
+define('E_DEFAULT', error_reporting(E_ALL|E_STRICT));
+date_default_timezone_set('UTC');
+require_once('../shared/include/includes.php');
+require_once('include/error_handling.php');
+require_once('include/constants.php');
+require_once('config.php');
+register_shutdown_function('onshutdown', realpath('include/footer.php'), realpath('include/header.php'));
+require_once('include/setup.php');
+foreach ($_REQUEST as $key => $value) {
+ $request[$key]=get_magic_quotes_gpc()?stripslashes($value):$value;
+}
+$routing=fopen('routing.csv', 'r');
+for ($line=fgets($routing, 32768); !feof($routing); $line=fgets($routing, 32768)) {
+ $line=trim($line, "\r\n");
+ if (substr($line, 0, 1) == '#' || strlen($line) == 0) {
+ continue;
+ }
+ $line=explode("\t", $line, 3);
+ if (count($line) < 2) {
+ continue;
+ } elseif (count($line) == 2) {
+ list($expr, $dest)=$line;
+ $vars=array();
+ } else {
+ list($expr, $dest, $vars)=$line;
+ $vars=explode("\t", $vars);
+ }
+ unset($line);
+ if (preg_match('{'.$expr.'}',$S['request'],$matches)) {
+ fclose($routing);
+ for ($i=0; $i < count($vars); $i++) {
+ if (strpos($vars[$i],'=')) {
+ $request[substr($vars[$i],0,strpos($vars[$i],'='))]=substr($vars[$i],strpos($vars[$i],'=')+1);
+ } else {
+ if ($i+1 > count($matches)-1) {
+ debug('routing',print_error('Routing failure','Trying to set request variable "'.$vars[$i].'" but ran out of matches (page='.$dest.')'));
+ } else {
+ $request[$vars[$i]]=$matches[$i+1];
+ }
+ }
+ }
+ while ($dest != null) {
+ debug('routing','Routing to '.$dest);
+ require_once('pages/'.$dest.'.php');
+ $dest=str_replace(array('/', '-'), '_', $dest);
+ $initfunc='init_'.$dest;
+ if (function_exists($initfunc)) {
+ $value=$initfunc();
+ if ($value !== null) {
+ $dest=$value;
+ } else {
+ break;
+ }
+ } else {
+ require_once('include/header.php');
+ die(print_error('Routing Failure', 'Init function undefined for '.$dest.'.'));
+ }
+ }
+ if (!$S['notemplates']) {
+ require_once('include/header.php');
+ }
+ $bodyfunc='body_'.str_replace('/','_',$dest);
+ if (function_exists($bodyfunc)) {
+ $bodyresult=$bodyfunc();
+ if ($bodyresult !== null) {
+ require($bodyresult);
+ }
+ } else {
+ if ($S['notemplates']) {
+ debug('Routing', 'Body function missing for page '.$dest);
+ } else {
+ die(print_error('Routing failure', 'Body function missing for page '.$dest));
+ }
+ }
+ die;
+ }
+}
+die(print_error('Routing Failure', 'You should never see this message. Please contact an administrator.'));
+?>
diff --git a/frontend/pages/404.php b/frontend/pages/404.php
new file mode 100755
index 0000000..c81af31
--- /dev/null
+++ b/frontend/pages/404.php
@@ -0,0 +1,11 @@
+<?php
+function init_404() {
+ global $S;
+ $S['title']='404: Not Found';
+ header('HTTP/1.0 404 Not Found');
+}
+function body_404() {
+ global $S;
+ echo print_error('Page Not Found!','The page you are trying to reach, <i>'.$S['root'].'/'.$S['request'].'</i> does not exist.');
+}
+?>
diff --git a/frontend/pages/passthrough.php b/frontend/pages/passthrough.php
new file mode 100755
index 0000000..22b49bb
--- /dev/null
+++ b/frontend/pages/passthrough.php
@@ -0,0 +1,71 @@
+<?php
+function init_passthrough() {
+ global $state, $request;
+ if (strpos('../',$request['dir'].'/'.$request['file']) !== false || !file_exists($request['dir'].'/'.$request['file']) && !file_exists($request['dir'].'/'.$request['file'].'.php')) {
+ debug('passthrough','File not found '.$request['dir'].'/'.$request['file']);
+ return '404';
+ }
+ switch (strtolower($request['ext'])) {
+ // http://www.w3schools.com/media/media_mimeref.asp
+ case 'mp3':
+ contenttype('audio/mpeg');
+ break;
+ case 'jpg':
+ case 'jpeg':
+ contenttype('image/jpeg');
+ break;
+ case 'gif':
+ contenttype('image/gif');
+ break;
+ case 'ico':
+ contenttype('image/x-icon');
+ break;
+ case 'js':
+ contenttype('application/x-javascript');
+ break;
+ case 'css':
+ contenttype('text/css');
+ break;
+ case 'html':
+ case 'htm':
+ case 'xhtml':
+ contenttype('text/html');
+ break;
+ case 'php':
+ $state->notemplates=true;
+ break;
+ default:
+ debug('passthrough', 'Unknown extension '.$request['ext']);
+ return '404';
+ }
+ // Set filesize if we're working with a static file (needed for normal download and streaming behavior)
+ if (strtolower($request['ext']) != 'php' && file_exists($request['dir'].'/'.$request['file'])) {
+ header('Content-Length: '.filesize($request['dir'].'/'.$request['file']));
+ }
+ // Force browser to download, possibly set dynamic filename, passed by previous page or by HTTP request (taken from the PHP manual on readfile()
+ if (isset($request['download']) && $request['download']) {
+ header('Content-Description: File Transfer');
+ header('Content-Transfer-Encoding: binary');
+ if (isset($request['download_name']) && strlen($request['download_name']) > 0) {
+ header('Content-Disposition: attachment; filename="'.str_replace('"','\'', $request['download_name']).'"');
+ } else {
+ header('Content-Disposition: attachment');
+ }
+ }
+ $state->notemplates=true;
+}
+function body_passthrough() {
+ global $request;
+ if (strtolower($request['ext']) == 'php') {
+ $_SERVER['PHP_SELF']=substr($_SERVER['PHP_SELF'],0,strlen($_SERVER['PHP_SELF'])-strlen('main.php')).$request['dir'].'/'.$request['file'];
+ unset($GLOBALS['state'], $GLOBALS['request'], $GLOBALS['conf']);
+ chdir($request['dir']);
+ error_reporting(E_DEFAULT);
+ return $request['file'];
+ } elseif (file_exists($request['dir'].'/'.$request['file'])) {
+ readfile($request['dir'].'/'.$request['file']);
+ } else {
+ return $request['dir'].'/'.$request['file'].'.php';
+ }
+}
+?>
diff --git a/frontend/routing.csv b/frontend/routing.csv
new file mode 100755
index 0000000..69f2e1c
--- /dev/null
+++ b/frontend/routing.csv
@@ -0,0 +1,25 @@
+# This file is a comma-separated set of rules for matching URLs to the pages they refer to. Rows are tried in order The following syntax is expected of each row:
+# Col 1: regexp to match
+# Col 2: page to use
+# [Col 3: varname for subexpr 1]
+# [Col 4: varname for subexpr 2]
+# [Col 5: varname=static value 1]
+# [Col 6: varname=static value 2]
+# #-ed lines are ignored.
+# Something like the following line should always be last to catch unrecognized URLs
+# ^ 404
+
+# Session
+^login$ login
+^logout$ logout
+# Pass through
+^(js)/([0-9a-zA-Z-_]+\.(js))$ passthrough dir file ext
+^(images)/([0-9a-zA-Z-_]+\.(gif|jpg|jpeg|ico))$ passthrough dir file ext
+# Recording/download just sets the download setting and filename before handing off to passthrough
+^(recordings)/([0-9]+\.(mp3))$ recording/download dir file ext
+# Replace xinha with a directory name to turn it into fairly normal handling like without all this crazy redirecting
+#^(xinha(?=/)[0-9a-zA-Z-_./]*).(?<=/)([0-9a-zA-Z-_.]+\.([a-zA-Z0-9]+))$ passthrough dir file ext
+# CSS
+^style.css$ stylesheet
+# This is the catch-all - never remove it
+^ 404