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