dolibarr 23.0.3
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 MDW <mdeweerd@users.noreply.github.com>
9 * Copyright (C) 2025 William Mead <william@m34d.com>
10 * Copyright (C) 2025 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 == 'product') {
356 require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
357
358 $tmpobject = new Product($this->db);
359 $result = $tmpobject->fetch(0, preg_replace('/\.[^\.]+$/', '', basename($original_file)));
360
361 if (!$result) {
362 throw new RestException(404, 'Product 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 == 'stock' || $modulepart == 'entrepot') {
372 require_once DOL_DOCUMENT_ROOT . '/product/stock/class/entrepot.class.php';
373
374 $tmpobject = new Entrepot($this->db);
375 $result = $tmpobject->fetch(0, preg_replace('/\.[^\.]+$/', '', basename($original_file)));
376
377 if (!$result) {
378 throw new RestException(404, 'Warehouse 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 == 'fichinter' || $modulepart == 'intervention') {
388 require_once DOL_DOCUMENT_ROOT . '/fichinter/class/fichinter.class.php';
389
390 $tmpobject = new Fichinter($this->db);
391 $result = $tmpobject->fetch(0, preg_replace('/\.[^\.]+$/', '', basename($original_file)));
392
393 if (!$result) {
394 throw new RestException(404, 'Intervention 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 } else {
404 throw new RestException(403, 'Generation not available for this modulepart');
405 }
406
407 $filename = basename($original_file);
408 $original_file_osencoded = dol_osencode($original_file); // New file name encoded in OS encoding charset
409
410 if (!file_exists($original_file_osencoded)) {
411 throw new RestException(404, 'File not found');
412 }
413
414 $file_content = file_get_contents($original_file_osencoded);
415 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');
416 }
417
447 public function getDocumentsListByElement($modulepart, $id = 0, $ref = '', $sortfield = '', $sortorder = '', $limit = 100, $page = 0, $content_type = '', $pagination_data = false)
448 {
449 global $conf;
452 if (empty($modulepart)) {
453 throw new RestException(400, 'bad value for parameter modulepart');
454 }
455
456 if (empty($id) && empty($ref)) {
457 throw new RestException(400, 'bad value for parameter id or ref');
458 }
459
460 $id = (empty($id) ? 0 : $id);
461 $recursive = 0;
462 $type = 'files';
463
464 if ($modulepart == 'societe' || $modulepart == 'thirdparty') {
465 require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
466
467 if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
468 throw new RestException(403);
469 }
470
471 $object = new Societe($this->db);
472 $result = $object->fetch($id, $ref);
473 if (!$result) {
474 throw new RestException(404, 'Thirdparty not found');
475 }
476
477 $upload_dir = $conf->societe->multidir_output[$object->entity ?? $conf->entity]."/".$object->id;
478 } elseif ($modulepart == 'user') {
479 require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
480
481 // Can get doc if has permission to read all user or if it is user itself
482 if (!DolibarrApiAccess::$user->hasRight('user', 'user', 'lire') && DolibarrApiAccess::$user->id != $id) {
483 throw new RestException(403);
484 }
485
486 $object = new User($this->db);
487 $result = $object->fetch($id, $ref);
488 if (!$result) {
489 throw new RestException(404, 'User not found');
490 }
491
492 $upload_dir = getMultidirOutput($object) . '/'.get_exdir(0, 0, 0, 0, $object, 'user').'/'.$object->id;
493 } elseif ($modulepart == 'adherent' || $modulepart == 'member') {
494 require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
495
496 if (!DolibarrApiAccess::$user->hasRight('adherent', 'lire')) {
497 throw new RestException(403);
498 }
499
500 $object = new Adherent($this->db);
501 $result = $object->fetch($id, $ref);
502 if (!$result) {
503 throw new RestException(404, 'Member not found');
504 }
505
506 $upload_dir = getMultidirOutput($object) . "/".get_exdir(0, 0, 0, 1, $object, 'member');
507 } elseif ($modulepart == 'propal' || $modulepart == 'proposal') {
508 require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
509
510 if (!DolibarrApiAccess::$user->hasRight('propal', 'lire')) {
511 throw new RestException(403);
512 }
513
514 $object = new Propal($this->db);
515 $result = $object->fetch($id, $ref);
516 if (!$result) {
517 throw new RestException(404, 'Proposal not found');
518 }
519
520 $upload_dir = $conf->propal->multidir_output[$object->entity ?? $conf->entity]."/".get_exdir(0, 0, 0, 1, $object, 'propal');
521 } elseif ($modulepart == 'supplier_proposal') {
522 require_once DOL_DOCUMENT_ROOT.'/supplier_proposal/class/supplier_proposal.class.php';
523
524 if (!DolibarrApiAccess::$user->hasRight('supplier_proposal', 'read')) {
525 throw new RestException(403);
526 }
527
528 $object = new Propal($this->db);
529 $result = $object->fetch($id, $ref);
530 if (!$result) {
531 throw new RestException(404, 'Supplier proposal not found');
532 }
533
534 $upload_dir = $conf->propal->multidir_output[$object->entity ?? $conf->entity]."/".get_exdir(0, 0, 0, 1, $object, 'propal');
535 } elseif ($modulepart == 'commande' || $modulepart == 'order') {
536 require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
537
538 if (!DolibarrApiAccess::$user->hasRight('commande', 'lire')) {
539 throw new RestException(403);
540 }
541
542 $object = new Commande($this->db);
543 $result = $object->fetch($id, $ref);
544 if (!$result) {
545 throw new RestException(404, 'Order not found');
546 }
547
548 $upload_dir = getMultidirOutput($object). "/".get_exdir(0, 0, 0, 1, $object, 'commande');
549 } elseif ($modulepart == 'commande_fournisseur' || $modulepart == 'supplier_order') {
550 $modulepart = 'supplier_order';
551
552 require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
553
554 if (!DolibarrApiAccess::$user->hasRight('fournisseur', 'commande', 'lire') && !DolibarrApiAccess::$user->hasRight('supplier_order', 'lire')) {
555 throw new RestException(403);
556 }
557
558 $object = new CommandeFournisseur($this->db);
559 $result = $object->fetch($id, $ref);
560 if (!$result) {
561 throw new RestException(404, 'Purchase order not found');
562 }
563
564 $upload_dir = getMultidirOutput($object) . "/commande/".dol_sanitizeFileName($object->ref);
565 } elseif ($modulepart == 'shipment' || $modulepart == 'expedition') {
566 require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php';
567
568 if (!DolibarrApiAccess::$user->hasRight('expedition', 'lire')) {
569 throw new RestException(403);
570 }
571
572 $object = new Expedition($this->db);
573 $result = $object->fetch($id, $ref);
574 if (!$result) {
575 throw new RestException(404, 'Shipment not found');
576 }
577
578 $upload_dir = getMultidirOutput($object) . "/sending/".get_exdir(0, 0, 0, 1, $object, 'shipment');
579 } elseif ($modulepart == 'facture' || $modulepart == 'invoice') {
580 require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
581
582 if (!DolibarrApiAccess::$user->hasRight('facture', 'lire')) {
583 throw new RestException(403);
584 }
585
586 $object = new Facture($this->db);
587 $result = $object->fetch($id, $ref);
588 if (!$result) {
589 throw new RestException(404, 'Invoice not found');
590 }
591
592 $upload_dir = getMultidirOutput($object) . "/".get_exdir(0, 0, 0, 1, $object, 'invoice');
593 } elseif ($modulepart == 'facture_fournisseur' || $modulepart == 'supplier_invoice') {
594 $modulepart = 'supplier_invoice';
595
596 require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
597
598 if (!DolibarrApiAccess::$user->hasRight('fournisseur', 'facture', 'lire') && !DolibarrApiAccess::$user->hasRight('supplier_invoice', 'lire')) {
599 throw new RestException(403);
600 }
601
602 $object = new FactureFournisseur($this->db);
603 $result = $object->fetch($id, $ref);
604 if (!$result) {
605 throw new RestException(404, 'Invoice not found');
606 }
607
608 $upload_dir = getMultidirOutput($object) . "/".get_exdir($object->id, 2, 0, 0, $object, 'invoice_supplier').dol_sanitizeFileName($object->ref);
609 } elseif ($modulepart == 'produit' || $modulepart == 'product' || $modulepart == 'service') {
610 require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
611
612 if (!DolibarrApiAccess::$user->hasRight('produit', 'lire')) {
613 throw new RestException(403);
614 }
615
616 $object = new Product($this->db);
617 $result = $object->fetch($id, $ref);
618 if ($result == 0) {
619 throw new RestException(404, 'Product not found');
620 } elseif ($result < 0) {
621 throw new RestException(500, 'Error while fetching object: '.$object->error);
622 }
623
624 $upload_dir = getMultidirOutput($object) . '/'.dol_sanitizeFileName($object->ref);
625 } elseif ($modulepart == 'agenda' || $modulepart == 'action' || $modulepart == 'event' || $modulepart == 'actioncomm') {
626 require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
627
628 if (!DolibarrApiAccess::$user->hasRight('agenda', 'myactions', 'read') && !DolibarrApiAccess::$user->hasRight('agenda', 'allactions', 'read')) {
629 throw new RestException(403);
630 }
631
632 $object = new ActionComm($this->db);
633 $result = $object->fetch($id, $ref);
634 if (!$result) {
635 throw new RestException(404, 'Event not found');
636 }
637
638 $upload_dir = getMultidirOutput($object) . '/'.dol_sanitizeFileName($object->ref);
639 } elseif ($modulepart == 'expensereport') {
640 require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
641
642 if (!DolibarrApiAccess::$user->hasRight('expensereport', 'read')) {
643 throw new RestException(403);
644 }
645
646 $object = new ExpenseReport($this->db);
647 $result = $object->fetch($id, $ref);
648 if (!$result) {
649 throw new RestException(404, 'Expense report not found');
650 }
651
652 $upload_dir = getMultidirOutput($object) . '/'.dol_sanitizeFileName($object->ref);
653 } elseif ($modulepart == 'ticket') {
654 require_once DOL_DOCUMENT_ROOT.'/ticket/class/ticket.class.php';
655
656 if (!DolibarrApiAccess::$user->hasRight('ticket', 'read')) {
657 throw new RestException(403);
658 }
659
660 $object = new Ticket($this->db);
661 $result = $object->fetch($id, $ref);
662 if (!$result) {
663 throw new RestException(404, 'Ticket not found');
664 }
665
666 $upload_dir = $conf->ticket->dir_output.'/'.dol_sanitizeFileName($object->ref);
667 } elseif ($modulepart == 'knowledgemanagement') {
668 require_once DOL_DOCUMENT_ROOT.'/knowledgemanagement/class/knowledgerecord.class.php';
669
670 if (!DolibarrApiAccess::$user->hasRight('knowledgemanagement', 'knowledgerecord', 'read')) {
671 throw new RestException(403);
672 }
673
674 $object = new KnowledgeRecord($this->db);
675 $result = $object->fetch($id, $ref);
676 if (!$result) {
677 throw new RestException(404, 'KM article not found');
678 }
679
680 $upload_dir = getMultidirOutput($object) . '/knowledgerecord/'.dol_sanitizeFileName($object->ref);
681 } elseif ($modulepart == 'categorie' || $modulepart == 'category') {
682 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
683
684 if (!DolibarrApiAccess::$user->hasRight('categorie', 'lire')) {
685 throw new RestException(403);
686 }
687
688 $object = new Categorie($this->db);
689 $result = $object->fetch($id, $ref);
690 if (!$result) {
691 throw new RestException(404, 'Category not found');
692 }
693
694 $upload_dir = $conf->categorie->multidir_output[$object->entity ?? $conf->entity].'/'.get_exdir($object->id, 2, 0, 0, $object, 'category').$object->id."/photos/".dol_sanitizeFileName($object->ref);
695 } elseif ($modulepart == 'ecm') {
696 throw new RestException(500, 'Modulepart Ecm not implemented yet.');
697 // require_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmdirectory.class.php';
698
699 // if (!DolibarrApiAccess::$user->hasRight('ecm', 'read')) {
700 // throw new RestException(403);
701 // }
702
703 // // $object = new EcmDirectory($this->db);
704 // // $result = $object->fetch($ref);
705 // // if (!$result) {
706 // // throw new RestException(404, 'EcmDirectory not found');
707 // // }
708 // $upload_dir = $conf->ecm->dir_output;
709 // $type = 'all';
710 // $recursive = 0;
711 } elseif ($modulepart == 'contrat' || $modulepart == 'contract') {
712 $modulepart = 'contrat';
713 require_once DOL_DOCUMENT_ROOT . '/contrat/class/contrat.class.php';
714
715 $object = new Contrat($this->db);
716 $result = $object->fetch($id, $ref);
717 if (!$result) {
718 throw new RestException(404, 'Contract not found');
719 }
720
721 $upload_dir = getMultidirOutput($object) . "/" . get_exdir(0, 0, 0, 1, $object, 'contract');
722 } elseif ($modulepart == 'intervention' || $modulepart == 'ficheinter') {
723 $modulepart = 'ficheinter';
724 require_once DOL_DOCUMENT_ROOT . '/fichinter/class/fichinter.class.php';
725
726 $object = new Fichinter($this->db);
727 $result = $object->fetch($id, $ref);
728 if (!$result) {
729 throw new RestException(404, 'Interventional not found');
730 }
731
732 $upload_dir = $conf->ficheinter->dir_output . "/" . get_exdir(0, 0, 0, 1, $object, 'ficheinter');
733 } elseif ($modulepart == 'projet' || $modulepart == 'project') {
734 $modulepart = 'project';
735 require_once DOL_DOCUMENT_ROOT . '/projet/class/project.class.php';
736
737 $object = new Project($this->db);
738 $result = $object->fetch($id, $ref);
739 if (!$result) {
740 throw new RestException(404, 'Project not found');
741 }
742 $upload_dir = $conf->project->dir_output . "/" . get_exdir(0, 0, 0, 1, $object, 'project');
743 } elseif ($modulepart == 'task' || $modulepart == 'project_task') {
744 $modulepart = 'project_task';
745 require_once DOL_DOCUMENT_ROOT . '/projet/class/task.class.php';
746
747 if (!DolibarrApiAccess::$user->hasRight('projet', 'lire')) {
748 throw new RestException(403);
749 }
750
751 $object = new Task($this->db);
752 $result = $object->fetch($id, $ref);
753 if (!$result) {
754 throw new RestException(404, 'Task not found');
755 }
756
757 // Fetch the project to build the correct path
758 $project_result = $object->fetchProject();
759 if ($project_result < 0) {
760 throw new RestException(500, 'Error while fetching project for task');
761 }
762
763 $upload_dir = $conf->project->dir_output . "/" . dol_sanitizeFileName($object->project->ref) . "/" . dol_sanitizeFileName($object->ref);
764 } elseif ($modulepart == 'mrp') {
765 $modulepart = 'mrp';
766 require_once DOL_DOCUMENT_ROOT . '/mrp/class/mo.class.php';
767
768 $object = new Mo($this->db);
769 $result = $object->fetch($id, $ref);
770 if (!$result) {
771 throw new RestException(404, 'MO not found');
772 }
773
774 $upload_dir = getMultidirOutput($object) . "/" . get_exdir(0, 0, 0, 1, $object, 'mrp');
775 } elseif ($modulepart == 'contact' || $modulepart == 'socpeople') {
776 $modulepart = 'contact';
777 require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
778
779 $object = new Contact($this->db);
780 $result = $object->fetch($id?$id:$ref);
781 if (!$result) {
782 throw new RestException(404, 'Contact not found');
783 }
784 $upload_dir = $conf->societe->multidir_output[$object->entity ?? $conf->entity] . "/contact/" . get_exdir(0, 0, 0, 1, $object, 'contact');
785 } elseif ($modulepart == 'stock') {
786 require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
787
788 if (!DolibarrApiAccess::$user->hasRight('stock', 'lire')) {
789 throw new RestException(403);
790 }
791
792 $object = new Entrepot($this->db);
793 $result = $object->fetch($id, $ref);
794 if (!$result) {
795 throw new RestException(404, 'Warehouse not found');
796 }
797 $upload_dir = $conf->stock->multidir_output[$object->entity ?? $conf->entity].'/'.get_exdir(0, 0, 0, 1, $object, 'stock');
798 } else {
799 throw new RestException(500, 'Modulepart '.$modulepart.' not implemented yet.');
800 }
801
802 $objectType = $modulepart;
803 if (! empty($object->id) && ! empty($object->table_element)) {
804 $objectType = $object->table_element;
805 }
806
807 $filearray = dol_dir_list($upload_dir, $type, $recursive, '', '(\.meta|_preview.*\.png)$', $sortfield, (strtolower($sortorder) == 'desc' ? SORT_DESC : SORT_ASC), 1);
808 $countarray = count($filearray);
809 $filearray = array_slice($filearray, $limit * $page, $limit);
810 if (empty($filearray)) {
811 throw new RestException(404, 'Search for modulepart '.$modulepart.' with Id '.$object->id.(!empty($object->ref) ? ' or Ref '.$object->ref : '').' does not return any document.');
812 } else {
813 if (($object->id) > 0 && !empty($modulepart)) {
814 require_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php';
815 $ecmfile = new EcmFiles($this->db);
816 $result = $ecmfile->fetchAll('', '', 0, 0, array('t.src_object_type' => $objectType, 't.src_object_id' => $object->id));
817 if ($result < 0) {
818 throw new RestException(503, 'Error when retrieve ecm list : '.$this->db->lasterror());
819 } elseif (is_array($ecmfile->lines) && count($ecmfile->lines) > 0) {
820 $count = count($filearray);
821 for ($i = 0 ; $i < $count ; $i++) {
822 foreach ($ecmfile->lines as $line) {
823 unset($line->db);
824 if ($filearray[$i]['name'] == $line->filename) {
825 // Next line converts EcmFilesLine properties to array
826 $filearray[$i] = array_merge($filearray[$i], (array) $line);
827 }
828 }
829 if (isset($filearray[$i]['relativename'])) $filearray[$i]['content-type'] = dol_mimetype($filearray[$i]['relativename']);
830 $arraycontenttype = explode(",", $content_type);
831 if (!empty($content_type) && isset($filearray[$i]['relativename']) && !in_array(dol_mimetype($filearray[$i]['relativename']), $arraycontenttype)) {
832 unset($filearray[$i]);
833 $countarray -= 1;
834 }
835 }
836 }
837 }
838 }
839
840 //if $pagination_data is true the response will contain element data with all values and element pagination with pagination data(total,page,limit)
841 if ($pagination_data) {
842 $tmp = $filearray;
843 $filearray = [];
844 $filearray['data'] = $tmp;
845 $filearray['pagination'] = [
846 'total' => (int) $countarray,
847 'page' => $page, //count starts from 0
848 'page_count' => ceil((int) $countarray / $limit),
849 'limit' => $limit
850 ];
851 }
852
853 return $filearray;
854 }
855
856
865 /*
866 public function get($id) {
867 return array('note'=>'xxx');
868 }*/
869
870
906 public function post($filename, $modulepart, $ref = '', $subdir = '', $filecontent = '', $fileencoding = '', $overwriteifexists = 0, $createdirifnotexists = 1, $position = 0, $cover = '', $array_options = [], $generateThumbs = 0)
907 {
908 global $conf;
909
910 $modulepartorig = $modulepart;
911
912 if (empty($modulepart)) {
913 throw new RestException(400, 'Modulepart not provided.');
914 }
915
916 $newfilecontent = '';
917 if (empty($fileencoding)) {
918 $newfilecontent = $filecontent;
919 }
920 if ($fileencoding == 'base64') {
921 $newfilecontent = base64_decode($filecontent);
922 }
923
924 $original_file = dol_sanitizeFileName($filename);
925 $relativefile = 'UNSET';
926
927 // Define $uploadir
928 $object = null;
929 $entity = DolibarrApiAccess::$user->entity;
930 if (empty($entity)) {
931 $entity = 1;
932 }
933
934 if ($ref) {
935 $tmpreldir = '';
936 $fetchbyid = false;
937
938 if ($modulepart == 'facture' || $modulepart == 'invoice') {
939 $modulepart = 'facture';
940
941 require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
942 $object = new Facture($this->db);
943 } elseif ($modulepart == 'facture_fournisseur' || $modulepart == 'supplier_invoice') {
944 $modulepart = 'supplier_invoice';
945
946 require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
947 $object = new FactureFournisseur($this->db);
948 } elseif ($modulepart == 'commande' || $modulepart == 'order') {
949 $modulepart = 'commande';
950
951 require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
952 $object = new Commande($this->db);
953 } elseif ($modulepart == 'commande_fournisseur' || $modulepart == 'supplier_order') {
954 $modulepart = 'supplier_order';
955
956 require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
957 $object = new CommandeFournisseur($this->db);
958 } elseif ($modulepart == 'projet' || $modulepart == 'project') {
959 require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
960 $object = new Project($this->db);
961 } elseif ($modulepart == 'task' || $modulepart == 'project_task') {
962 $modulepart = 'project_task';
963
964 require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
965 $object = new Task($this->db);
966
967 $task_result = $object->fetch(0, $ref);
968
969 // Fetching the tasks project is required because its out_dir might be a sub-directory of the project
970 if ($task_result > 0) {
971 $project_result = $object->fetchProject();
972
973 if ($project_result >= 0) {
974 $tmpreldir = dol_sanitizeFileName($object->project->ref).'/';
975 }
976 } else {
977 throw new RestException(500, 'Error while fetching Task '.$ref);
978 }
979 } elseif ($modulepart == 'product' || $modulepart == 'produit' || $modulepart == 'service' || $modulepart == 'produit|service') {
980 require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
981 $object = new Product($this->db);
982 } elseif ($modulepart == 'expensereport') {
983 require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
984 $object = new ExpenseReport($this->db);
985 } elseif ($modulepart == 'ficheinter' || $modulepart == 'intervention') {
986 require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinter.class.php';
987 $object = new Fichinter($this->db);
988 } elseif ($modulepart == 'shipment' || $modulepart == 'expedition') {
989 require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php';
990 $object = new Expedition($this->db);
991 } elseif ($modulepart == 'adherent' || $modulepart == 'member') {
992 $modulepart = 'adherent';
993 require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
994 $object = new Adherent($this->db);
995 } elseif ($modulepart == 'proposal' || $modulepart == 'propal' || $modulepart == 'propale') {
996 $modulepart = 'propale';
997 require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
998 $object = new Propal($this->db);
999 } elseif ($modulepart == 'agenda' || $modulepart == 'action' || $modulepart == 'event') {
1000 $modulepart = 'agenda';
1001 require_once DOL_DOCUMENT_ROOT . '/comm/action/class/actioncomm.class.php';
1002 $object = new ActionComm($this->db);
1003 } elseif ($modulepart == 'contact' || $modulepart == 'socpeople') {
1004 $modulepart = 'contact';
1005 require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
1006 $object = new Contact($this->db);
1007 $fetchbyid = true;
1008 } elseif ($modulepart == 'societe' || $modulepart == 'company') {
1009 $modulepart = 'societe';
1010 require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
1011 $object = new Societe($this->db);
1012 $fetchbyid = true;
1013 } elseif ($modulepart == 'knowledgemanagement' ) {
1014 $modulepart = 'knowledgemanagement';
1015 require_once DOL_DOCUMENT_ROOT.'/knowledgemanagement/class/knowledgerecord.class.php';
1016 $object = new KnowledgeRecord($this->db);
1017 $fetchbyid = true;
1018 } elseif ($modulepart == 'ticket' ) {
1019 $modulepart = 'ticket';
1020 require_once DOL_DOCUMENT_ROOT.'/ticket/class/ticket.class.php';
1021 $object = new Ticket($this->db);
1022 $fetchbyid = true;
1023 } elseif ($modulepart == 'contrat' || $modulepart == 'contract') {
1024 $modulepart = 'contrat';
1025 require_once DOL_DOCUMENT_ROOT . '/contrat/class/contrat.class.php';
1026 $object = new Contrat($this->db);
1027 } elseif ($modulepart == 'mrp') {
1028 $modulepart = 'mrp';
1029 require_once DOL_DOCUMENT_ROOT . '/mrp/class/mo.class.php';
1030 $object = new Mo($this->db);
1031 } elseif ($modulepart == 'stock') {
1032 $modulepart = 'stock';
1033 require_once DOL_DOCUMENT_ROOT . '/product/stock/class/entrepot.class.php';
1034 $object = new Entrepot($this->db);
1035 } elseif ($modulepart == 'ecm') {
1036 throw new RestException(500, 'Using a non empty "ref" is not compatible with using modulepart = '.$modulepart);
1037 } else {
1038 // TODO Implement additional moduleparts
1039 throw new RestException(500, 'Modulepart '.$modulepart.' not implemented yet.');
1040 }
1041
1042 // at this step $object is always an object
1043 if ($fetchbyid) {
1044 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
1045 $result = $object->fetch((int) $ref);
1046 } else {
1047 $result = $object->fetch(0, $ref);
1048 }
1049
1050 if ($result == 0) {
1051 throw new RestException(404, "Object with ref '".$ref."' was not found.");
1052 } elseif ($result < 0) {
1053 throw new RestException(500, 'Error while fetching object: '.$object->error);
1054 }
1055
1056 if (!($object->id > 0)) {
1057 throw new RestException(404, 'The object '.$modulepart." with ref '".$ref."' was not found.");
1058 }
1059
1060 // Special cases that need to use get_exdir to get real dir of object
1061 // In future, all object should use this to define path of documents.
1062 if ($modulepart == 'supplier_invoice') {
1063 $tmpreldir = get_exdir($object->id, 2, 0, 0, $object, 'invoice_supplier');
1064 }
1065
1066 // Test on permissions
1067 //if ($modulepart != 'ecm') { // Here $modulepart is always != 'ecm'
1068 if ($modulepart == 'societe') {
1069 $relativefile = $tmpreldir.dol_sanitizeFileName((string) $object->id);
1070 } else {
1071 $relativefile = $tmpreldir.dol_sanitizeFileName($object->ref);
1072 }
1073 $tmp = dol_check_secure_access_document($modulepart, $relativefile, $entity, DolibarrApiAccess::$user, $ref, 'write');
1074 $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
1075 /*} else {
1076 if (!DolibarrApiAccess::$user->hasRight('ecm', 'upload')) {
1077 throw new RestException(403, 'Missing permission to upload files in ECM module');
1078 }
1079 $upload_dir = $conf->medias->multidir_output[$conf->entity];
1080 }*/
1081
1082 if (empty($upload_dir) || $upload_dir == '/') {
1083 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.');
1084 }
1085 } else {
1086 if ($modulepart == 'invoice') {
1087 $modulepart = 'facture';
1088 }
1089 if ($modulepart == 'member') {
1090 $modulepart = 'adherent';
1091 }
1092
1093 // Test on permissions
1094 if ($modulepart != 'ecm') {
1095 $relativefile = $subdir;
1096 $tmp = dol_check_secure_access_document($modulepart, $relativefile, $entity, DolibarrApiAccess::$user, '', 'write');
1097 $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
1098 } else {
1099 if (!DolibarrApiAccess::$user->hasRight('ecm', 'upload')) {
1100 throw new RestException(403, 'Missing permission to upload files in ECM module');
1101 }
1102 $upload_dir = $conf->medias->multidir_output[$conf->entity];
1103 }
1104
1105 if (empty($upload_dir) || $upload_dir == '/') {
1106 if (!empty($tmp['error'])) {
1107 throw new RestException(403, 'Error returned by dol_check_secure_access_document: '.$tmp['error']);
1108 } else {
1109 throw new RestException(400, 'This value of modulepart ('.$modulepart.') is not allowed with this value of subdir ('.$relativefile.')');
1110 }
1111 }
1112 }
1113 // $original_file here is still value of filename without any dir.
1114
1115 $upload_dir = dol_sanitizePathName($upload_dir);
1116
1117 if (!empty($createdirifnotexists)) {
1118 if (dol_mkdir($upload_dir) < 0) { // needed by products
1119 throw new RestException(500, 'Error while trying to create directory '.$upload_dir);
1120 }
1121 }
1122
1123 $destfile = $upload_dir.'/'.$original_file;
1124 $destfiletmp = DOL_DATA_ROOT.'/admin/temp/'.$original_file;
1125 dol_delete_file($destfiletmp);
1126 //var_dump($original_file);exit;
1127
1128 if (!dol_is_dir(dirname($destfile))) {
1129 throw new RestException(400, 'Directory does not exists : '.dirname($destfile));
1130 }
1131
1132 if (!$overwriteifexists && dol_is_file($destfile)) {
1133 throw new RestException(400, "File with name '".$original_file."' already exists.");
1134 }
1135
1136 // in case temporary directory admin/temp doesn't exist
1137 if (!dol_is_dir(dirname($destfiletmp))) {
1138 dol_mkdir(dirname($destfiletmp));
1139 }
1140
1141 $fhandle = @fopen($destfiletmp, 'w');
1142 if ($fhandle) {
1143 $nbofbyteswrote = fwrite($fhandle, $newfilecontent);
1144 fclose($fhandle);
1145 dolChmod($destfiletmp);
1146 } else {
1147 throw new RestException(500, "Failed to open file '".$destfiletmp."' for write");
1148 }
1149
1150 $disablevirusscan = 0;
1151 $src_file = $destfiletmp;
1152 $dest_file = $destfile;
1153
1154 // Security:
1155 // If we need to make a virus scan
1156 if (empty($disablevirusscan) && file_exists($src_file)) {
1157 $checkvirusarray = dolCheckVirus($src_file, $dest_file);
1158 if (count($checkvirusarray)) {
1159 dol_syslog('Files.lib::dol_move_uploaded_file File "'.$src_file.'" (target name "'.$dest_file.'") KO with antivirus: errors='.implode(',', $checkvirusarray), LOG_WARNING);
1160 throw new RestException(500, 'ErrorFileIsInfectedWithAVirus: '.implode(',', $checkvirusarray));
1161 }
1162 }
1163
1164 // Security:
1165 // Disallow file with some extensions. We rename them.
1166 // Because if we put the documents directory into a directory inside web root (very bad), this allows to execute on demand arbitrary code.
1167 if (isAFileWithExecutableContent($dest_file) && !getDolGlobalString('MAIN_DOCUMENT_IS_OUTSIDE_WEBROOT_SO_NOEXE_NOT_REQUIRED')) {
1168 // $upload_dir ends with a slash, so be must be sure the medias dir to compare to ends with slash too.
1169 $publicmediasdirwithslash = $conf->medias->multidir_output[$conf->entity];
1170 if (!preg_match('/\/$/', $publicmediasdirwithslash)) {
1171 $publicmediasdirwithslash .= '/';
1172 }
1173
1174 if (strpos($upload_dir, $publicmediasdirwithslash) !== 0 || !getDolGlobalInt("MAIN_DOCUMENT_DISABLE_NOEXE_IN_MEDIAS_DIR")) { // We never add .noexe on files into media directory
1175 $dest_file .= '.noexe';
1176 }
1177 }
1178
1179 // Security:
1180 // We refuse cache files/dirs, upload using .. and pipes into filenames.
1181 if (preg_match('/^\./', basename($src_file)) || preg_match('/\.\./', $src_file) || preg_match('/[<>|]/', $src_file)) {
1182 dol_syslog("Refused to deliver file ".$src_file, LOG_WARNING);
1183 throw new RestException(500, "Refused to deliver file ".$src_file);
1184 }
1185
1186 // Security:
1187 // We refuse cache files/dirs, upload using .. and pipes into filenames.
1188 if (preg_match('/^\./', basename($dest_file)) || preg_match('/\.\./', $dest_file) || preg_match('/[<>|]/', $dest_file)) {
1189 dol_syslog("Refused to deliver file ".$dest_file, LOG_WARNING);
1190 throw new RestException(500, "Refused to deliver file ".$dest_file);
1191 }
1192
1193 $moreinfo = array('note_private' => 'File uploaded using API /documents from IP '.getUserRemoteIP());
1194 // $object may be null
1195 if (is_object($object) && $object->id > 0) {
1196 $moreinfo['src_object_type'] = $object->table_element;
1197 $moreinfo['src_object_id'] = $object->id;
1198 }
1199 if (!empty($array_options)) {
1200 $moreinfo = array_merge($moreinfo, ["array_options" => $array_options]);
1201 }
1202 if (!empty($position)) {
1203 $moreinfo = array_merge($moreinfo, ["position" => $position]);
1204 }
1205 if (!empty($cover)) {
1206 $moreinfo = array_merge($moreinfo, ["cover" => $cover]);
1207 }
1208 $moreinfo['gen_or_uploaded'] = 'api';
1209
1210 // Move the temporary file at its final emplacement
1211 $result = dol_move($destfiletmp, $dest_file, '0', $overwriteifexists, 1, 1, $moreinfo);
1212 if (!$result) {
1213 throw new RestException(500, "Failed to move file into '".$dest_file."'");
1214 }
1215
1216 if (is_object($object) && $generateThumbs) {
1217 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
1218 if (image_format_supported($dest_file)) {
1219 $object->addThumbs($dest_file);
1220 }
1221 }
1222
1223 return dol_basename($destfile);
1224 }
1225
1245 public function delete($modulepart, $original_file)
1246 {
1247 global $conf;
1248
1249 if (empty($modulepart)) {
1250 throw new RestException(400, 'bad value for parameter modulepart');
1251 }
1252 if (empty($original_file)) {
1253 throw new RestException(400, 'bad value for parameter original_file');
1254 }
1255
1256 // Normalize modulepart for project_task
1257 if ($modulepart == 'task') {
1258 $modulepart = 'project_task';
1259 }
1260
1261 //--- Finds and returns the document
1262 $entity = $conf->entity;
1263
1264 // Special cases that need to use get_exdir to get real dir of object
1265 // If future, all object should use this to define path of documents.
1266 /*
1267 $tmpreldir = '';
1268 if ($modulepart == 'supplier_invoice') {
1269 $tmpreldir = get_exdir($object->id, 2, 0, 0, $object, 'invoice_supplier');
1270 }
1271
1272 $relativefile = $tmpreldir.dol_sanitizeFileName($object->ref); */
1273 $relativefile = $original_file;
1274
1275 $check_access = dol_check_secure_access_document($modulepart, $relativefile, $entity, DolibarrApiAccess::$user, '', 'read');
1276 $accessallowed = $check_access['accessallowed'];
1277 $sqlprotectagainstexternals = $check_access['sqlprotectagainstexternals'];
1278 $original_file = $check_access['original_file'];
1279
1280 if (preg_match('/\.\./', $original_file) || preg_match('/[<>|]/', $original_file)) {
1281 throw new RestException(403);
1282 }
1283 if (!$accessallowed) {
1284 throw new RestException(403);
1285 }
1286
1287 if (DolibarrApiAccess::$user->socid > 0) {
1288 if ($sqlprotectagainstexternals) {
1289 $resql = $this->db->query($sqlprotectagainstexternals);
1290 if ($resql) {
1291 $num = $this->db->num_rows($resql);
1292 $i = 0;
1293 while ($i < $num) {
1294 $obj = $this->db->fetch_object($resql);
1295 if (DolibarrApiAccess::$user->socid != $obj->fk_soc) {
1296 throw new RestException(403, 'Not allowed to download documents with such a ref');
1297 }
1298 $i++;
1299 }
1300 }
1301 }
1302 }
1303
1304 $filename = basename($original_file);
1305 $original_file_osencoded = dol_osencode($original_file); // New file name encoded in OS encoding charset
1306
1307 if (!file_exists($original_file_osencoded)) {
1308 dol_syslog("Try to download not found file ".$original_file_osencoded, LOG_WARNING);
1309 throw new RestException(404, 'File not found');
1310 }
1311
1312 if (@unlink($original_file_osencoded)) {
1313 return array(
1314 'success' => array(
1315 'code' => 200,
1316 'message' => 'Document deleted'
1317 )
1318 );
1319 }
1320
1321 throw new RestException(403);
1322 }
1323}
$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 categories.
Class to manage predefined suppliers products.
Class to manage customers orders.
Class to manage contact/addresses.
API class for receive files.
__construct()
Constructor.
index($modulepart, $original_file='')
Download a 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:33
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 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.
Class to manage Dolibarr users.
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.
if(!function_exists( 'utf8_encode')) if(!function_exists('utf8_decode')) if(!function_exists( 'str_starts_with')) if(!function_exists('str_ends_with')) if(!function_exists( 'str_contains')) 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.