Sometimes with wordpress, you want to let WordPress do what it does best and you do what you do best, right? We’ll this tutorial will show you how to hook sessions into WordPress, hook a custom construction holding page into WordPress and then create an administration area within a standalone page.
Firstly open up your functions.php and insert the following at the bottom:
if( file_exists( TEMPLATEPATH . '/custom_functions.php' ) ) {
include TEMPLATEPATH . '/custom_functions.php';
}
This simply enables us to tare away from the functions.php and have all our own functions in a seperate file.
In a moment we will be tying into the database so we can do what we want therefor you have 2 options. As we are still running through WordPress, you can use the wpdb class for all your queries, or if your like me you can just use standard mysql/mysqli and thats why at the top of custom_functions.php, I have defined my constants and included a small dbclass:
<?php
define( "DBSERVER", 'localhost' );
define( "DBNAME", 'dbname' );
define( "DBUSER", 'root' );
define( "DBPASS", 'pass' );
if( file_exists("./wp-dbClass.php") ) {
require_once "./wp-dbClass.php";
}
?>
The next step will be to intergrate the use of sessions in WordPress. This sadly requires one alteration to the core index file which, I will come up with a work around when I have time. Simply add ob_start(); on the first line of your index.php file:
<?php
ob_start();
/**
* Front to the WordPress application. This file doesn't do anything, but loads
* wp-blog-header.php which does and tells WordPress to load the theme.
*
* @package WordPress
*/
/**
* Tells WordPress to load the WordPress theme and output it.
*
* @var bool
*/
define('WP_USE_THEMES', true);
/** Loads the WordPress Environment and Template */
require('./wp-blog-header.php');
?>
The reason for the ob_start(); is that there are many plugins which you may want to install which may output some whitespace and also, I didn’t make WordPress so I can’t vouch that there is and will neverbe any output leakage.
Heres the session function which then needs to be added into the custom_functions.php:
<?php
function init_sessions(){
$od = ob_get_contents();
ob_clean();
session_set_cookie_params( '0', '/', '.domain.co.uk', false );
ini_set("session.cookie_lifetime", "0");
session_save_path('/tmp');
if( session_id() == '' ) {
session_start();
}
echo $od;
}
?>
Here, we are basicaly taking out any current output, starting the session first, and then spitting back out the output after.
Next we need some kind of authorisation process, validation process and these functions are just something I knocked up quick for this post:
<?php
function authorisation_init(){
if( isset( $_POST['customer-login'] ) && isset( $_POST['username'] ) && isset( $_POST['password'] ) ) {
client_authorisation();
}
}
function client_authorisation(){
$con = Database::getInstance();
$error = '';
$password = $con->real_escape_string( md5( $_POST['password'] ) );
$email = $con->real_escape_string( $_POST['username'] );
if( $re = $con->query("SELECT * FROM " . CLIENT_TABLE . " WHERE email_address = '$email' AND password = '$password'") ) {
if( $re->num_rows == 0 ) {
if( $re2 = $con->query("SELECT * FROM " . ADMIN_TABLE . " WHERE email_address = '$email' AND password = '$password'") ) {
if( $re2->num_rows == 0 ) {
$error = '[error] <p class="error">Incorrect email or password.</p>';
}else{
$token = md5( 'superfragilisticexpialidocious' . $email . $password );
$_SESSION['user']['token'] = $token;
$error = 'You are now successfuly logged in.';
define('ADMIN', true);
}
}else{
$error = '[serror] ' . $con->error . ' :: ' . __FILE__ . ' LINE:' . __LINE__;
}
}else{
if( $con->query("UPDATE " . CLIENT_TABLE . " SET last_login = NOW()") ) {
$token = md5( 'superfragilisticexpialidocious' . $email . $password );
$_SESSION['user']['token'] = $token;
define('CLIENT', true);
$error = 'You are now successfuly logged in.';
}else{
$error = '[serror] ' . $con->error . ' :: ' . __FILE__ . ' LINE:' . __LINE__;
}
}
}else{
$error = '[serror] ' . $con->error . ' :: ' . __FILE__ . ' LINE:' . __LINE__;
}
load_client( $error );
}
function load_client( $er ){
if( $er != '' ) {
if( substr( $er, 0, 8 ) == '[serror]' ) {
// make a note of the error in the database
$error = substr( $er, 9 );
$con = Database::getInstance();
$con->query("INSERT INTO `site_errors` ( `timestamp`, `error`) VALUES (NOW(), '$error')");
$_SESSION['user']['error'] = 'An internal error has occured. The information about this error has been stored. Please contact info@planet-design.co.uk if this problem persists.
';
}elseif( substr( $er, 0, 7 ) == '[error]' ) {
// no need to take note, it's clients fault!
$_SESSION['user']['error'] = substr( $er, 8 );
}
if( defined('ADMIN') ) {
$state = admin_page_to_state( get_admin_page() );
header('Location: http://www.domain.co.uk/' . $state );
exit;
}elseif( defined('CLIENT') ) {
$state = client_page_to_state( get_client_page() );
header('Location: http://www.domain.co.uk/' . $state );
exit;
}else{
header('Location: http://www.domain.co.uk/client-login/');
exit;
}
}
}
function is_authorised( $type = '' ){
if( isset( $_SESSION['user']['token'] ) && strlen( $_SESSION['user']['token'] ) == 32 ) {
$con = Database::getInstance();
$token = $con->real_escape_string( $_SESSION['user']['token'] );
if( $re = $con->query("SELECT * FROM " . ( $type == 'admin' ? ADMIN_TABLE : CLIENT_TABLE ) . " WHERE MD5( CONCAT('superfragilisticexpialidocious', `email_address`, `password` ) ) = '$token' ") ) {
if( $re->num_rows == 1 ) {
$ob = $re->fetch_object();
define('USER_EMAIL' , $ob->email_address);
define('USER_TOKEN', $_SESSION['user']['token']);
if( $type == 'admin' ) {
if( ! defined( 'ADMIN' ) ) {
$_SESSION['type'] = 'ADMIN';
define('ADMIN', true);
}
}else{
if( ! defined('CLIENT') ) {
define('CLIENT', true );
}
}
return true;
}
}else{
die( $con->error );
}
}else{
return false;
}
}
?>
Here we are simply
- Check to see if a login form has been submited (I’m sure you can knock one up)
- If it has, run the client_authorisation(); function
- Validate that the client is authorised whilst browsing
- At the end of the function, run the $error variable through the load_client(); function which redirects to the appropriate page and or stores/sets an error based on the output.
There are also the following functions in the above which I use due to I am using a simple mod rewrite in the htaccess file. There is more than likely a more elegent way of doing this (but its just a demo!)
<?php
function get_admin_page(){
if( isset( $_GET['state'] ) ) {
switch( $_GET['state'] ) {
case 'logout' : return './admin/logout.php'; break;
case 'users' : return './admin/users.php'; break;
case 'invoices' : return './admin/invoices.php'; break;
case 'progress' : return './admin/progress.php'; break;
default : return './admin/main.php'; break;
}
}else{
return './admin/main.php';
}
}
function get_client_page(){
if( isset( $_GET['state'] ) ) {
switch( $_GET['state'] ) {
case 'logout' : return './client/logout.php'; break;
case 'password' : return './client/password.php'; break;
case 'invoices' : return './client/invoices.php'; break;
case 'progress' : return './client/progress.php'; break;
default : return './client/main.php'; break;
}
}else{
return './client/main.php';
}
}
function admin_page_to_state( $adminPage ) {
switch( $adminPage ) {
case './admin/users.php' : return 'admin-users/'; break;
case './admin/logout.php' : return 'admin-logout/'; break;
case './admin/invoices.php' : return 'admin-invoices/'; break;
case './admin/progress.php' : return 'admin-progress/'; break;
default : return 'admin-logged-in/'; break;
}
}
function client_page_to_state( $adminPage ) {
switch( $adminPage ) {
case './client/password.php' : return 'client-password/'; break;
case './client/logout.php' : return 'client-logout/'; break;
case './client/invoices.php' : return 'client-invoices/'; break;
case './client/progress.php' : return 'client-progress/'; break;
default : return 'client-logged-in/'; break;
}
}
?>
and the htaccess:
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{QUERY_STRING} .
RewriteRule ^admin-logged-in/?(.*)?$ /wp-content/themes/theme_name/admin-logged-in.php?%{QUERY_STRING}&state=home [L]
RewriteRule ^admin-logged-in/?(.*)?$ /wp-content/themes/theme_name/admin-logged-in.php?state=home [L]
RewriteCond %{QUERY_STRING} .
RewriteRule ^admin-progress/?$ /wp-content/themes/theme_name/admin-logged-in.php?%{QUERY_STRING}&state=progress [L]
RewriteRule ^admin-progress/?$ /wp-content/themes/theme_name/admin-logged-in.php?state=progress [L]
RewriteCond %{QUERY_STRING} .
RewriteRule ^admin-users/?$ /wp-content/themes/theme_name/admin-logged-in.php?%{QUERY_STRING}&state=users [L]
RewriteRule ^admin-users/?$ /wp-content/themes/theme_name/admin-logged-in.php?state=users [L]
RewriteCond %{QUERY_STRING} .
RewriteRule ^admin-invoices/?$ /wp-content/themes/theme_name/admin-logged-in.php?%{QUERY_STRING}&state=invoices [L]
RewriteRule ^admin-invoices/?$ /wp-content/themes/theme_name/admin-logged-in.php?state=invoices [L]
RewriteCond %{QUERY_STRING} .
RewriteRule ^admin-logout/?$ /wp-content/themes/theme_name/admin-logged-in.php?%{QUERY_STRING}&state=logout [L]
RewriteRule ^admin-logout/?$ /wp-content/themes/theme_name/admin-logged-in.php?state=logout [L]
RewriteCond %{QUERY_STRING} .
RewriteRule ^client-logged-in/?(.*)?$ /wp-content/themes/theme_name/client-logged-in.php?%{QUERY_STRING}&state=home [L]
RewriteRule ^client-logged-in/?(.*)?$ /wp-content/themes/theme_name/client-logged-in.php?state=home [L]
RewriteCond %{QUERY_STRING} .
RewriteRule ^client-progress/?(.*)?$ /wp-content/themes/theme_name/client-logged-in.php?%{QUERY_STRING}&state=home [L]
RewriteRule ^client-progress/?(.*)?$ /wp-content/themes/theme_name/client-logged-in.php?state=home [L]
RewriteCond %{QUERY_STRING} .
RewriteRule ^client-invoices/?(.*)?$ /wp-content/themes/theme_name/client-logged-in.php?%{QUERY_STRING}&state=invocies [L]
RewriteRule ^client-invoices/?(.*)?$ /wp-content/themes/theme_name/client-logged-in.php?state=invoices [L]
RewriteCond %{QUERY_STRING} .
RewriteRule ^client-password/?(.*)?$ /wp-content/themes/theme_name/client-logged-in.php?%{QUERY_STRING}&state=password [L]
RewriteRule ^client-password/?(.*)?$ /wp-content/themes/theme_name/client-logged-in.php?state=password [L]
RewriteCond %{QUERY_STRING} .
RewriteRule ^client-logout/?(.*)?$ /wp-content/themes/theme_name/client-logged-in.php?%{QUERY_STRING}&state=logout [L]
RewriteRule ^client-logout/?(.*)?$ /wp-content/themes/theme_name/client-logged-in.php?state=logout [L]
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
You will then need two loader pages (or one if you want to) one for clients and one for admin which will load in the appropriate pages:
Admin logged in:
<?php
require "custom_functions.php";
init_sessions();
authorisation_init();
if( ! is_authorised( 'admin' ) || ! is_admin_team() ) {
header('location: ' . URI);
}
// here you could have some switch statments depending on post or get to load certain custom functions...
include "admin-loader.php";
?>
Client logged in:
<?php
require "custom_functions.php";
init_sessions();
authorisation_init();
if( ! is_authorised() ) {
header('location: ' . URI);
}
// here you could have some switch statments depending on post or get to load certain custom functions...
include "client-loader.php";
?>
You then need to create a client-loader.php and admin-loader.php file to load in the design and content. To switch between body content you can use the functions displayed above:
<?php
if( $content = get_client_page() ) {
include $content;
}
?>
and:
<?php
if( $content = get_admin_page() ) {
include $content;
}
?>
Finally, we need to load hook all this into WordPress using the following:
<?php
if( function_exists('add_action') ) {
add_action('init', 'init_sessions', 1);
add_action('init', 'authorisation_init', 1);
add_action('init', 'is_authorised', 1);
}
?>
And that should be the basis for you to be able create a client and admin area. Obviously there is a lot more to think about but that’s another story.
Ah, almost forgot! The construction page. Well this is a little function to hook in after the session function:
<?php
function construction(){
if( file_exists( './act.php' ) )
$_file = './act.php';
elseif( file_exists( './act.html' ) )
$_file = './act.html';
if( isset( $_file ) ) {
if( isset( $_GET['wp'] ) ) {
if( $_GET['wp'] == 'run' )
$_SESSION['custom-wp'] = 'run';
elseif( $_GET['wp'] == 'stop' )
$_SESSION['custom-wp'] = 'stop';
}
if( isset( $_SESSION['custom-wp'] ) ) {
if( $_SESSION['custom-wp'] != 'run' )
echo file_get_contents( $_file );
}else{
echo file_get_contents( $_file );
die();
}
}
}
?>
and hook in:
<?php
if( function_exists('add_action') ) {
add_action('init', 'init_sessions', 1);
add_action('init', 'construction', 1);
add_action('init', 'authorisation_init', 1);
add_action('init', 'is_authorised', 1);
}
?>
All you need to do now is is create a file (act.html or act.php) and stick it in the root directory. If the file exists, domain.com/?wp=run will load the site, domain.com/?wp=stop will revert back to the holding page, and since it uses sessions then it only affects your pc! When the file is deleted, the site will run as normal.