1 | <?php |
||
2 | if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point'); |
||
3 | /********************************************************************************* |
||
4 | * SugarCRM Community Edition is a customer relationship management program developed by |
||
5 | * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc. |
||
6 | |||
7 | * SuiteCRM is an extension to SugarCRM Community Edition developed by Salesagility Ltd. |
||
8 | * Copyright (C) 2011 - 2014 Salesagility Ltd. |
||
9 | * |
||
10 | * This program is free software; you can redistribute it and/or modify it under |
||
11 | * the terms of the GNU Affero General Public License version 3 as published by the |
||
12 | * Free Software Foundation with the addition of the following permission added |
||
13 | * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK |
||
14 | * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY |
||
15 | * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. |
||
16 | * |
||
17 | * This program is distributed in the hope that it will be useful, but WITHOUT |
||
18 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
||
19 | * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more |
||
20 | * details. |
||
21 | * |
||
22 | * You should have received a copy of the GNU Affero General Public License along with |
||
23 | * this program; if not, see http://www.gnu.org/licenses or write to the Free |
||
24 | * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
||
25 | * 02110-1301 USA. |
||
26 | * |
||
27 | * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road, |
||
28 | * SW2-130, Cupertino, CA 95014, USA. or at email address [email protected]. |
||
29 | * |
||
30 | * The interactive user interfaces in modified source and object code versions |
||
31 | * of this program must display Appropriate Legal Notices, as required under |
||
32 | * Section 5 of the GNU Affero General Public License version 3. |
||
33 | * |
||
34 | * In accordance with Section 7(b) of the GNU Affero General Public License version 3, |
||
35 | * these Appropriate Legal Notices must retain the display of the "Powered by |
||
36 | * SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not |
||
37 | * reasonably feasible for technical reasons, the Appropriate Legal Notices must |
||
38 | * display the words "Powered by SugarCRM" and "Supercharged by SuiteCRM". |
||
39 | ********************************************************************************/ |
||
40 | |||
41 | |||
42 | global $db; |
||
43 | |||
44 | if((!isset($_REQUEST['isProfile']) && empty($_REQUEST['id'])) || empty($_REQUEST['type']) || !isset($_SESSION['authenticated_user_id'])) { |
||
45 | die("Not a Valid Entry Point"); |
||
46 | } |
||
47 | else { |
||
48 | require_once("data/BeanFactory.php"); |
||
49 | $file_type=''; // bug 45896 |
||
50 | require_once("data/BeanFactory.php"); |
||
51 | ini_set('zlib.output_compression','Off');//bug 27089, if use gzip here, the Content-Length in header may be incorrect. |
||
52 | // cn: bug 8753: current_user's preferred export charset not being honored |
||
53 | $GLOBALS['current_user']->retrieve($_SESSION['authenticated_user_id']); |
||
54 | $GLOBALS['current_language'] = $_SESSION['authenticated_user_language']; |
||
55 | $app_strings = return_application_language($GLOBALS['current_language']); |
||
56 | $mod_strings = return_module_language($GLOBALS['current_language'], 'ACL'); |
||
57 | $file_type = strtolower($_REQUEST['type']); |
||
58 | if(!isset($_REQUEST['isTempFile'])) { |
||
59 | //Custom modules may have capitalizations anywhere in their names. We should check the passed in format first. |
||
60 | require('include/modules.php'); |
||
61 | $module = $db->quote($_REQUEST['type']); |
||
62 | if(empty($beanList[$module])) { |
||
63 | //start guessing at a module name |
||
64 | $module = ucfirst($file_type); |
||
65 | if(empty($beanList[$module])) { |
||
66 | die($app_strings['ERROR_TYPE_NOT_VALID']); |
||
67 | } |
||
68 | } |
||
69 | $bean_name = $beanList[$module]; |
||
70 | if(!file_exists('modules/' . $module . '/' . $bean_name . '.php')) { |
||
71 | die($app_strings['ERROR_TYPE_NOT_VALID']); |
||
72 | } |
||
73 | |||
74 | $focus = BeanFactory::newBean($module); |
||
75 | if(!$focus->ACLAccess('view')){ |
||
76 | die($mod_strings['LBL_NO_ACCESS']); |
||
77 | } // if |
||
78 | $focus->retrieve($_REQUEST['id']); |
||
79 | // Pull up the document revision, if it's of type Document |
||
80 | if ( isset($focus->object_name) && $focus->object_name == 'Document' ) { |
||
81 | // It's a document, get the revision that really stores this file |
||
82 | $focusRevision = new DocumentRevision(); |
||
83 | $focusRevision->retrieve($_REQUEST['id']); |
||
84 | |||
85 | if ( empty($focusRevision->id) ) { |
||
86 | // This wasn't a document revision id, it's probably actually a document id, |
||
87 | // we need to grab the latest revision and use that |
||
88 | $focusRevision->retrieve($focus->document_revision_id); |
||
89 | |||
90 | if ( !empty($focusRevision->id) ) { |
||
91 | $_REQUEST['id'] = $focusRevision->id; |
||
92 | } |
||
93 | } |
||
94 | } |
||
95 | |||
96 | // See if it is a remote file, if so, send them that direction |
||
97 | if ( isset($focus->doc_url) && !empty($focus->doc_url) ) { |
||
98 | header('Location: '.$focus->doc_url); |
||
99 | sugar_die("Remote file detected, location header sent."); |
||
100 | } |
||
101 | |||
102 | if ( isset($focusRevision) && isset($focusRevision->doc_url) && !empty($focusRevision->doc_url) ) { |
||
103 | header('Location: '.$focusRevision->doc_url); |
||
104 | sugar_die("Remote file detected, location header sent."); |
||
105 | } |
||
106 | |||
107 | } // if |
||
108 | $temp = explode ( "_" , $_REQUEST['id'], 2 ); |
||
109 | if(is_array($temp)){ |
||
110 | $image_field = $temp[1]; |
||
111 | $image_id = $temp[0]; |
||
112 | } |
||
113 | if(isset($_REQUEST['ieId']) && isset($_REQUEST['isTempFile'])) { |
||
114 | $local_location = sugar_cached("modules/Emails/{$_REQUEST['ieId']}/attachments/{$_REQUEST['id']}"); |
||
115 | } elseif(isset($_REQUEST['isTempFile']) && $file_type == "import") { |
||
116 | $local_location = "upload://import/{$_REQUEST['tempName']}"; |
||
117 | } else { |
||
118 | $local_location = "upload://{$_REQUEST['id']}"; |
||
119 | } |
||
120 | |||
121 | if(isset($_REQUEST['isTempFile']) && ($_REQUEST['type']=="SugarFieldImage")) { |
||
122 | $local_location = "upload://{$_REQUEST['id']}"; |
||
123 | } |
||
124 | |||
125 | if(isset($_REQUEST['isTempFile']) && ($_REQUEST['type']=="SugarFieldImage") && (isset($_REQUEST['isProfile'])) && empty($_REQUEST['id'])) { |
||
126 | $local_location = "include/images/default-profile.png"; |
||
127 | } |
||
128 | |||
129 | if(!file_exists( $local_location ) || strpos($local_location, "..")) { |
||
130 | |||
131 | if(isset($image_field)) { |
||
132 | header("Content-Type: image/png"); |
||
133 | header("Content-Disposition: attachment; filename=\"No-Image.png\""); |
||
134 | header("X-Content-Type-Options: nosniff"); |
||
135 | header("Content-Length: " . filesize('include/SugarFields/Fields/Image/no_image.png')); |
||
136 | header('Expires: ' . gmdate('D, d M Y H:i:s \G\M\T', time() + 2592000)); |
||
137 | set_time_limit(0); |
||
138 | readfile('include/SugarFields/Fields/Image/no_image.png'); |
||
139 | die(); |
||
140 | }else { |
||
141 | die($app_strings['ERR_INVALID_FILE_REFERENCE']); |
||
142 | } |
||
143 | } else { |
||
144 | $doQuery = true; |
||
145 | |||
146 | if($file_type == 'documents') { |
||
147 | // cn: bug 9674 document_revisions table has no 'name' column. |
||
148 | $query = "SELECT filename name FROM document_revisions INNER JOIN documents ON documents.id = document_revisions.document_id "; |
||
149 | $query .= "WHERE document_revisions.id = '".$db->quote($_REQUEST['id'])."' "; |
||
150 | } elseif($file_type == 'kbdocuments') { |
||
151 | $query="SELECT document_revisions.filename name FROM document_revisions INNER JOIN kbdocument_revisions ON document_revisions.id = kbdocument_revisions.document_revision_id INNER JOIN kbdocuments ON kbdocument_revisions.kbdocument_id = kbdocuments.id "; |
||
152 | $query .= "WHERE document_revisions.id = '" . $db->quote($_REQUEST['id']) ."'"; |
||
153 | } elseif($file_type == 'notes') { |
||
154 | $query = "SELECT filename name, file_mime_type FROM notes "; |
||
155 | $query .= "WHERE notes.id = '" . $db->quote($_REQUEST['id']) ."'"; |
||
156 | } elseif( !isset($_REQUEST['isTempFile']) && !isset($_REQUEST['tempName'] ) && isset($_REQUEST['type']) && $file_type!='temp' && isset($image_field) ) { //make sure not email temp file. |
||
157 | //$query = "SELECT " . $image_field ." FROM " . $file_type . " LEFT JOIN " . $file_type . "_cstm cstm ON cstm.id_c = " . $file_type . ".id "; |
||
158 | |||
159 | // Fix for issue #1195: because the module was created using Module Builder and it does not create any _cstm table, |
||
160 | // there is a need to check whether the field has _c extension. |
||
161 | $query = "SELECT " . $image_field ." FROM " . $file_type . " "; |
||
162 | if(substr($image_field, -2) == "_c" ) $query .= "LEFT JOIN " . $file_type . "_cstm cstm ON cstm.id_c = " . $file_type . ".id "; |
||
163 | $query .= "WHERE " . $file_type . ".id= '" . $db->quote($image_id) . "'"; |
||
164 | |||
165 | //$query .= "WHERE " . $file_type . ".id= '" . $db->quote($image_id) . "'"; |
||
166 | }elseif( !isset($_REQUEST['isTempFile']) && !isset($_REQUEST['tempName'] ) && isset($_REQUEST['type']) && $file_type!='temp' ){ //make sure not email temp file. |
||
167 | $query = "SELECT filename name FROM ". $file_type ." "; |
||
168 | $query .= "WHERE ". $file_type .".id= '".$db->quote($_REQUEST['id'])."'"; |
||
169 | }elseif( $file_type == 'temp'){ |
||
170 | $doQuery = false; |
||
171 | } |
||
172 | |||
173 | $mime_type = 'application/octet-stream'; |
||
174 | if($doQuery && isset($query)) { |
||
175 | $rs = $GLOBALS['db']->query($query); |
||
176 | $row = $GLOBALS['db']->fetchByAssoc($rs); |
||
177 | |||
178 | if(empty($row)){ |
||
179 | die($app_strings['ERROR_NO_RECORD']); |
||
180 | } |
||
181 | |||
182 | if(isset($image_field)){ |
||
183 | $name = $row[$image_field]; |
||
184 | }else { |
||
185 | $name = $row['name']; |
||
186 | } |
||
187 | // expose original mime type only for images, otherwise the content of arbitrary type |
||
188 | // may be interpreted/executed by browser |
||
189 | if (isset($row['file_mime_type']) && strpos($row['file_mime_type'], 'image/') === 0) { |
||
190 | $mime_type = $row['file_mime_type']; |
||
191 | } |
||
192 | if(isset($_REQUEST['field'])){ |
||
193 | $id = $row[$id_field]; |
||
194 | $download_location = "upload://{$id}"; |
||
195 | }else{ |
||
196 | $download_location = "upload://{$_REQUEST['id']}"; |
||
197 | } |
||
198 | |||
199 | } else if(isset( $_REQUEST['tempName'] ) && isset($_REQUEST['isTempFile']) ){ |
||
200 | // downloading a temp file (email 2.0) |
||
201 | $download_location = $local_location; |
||
202 | $name = isset($_REQUEST['tempName'])?$_REQUEST['tempName']:''; |
||
203 | } else if(isset($_REQUEST['isTempFile']) && ($_REQUEST['type']=="SugarFieldImage")) { |
||
204 | $download_location = $local_location; |
||
205 | $name = isset($_REQUEST['tempName'])?$_REQUEST['tempName']:''; |
||
206 | } |
||
207 | |||
208 | if(isset($_SERVER['HTTP_USER_AGENT']) && preg_match("/MSIE/", $_SERVER['HTTP_USER_AGENT'])) |
||
209 | { |
||
210 | $name = urlencode($name); |
||
211 | $name = str_replace("+", "_", $name); |
||
212 | } |
||
213 | |||
214 | header("Pragma: public"); |
||
215 | header("Cache-Control: maxage=1, post-check=0, pre-check=0"); |
||
216 | if(isset($_REQUEST['isTempFile']) && ($_REQUEST['type']=="SugarFieldImage")) { |
||
217 | $mime = getimagesize($download_location); |
||
218 | if(!empty($mime)) { |
||
219 | header("Content-Type: {$mime['mime']}"); |
||
220 | } else { |
||
221 | header("Content-Type: image/png"); |
||
222 | } |
||
223 | } else { |
||
224 | header('Content-type: ' . $mime_type); |
||
225 | header("Content-Disposition: attachment; filename=\"".$name."\";"); |
||
226 | |||
227 | } |
||
228 | // disable content type sniffing in MSIE |
||
229 | header("X-Content-Type-Options: nosniff"); |
||
230 | header("Content-Length: " . filesize($local_location)); |
||
231 | header('Expires: ' . gmdate('D, d M Y H:i:s \G\M\T', time() + 2592000)); |
||
232 | set_time_limit(0); |
||
233 | |||
234 | // When output_buffering = On, ob_get_level() may return 1 even if ob_end_clean() returns false |
||
235 | // This happens on some QA stacks. See Bug#64860 |
||
236 | while (ob_get_level() && @ob_end_clean()); |
||
237 | |||
238 | readfile($download_location); |
||
239 | } |
||
240 | } |
||
241 |