dolibarr  13.0.2
viewimage.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2004-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3  * Copyright (C) 2005-2016 Laurent Destailleur <eldy@users.sourceforge.net>
4  * Copyright (C) 2005-2016 Regis Houssin <regis.houssin@inodbox.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see <https://www.gnu.org/licenses/>.
18  * or see https://www.gnu.org/
19  */
20 
29 //if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1'); // Not disabled cause need to load personalized language
30 //if (! defined('NOREQUIREDB')) define('NOREQUIREDB','1'); // Not disabled cause need to load personalized language
31 if (!defined('NOREQUIRESOC')) define('NOREQUIRESOC', '1');
32 if (!defined('NOREQUIRETRAN')) define('NOREQUIRETRAN', '1');
33 if (!defined('NOCSRFCHECK')) define('NOCSRFCHECK', '1');
34 if (!defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL', '1');
35 if (!defined('NOREQUIREMENU')) define('NOREQUIREMENU', '1');
36 if (!defined('NOREQUIREHTML')) define('NOREQUIREHTML', '1');
37 if (!defined('NOREQUIREAJAX')) define('NOREQUIREAJAX', '1');
38 
39 // Some value of modulepart can be used to get resources that are public so no login are required.
40 // Note that only directory logo is free to access without login.
41 if (isset($_GET["modulepart"]) && $_GET["modulepart"] == 'mycompany' && preg_match('/^\/?logos\//', $_GET['file']))
42 {
43  if (!defined("NOLOGIN")) define("NOLOGIN", 1);
44  if (!defined("NOCSRFCHECK")) define("NOCSRFCHECK", 1); // We accept to go on this page from external web site.
45  if (!defined("NOIPCHECK")) define("NOIPCHECK", 1); // Do not check IP defined into conf $dolibarr_main_restrict_ip
46 }
47 // For direct external download link, we don't need to load/check we are into a login session
48 if (isset($_GET["hashp"]) && !defined("NOLOGIN"))
49 {
50  if (!defined("NOLOGIN")) define("NOLOGIN", 1);
51  if (!defined("NOCSRFCHECK")) define("NOCSRFCHECK", 1); // We accept to go on this page from external web site.
52  if (!defined("NOIPCHECK")) define("NOIPCHECK", 1); // Do not check IP defined into conf $dolibarr_main_restrict_ip
53 }
54 // Some value of modulepart can be used to get resources that are public so no login are required.
55 if (isset($_GET["modulepart"]) && $_GET["modulepart"] == 'medias')
56 {
57  if (!defined("NOLOGIN")) define("NOLOGIN", 1);
58  if (!defined("NOCSRFCHECK")) define("NOCSRFCHECK", 1); // We accept to go on this page from external web site.
59  if (!defined("NOIPCHECK")) define("NOIPCHECK", 1); // Do not check IP defined into conf $dolibarr_main_restrict_ip
60 }
61 
62 // Used by TakePOS Auto Order
63 if (isset($_GET["modulepart"]) && $_GET["modulepart"] == 'product' && isset($_GET["publictakepos"]))
64 {
65  if (!defined("NOLOGIN")) define("NOLOGIN", 1);
66  if (!defined("NOCSRFCHECK")) define("NOCSRFCHECK", 1); // We accept to go on this page from external web site.
67  if (!defined("NOIPCHECK")) define("NOIPCHECK", 1); // Do not check IP defined into conf $dolibarr_main_restrict_ip
68 }
69 
70 // For multicompany
71 $entity = (!empty($_GET['entity']) ? (int) $_GET['entity'] : (!empty($_POST['entity']) ? (int) $_POST['entity'] : 1));
72 if (is_numeric($entity)) define("DOLENTITY", $entity);
73 
80 function llxHeader()
81 {
82 }
89 function llxFooter()
90 {
91 }
92 
93 require 'main.inc.php'; // Load $user and permissions
94 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
95 
96 $action = GETPOST('action', 'aZ09');
97 $original_file = GETPOST('file', 'alphanohtml'); // Do not use urldecode here ($_GET are already decoded by PHP).
98 $hashp = GETPOST('hashp', 'aZ09');
99 $modulepart = GETPOST('modulepart', 'alpha');
100 $urlsource = GETPOST('urlsource', 'alpha');
101 $entity = GETPOST('entity', 'int') ?GETPOST('entity', 'int') : $conf->entity;
102 
103 // Security check
104 if (empty($modulepart) && empty($hashp)) accessforbidden('Bad link. Bad value for parameter modulepart', 0, 0, 1);
105 if (empty($original_file) && empty($hashp) && $modulepart != 'barcode') accessforbidden('Bad link. Missing identification to find file (param file or hashp)', 0, 0, 1);
106 if ($modulepart == 'fckeditor') $modulepart = 'medias'; // For backward compatibility
107 
108 
109 
110 /*
111  * Actions
112  */
113 
114 // None
115 
116 
117 
118 /*
119  * View
120  */
121 
122 if (GETPOST("cache", 'alpha'))
123 {
124  // Important: Following code is to avoid page request by browser and PHP CPU at
125  // each Dolibarr page access.
126  if (empty($dolibarr_nocache))
127  {
128  header('Cache-Control: max-age=3600, public, must-revalidate');
129  header('Pragma: cache'); // This is to avoid having Pragma: no-cache
130  } else header('Cache-Control: no-cache');
131  //print $dolibarr_nocache; exit;
132 }
133 
134 // If we have a hash public (hashp), we guess the original_file.
135 if (!empty($hashp))
136 {
137  include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php';
138  $ecmfile = new EcmFiles($db);
139  $result = $ecmfile->fetch(0, '', '', '', $hashp);
140  if ($result > 0)
141  {
142  $tmp = explode('/', $ecmfile->filepath, 2); // $ecmfile->filepath is relative to document directory
143  // filepath can be 'users/X' or 'X/propale/PR11111'
144  if (is_numeric($tmp[0])) // If first tmp is numeric, it is subdir of company for multicompany, we take next part.
145  {
146  $tmp = explode('/', $tmp[1], 2);
147  }
148  $moduleparttocheck = $tmp[0]; // moduleparttocheck is first part of path
149 
150  if ($modulepart) // Not required, so often not defined, for link using public hashp parameter.
151  {
152  if ($moduleparttocheck == $modulepart)
153  {
154  // We remove first level of directory
155  $original_file = (($tmp[1] ? $tmp[1].'/' : '').$ecmfile->filename); // this is relative to module dir
156  //var_dump($original_file); exit;
157  } else {
158  accessforbidden('Bad link. File is from another module part.', 0, 0, 1);
159  }
160  } else {
161  $modulepart = $moduleparttocheck;
162  $original_file = (($tmp[1] ? $tmp[1].'/' : '').$ecmfile->filename); // this is relative to module dir
163  }
164  } else {
165  $langs->load("errors");
166  accessforbidden($langs->trans("ErrorFileNotFoundWithSharedLink"), 0, 0, 1);
167  }
168 }
169 
170 // Define mime type
171 $type = 'application/octet-stream';
172 if (GETPOST('type', 'alpha')) $type = GETPOST('type', 'alpha');
173 else $type = dol_mimetype($original_file);
174 
175 // Security: This wrapper is for images. We do not allow type/html
176 if (preg_match('/html/i', $type)) accessforbidden('Error: Using the image wrapper to output a file with a mime type HTML is not possible.', 0, 0, 1);
177 // Security: This wrapper is for images. We do not allow files ending with .noexe
178 if (preg_match('/\.noexe$/i', $original_file)) accessforbidden('Error: Using the image wrapper to output a file ending with .noexe is not allowed.', 0, 0, 1);
179 
180 // Security: Delete string ../ into $original_file
181 $original_file = str_replace("../", "/", $original_file);
182 
183 // Find the subdirectory name as the reference
184 $refname = basename(dirname($original_file)."/");
185 
186 // Security check
187 if (empty($modulepart)) accessforbidden('Bad value for parameter modulepart', 0, 0, 1);
188 
189 $check_access = dol_check_secure_access_document($modulepart, $original_file, $entity, $refname);
190 $accessallowed = $check_access['accessallowed'];
191 $sqlprotectagainstexternals = $check_access['sqlprotectagainstexternals'];
192 $fullpath_original_file = $check_access['original_file']; // $fullpath_original_file is now a full path name
193 
194 if (!empty($hashp)) {
195  $accessallowed = 1; // When using hashp, link is public so we force $accessallowed
196  $sqlprotectagainstexternals = '';
197 } elseif (isset($_GET["publictakepos"])) {
198  if (!empty($conf->global->TAKEPOS_AUTO_ORDER)) {
199  $accessallowed = 1; // Only if TakePOS Public Auto Order is enabled and received publictakepos variable
200  }
201 } else {
202  // Basic protection (against external users only)
203  if ($user->socid > 0)
204  {
205  if ($sqlprotectagainstexternals)
206  {
207  $resql = $db->query($sqlprotectagainstexternals);
208  if ($resql)
209  {
210  $num = $db->num_rows($resql);
211  $i = 0;
212  while ($i < $num)
213  {
214  $obj = $db->fetch_object($resql);
215  if ($user->socid != $obj->fk_soc)
216  {
217  $accessallowed = 0;
218  break;
219  }
220  $i++;
221  }
222  }
223  }
224  }
225 }
226 
227 // Security:
228 // Limit access if permissions are wrong
229 if (!$accessallowed)
230 {
231  accessforbidden();
232 }
233 
234 // Security:
235 // On interdit les remontees de repertoire ainsi que les pipe dans les noms de fichiers.
236 if (preg_match('/\.\./', $fullpath_original_file) || preg_match('/[<>|]/', $fullpath_original_file))
237 {
238  dol_syslog("Refused to deliver file ".$fullpath_original_file);
239  print "ErrorFileNameInvalid: ".dol_escape_htmltag($original_file);
240  exit;
241 }
242 
243 
244 
245 if ($modulepart == 'barcode')
246 {
247  $generator = GETPOST("generator", "alpha");
248  $code = GETPOST("code", 'none'); // This can be rich content (qrcode, datamatrix, ...)
249  $encoding = GETPOST("encoding", "alpha");
250  $readable = GETPOST("readable", 'alpha') ?GETPOST("readable", "alpha") : "Y";
251 
252  if (empty($generator) || empty($encoding))
253  {
254  print 'Error: Parameter "generator" or "encoding" not defined';
255  exit;
256  }
257 
258  $dirbarcode = array_merge(array("/core/modules/barcode/doc/"), $conf->modules_parts['barcode']);
259 
260  $result = 0;
261 
262  foreach ($dirbarcode as $reldir)
263  {
264  $dir = dol_buildpath($reldir, 0);
265  $newdir = dol_osencode($dir);
266 
267  // Check if directory exists (we do not use dol_is_dir to avoid loading files.lib.php)
268  if (!is_dir($newdir)) continue;
269 
270  $result = @include_once $newdir.$generator.'.modules.php';
271  if ($result) break;
272  }
273 
274  // Load barcode class
275  $classname = "mod".ucfirst($generator);
276  $module = new $classname($db);
277  if ($module->encodingIsSupported($encoding))
278  {
279  $result = $module->buildBarCode($code, $encoding, $readable);
280  }
281 } else {
282  // Open and return file
283  clearstatcache();
284 
285  $filename = basename($fullpath_original_file);
286 
287  // Output files on browser
288  dol_syslog("viewimage.php return file $fullpath_original_file filename=$filename content-type=$type");
289 
290  // This test is to avoid error images when image is not available (for example thumbs).
291  if (!dol_is_file($fullpath_original_file) && empty($_GET["noalt"]))
292  {
293  $fullpath_original_file = DOL_DOCUMENT_ROOT.'/public/theme/common/nophoto.png';
294  /*$error='Error: File '.$_GET["file"].' does not exists or filesystems permissions are not allowed';
295  print $error;
296  exit;*/
297  }
298 
299  // Permissions are ok and file found, so we return it
300  if ($type)
301  {
302  top_httphead($type);
303  header('Content-Disposition: inline; filename="'.basename($fullpath_original_file).'"');
304  } else {
305  top_httphead('image/png');
306  header('Content-Disposition: inline; filename="'.basename($fullpath_original_file).'"');
307  }
308 
309  $fullpath_original_file_osencoded = dol_osencode($fullpath_original_file);
310 
311  readfile($fullpath_original_file_osencoded);
312 }
313 
314 
315 if (is_object($db)) $db->close();
dol_osencode($str)
Return a string encoded into OS filesystem encoding.
GETPOST($paramname, $check= 'alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
if(!defined('NOREQUIREMENU')) if(!function_exists("llxHeader")) top_httphead($contenttype= 'text/html', $forcenocache=0)
Show HTTP header.
Definition: main.inc.php:1214
llxHeader()
Empty header.
Definition: wrapper.php:45
dol_check_secure_access_document($modulepart, $original_file, $entity, $fuser= '', $refname= '', $mode= 'read')
Security check when accessing to a document (used by document.php, viewimage.php and webservices) ...
Definition: files.lib.php:2230
dol_mimetype($file, $default= 'application/octet-stream', $mode=0)
Return mime type of a file.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename= '', $restricttologhandler= '', $logcontext=null)
Write log message into outputs.
accessforbidden($message= '', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program Calling this function terminate execution ...
dol_is_file($pathoffile)
Return if path is a file.
Definition: files.lib.php:457
print
Draft customers invoices.
Definition: index.php:89
if(!empty($conf->facture->enabled)&&$user->rights->facture->lire) if((!empty($conf->fournisseur->enabled)&&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)||!empty($conf->supplier_invoice->enabled))&&$user->rights->fournisseur->facture->lire) if(!empty($conf->don->enabled)&&$user->rights->don->lire) if(!empty($conf->tax->enabled)&&$user->rights->tax->charges->lire) if(!empty($conf->facture->enabled)&&!empty($conf->commande->enabled)&&$user->rights->commande->lire &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) if(!empty($conf->facture->enabled)&&$user->rights->facture->lire) if((!empty($conf->fournisseur->enabled)&&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)||!empty($conf->supplier_invoice->enabled))&&$user->rights->fournisseur->facture->lire) $resql
Social contributions to pay.
Definition: index.php:1232
llxFooter()
Empty footer.
Definition: wrapper.php:59
Class to manage ECM files.