<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
 * CodeIgniter
 *
 * An open source application development framework for PHP 5.1.6 or newer
 *
 * @package		CodeIgniter
 * @author		ExpressionEngine Dev Team
 * @copyright	Copyright (c) 2008 - 2010, 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
 * @PHP4
 *
 * @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 OR strpos($cell, $enclosure) !== FALSE OR 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 OR $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 */