Sources for file xnyo.php in version 4.0 Beta 1
Click on a comment to hide it. Click here to show all comments.
/**
* Project: Xnyo 4: Bubbles
* File: xnyo.class.php
*
* Version: 4.0-dev
* SVN Id: $Id: xnyo.php 5 2007-05-18 03:49:07Z bok $
* SVN URL: $HeadURL: http://svn.syd.wholesalebroadband.com.au/xnyo/trunk/xnyo.php $
* Authors: Robert Amos <bok[at]odynia.org>
*
* Copyright (c) 2001-2007 Robert Amos <bok[at]odynia.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**/
/**
* Production / Development Mode
*
* By default, Xnyo will start in development mode. By setting the XNYO_PRODUCTION
* constant to true, Xnyo will take steps to improve performance by not performing unnecessary
* checks. Performance will be consistently slower during development mode.
**/
if (!defined('XNYO_PRODUCTION')) define('XNYO_PRODUCTION', false);
/**
* Constants
**/
// Directory / Path Separator shortcuts
if (!defined('DIRSEP')) define('DIRSEP', DIRECTORY_SEPARATOR);
if (!defined('PATHSEP')) define('PATHSEP', PATH_SEPARATOR);
// Location Shortcuts
if (!defined('XNYO_DIR')) define('XNYO_DIR', dirname(__FILE__).DIRSEP);
if (!defined('SMARTY_DIR')) define('SMARTY_DIR', XNYO_DIR.'smarty'.DIRSEP);
if (!defined('SCRIPT_DIR')) define('SCRIPT_DIR', dirname($_SERVER['SCRIPT_FILENAME']).DIRSEP);
// are we using the Odynia-recommended file layout?
if (defined('ODYNIA_LAYOUT') && ODYNIA_LAYOUT)
{
if (!defined('ROOT_DIR')) define('ROOT_DIR', strrev(preg_replace('/^.*?etis/i', '',
strrev(SCRIPT_DIR))));
if (!defined('INCLUDE_DIR')) define('INCLUDE_DIR', ROOT_DIR.'include'.DIRSEP);
if (!defined('SMARTY_TEMPLATE_DIR')) define('SMARTY_TEMPLATE_DIR', ROOT_DIR.'templates');
if (!defined('SMARTY_COMPILE_DIR')) define('SMARTY_COMPILE_DIR',
ROOT_DIR.'backend'.DIRSEP.'compile');
if (!defined('SMARTY_CACHE_DIR')) define('SMARTY_CACHE_DIR', ROOT_DIR.'backend'.DIRSEP.'cache');
if (!defined('XNYO_CACHE_DIR')) define('XNYO_CACHE_DIR', ROOT_DIR.'backend'.DIRSEP.'cache'.DIRSEP);
if (!defined('BUBBLES_DIR')) define('BUBBLES_DIR', ROOT_DIR.'bubbles'.DIRSEP);
}
// Error Shortcuts
if (!defined('ERROR')) define('ERROR', E_USER_ERROR);
if (!defined('WARNING')) define('WARNING', E_USER_WARNING);
if (!defined('NOTICE')) define('NOTICE', E_USER_NOTICE);
if (!defined('CLIENT')) define('CLIENT', 8192);
if (!defined('DEBUG')) define('DEBUG', 16384);
// Control Shortcuts - define these to turn stuff on or off
if (!defined('XNYO_BUBBLES')) define('XNYO_BUBBLES', true);
if (!defined('XNYO_DATABASE')) define('XNYO_DATABASE', true);
if (!defined('XNYO_SESSION')) define('XNYO_SESSION', true);
if (!defined('XNYO_LANGUAGE')) define('XNYO_LANGUAGE', true);
if (!defined('XNYO_INPUT')) define('XNYO_INPUT', true);
if (!defined('XNYO_FILTER')) define('XNYO_FILTER', true);
if (!defined('XNYO_SMARTY')) define('XNYO_SMARTY', true);
if (!defined('XNYO_CACHE')) define('XNYO_CACHE', false);
if (!defined('XNYO_BUFFER')) define('XNYO_BUFFER', true);
//if (!defined('XNYO_DEBUG')) define('XNYO_DEBUG', false);
// Debug Controls
if (!defined('XNYO_DEBUG_ALLOW')) define('XNYO_DEBUG_ALLOW', false);
if (!defined('XYNO_DEBUG_VAR')) define('XNYO_DEBUG_VAR', 'xnyo_debug');
if (!defined('XNYO_DEBUG_LOG')) define('XNYO_DEBUG_LOG', false);
/**
* The Xnyo Class!
**/
class Xnyo
{
/**
* Variable declerations
**/
// Shortcuts to load/include.
public $shortcuts = array();
/**
* Constructor function
**/
public function __construct ()
{
// Start a session first thing, prevents arguments later on
if (XNYO_SESSION) session_start();
// we need to check to see if we can enable debug first
if (XNYO_DEBUG_ALLOW)
{
// this is the ONLY time we will ever check a GET variable without the filter!
// this is a call to load the debug console.
if ($_GET[XNYO_DEBUG_VAR] == 'console')
{
if (!defined('XNYO_DEBUG')) define('XNYO_DEBUG', false);
echo $_SESSION['_xnyo_debug_console'];
$_SESSION['_xnyo_debug_console'] = "Please re-run the debugged page to re-generate the
console.";
exit;
// this is a call to enable debugging
} elseif (isset($_GET[XNYO_DEBUG_VAR]))
{
if (!defined('XNYO_DEBUG')) define('XNYO_DEBUG', true);
if (!defined('XNYO_DEBUG_CONSOLE')) define('XNYO_DEBUG_CONSOLE', false);
// no debugging
} else
{
if (!defined('XNYO_DEBUG')) define('XNYO_DEBUG', false);
if (!defined('XNYO_DEBUG_CONSOLE')) define('XNYO_DEBUG_CONSOLE', false);
}
// not allowed debugging, make sure it doesnt get set.
} else
{
if (!defined('XNYO_DEBUG')) define('XNYO_DEBUG', false);
if (!defined('XNYO_DEBUG_CONSOLE')) define('XNYO_DEBUG_CONSOLE', false);
}
// we need to maintain a link to the Xnyo class by using the $xnyo_parent global variable.
$GLOBALS['xnyo_parent'] =& $this;
// include the root options
$this->inc('interfaces');
$this->inc('options');
$this->inc('storage');
$this->inc('exceptions');
$this->options = new XnyoOptions;
$this->plugins = new XnyoOptionsPlugins;
$this->error = new XnyoOptionsError;
$this->storage = new XnyoStorage;
// load the error handler
$this->load($this->error->handler, XNYO_PLUGIN_ERROR);
set_error_handler(array(&$this, 'php_error_handler'), E_ALL);
set_exception_handler(array(&$this, 'exception_handler'));
// load debug
if (XNYO_DEBUG)
{
$this->d('Enabling debugging.');
$this->debug = new XnyoOptionsDebug;
$this->load('debug');
}
// Force the Content Type to UTF-8, this can be overridden by sending another Content-Type header.
if (XNYO_DEBUG) $this->d('Forcing <b>Content-Type</b> header to <b>UTF-8</b>');
header('Content-Type: text/html; charset=UTF-8');
// we need the input plugin for stuff from here on.
$this->inc('input');
$this->session = new XnyoOptionsSession;
// If we've got a language thing going on we'll need it for the cache
if (XNYO_LANGUAGE)
$this->load('language');
// Do we have caching enabled? If so we'd better check to see if this page is cached!
if (XNYO_CACHE)
{
$this->cache = new XnyoOptionsCache;
$this->load('cache');
if ($this->objects->cache->is_cached())
{
// The page is cached. Display the cache and exit, nothing else left to do
$this->objects->cache->display_cache();
exit;
}
if (XNYO_DEBUG) $this->d('Not using cached copy of page.');
}
/**
* The possibility of being cached has passed, start into normal page load sequence.
**/
// Start the output buffer.
if (PHP_SAPI != 'cli' && XNYO_BUFFER)
{
if (XNYO_DEBUG) $this->d('Setting the Output Buffer Handler');
ob_start(array(&$this, 'ob_handler'));
if (XNYO_DEBUG) $this->d('Set to $xnyo->ob_handler.');
}
// load the database plugin
if (XNYO_DATABASE)
{
$this->load('XnyoDB');
$this->inc('XnyoActiveRecord');
}
// load the session plugin
if (XNYO_SESSION)
{
$this->session = new XnyoOptionsSession;
/**
* We dont load the session plugin unless we need it. A call to $xnyo->login() will load it
automatically
* so we only need it otherwise if there is already a session in progress.
**/
if (isset($_SESSION['_xnyo_auth']) && is_array($_SESSION['_xnyo_auth']))
$this->load('XnyoSession', XNYO_PLUGIN_CLASS);
}
// load the filter plugin
if (XNYO_FILTER)
{
$this->filter = new XnyoOptionsFilter;
$this->load('XnyoFilter');
}
// and load Smarty
if (XNYO_SMARTY)
{
$this->smartyvar = new XnyoOptionsSmartyVar;
$this->inc('smarty');
$this->load('XnyoSmarty');
}
/**
* Enable bubbles!
**/
if (XNYO_BUBBLES)
{
$this->load('XnyoBubbles');
}
}
/**
* Inc
*
* Include a plugin's source file
**/
public function inc ($name, $type=null)
{
// interfaces shortcut
if ($name == 'interfaces')
{
if (!defined('XNYO_INTERFACES_LOADED'))
include_once(XNYO_DIR.'plugins'.DIRSEP.'class'.DIRSEP.'interfaces.php');
return true;
}
// options shortcut
if ($name == 'options')
{
if (!defined('XNYO_OPTIONS_LOADED'))
include_once(XNYO_DIR.'plugins'.DIRSEP.'class'.DIRSEP.'options.php');
return true;
}
// storage shortcut
if ($name == 'storage')
{
if (!defined('XNYO_STORAGE_LOADED'))
include_once(XNYO_DIR.'plugins'.DIRSEP.'class'.DIRSEP.'storage.php');
return true;
}
// exceptions shortcut
if ($name == 'exceptions')
{
if (!defined('XNYO_EXCEPTIONS_LOADED'))
include_once(XNYO_DIR.'plugins'.DIRSEP.'error'.DIRSEP.'exceptions.php');
return true;
}
// smarty shortcut
if ($name == 'smarty')
{
include_once(SMARTY_DIR.'Smarty.class.php');
return true;
}
// set the default class type
$checks = 1;
if ($type == null)
{
if (XNYO_DEBUG) $this->d('Assuming plugin <b>%s</b> is of type <b>%s</b>.', $name,
XNYO_PLUGIN_CLASS);
$checks = 3;
$type = XNYO_PLUGIN_CLASS;
}
// empty or null plugin name?
if (empty($name))
throw new XnyoError('Empty plugin name specified.');
// Have we loaded this plugin before?
if ($this->storage->plugins->is_inced($name, $type))
{
if (XNYO_DEBUG) $this->d('Trying to include plugin <b>%s</b> (<b>%s</b>) that has already been
included.', $name, $type);
return true;
}
// Clean up the plugin - security
$name = preg_replace('/[^a-z0-9._]/i', '', strtolower($name));
// bubbles live in a special place
if ($type == XNYO_PLUGIN_BUBBLE && XNYO_BUBBLES)
{
// check BUBBLES_DIR
if (!defined('BUBBLES_DIR'))
throw new XnyoError('Please define the constant BUBBLES_DIR to the directory where bubbles
live.');
if (!is_dir(BUBBLES_DIR) || !is_readable(BUBBLES_DIR))
throw new XnyoError('BUBBLES_DIR <b>%s</b> does not exist or is not readable.', BUBBLES_DIR);
// check to see if our bubble plugin exists
if (!file_exists(BUBBLES_DIR.$name.DIRSEP.'plugin.php'))
throw new XnyoError('Bubble <b>%s</b> does not exist or has no plugin.', $name);
// set the file and let the inc continue
$file = BUBBLES_DIR.$name.DIRSEP.'plugin.php';
} else
{
// check the plugin directories for the plugin
$checked = array();
for ($i = 0; $i < $checks; $i++)
{
foreach ($this->plugins->dirs as $dir)
{
// remove double dots and additional slashes
$dir = preg_replace('/\.\./', '', $dir.DIRSEP.$type.DIRSEP);
$dir = preg_replace('/\/+/', '/', $dir);
// can we see the file in the include_path ?
if (file_exists($dir.$name.$this->plugins->ext))
$file = $dir.$name.$this->plugins->ext;
// check to see whether its a plugin directory inside the ROOT_DIR
elseif (defined('ROOT_DIR') && file_exists(ROOT_DIR.$dir.$name.$this->plugins->ext))
$file = ROOT_DIR.$dir.$name.$this->plugins->ext;
// check to see whether its a plugin directory inside the SCRIPT_DIR
elseif (defined('SCRIPT_DIR') && file_exists(SCRIPT_DIR.$dir.$name.$this->plugins->ext))
$file = SCRIPT_DIR.$dir.$name.$this->plugins->ext;
// check to see whether its a plugin directory inside the XNYO_DIR
elseif (defined('XNYO_DIR') && file_exists(XNYO_DIR.$dir.$name.$this->plugins->ext))
$file = XNYO_DIR.$dir.$name.$this->plugins->ext;
// not able to find it that way, what if they've provided the class name here?
elseif (strtolower(substr($name, 0, 4)) == 'xnyo')
{
// strip off the Xnyo bit, and lowercase it.
$p = strtolower(substr($name, 4));
// check the same locations as previously
if (file_exists($dir.$p.$this->plugins->ext))
$file = $dir.$p.$this->plugins->ext;
elseif (defined('ROOT_DIR') && file_exists(ROOT_DIR.$dir.$p.$this->plugins->ext))
$file = ROOT_DIR.$dir.$p.$this->plugins->ext;
elseif (defined('SCRIPT_DIR') && file_exists(SCRIPT_DIR.$dir.$p.$this->plugins->ext))
$file = SCRIPT_DIR.$dir.$p.$this->plugins->ext;
elseif (defined('XNYO_DIR') && file_exists(XNYO_DIR.$dir.$p.$this->plugins->ext))
$file = XNYO_DIR.$dir.$p.$this->plugins->ext;
// what if its XnyoTypeName ?
elseif(strtolower(substr($p, 0, strlen($type))) == strtolower($type))
{
// strip off the type, and lowercase it
$q = strtolower(substr($p, strlen($type)));
// check the same locations as before!
if (file_exists($dir.$q.$this->plugins->ext))
$file = $dir.$q.$this->plugins->ext;
elseif (defined('ROOT_DIR') && file_exists(ROOT_DIR.$dir.$q.$this->plugins->ext))
$file = ROOT_DIR.$dir.$q.$this->plugins->ext;
elseif (defined('SCRIPT_DIR') && file_exists(SCRIPT_DIR.$dir.$q.$this->plugins->ext))
$file = SCRIPT_DIR.$dir.$q.$this->plugins->ext;
elseif (defined('XNYO_DIR') && file_exists(XNYO_DIR.$dir.$q.$this->plugins->ext))
$file = XNYO_DIR.$dir.$q.$this->plugins->ext;
}
}
if (isset($file))
break 2;
}
// haven't found anything and we're assuming its a class
if ($checks == 3)
{
if ($i == 0)
{
if (XNYO_DEBUG) $this->d('Could not locate plugin <b>%s</b> as type <b>%s</b>, trying again
with type <b>%s</b>', $name, $type, XNYO_PLUGIN_DBSPEC);
$type = XNYO_PLUGIN_DBSPEC;
} elseif ($i == 1)
{
if (XNYO_DEBUG) $this->d('Could not locate plugin <b>%s</b> as type <b>%s</b>, trying again
with type <b>%s</b>', $name, $type, XNYO_PLUGIN_BUBBLE);
$type = XNYO_PLUGIN_BUBBLE;
}
}
}
}
// not located the plugin?
if (empty($file))
throw new XnyoError('Unable to find plugin <b>%s</b> (<b>%s</b>).', $name, ($checks == 3 ?
XNYO_PLUGIN_CLASS.'/'.XNYO_PLUGIN_DBSPEC.'/'.XNYO_PLUGIN_BUBBLE : $type));
// include the plugin
if (!file_exists($file) || !is_readable($file))
throw new XnyoError('File <b>%s</b> for plugin <b>%s</b> (<b>%s</b>) not found or not readable.',
$file, $name, $type);
if (XNYO_DEBUG) $this->d('Including file <b>%s</b> for plugin <b>%s</b> (<b>%s</b>).', $file,
$name, $type);
include_once($file);
$this->storage->plugins->mark_inced($name, $type);
if (!empty($p))
$this->storage->plugins->mark_inced($p, $type);
return true;
}
/**
* Load
*
* Load up a plugin and place it where it wants to be
**/
public function load ($name, $type=null)
{
// set the default class type
if ($type == null)
{
if (XNYO_DEBUG) $this->d('Assuming plugin <b>%s</b> is of type <b>%s</b>.', $name,
XNYO_PLUGIN_CLASS);
$type = XNYO_PLUGIN_CLASS;
}
// empty or null plugin name?
if (empty($name))
throw new XnyoError('Empty plugin name specified.');
// has this plugin been loaded before?
if ($this->storage->plugins->is_loaded($name, $type))
{
if (XNYO_DEBUG) $this->d('Trying to load plugin <b>%s</b> (<b>%s</b>) that has already been
loaded.', $name, $type);
$o = $this->storage->plugins->get_plugin_reference($name, $type);
if ($o->_plugin_info['action'] == XNYO_PLUGIN_ACTION_RETURN)
return $o;
return true;
}
// include the plugin!
$this->inc($name, $type);
// did they pass the class name as $name?
if (class_exists('Xnyo'.ucfirst($type).ucfirst($name)))
$class = 'Xnyo'.ucfirst($type).ucfirst($name);
elseif (class_exists('Xnyo'.ucfirst($name)))
$class = 'Xnyo'.ucfirst($name);
elseif (class_exists($name) && strtolower($name) != 'xnyo')
$class = $name;
else
throw new XnyoError('Unable to load plugin <b>%s</b> (<b>%s</b>) as no suitable class could be
found.', $name, $type);
// create an instance of the class
if (XNYO_DEBUG) $this->d('Created instance of <b>%s</b> for plugin <b>%s</b> (<b>%s</b>)', $class,
$name, $type);
$obj = new $class;
// implementation checks
switch ($type)
{
case XNYO_PLUGIN_CLASS:
if (!$obj instanceof XnyoClassPlugin)
throw new XnyoError('Implementation Error: Class Plugin <b>%s</b> does not implement interface
XnyoClassPlugin', $name);
break;
case XNYO_PLUGIN_BUBBLE:
if (!$obj instanceof XnyoBubble)
throw new XnyoError('Implementation Error: Bubble Plugin <b>%s</b> does not extend class
XnyoBubble.', $name);
break;
case XNYO_PLUGIN_AUTH:
if (!$obj instanceof XnyoAuthPlugin)
throw new XnyoError('Implementation Error: Auth Plugin <b>%s</b> does not implement interface
XnyoAuthPlugin', $name);
break;
case XNYO_PLUGIN_CACHE:
if (!$obj instanceof XnyoCachePlugin)
throw new XnyoError('Implementation Error: Cache Plugin <b>%s</b> does not implement interface
XnyoCachePlugin', $name);
break;
case XNYO_PLUGIN_DATABASE:
if (!$obj instanceof XnyoDatabasePlugin)
throw new XnyoError('Implementation Error: Database Plugin <b>%s</b> does not implement
interface XnyoDatabasePlugin', $name);
break;
case XNYO_PLUGIN_DBSPEC:
if (!$obj instanceof XnyoActiveDirectory)
throw new XnyoError('Implementation Error: DB Spec Plugin <b>%s</b> does not extend class
XnyoActiveDirectory', $name);
break;
case XNYO_PLUGIN_ERROR:
if (!$obj instanceof XnyoErrorPlugin)
throw new XnyoError('Implementation Error: Error Plugin <b>%s</b> does not implement interface
XnyoErrorPlugin', $name);
break;
}
// lets read through the plugin information
if (!isset($obj->_plugin_info) || empty($obj->_plugin_info) ||
empty($obj->_plugin_info['action']))
throw new XnyoError('Plugin <b>%s</b> (<b>%s</b>) does not contain information about what to do
with the class <b>%s</b>', $name, $type, $class);
// what action is listed for this plugin
switch ($obj->_plugin_info['action'])
{
case XNYO_PLUGIN_ACTION_GLOBAL:
// check to make sure a varname was specified
if (empty($obj->_plugin_info['varname']))
throw new XnyoError('Plugin class <b>%s</b> indicates object should be made global, but no
<i>varname</b> was specified.', $class);
if (XNYO_DEBUG) $this->d('Plugin <b>%s</b> (<b>%s</b>) is being made into global object
<b>$%s</b>.', $name, $type, $obj->_plugin_info['varname']);
if (XNYO_DEBUG && !empty($GLOBALS['smarty']))
$this->d('Global variable <b>$%s</b> already exists, overwriting with instance of <b>%s</b>.',
$obj->_plugin_info['varname'], $class);
$GLOBALS[$obj->_plugin_info['varname']] = $obj;
// mark it loaded
$this->storage->plugins->mark_loaded($name, $type, $obj);
break;
case XNYO_PLUGIN_ACTION_STORAGE:
// this is being created as an internal Xnyo object
if (empty($obj->_plugin_info['varname']))
throw new XnyoError('Plugin class <b>%s</b> indicates object should be attached to the Xnyo
Storage Facility, but no <i>varname</B> was specified.', $class);
if (XNYO_DEBUG) $this->d('Plugin <b>%s</b> (<b>%s</b>) is being attached to the Xnyo Storage
Facility under the name <b>%s</b>.', $name, $type, $obj->_plugin_info['varname']);
$v = $obj->_plugin_info['varname'];
if (!empty($this->storage->$v))
throw new XnyoError('Object <b>%s</b> already exists in the Xnyo Storage Facility, unable to
make it new instance of <b>%s</b>', $v, $class);
$this->storage->$v = $obj;
// mark it loaded
$this->storage->plugins->mark_loaded($name, $type, $obj);
break;
case XNYO_PLUGIN_ACTION_RETURN:
// this is being returned, nice and easy
if (XNYO_DEBUG) $this->d('Plugin <b>%s</b> (<b>%s</b>) is to be returned, returning instance of
<b>%s</b>.', $name, $type, $class);
// mark it loaded
$this->storage->plugins->mark_loaded($name, $type, $obj);
return $obj;
case XNYO_PLUGIN_ACTION_NONE:
$this->storage->plugins->mark_loaded($name, $type, $obj);
return;
default:
throw new XnyoError('Plugin <b>%s</b> has not specified a valid action <b>%s</b>.', $name,
$obj->_plugin_info['action']);
}
}
/**
* D
*
* Log a debug message
**/
public function d ($msg=null)
{
if (func_num_args() > 1)
{
$args = func_get_args();
$msg = call_user_func_array('sprintf', $args);
}
if (!is_object($this->storage->error))
return false;
$this->storage->error->raise(new XnyoDebugException($msg));
}
/**
* Catch all other method calls
**/
public function __call ($func, $args)
{
$func = strtolower($func);
switch ($func)
{
case 'fget':
case 'fpost':
case 'fcookie':
case 'fenv':
case 'fserver':
case 'ffile':
// filter plugins
if (!$this->storage->plugins->is_loaded('XnyoFilter', XNYO_PLUGIN_CLASS))
throw new XnyoError('Unable to filter variable as the Filter plugin is not loaded.');
return call_user_func_array(array($this->storage->filter, $func), $args);
case 'login':
case 'logout':
case 'check':
case 'setacl':
// session plugins
if (!$this->storage->plugins->is_loaded('XnyoSession', XNYO_PLUGIN_CLASS))
$this->load('XnyoSession', XNYO_PLUGIN_CLASS);
return call_user_func_array(array($this->storage->session, $func), $args);
case 'getclienterrors':
// error plugin
return call_user_func_array(array($this->storage->error, 'get'), array(CLIENT));
default:
throw new XnyoError('Call to non-existant method <b>%s</b> on Xnyo object.', $func);
}
}
/**
* Output Buffer Handler
*
* This is the output buffer callback function set in the constructor to feed the cache system
* and allow for the generation of the debug console
**/
public function ob_handler ($buf)
{
// destructor function
if (!empty($this->options->destructor) && is_callable($this->options->destructor))
{
call_user_func($this->options->destructor);
}
// trim whitespaces!
if ($this->options->trim)
$buf = XnyoInput::trim_whitespace($buf);
// debug? attach the console!
if (XNYO_DEBUG)
{
$this->d('Generating debug console.');
$buf .= $this->storage->debug->build();
}
//$buf .= $this->storage->debug->build();
// if its not set to compress the page, output a Content-Length header.
// zlib takes care of it if it is compressed
//if (!ini_get('zlib.output_compression'))
// header('Content-Length: '.strlen($buf));
// no caching if debug is on, just go!
if (XNYO_DEBUG)
return $buf;
// caching stuff goes here
if (XNYO_CACHE)
$this->storage->cache->write($buf);
// finished, return data
return $buf;
}
/**
* PHP Error Handler
**/
public function php_error_handler ($code, $msg, $file, $line)
{
switch ($code)
{
case WARNING:
case E_WARNING:
$e = new XnyoWarning($msg);
break;
case NOTICE:
case E_NOTICE:
$e = new XnyoNotice($msg);
break;
case E_STRICT:
$e = new XnyoStrict($msg);
break;
case ERROR:
case E_ERROR:
default:
$e = new XnyoError($msg);
break;
}
$e->overrideFile($file, $line);
$this->storage->error->raise($e);
}
/**
* Exception Handler
**/
public function exception_handler ($e)
{
// if the error handler hasn't loaded we'd best let PHP handle it
if (!is_object($this->storage->error))
throw $e;
// let the Xnyo error handler take care of it.
$this->storage->error->raise($e);
}
}
/**
* Autoload handler!
**/
function __autoload ($class)
{
global $xnyo_parent;
try
{
$xnyo_parent->inc($class);
} catch (XnyoError $e)
{
}
}
