dolibarr 20.0.0
api_documents.class.php
1<?php
2/* Copyright (C) 2016 Xebax Christy <xebax@wanadoo.fr>
3 * Copyright (C) 2016 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2016 Jean-François Ferry <jfefe@aternatik.fr>
5 * Copyright (C) 2023 Romain Neil <contact@romain-neil.fr>
6 *
7 * This program is free software you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
21use Luracast\Restler\RestException;
22
23require_once DOL_DOCUMENT_ROOT.'/main.inc.php';
24require_once DOL_DOCUMENT_ROOT.'/api/class/api.class.php';
25require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
26
34{
38 public function __construct()
39 {
40 global $db;
41 $this->db = $db;
42 }
43
44
61 public function index($modulepart, $original_file = '')
62 {
63 global $conf;
64
65 if (empty($modulepart)) {
66 throw new RestException(400, 'bad value for parameter modulepart');
67 }
68 if (empty($original_file)) {
69 throw new RestException(400, 'bad value for parameter original_file');
70 }
71
72 //--- Finds and returns the document
73 $entity = $conf->entity;
74
75 // Special cases that need to use get_exdir to get real dir of object
76 // If future, all object should use this to define path of documents.
77 /*
78 $tmpreldir = '';
79 if ($modulepart == 'supplier_invoice') {
80 $tmpreldir = get_exdir($object->id, 2, 0, 0, $object, 'invoice_supplier');
81 }
82
83 $relativefile = $tmpreldir.dol_sanitizeFileName($object->ref); */
84 $relativefile = $original_file;
85
86 $check_access = dol_check_secure_access_document($modulepart, $relativefile, $entity, DolibarrApiAccess::$user, '', 'read');
87 $accessallowed = $check_access['accessallowed'];
88 $sqlprotectagainstexternals = $check_access['sqlprotectagainstexternals'];
89 $original_file = $check_access['original_file'];
90
91 if (preg_match('/\.\./', $original_file) || preg_match('/[<>|]/', $original_file)) {
92 throw new RestException(403);
93 }
94 if (!$accessallowed) {
95 throw new RestException(403);
96 }
97
98 $filename = basename($original_file);
99 $original_file_osencoded = dol_osencode($original_file); // New file name encoded in OS encoding charset
100
101 if (!file_exists($original_file_osencoded)) {
102 dol_syslog("Try to download not found file ".$original_file_osencoded, LOG_WARNING);
103 throw new RestException(404, 'File not found');
104 }
105
106 $file_content = file_get_contents($original_file_osencoded);
107 return array('filename'=>$filename, 'content-type' => dol_mimetype($filename), 'filesize'=>filesize($original_file), 'content'=>base64_encode($file_content), 'encoding'=>'base64');
108 }
109
110
132 public function builddoc($modulepart, $original_file = '', $doctemplate = '', $langcode = '')
133 {
134 global $conf, $langs;
135
136 if (empty($modulepart)) {
137 throw new RestException(400, 'bad value for parameter modulepart');
138 }
139 if (empty($original_file)) {
140 throw new RestException(400, 'bad value for parameter original_file');
141 }
142
143 $outputlangs = $langs;
144 if ($langcode && $langs->defaultlang != $langcode) {
145 $outputlangs = new Translate('', $conf);
146 $outputlangs->setDefaultLang($langcode);
147 }
148
149 //--- Finds and returns the document
150 $entity = $conf->entity;
151
152 // Special cases that need to use get_exdir to get real dir of object
153 // If future, all object should use this to define path of documents.
154 /*
155 $tmpreldir = '';
156 if ($modulepart == 'supplier_invoice') {
157 $tmpreldir = get_exdir($object->id, 2, 0, 0, $object, 'invoice_supplier');
158 }
159
160 $relativefile = $tmpreldir.dol_sanitizeFileName($object->ref); */
161 $relativefile = $original_file;
162
163 $check_access = dol_check_secure_access_document($modulepart, $relativefile, $entity, DolibarrApiAccess::$user, '', 'write');
164 $accessallowed = $check_access['accessallowed'];
165 $sqlprotectagainstexternals = $check_access['sqlprotectagainstexternals'];
166 $original_file = $check_access['original_file'];
167
168 if (preg_match('/\.\./', $original_file) || preg_match('/[<>|]/', $original_file)) {
169 throw new RestException(403);
170 }
171 if (!$accessallowed) {
172 throw new RestException(403);
173 }
174
175 // --- Generates the document
176 $hidedetails = !getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS') ? 0 : 1;
177 $hidedesc = !getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_DESC') ? 0 : 1;
178 $hideref = !getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_REF') ? 0 : 1;
179
180 $templateused = '';
181
182 if ($modulepart == 'facture' || $modulepart == 'invoice') {
183 require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
184 $tmpobject = new Facture($this->db);
185 $result = $tmpobject->fetch(0, preg_replace('/\.[^\.]+$/', '', basename($original_file)));
186 if (!$result) {
187 throw new RestException(404, 'Invoice not found');
188 }
189
190 $templateused = $doctemplate ? $doctemplate : $tmpobject->model_pdf;
191 $result = $tmpobject->generateDocument($templateused, $outputlangs, $hidedetails, $hidedesc, $hideref);
192 if ($result <= 0) {
193 throw new RestException(500, 'Error generating document');
194 }
195 } elseif ($modulepart == 'facture_fournisseur' || $modulepart == 'invoice_supplier') {
196 require_once DOL_DOCUMENT_ROOT . '/fourn/class/fournisseur.facture.class.php';
197 $tmpobject = new FactureFournisseur($this->db);
198 $result = $tmpobject->fetch(0, preg_replace('/\.[^\.]+$/', '', basename($original_file)));
199 if (!$result) {
200 throw new RestException(404, 'Supplier invoice not found');
201 }
202
203 $templateused = $doctemplate ? $doctemplate : $tmpobject->model_pdf;
204 $result = $tmpobject->generateDocument($templateused, $outputlangs, $hidedetails, $hidedesc, $hideref);
205 if ($result < 0) {
206 throw new RestException(500, 'Error generating document');
207 }
208 } elseif ($modulepart == 'commande' || $modulepart == 'order') {
209 require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
210 $tmpobject = new Commande($this->db);
211 $result = $tmpobject->fetch(0, preg_replace('/\.[^\.]+$/', '', basename($original_file)));
212 if (!$result) {
213 throw new RestException(404, 'Order not found');
214 }
215 $templateused = $doctemplate ? $doctemplate : $tmpobject->model_pdf;
216 $result = $tmpobject->generateDocument($templateused, $outputlangs, $hidedetails, $hidedesc, $hideref);
217 if ($result <= 0) {
218 throw new RestException(500, 'Error generating document');
219 }
220 } elseif ($modulepart == 'propal' || $modulepart == 'proposal') {
221 require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
222 $tmpobject = new Propal($this->db);
223 $result = $tmpobject->fetch(0, preg_replace('/\.[^\.]+$/', '', basename($original_file)));
224 if (!$result) {
225 throw new RestException(404, 'Proposal not found');
226 }
227 $templateused = $doctemplate ? $doctemplate : $tmpobject->model_pdf;
228 $result = $tmpobject->generateDocument($templateused, $outputlangs, $hidedetails, $hidedesc, $hideref);
229 if ($result <= 0) {
230 throw new RestException(500, 'Error generating document');
231 }
232 } elseif ($modulepart == 'contrat' || $modulepart == 'contract') {
233 require_once DOL_DOCUMENT_ROOT . '/contrat/class/contrat.class.php';
234
235 $tmpobject = new Contrat($this->db);
236 $result = $tmpobject->fetch(0, preg_replace('/\.[^\.]+$/', '', basename($original_file)));
237
238 if (!$result) {
239 throw new RestException(404, 'Contract not found');
240 }
241
242 $templateused = $doctemplate ? $doctemplate : $tmpobject->model_pdf;
243 $result = $tmpobject->generateDocument($templateused, $outputlangs, $hidedetails, $hidedesc, $hideref);
244
245 if ($result <= 0) {
246 throw new RestException(500, 'Error generating document missing doctemplate parameter');
247 }
248 } elseif ($modulepart == 'expedition' || $modulepart == 'shipment') {
249 require_once DOL_DOCUMENT_ROOT . '/expedition/class/expedition.class.php';
250
251 $tmpobject = new Expedition($this->db);
252 $result = $tmpobject->fetch(0, preg_replace('/\.[^\.]+$/', '', basename($original_file)));
253
254 if (!$result) {
255 throw new RestException(404, 'Shipment not found');
256 }
257
258 $templateused = $doctemplate ? $doctemplate : $tmpobject->model_pdf;
259 $result = $tmpobject->generateDocument($templateused, $outputlangs, $hidedetails, $hidedesc, $hideref);
260
261 if ($result <= 0) {
262 throw new RestException(500, 'Error generating document missing doctemplate parameter');
263 }
264 } elseif ($modulepart == 'mrp') {
265 require_once DOL_DOCUMENT_ROOT . '/mrp/class/mo.class.php';
266
267 $tmpobject = new Mo($this->db);
268 $result = $tmpobject->fetch(0, preg_replace('/\.[^\.]+$/', '', basename($original_file)));
269
270 if (!$result) {
271 throw new RestException(404, 'MO not found');
272 }
273
274 $templateused = $doctemplate ? $doctemplate : $tmpobject->model_pdf;
275 $result = $tmpobject->generateDocument($templateused, $outputlangs, $hidedetails, $hidedesc, $hideref);
276
277 if ($result <= 0) {
278 throw new RestException(500, 'Error generating document missing doctemplate parameter');
279 }
280 } else {
281 throw new RestException(403, 'Generation not available for this modulepart');
282 }
283
284 $filename = basename($original_file);
285 $original_file_osencoded = dol_osencode($original_file); // New file name encoded in OS encoding charset
286
287 if (!file_exists($original_file_osencoded)) {
288 throw new RestException(404, 'File not found');
289 }
290
291 $file_content = file_get_contents($original_file_osencoded);
292 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');
293 }
294
315 public function getDocumentsListByElement($modulepart, $id = 0, $ref = '', $sortfield = '', $sortorder = '')
316 {
317 global $conf;
318
319 if (empty($modulepart)) {
320 throw new RestException(400, 'bad value for parameter modulepart');
321 }
322
323 if (empty($id) && empty($ref)) {
324 throw new RestException(400, 'bad value for parameter id or ref');
325 }
326
327 $id = (empty($id) ? 0 : $id);
328 $recursive = 0;
329 $type = 'files';
330
331 if ($modulepart == 'societe' || $modulepart == 'thirdparty') {
332 require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
333
334 if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
335 throw new RestException(403);
336 }
337
338 $object = new Societe($this->db);
339 $result = $object->fetch($id, $ref);
340 if (!$result) {
341 throw new RestException(404, 'Thirdparty not found');
342 }
343
344 $upload_dir = $conf->societe->multidir_output[$object->entity]."/".$object->id;
345 } elseif ($modulepart == 'user') {
346 require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
347
348 // Can get doc if has permission to read all user or if it is user itself
349 if (!DolibarrApiAccess::$user->hasRight('user', 'user', 'lire') && DolibarrApiAccess::$user->id != $id) {
350 throw new RestException(403);
351 }
352
353 $object = new User($this->db);
354 $result = $object->fetch($id, $ref);
355 if (!$result) {
356 throw new RestException(404, 'User not found');
357 }
358
359 $upload_dir = $conf->user->dir_output.'/'.get_exdir(0, 0, 0, 0, $object, 'user').'/'.$object->id;
360 } elseif ($modulepart == 'adherent' || $modulepart == 'member') {
361 require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
362
363 if (!DolibarrApiAccess::$user->hasRight('adherent', 'lire')) {
364 throw new RestException(403);
365 }
366
367 $object = new Adherent($this->db);
368 $result = $object->fetch($id, $ref);
369 if (!$result) {
370 throw new RestException(404, 'Member not found');
371 }
372
373 $upload_dir = $conf->adherent->dir_output."/".get_exdir(0, 0, 0, 1, $object, 'member');
374 } elseif ($modulepart == 'propal' || $modulepart == 'proposal') {
375 require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
376
377 if (!DolibarrApiAccess::$user->hasRight('propal', 'lire')) {
378 throw new RestException(403);
379 }
380
381 $object = new Propal($this->db);
382 $result = $object->fetch($id, $ref);
383 if (!$result) {
384 throw new RestException(404, 'Proposal not found');
385 }
386
387 $upload_dir = $conf->propal->multidir_output[$object->entity]."/".get_exdir(0, 0, 0, 1, $object, 'propal');
388 } elseif ($modulepart == 'supplier_proposal') {
389 require_once DOL_DOCUMENT_ROOT.'/supplier_proposal/class/supplier_proposal.class.php';
390
391 if (!DolibarrApiAccess::$user->hasRight('supplier_proposal', 'read')) {
392 throw new RestException(403);
393 }
394
395 $object = new Propal($this->db);
396 $result = $object->fetch($id, $ref);
397 if (!$result) {
398 throw new RestException(404, 'Supplier proposal not found');
399 }
400
401 $upload_dir = $conf->propal->multidir_output[$object->entity]."/".get_exdir(0, 0, 0, 1, $object, 'propal');
402 } elseif ($modulepart == 'commande' || $modulepart == 'order') {
403 require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
404
405 if (!DolibarrApiAccess::$user->hasRight('commande', 'lire')) {
406 throw new RestException(403);
407 }
408
409 $object = new Commande($this->db);
410 $result = $object->fetch($id, $ref);
411 if (!$result) {
412 throw new RestException(404, 'Order not found');
413 }
414
415 $upload_dir = $conf->commande->dir_output."/".get_exdir(0, 0, 0, 1, $object, 'commande');
416 } elseif ($modulepart == 'commande_fournisseur' || $modulepart == 'supplier_order') {
417 $modulepart = 'supplier_order';
418
419 require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
420
421 if (!DolibarrApiAccess::$user->hasRight('fournisseur', 'commande', 'lire') && !DolibarrApiAccess::$user->hasRight('supplier_order', 'lire')) {
422 throw new RestException(403);
423 }
424
425 $object = new CommandeFournisseur($this->db);
426 $result = $object->fetch($id, $ref);
427 if (!$result) {
428 throw new RestException(404, 'Purchase order not found');
429 }
430
431 $upload_dir = $conf->fournisseur->dir_output."/commande/".dol_sanitizeFileName($object->ref);
432 } elseif ($modulepart == 'shipment' || $modulepart == 'expedition') {
433 require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php';
434
435 if (!DolibarrApiAccess::$user->hasRight('expedition', 'lire')) {
436 throw new RestException(403);
437 }
438
439 $object = new Expedition($this->db);
440 $result = $object->fetch($id, $ref);
441 if (!$result) {
442 throw new RestException(404, 'Shipment not found');
443 }
444
445 $upload_dir = $conf->expedition->dir_output."/sending/".get_exdir(0, 0, 0, 1, $object, 'shipment');
446 } elseif ($modulepart == 'facture' || $modulepart == 'invoice') {
447 require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
448
449 if (!DolibarrApiAccess::$user->hasRight('facture', 'lire')) {
450 throw new RestException(403);
451 }
452
453 $object = new Facture($this->db);
454 $result = $object->fetch($id, $ref);
455 if (!$result) {
456 throw new RestException(404, 'Invoice not found');
457 }
458
459 $upload_dir = $conf->facture->dir_output."/".get_exdir(0, 0, 0, 1, $object, 'invoice');
460 } elseif ($modulepart == 'facture_fournisseur' || $modulepart == 'supplier_invoice') {
461 $modulepart = 'supplier_invoice';
462
463 require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
464
465 if (!DolibarrApiAccess::$user->hasRight('fournisseur', 'facture', 'lire') && !DolibarrApiAccess::$user->hasRight('supplier_invoice', 'lire')) {
466 throw new RestException(403);
467 }
468
469 $object = new FactureFournisseur($this->db);
470 $result = $object->fetch($id, $ref);
471 if (!$result) {
472 throw new RestException(404, 'Invoice not found');
473 }
474
475 $upload_dir = $conf->fournisseur->dir_output."/facture/".get_exdir($object->id, 2, 0, 0, $object, 'invoice_supplier').dol_sanitizeFileName($object->ref);
476 } elseif ($modulepart == 'produit' || $modulepart == 'product') {
477 require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
478
479 if (!DolibarrApiAccess::$user->hasRight('produit', 'lire')) {
480 throw new RestException(403);
481 }
482
483 $object = new Product($this->db);
484 $result = $object->fetch($id, $ref);
485 if ($result == 0) {
486 throw new RestException(404, 'Product not found');
487 } elseif ($result < 0) {
488 throw new RestException(500, 'Error while fetching object: '.$object->error);
489 }
490
491 $upload_dir = $conf->product->multidir_output[$object->entity].'/'.get_exdir(0, 0, 0, 1, $object, 'product');
492 } elseif ($modulepart == 'agenda' || $modulepart == 'action' || $modulepart == 'event') {
493 require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
494
495 if (!DolibarrApiAccess::$user->hasRight('agenda', 'myactions', 'read') && !DolibarrApiAccess::$user->hasRight('agenda', 'allactions', 'read')) {
496 throw new RestException(403);
497 }
498
499 $object = new ActionComm($this->db);
500 $result = $object->fetch($id, $ref);
501 if (!$result) {
502 throw new RestException(404, 'Event not found');
503 }
504
505 $upload_dir = $conf->agenda->dir_output.'/'.dol_sanitizeFileName($object->ref);
506 } elseif ($modulepart == 'expensereport') {
507 require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
508
509 if (!DolibarrApiAccess::$user->hasRight('expensereport', 'read') && !DolibarrApiAccess::$user->hasRight('expensereport', 'read')) {
510 throw new RestException(403);
511 }
512
513 $object = new ExpenseReport($this->db);
514 $result = $object->fetch($id, $ref);
515 if (!$result) {
516 throw new RestException(404, 'Expense report not found');
517 }
518
519 $upload_dir = $conf->expensereport->dir_output.'/'.dol_sanitizeFileName($object->ref);
520 } elseif ($modulepart == 'knowledgemanagement') {
521 require_once DOL_DOCUMENT_ROOT.'/knowledgemanagement/class/knowledgerecord.class.php';
522
523 if (!DolibarrApiAccess::$user->hasRight('knowledgemanagement', 'knowledgerecord', 'read') && !DolibarrApiAccess::$user->hasRight('knowledgemanagement', 'knowledgerecord', 'read')) {
524 throw new RestException(403);
525 }
526
527 $object = new KnowledgeRecord($this->db);
528 $result = $object->fetch($id, $ref);
529 if (!$result) {
530 throw new RestException(404, 'KM article not found');
531 }
532
533 $upload_dir = $conf->knowledgemanagement->dir_output.'/knowledgerecord/'.dol_sanitizeFileName($object->ref);
534 } elseif ($modulepart == 'categorie' || $modulepart == 'category') {
535 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
536
537 if (!DolibarrApiAccess::$user->hasRight('categorie', 'lire')) {
538 throw new RestException(403);
539 }
540
541 $object = new Categorie($this->db);
542 $result = $object->fetch($id, $ref);
543 if (!$result) {
544 throw new RestException(404, 'Category not found');
545 }
546
547 $upload_dir = $conf->categorie->multidir_output[$object->entity].'/'.get_exdir($object->id, 2, 0, 0, $object, 'category').$object->id."/photos/".dol_sanitizeFileName($object->ref);
548 } elseif ($modulepart == 'ecm') {
549 throw new RestException(500, 'Modulepart Ecm not implemented yet.');
550 // require_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmdirectory.class.php';
551
552 // if (!DolibarrApiAccess::$user->hasRight('ecm', 'read')) {
553 // throw new RestException(403);
554 // }
555
556 // // $object = new EcmDirectory($this->db);
557 // // $result = $object->fetch($ref);
558 // // if (!$result) {
559 // // throw new RestException(404, 'EcmDirectory not found');
560 // // }
561 // $upload_dir = $conf->ecm->dir_output;
562 // $type = 'all';
563 // $recursive = 0;
564 } elseif ($modulepart == 'contrat' || $modulepart == 'contract') {
565 $modulepart = 'contrat';
566 require_once DOL_DOCUMENT_ROOT . '/contrat/class/contrat.class.php';
567
568 $object = new Contrat($this->db);
569 $result = $object->fetch($id, $ref);
570 if (!$result) {
571 throw new RestException(404, 'Contract not found');
572 }
573
574 $upload_dir = $conf->contrat->dir_output . "/" . get_exdir(0, 0, 0, 1, $object, 'contract');
575 } elseif ($modulepart == 'projet' || $modulepart == 'project') {
576 $modulepart = 'project';
577 require_once DOL_DOCUMENT_ROOT . '/projet/class/project.class.php';
578
579 $object = new Project($this->db);
580 $result = $object->fetch($id, $ref);
581 if (!$result) {
582 throw new RestException(404, 'Project not found');
583 }
584
585 $upload_dir = $conf->projet->dir_output . "/" . get_exdir(0, 0, 0, 1, $object, 'project');
586 } elseif ($modulepart == 'mrp') {
587 $modulepart = 'mrp';
588 require_once DOL_DOCUMENT_ROOT . '/mrp/class/mo.class.php';
589
590 $object = new Mo($this->db);
591 $result = $object->fetch($id, $ref);
592 if (!$result) {
593 throw new RestException(404, 'MO not found');
594 }
595
596 $upload_dir = $conf->mrp->dir_output . "/" . get_exdir(0, 0, 0, 1, $object, 'mrp');
597 } else {
598 throw new RestException(500, 'Modulepart '.$modulepart.' not implemented yet.');
599 }
600
601 $objectType = $modulepart;
602 if (! empty($object->id) && ! empty($object->table_element)) {
603 $objectType = $object->table_element;
604 }
605
606 $filearray = dol_dir_list($upload_dir, $type, $recursive, '', '(\.meta|_preview.*\.png)$', $sortfield, (strtolower($sortorder) == 'desc' ? SORT_DESC : SORT_ASC), 1);
607 if (empty($filearray)) {
608 throw new RestException(404, 'Search for modulepart '.$modulepart.' with Id '.$object->id.(!empty($object->ref) ? ' or Ref '.$object->ref : '').' does not return any document.');
609 } else {
610 if (($object->id) > 0 && !empty($modulepart)) {
611 require_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php';
612 $ecmfile = new EcmFiles($this->db);
613 $result = $ecmfile->fetchAll('', '', 0, 0, array('t.src_object_type' => $objectType, 't.src_object_id' => $object->id));
614 if ($result < 0) {
615 throw new RestException(503, 'Error when retrieve ecm list : '.$this->db->lasterror());
616 } elseif (is_array($ecmfile->lines) && count($ecmfile->lines) > 0) {
617 $count = count($filearray);
618 for ($i = 0 ; $i < $count ; $i++) {
619 foreach ($ecmfile->lines as $line) {
620 if ($filearray[$i]['name'] == $line->filename) {
621 $filearray[$i] = array_merge($filearray[$i], (array) $line);
622 }
623 }
624 }
625 }
626 }
627 }
628
629 return $filearray;
630 }
631
632
641 /*
642 public function get($id) {
643 return array('note'=>'xxx');
644 }*/
645
646
673 public function post($filename, $modulepart, $ref = '', $subdir = '', $filecontent = '', $fileencoding = '', $overwriteifexists = 0, $createdirifnotexists = 1)
674 {
675 global $conf;
676
677 //var_dump($modulepart);
678 //var_dump($filename);
679 //var_dump($filecontent);exit;
680
681 $modulepartorig = $modulepart;
682
683 if (empty($modulepart)) {
684 throw new RestException(400, 'Modulepart not provided.');
685 }
686
687 $newfilecontent = '';
688 if (empty($fileencoding)) {
689 $newfilecontent = $filecontent;
690 }
691 if ($fileencoding == 'base64') {
692 $newfilecontent = base64_decode($filecontent);
693 }
694
695 $original_file = dol_sanitizeFileName($filename);
696
697 // Define $uploadir
698 $object = null;
699 $entity = DolibarrApiAccess::$user->entity;
700 if (empty($entity)) {
701 $entity = 1;
702 }
703
704 if ($ref) {
705 $tmpreldir = '';
706 $fetchbyid = false;
707
708 if ($modulepart == 'facture' || $modulepart == 'invoice') {
709 $modulepart = 'facture';
710
711 require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
712 $object = new Facture($this->db);
713 } elseif ($modulepart == 'facture_fournisseur' || $modulepart == 'supplier_invoice') {
714 $modulepart = 'supplier_invoice';
715
716 require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
717 $object = new FactureFournisseur($this->db);
718 } elseif ($modulepart == 'commande' || $modulepart == 'order') {
719 $modulepart = 'commande';
720
721 require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
722 $object = new Commande($this->db);
723 } elseif ($modulepart == 'commande_fournisseur' || $modulepart == 'supplier_order') {
724 $modulepart = 'supplier_order';
725
726 require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
727 $object = new CommandeFournisseur($this->db);
728 } elseif ($modulepart == 'projet' || $modulepart == 'project') {
729 require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
730 $object = new Project($this->db);
731 } elseif ($modulepart == 'task' || $modulepart == 'project_task') {
732 $modulepart = 'project_task';
733
734 require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
735 $object = new Task($this->db);
736
737 $task_result = $object->fetch('', $ref);
738
739 // Fetching the tasks project is required because its out_dir might be a sub-directory of the project
740 if ($task_result > 0) {
741 $project_result = $object->fetch_projet();
742
743 if ($project_result >= 0) {
744 $tmpreldir = dol_sanitizeFileName($object->project->ref).'/';
745 }
746 } else {
747 throw new RestException(500, 'Error while fetching Task '.$ref);
748 }
749 } elseif ($modulepart == 'product' || $modulepart == 'produit' || $modulepart == 'service' || $modulepart == 'produit|service') {
750 require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
751 $object = new Product($this->db);
752 } elseif ($modulepart == 'expensereport') {
753 require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
754 $object = new ExpenseReport($this->db);
755 } elseif ($modulepart == 'fichinter') {
756 require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinter.class.php';
757 $object = new Fichinter($this->db);
758 } elseif ($modulepart == 'adherent' || $modulepart == 'member') {
759 $modulepart = 'adherent';
760 require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
761 $object = new Adherent($this->db);
762 } elseif ($modulepart == 'proposal' || $modulepart == 'propal' || $modulepart == 'propale') {
763 $modulepart = 'propale';
764 require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
765 $object = new Propal($this->db);
766 } elseif ($modulepart == 'agenda' || $modulepart == 'action' || $modulepart == 'event') {
767 $modulepart = 'agenda';
768 require_once DOL_DOCUMENT_ROOT . '/comm/action/class/actioncomm.class.php';
769 $object = new ActionComm($this->db);
770 } elseif ($modulepart == 'contact' || $modulepart == 'socpeople') {
771 $modulepart = 'contact';
772 require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
773 $object = new Contact($this->db);
774 $fetchbyid = true;
775 } elseif ($modulepart == 'contrat' || $modulepart == 'contract') {
776 $modulepart = 'contrat';
777 require_once DOL_DOCUMENT_ROOT . '/contrat/class/contrat.class.php';
778 $object = new Contrat($this->db);
779 } elseif ($modulepart == 'mrp') {
780 $modulepart = 'mrp';
781 require_once DOL_DOCUMENT_ROOT . '/mrp/class/mo.class.php';
782 $object = new Mo($this->db);
783 } else {
784 // TODO Implement additional moduleparts
785 throw new RestException(500, 'Modulepart '.$modulepart.' not implemented yet.');
786 }
787
788 if (is_object($object)) {
789 if ($fetchbyid) {
790 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
791 $result = $object->fetch($ref);
792 } else {
793 $result = $object->fetch('', $ref);
794 }
795
796 if ($result == 0) {
797 throw new RestException(404, "Object with ref '".$ref."' was not found.");
798 } elseif ($result < 0) {
799 throw new RestException(500, 'Error while fetching object: '.$object->error);
800 }
801 }
802
803 if (!($object->id > 0)) {
804 throw new RestException(404, 'The object '.$modulepart." with ref '".$ref."' was not found.");
805 }
806
807 // Special cases that need to use get_exdir to get real dir of object
808 // In future, all object should use this to define path of documents.
809 if ($modulepart == 'supplier_invoice') {
810 $tmpreldir = get_exdir($object->id, 2, 0, 0, $object, 'invoice_supplier');
811 }
812
813 // Test on permissions
814 if ($modulepart != 'ecm') {
815 $relativefile = $tmpreldir.dol_sanitizeFileName($object->ref);
816 $tmp = dol_check_secure_access_document($modulepart, $relativefile, $entity, DolibarrApiAccess::$user, $ref, 'write');
817 $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
818 } else {
819 if (!DolibarrApiAccess::$user->hasRight('ecm', 'upload')) {
820 throw new RestException(403, 'Missing permission to upload files in ECM module');
821 }
822 $upload_dir = $conf->medias->multidir_output[$conf->entity];
823 }
824
825 if (empty($upload_dir) || $upload_dir == '/') {
826 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.');
827 }
828 } else {
829 if ($modulepart == 'invoice') {
830 $modulepart = 'facture';
831 }
832 if ($modulepart == 'member') {
833 $modulepart = 'adherent';
834 }
835
836 // Test on permissions
837 if ($modulepart != 'ecm') {
838 $relativefile = $subdir;
839 $tmp = dol_check_secure_access_document($modulepart, $relativefile, $entity, DolibarrApiAccess::$user, '', 'write');
840 $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
841 } else {
842 if (!DolibarrApiAccess::$user->hasRight('ecm', 'upload')) {
843 throw new RestException(403, 'Missing permission to upload files in ECM module');
844 }
845 $upload_dir = $conf->medias->multidir_output[$conf->entity];
846 }
847
848 if (empty($upload_dir) || $upload_dir == '/') {
849 if (!empty($tmp['error'])) {
850 throw new RestException(403, 'Error returned by dol_check_secure_access_document: '.$tmp['error']);
851 } else {
852 throw new RestException(400, 'This value of modulepart ('.$modulepart.') is not allowed with this value of subdir ('.$relativefile.')');
853 }
854 }
855 }
856 // $original_file here is still value of filename without any dir.
857
858 $upload_dir = dol_sanitizePathName($upload_dir);
859
860 if (!empty($createdirifnotexists)) {
861 if (dol_mkdir($upload_dir) < 0) { // needed by products
862 throw new RestException(500, 'Error while trying to create directory '.$upload_dir);
863 }
864 }
865
866 $destfile = $upload_dir.'/'.$original_file;
867 $destfiletmp = DOL_DATA_ROOT.'/admin/temp/'.$original_file;
868 dol_delete_file($destfiletmp);
869 //var_dump($original_file);exit;
870
871 if (!dol_is_dir(dirname($destfile))) {
872 throw new RestException(400, 'Directory does not exists : '.dirname($destfile));
873 }
874
875 if (!$overwriteifexists && dol_is_file($destfile)) {
876 throw new RestException(400, "File with name '".$original_file."' already exists.");
877 }
878
879 // in case temporary directory admin/temp doesn't exist
880 if (!dol_is_dir(dirname($destfiletmp))) {
881 dol_mkdir(dirname($destfiletmp));
882 }
883
884 $fhandle = @fopen($destfiletmp, 'w');
885 if ($fhandle) {
886 $nbofbyteswrote = fwrite($fhandle, $newfilecontent);
887 fclose($fhandle);
888 dolChmod($destfiletmp);
889 } else {
890 throw new RestException(500, "Failed to open file '".$destfiletmp."' for write");
891 }
892
893 $disablevirusscan = 0;
894 $src_file = $destfiletmp;
895 $dest_file = $destfile;
896
897 // Security:
898 // If we need to make a virus scan
899 if (empty($disablevirusscan) && file_exists($src_file)) {
900 $checkvirusarray = dolCheckVirus($src_file, $dest_file);
901 if (count($checkvirusarray)) {
902 dol_syslog('Files.lib::dol_move_uploaded_file File "'.$src_file.'" (target name "'.$dest_file.'") KO with antivirus: errors='.implode(',', $checkvirusarray), LOG_WARNING);
903 throw new RestException(500, 'ErrorFileIsInfectedWithAVirus: '.implode(',', $checkvirusarray));
904 }
905 }
906
907 // Security:
908 // Disallow file with some extensions. We rename them.
909 // Because if we put the documents directory into a directory inside web root (very bad), this allows to execute on demand arbitrary code.
910 if (isAFileWithExecutableContent($dest_file) && !getDolGlobalString('MAIN_DOCUMENT_IS_OUTSIDE_WEBROOT_SO_NOEXE_NOT_REQUIRED')) {
911 // $upload_dir ends with a slash, so be must be sure the medias dir to compare to ends with slash too.
912 $publicmediasdirwithslash = $conf->medias->multidir_output[$conf->entity];
913 if (!preg_match('/\/$/', $publicmediasdirwithslash)) {
914 $publicmediasdirwithslash .= '/';
915 }
916
917 if (strpos($upload_dir, $publicmediasdirwithslash) !== 0 || !getDolGlobalInt("MAIN_DOCUMENT_DISABLE_NOEXE_IN_MEDIAS_DIR")) { // We never add .noexe on files into media directory
918 $dest_file .= '.noexe';
919 }
920 }
921
922 // Security:
923 // We refuse cache files/dirs, upload using .. and pipes into filenames.
924 if (preg_match('/^\./', basename($src_file)) || preg_match('/\.\./', $src_file) || preg_match('/[<>|]/', $src_file)) {
925 dol_syslog("Refused to deliver file ".$src_file, LOG_WARNING);
926 throw new RestException(500, "Refused to deliver file ".$src_file);
927 }
928
929 // Security:
930 // We refuse cache files/dirs, upload using .. and pipes into filenames.
931 if (preg_match('/^\./', basename($dest_file)) || preg_match('/\.\./', $dest_file) || preg_match('/[<>|]/', $dest_file)) {
932 dol_syslog("Refused to deliver file ".$dest_file, LOG_WARNING);
933 throw new RestException(500, "Refused to deliver file ".$dest_file);
934 }
935
936 $moreinfo = array('note_private' => 'File uploaded using API /documents from IP '.getUserRemoteIP());
937 if (!empty($object) && is_object($object) && $object->id > 0) {
938 $moreinfo['src_object_type'] = $object->table_element;
939 $moreinfo['src_object_id'] = $object->id;
940 }
941
942 // Move the temporary file at its final emplacement
943 $result = dol_move($destfiletmp, $dest_file, 0, $overwriteifexists, 1, 1, $moreinfo);
944 if (!$result) {
945 throw new RestException(500, "Failed to move file into '".$destfile."'");
946 }
947
948 return dol_basename($destfile);
949 }
950
966 public function delete($modulepart, $original_file)
967 {
968 global $conf, $langs;
969
970 if (empty($modulepart)) {
971 throw new RestException(400, 'bad value for parameter modulepart');
972 }
973 if (empty($original_file)) {
974 throw new RestException(400, 'bad value for parameter original_file');
975 }
976
977 //--- Finds and returns the document
978 $entity = $conf->entity;
979
980 // Special cases that need to use get_exdir to get real dir of object
981 // If future, all object should use this to define path of documents.
982 /*
983 $tmpreldir = '';
984 if ($modulepart == 'supplier_invoice') {
985 $tmpreldir = get_exdir($object->id, 2, 0, 0, $object, 'invoice_supplier');
986 }
987
988 $relativefile = $tmpreldir.dol_sanitizeFileName($object->ref); */
989 $relativefile = $original_file;
990
991 $check_access = dol_check_secure_access_document($modulepart, $relativefile, $entity, DolibarrApiAccess::$user, '', 'read');
992 $accessallowed = $check_access['accessallowed'];
993 $sqlprotectagainstexternals = $check_access['sqlprotectagainstexternals'];
994 $original_file = $check_access['original_file'];
995
996 if (preg_match('/\.\./', $original_file) || preg_match('/[<>|]/', $original_file)) {
997 throw new RestException(403);
998 }
999 if (!$accessallowed) {
1000 throw new RestException(403);
1001 }
1002
1003 $filename = basename($original_file);
1004 $original_file_osencoded = dol_osencode($original_file); // New file name encoded in OS encoding charset
1005
1006 if (!file_exists($original_file_osencoded)) {
1007 dol_syslog("Try to download not found file ".$original_file_osencoded, LOG_WARNING);
1008 throw new RestException(404, 'File not found');
1009 }
1010
1011 if (@unlink($original_file_osencoded)) {
1012 return array(
1013 'success' => array(
1014 'code' => 200,
1015 'message' => 'Document deleted'
1016 )
1017 );
1018 }
1019
1020 throw new RestException(403);
1021 }
1022}
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:58
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.
Class to manage contracts.
API class for receive files.
post($filename, $modulepart, $ref='', $subdir='', $filecontent='', $fileencoding='', $overwriteifexists=0, $createdirifnotexists=1)
Return a document.
__construct()
Constructor.
index($modulepart, $original_file='')
Download a document.
getDocumentsListByElement($modulepart, $id=0, $ref='', $sortfield='', $sortorder='')
Return the list of documents of a dedicated element (from its ID or Ref)
builddoc($modulepart, $original_file='', $doctemplate='', $langcode='')
Build a document.
Class for API REST v1.
Definition api.class.php:30
Class to manage ECM files.
Class to manage shipments.
Class to manage Trips and Expenses.
Class to manage suppliers invoices.
Class to manage invoices.
Class to manage interventions.
Class for KnowledgeRecord.
Class for Mo.
Definition mo.class.php:36
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_basename($pathfile)
Make a basename working with all page code (default PHP basenamed fails with cyrillic).
Definition files.lib.php:38
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_move($srcfile, $destfile, $newmask='0', $overwriteifexists=1, $testvirus=0, $indexdatabase=1, $moreinfo=array())
Move a file into another name.
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:63
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.
dolChmod($filepath, $newmask='')
Change mod of a file.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
isAFileWithExecutableContent($filename)
Return if a file can contains executable content.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
getUserRemoteIP()
Return the IP of remote user.
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_sanitizePathName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a path name.
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)