<?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		Rick Ellis
 * @copyright	Copyright (c) 2006, EllisLab, Inc.
 * @license		http://www.codeignitor.com/user_guide/license.html
 * @link		http://www.codeigniter.com
 * @since		Version 1.0
 * @filesource
 */

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

/**
 * CodeIgniter Download Helpers
 *
 * @package		CodeIgniter
 * @subpackage	Helpers
 * @category	Helpers
 * @author		Rick Ellis
 * @link		http://www.codeigniter.com/user_guide/helpers/download_helper.html
 */

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

/**
 * Force Download
 *
 * Generates headers that force a download to happen
 *
 * @access	public
 * @param	string	filename
 * @param	mixed	the data to be downloaded
 * @return	void
 */
function force_download($filename = '', $data = '')
{
	if ($filename == '' OR $data == '')
	{
		return FALSE;
	}

	// Try to determine if the filename includes a file extension.
	// We need it in order to set the MIME type
	if (FALSE === strpos($filename, '.'))
	{
		return FALSE;
	}

	// Grab the file extension
	$x = explode('.', $filename);
	$extension = end($x);

	// Load the mime types
	@include(APPPATH.'config/mimes'.EXT);

	// Set a default mime if we can't find it
	if ( ! isset($mimes[$extension]))
	{
		$mime = 'application/octet-stream';
	}
	else
	{
		$mime = (is_array($mimes[$extension])) ? $mimes[$extension][0] : $mimes[$extension];
	}

	// Generate the server headers
	if (strstr($_SERVER['HTTP_USER_AGENT'], "MSIE"))
	{
		header('Content-Type: "'.$mime.'"');
		header('Content-Disposition: attachment; filename="'.$filename.'"');
		header('Expires: 0');
		header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
		header("Content-Transfer-Encoding: binary");
		header('Pragma: public');
		header("Content-Length: ".strlen($data));
	}
	else
	{
		header('Content-Type: "'.$mime.'"');
		header('Content-Disposition: attachment; filename="'.$filename.'"');
		header("Content-Transfer-Encoding: binary");
		header('Expires: 0');
		header('Pragma: no-cache');
		header("Content-Length: ".strlen($data));
	}

	echo $data;
    exit;
}

/**
 * If you want to do something on download abort/finish,
 * register_shutdown_function('function_name');
 * @category: Helpers [Appended]
 * @author: White Shadow
 * @link : http://w-shadow.com/blog/2007/08/12/how-to-force-file-download-with-php/
 * @modified By : Himel Nag Rana
 *
 * @param $file		 : The file path after base url without slash.
 * @param $name		 : The required file name [excluding path].
 * @param $mime_type : The mime type of the file [optional]
 */

function output_file($file, $name, $mime_type='', $real_path = false)
{
	if(!$real_path)
        $file = $_SERVER['DOCUMENT_ROOT'].$file;

	if(!is_readable($file))
 		die('File not found or inaccessible!');

 	$size = filesize($file);

 	$name = rawurldecode($name);

 	/* Figure out the MIME type (if not specified) */
 	$known_mime_types = array(
 			"php" => "text/plain",
			"xls" => "application/excel",
			"jar" => "application/java-archive",
			"pot" => "application/mspowerpoint",
			"pps" => "application/mspowerpoint",
			"ppt" => "application/mspowerpoint",
			"doc" => "application/msword",
			"pdf" => "application/pdf",
			"rtf" => "application/rtf",
			"xls" => "application/vnd.ms-excel",
			"gz" => "application/x-gunzip",
			"gz" => "application/x-gzip",
			"js" => "application/x-javascript",
			"rar" => "application/x-rar-compressed",
			"swf" => "application/x-shockwave-flash",
			"tar.gz" => "application/x-tar-gz",
			"tgz" => "application/x-tar-gz",
			"tar" => "application/x-tar",
			"zip" => "application/x-zip-compressed",
			"zip" => "application/zip",
			"kar" => "audio/midi",
			"mid" => "audio/midi",
			"midi" => "audio/midi",
			"mp3" => "audio/mpeg",
			"m3u" => "audio/x-mpegurl",
			"wma" => "audio/x-ms-wma",
			"rpm" => "audio/x-pn-realaudio-plugin",
			"ram" => "audio/x-pn-realaudio",
			"rm" => "audio/x-pn-realaudio",
			"ra" => "audio/x-realaudio",
			"wav" => "audio/x-wav",
			"gif" => "image/gif",
			"jpeg" => "image/jpeg",
			"jpg" => "image/jpeg",
			"png" => "image/png",
			"tif" => "image/tiff",
			"tiff" => "image/tiff",
			"css" => "text/css",
			"htm" => "text/html",
			"html" => "text/html",
			"txt" => "text/plain",
			"rtx" => "text/richtext",
			"rtf" => "text/rtf",
			"jad" => "text/vnd.sun.j2me.app-descriptor",
			"xml" => "text/xml",
			"flv" => "video/flv",
			"mp2" => "video/mpeg",
			"mpeg" => "video/mpeg",
			"mpg" => "video/mpeg",
			"wmv" => "video/x-ms-wmv",
			"avi" => "video/x-msvideo",
			"movie" => "video/x-sgi-movie"
	);

	 if($mime_type=='')
	 {
		 $file_extension = strtolower(substr(strrchr($file,"."),1));
		 if(array_key_exists($file_extension, $known_mime_types))
		 {
			$mime_type=$known_mime_types[$file_extension];
		 }
		 else
		 {
			$mime_type="application/force-download";
		 };
	 };

 	@ob_end_clean(); //turn off output buffering to decrease cpu usage

	// required for IE, otherwise Content-Disposition may be ignored
 	if(ini_get('zlib.output_compression'))
  		ini_set('zlib.output_compression', 'Off');

	 header('Content-Type: ' . $mime_type);
	 header('Content-Disposition: attachment; filename="'.basename($name).'"');
	 header("Content-Transfer-Encoding: binary");
	 header('Accept-Ranges: bytes');

 	/* The three lines below basically make the download non-cacheable */
 	header("Cache-control: private");
 	header('Pragma: private');
 	header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");

	// multipart-download and download resuming support
	if(isset($_SERVER['HTTP_RANGE']))
	 {
		list($a, $range) = explode("=",$_SERVER['HTTP_RANGE'],2);
		list($range) = explode(",",$range,2);
		list($range, $range_end) = explode("-", $range);
		$range=intval($range);
		if(!$range_end)
		{
			$range_end=$size-1;
		}
		else
		{
			$range_end=intval($range_end);
		}

		$new_length = $range_end-$range+1;
		header("HTTP/1.1 206 Partial Content");
		header("Content-Length: $new_length");
		header("Content-Range: bytes $range-$range_end/$size");
	 }
	 else
	 {
		$new_length=$size;
		header("Content-Length: ".$size);
	 }

	 /* output the file itself */
	 $chunksize = 1*(1024*1024); //you may want to change this
	 $bytes_send = 0;
	 if ($file = fopen($file, 'r'))
	 {
		if(isset($_SERVER['HTTP_RANGE']))
			fseek($file, $range);

		while(!feof($file) && (!connection_aborted()) && ($bytes_send<$new_length))
		{
			$buffer = fread($file, $chunksize);
			print($buffer); //echo($buffer); // is also possible
			flush();
			$bytes_send += strlen($buffer);
		}
	 	fclose($file);
	 }
	 else
	 	die('Error - can not open file.');

	die();
}
?>