<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
 * Code Igniter
 *
 * An open source application development framework for PHP 4.3.2 or newer
 *
 * @package		CodeIgniter
 * @author		Rick Ellis
 * @copyright	Copyright (c) 2006, pMachine, Inc.
 * @license		http://www.codeignitor.com/user_guide/license.html 
 * @link		http://www.codeigniter.com
 * @since		Version 1.0
 * @filesource
 */
 
// ------------------------------------------------------------------------

/**
 * Common Functions
 *
 * Loads the base classes and executes the request. 
 * 
 * @package		CodeIgniter
 * @subpackage	codeigniter
 * @category	Common Functions
 * @author		Rick Ellis
 * @link		http://www.codeigniter.com/user_guide/
 */
 
// ------------------------------------------------------------------------

/**
* Class registry
*
* This function acts as a singleton.  If the requested class does not
* exist it is instantiated and set to a static variable.  If it has
* previously been instantiated the variable is returned.
* 
* @access	public
* @param	string	the class name being requested
* @param	bool	optional flag that lets classes get loaded but not instantiated
* @return	object
*/
function &load_class($class, $instantiate = TRUE)
{
	static $objects = array();

	// Does the class exist?  If so, we're done...
	if (isset($objects[$class]))
	{
		return $objects[$class];
	}
	
	// This is a special case.  It's a class in the Base5.php file
	// which we don't need to load.  We only instantiate it.
	if ($class == 'Instance')
	{
		$objects[$class] =& new $class();
		return $objects[$class];
	}
		
	// If the requested class does not exist in the application/libraries
	// folder we'll load the native class from the system/libraries folder.
	
	$is_subclass = FALSE;	
	if ( ! file_exists(APPPATH.'libraries/'.$class.EXT))
	{
		require(BASEPATH.'libraries/'.$class.EXT);		
	}
	else
	{
		// A core class can either be extended or replaced by putting an
		// identically named file in the application/libraries folder. 
		// We need to determine, however, if the class being requested is
		// a sub-class of an existing library or an independent instance
		// since each needs to be handled slightly different. 
		// To do this we'll open the requested class and read the top portion
		// of it. If the class extends a base class we will load the base first.
		// If it doesn't extend the base we'll only load the requested class.
		
		// Note: I'm not thrilled with this approach since it requires us to
		// read the top part of the file (I set a character limit of 5000 bytes,
		// which correlates to roughly the first 100 lines of code), but
		// I can't think of a better way to allow classes to be extended or
		// replaced on-the-fly with nothing required for the user to do
		// except write the declaration.  Fortunately PHP is ridiculously fast
		// at file reading operations so I'm not able to discern a performance
		// hit based on my benchmarks, assuming only a small number of core
		// files are being extended, which will usually be the case.
		
		$fp	= fopen(APPPATH.'libraries/'.$class.EXT, "rb");
		
		if (preg_match("/MY_".$class."\s+extends\s+CI_".$class."/i", fread($fp, '6000')))
		{
			require(BASEPATH.'libraries/'.$class.EXT);	
			require(APPPATH.'libraries/'.$class.EXT);
			$is_subclass = TRUE;
		}
		else
		{
			require(APPPATH.'libraries/'.$class.EXT);
		}
		fclose($fp);	
	}

	if ($instantiate == FALSE)
	{
		$objects[$class] = TRUE;
		return $objects[$class];
	}
		
	if ($is_subclass == TRUE)
	{
		$name = 'MY_'.$class;
		$objects[$class] =& new $name();
		return $objects[$class];
	}

	$name = ($class != 'Controller') ? 'CI_'.$class : $class;
	
	$objects[$class] =& new $name();
	return $objects[$class];
}

/**
* Loads the main config.php file
*
* @access	private
* @return	array
*/
function &get_config()
{
	static $main_conf;
		
	if ( ! isset($main_conf))
	{
		if ( ! file_exists(APPPATH.'config/config'.EXT))
		{
			show_error('The configuration file config'.EXT.' does not exist.');
		}
		
		require(APPPATH.'config/config'.EXT);
		
		if ( ! isset($config) OR ! is_array($config))
		{
			show_error('Your config file does not appear to be formatted correctly.');
		}

		$main_conf[0] =& $config;
	}
	return $main_conf[0];
}


/**
* Error Handler
*
* This function lets us invoke the exception class and
* display errors using the standard error template located 
* in application/errors/errors.php
* This function will send the error page directly to the 
* browser and exit.
*
* @access	public
* @return	void
*/
function show_error($message)
{
	$error =& load_class('Exceptions');
	echo $error->show_error('An Error Was Encountered', $message);
	exit;
}


/**
* 404 Page Handler
*
* This function is similar to the show_error() function above
* However, instead of the standard error template it displays
* 404 errors.
*
* @access	public
* @return	void
*/
function show_404($page = '')
{
	$error =& load_class('Exceptions');
	$error->show_404($page);
	exit;
}


/**
* Error Logging Interface 
*
* We use this as a simple mechanism to access the logging
* class and send messages to be logged.
*
* @access	public
* @return	void
*/
function log_message($level = 'error', $message, $php_error = FALSE)
{
	static $LOG;
	
	$config = get_config();
	if ($config['log_errors'] === FALSE)
	{
		return;
	}

	$LOG =& load_class('Log');	
	$LOG->write_log($level, $message, $php_error);
}


/**
* Exception Handler
*
* This is the custom exception handler we defined at the
* top of this file. The main reason we use this is permit 
* PHP errors to be logged in our own log files since we may 
* not have access to server logs. Since this function
* effectively intercepts PHP errors, however, we also need
* to display errors based on the current error_reporting level.
* We do that with the use of a PHP error template.
*
* @access	private
* @return	void
*/
function _exception_handler($severity, $message, $filepath, $line)
{	
	 // We don't bother with "strict" notices since they will fill up
	 // the log file with information that isn't normally very
	 // helpful.  For example, if you are running PHP 5 and you
	 // use version 4 style class functions (without prefixes
	 // like "public", "private", etc.) you'll get notices telling
	 // you that these have been deprecated.
	 
	if ($severity == E_STRICT)
	{
		return;
	}

	$error =& load_class('Exceptions');

	// Should we display the error?  
	// We'll get the current error_reporting level and add its bits
	// with the severity bits to find out.
	
	if (($severity & error_reporting()) == $severity)
	{
		$error->show_php_error($severity, $message, $filepath, $line);
	}
	
	// Should we log the error?  No?  We're done...
	$config = get_config();
	if ($config['log_errors'] === FALSE)
	{
		return;
	}

	$error->log_exception($severity, $message, $filepath, $line);
}


?>