blob: 9a6f684e4fca9d104c5a0095c779fa46b520acab [file] [log] [blame]
Andrey Andreevc5536aa2012-11-01 17:33:58 +02001<?php
Derek Allard2067d1a2008-11-13 22:59:24 +00002/**
3 * CodeIgniter
4 *
Phil Sturgeon07c1ac82012-03-09 17:03:37 +00005 * An open source application development framework for PHP 5.2.4 or newer
Derek Allard2067d1a2008-11-13 22:59:24 +00006 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05007 * NOTICE OF LICENSE
Andrey Andreevb38c5dd2012-02-29 14:07:45 +02008 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05009 * Licensed under the Open Software License version 3.0
Andrey Andreevb38c5dd2012-02-29 14:07:45 +020010 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -050011 * This source file is subject to the Open Software License (OSL 3.0) that is
12 * bundled with this package in the files license.txt / license.rst. It is
13 * also available through the world wide web at this URL:
14 * http://opensource.org/licenses/OSL-3.0
15 * If you did not receive a copy of the license and are unable to obtain it
16 * through the world wide web, please send an email to
17 * licensing@ellislab.com so we can send you a copy immediately.
18 *
Derek Allard2067d1a2008-11-13 22:59:24 +000019 * @package CodeIgniter
Derek Jonesf4a4bd82011-10-20 12:18:42 -050020 * @author EllisLab Dev Team
Andrey Andreev80500af2013-01-01 08:16:53 +020021 * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
Derek Jonesf4a4bd82011-10-20 12:18:42 -050022 * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
Derek Allard2067d1a2008-11-13 22:59:24 +000023 * @link http://codeigniter.com
24 * @since Version 1.0
25 * @filesource
26 */
Andrey Andreevc5536aa2012-11-01 17:33:58 +020027defined('BASEPATH') OR exit('No direct script access allowed');
Derek Allard2067d1a2008-11-13 22:59:24 +000028
Derek Allard2067d1a2008-11-13 22:59:24 +000029/**
30 * CodeIgniter Download Helpers
31 *
32 * @package CodeIgniter
33 * @subpackage Helpers
34 * @category Helpers
Derek Jonesf4a4bd82011-10-20 12:18:42 -050035 * @author EllisLab Dev Team
Derek Allard2067d1a2008-11-13 22:59:24 +000036 * @link http://codeigniter.com/user_guide/helpers/download_helper.html
37 */
38
39// ------------------------------------------------------------------------
40
Derek Allard2067d1a2008-11-13 22:59:24 +000041if ( ! function_exists('force_download'))
42{
Timothy Warren01b129a2012-04-27 11:36:50 -040043 /**
44 * Force Download
45 *
46 * Generates headers that force a download to happen
47 *
48 * @param string filename
49 * @param mixed the data to be downloaded
Alex Bilbief512b732012-06-16 11:15:19 +010050 * @param bool whether to try and send the actual file MIME type
Timothy Warren01b129a2012-04-27 11:36:50 -040051 * @return void
52 */
Andrey Andreevb38c5dd2012-02-29 14:07:45 +020053 function force_download($filename = '', $data = '', $set_mime = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +000054 {
Alex Bilbie773ccc32012-06-02 11:11:08 +010055 if ($filename === '' OR $data === '')
Derek Allard2067d1a2008-11-13 22:59:24 +000056 {
57 return FALSE;
58 }
Andrey Andreev53fff912012-11-22 16:57:23 +020059 elseif ($data === NULL)
60 {
Andrey Andreev06879112013-01-29 15:05:02 +020061 if (@is_file($filename) && ($filesize = @filesize($filename)) !== FALSE)
Andrey Andreev53fff912012-11-22 16:57:23 +020062 {
63 $filepath = $filename;
64 $filename = explode('/', str_replace(DIRECTORY_SEPARATOR, '/', $filename));
65 $filename = end($filename);
66 }
67 else
68 {
69 return FALSE;
70 }
71 }
72 else
73 {
74 $filesize = strlen($data);
75 }
Derek Allard2067d1a2008-11-13 22:59:24 +000076
Andrey Andreevb38c5dd2012-02-29 14:07:45 +020077 // Set the default MIME type to send
78 $mime = 'application/octet-stream';
79
Andrey Andreevfce2ed62012-03-11 22:04:48 +020080 $x = explode('.', $filename);
81 $extension = end($x);
82
Andrey Andreevb38c5dd2012-02-29 14:07:45 +020083 if ($set_mime === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +000084 {
Andrey Andreevfce2ed62012-03-11 22:04:48 +020085 if (count($x) === 1 OR $extension === '')
Andrey Andreevb38c5dd2012-02-29 14:07:45 +020086 {
Andrey Andreevfce2ed62012-03-11 22:04:48 +020087 /* If we're going to detect the MIME type,
88 * we'll need a file extension.
89 */
Andrey Andreevb38c5dd2012-02-29 14:07:45 +020090 return FALSE;
91 }
92
Andrey Andreevb38c5dd2012-02-29 14:07:45 +020093 // Load the mime types
Andrey Andreev6ef498b2012-06-05 22:01:58 +030094 $mimes =& get_mimes();
Andrey Andreevb38c5dd2012-02-29 14:07:45 +020095
96 // Only change the default MIME if we can find one
97 if (isset($mimes[$extension]))
98 {
99 $mime = is_array($mimes[$extension]) ? $mimes[$extension][0] : $mimes[$extension];
100 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000101 }
Barry Mienydd671972010-10-04 16:33:58 +0200102
Andrey Andreevfce2ed62012-03-11 22:04:48 +0200103 /* It was reported that browsers on Android 2.1 (and possibly older as well)
104 * need to have the filename extension upper-cased in order to be able to
105 * download it.
106 *
107 * Reference: http://digiblog.de/2011/04/19/android-and-the-download-file-headers/
108 */
Andrey Andreev3d933b62012-03-11 22:08:57 +0200109 if (count($x) !== 1 && isset($_SERVER['HTTP_USER_AGENT']) && preg_match('/Android\s(1|2\.[01])/', $_SERVER['HTTP_USER_AGENT']))
Andrey Andreevfce2ed62012-03-11 22:04:48 +0200110 {
111 $x[count($x) - 1] = strtoupper($extension);
112 $filename = implode('.', $x);
113 }
Andrey Andreevae31eb52012-05-17 14:54:15 +0300114
Andrey Andreev53fff912012-11-22 16:57:23 +0200115 if ($data === NULL && ($fp = @fopen($filepath, 'rb')) === FALSE)
116 {
117 return FALSE;
118 }
119
Sam Libbd9dd32012-04-23 23:13:46 +0800120 // Clean output buffer
Andrey Andreev53fff912012-11-22 16:57:23 +0200121 if (ob_get_level() !== 0 && @ob_end_clean() === FALSE)
Michiel Vugteveen28ff2922012-08-14 10:55:46 +0200122 {
Andrey Andreev88d16d72014-01-28 12:28:42 +0200123 @ob_clean();
Michiel Vugteveen28ff2922012-08-14 10:55:46 +0200124 }
Andrey Andreevfce2ed62012-03-11 22:04:48 +0200125
Derek Allard2067d1a2008-11-13 22:59:24 +0000126 // Generate the server headers
dododedodonl4da94782012-03-10 13:56:17 +0100127 header('Content-Type: '.$mime);
Eric Roberts0e4d2b62012-01-23 18:19:20 -0600128 header('Content-Disposition: attachment; filename="'.$filename.'"');
129 header('Expires: 0');
Andrey Andreevb38c5dd2012-02-29 14:07:45 +0200130 header('Content-Transfer-Encoding: binary');
Andrey Andreev53fff912012-11-22 16:57:23 +0200131 header('Content-Length: '.$filesize);
Eric Roberts0e4d2b62012-01-23 18:19:20 -0600132
Andrey Andreevb38c5dd2012-02-29 14:07:45 +0200133 // Internet Explorer-specific headers
134 if (isset($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000135 {
Andrey Andreevd87f6bf2012-10-24 22:12:53 +0300136 header('Cache-Control: no-cache, no-store, must-revalidate');
Derek Allard2067d1a2008-11-13 22:59:24 +0000137 }
Andrey Andreevd87f6bf2012-10-24 22:12:53 +0300138
139 header('Pragma: no-cache');
Barry Mienydd671972010-10-04 16:33:58 +0200140
Andrey Andreev53fff912012-11-22 16:57:23 +0200141 // If we have raw data - just dump it
142 if ($data !== NULL)
143 {
144 exit($data);
145 }
146
147 // Flush 1MB chunks of data
148 while ( ! feof($fp) && ($data = fread($fp, 1048576)) !== FALSE)
149 {
150 echo $data;
151 }
152
153 fclose($fp);
154 exit;
Derek Allard2067d1a2008-11-13 22:59:24 +0000155 }
156}
157
Derek Allard2067d1a2008-11-13 22:59:24 +0000158/* End of file download_helper.php */
Andrey Andreev627e1722012-03-26 20:53:47 +0300159/* Location: ./system/helpers/download_helper.php */