<?php defined('SYSPATH') or die('No direct script access.');
/**
 * Download helper class.
 *
 * $Id$
 *
 * @package    Core
 * @author     Kohana Team
 * @copyright  (c) 2007-2008 Kohana Team
 * @license    http://kohanaphp.com/license.html
 */
class download_Core {

	/**
	 * Force a download of a file to the user's browser. This function is
	 * binary-safe and will work with any MIME type that Kohana is aware of.
	 *
	 * @param   string  a file path or file name
	 * @param   mixed   data to be sent if the filename does not exist
	 * @param   float  	size of block to be read from file at a time in megabytes
	 * @return  void
	 */
	public static function force($filename = '', $data = '', $blocksize = 1)
	{
		static $user_agent;

		if ($filename == '')
			return FALSE;
		
		if (valid::numeric($blocksize))
			$blocksize = abs($blocksize);
		else
			return FALSE;

		if (is_file($filename))
		{
			// Get the real path
			$filepath = str_replace('\\', '/', realpath($filename));

			// Get extension
			$extension = pathinfo($filepath, PATHINFO_EXTENSION);

			// Remove directory path from the filename
			$filename = end(explode('/', $filepath));

			// Set filesize
			$filesize = filesize($filepath);
		}
		else
		{
			// Grab the file extension
			$extension = end(explode('.', $filename));

			// Try to determine if the filename includes a file extension.
			// We need it in order to set the MIME type
			if (empty($data) OR $extension === $filename)
				return FALSE;

			// Set filesize
			$filesize = strlen($data);
		}

		// Set a default mime if we can't find it
		if (($mime = Config::item('mimes.'.$extension)) === NULL)
		{
			$mime = 'application/octet-stream';
		}
		else
		{
			$mime = current((array) $mime);
		}

		// Generate the server headers
		header('Content-Type: '.$mime);
		header('Content-Disposition: attachment; filename="'.$filename.'"');
		header('Content-Transfer-Encoding: binary');
		header('Expires: 0');
		header('Content-Length: '.$filesize);
		
		// IE headers
		if (Kohana::user_agent('browser') === 'Internet Explorer')
		{
			header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
			header('Pragma: public');
		}
		else
		{
			header('Pragma: no-cache');
		}

		if (isset($filepath))
		{
			// Convert blocksize to bytes
			$blocksize *= 1000000;
			
			// Open the file
			$handle = fopen($filepath, 'rb');
			
			// Loop through the file, 1MB at a time
			while ( ! feof($handle))
			{
				// Echo the result
				echo fread($handle, $blocksize);
				
				// Flush the output buffer to start sending data
				ob_flush();
				flush();
			}
			
			// Close the file
			fclose($handle);
		}
		else
		{
			// Send the file data
			echo $data;
		}
	}

} // End download