Location: PHPKode > projects > tgsf > tgsf-0.9.2/tgsf_core/tgSimpleFramework.php
<?php defined( 'BASEPATH' ) or die( 'Restricted' );
/*
This code is copyright 2009-2010 by TMLA INC.  ALL RIGHTS RESERVED.
Please view license.txt in /tgsf_core/legal/license.txt or
http://tgWebSolutions.com/opensource/tgsf/license.txt
for complete licensing information.
*/

define( 'REPORT_EOL', "\n" );
define( 'EXT', '.php' );
define( 'PHP', '.php' );

define( 'JS', '.js' );
define( 'CSS', '.css' );
define( 'HTML', '.html' );
define( 'HTM', '.htm' );

define( 'PNG', '.png' );
define( 'JPG', '.jpg' );
define( 'JPEG', '.jpeg' );
define( 'GIF', '.gif' );
//------------------------------------------------------------------------
define( 'IS_CORE_PATH', true );
define( 'IS_CORE_LIB', true );
define( 'IS_CORE_CONFIG', true );
define( 'IS_CORE', true );
define( 'IS_APP', false );
define( 'IS_CORE_TEMPLATE', true );
define( 'IS_APP_TEMPLATE', false );
//------------------------------------------------------------------------
define( 'ENUM_USE_VALUE', true );
//------------------------------------------------------------------------
define( 'SALT_LENGTH', 40 );
//------------------------------------------------------------------------
// used when redirecting - used in tgsfUrl.php
define( 'DO_NOT_EXIT', false );
//------------------------------------------------------------------------
define( 'GET_DUMP_HTML', true );
//------------------------------------------------------------------------
define( 'IMAGE_URL_ABSOLUTE', true );
define( 'IMAGE_URL_RELATIVE', false );
//------------------------------------------------------------------------
function current_server_id()
{
	if ( TGSF_CLI )
	{
		return strtoupper( md5 ( __FILE__ . PHP_OS ) );
	}

	return strtoupper( md5( current_host() . current_base_url_path() ) );
}
//------------------------------------------------------------------------
function show_current_server_id_parts()
{
	 echo __FILE__ . PHP_OS;
}
//------------------------------------------------------------------------
//
/**
* @param String The folder
* @param Is the folder located in the core (assets is parsed correctly)
*/
function relative_path( $folder, $core = false )
{
	$folder = trim( $folder, ' /' );

	if ( $core === IS_CORE_PATH )
	{
		$root = 'tgsf_core/';
		if ( starts_with( $folder, 'assets' ) )
		{
			$root = 'tgsf_core_assets/';
			$folder = trim( substr( $folder, 6 ), ' /' );
		}
	}
	else
	{
		$root = APP_FOLDER;
	}

	if ( $folder != '' )
	{
		$folder .= '/';
	}

	return $root . $folder;
}
//------------------------------------------------------------------------
function path( $folder, $core = false )
{
	return BASEPATH . relative_path( $folder, $core );
}
//------------------------------------------------------------------------
function asset_path( $folder, $core = false )
{
	$folder = trim( 'assets/' . $folder, ' /' );
	return path( $folder, $core );
}
//------------------------------------------------------------------------
function css_path( $folder = '', $core = false )
{
	$folder = trim( 'css/' . $folder, ' /' );
	return asset_path( $folder, $core );
}
//------------------------------------------------------------------------
function js_path( $folder = '', $core = false )
{
	$folder = trim( 'js/' . $folder, ' /' );
	return asset_path( $folder, $core );
}
//------------------------------------------------------------------------
function jquery_path( $folder = '' )
{
	$folder = trim( 'jquery/' . $folder, ' /' );
	return js_path( $folder, IS_CORE_PATH );
}
//------------------------------------------------------------------------
function url_path( $folder, $core = false )
{
	return current_base_url() . relative_path( $folder, $core );
}
//------------------------------------------------------------------------
function can_plugin()
{
	return function_exists( 'do_filter' );
}
//------------------------------------------------------------------------
function load_library( $name, $core = false )
{
	$path = path( 'libraries', $core );

	return require_once  $path . $name . PHP;
}
//------------------------------------------------------------------------
function load_search( $name, $core = false )
{
	return load_cloned_object( path( 'searches', $core ), $name );
}
//------------------------------------------------------------------------
function load_report( $name, $core = false )
{
	load_library( 'report/tgsfReport', IS_CORE_LIB );
	return load_cloned_object( path( 'reports', $core ), $name );
}
//------------------------------------------------------------------------
/**
* Loads an instantiated template library.  Works just like models.
* Unlike most other load functions, this one is controlled by a global variable
* that is located in the front controller index.php
* @param String The path and name (minus the extension) of the template library
* @see load_cloned_object
*/
function &load_template_library( $name, $core = true )
{
	return load_cloned_object( path( 'libraries/templates', $core ), $name );
}
//------------------------------------------------------------------------
/**
* Loads a form.  Works just like models.
* @param String The path and name (minus the extension) of the form to load)
* This is prefixed by the current application's forms path
* @param Bool Is the form located in the core?  This would only be for built in forms
* like might be used in a core library (like a user lib).
* @see load_cloned_object
*/
function &load_form( $name, $core = false )
{
	return load_cloned_object( path( 'forms', $core ), $name );
}
//------------------------------------------------------------------------
/**
* The first time a model is loaded, this function will require_once on the model file.
* It will take the return value from that required file and use it as an internal instance
* of that model.
* All return values from this function will be performed using object cloning.
* if a model has already loaded, a new instance is returned and no further filesystem
* access occurs.
* Model files are required to return a new instance of the model
* Models should not require constructor parameters as this loader will know nothing about that.
* @param String The path and name of the model.  This is prefixed by the application's
* model's path
* @param Bool Is the model located in the core?  This would only be used for built in models
* like might be used in a core library (like a user lib).
* @see load_cloned_object
*/
function &load_model( $name, $core = false )
{
	return load_cloned_object( path( 'models', $core ), $name );
}
//------------------------------------------------------------------------
/**
* Works like models and forms.  Used for grids (html tables)
* @param String The path and name of the model.  This is prefixed by the application's
* grid's path
* @param Bool Is the grid located in the core?  This would only be used for built in grids
* like might be used in a core library (like a user lib).
* @see load_cloned_object
*/
function &load_grid( $name, $core = false )
{
	return load_cloned_object( path( 'grids', $core ), $name );
}
//------------------------------------------------------------------------
/**
* Requires a file based on path and name.  Stores the return value from that included file
* in a static array.  Assumes return values are object instances.
* Returns a clone of that return value.  If a file has already been included, we skip the require_once
* and simply return a clone of the original that has been stored in the static array.
* @param String The path to the file.
* @param String The name of the file - without the php extension
*/
function &load_cloned_object( $path, $name )
{
	static $masterObjects = array();

	$file = $path . $name . PHP;

	if ( ! in_array( $file, array_keys( $masterObjects ) ) )
	{
		$obj = require_once( $file );

		if ( ! is_object( $obj ) )
		{
			throw new tgsfException( "You must return an object instance when loading {$file}" );
		}

		$masterObjects[$file] =& $obj;
	}

	$returnObj = clone $masterObjects[$file];
	return $returnObj;
}
//------------------------------------------------------------------------
function load_config( $name, $core=false )
{
	global $config;
	global $plugins;

	// while bootstrapping we don't have the plugin functions, but later on we will
	if ( can_plugin() )
	{
		$name = do_filter( 'load_config', $name );

		$action = ($core?'core-':'') . 'config' . $name;
		do_action( $action );
	}

	require_once path( 'config', $core ) . $name . PHP;
}
//------------------------------------------------------------------------
function load_database_libraries()
{
	// db search extends grid
	load_library( 'html/tgsfGrid', IS_CORE_LIB );
	
	// enums for the database libraries
	load_library( 'db/enum',				IS_CORE_LIB );
	load_library( 'db/dbManager',			IS_CORE_LIB );
	load_library( 'db/dbSetup',				IS_CORE_LIB );
	load_library( 'db/queryJoin',			IS_CORE_LIB );
	load_library( 'db/query',				IS_CORE_LIB );
	load_library( 'db/tgsfPaginateQuery',	IS_CORE_LIB );
	load_library( 'db/tgsfDbSearch',		IS_CORE_LIB );
	load_library( 'db/foreignKey',			IS_CORE_LIB );
	load_library( 'db/field',				IS_CORE_LIB );
	load_library( 'db/dbIndex',				IS_CORE_LIB );
	load_library( 'db/table',				IS_CORE_LIB );
	load_library( 'db/model',				IS_CORE_LIB );
	load_library( 'db/dbDataSource',		IS_CORE_LIB );
}
//------------------------------------------------------------------------
function load_form_libraries()
{
	load_library( 'html/tgForm',			IS_CORE_LIB );
	load_library( 'html/tgFormField',		IS_CORE_LIB );
}
//------------------------------------------------------------------------
function maintenance_mode_check()
{
	do_action( 'maintenance_mode_check' );

	if ( config( 'maintenanceMode' ) )
	{
		if ( ! isset( $_GET[config( 'maintenanceModeVar' )] ) || $_GET[config( 'maintenanceModeVar' )] != config('maintenanceModeVarValue' )  )
		{
			do_action( 'maintenance_mode_message' );
			echo 'Our website is currently down for maintenance. Please check back a little later.';
			exit();
		}
	}
}
//------------------------------------------------------------------------
function force_no_www( $checkFor = true )
{
	global $config;
	if ( starts_with( $_SERVER['HTTP_HOST'], 'www.' ) )
	{
		$config['host_www'] = false;
		URL( $_SERVER['REQUEST_URI'] )->permRedirect();
	}
}
//------------------------------------------------------------------------
/**
* Forces a reload (permanent redirect) to the base url as defined in your config file.
*/
function force_www()
{
	global $config;
	$config['host_www'] = true;
	if ( ! starts_with( current_host(), 'www.' ) )
	{
		URL( $_SERVER['REQUEST_URI'] )->permRedirect();
	}
}
//------------------------------------------------------------------------
function force_trailing_slash()
{
	define( 'tgTrailingSlash', true );

	if ( empty( $_SERVER['REDIRECT_QUERY_STRING'] ) && ! empty( $_SERVER['REDIRECT_URL'] ) && strlen( $_SERVER['REDIRECT_URL'] ) && substr( $_SERVER['REDIRECT_URL'], -1 ) != '/' )
	{
		$page = tgsf_parse_url();
		$vars = empty( $_GET['__tgsf_vars'] )?array():$_GET['__tgsf_vars'];

		$extra = '';
		if ( count( $vars ) )
		{
			$extra = '_/';

			foreach ( $vars as $name => $val )
			{
				$extra .= $name . '/' . $val . '/';
			}
			$extra = trim( $extra, ' /' ) . '/';
		}

		$url = current_base_url() . $page . '/' . $extra;

		if ( can_plugin() )
		{
			$url = do_filter( 'force_trailing_slash_redirect_url', $url );
			do_action( 'force_trailing_slash_redirect', $url );
		}

	 	header( "HTTP/1.1 301 Moved Permanently" );
	    header( 'Location: ' . $url );
	    exit();
	}
}
//------------------------------------------------------------------------
function force_https()
{
	if ( TGSF_CLI === true )
	{
		return;
	}

	if ( current_has_ssl() == false )
	{
		header( "HTTP/1.1 301 Moved Permanently" );
	    header( 'Location: ' . current_https_url() );
		exit();
	}
}
//------------------------------------------------------------------------
function config( $item, $defaultValue = false )
{
	global $config;

	$retVal = $defaultValue;
	if ( isset( $config[$item] ) )
	{
		$retVal = $config[$item];
	}

	if ( can_plugin() )
	{
		$retVal = do_filter( 'config_item', $retVal );
	}

	return $retVal;
}
//------------------------------------------------------------------------
function cli_controller_exists( $name, $core = false )
{
	return file_exists( cli_controller( $name, $core ) );
}
//------------------------------------------------------------------------
function controller_exists( $name, $core = false )
{
	return file_exists( controller( $name, $core ) );
}
//------------------------------------------------------------------------
function cli_controller( $name, $core = false )
{
	return path( 'cli', $core ) . $name . PHP;
}
//------------------------------------------------------------------------
function controller( $name, $core = false )
{
	return path( 'controllers', $core ) . $name . PHP;
}
//------------------------------------------------------------------------
function view( $name, $core = false )
{
	return path( 'views', $core ) . $name . PHP;
}
//------------------------------------------------------------------------
function get_view_content( $name, $vars = array(), $core = false )
{
	extract( $vars );
	ob_start();
	include view( $name, $core );
	return ob_get_clean();
}
//------------------------------------------------------------------------
function image( $file, $core = false )
{
	$root = path( 'assets', $core );
	$root .= path( 'images' );

	return $root . $file;
}
//------------------------------------------------------------------------
function image_url( $file, $absolute = false, $core = false )
{
	$loc = url_path( 'assets/images', $core );

	if ( $absolute )
	{
		$loc = '';
	}

	return $loc . $file;
}
//------------------------------------------------------------------------
function plugin( $file, $core = false )
{
	return path( 'plugins', $core ) . $file . PHP;
}
//------------------------------------------------------------------------
function font( $file, $core = false )
{
	return path( 'assets', $core ) . 'fonts/' . $file;
}
//------------------------------------------------------------------------
// parse_url is a PHP function, that's why this is named tgsf_parse_url
function tgsf_parse_url()
{
	if ( TGSF_CLI )
	{
		return CLI();
	}

	$baseUrlPart = current_base_url_path();

	$page = empty( $_SERVER['REDIRECT_URL'] ) ? '' : $_SERVER['REDIRECT_URL'];

	$page = substr( ltrim( $page,'/ ' ), strlen( $baseUrlPart ) );

	$pieces = explode( config( 'get_string' ), $page );
	$varPieces = '';
	if ( count( $pieces ) > 1 )
	{
		$page = trim( $pieces[0], '/' );
		$varPieces = $pieces[1];
		tgsf_parse_url_vars( $varPieces );
	}
	$page = trim( $page, ' /' );

    if ( $page == '' )
	{
	    $page = 'home';
	}

	return $page;
}
//------------------------------------------------------------------------
function tgsf_parse_url_vars( $varPieces )
{
	static $vars = null;

	if ( ! $vars === null )
	{
		return $vars;
	}

	// get our pieces by exploding on the slash
	$pieces = array();
	if ( ! is_null( $varPieces ) )
	{
		if ( ends_with( $varPieces, '//' ) )
		{
			$varPieces = trim( $varPieces,'/' ) . '/';
		}
		else
		{
			$varPieces = trim( $varPieces,' /' );
		}

		$pieces = explode( '/', $varPieces );
	}

	// if we have pieces, then loop through them assigning the array [piece1] => piece2
	// throw an error if we have an odd number of pieces
	$pieceCnt = count( $pieces );
	if ( $pieceCnt > 0 )
	{
		for ( $ix = 0; $ix < $pieceCnt; $ix++ )
		{
			$name = $pieces[$ix];
			$val = null;
			if ( isset( $pieces[$ix+1] ) )
			{
				$val = $pieces[$ix+1];
			}
			// attempt to set $_GET
			// we don't overwrite existing get vars though
			if ( ! isset( $_GET[$name] ) )
			{
				$_GET[$name] =& $val;
			}

			/*
			// also set $_GET using an underscore prefix
						// this provides an additional attempt in case the first one fails
						// but also provides a way for someone to use _vars for their
						// application in case they decide to use that as a naming convention
						if ( ! isset( $_GET['_' . $name] ) )
						{
							$_GET['_' . $name] =& $val;
						}*/


			$vars[$name] =& $val;
			$ix++;
			unset( $val );
		}

		$_GET['__tgsf_vars'] =& $vars;

		if ( $pieceCnt % 2 != 0  )
		{
			throw new tgsfException( 'Count of variables is not even - pass variables using name/value pairs' );
		}
	}
	return $vars;
}
//------------------------------------------------------------------------
function url_array()
{
	return explode( '/', tg_parse_url() );
}
//------------------------------------------------------------------------
function display_404( $page = null )
{
	if ( $page === null )
	{
		$page = $GLOBALS['page'];
	}

	require get_404( $page );
	exit();
}
//------------------------------------------------------------------------
function get_404( $page )
{
	do_action( 'pre_404', $page );
	// we don't output 404 headers here so that the 404 controller can make choices of its own
	// it should output the 404 header.
	$out = controller( '404' );
	$out = do_filter( 'controller_404', $out, $page );
	return $out;
}
//------------------------------------------------------------------------
function resolve_controller( $page )
{
	do_action( 'pre_resolve_controller', $page );
	$page = do_filter( 'pre_resolve_controller', $page );

	if ( controller_exists( $page ) )
	{
		$out = controller( $page );
	}
	else
	{
		if ( controller_exists( $page . '/index' ) )
		{
			$out = controller( $page . '/index' );
		}
		else
		{
			$out = get_404( $page );
		}
	}

	$out = do_filter( 'post_resolve_controller', $out, $page );
	do_action( 'post_resolve_controller', $page, $out );

	return $out;
}
//------------------------------------------------------------------------
function resolve_cli_controller( $name )
{
	do_action( 'pre_resolve_cli_controller', $name );
	$name = do_filter( 'pre_resolve_cli_controller', $name );

	// check to see if controllers exist in:
	// app/cli/$name.php
	// app/cli/$name/index.php
	// app/controllers/$name.php
	// app/controllers/$name/index.php

	if ( cli_controller_exists( $name ) )
	{
		$out = cli_controller( $name );
	}
	else
	{
		if ( cli_controller_exists( $name . '/index' ) )
		{
			$out = cli_controller( $name . '/index' );
		}
		else
		{
			if ( controller_exists( $name ) )
			{
				$out = controller( $name );
			}
			else
			{
				if ( controller_exists( $name . '/index' ) )
				{
					$out = controller( $name . '/index' );
				}
				else
				{
					show_error( 'Missing CLI Controller' );
				}
			}
		}
	}

	$out = do_filter( 'post_resolve_cli_controller', $out, $name );
	do_action( 'post_resolve_cli_controller', $name, $out );

	return $out;
}
//------------------------------------------------------------------------
function is_gz_capable()
{
	return false;
	$cnt1 = substr_count($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip');
	$cnt2 = substr_count($_SERVER['HTTP_ACCEPT_ENCODING'], '*');

	return $cnt1 > 0 || $cnt2 > 0;
}
//------------------------------------------------------------------------
/**
* Returns true/false if debug_mode has been set in config files
* returns false if the config function hasn't been defined yet since we can't check.
*/
function in_debug_mode()
{
	if ( ! function_exists( 'config' ) || config( 'debug_mode' ) === false )
	{
		return false;
	}

	return true;
}
//------------------------------------------------------------------------
/**
* Selectively buffers content.  This function is plugin enabled so you can hook the filter: 'cancel_content_buffer' to turn off buffering entirely.
* If the user agent is capable of accepting gz compressed output, then we turn on gz compression.
*/
function content_buffer()
{
	global $no_content_buffer;
	$cancel = do_filter( 'cancel_content_buffer', false );

	if ( $cancel )
	{
		$no_content_buffer = true;
		return;
	}

	$no_content_buffer = false;

	if (  is_gz_capable() )
	{
	    //ob_start("ob_gzhandler");
		ob_start();
	}
	else
	{
		//ob_start("ob_gzhandler");
	    ob_start();
	}
}
//------------------------------------------------------------------------
function end_buffer()
{
	global $no_content_buffer;
	if ( $no_content_buffer )
	{
		return;
	}

	ob_end_flush();
}
//------------------------------------------------------------------------
function enable_browser_cache( $file )
{
	$last_modified_time = filemtime( $file );
	$etag = md5_file( $file );

	$lastModified = 'Last-Modified: ' . gmdate( 'D, d M Y H:i:s', $last_modified_time ) . ' GMT';

	$lastModified = do_filter( 'cache_last_modified', $lastModified );
	$etag = do_filter( 'cache_etag', $etag );

	header( $lastModified );
	header( "Etag: $etag" );

	if ( @strtotime( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) == $last_modified_time || trim( $_SERVER['HTTP_IF_NONE_MATCH'] ) == $etag )
	{
	    header( 'HTTP/1.1 304 Not Modified' );
	    exit();
	}
}
//------------------------------------------------------------------------
/**
* Generates an extremely secure password hash (one way) using a salt
* to prevent dictionary attacks against a compromised database
* @param String The clear text password
* @param String The salt (actually a password string produced by this function)
*/
function hash_password( $clearText, $salt = null )
{
    if ( is_null( $salt ) )
    {
        $salt = randomHash( SALT_LENGTH );
    }
    else
    {
        $salt = substr( $salt, 0, SALT_LENGTH );
    }
    $hashed = $salt . sha1($salt . $clearText);
	//do_action( 'hash_password', $hashed, $salt, $clearText );

	// we should never be calling this before the plugin library has loaded
	$hashed = do_filter( 'hash_password', $hashed, $clearText, $salt );
    return $hashed;
}
//------------------------------------------------------------------------
/**
* Random hash - defaults to being 12 characters long
*/
function randomHash( $length = 12 )
{
	return strtoupper( substr( sha1( uniqid( rand(), true ) ), 0, $length ) );
}
//------------------------------------------------------------------------
function randomCode ( $length = 4, $useNumbers = true, $useLower = false, $useSpecial = false )
{
	$set = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';

	if ( $useNumbers )
	{
		$set .= "0123456789";
	}

	if ( $useLower )
	{
		$set .= "abcdefghijklmnopqrstuvwxyz";;
	}

	if ( $useSpecial )
	{
		$set .= "~@#$%^*()_+-={}|][";
	}
	$code = '';
	for ( $ix=0; $ix < $length; $ix++ )
	{
		$code .= $set[(mt_rand(0, (strlen( $set ) - 1 ) ) )];
	}
	return $code;
}
//------------------------------------------------------------------------
/**
* Sends the headers to force a browser to start a download.
* @param String the filename the browser should save the file as
* @param String the file data
* @param String The content-type to send to the browser - defaults to text/plain
*/
function sendDownload( $filename, $data, $type = 'text/plain' )
{
	header( 'Cache-Control: must-revalidate' );
	header( 'Pragma: must-revalidate' );

	header( 'Content-Description: File Transfer' );
 	header( 'Content-Disposition: attachment; filename=' . $filename );
	header( 'Content-Type: ' . $type );
	echo $data;
	exit();
}
//------------------------------------------------------------------------
//------------------------------------------------------------------------
//------------------------------------------------------------------------
//------------------------------------------------------------------------
// log functions
//------------------------------------------------------------------------
function log_exception( $e, $tgsfLogError = false )
{
	$out  = $e->getMessage() . PHP_EOL;
	$out .= 'File: ' . $e->getFile() . PHP_EOL;
	$out .= 'Line: ' . $e->getLine() . PHP_EOL;
	$out .= $e->getTraceAsString();

	if ( can_plugin() )
	{
		$out = do_filter( 'log_exception', $out, $e );
	}
	general_log( $out, 'exception_log.txt' );
}
//------------------------------------------------------------------------
function log_query_error( $query )
{
	if ( can_plugin() )
	{
		$query = do_filter( 'log_query_error', $query );
	}
	general_log( $query, 'query_error_log.txt' );
}
//------------------------------------------------------------------------
function log_error( $message )
{
	if ( can_plugin() )
	{
		$message = do_filter( 'log_error', $message );
	}
	general_log( $message, 'error_log.txt' );
}
//------------------------------------------------------------------------
function general_log( $message, $file = 'general_log.txt' )
{
	$date = new DateTime();
	$cst = new DateTimeZone( 'America/Chicago' );
	$date->setTimezone( $cst );

	$file = clean_text( $file, '_', "." );
	$file = path( 'logs', IS_CORE_PATH ) . $file;

	$out = PHP_EOL . '------------------------------------------------------------------------' . PHP_EOL;
	$out .= $date->format( 'Y-m-d H:i:s T' ) . PHP_EOL;
	$out .= '----------------------' . PHP_EOL;
	$out .= $message . PHP_EOL;

	if ( can_plugin() )
	{
		$out = do_filter( 'general_log', $out, $message );
	}

	try
	{
		file_put_contents( $file, $out, FILE_APPEND );
	}
	catch( Exception $e )
	{
		echo 'Unable to log errors - you should use database logging.';
		exit();
	}
}
//------------------------------------------------------------------------
//------------------------------------------------------------------------
//------------------------------------------------------------------------
//------------------------------------------------------------------------
// utility functions
//------------------------------------------------------------------------
/**
*
*/
function wrap_not_empty( $before, $subject, $after = '' )
{
	if ( ! empty( $subject ) )
	{
		$subject = $before . $subject . $after;
	}

	return $subject;
}
//------------------------------------------------------------------------
/**
* Cleans out possible email header injection attacks.  Spammers try to inject new line characters as delimiters
* so they can put in their own headers in an email message.  We're simply removing them.  these characters
* should not exist in email addresses or in email subjects.  don't use this on message bodies.
* @param String The text to clean (something like an email address that was typed in)
*/
function clean_for_email( $inbound )
{
    return str_replace( array( "\n", "\r" ), "", $inbound );
}
//------------------------------------------------------------------------
/**
* Trims an array - removes empty and null elements
* @param String The entire string to compare against
* @param String The snippet to test for at the beginning of $compare
*/
function trimArray( $inArray )
{
    foreach ( $inArray as $key => $value )
    {
        if ( trim( $value ) !="" )
        {
            if ( is_int( $key ) )
            {
                $outArray[] = trim( $value );
            }
            elseif ( is_string( $key ) )
            {
                $outArray[$key] = trim( $value );
            }
        }
    }

    return $outArray;
}
//------------------------------------------------------------------------
/**
* Returns true if the string to compare starts with the snippet
* @param String The entire string to compare against
* @param String The snippet to test for at the beginning of $compare
*/
function starts_with( $subject, $snippet )
{
	if ( is_array( $snippet ) )
	{
		$out = false;
		foreach ( $snippet as $value )
		{
			if ( $value == substr( $subject, 0, strlen( $value ) ) )
			{
				$out = true;
				break;
			}
		}
	}
	else
	{
		$out = $snippet === substr( $subject, 0, strlen( $snippet ) );
	}

	return $out;
}
//------------------------------------------------------------------------
/**
* Returns true if the string to compare ends with the snippet
* @param String The entire string to compare against
* @param String The snippet to test for at the end of $compare
*/
function ends_with( $subject, $snippet )
{
	if ( is_array( $snippet ) )
	{
		$out = false;
		foreach ( $snippet as $value )
		{
			if ( $value == substr( $subject, -1 * strlen( $value ) ) )
			{
				$out = true;
				break;
			}
		}
	}
	else
	{
		$out = $snippet == substr( $subject, -1 * strlen( $snippet ) );
	}

	return $out;
}
//------------------------------------------------------------------------
/**
* Returns the specified number of tab characters - a silly function
* that only serves to create pretty looking code.
* @param Int The number of tab characters to return.
*/
function tab( $repeat )
{
	return str_repeat( "\t", $repeat );
}
//------------------------------------------------------------------------
/**
* Attempts to simulate the C language enum construct by creating defines
* for the array items passed in.
* @param String The name of the group/prefix for the enum'd values. example: qt or QUERY_TYPE_
* @param Array The array of items to define values for.  If an array key is non-numeric  then that becomes the define name.
* @param bool Should enum use the value for the defined value or use the given array key.  Use define: ENUM_USE_VALUE
* example: $arrayExample['DEF'] = 'value'; enum( 'example', $arrayExample ); creates this define:
* define( 'exampleDEF', 'value' );
*/
function enum( $prefix, $items, $useValueForDefine = false )
{
	if ( $useValueForDefine )
	{
		foreach ( $items as $key => $value )
		{
			define( $prefix . $value, $value );
		}
	}
	else
	{
		foreach ( $items as $key => $value )
		{
			if ( is_numeric( $key ) )
			{
				define( $prefix . $value, $key );
			}
			else
			{
				define( $prefix . $key, $value );
			}
		}
	}
}
//------------------------------------------------------------------------
/**
* Determines if a string is a local file based on whether or not it
* begins with http:// or https://
* @param String The file or path to check
*/
function is_local( $file )
{
	// return if the file does not start with
	return ! starts_with( $file, array( 'http://', 'https://' ) );
}
//------------------------------------------------------------------------
function must_end_with( &$subject, $ending )
{
	if ( ! ends_with( $subject, $ending ) )
	{
		$subject .= $ending;
	}
}
//------------------------------------------------------------------------
function clean_text( $subject, $replace = '_', $extraAllowedChars = '' )
{
	return preg_replace( '/[^a-z0-9' . $extraAllowedChars . ']+/sim', $replace, $subject );
}
//------------------------------------------------------------------------
function zeroPad( $value, $places )
{
	$value = rtrim( substr( $value, 0, $places ), " \n\r0" );
	if ( empty( $value ) )
	{
		return str_repeat( '0', $places );
	}

	if ( strlen( $value ) < $places )
	{
		$value = $value . str_repeat( '0', $places - strlen( $value ) );
	}
	
	return $value;
}
//------------------------------------------------------------------------
function truncateNumberFormat( $value, $places )
{
	$neg = '';
	if ( $value < 0 && $value > -1 )
	{
		$neg = '-';
	}

	$vals = preg_split( '/\\./', (string)$value );

	if ( $places == 0 )
	{
		return $neg . number_format( $vals[0] );
	}

	if ( ! empty( $vals[1] ) )
	{
		return $neg . number_format( $vals[0] ) . '.' . zeroPad( $vals[1], $places );
	}
	else
	{
		return $neg . number_format( $vals[0] ) . '.' . zeroPad( 0, $places );
	}
}
//------------------------------------------------------------------------
function get_dump( &$var, $formatHTML = false )
{
	$prefix = '';
	$postfix = '';

	if ( $formatHTML === true )
	{
		$prefix = '<pre>';
		$postfix = '</pre>';
	}

	ob_start();
	var_dump( $var );
	return $prefix . ob_get_clean() . $postfix;
}
//------------------------------------------------------------------------
function memory_stats()
{
	if ( ! headers_sent() )
	{
		fb( number_format(memory_get_usage()), 'Mem Usage', FirePHP::INFO );
		fb( number_format(memory_get_peak_usage()), 'Mem Usage (Peak)', FirePHP::INFO );
	}
}
//------------------------------------------------------------------------
function tz_convert_string_to_utc( $text, $tz = 'UTC' )
{
	return tz_strtotime( $text, $tz );
}
//------------------------------------------------------------------------
function tz_str_to_utc_ts( $text, $tz  )
{
	return tz_strtotime( $text, $tz );
}
//------------------------------------------------------------------------
/*
 * Convert a date string for a specific timezone into a timestamp
 * @param Str The date string
 * @param Str The timezone of the date string
 * @return Int The timestamp result
 */
function tz_strtotime( $text, $tz = 'UTC' )
{
	if ( empty( $text )  ) return time();

	$ts = strtotime( $text . ' ' . $tz );

	return $ts;
}
//------------------------------------------------------------------------
/*
 * DEPENDENCY: Zend_Date
 * Convert a timestamp into a date string with a specific timezone
 * @param Str The date format to return
 * @param Int The timestamp to offset and stringify
 * @param Str The timezone to use for the return date string
 * @return Str The formatted date string for specified timezone
 */
function tz_date( $format, $ts, $tz = 'UTC' )
{
	// force ts to be a timestamp (integer) - if not an int we force a strtotime
	$ts = is_int( $ts )?$ts:strtotime($ts);

	$date = new Zend_Date( $ts, Zend_Date::TIMESTAMP );
	$date->setTimezone( $tz );
	
	return $date->toString( $format );
}

//------------------------------------------------------------------------
/*
* $ts is expected to be a time stamp.  You can pass a string, but the string
* must already be in UTC - the timezone here is only used for output
* not for translating a passed $ts string
*/
function tz_gmdate_start( $format, $ts, $tz )
{
	$ts = tz_strtotime( tz_date( DT_FORMAT_SQL_START, $ts, $tz ), $tz );
	return gmdate( $format, $ts );
}

//------------------------------------------------------------------------
/*
* $ts is expected to be a time stamp.  You can pass a string, but the string
* must already be in UTC - the timezone here is only used for output
* not for translating a passed $ts string
*/
function tz_gmdate_end( $format, $ts, $tz )
{
	$ts = tz_strtotime( tz_date( DT_FORMAT_SQL_END, $ts, $tz ), $tz );
	return gmdate( $format, $ts );
}
//------------------------------------------------------------------------
Return current item: tgsf