dolibarr 25.0.0-alpha
api_documents.class.php
1<?php
2
3/* Copyright (C) 2016 Xebax Christy <xebax@wanadoo.fr>
4 * Copyright (C) 2016 Laurent Destailleur <eldy@users.sourceforge.net>
5 * Copyright (C) 2016 Jean-François Ferry <jfefe@aternatik.fr>
6 * Copyright (C) 2023 Romain Neil <contact@romain-neil.fr>
7 * Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
8 * Copyright (C) 2025-2026 MDW <mdeweerd@users.noreply.github.com>
9 * Copyright (C) 2025 William Mead <william@m34d.com>
10 * Copyright (C) 2025-2026 Charlene Benke <charlene@patas-monkey.com>
11 *
12 * This program is free software you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 3 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program. If not, see <https://www.gnu.org/licenses/>.
24 */
25
26use Luracast\Restler\RestException;
27
28require_once DOL_DOCUMENT_ROOT.'/main.inc.php';
29require_once DOL_DOCUMENT_ROOT.'/api/class/api.class.php';
30require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
31
41{
45 public function __construct()
46 {
47 global $db;
48 $this->db = $db;
49 }
50
51
72 public function index($modulepart, $original_file = '')
73 {
74 global $conf;
75
76 if (empty($modulepart)) {
77 throw new RestException(400, 'bad value for parameter modulepart');
78 }
79 if (empty($original_file)) {
80 throw new RestException(400, 'bad value for parameter original_file');
81 }
82
83 // Normalize modulepart for project_task
84 if ($modulepart == 'task' || $modulepart == 'project_task') {
85 $modulepart = 'project_task';
86 }
87
88 //--- Finds and returns the document
89 $entity = $conf->entity;
90
91 // Special cases that need to use get_exdir to get real dir of object
92 // If future, all object should use this to define path of documents.
93 /*
94 $tmpreldir = '';
95 if ($modulepart == 'supplier_invoice') {
96 $tmpreldir = get_exdir($object->id, 2, 0, 0, $object, 'invoice_supplier');
97 }
98
99 $relativefile = $tmpreldir.dol_sanitizeFileName($object->ref); */
100 $relativefile = $original_file;
101
102 $check_access = dol_check_secure_access_document($modulepart, $relativefile, $entity, DolibarrApiAccess::$user, '', 'read');
103 $accessallowed = $check_access['accessallowed'];
104 $sqlprotectagainstexternals = $check_access['sqlprotectagainstexternals'];
105 $original_file = $check_access['original_file'];
106
107 if (preg_match('/\.\./', $original_file) || preg_match('/[<>|]/', $original_file)) {
108 throw new RestException(403);
109 }
110 if (!$accessallowed) {
111 throw new RestException(403);
112 }
113
114 if (DolibarrApiAccess::$user->socid > 0) {
115 if ($sqlprotectagainstexternals) {
116 $resql = $this->db->query($sqlprotectagainstexternals);
117 if ($resql) {
118 $num = $this->db->num_rows($resql);
119 $i = 0;
120 while ($i < $num) {
121 $obj = $this->db->fetch_object($resql);
122 if (DolibarrApiAccess::$user->socid != $obj->fk_soc) {
123 throw new RestException(403, 'Not allowed to download documents with such a ref');
124 }
125 $i++;
126 }
127 }
128 }
129 }
130
131 $filename = basename($original_file);
132 $original_file_osencoded = dol_osencode($original_file); // New file name encoded in OS encoding charset
133
134 if (!file_exists($original_file_osencoded)) {
135 dol_syslog("Try to download not found file ".$original_file_osencoded, LOG_WARNING);
136 throw new RestException(404, 'File not found');
137 }
138
139 $file_content = file_get_contents($original_file_osencoded);
140 return array('filename' => $filename, 'content-type' => dol_mimetype($filename), 'filesize' => filesize($original_file), 'content' => base64_encode($file_content), 'encoding' => 'base64');
141 }
142
143
174 public function builddoc($modulepart, $original_file = '', $doctemplate = '', $langcode = '')
175 {
176 global $conf, $langs;
177
178 if (empty($modulepart)) {
179 throw new RestException(400, 'bad value for parameter modulepart');
180 }
181 if (empty($original_file)) {
182 throw new RestException(400, 'bad value for parameter original_file');
183 }
184
185 $outputlangs = $langs;
186 if ($langcode && $langs->defaultlang != $langcode) {
187 $outputlangs = new Translate('', $conf);
188 $outputlangs->setDefaultLang($langcode);
189 }
190
191 //--- Finds and returns the document
192 $entity = $conf->entity;
193
194 // Special cases that need to use get_exdir to get real dir of object
195 // If future, all object should use this to define path of documents.
196 /*
197 $tmpreldir = '';
198 if ($modulepart == 'supplier_invoice') {
199 $tmpreldir = get_exdir($object->id, 2, 0, 0, $object, 'invoice_supplier');
200 }
201
202 $relativefile = $tmpreldir.dol_sanitizeFileName($object->ref); */
203 $relativefile = $original_file;
204
205 $check_access = dol_check_secure_access_document($modulepart, $relativefile, $entity, DolibarrApiAccess::$user, '', 'write');
206 $accessallowed = $check_access['accessallowed'];
207 $sqlprotectagainstexternals = $check_access['sqlprotectagainstexternals'];
208 $original_file = $check_access['original_file'];
209
210 if (preg_match('/\.\./', $original_file) || preg_match('/[<>|]/', $original_file)) {
211 throw new RestException(403);
212 }
213 if (!$accessallowed) {
214 throw new RestException(403);
215 }
216
217 if (DolibarrApiAccess::$user->socid > 0) {
218 if ($sqlprotectagainstexternals) {
219 $resql = $this->db->query($sqlprotectagainstexternals);
220 if ($resql) {
221 $num = $this->db->num_rows($resql);
222 $i = 0;
223 while ($i < $num) {
224 $obj = $this->db->fetch_object($resql);
225 if (DolibarrApiAccess::$user->socid != $obj->fk_soc) {
226 throw new RestException(403, 'Not allowed to download documents with such a ref');
227 }
228 $i++;
229 }
230 }
231 }
232 }
233
234 // --- Generates the document
235 $hidedetails = !getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS') ? 0 : 1;
236 $hidedesc = !getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_DESC') ? 0 : 1;
237 $hideref = !getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_REF') ? 0 : 1;
238
239 $templateused = '';
240
241 if ($modulepart == 'facture' || $modulepart == 'invoice') {
242 require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
243 $tmpobject = new Facture($this->db);
244 $result = $tmpobject->fetch(0, preg_replace('/\.[^\.]+$/', '', basename($original_file)));
245 if (!$result) {
246 throw new RestException(404, 'Invoice not found');
247 }
248
249 $templateused = $doctemplate ? $doctemplate : $tmpobject->model_pdf;
250 $result = $tmpobject->generateDocument($templateused, $outputlangs, $hidedetails, $hidedesc, $hideref);
251 if ($result <= 0) {
252 throw new RestException(500, 'Error generating document');
253 }
254 } elseif ($modulepart == 'facture_fournisseur' || $modulepart == 'invoice_supplier') {
255 require_once DOL_DOCUMENT_ROOT . '/fourn/class/fournisseur.facture.class.php';
256 $tmpobject = new FactureFournisseur($this->db);
257 $result = $tmpobject->fetch(0, preg_replace('/\.[^\.]+$/', '', basename($original_file)));
258 if (!$result) {
259 throw new RestException(404, 'Supplier invoice not found');
260 }
261
262 $templateused = $doctemplate ? $doctemplate : $tmpobject->model_pdf;
263 $result = $tmpobject->generateDocument($templateused, $outputlangs, $hidedetails, $hidedesc, $hideref);
264 if ($result < 0) {
265 throw new RestException(500, 'Error generating document');
266 }
267 } elseif ($modulepart == 'commande' || $modulepart == 'order') {
268 require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
269 $tmpobject = new Commande($this->db);
270 $result = $tmpobject->fetch(0, preg_replace('/\.[^\.]+$/', '', basename($original_file)));
271 if (!$result) {
272 throw new RestException(404, 'Order not found');
273 }
274 $templateused = $doctemplate ? $doctemplate : $tmpobject->model_pdf;
275 $result = $tmpobject->generateDocument($templateused, $outputlangs, $hidedetails, $hidedesc, $hideref);
276 if ($result <= 0) {
277 throw new RestException(500, 'Error generating document');
278 }
279 } elseif ($modulepart == 'propal' || $modulepart == 'proposal') {
280 require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
281 $tmpobject = new Propal($this->db);
282 $result = $tmpobject->fetch(0, preg_replace('/\.[^\.]+$/', '', basename($original_file)));
283 if (!$result) {
284 throw new RestException(404, 'Proposal not found');
285 }
286 $templateused = $doctemplate ? $doctemplate : $tmpobject->model_pdf;
287 $result = $tmpobject->generateDocument($templateused, $outputlangs, $hidedetails, $hidedesc, $hideref);
288 if ($result <= 0) {
289 throw new RestException(500, 'Error generating document');
290 }
291 } elseif ($modulepart == 'contrat' || $modulepart == 'contract') {
292 require_once DOL_DOCUMENT_ROOT . '/contrat/class/contrat.class.php';
293
294 $tmpobject = new Contrat($this->db);
295 $result = $tmpobject->fetch(0, preg_replace('/\.[^\.]+$/', '', basename($original_file)));
296
297 if (!$result) {
298 throw new RestException(404, 'Contract not found');
299 }
300
301 $templateused = $doctemplate ? $doctemplate : $tmpobject->model_pdf;
302 $result = $tmpobject->generateDocument($templateused, $outputlangs, $hidedetails, $hidedesc, $hideref);
303
304 if ($result <= 0) {
305 throw new RestException(500, 'Error generating document');
306 }
307 } elseif ($modulepart == 'expedition' || $modulepart == 'shipment') {
308 require_once DOL_DOCUMENT_ROOT . '/expedition/class/expedition.class.php';
309
310 $tmpobject = new Expedition($this->db);
311 $result = $tmpobject->fetch(0, preg_replace('/\.[^\.]+$/', '', basename($original_file)));
312
313 if (!$result) {
314 throw new RestException(404, 'Shipment not found');
315 }
316
317 $templateused = $doctemplate ? $doctemplate : $tmpobject->model_pdf;
318 $result = $tmpobject->generateDocument($templateused, $outputlangs, $hidedetails, $hidedesc, $hideref);
319
320 if ($result <= 0) {
321 throw new RestException(500, 'Error generating document');
322 }
323 } elseif ($modulepart == 'mrp') {
324 require_once DOL_DOCUMENT_ROOT . '/mrp/class/mo.class.php';
325
326 $tmpobject = new Mo($this->db);
327 $result = $tmpobject->fetch(0, preg_replace('/\.[^\.]+$/', '', basename($original_file)));
328
329 if (!$result) {
330 throw new RestException(404, 'MO not found');
331 }
332
333 $templateused = $doctemplate ? $doctemplate : $tmpobject->model_pdf;
334 $result = $tmpobject->generateDocument($templateused, $outputlangs, $hidedetails, $hidedesc, $hideref);
335
336 if ($result <= 0) {
337 throw new RestException(500, 'Error generating document');
338 }
339 } elseif ($modulepart == 'expensereport') {
340 require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
341
342 $tmpobject = new ExpenseReport($this->db);
343 $result = $tmpobject->fetch(0, preg_replace('/\.[^\.]+$/', '', basename($original_file)));
344
345 if (!$result) {
346 throw new RestException(404, 'Expense report not found');
347 }
348
349 $templateused = $doctemplate ? $doctemplate : $tmpobject->model_pdf;
350 $result = $tmpobject->generateDocument($templateused, $outputlangs, $hidedetails, $hidedesc, $hideref);
351
352 if ($result <= 0) {
353 throw new RestException(500, 'Error generating document');
354 }
355 } elseif ($modulepart == 'holiday') {
356 require_once DOL_DOCUMENT_ROOT.'/holiday/class/holiday.class.php';
357
358 $tmpobject = new Holiday($this->db);
359 $result = $tmpobject->fetch(0, preg_replace('/\.[^\.]+$/', '', basename($original_file)));
360
361 if (!$result) {
362 throw new RestException(404, 'Holiday not found');
363 }
364
365 $templateused = $doctemplate ? $doctemplate : $tmpobject->model_pdf;
366 $result = $tmpobject->generateDocument($templateused, $outputlangs, $hidedetails, $hidedesc, $hideref);
367
368 if ($result <= 0) {
369 throw new RestException(500, 'Error generating document');
370 }
371 } elseif ($modulepart == 'product') {
372 require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
373
374 $tmpobject = new Product($this->db);
375 $result = $tmpobject->fetch(0, preg_replace('/\.[^\.]+$/', '', basename($original_file)));
376
377 if (!$result) {
378 throw new RestException(404, 'Product not found');
379 }
380
381 $templateused = $doctemplate ? $doctemplate : $tmpobject->model_pdf;
382 $result = $tmpobject->generateDocument($templateused, $outputlangs, $hidedetails, $hidedesc, $hideref);
383
384 if ($result <= 0) {
385 throw new RestException(500, 'Error generating document');
386 }
387 } elseif ($modulepart == 'stock' || $modulepart == 'entrepot') {
388 require_once DOL_DOCUMENT_ROOT . '/product/stock/class/entrepot.class.php';
389
390 $tmpobject = new Entrepot($this->db);
391 $result = $tmpobject->fetch(0, preg_replace('/\.[^\.]+$/', '', basename($original_file)));
392
393 if (!$result) {
394 throw new RestException(404, 'Warehouse not found');
395 }
396
397 $templateused = $doctemplate ? $doctemplate : $tmpobject->model_pdf;
398 $result = $tmpobject->generateDocument($templateused, $outputlangs, $hidedetails, $hidedesc, $hideref);
399
400 if ($result <= 0) {
401 throw new RestException(500, 'Error generating document');
402 }
403 } elseif ($modulepart == 'fichinter' || $modulepart == 'intervention') {
404 require_once DOL_DOCUMENT_ROOT . '/fichinter/class/fichinter.class.php';
405
406 $tmpobject = new Fichinter($this->db);
407 $result = $tmpobject->fetch(0, preg_replace('/\.[^\.]+$/', '', basename($original_file)));
408
409 if (!$result) {
410 throw new RestException(404, 'Intervention not found');
411 }
412
413 $templateused = $doctemplate ? $doctemplate : $tmpobject->model_pdf;
414 $result = $tmpobject->generateDocument($templateused, $outputlangs, $hidedetails, $hidedesc, $hideref);
415
416 if ($result <= 0) {
417 throw new RestException(500, 'Error generating document');
418 }
419 } else {
420 throw new RestException(403, 'Generation not available for this modulepart');
421 }
422
423 $filename = basename($original_file);
424 $original_file_osencoded = dol_osencode($original_file); // New file name encoded in OS encoding charset
425
426 if (!file_exists($original_file_osencoded)) {
427 throw new RestException(404, 'File not found');
428 }
429
430 $file_content = file_get_contents($original_file_osencoded);
431 return array('filename' => $filename, 'content-type' => dol_mimetype($filename), 'filesize' => filesize($original_file), 'content' => base64_encode($file_content), 'langcode' => $outputlangs->defaultlang, 'template' => $templateused, 'encoding' => 'base64');
432 }
433
463 public function getDocumentsListByElement($modulepart, $id = 0, $ref = '', $sortfield = '', $sortorder = '', $limit = 100, $page = 0, $content_type = '', $pagination_data = false)
464 {
465 if (empty($modulepart)) {
466 throw new RestException(400, 'bad value for parameter modulepart');
467 }
468
469 if (empty($id) && empty($ref)) {
470 throw new RestException(400, 'bad value for parameter id or ref');
471 }
472
473 $id = (empty($id) ? 0 : $id);
474
475 if ($modulepart == 'facture_fournisseur') {
476 $modulepart = 'supplier_invoice'; // Alias unknown by fetchObjectByElement()
477 }
478
479 // Define $object
480 $object = fetchObjectByElement($id, $modulepart, $ref); // Note that we don't mind id and ref, we want to get a valid instantiated $object but not necessarily initialized
481 if (!is_object($object)) {
482 throw new RestException(404, 'Module for modulepart = '.$modulepart." is not enabled (or not yet supported by API");
483 }
484
485 // Define $upload_dir to scan
486 if ($object->element == 'invoice_supplier' && $object->id > 0) {
487 // Supplier invoices are stored under a hashed subdir, as in the other methods of this file
488 $upload_dir = getMultidirOutput($object).'/'.get_exdir($object->id, 2, 0, 0, $object, 'invoice_supplier').dol_sanitizeFileName($object->ref);
489 } else {
490 $upload_dir = (string) getMultidirOutput($object, '', 1);
491 }
492
493 // Check object-level permissions
494 $ok = checkUserAccessToObject(DolibarrApiAccess::$user, array($object->element), $object, $object->table_element, '');
495 if (empty($ok)) {
496 throw new RestException(403, 'Access not allowed to this object (refused by checkUserAccessToObject)');
497 }
498
499 // Check permission on module
500 if ($modulepart == 'societe' || $modulepart == 'thirdparty') {
501 if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
502 throw new RestException(403);
503 }
504 } elseif ($modulepart == 'user') {
505 // Can get doc if has permission to read all user or if it is user itself
506 if (!DolibarrApiAccess::$user->hasRight('user', 'user', 'lire') && DolibarrApiAccess::$user->id != $id) {
507 throw new RestException(403);
508 }
509 } elseif ($modulepart == 'adherent' || $modulepart == 'member') {
510 if (!DolibarrApiAccess::$user->hasRight('adherent', 'lire')) {
511 throw new RestException(403);
512 }
513 } elseif ($modulepart == 'propal' || $modulepart == 'proposal') {
514 if (!DolibarrApiAccess::$user->hasRight('propal', 'lire')) {
515 throw new RestException(403);
516 }
517 } elseif ($modulepart == 'supplier_proposal') {
518 if (!DolibarrApiAccess::$user->hasRight('supplier_proposal', 'read')) {
519 throw new RestException(403);
520 }
521 } elseif ($modulepart == 'commande' || $modulepart == 'order') {
522 if (!DolibarrApiAccess::$user->hasRight('commande', 'lire')) {
523 throw new RestException(403);
524 }
525 } elseif ($modulepart == 'commande_fournisseur' || $modulepart == 'supplier_order') {
526 $modulepart = 'supplier_order';
527 if (!DolibarrApiAccess::$user->hasRight('fournisseur', 'commande', 'lire') && !DolibarrApiAccess::$user->hasRight('supplier_order', 'lire')) {
528 throw new RestException(403);
529 }
530 } elseif ($modulepart == 'shipment' || $modulepart == 'expedition') {
531 if (!DolibarrApiAccess::$user->hasRight('expedition', 'lire')) {
532 throw new RestException(403);
533 }
534 } elseif ($modulepart == 'facture' || $modulepart == 'invoice') {
535 if (!DolibarrApiAccess::$user->hasRight('facture', 'lire')) {
536 throw new RestException(403);
537 }
538 } elseif ($modulepart == 'facture_fournisseur' || $modulepart == 'supplier_invoice') {
539 $modulepart = 'supplier_invoice';
540 if (!DolibarrApiAccess::$user->hasRight('fournisseur', 'facture', 'lire') && !DolibarrApiAccess::$user->hasRight('supplier_invoice', 'lire')) {
541 throw new RestException(403);
542 }
543 } elseif ($modulepart == 'produit' || $modulepart == 'product' || $modulepart == 'service') {
544 if (!DolibarrApiAccess::$user->hasRight('produit', 'lire')) {
545 throw new RestException(403);
546 }
547 } elseif ($modulepart == 'agenda' || $modulepart == 'action' || $modulepart == 'event' || $modulepart == 'actioncomm') {
548 if (!DolibarrApiAccess::$user->hasRight('agenda', 'myactions', 'read') && !DolibarrApiAccess::$user->hasRight('agenda', 'allactions', 'read')) {
549 throw new RestException(403);
550 }
551 } elseif ($modulepart == 'expensereport') {
552 if (!DolibarrApiAccess::$user->hasRight('expensereport', 'read')) {
553 throw new RestException(403);
554 }
555 } elseif ($modulepart == 'holiday') {
556 if (!DolibarrApiAccess::$user->hasRight('holiday', 'read')) {
557 throw new RestException(403);
558 }
559 } elseif ($modulepart == 'ticket') {
560 if (!DolibarrApiAccess::$user->hasRight('ticket', 'read')) {
561 throw new RestException(403);
562 }
563 } elseif ($modulepart == 'knowledgemanagement') {
564 if (!DolibarrApiAccess::$user->hasRight('knowledgemanagement', 'knowledgerecord', 'read')) {
565 throw new RestException(403);
566 }
567 } elseif ($modulepart == 'categorie' || $modulepart == 'category') {
568 if (!DolibarrApiAccess::$user->hasRight('categorie', 'lire')) {
569 throw new RestException(403);
570 }
571 } elseif ($modulepart == 'ecm') {
572 throw new RestException(500, 'Modulepart Ecm not implemented yet.');
573 // if (!DolibarrApiAccess::$user->hasRight('ecm', 'read')) {
574 // throw new RestException(403);
575 // }
576 } elseif ($modulepart == 'contrat' || $modulepart == 'contract') {
577 $modulepart = 'contrat';
578 if (!DolibarrApiAccess::$user->hasRight('contrat', 'lire')) {
579 throw new RestException(403);
580 }
581 } elseif ($modulepart == 'intervention' || $modulepart == 'ficheinter') {
582 $modulepart = 'ficheinter';
583 if (!DolibarrApiAccess::$user->hasRight('ficheinter', 'lire')) {
584 throw new RestException(403);
585 }
586 } elseif ($modulepart == 'projet' || $modulepart == 'project') {
587 $modulepart = 'project';
588 if (!DolibarrApiAccess::$user->hasRight('projet', 'lire')) {
589 throw new RestException(403);
590 }
591 } elseif ($modulepart == 'task' || $modulepart == 'project_task') {
592 $modulepart = 'project_task';
593 if (!DolibarrApiAccess::$user->hasRight('projet', 'lire')) {
594 throw new RestException(403);
595 }
596 } elseif ($modulepart == 'mrp') {
597 $modulepart = 'mrp';
598 if (!DolibarrApiAccess::$user->hasRight('mrp', 'read')) {
599 throw new RestException(403);
600 }
601 } elseif ($modulepart == 'contact' || $modulepart == 'socpeople') {
602 $modulepart = 'contact';
603 if (!DolibarrApiAccess::$user->hasRight('societe', 'contact', 'lire')) {
604 throw new RestException(403);
605 }
606 } elseif ($modulepart == 'stock') {
607 if (!DolibarrApiAccess::$user->hasRight('stock', 'lire')) {
608 throw new RestException(403);
609 }
610 } else {
611 throw new RestException(500, 'Modulepart '.$modulepart.' not implemented yet.');
612 }
613
614 // Scan files into directory
615 $recursive = 0;
616 $type = 'files';
617
618 $objectType = $modulepart;
619 if (! empty($object->id) && ! empty($object->table_element)) {
620 $objectType = $object->table_element;
621 }
622
623 $filearray = dol_dir_list($upload_dir, $type, $recursive, '', '(\.meta|_preview.*\.png)$', $sortfield, (strtolower($sortorder) == 'desc' ? SORT_DESC : SORT_ASC), 1);
624
625 $countarray = is_array($filearray) ? count($filearray) : 0;
626
627 if (empty($filearray)) {
628 throw new RestException(404, 'Search for modulepart '.$modulepart.' with Id '.$id.(!empty($ref) ? ' or Ref '.$ref : '').' does not return any document.');
629 } else {
630 $filearray = array_slice($filearray, $limit * $page, $limit);
631 if (($object->id) > 0 && !empty($modulepart)) {
632 require_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php';
633 $ecmfile = new EcmFiles($this->db);
634 $result = $ecmfile->fetchAll('', '', 0, 0, array('t.src_object_type' => $objectType, 't.src_object_id' => $object->id));
635 if ($result < 0) {
636 throw new RestException(503, 'Error when retrieve ecm list : '.$this->db->lasterror());
637 } elseif (is_array($ecmfile->lines) && count($ecmfile->lines) > 0) {
638 foreach ($filearray as &$fileitem) {
639 foreach ($ecmfile->lines as $line) {
640 if ($fileitem['name'] == $line->filename) {
641 // Next line converts EcmFilesLine properties to array
642 //$fileitem = array_merge($fileitem, (array) $line);
643 $fileitem['ref'] = $line->ref;
644 $fileitem['label'] = $line->label;
645 $fileitem['filepath'] = $line->filepath;
646 $fileitem['filename'] = $line->filename;
647 $fileitem['fullpath_orig'] = $line->fullpath_orig;
648 $fileitem['position'] = $line->position;
649 $fileitem['gen_or_uploaded'] = $line->gen_or_uploaded;
650 $fileitem['description'] = $line->desc;
651 $fileitem['keywords'] = $line->keywords;
652 $fileitem['cover'] = $line->cover;
653 $fileitem['share'] = $line->share;
654 $fileitem['date_c'] = $line->date_c;
655 $fileitem['agenda_id'] = $line->agenda_id;
656 $fileitem['fk_user_c'] = $line->fk_user_c;
657 $fileitem['fk_user_m'] = $line->fk_user_m;
658 $fileitem['note_private'] = $line->note_private;
659 $fileitem['note_public'] = $line->note_public;
660 }
661 }
662 if (isset($fileitem['relativename'])) {
663 $fileitem['content-type'] = dol_mimetype((string) $fileitem['relativename']);
664 }
665 }
666
667 // Select only files that match the requested $content_type, if provided
668 $arraycontenttype = explode(",", $content_type);
669 if (!empty($content_type)) {
670 $filearray = array_filter(
671 $filearray,
676 static function ($fileitem) use (&$arraycontenttype) {
677 return in_array(($fileitem['content-type'] ?: 'UNKNOWN'), $arraycontenttype);
678 }
679 );
680 }
681 }
682 }
683 }
684
685 // Clean result from fullname
686 foreach ($filearray as $tmpkey => $tmpval) {
687 unset($filearray[$tmpkey]['path']);
688 unset($filearray[$tmpkey]['fullname']);
689 }
690
691 //if $pagination_data is true the response will contain element data with all values and element pagination with pagination data(total,page,limit)
692 if ($pagination_data) {
693 $filearray = [
694 'data' => $filearray,
695 'pagination' => [
696 'total' => (int) $countarray,
697 'page' => $page, // count starts from 0
698 'page_count' => (int) ceil((int) $countarray / $limit),
699 'limit' => $limit
700 ]
701 ];
702 }
703
704 return $filearray;
705 }
706
707
716 /*
717 public function get($id) {
718 return array('note'=>'xxx');
719 }*/
720
721
758 public function post($filename, $modulepart, $ref = '', $subdir = '', $filecontent = '', $fileencoding = '', $overwriteifexists = 0, $createdirifnotexists = 1, $position = 0, $cover = '', $array_options = [], $generateThumbs = 0, $share = 0)
759 {
760 global $conf;
761
762 $modulepartorig = $modulepart;
763
764 if (empty($modulepart)) {
765 throw new RestException(400, 'Modulepart not provided.');
766 }
767
768 $newfilecontent = '';
769 if (empty($fileencoding)) {
770 $newfilecontent = $filecontent;
771 }
772 if ($fileencoding == 'base64') {
773 $newfilecontent = base64_decode($filecontent);
774 }
775
776 $original_file = dol_sanitizeFileName($filename);
777 $relativefile = 'UNSET';
778
779 // Define $uploadir
780 $object = null;
781 $entity = DolibarrApiAccess::$user->entity;
782 if (empty($entity)) {
783 $entity = 1;
784 }
785
786 if ($ref) {
787 $tmpreldir = '';
788 $fetchbyid = false;
789
790 if ($modulepart == 'facture' || $modulepart == 'invoice') {
791 $modulepart = 'facture';
792
793 require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
794 $object = new Facture($this->db);
795 } elseif ($modulepart == 'facture_fournisseur' || $modulepart == 'supplier_invoice') {
796 $modulepart = 'supplier_invoice';
797
798 require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
799 $object = new FactureFournisseur($this->db);
800 } elseif ($modulepart == 'commande' || $modulepart == 'order') {
801 $modulepart = 'commande';
802
803 require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
804 $object = new Commande($this->db);
805 } elseif ($modulepart == 'commande_fournisseur' || $modulepart == 'supplier_order') {
806 $modulepart = 'supplier_order';
807
808 require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
809 $object = new CommandeFournisseur($this->db);
810 } elseif ($modulepart == 'projet' || $modulepart == 'project') {
811 require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
812 $object = new Project($this->db);
813 } elseif ($modulepart == 'task' || $modulepart == 'project_task') {
814 $modulepart = 'project_task';
815
816 require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
817 $object = new Task($this->db);
818
819 $task_result = $object->fetch(0, $ref);
820
821 // Fetching the tasks project is required because its out_dir might be a sub-directory of the project
822 if ($task_result > 0) {
823 $project_result = $object->fetchProject();
824
825 if ($project_result >= 0) {
826 $tmpreldir = dol_sanitizeFileName((string) $object->project->ref).'/';
827 }
828 } else {
829 throw new RestException(500, 'Error while fetching Task '.$ref);
830 }
831 } elseif ($modulepart == 'product' || $modulepart == 'produit' || $modulepart == 'service' || $modulepart == 'produit|service') {
832 require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
833 $object = new Product($this->db);
834 } elseif ($modulepart == 'expensereport') {
835 require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
836 $object = new ExpenseReport($this->db);
837 } elseif ($modulepart == 'holiday') {
838 require_once DOL_DOCUMENT_ROOT.'/holiday/class/holiday.class.php';
839 $object = new Holiday($this->db);
840 } elseif ($modulepart == 'ficheinter' || $modulepart == 'intervention') {
841 require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinter.class.php';
842 $object = new Fichinter($this->db);
843 } elseif ($modulepart == 'shipment' || $modulepart == 'expedition') {
844 require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php';
845 $object = new Expedition($this->db);
846 } elseif ($modulepart == 'adherent' || $modulepart == 'member') {
847 $modulepart = 'adherent';
848 require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
849 $object = new Adherent($this->db);
850 } elseif ($modulepart == 'proposal' || $modulepart == 'propal' || $modulepart == 'propale') {
851 $modulepart = 'propale';
852 require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
853 $object = new Propal($this->db);
854 } elseif ($modulepart == 'agenda' || $modulepart == 'action' || $modulepart == 'event') {
855 $modulepart = 'agenda';
856 require_once DOL_DOCUMENT_ROOT . '/comm/action/class/actioncomm.class.php';
857 $object = new ActionComm($this->db);
858 } elseif ($modulepart == 'contact' || $modulepart == 'socpeople') {
859 $modulepart = 'contact';
860 require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
861 $object = new Contact($this->db);
862 $fetchbyid = true;
863 } elseif ($modulepart == 'societe' || $modulepart == 'company') {
864 $modulepart = 'societe';
865 require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
866 $object = new Societe($this->db);
867 $fetchbyid = true;
868 } elseif ($modulepart == 'knowledgemanagement') {
869 $modulepart = 'knowledgemanagement';
870 require_once DOL_DOCUMENT_ROOT.'/knowledgemanagement/class/knowledgerecord.class.php';
871 $object = new KnowledgeRecord($this->db);
872 $fetchbyid = true;
873 } elseif ($modulepart == 'ticket') {
874 $modulepart = 'ticket';
875 require_once DOL_DOCUMENT_ROOT.'/ticket/class/ticket.class.php';
876 $object = new Ticket($this->db);
877 $fetchbyid = true;
878 } elseif ($modulepart == 'contrat' || $modulepart == 'contract') {
879 $modulepart = 'contrat';
880 require_once DOL_DOCUMENT_ROOT . '/contrat/class/contrat.class.php';
881 $object = new Contrat($this->db);
882 } elseif ($modulepart == 'mrp') {
883 $modulepart = 'mrp';
884 require_once DOL_DOCUMENT_ROOT . '/mrp/class/mo.class.php';
885 $object = new Mo($this->db);
886 } elseif ($modulepart == 'stock') {
887 $modulepart = 'stock';
888 require_once DOL_DOCUMENT_ROOT . '/product/stock/class/entrepot.class.php';
889 $object = new Entrepot($this->db);
890 } elseif ($modulepart == 'ecm') {
891 throw new RestException(500, 'Using a non empty "ref" is not compatible with using modulepart = '.$modulepart);
892 } else {
893 // TODO Implement additional moduleparts
894 throw new RestException(500, 'Modulepart '.$modulepart.' not implemented yet.');
895 }
896
897 // at this step $object is always an object
898 if ($fetchbyid) {
899 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
900 $result = $object->fetch((int) $ref);
901 } else {
902 $result = $object->fetch(0, $ref);
903 }
904
905 if ($result == 0) {
906 throw new RestException(404, "Object with ref '".$ref."' was not found.");
907 } elseif ($result < 0) {
908 throw new RestException(500, 'Error while fetching object: '.$object->errorsToString());
909 }
910
911 if (!($object->id > 0)) {
912 throw new RestException(404, 'The object '.$modulepart." with ref '".$ref."' was not found.");
913 }
914
915 // Special cases that need to use get_exdir to get real dir of object
916 // In future, all object should use this to define path of documents.
917 if ($modulepart == 'supplier_invoice') {
918 $tmpreldir = get_exdir($object->id, 2, 0, 0, $object, 'invoice_supplier');
919 }
920
921 // Test on permissions
922 //if ($modulepart != 'ecm') { // Here $modulepart is always != 'ecm'
923 if ($modulepart == 'societe') {
924 $relativefile = $tmpreldir.dol_sanitizeFileName((string) $object->id);
925 } else {
926 $relativefile = $tmpreldir.dol_sanitizeFileName((string) $object->ref);
927 }
928 $tmp = dol_check_secure_access_document($modulepart, $relativefile, $entity, DolibarrApiAccess::$user, $ref, 'write');
929 if (empty($tmp['accessallowed'])) {
930 throw new RestException(403, 'Access not allowed to upload file into this directory');
931 }
932 $upload_dir = $tmp['original_file']; // No dirname here, tmp['original_file'] is already the dir because dol_check_secure_access_document was called with param original_file that is only the dir
933 /*} else {
934 if (!DolibarrApiAccess::$user->hasRight('ecm', 'upload')) {
935 throw new RestException(403, 'Missing permission to upload files in ECM module');
936 }
937 $upload_dir = $conf->medias->multidir_output[$conf->entity];
938 }*/
939
940 if (empty($upload_dir) || $upload_dir == '/') {
941 throw new RestException(500, 'This value of modulepart ('.$modulepart.') does not support yet usage of ref. Check modulepart parameter or try to use subdir parameter instead of ref.');
942 }
943 } else {
944 if ($modulepart == 'invoice') {
945 $modulepart = 'facture';
946 }
947 if ($modulepart == 'member') {
948 $modulepart = 'adherent';
949 }
950
951 // Test on permissions
952 if ($modulepart != 'ecm') {
953 $relativefile = $subdir;
954 $tmp = dol_check_secure_access_document($modulepart, $relativefile, $entity, DolibarrApiAccess::$user, '', 'write');
955 if (empty($tmp['accessallowed'])) {
956 throw new RestException(403, 'Access not allowed to upload file into this directory');
957 }
958 $upload_dir = $tmp['original_file']; // No dirname here, tmp['original_file'] is already the dir because dol_check_secure_access_document was called with param original_file that is only the dir
959 } else {
960 if (!DolibarrApiAccess::$user->hasRight('ecm', 'upload')) {
961 throw new RestException(403, 'Missing permission to upload files in ECM module');
962 }
963 $upload_dir = $conf->medias->multidir_output[$conf->entity];
964 }
965
966 if (empty($upload_dir) || $upload_dir == '/') {
967 if (!empty($tmp['error'])) {
968 throw new RestException(403, 'Error returned by dol_check_secure_access_document: '.$tmp['error']);
969 } else {
970 throw new RestException(400, 'This value of modulepart ('.$modulepart.') is not allowed with this value of subdir ('.$relativefile.')');
971 }
972 }
973 }
974 // $original_file here is still value of filename without any dir.
975
976 $upload_dir = dol_sanitizePathName($upload_dir);
977
978 if (!empty($createdirifnotexists)) {
979 if (dol_mkdir($upload_dir) < 0) { // needed by products
980 throw new RestException(500, 'Error while trying to create directory '.$upload_dir);
981 }
982 }
983
984 $destfile = $upload_dir.'/'.$original_file;
985 $destfiletmp = DOL_DATA_ROOT.'/admin/temp/'.$original_file;
986 dol_delete_file($destfiletmp);
987 //var_dump($original_file);exit;
988
989 if (!dol_is_dir(dirname($destfile))) {
990 throw new RestException(400, 'Directory does not exists : '.dirname($destfile));
991 }
992
993 if (!$overwriteifexists && dol_is_file($destfile)) {
994 throw new RestException(400, "File with name '".$original_file."' already exists.");
995 }
996
997 // in case temporary directory admin/temp doesn't exist
998 if (!dol_is_dir(dirname($destfiletmp))) {
999 dol_mkdir(dirname($destfiletmp));
1000 }
1001
1002 $fhandle = @fopen($destfiletmp, 'w');
1003 if ($fhandle) {
1004 $nbofbyteswrote = fwrite($fhandle, $newfilecontent);
1005 fclose($fhandle);
1006 dolChmod($destfiletmp);
1007 } else {
1008 throw new RestException(500, "Failed to open file '".$destfiletmp."' for write");
1009 }
1010
1011 $disablevirusscan = 0;
1012 $src_file = $destfiletmp;
1013 $dest_file = $destfile;
1014
1015 // Security:
1016 // If we need to make a virus scan
1017 if (empty($disablevirusscan) && file_exists($src_file)) {
1018 $checkvirusarray = dolCheckVirus($src_file, $dest_file);
1019 if (count($checkvirusarray)) {
1020 dol_syslog('Files.lib::dol_move_uploaded_file File "'.$src_file.'" (target name "'.$dest_file.'") KO with antivirus: errors='.implode(',', $checkvirusarray), LOG_WARNING);
1021 throw new RestException(500, 'ErrorFileIsInfectedWithAVirus: '.implode(',', $checkvirusarray));
1022 }
1023 }
1024
1025 // Security:
1026 // Disallow file with some extensions. We rename them.
1027 // Because if we put the documents directory into a directory inside web root (very bad), this allows to execute on demand arbitrary code.
1028 if (isAFileWithExecutableContent($dest_file) && !getDolGlobalString('MAIN_DOCUMENT_IS_OUTSIDE_WEBROOT_SO_NOEXE_NOT_REQUIRED')) {
1029 // $upload_dir ends with a slash, so be must be sure the medias dir to compare to ends with slash too.
1030 $publicmediasdirwithslash = $conf->medias->multidir_output[$conf->entity];
1031 if (!preg_match('/\/$/', $publicmediasdirwithslash)) {
1032 $publicmediasdirwithslash .= '/';
1033 }
1034
1035 if (strpos($upload_dir, $publicmediasdirwithslash) !== 0 || !getDolGlobalInt("MAIN_DOCUMENT_DISABLE_NOEXE_IN_MEDIAS_DIR")) { // We never add .noexe on files into media directory
1036 $dest_file .= '.noexe';
1037 }
1038 }
1039
1040 // Security:
1041 // We refuse cache files/dirs, upload using .. and pipes into filenames.
1042 if (preg_match('/^\./', basename($src_file)) || preg_match('/\.\./', $src_file) || preg_match('/[<>|]/', $src_file)) {
1043 dol_syslog("Refused to deliver file ".$src_file, LOG_WARNING);
1044 throw new RestException(500, "Refused to deliver file ".$src_file);
1045 }
1046
1047 // Security:
1048 // We refuse cache files/dirs, upload using .. and pipes into filenames.
1049 if (preg_match('/^\./', basename($dest_file)) || preg_match('/\.\./', $dest_file) || preg_match('/[<>|]/', $dest_file)) {
1050 dol_syslog("Refused to deliver file ".$dest_file, LOG_WARNING);
1051 throw new RestException(500, "Refused to deliver file ".$dest_file);
1052 }
1053
1054 $moreinfo = array('note_private' => 'File uploaded using API /documents from IP '.getUserRemoteIP());
1055 // $object may be null
1056 if (is_object($object) && $object->id > 0) {
1057 $moreinfo['src_object_type'] = $object->table_element;
1058 $moreinfo['src_object_id'] = $object->id;
1059 }
1060 if (!empty($array_options)) {
1061 $moreinfo = array_merge($moreinfo, ["array_options" => $array_options]);
1062 }
1063 if (!empty($position)) {
1064 $moreinfo = array_merge($moreinfo, ["position" => $position]);
1065 }
1066 if (!empty($cover)) {
1067 $moreinfo = array_merge($moreinfo, ["cover" => $cover]);
1068 }
1069 if (!empty($share)) {
1070 require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
1071 $moreinfo = array_merge($moreinfo, ["share" => getRandomPassword(true)]);
1072 }
1073 $moreinfo['gen_or_uploaded'] = 'api';
1074
1075 // Move the temporary file at its final emplacement
1076 $result = dol_move($destfiletmp, $dest_file, '0', $overwriteifexists, 1, 1, $moreinfo);
1077 if (!$result) {
1078 throw new RestException(500, "Failed to move file into '".$dest_file."'");
1079 }
1080
1081 if (is_object($object) && $generateThumbs) {
1082 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
1083 require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php'; // image_format_supported() is defined here
1084 if (image_format_supported($dest_file)) {
1085 $object->addThumbs($dest_file);
1086 }
1087 }
1088
1089 return dol_basename($destfile);
1090 }
1091
1111 public function delete($modulepart, $original_file)
1112 {
1113 global $conf;
1114
1115 if (empty($modulepart)) {
1116 throw new RestException(400, 'bad value for parameter modulepart');
1117 }
1118 if (empty($original_file)) {
1119 throw new RestException(400, 'bad value for parameter original_file');
1120 }
1121
1122 // Normalize modulepart for project_task
1123 if ($modulepart == 'task') {
1124 $modulepart = 'project_task';
1125 }
1126
1127 //--- Finds and returns the document
1128 $entity = $conf->entity;
1129
1130 // Special cases that need to use get_exdir to get real dir of object
1131 // If future, all object should use this to define path of documents.
1132 /*
1133 $tmpreldir = '';
1134 if ($modulepart == 'supplier_invoice') {
1135 $tmpreldir = get_exdir($object->id, 2, 0, 0, $object, 'invoice_supplier');
1136 }
1137
1138 $relativefile = $tmpreldir.dol_sanitizeFileName($object->ref); */
1139 $relativefile = $original_file;
1140
1141 $check_access = dol_check_secure_access_document($modulepart, $relativefile, $entity, DolibarrApiAccess::$user, '', 'write');
1142 $accessallowed = $check_access['accessallowed'];
1143 $sqlprotectagainstexternals = $check_access['sqlprotectagainstexternals'];
1144 $original_file = $check_access['original_file'];
1145
1146 if (preg_match('/\.\./', $original_file) || preg_match('/[<>|]/', $original_file)) {
1147 throw new RestException(403);
1148 }
1149 if (!$accessallowed) {
1150 throw new RestException(403);
1151 }
1152
1153 if (DolibarrApiAccess::$user->socid > 0) {
1154 if ($sqlprotectagainstexternals) {
1155 $resql = $this->db->query($sqlprotectagainstexternals);
1156 if ($resql) {
1157 $num = $this->db->num_rows($resql);
1158 $i = 0;
1159 while ($i < $num) {
1160 $obj = $this->db->fetch_object($resql);
1161 if (DolibarrApiAccess::$user->socid != $obj->fk_soc) {
1162 throw new RestException(403, 'Not allowed to download documents with such a ref');
1163 }
1164 $i++;
1165 }
1166 }
1167 }
1168 }
1169
1170 $filename = basename($original_file);
1171 $original_file_osencoded = dol_osencode($original_file); // New file name encoded in OS encoding charset
1172
1173 if (!file_exists($original_file_osencoded)) {
1174 dol_syslog("Try to download not found file ".$original_file_osencoded, LOG_WARNING);
1175 throw new RestException(404, 'File not found');
1176 }
1177
1178 if (@unlink($original_file_osencoded)) {
1179 return array(
1180 'success' => array(
1181 'code' => 200,
1182 'message' => 'Document deleted'
1183 )
1184 );
1185 }
1186
1187 throw new RestException(403);
1188 }
1189}
$id
Support class for third parties, contacts, members, users or resources.
Definition account.php:47
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
Class to manage agenda events (actions)
Class to manage members of a foundation.
Class to manage predefined suppliers products.
Class to manage customers orders.
Class to manage contact/addresses.
API class for receive files.
post($filename, $modulepart, $ref='', $subdir='', $filecontent='', $fileencoding='', $overwriteifexists=0, $createdirifnotexists=1, $position=0, $cover='', $array_options=[], $generateThumbs=0, $share=0)
Return a document.
__construct()
Constructor.
getDocumentsListByElement($modulepart, $id=0, $ref='', $sortfield='', $sortorder='', $limit=100, $page=0, $content_type='', $pagination_data=false)
List all documents of an element.
index($modulepart, $original_file='')
Download a given document.
builddoc($modulepart, $original_file='', $doctemplate='', $langcode='')
Build a document.
Class for API REST v1.
Definition api.class.php:35
Class to manage ECM files.
Class to manage warehouses.
Class to manage Trips and Expenses.
Class to manage suppliers invoices.
Class to manage invoices.
Class of the module paid holiday.
Class for KnowledgeRecord.
Class for Mo.
Definition mo.class.php:35
Class to manage products or services.
Class to manage projects.
Class to manage proposals.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage tasks.
Class to manage translations.
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
dol_move($srcfile, $destfile, $newmask='0', $overwriteifexists=1, $testvirus=0, $indexdatabase=1, $moreinfo=array(), $entity=null)
Move a file into another name.
dol_basename($pathfile)
Make a basename working with all page code (default PHP basenamed fails with cyrillic).
Definition files.lib.php:40
dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $object=null, $allowdotdot=false, $indexdatabase=1, $nolog=0)
Remove a file or several files with a mask.
dol_check_secure_access_document($modulepart, $original_file, $entity, $fuser=null, $refname='', $mode='read')
Security check when accessing to a document (used by document.php, viewimage.php and webservices to g...
dol_is_file($pathoffile)
Return if path is a file.
dolCheckVirus($src_file, $dest_file='')
Check virus into a file.
dol_dir_list($utf8_path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0, $nbsecondsold=0)
Scan a directory and return a list of files/directories.
Definition files.lib.php:65
dol_is_dir($folder)
Test if filename is a directory.
dol_mimetype($file, $default='application/octet-stream', $mode=0)
Return MIME type of a file from its name with extension.
dol_osencode($str)
Return a string encoded into OS filesystem encoding.
dol_sanitizePathName($str, $newstr='_', $unaccent=0, $allowdash=0)
Clean a string to use it as a path name.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0, $allowdash=0)
Clean a string to use it as a file name.
dolChmod($filepath, $newmask='')
Change mod of a file.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
getMultidirOutput($object, $module='', $forobject=0, $mode='output')
Return the full path of the directory where a module (or an object of a module) stores its files.
getUserRemoteIP($trusted=0)
Return the real IP of remote user.
isAFileWithExecutableContent($filename)
Return if a file can contains executable content.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
get_exdir($num, $level, $alpha, $withoutslash, $object, $modulepart='')
Return a path to have a the directory according to object where files are stored.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
image_format_supported($file, $acceptsvg=0)
Return if a filename is file name of a supported image format.
Class to generate the form for creating a new ticket.
getRandomPassword($generic=false, $replaceambiguouschars=null, $length=32)
Return a generated password using default module.
checkUserAccessToObject($user, array $featuresarray, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='', $dbt_select='rowid', $parenttableforentity='')
Check that access by a given user to an object is ok.