dolibarr 24.0.1
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 // Define $object
476 $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
477 if (!is_object($object)) {
478 throw new RestException(404, 'Module for modulepart = '.$modulepart." is not enabled (or not yet supported by API");
479 }
480
481 // Define $upload_dir to scan
482 $upload_dir = getMultidirOutput($object, '', 1);
483
484 // Check object-level permissions
485 $ok = checkUserAccessToObject(DolibarrApiAccess::$user, array($object->element), $object, $object->table_element, '');
486 if (empty($ok)) {
487 throw new RestException(403, 'Access not allowed to this object (refused by checkUserAccessToObject)');
488 }
489
490 // Check permission on module
491 if ($modulepart == 'societe' || $modulepart == 'thirdparty') {
492 if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
493 throw new RestException(403);
494 }
495 } elseif ($modulepart == 'user') {
496 // Can get doc if has permission to read all user or if it is user itself
497 if (!DolibarrApiAccess::$user->hasRight('user', 'user', 'lire') && DolibarrApiAccess::$user->id != $id) {
498 throw new RestException(403);
499 }
500 } elseif ($modulepart == 'adherent' || $modulepart == 'member') {
501 if (!DolibarrApiAccess::$user->hasRight('adherent', 'lire')) {
502 throw new RestException(403);
503 }
504 } elseif ($modulepart == 'propal' || $modulepart == 'proposal') {
505 if (!DolibarrApiAccess::$user->hasRight('propal', 'lire')) {
506 throw new RestException(403);
507 }
508 } elseif ($modulepart == 'supplier_proposal') {
509 if (!DolibarrApiAccess::$user->hasRight('supplier_proposal', 'read')) {
510 throw new RestException(403);
511 }
512 } elseif ($modulepart == 'commande' || $modulepart == 'order') {
513 if (!DolibarrApiAccess::$user->hasRight('commande', 'lire')) {
514 throw new RestException(403);
515 }
516 } elseif ($modulepart == 'commande_fournisseur' || $modulepart == 'supplier_order') {
517 $modulepart = 'supplier_order';
518 if (!DolibarrApiAccess::$user->hasRight('fournisseur', 'commande', 'lire') && !DolibarrApiAccess::$user->hasRight('supplier_order', 'lire')) {
519 throw new RestException(403);
520 }
521 } elseif ($modulepart == 'shipment' || $modulepart == 'expedition') {
522 if (!DolibarrApiAccess::$user->hasRight('expedition', 'lire')) {
523 throw new RestException(403);
524 }
525 } elseif ($modulepart == 'facture' || $modulepart == 'invoice') {
526 if (!DolibarrApiAccess::$user->hasRight('facture', 'lire')) {
527 throw new RestException(403);
528 }
529 } elseif ($modulepart == 'facture_fournisseur' || $modulepart == 'supplier_invoice') {
530 $modulepart = 'supplier_invoice';
531 if (!DolibarrApiAccess::$user->hasRight('fournisseur', 'facture', 'lire') && !DolibarrApiAccess::$user->hasRight('supplier_invoice', 'lire')) {
532 throw new RestException(403);
533 }
534 } elseif ($modulepart == 'produit' || $modulepart == 'product' || $modulepart == 'service') {
535 if (!DolibarrApiAccess::$user->hasRight('produit', 'lire')) {
536 throw new RestException(403);
537 }
538 } elseif ($modulepart == 'agenda' || $modulepart == 'action' || $modulepart == 'event' || $modulepart == 'actioncomm') {
539 if (!DolibarrApiAccess::$user->hasRight('agenda', 'myactions', 'read') && !DolibarrApiAccess::$user->hasRight('agenda', 'allactions', 'read')) {
540 throw new RestException(403);
541 }
542 } elseif ($modulepart == 'expensereport') {
543 if (!DolibarrApiAccess::$user->hasRight('expensereport', 'read')) {
544 throw new RestException(403);
545 }
546 } elseif ($modulepart == 'holiday') {
547 if (!DolibarrApiAccess::$user->hasRight('holiday', 'read')) {
548 throw new RestException(403);
549 }
550 } elseif ($modulepart == 'ticket') {
551 if (!DolibarrApiAccess::$user->hasRight('ticket', 'read')) {
552 throw new RestException(403);
553 }
554 } elseif ($modulepart == 'knowledgemanagement') {
555 if (!DolibarrApiAccess::$user->hasRight('knowledgemanagement', 'knowledgerecord', 'read')) {
556 throw new RestException(403);
557 }
558 } elseif ($modulepart == 'categorie' || $modulepart == 'category') {
559 if (!DolibarrApiAccess::$user->hasRight('categorie', 'lire')) {
560 throw new RestException(403);
561 }
562 } elseif ($modulepart == 'ecm') {
563 throw new RestException(500, 'Modulepart Ecm not implemented yet.');
564 // if (!DolibarrApiAccess::$user->hasRight('ecm', 'read')) {
565 // throw new RestException(403);
566 // }
567 } elseif ($modulepart == 'contrat' || $modulepart == 'contract') {
568 $modulepart = 'contrat';
569 if (!DolibarrApiAccess::$user->hasRight('contrat', 'lire')) {
570 throw new RestException(403);
571 }
572 } elseif ($modulepart == 'intervention' || $modulepart == 'ficheinter') {
573 $modulepart = 'ficheinter';
574 if (!DolibarrApiAccess::$user->hasRight('ficheinter', 'lire')) {
575 throw new RestException(403);
576 }
577 } elseif ($modulepart == 'projet' || $modulepart == 'project') {
578 $modulepart = 'project';
579 if (!DolibarrApiAccess::$user->hasRight('projet', 'lire')) {
580 throw new RestException(403);
581 }
582 } elseif ($modulepart == 'task' || $modulepart == 'project_task') {
583 $modulepart = 'project_task';
584 if (!DolibarrApiAccess::$user->hasRight('projet', 'lire')) {
585 throw new RestException(403);
586 }
587 } elseif ($modulepart == 'mrp') {
588 $modulepart = 'mrp';
589 if (!DolibarrApiAccess::$user->hasRight('mrp', 'read')) {
590 throw new RestException(403);
591 }
592 } elseif ($modulepart == 'contact' || $modulepart == 'socpeople') {
593 $modulepart = 'contact';
594 if (!DolibarrApiAccess::$user->hasRight('societe', 'contact', 'lire')) {
595 throw new RestException(403);
596 }
597 } elseif ($modulepart == 'stock') {
598 if (!DolibarrApiAccess::$user->hasRight('stock', 'lire')) {
599 throw new RestException(403);
600 }
601 } else {
602 throw new RestException(500, 'Modulepart '.$modulepart.' not implemented yet.');
603 }
604
605 // Scan files into directory
606 $recursive = 0;
607 $type = 'files';
608
609 $objectType = $modulepart;
610 if (! empty($object->id) && ! empty($object->table_element)) {
611 $objectType = $object->table_element;
612 }
613
614 $filearray = dol_dir_list($upload_dir, $type, $recursive, '', '(\.meta|_preview.*\.png)$', $sortfield, (strtolower($sortorder) == 'desc' ? SORT_DESC : SORT_ASC), 1);
615
616 $countarray = is_array($filearray) ? count($filearray) : 0;
617
618 if (empty($filearray)) {
619 throw new RestException(404, 'Search for modulepart '.$modulepart.' with Id '.$id.(!empty($ref) ? ' or Ref '.$ref : '').' does not return any document.');
620 } else {
621 $filearray = array_slice($filearray, $limit * $page, $limit);
622 if (($object->id) > 0 && !empty($modulepart)) {
623 require_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php';
624 $ecmfile = new EcmFiles($this->db);
625 $result = $ecmfile->fetchAll('', '', 0, 0, array('t.src_object_type' => $objectType, 't.src_object_id' => $object->id));
626 if ($result < 0) {
627 throw new RestException(503, 'Error when retrieve ecm list : '.$this->db->lasterror());
628 } elseif (is_array($ecmfile->lines) && count($ecmfile->lines) > 0) {
629 foreach ($filearray as &$fileitem) {
630 foreach ($ecmfile->lines as $line) {
631 if ($fileitem['name'] == $line->filename) {
632 // Next line converts EcmFilesLine properties to array
633 //$fileitem = array_merge($fileitem, (array) $line);
634 $fileitem['ref'] = $line->ref;
635 $fileitem['label'] = $line->label;
636 $fileitem['filepath'] = $line->filepath;
637 $fileitem['filename'] = $line->filename;
638 $fileitem['fullpath_orig'] = $line->fullpath_orig;
639 $fileitem['position'] = $line->position;
640 $fileitem['gen_or_uploaded'] = $line->gen_or_uploaded;
641 $fileitem['description'] = $line->desc;
642 $fileitem['keywords'] = $line->keywords;
643 $fileitem['cover'] = $line->cover;
644 $fileitem['share'] = $line->share;
645 $fileitem['date_c'] = $line->date_c;
646 $fileitem['agenda_id'] = $line->agenda_id;
647 $fileitem['fk_user_c'] = $line->fk_user_c;
648 $fileitem['fk_user_m'] = $line->fk_user_m;
649 $fileitem['note_private'] = $line->note_private;
650 $fileitem['note_public'] = $line->note_public;
651 }
652 }
653 if (isset($fileitem['relativename'])) {
654 $fileitem['content-type'] = dol_mimetype((string) $fileitem['relativename']);
655 }
656 }
657
658 // Select only files that match the requested $content_type, if provided
659 $arraycontenttype = explode(",", $content_type);
660 if (!empty($content_type)) {
661 $filearray = array_filter(
662 $filearray,
667 static function ($fileitem) use (&$arraycontenttype) {
668 return in_array(($fileitem['content-type'] ?: 'UNKNOWN'), $arraycontenttype);
669 }
670 );
671 }
672 }
673 }
674 }
675
676 // Clean result from fullname
677 foreach ($filearray as $tmpkey => $tmpval) {
678 unset($filearray[$tmpkey]['path']);
679 unset($filearray[$tmpkey]['fullname']);
680 }
681
682 //if $pagination_data is true the response will contain element data with all values and element pagination with pagination data(total,page,limit)
683 if ($pagination_data) {
684 $filearray = [
685 'data' => $filearray,
686 'pagination' => [
687 'total' => (int) $countarray,
688 'page' => $page, // count starts from 0
689 'page_count' => (int) ceil((int) $countarray / $limit),
690 'limit' => $limit
691 ]
692 ];
693 }
694
695 return $filearray;
696 }
697
698
707 /*
708 public function get($id) {
709 return array('note'=>'xxx');
710 }*/
711
712
749 public function post($filename, $modulepart, $ref = '', $subdir = '', $filecontent = '', $fileencoding = '', $overwriteifexists = 0, $createdirifnotexists = 1, $position = 0, $cover = '', $array_options = [], $generateThumbs = 0, $share = 0)
750 {
751 global $conf;
752
753 $modulepartorig = $modulepart;
754
755 if (empty($modulepart)) {
756 throw new RestException(400, 'Modulepart not provided.');
757 }
758
759 $newfilecontent = '';
760 if (empty($fileencoding)) {
761 $newfilecontent = $filecontent;
762 }
763 if ($fileencoding == 'base64') {
764 $newfilecontent = base64_decode($filecontent);
765 }
766
767 $original_file = dol_sanitizeFileName($filename);
768 $relativefile = 'UNSET';
769
770 // Define $uploadir
771 $object = null;
772 $entity = DolibarrApiAccess::$user->entity;
773 if (empty($entity)) {
774 $entity = 1;
775 }
776
777 if ($ref) {
778 $tmpreldir = '';
779 $fetchbyid = false;
780
781 if ($modulepart == 'facture' || $modulepart == 'invoice') {
782 $modulepart = 'facture';
783
784 require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
785 $object = new Facture($this->db);
786 } elseif ($modulepart == 'facture_fournisseur' || $modulepart == 'supplier_invoice') {
787 $modulepart = 'supplier_invoice';
788
789 require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
790 $object = new FactureFournisseur($this->db);
791 } elseif ($modulepart == 'commande' || $modulepart == 'order') {
792 $modulepart = 'commande';
793
794 require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
795 $object = new Commande($this->db);
796 } elseif ($modulepart == 'commande_fournisseur' || $modulepart == 'supplier_order') {
797 $modulepart = 'supplier_order';
798
799 require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
800 $object = new CommandeFournisseur($this->db);
801 } elseif ($modulepart == 'projet' || $modulepart == 'project') {
802 require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
803 $object = new Project($this->db);
804 } elseif ($modulepart == 'task' || $modulepart == 'project_task') {
805 $modulepart = 'project_task';
806
807 require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
808 $object = new Task($this->db);
809
810 $task_result = $object->fetch(0, $ref);
811
812 // Fetching the tasks project is required because its out_dir might be a sub-directory of the project
813 if ($task_result > 0) {
814 $project_result = $object->fetchProject();
815
816 if ($project_result >= 0) {
817 $tmpreldir = dol_sanitizeFileName((string) $object->project->ref).'/';
818 }
819 } else {
820 throw new RestException(500, 'Error while fetching Task '.$ref);
821 }
822 } elseif ($modulepart == 'product' || $modulepart == 'produit' || $modulepart == 'service' || $modulepart == 'produit|service') {
823 require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
824 $object = new Product($this->db);
825 } elseif ($modulepart == 'expensereport') {
826 require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
827 $object = new ExpenseReport($this->db);
828 } elseif ($modulepart == 'holiday') {
829 require_once DOL_DOCUMENT_ROOT.'/holiday/class/holiday.class.php';
830 $object = new Holiday($this->db);
831 } elseif ($modulepart == 'ficheinter' || $modulepart == 'intervention') {
832 require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinter.class.php';
833 $object = new Fichinter($this->db);
834 } elseif ($modulepart == 'shipment' || $modulepart == 'expedition') {
835 require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php';
836 $object = new Expedition($this->db);
837 } elseif ($modulepart == 'adherent' || $modulepart == 'member') {
838 $modulepart = 'adherent';
839 require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
840 $object = new Adherent($this->db);
841 } elseif ($modulepart == 'proposal' || $modulepart == 'propal' || $modulepart == 'propale') {
842 $modulepart = 'propale';
843 require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
844 $object = new Propal($this->db);
845 } elseif ($modulepart == 'agenda' || $modulepart == 'action' || $modulepart == 'event') {
846 $modulepart = 'agenda';
847 require_once DOL_DOCUMENT_ROOT . '/comm/action/class/actioncomm.class.php';
848 $object = new ActionComm($this->db);
849 } elseif ($modulepart == 'contact' || $modulepart == 'socpeople') {
850 $modulepart = 'contact';
851 require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
852 $object = new Contact($this->db);
853 $fetchbyid = true;
854 } elseif ($modulepart == 'societe' || $modulepart == 'company') {
855 $modulepart = 'societe';
856 require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
857 $object = new Societe($this->db);
858 $fetchbyid = true;
859 } elseif ($modulepart == 'knowledgemanagement') {
860 $modulepart = 'knowledgemanagement';
861 require_once DOL_DOCUMENT_ROOT.'/knowledgemanagement/class/knowledgerecord.class.php';
862 $object = new KnowledgeRecord($this->db);
863 $fetchbyid = true;
864 } elseif ($modulepart == 'ticket') {
865 $modulepart = 'ticket';
866 require_once DOL_DOCUMENT_ROOT.'/ticket/class/ticket.class.php';
867 $object = new Ticket($this->db);
868 $fetchbyid = true;
869 } elseif ($modulepart == 'contrat' || $modulepart == 'contract') {
870 $modulepart = 'contrat';
871 require_once DOL_DOCUMENT_ROOT . '/contrat/class/contrat.class.php';
872 $object = new Contrat($this->db);
873 } elseif ($modulepart == 'mrp') {
874 $modulepart = 'mrp';
875 require_once DOL_DOCUMENT_ROOT . '/mrp/class/mo.class.php';
876 $object = new Mo($this->db);
877 } elseif ($modulepart == 'stock') {
878 $modulepart = 'stock';
879 require_once DOL_DOCUMENT_ROOT . '/product/stock/class/entrepot.class.php';
880 $object = new Entrepot($this->db);
881 } elseif ($modulepart == 'ecm') {
882 throw new RestException(500, 'Using a non empty "ref" is not compatible with using modulepart = '.$modulepart);
883 } else {
884 // TODO Implement additional moduleparts
885 throw new RestException(500, 'Modulepart '.$modulepart.' not implemented yet.');
886 }
887
888 // at this step $object is always an object
889 if ($fetchbyid) {
890 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
891 $result = $object->fetch((int) $ref);
892 } else {
893 $result = $object->fetch(0, $ref);
894 }
895
896 if ($result == 0) {
897 throw new RestException(404, "Object with ref '".$ref."' was not found.");
898 } elseif ($result < 0) {
899 throw new RestException(500, 'Error while fetching object: '.$object->error);
900 }
901
902 if (!($object->id > 0)) {
903 throw new RestException(404, 'The object '.$modulepart." with ref '".$ref."' was not found.");
904 }
905
906 // Special cases that need to use get_exdir to get real dir of object
907 // In future, all object should use this to define path of documents.
908 if ($modulepart == 'supplier_invoice') {
909 $tmpreldir = get_exdir($object->id, 2, 0, 0, $object, 'invoice_supplier');
910 }
911
912 // Test on permissions
913 //if ($modulepart != 'ecm') { // Here $modulepart is always != 'ecm'
914 if ($modulepart == 'societe') {
915 $relativefile = $tmpreldir.dol_sanitizeFileName((string) $object->id);
916 } else {
917 $relativefile = $tmpreldir.dol_sanitizeFileName((string) $object->ref);
918 }
919 $tmp = dol_check_secure_access_document($modulepart, $relativefile, $entity, DolibarrApiAccess::$user, $ref, 'write');
920 if (empty($tmp['accessallowed'])) {
921 throw new RestException(403, 'Access not allowed to upload file into this directory');
922 }
923 $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
924 /*} else {
925 if (!DolibarrApiAccess::$user->hasRight('ecm', 'upload')) {
926 throw new RestException(403, 'Missing permission to upload files in ECM module');
927 }
928 $upload_dir = $conf->medias->multidir_output[$conf->entity];
929 }*/
930
931 if (empty($upload_dir) || $upload_dir == '/') {
932 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.');
933 }
934 } else {
935 if ($modulepart == 'invoice') {
936 $modulepart = 'facture';
937 }
938 if ($modulepart == 'member') {
939 $modulepart = 'adherent';
940 }
941
942 // Test on permissions
943 if ($modulepart != 'ecm') {
944 $relativefile = $subdir;
945 $tmp = dol_check_secure_access_document($modulepart, $relativefile, $entity, DolibarrApiAccess::$user, '', 'write');
946 if (empty($tmp['accessallowed'])) {
947 throw new RestException(403, 'Access not allowed to upload file into this directory');
948 }
949 $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
950 } else {
951 if (!DolibarrApiAccess::$user->hasRight('ecm', 'upload')) {
952 throw new RestException(403, 'Missing permission to upload files in ECM module');
953 }
954 $upload_dir = $conf->medias->multidir_output[$conf->entity];
955 }
956
957 if (empty($upload_dir) || $upload_dir == '/') {
958 if (!empty($tmp['error'])) {
959 throw new RestException(403, 'Error returned by dol_check_secure_access_document: '.$tmp['error']);
960 } else {
961 throw new RestException(400, 'This value of modulepart ('.$modulepart.') is not allowed with this value of subdir ('.$relativefile.')');
962 }
963 }
964 }
965 // $original_file here is still value of filename without any dir.
966
967 $upload_dir = dol_sanitizePathName($upload_dir);
968
969 if (!empty($createdirifnotexists)) {
970 if (dol_mkdir($upload_dir) < 0) { // needed by products
971 throw new RestException(500, 'Error while trying to create directory '.$upload_dir);
972 }
973 }
974
975 $destfile = $upload_dir.'/'.$original_file;
976 $destfiletmp = DOL_DATA_ROOT.'/admin/temp/'.$original_file;
977 dol_delete_file($destfiletmp);
978 //var_dump($original_file);exit;
979
980 if (!dol_is_dir(dirname($destfile))) {
981 throw new RestException(400, 'Directory does not exists : '.dirname($destfile));
982 }
983
984 if (!$overwriteifexists && dol_is_file($destfile)) {
985 throw new RestException(400, "File with name '".$original_file."' already exists.");
986 }
987
988 // in case temporary directory admin/temp doesn't exist
989 if (!dol_is_dir(dirname($destfiletmp))) {
990 dol_mkdir(dirname($destfiletmp));
991 }
992
993 $fhandle = @fopen($destfiletmp, 'w');
994 if ($fhandle) {
995 $nbofbyteswrote = fwrite($fhandle, $newfilecontent);
996 fclose($fhandle);
997 dolChmod($destfiletmp);
998 } else {
999 throw new RestException(500, "Failed to open file '".$destfiletmp."' for write");
1000 }
1001
1002 $disablevirusscan = 0;
1003 $src_file = $destfiletmp;
1004 $dest_file = $destfile;
1005
1006 // Security:
1007 // If we need to make a virus scan
1008 if (empty($disablevirusscan) && file_exists($src_file)) {
1009 $checkvirusarray = dolCheckVirus($src_file, $dest_file);
1010 if (count($checkvirusarray)) {
1011 dol_syslog('Files.lib::dol_move_uploaded_file File "'.$src_file.'" (target name "'.$dest_file.'") KO with antivirus: errors='.implode(',', $checkvirusarray), LOG_WARNING);
1012 throw new RestException(500, 'ErrorFileIsInfectedWithAVirus: '.implode(',', $checkvirusarray));
1013 }
1014 }
1015
1016 // Security:
1017 // Disallow file with some extensions. We rename them.
1018 // Because if we put the documents directory into a directory inside web root (very bad), this allows to execute on demand arbitrary code.
1019 if (isAFileWithExecutableContent($dest_file) && !getDolGlobalString('MAIN_DOCUMENT_IS_OUTSIDE_WEBROOT_SO_NOEXE_NOT_REQUIRED')) {
1020 // $upload_dir ends with a slash, so be must be sure the medias dir to compare to ends with slash too.
1021 $publicmediasdirwithslash = $conf->medias->multidir_output[$conf->entity];
1022 if (!preg_match('/\/$/', $publicmediasdirwithslash)) {
1023 $publicmediasdirwithslash .= '/';
1024 }
1025
1026 if (strpos($upload_dir, $publicmediasdirwithslash) !== 0 || !getDolGlobalInt("MAIN_DOCUMENT_DISABLE_NOEXE_IN_MEDIAS_DIR")) { // We never add .noexe on files into media directory
1027 $dest_file .= '.noexe';
1028 }
1029 }
1030
1031 // Security:
1032 // We refuse cache files/dirs, upload using .. and pipes into filenames.
1033 if (preg_match('/^\./', basename($src_file)) || preg_match('/\.\./', $src_file) || preg_match('/[<>|]/', $src_file)) {
1034 dol_syslog("Refused to deliver file ".$src_file, LOG_WARNING);
1035 throw new RestException(500, "Refused to deliver file ".$src_file);
1036 }
1037
1038 // Security:
1039 // We refuse cache files/dirs, upload using .. and pipes into filenames.
1040 if (preg_match('/^\./', basename($dest_file)) || preg_match('/\.\./', $dest_file) || preg_match('/[<>|]/', $dest_file)) {
1041 dol_syslog("Refused to deliver file ".$dest_file, LOG_WARNING);
1042 throw new RestException(500, "Refused to deliver file ".$dest_file);
1043 }
1044
1045 $moreinfo = array('note_private' => 'File uploaded using API /documents from IP '.getUserRemoteIP());
1046 // $object may be null
1047 if (is_object($object) && $object->id > 0) {
1048 $moreinfo['src_object_type'] = $object->table_element;
1049 $moreinfo['src_object_id'] = $object->id;
1050 }
1051 if (!empty($array_options)) {
1052 $moreinfo = array_merge($moreinfo, ["array_options" => $array_options]);
1053 }
1054 if (!empty($position)) {
1055 $moreinfo = array_merge($moreinfo, ["position" => $position]);
1056 }
1057 if (!empty($cover)) {
1058 $moreinfo = array_merge($moreinfo, ["cover" => $cover]);
1059 }
1060 if (!empty($share)) {
1061 require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
1062 $moreinfo = array_merge($moreinfo, ["share" => getRandomPassword(true)]);
1063 }
1064 $moreinfo['gen_or_uploaded'] = 'api';
1065
1066 // Move the temporary file at its final emplacement
1067 $result = dol_move($destfiletmp, $dest_file, '0', $overwriteifexists, 1, 1, $moreinfo);
1068 if (!$result) {
1069 throw new RestException(500, "Failed to move file into '".$dest_file."'");
1070 }
1071
1072 if (is_object($object) && $generateThumbs) {
1073 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
1074 require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php'; // image_format_supported() is defined here
1075 if (image_format_supported($dest_file)) {
1076 $object->addThumbs($dest_file);
1077 }
1078 }
1079
1080 return dol_basename($destfile);
1081 }
1082
1102 public function delete($modulepart, $original_file)
1103 {
1104 global $conf;
1105
1106 if (empty($modulepart)) {
1107 throw new RestException(400, 'bad value for parameter modulepart');
1108 }
1109 if (empty($original_file)) {
1110 throw new RestException(400, 'bad value for parameter original_file');
1111 }
1112
1113 // Normalize modulepart for project_task
1114 if ($modulepart == 'task') {
1115 $modulepart = 'project_task';
1116 }
1117
1118 //--- Finds and returns the document
1119 $entity = $conf->entity;
1120
1121 // Special cases that need to use get_exdir to get real dir of object
1122 // If future, all object should use this to define path of documents.
1123 /*
1124 $tmpreldir = '';
1125 if ($modulepart == 'supplier_invoice') {
1126 $tmpreldir = get_exdir($object->id, 2, 0, 0, $object, 'invoice_supplier');
1127 }
1128
1129 $relativefile = $tmpreldir.dol_sanitizeFileName($object->ref); */
1130 $relativefile = $original_file;
1131
1132 $check_access = dol_check_secure_access_document($modulepart, $relativefile, $entity, DolibarrApiAccess::$user, '', 'write');
1133 $accessallowed = $check_access['accessallowed'];
1134 $sqlprotectagainstexternals = $check_access['sqlprotectagainstexternals'];
1135 $original_file = $check_access['original_file'];
1136
1137 if (preg_match('/\.\./', $original_file) || preg_match('/[<>|]/', $original_file)) {
1138 throw new RestException(403);
1139 }
1140 if (!$accessallowed) {
1141 throw new RestException(403);
1142 }
1143
1144 if (DolibarrApiAccess::$user->socid > 0) {
1145 if ($sqlprotectagainstexternals) {
1146 $resql = $this->db->query($sqlprotectagainstexternals);
1147 if ($resql) {
1148 $num = $this->db->num_rows($resql);
1149 $i = 0;
1150 while ($i < $num) {
1151 $obj = $this->db->fetch_object($resql);
1152 if (DolibarrApiAccess::$user->socid != $obj->fk_soc) {
1153 throw new RestException(403, 'Not allowed to download documents with such a ref');
1154 }
1155 $i++;
1156 }
1157 }
1158 }
1159 }
1160
1161 $filename = basename($original_file);
1162 $original_file_osencoded = dol_osencode($original_file); // New file name encoded in OS encoding charset
1163
1164 if (!file_exists($original_file_osencoded)) {
1165 dol_syslog("Try to download not found file ".$original_file_osencoded, LOG_WARNING);
1166 throw new RestException(404, 'File not found');
1167 }
1168
1169 if (@unlink($original_file_osencoded)) {
1170 return array(
1171 'success' => array(
1172 'code' => 200,
1173 'message' => 'Document deleted'
1174 )
1175 );
1176 }
1177
1178 throw new RestException(403);
1179 }
1180}
$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:
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $db
API class for accounts.
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:39
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:64
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.