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

// ------------------------------------------------------------------------

/**
 * CodeIgniter Compatibility Helpers
 *
 * This helper contains some functions based on the PEAR PHP_Compat library
 * http://pear.php.net/package/PHP_Compat
 * 
 * The PEAR compat library is a little bloated and the code doesn't harmonize
 * well with CodeIgniter, so those functions have been refactored.
 * We cheat a little and use CI's _exception_handler() to output our own PHP errors
 * so that the behavior fully mimicks the PHP 5 counterparts.  -- Derek Jones
 * 
 * @package		CodeIgniter
 * @subpackage	Helpers
 * @category	Helpers
 * @author		ExpressionEngine Dev Team
 * @link		http://codeigniter.com/user_guide/helpers/compatibility_helper.html
 */

// ------------------------------------------------------------------------

if (! defined('PHP_EOL'))
{
	define('PHP_EOL', (DIRECTORY_SEPARATOR == '/') ? "\n" : "\r\n");
} 

// ------------------------------------------------------------------------

/**
 * file_put_contents()
 *
 * Writes a string to a file
 * http://us.php.net/manual/en/function.file_put_contents.php
 * argument 4, $context, not supported
 *
 * @access	public
 * @param	string		file name
 * @param	mixed		data to be written
 * @param	int			flags
 * @return	int			length of written string
 */
if (! function_exists('file_put_contents'))
{
	function file_put_contents($filename, $data, $flags = NULL)
	{
		if (is_scalar($data))
		{
			settype($data, 'STRING');
		}

		if (! is_string($data) && ! is_array($data) && ! is_resource($data))
		{
			$backtrace = debug_backtrace();
			_exception_handler(E_USER_WARNING, 'file_put_contents(): the 2nd parameter should be either a string or an array', $backtrace[0]['file'], $backtrace[0]['line']);
			return FALSE;
		}

		// read stream if given a stream resource
		if (is_resource($data))
		{
			if (get_resource_type($data) !== 'stream')
			{
				$backtrace = debug_backtrace();
				_exception_handler(E_USER_WARNING, 'file_put_contents(): supplied resource is not a valid stream resource', $backtrace[0]['file'], $backtrace[0]['line']);
				return FALSE;
			}

			$text = '';
			
			while (! feof($data))
			{
				$text .= fread($data, 4096);
			}
			
			$data = $text;
			unset($text);
		}
	
		// strings only please!
		if (is_array($data))
		{
			$data = implode('', $data);
		}

		// Set the appropriate mode
		if (($flags & 8) > 0) // 8 = FILE_APPEND flag
		{
			$mode = FOPEN_WRITE_CREATE;
		}
		else
		{
			$mode = FOPEN_WRITE_CREATE_DESTRUCTIVE;
		}
	
		// Check if we're using the include path
		if (($flags & 1) > 0) // 1 = FILE_USE_INCLUDE_PATH flag
		{
			$use_include_path = TRUE;
		}
		else
		{
			$use_include_path = FALSE;
		}
	
		$fp = @fopen($filename, $mode, $use_include_path);
	
		if ($fp === FALSE)
		{
			$backtrace = debug_backtrace();
			_exception_handler(E_USER_WARNING, 'file_put_contents('.htmlentities($filename).') failed to open stream', $backtrace[0]['file'], $backtrace[0]['line']);
			return FALSE;
		}
	
		if (($flags & LOCK_EX) > 0)
		{
			if (! flock($fp, LOCK_EX))
			{
				$backtrace = debug_backtrace();
				_exception_handler(E_USER_WARNING, 'file_put_contents('.htmlentities($filename).') unable to acquire an exclusive lock on file', $backtrace[0]['file'], $backtrace[0]['line']);
				return FALSE;
			}
		}
		
		// write it
		if (($written = @fwrite($fp, $data)) === FALSE)
		{
			$backtrace = debug_backtrace();
			_exception_handler(E_USER_WARNING, 'file_put_contents('.htmlentities($filename).') failed to write to '.htmlentities($filename), $backtrace[0]['file'], $backtrace[0]['line']);
		}
	
		// Close the handle
		@fclose($fp);
	
		// Return length
		return $written;
	}
}

// ------------------------------------------------------------------------

/**
 * fputcsv()
 *
 * Format line as CSV and write to file pointer
 * http://us.php.net/manual/en/function.fputcsv.php
 *
 * @access	public
 * @param	resource	file pointer
 * @param	array		data to be written
 * @param	string		delimiter
 * @param	string		enclosure
 * @return	int			length of written string
 */
if (! function_exists('fputcsv'))
{
	function fputcsv($handle, $fields, $delimiter = ',', $enclosure = '"')
	{
		// Checking for a handle resource
		if (! is_resource($handle))
		{
			$backtrace = debug_backtrace();
			_exception_handler(E_USER_WARNING, 'fputcsv() expects parameter 1 to be stream resource, '.gettype($handle).' given', $backtrace[0]['file'], $backtrace[0]['line']);
			return FALSE;
		}
	
		// OK, it is a resource, but is it a stream?
		if (get_resource_type($handle) !== 'stream')
		{
			$backtrace = debug_backtrace();
			_exception_handler(E_USER_WARNING, 'fputcsv() expects parameter 1 to be stream resource, '.get_resource_type($handle).' given', $backtrace[0]['file'], $backtrace[0]['line']);
			return FALSE;
		}
	
		// Checking for an array of fields
		if (! is_array($fields))
		{
			$backtrace = debug_backtrace();
			_exception_handler(E_USER_WARNING, 'fputcsv() expects parameter 2 to be array, '.gettype($fields).' given', $backtrace[0]['file'], $backtrace[0]['line']);
			return FALSE;
		}
	
		// validate delimiter
		if (strlen($delimiter) > 1)
		{
			$delimiter = substr($delimiter, 0, 1);
			$backtrace = debug_backtrace();
			_exception_handler(E_NOTICE, 'fputcsv() delimiter must be one character long, "'.htmlentities($delimiter).'" used', $backtrace[0]['file'], $backtrace[0]['line']);
		}
	
		// validate enclosure
		if (strlen($enclosure) > 1)
		{
			$enclosure = substr($enclosure, 0, 1);
			$backtrace = debug_backtrace();
			_exception_handler(E_NOTICE, 'fputcsv() enclosure must be one character long, "'.htmlentities($enclosure).'" used', $backtrace[0]['file'], $backtrace[0]['line']);

		}
	
		$out = '';
	
		foreach ($fields as $cell)
		{
			$cell = str_replace($enclosure, $enclosure.$enclosure, $cell);

			if (strpos($cell, $delimiter) !== FALSE || strpos($cell, $enclosure) !== FALSE || strpos($cell, "\n") !== FALSE)
			{
				$out .= $enclosure.$cell.$enclosure.$delimiter;
			}
			else
			{
				$out .= $cell.$delimiter;
			}
		}
	
		$length = @fwrite($handle, substr($out, 0, -1)."\n");
	
		return $length;
	}
}

// ------------------------------------------------------------------------

/**
 * stripos()
 *
 * Find position of first occurrence of a case-insensitive string
 * http://us.php.net/manual/en/function.stripos.php
 *
 * @access	public
 * @param	string		haystack
 * @param	string		needle
 * @param	int			offset
 * @return	int			numeric position of the first occurrence of needle in the haystack
 */
if (! function_exists('stripos'))
{
	function stripos($haystack, $needle, $offset = NULL)
	{
		// Cast non string scalar values
		if (is_scalar($haystack))
		{
			settype($haystack, 'STRING');
		}
	
		if (! is_string($haystack))
		{
			$backtrace = debug_backtrace();
			_exception_handler(E_USER_WARNING, 'stripos() expects parameter 1 to be string, '.gettype($haystack).' given', $backtrace[0]['file'], $backtrace[0]['line']);
			return FALSE;
		}
	
		if (! is_scalar($needle))
		{
			$backtrace = debug_backtrace();
			_exception_handler(E_USER_WARNING, 'stripos() needle is not a string or an integer in '.$backtrace[0]['file'], $backtrace[0]['line']);
			return FALSE;
		}
	
		if (is_float($offset))
		{
			$offset = (int)$offset;
		}
	
		if (! is_int($offset) && ! is_bool($offset) && ! is_null($offset))
		{
			$backtrace = debug_backtrace();
			_exception_handler(E_USER_WARNING, 'stripos() expects parameter 3 to be long, '.gettype($offset).' given', $backtrace[0]['file'], $backtrace[0]['line']);
			return NULL;
		}
	
		return strpos(strtolower($haystack), strtolower($needle), $offset);
	}
}

// ------------------------------------------------------------------------

/**
 * str_ireplace()
 *
 * Find position of first occurrence of a case-insensitive string
 * http://us.php.net/manual/en/function.str-ireplace.php
 * (parameter 4, $count, is not supported as to do so in PHP 4 would make
 * it a required parameter)
 *
 * @access	public
 * @param	mixed		search
 * @param	mixed		replace
 * @param	mixed		subject
 * @return	int			numeric position of the first occurrence of needle in the haystack
 */
if (! function_exists('str_ireplace'))
{
	function str_ireplace($search, $replace, $subject)
	{
		// Nothing to do here
		if ($search === NULL || $subject === NULL)
		{
			return $subject;
		}
	
		// Crazy arguments
		if (is_scalar($search) && is_array($replace))
		{
			$backtrace = debug_backtrace();

			if (is_object($replace))
			{
				show_error('Object of class '.get_class($replace).' could not be converted to string in '.$backtrace[0]['file'].' on line '.$backtrace[0]['line']);
			}
			else
			{
				_exception_handler(E_USER_NOTICE, 'Array to string conversion in '.$backtrace[0]['file'], $backtrace[0]['line']);
			}
		}
	
		// Searching for an array
		if (is_array($search))
		{
			// Replacing with an array
			if (is_array($replace))
			{
				$search = array_values($search);
				$replace = array_values($replace);

				if (count($search) >= count($replace))
				{
					$replace = array_pad($replace, count($search), '');
				}
				else
				{
					$replace = array_slice($replace, 0, count($search));
				}
			}
			else
			{
				// Replacing with a string all positions
				$replace = array_fill(0, count($search), $replace);
			}
		}
		else
		{
			//Searching for a string and replacing with a string.
			$search  = array((string)$search);
			$replace = array((string)$replace);
		}
		
		// Prepare the search array
		foreach ($search as $search_key => $search_value)
		{
			$search[$search_key] = '/'.preg_quote($search_value, '/').'/i';
		}
		
		// Prepare the replace array (escape backreferences)
		foreach ($replace as $k => $v)
		{
			$replace[$k] = str_replace(array(chr(92), '$'), array(chr(92).chr(92), '\$'), $v);
		}
	
		// do the replacement
		$result = preg_replace($search, $replace, (array)$subject);
	
		// Check if subject was initially a string and return it as a string
		if (! is_array($subject))
		{
			return current($result);
		}
	
		// Otherwise, just return the array
		return $result;
	}
}

// ------------------------------------------------------------------------

/**
 * http_build_query()
 *
 * Generate URL-encoded query string
 * http://us.php.net/manual/en/function.http-build-query.php
 *
 * @access	public
 * @param	array		form data
 * @param	string		numeric prefix
 * @param	string		argument separator
 * @return	string		URL-encoded string
 */
if (! function_exists('http_build_query'))
{
	function http_build_query($formdata, $numeric_prefix = NULL, $separator = NULL)
	{
		// Check the data
		if (! is_array($formdata) && ! is_object($formdata))
		{
			$backtrace = debug_backtrace();
			_exception_handler(E_USER_WARNING, 'http_build_query() Parameter 1 expected to be Array or Object. Incorrect value given', $backtrace[0]['file'], $backtrace[0]['line']);
			return FALSE;
		}
	
		// Cast it as array
		if (is_object($formdata))
		{
			$formdata = get_object_vars($formdata);
		}
	
		// If the array is empty, return NULL
		if (empty($formdata))
		{
			return NULL;
		}
	
		// Argument separator
		if ($separator === NULL)
		{
			$separator = ini_get('arg_separator.output');

			if (strlen($separator) == 0)
			{
				$separator = '&';
			}
		}
	
		// Start building the query
		$tmp = array();

		foreach ($formdata as $key => $val)
		{
			if ($val === NULL)
			{
				continue;
			}
	
			if (is_integer($key) && $numeric_prefix != NULL)
			{
				$key = $numeric_prefix.$key;
			}
	
			if (is_resource($val))
			{
				return NULL;
			}
			
			// hand it off to a recursive parser
			$tmp[] = _http_build_query_helper($key, $val, $separator);
		}
	
		return implode($separator, $tmp);
	}
	
	
	// Helper helper.  Remind anyone of college?
	// Required to handle recursion in nested arrays.
	// 
	// You could shave fractions of fractions of a second by moving where
	// the urlencoding takes place, but it's much less intuitive, and if
	// your application has 10,000 form fields, well, you have other problems ;)
	function _http_build_query_helper($key, $val, $separator = '&')
	{	
		if (is_scalar($val))
		{
			return urlencode($key).'='.urlencode($val);			
		}
		else
		{
			// arrays please
			if (is_object($val))
			{
				$val = get_object_vars($val);
			}
			
			foreach ($val as $k => $v)
			{
				$tmp[] = _http_build_query_helper($key.'['.$k.']', $v, $separator);
			}
		}
			
		return implode($separator, $tmp);
	}
}


/* End of file compatibility_helper.php */
/* Location: ./system/helpers/compatibility_helper.php */