JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
major updates to db.php, added session.php, run.php uses file_run.php
authorJason Woofenden <jason183@herkamire.com>
Sun, 31 Dec 2006 09:26:32 +0000 (04:26 -0500)
committerJason Woofenden <jason183@herkamire.com>
Sun, 31 Dec 2006 09:26:32 +0000 (04:26 -0500)
added db_delete(), db_update(), db_auto_id(), db_replace()
fixed lots of places in db.php where it wasn't passing the mysql link identifier
added redirect() to http.php
run.php now calls file_run() (so you define a function in your file that matches the basename)
   and you can return another basename, and run.php will do that one
session.php uses session cookies (cookies that dissapear when the browser is closed) sessions also expire from the db at a given time

db.php
file_run.php [new file with mode: 0644]
http.php
metaform/template.html
run.php
session.php [new file with mode: 0644]

diff --git a/db.php b/db.php
index ea0a900..4cb4a61 100644 (file)
--- a/db.php
+++ b/db.php
@@ -73,7 +73,7 @@ function db_connect($database = 'auto', $user = 'auto', $pass = 'auto', $host =
        }
 
        if(!mysql_select_db($database, $GLOBALS['wfpl_db_handle'])) {
-               die("Couldn not access database \"$database\": " . mysql_error());
+               die("Couldn not access database \"$database\": " . mysql_error($GLOBALS['wfpl_db_handle']));
        }
 
        return $GLOBALS['wfpl_db_handle'];
@@ -82,9 +82,9 @@ function db_connect($database = 'auto', $user = 'auto', $pass = 'auto', $host =
 # Unless you're doing something unusual like an ALTER TABLE don't call this directly
 function db_send_query($sql) {
        #echo("Sending query: " . enc_html($sql) . "<br>\n");
-       $result = mysql_query($sql);
+       $result = mysql_query($sql, $GLOBALS['wfpl_db_handle']);
        if(!$result) {
-               die(enc_html('DATABASE ERROR: ' . mysql_error() . ' in the following query: ' . $sql));
+               die(enc_html('DATABASE ERROR: ' . mysql_error($GLOBALS['wfpl_db_handle']) . ' in the following query: ' . $sql));
        }
 
        return $result;
@@ -140,7 +140,7 @@ function _db_printf($str, $args) {
 }
 
 
-function db_send_get($table, $columns, $where = '', $args) {
+function db_send_get($table, $columns, $where, $args) {
        $sql = "SELECT $columns FROM $table";
        if($where) {
                $sql .= ' WHERE ' . _db_printf($where, $args);
@@ -217,6 +217,27 @@ function db_insert($table, $columns, $values) {
                $values = func_get_args();
                $values = array_slice($values, 2);
        }
+       
+       db_insert_ish('INSERT', $table, $columns, $values);
+}
+# same as above, except uses the "replace" command instead of "insert"
+function db_replace($table, $columns, $values) {
+       if(!is_array($values)) {
+               $values = func_get_args();
+               $values = array_slice($values, 2);
+       }
+       
+       db_insert_ish('REPLACE', $table, $columns, $values);
+}
+       
+# return the value mysql made up for the auto_increment field (for the last insert)
+function db_auto_id() {
+       return mysql_insert_id($GLOBALS['wfpl_db_handle']);
+}
+
+
+# used to implement db_insert() and db_replace()
+function db_insert_ish($command, $table, $columns, $values) {
 
        $sql = '';
        foreach($values as $value) {
@@ -224,7 +245,89 @@ function db_insert($table, $columns, $values) {
                $sql .= '"' . enc_sql($value) . '"';
        }
 
-       $sql = "INSERT INTO $table ($columns) values($sql)";
+       $sql = "$command INTO $table ($columns) values($sql)";
+
+       db_send_query($sql);
+}
+
+# to be consistant with the syntax of the other db functions, $values can be an
+# array, a single value, or multiple parameters.
+#
+# as usual the where clause stuff is optional, but it will ofcourse update the
+# whole table if you leave it off.
+#
+# examples:
+#
+# # name everybody Bruce
+# db_update('users', 'name', 'Bruce');
+#
+# # name user #6 Bruce
+# db_update('users', 'name', 'Bruce', 'id= %"', 6);
+#
+# # update the whole bit for user #6
+# db_update('users', 'name,email,description', 'Bruce', 'bruce@example.com', 'is a cool guy', 'id= %"', 6);
+#
+# # update the whole bit for user #6 (passing data as an array)
+# $data = array('Bruce', 'bruce@example.com', 'is a cool guy');
+# db_update('users', 'name,email,description', $data, 'id= %"', 6);
+
+# The prototype is really something like this:
+# db_update(table, columns, values..., where(optional), where_args...(optional
+function db_update($table, $columns, $values) {
+       $args = func_get_args();
+       $args = array_slice($args, 2);
+       $columns = explode(',', $columns);
+       $num_fields = count($columns);
+
+       if(is_array($values)) {
+               $args = array_slice($args, 1);
+       } else {
+               $values = array_slice($args, 0, $num_fields);
+               $args = array_slice($args, $num_fields);
+       }
+
+       $sql = '';
+       for($i = 0; $i < $num_fields; ++$i) {
+               if($sql != '') {
+                       $sql .= ', ';
+               }
+               $sql .= $columns[$i] . ' = "' . enc_sql($values[$i]) . '"';
+       }
+
+
+       $sql = "UPDATE $table SET $sql";
+
+       # if there's any more arguments
+       if($args) {
+               $where = $args[0];
+               $args = array_slice($args, 1);
+
+               $sql .= ' WHERE ';
+               # any left for where claus arguments?
+               if($args) {
+                       $sql .= _db_printf($where, $args);
+               } else {
+                       $sql .= $where;
+               }
+
+       }
+
+       db_send_query($sql);
+}
+
+# pass args for printf-style where clause as usual
+function db_delete($table, $where = '') {
+       $sql = "DELETE FROM $table";
+       if($where) {
+               $sql .= ' WHERE ';
+               $args = func_get_args();
+               $args = array_slice($args, 2);
+               if($args) {
+                       $sql .= _db_printf($where, $args);
+               } else {
+                       $sql .= $where;
+               }
+       }
 
        db_send_query($sql);
 }
diff --git a/file_run.php b/file_run.php
new file mode 100644 (file)
index 0000000..014cab5
--- /dev/null
@@ -0,0 +1,47 @@
+<?
+
+#  Copyright (C) 2005 Jason Woofenden
+#
+#  This file is part of wfpl.
+#
+#  wfpl is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU General Public License as published by
+#  the Free Software Foundation; either version 2, or (at your option)
+#  any later version.
+#
+#  wfpl is distributed in the hope that it will be useful, but
+#  WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#  General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with wfpl; see the file COPYING.  If not, write to the
+#  Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+#  MA 02111-1307, USA.
+
+
+# This function makes it easier to put everything in functions like you should.
+#
+# Instead of putting everything in the global namespace and having it run when
+# you include the file, put everything in functions. This function makes it so
+# you can both include (require_once) the file, and call its main function in
+# one easy step.
+
+# EXAMPLE
+#
+# list($user, $pass) = file_run('db_password.php');
+#
+# the file db_password.php would be like so:
+#
+#     function db_password() {
+#           return array('me', 'secret');
+#     }
+
+function file_run($filename) {
+    require_once($filename);
+    ereg_replace('.*/', '', $filename);
+    $func = basename($filename, '.php');
+    return $func();
+}
+
+?>
index c38f97d..efc08da 100644 (file)
--- a/http.php
+++ b/http.php
@@ -48,4 +48,11 @@ function this_url() {
        return $url;
 }
 
+function redirect($url, $status = '302 Moved Temporarily', $message = '') {
+       header("HTTP/1.1 $status");
+       header("Location: $url");
+       echo($message);
+       exit();
+}
+
 ?>
index d334cd6..beb9bb4 100644 (file)
@@ -4,7 +4,7 @@
 <head>
   <title>~form_name~ entry</title>
   <style type="text/css"><!--
-td.caption { text-align: right; font-weight: bold; }
+td.caption { text-align: right; vertical-align: top; font-weight: bold; }
 --></style>
 </head>
 
diff --git a/run.php b/run.php
index 3a3d85a..20b3111 100644 (file)
--- a/run.php
+++ b/run.php
@@ -56,6 +56,8 @@
 # RewriteRule    ^$  /foo/run.php
 # RewriteRule    .*\.html$  /foo/run.php
 
+require_once('code/wfpl/file_run.php');
+
 function run_php($basename = false) {
        if($basename) {
                $html_file = "$basename.html";
@@ -71,11 +73,15 @@ function run_php($basename = false) {
        if($php_file != $html_file && file_exists($php_file)) {
                require_once('code/wfpl/template.php');
                if(file_exists($html_file)) tem_load($html_file);
-               require $php_file;
+               $other = file_run($php_file);
+               if($other) {
+                       run_php($other);
+                       return;
+               }
                if(file_exists($html_file)) tem_output();
        } else {
                if(file_exists($html_file)) {
-                       require $html_file;
+                       readfile($html_file);
                } else {
                        header('HTTP/1.0 404 File Not Found');
                        if(file_exists('404.php') || file_exists('404.html')) {
diff --git a/session.php b/session.php
new file mode 100644 (file)
index 0000000..93b374f
--- /dev/null
@@ -0,0 +1,123 @@
+<?php
+
+# you'll need this file that calles db_connect()
+require_once('db_connect.php');
+
+# and these database tables:
+# create table sessions (id int unique auto_increment, session_key varchar(16), length int, expires int);
+# create table session_data (id int unique auto_increment, session_id int, name varchar(100), value text);
+
+# GLOSSARY
+#
+# session_key  16 digit string identifying the session
+# session_id   integer id of the record in the "sessions" table of the database
+# UNTIL_CLOSE  a constant passed as session length to indicate "until browser window closes"
+
+
+# session_id is kept in $GLOBALS
+# session_key is sent as a cookie, and thus appears in $_REQUEST. The clean version is in $GLOBALS
+
+# generate a new random 16-character string
+function session_generate_key() {
+       $character_set = "abcdefghijklmnopqrstuvwqyzABCDEFGHIJKLMNOPQRSTUVWQYZ0123456789";
+    $id = "                ";
+
+       # PHP 4.2.0 and up seed the random number generator for you.
+       # Lets hope that it seeds with something harder to guess than the clock.
+    for($i = 0; $i < 16; ++$i) {
+        $id{$i} = $character_set{mt_rand(0, 61)};
+    }
+
+    return $id;
+}
+
+# track this user with a session cookie (ie a cookie that goes away when the
+# user closes the browser). The timestamp is how long to track the session in
+# the database. Defaults to one day.
+function session_new($length = 86400) {
+       $session_key = session_generate_key();
+
+       db_insert('sessions', 'session_key,length', $session_key, $length);
+       $GLOBALS['session_id'] = db_auto_id();
+       $GLOBALS['session_key'] = $session_key;
+       $_REQUEST['session_key'] = $session_key; #just in case someone calls session_exists() after session_new()
+       session_touch($length);
+}
+
+# call to renew the timeout for the session.
+# assumes there's a session. call session_init() if you'd like one auto-create one if not found.
+function session_touch($length = false) {
+       if(!$length) {
+               $length = db_get_value('sessions', 'length', 'id = %i', $GLOBALS['session_id']);
+       }
+       $expires = time() + $length;
+
+       header('Set-Cookie: session_key=' . $GLOBALS['session_key']);
+
+       db_update('sessions', 'expires', $expires, 'id = %i', $GLOBALS['session_id']);
+}
+
+# delete expired sessions from database
+function session_purge_old() {
+       $now = time();
+       $exired_sessions = db_get_column('sessions', 'id', 'expires < %i', $now);
+       db_delete('sessions', 'expires < %i', $now);
+       if($expired_sessions) {
+               foreach($expired_sessions as $expired_session) {
+                       db_delete('session_data', 'session_id=%i', $expired_session);
+               }
+       }
+}
+
+# return true if a session exists
+function session_exists() {
+       if(!isset($_REQUEST['session_key'])) {
+               return false;
+       }
+
+       $session_key = ereg_replace('[^a-zA-Z0-9]', '', $_REQUEST['session_key']);
+
+       if(!strlen($session_key) == 16) {
+               return false;
+       }
+
+       $GLOBALS['session_key'] = $session_key;
+
+       session_purge_old();
+       $id = db_get_value('sessions', 'id', 'session_key = %"', $session_key);
+       if($id === false) {
+               return false;
+       }
+
+       $GLOBALS['session_id'] = $id;
+       return true;
+}
+
+# return username if a session exists and is authenticated
+function session_exists_and_authed() {
+       if(!session_exists()) {
+               return false;
+       }
+
+       return session_get('auth_username');
+}
+
+
+# find existing session, or make one
+function init_session() {
+       if(!session_exists()) {
+               session_new();
+       }
+}
+
+# save a variable into the session
+function session_set($name, $value) {
+       db_replace('session_data', 'name,value', $name, $value);
+}
+
+# get a variable into the session
+function session_get($name) {
+       return db_get_value('session_data', 'value', 'name=%"', $name);
+}
+
+?>