dolibarr 21.0.0-alpha
html.formfile.class.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2008-2013 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2010-2014 Regis Houssin <regis.houssin@inodbox.com>
4 * Copyright (C) 2010-2016 Juanjo Menent <jmenent@2byte.es>
5 * Copyright (C) 2013 Charles-Fr BENKE <charles.fr@benke.fr>
6 * Copyright (C) 2013 Cédric Salvador <csalvador@gpcsolutions.fr>
7 * Copyright (C) 2014 Marcos García <marcosgdf@gmail.com>
8 * Copyright (C) 2015 Bahfir Abbes <bafbes@gmail.com>
9 * Copyright (C) 2016-2017 Ferran Marcet <fmarcet@2byte.es>
10 * Copyright (C) 2019-2024 Frédéric France <frederic.france@free.fr>
11 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 3 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program. If not, see <https://www.gnu.org/licenses/>.
25 */
26
38{
42 private $db;
43
47 public $error;
48
52 public $numoffiles;
56 public $infofiles;
57
58
64 public function __construct($db)
65 {
66 $this->db = $db;
67 $this->numoffiles = 0;
68 }
69
70
71 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
96 public function form_attach_new_file($url, $title = '', $addcancel = 0, $sectionid = 0, $perm = 1, $size = 50, $object = null, $options = '', $useajax = 1, $savingdocmask = '', $linkfiles = 1, $htmlname = 'formuserfile', $accept = '', $sectiondir = '', $usewithoutform = 0, $capture = 0, $disablemulti = 0, $nooutput = 0)
97 {
98 // phpcs:enable
99 global $conf, $langs, $hookmanager;
100 $hookmanager->initHooks(array('formfile'));
101
102 // Deprecation warning
103 if ($useajax == 2) {
104 dol_syslog(__METHOD__.": using 2 for useajax is deprecated and should be not used", LOG_WARNING);
105 }
106
107 if (!empty($conf->browser->layout) && $conf->browser->layout != 'classic') {
108 $useajax = 0;
109 }
110
111 //If there is no permission and the option to hide unauthorized actions is enabled, then nothing is printed
112 if (!$perm && getDolGlobalString('MAIN_BUTTON_HIDE_UNAUTHORIZED')) {
113 if ($nooutput) {
114 return '';
115 } else {
116 return 1;
117 }
118 }
119
120 // Section to generate the form to upload a new file
121 $out = "\n".'<!-- Start form attach new file --><div class="formattachnewfile">'."\n";
122
123 if ($nooutput != 2) {
124 if (empty($title)) {
125 $title = $langs->trans("AttachANewFile");
126 }
127 if ($title != 'none') {
128 $out .= load_fiche_titre($title, '', '');
129 }
130 }
131
132 if (empty($usewithoutform)) { // Try to avoid this and set instead the form by the caller.
133 // Add a param as GET parameter to detect when POST were cleaned by PHP because a file larger than post_max_size
134 $url .= (strpos($url, '?') === false ? '?' : '&').'uploadform=1';
135
136 $out .= '<form name="'.$htmlname.'" id="'.$htmlname.'" action="'.$url.'" enctype="multipart/form-data" method="POST">'."\n";
137 }
138 if (empty($usewithoutform) || $usewithoutform == 2) {
139 $out .= '<input type="hidden" name="token" value="'.newToken().'">'."\n";
140 $out .= '<input type="hidden" id="'.$htmlname.'_section_dir" name="section_dir" value="'.$sectiondir.'">'."\n";
141 $out .= '<input type="hidden" id="'.$htmlname.'_section_id" name="section_id" value="'.$sectionid.'">'."\n";
142 $out .= '<input type="hidden" name="sortfield" value="'.GETPOST('sortfield', 'aZ09comma').'">'."\n";
143 $out .= '<input type="hidden" name="sortorder" value="'.GETPOST('sortorder', 'aZ09comma').'">'."\n";
144 $out .= '<input type="hidden" name="page_y" value="">'."\n";
145 }
146
147 $out .= '<table class="nobordernopadding centpercent">';
148 $out .= '<tr>';
149
150 if (!empty($options)) {
151 $out .= '<td>'.$options.'</td>';
152 }
153
154 $out .= '<td class="valignmiddle nowrap">';
155
156 $maxfilesizearray = getMaxFileSizeArray();
157 $max = $maxfilesizearray['max'];
158 $maxmin = $maxfilesizearray['maxmin'];
159 $maxphptoshow = $maxfilesizearray['maxphptoshow'];
160 $maxphptoshowparam = $maxfilesizearray['maxphptoshowparam'];
161 if ($maxmin > 0) {
162 $out .= '<input type="hidden" name="MAX_FILE_SIZE" value="'.($maxmin * 1024).'">'; // MAX_FILE_SIZE must precede the field type=file
163 }
164 $out .= '<input class="flat minwidth400 maxwidth200onsmartphone" type="file"';
165 $out .= ((getDolGlobalString('MAIN_DISABLE_MULTIPLE_FILEUPLOAD') || $disablemulti) ? ' name="userfile"' : ' name="userfile[]" multiple');
166 $out .= (!getDolGlobalString('MAIN_UPLOAD_DOC') || empty($perm) ? ' disabled' : '');
167 $out .= (!empty($accept) ? ' accept="'.$accept.'"' : ' accept=""');
168 $out .= (!empty($capture) ? ' capture="capture"' : '');
169 $out .= '>';
170 $out .= ' ';
171 if ($sectionid) { // Show overwrite if exists for ECM module only
172 $langs->load('link');
173 $out .= '<span class="nowraponsmartphone"><input style="margin-right: 2px;" type="checkbox" id="overwritefile" name="overwritefile" value="1">';
174 $out .= '<label for="overwritefile" class="opacitylow paddingright">'.$langs->trans("OverwriteIfExists").'</label>';
175 $out .= '</span>';
176 }
177 $out .= '<input type="submit" class="button small reposition" name="sendit" value="'.$langs->trans("Upload").'"';
178 $out .= (!getDolGlobalString('MAIN_UPLOAD_DOC') || empty($perm) ? ' disabled' : '');
179 $out .= '>';
180
181 if ($addcancel) {
182 $out .= ' &nbsp; ';
183 $out .= '<input type="submit" class="button small button-cancel" name="cancel" value="'.$langs->trans("Cancel").'">';
184 }
185
186 if (getDolGlobalString('MAIN_UPLOAD_DOC')) {
187 if ($perm) {
188 $menudolibarrsetupmax = $langs->transnoentitiesnoconv("Home").' - '.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("Security");
189 $langs->load('other');
190 $out .= ' ';
191 $out .= info_admin($langs->trans("ThisLimitIsDefinedInSetupAt", $menudolibarrsetupmax, $max, $maxphptoshowparam, $maxphptoshow), 1, 0, '1', 'classfortooltip');
192 }
193 } else {
194 $out .= ' ('.$langs->trans("UploadDisabled").')';
195 }
196 $out .= "</td></tr>";
197
198 if ($savingdocmask) {
199 //add a global variable for disable the auto renaming on upload
200 $rename = (!getDolGlobalString('MAIN_DOC_UPLOAD_NOT_RENAME_BY_DEFAULT') ? 'checked' : '');
201
202 $out .= '<tr>';
203 if (!empty($options)) {
204 $out .= '<td>'.$options.'</td>';
205 }
206 $out .= '<td valign="middle" class="nowrap">';
207 $out .= '<input type="checkbox" '.$rename.' class="savingdocmask" name="savingdocmask" id="savingdocmask" value="'.dol_escape_js($savingdocmask).'"> ';
208 $out .= '<label class="opacitymedium small" for="savingdocmask">';
209 $out .= $langs->trans("SaveUploadedFileWithMask", preg_replace('/__file__/', $langs->transnoentitiesnoconv("OriginFileName"), $savingdocmask), $langs->transnoentitiesnoconv("OriginFileName"));
210 $out .= '</label>';
211 $out .= '</td>';
212 $out .= '</tr>';
213 }
214
215 $out .= "</table>";
216
217 if (empty($usewithoutform)) {
218 $out .= '</form>';
219 if (empty($sectionid)) {
220 $out .= '<br>';
221 }
222 }
223
224 $parameters = array('socid' => (isset($GLOBALS['socid']) ? $GLOBALS['socid'] : ''), 'id' => (isset($GLOBALS['id']) ? $GLOBALS['id'] : ''), 'url' => $url, 'perm' => $perm, 'options' => $options);
225 $res = $hookmanager->executeHooks('formattachOptionsUpload', $parameters, $object);
226 if (empty($res)) {
227 $out = '<div class="'.($usewithoutform ? 'inline-block valignmiddle' : (($nooutput == 2 ? '' : 'attacharea ').'attacharea'.$htmlname)).'">'.$out.'</div>';
228 }
229 $out .= $hookmanager->resPrint;
230
231 $out .= "\n</div><!-- End form class=formattachnewfile -->\n";
232
233
234 $out2 = "";
235
236 // Section to generate the form to upload a new file
237 if ($linkfiles) {
238 $out2 .= "\n".'<!-- Start form link new url --><div class="formlinknewurl">'."\n";
239 $langs->load('link');
240
241 if ($nooutput != 2) {
242 $title = $langs->trans("LinkANewFile");
243 $out2 .= load_fiche_titre($title, '', '');
244 }
245
246 if (empty($usewithoutform)) {
247 $out2 .= '<form name="'.$htmlname.'_link" id="'.$htmlname.'_link" action="'.$url.'" method="POST">'."\n";
248 $out2 .= '<input type="hidden" name="token" value="'.newToken().'">'."\n";
249 $out2 .= '<input type="hidden" id="'.$htmlname.'_link_section_dir" name="link_section_dir" value="">'."\n";
250 $out2 .= '<input type="hidden" id="'.$htmlname.'_link_section_id" name="link_section_id" value="'.$sectionid.'">'."\n";
251 $out2 .= '<input type="hidden" name="page_y" value="">'."\n";
252 }
253
254 $out2 .= '<div class="valignmiddle">';
255 $out2 .= '<div class="inline-block" style="padding-right: 10px;">';
256 if (getDolGlobalString('OPTIMIZEFORTEXTBROWSER')) {
257 $out2 .= '<label for="link">'.$langs->trans("URLToLink").':</label> ';
258 }
259 $out2 .= '<input type="text" name="link" class="flat minwidth400imp" id="link" placeholder="'.dol_escape_htmltag($langs->trans("URLToLink")).'">';
260 $out2 .= '</div>';
261 $out2 .= '<div class="inline-block" style="padding-right: 10px;">';
262 if (getDolGlobalString('OPTIMIZEFORTEXTBROWSER')) {
263 $out2 .= '<label for="label">'.$langs->trans("Label").':</label> ';
264 }
265 $out2 .= '<input type="text" class="flat" name="label" id="label" placeholder="'.dol_escape_htmltag($langs->trans("Label")).'">';
266 $out2 .= '<input type="hidden" name="objecttype" value="'.$object->element.'">';
267 $out2 .= '<input type="hidden" name="objectid" value="'.$object->id.'">';
268 $out2 .= '</div>';
269 $out2 .= '<div class="inline-block" style="padding-right: 10px;">';
270 $out2 .= '<input type="submit" class="button small reposition" name="linkit" value="'.$langs->trans("ToLink").'"';
271 $out2 .= (!getDolGlobalString('MAIN_UPLOAD_DOC') || empty($perm) ? ' disabled' : '');
272 $out2 .= '>';
273 $out2 .= '</div>';
274 $out2 .= '</div>';
275 if (empty($usewithoutform)) {
276 $out2 .= '<div class="clearboth"></div>';
277 $out2 .= '</form><br>';
278 }
279
280 $parameters = array('socid' => (isset($GLOBALS['socid']) ? $GLOBALS['socid'] : ''), 'id' => (isset($GLOBALS['id']) ? $GLOBALS['id'] : ''), 'url' => $url, 'perm' => $perm, 'options' => $options);
281 $res = $hookmanager->executeHooks('formattachOptions', $parameters, $object);
282 if (empty($res)) {
283 $out2 = '<div class="'.($usewithoutform ? 'inline-block valignmiddle' : (($nooutput == 2 ? '' : 'attacharea ').$htmlname)).'">'.$out2.'</div>';
284 }
285 $out2 .= $hookmanager->resPrint;
286
287 $out2 .= "\n</div><!-- End form class=formlinknewurl -->\n";
288 }
289
290
291 if ($nooutput == 2) {
292 return array('formToUploadAFile' => $out, 'formToAddALink' => $out2);
293 } elseif ($nooutput) {
294 return $out.$out2;
295 } else {
296 print $out.$out2;
297 return 1;
298 }
299 }
300
301 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
324 public function show_documents($modulepart, $modulesubdir, $filedir, $urlsource, $genallowed, $delallowed = 0, $modelselected = '', $allowgenifempty = 1, $forcenomultilang = 0, $iconPDF = 0, $notused = 0, $noform = 0, $param = '', $title = '', $buttonlabel = '', $codelang = '')
325 {
326 // phpcs:enable
327 $this->numoffiles = 0;
328 print $this->showdocuments($modulepart, $modulesubdir, $filedir, $urlsource, $genallowed, $delallowed, $modelselected, $allowgenifempty, $forcenomultilang, $iconPDF, $notused, $noform, $param, $title, $buttonlabel, $codelang);
329 return $this->numoffiles;
330 }
331
359 public function showdocuments($modulepart, $modulesubdir, $filedir, $urlsource, $genallowed, $delallowed = 0, $modelselected = '', $allowgenifempty = 1, $forcenomultilang = 0, $iconPDF = 0, $notused = 0, $noform = 0, $param = '', $title = '', $buttonlabel = '', $codelang = '', $morepicto = '', $object = null, $hideifempty = 0, $removeaction = 'remove_file', $tooltipontemplatecombo = '')
360 {
361 global $dolibarr_main_url_root;
362
363 // Deprecation warning
364 if (!empty($iconPDF)) {
365 dol_syslog(__METHOD__.": passing iconPDF parameter is deprecated", LOG_WARNING);
366 }
367
368 global $langs, $conf, $user, $hookmanager;
369 global $form;
370
371 $reshook = 0;
372 if (is_object($hookmanager)) {
373 $parameters = array(
374 'modulepart' => &$modulepart,
375 'modulesubdir' => &$modulesubdir,
376 'filedir' => &$filedir,
377 'urlsource' => &$urlsource,
378 'genallowed' => &$genallowed,
379 'delallowed' => &$delallowed,
380 'modelselected' => &$modelselected,
381 'allowgenifempty' => &$allowgenifempty,
382 'forcenomultilang' => &$forcenomultilang,
383 'noform' => &$noform,
384 'param' => &$param,
385 'title' => &$title,
386 'buttonlabel' => &$buttonlabel,
387 'codelang' => &$codelang,
388 'morepicto' => &$morepicto,
389 'hideifempty' => &$hideifempty,
390 'removeaction' => &$removeaction
391 );
392 $reshook = $hookmanager->executeHooks('showDocuments', $parameters, $object); // Note that parameters may have been updated by hook
393 // May report error
394 if ($reshook < 0) {
395 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
396 }
397 }
398 // Remode default action if $reskook > 0
399 if ($reshook > 0) {
400 return $hookmanager->resPrint;
401 }
402
403 if (!is_object($form)) {
404 $form = new Form($this->db);
405 }
406
407 include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
408
409 // For backward compatibility
410 if (!empty($iconPDF)) {
411 return $this->getDocumentsLink($modulepart, $modulesubdir, $filedir);
412 }
413
414 // Add entity in $param if not already exists
415 if (!preg_match('/entity\=[0-9]+/', $param)) {
416 $param .= ($param ? '&' : '').'entity='.(empty($object->entity) ? $conf->entity : $object->entity);
417 }
418
419 $printer = 0;
420 // The direct print feature is implemented only for such elements
421 if (in_array($modulepart, array('contract', 'facture', 'supplier_proposal', 'propal', 'proposal', 'order', 'commande', 'expedition', 'commande_fournisseur', 'expensereport', 'delivery', 'ticket'))) {
422 $printer = ($user->hasRight('printing', 'read') && !empty($conf->printing->enabled));
423 }
424
425 $hookmanager->initHooks(array('formfile'));
426
427 // Get list of files
428 $file_list = array();
429 if (!empty($filedir)) {
430 $file_list = dol_dir_list($filedir, 'files', 0, '', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC);
431 }
432 if ($hideifempty && empty($file_list)) {
433 return '';
434 }
435
436 $out = '';
437 $forname = 'builddoc';
438 $headershown = 0;
439 $showempty = 0;
440 $i = 0;
441
442 $out .= "\n".'<!-- Start show_document -->'."\n";
443 //print 'filedir='.$filedir;
444
445 if (preg_match('/massfilesarea_/', $modulepart)) {
446 $out .= '<div id="show_files"><br></div>'."\n";
447 $title = $langs->trans("MassFilesArea").' <a href="" id="togglemassfilesarea" ref="shown">('.$langs->trans("Hide").')</a>';
448 $title .= '<script nonce="'.getNonce().'">
449 jQuery(document).ready(function() {
450 jQuery(\'#togglemassfilesarea\').click(function() {
451 if (jQuery(\'#togglemassfilesarea\').attr(\'ref\') == "shown")
452 {
453 jQuery(\'#'.$modulepart.'_table\').hide();
454 jQuery(\'#togglemassfilesarea\').attr("ref", "hidden");
455 jQuery(\'#togglemassfilesarea\').text("('.dol_escape_js($langs->trans("Show")).')");
456 }
457 else
458 {
459 jQuery(\'#'.$modulepart.'_table\').show();
460 jQuery(\'#togglemassfilesarea\').attr("ref","shown");
461 jQuery(\'#togglemassfilesarea\').text("('.dol_escape_js($langs->trans("Hide")).')");
462 }
463 return false;
464 });
465 });
466 </script>';
467 }
468
469 $titletoshow = $langs->trans("Documents");
470 if (!empty($title)) {
471 $titletoshow = ($title == 'none' ? '' : $title);
472 }
473
474 $submodulepart = $modulepart;
475
476 // modulepart = 'nameofmodule' or 'nameofmodule:NameOfObject'
477 $tmp = explode(':', $modulepart);
478 if (!empty($tmp[1])) {
479 $modulepart = $tmp[0];
480 $submodulepart = $tmp[1];
481 }
482
483 $addcolumforpicto = ($delallowed || $printer || $morepicto);
484 $colspan = (4 + ($addcolumforpicto ? 1 : 0));
485 $colspanmore = 0;
486
487 // Show table
488 if ($genallowed) {
489 $modellist = array();
490
491 if ($modulepart == 'company') {
492 $showempty = 1; // can have no template active
493 if (is_array($genallowed)) {
494 $modellist = $genallowed;
495 } else {
496 include_once DOL_DOCUMENT_ROOT.'/core/modules/societe/modules_societe.class.php';
497 $modellist = ModeleThirdPartyDoc::liste_modeles($this->db);
498 }
499 } elseif ($modulepart == 'propal') {
500 if (is_array($genallowed)) {
501 $modellist = $genallowed;
502 } else {
503 include_once DOL_DOCUMENT_ROOT.'/core/modules/propale/modules_propale.php';
504 $modellist = ModelePDFPropales::liste_modeles($this->db);
505 }
506 } elseif ($modulepart == 'supplier_proposal') {
507 if (is_array($genallowed)) {
508 $modellist = $genallowed;
509 } else {
510 include_once DOL_DOCUMENT_ROOT.'/core/modules/supplier_proposal/modules_supplier_proposal.php';
511 $modellist = ModelePDFSupplierProposal::liste_modeles($this->db);
512 }
513 } elseif ($modulepart == 'commande') {
514 if (is_array($genallowed)) {
515 $modellist = $genallowed;
516 } else {
517 include_once DOL_DOCUMENT_ROOT.'/core/modules/commande/modules_commande.php';
518 $modellist = ModelePDFCommandes::liste_modeles($this->db);
519 }
520 } elseif ($modulepart == 'expedition') {
521 if (is_array($genallowed)) {
522 $modellist = $genallowed;
523 } else {
524 include_once DOL_DOCUMENT_ROOT.'/core/modules/expedition/modules_expedition.php';
525 $modellist = ModelePdfExpedition::liste_modeles($this->db);
526 }
527 } elseif ($modulepart == 'reception') {
528 if (is_array($genallowed)) {
529 $modellist = $genallowed;
530 } else {
531 include_once DOL_DOCUMENT_ROOT.'/core/modules/reception/modules_reception.php';
532 $modellist = ModelePdfReception::liste_modeles($this->db);
533 }
534 } elseif ($modulepart == 'delivery') {
535 if (is_array($genallowed)) {
536 $modellist = $genallowed;
537 } else {
538 include_once DOL_DOCUMENT_ROOT.'/core/modules/delivery/modules_delivery.php';
539 $modellist = ModelePDFDeliveryOrder::liste_modeles($this->db);
540 }
541 } elseif ($modulepart == 'ficheinter') {
542 if (is_array($genallowed)) {
543 $modellist = $genallowed;
544 } else {
545 include_once DOL_DOCUMENT_ROOT.'/core/modules/fichinter/modules_fichinter.php';
546 $modellist = ModelePDFFicheinter::liste_modeles($this->db);
547 }
548 } elseif ($modulepart == 'facture') {
549 if (is_array($genallowed)) {
550 $modellist = $genallowed;
551 } else {
552 include_once DOL_DOCUMENT_ROOT.'/core/modules/facture/modules_facture.php';
553 $modellist = ModelePDFFactures::liste_modeles($this->db);
554 }
555 } elseif ($modulepart == 'contract') {
556 $showempty = 1; // can have no template active
557 if (is_array($genallowed)) {
558 $modellist = $genallowed;
559 } else {
560 include_once DOL_DOCUMENT_ROOT.'/core/modules/contract/modules_contract.php';
561 $modellist = ModelePDFContract::liste_modeles($this->db);
562 }
563 } elseif ($modulepart == 'project') {
564 if (is_array($genallowed)) {
565 $modellist = $genallowed;
566 } else {
567 include_once DOL_DOCUMENT_ROOT.'/core/modules/project/modules_project.php';
568 $modellist = ModelePDFProjects::liste_modeles($this->db);
569 }
570 } elseif ($modulepart == 'project_task') {
571 if (is_array($genallowed)) {
572 $modellist = $genallowed;
573 } else {
574 include_once DOL_DOCUMENT_ROOT.'/core/modules/project/task/modules_task.php';
575 $modellist = ModelePDFTask::liste_modeles($this->db);
576 }
577 } elseif ($modulepart == 'product') {
578 if (is_array($genallowed)) {
579 $modellist = $genallowed;
580 } else {
581 include_once DOL_DOCUMENT_ROOT.'/core/modules/product/modules_product.class.php';
582 $modellist = ModelePDFProduct::liste_modeles($this->db);
583 }
584 } elseif ($modulepart == 'product_batch') {
585 if (is_array($genallowed)) {
586 $modellist = $genallowed;
587 } else {
588 include_once DOL_DOCUMENT_ROOT.'/core/modules/product_batch/modules_product_batch.class.php';
589 $modellist = ModelePDFProductBatch::liste_modeles($this->db);
590 }
591 } elseif ($modulepart == 'stock') {
592 if (is_array($genallowed)) {
593 $modellist = $genallowed;
594 } else {
595 include_once DOL_DOCUMENT_ROOT.'/core/modules/stock/modules_stock.php';
596 $modellist = ModelePDFStock::liste_modeles($this->db);
597 }
598 } elseif ($modulepart == 'hrm') {
599 if (is_array($genallowed)) {
600 $modellist = $genallowed;
601 } else {
602 include_once DOL_DOCUMENT_ROOT.'/core/modules/hrm/modules_evaluation.php';
603 $modellist = ModelePDFEvaluation::liste_modeles($this->db);
604 }
605 } elseif ($modulepart == 'movement') {
606 if (is_array($genallowed)) {
607 $modellist = $genallowed;
608 } else {
609 include_once DOL_DOCUMENT_ROOT.'/core/modules/stock/modules_movement.php';
610 $modellist = ModelePDFMovement::liste_modeles($this->db);
611 }
612 } elseif ($modulepart == 'export') {
613 if (is_array($genallowed)) {
614 $modellist = $genallowed;
615 } else {
616 include_once DOL_DOCUMENT_ROOT.'/core/modules/export/modules_export.php';
617 //$modellist = ModeleExports::liste_modeles($this->db); // liste_modeles() does not exists. We are using listOfAvailableExportFormat() method instead that return a different array format.
618 $modellist = array();
619 }
620 } elseif ($modulepart == 'commande_fournisseur' || $modulepart == 'supplier_order') {
621 if (is_array($genallowed)) {
622 $modellist = $genallowed;
623 } else {
624 include_once DOL_DOCUMENT_ROOT.'/core/modules/supplier_order/modules_commandefournisseur.php';
625 $modellist = ModelePDFSuppliersOrders::liste_modeles($this->db);
626 }
627 } elseif ($modulepart == 'facture_fournisseur' || $modulepart == 'supplier_invoice') {
628 $showempty = 1; // can have no template active
629 if (is_array($genallowed)) {
630 $modellist = $genallowed;
631 } else {
632 include_once DOL_DOCUMENT_ROOT.'/core/modules/supplier_invoice/modules_facturefournisseur.php';
633 $modellist = ModelePDFSuppliersInvoices::liste_modeles($this->db);
634 }
635 } elseif ($modulepart == 'supplier_payment') {
636 if (is_array($genallowed)) {
637 $modellist = $genallowed;
638 } else {
639 include_once DOL_DOCUMENT_ROOT.'/core/modules/supplier_payment/modules_supplier_payment.php';
640 $modellist = ModelePDFSuppliersPayments::liste_modeles($this->db);
641 }
642 } elseif ($modulepart == 'remisecheque') {
643 if (is_array($genallowed)) {
644 $modellist = $genallowed;
645 } else {
646 include_once DOL_DOCUMENT_ROOT.'/core/modules/cheque/modules_chequereceipts.php';
647 $modellist = ModeleChequeReceipts::liste_modeles($this->db);
648 }
649 } elseif ($modulepart == 'donation') {
650 if (is_array($genallowed)) {
651 $modellist = $genallowed;
652 } else {
653 include_once DOL_DOCUMENT_ROOT.'/core/modules/dons/modules_don.php';
654 $modellist = ModeleDon::liste_modeles($this->db);
655 }
656 } elseif ($modulepart == 'member') {
657 if (is_array($genallowed)) {
658 $modellist = $genallowed;
659 } else {
660 include_once DOL_DOCUMENT_ROOT.'/core/modules/member/modules_cards.php';
661 $modellist = ModelePDFCards::liste_modeles($this->db);
662 }
663 } elseif ($modulepart == 'agenda' || $modulepart == 'actions') {
664 if (is_array($genallowed)) {
665 $modellist = $genallowed;
666 } else {
667 include_once DOL_DOCUMENT_ROOT.'/core/modules/action/modules_action.php';
668 $modellist = ModeleAction::liste_modeles($this->db);
669 }
670 } elseif ($modulepart == 'expensereport') {
671 if (is_array($genallowed)) {
672 $modellist = $genallowed;
673 } else {
674 include_once DOL_DOCUMENT_ROOT.'/core/modules/expensereport/modules_expensereport.php';
675 $modellist = ModeleExpenseReport::liste_modeles($this->db);
676 }
677 } elseif ($modulepart == 'unpaid') {
678 $modellist = '';
679 } elseif ($modulepart == 'user') {
680 if (is_array($genallowed)) {
681 $modellist = $genallowed;
682 } else {
683 include_once DOL_DOCUMENT_ROOT.'/core/modules/user/modules_user.class.php';
684 $modellist = ModelePDFUser::liste_modeles($this->db);
685 }
686 } elseif ($modulepart == 'usergroup') {
687 if (is_array($genallowed)) {
688 $modellist = $genallowed;
689 } else {
690 include_once DOL_DOCUMENT_ROOT.'/core/modules/usergroup/modules_usergroup.class.php';
691 $modellist = ModelePDFUserGroup::liste_modeles($this->db);
692 }
693 } else {
694 // For normalized standard modules
695 $file = dol_buildpath('/core/modules/'.$modulepart.'/modules_'.strtolower($submodulepart).'.php', 0);
696 if (file_exists($file)) {
697 $res = include_once $file;
698 } else {
699 // For normalized external modules.
700 $file = dol_buildpath('/'.$modulepart.'/core/modules/'.$modulepart.'/modules_'.strtolower($submodulepart).'.php', 0);
701 $res = include_once $file;
702 }
703
704 $class = 'ModelePDF'.ucfirst($submodulepart);
705
706 if (class_exists($class)) {
707 $modellist = call_user_func($class.'::liste_modeles', $this->db);
708 } else {
709 dol_print_error($this->db, "Bad value for modulepart '".$modulepart."' in showdocuments (class ".$class." for Doc generation not found)");
710 return -1;
711 }
712 }
713
714 // Set headershown to avoid to have table opened a second time later
715 $headershown = 1;
716
717 if (empty($buttonlabel)) {
718 $buttonlabel = $langs->trans('Generate');
719 }
720
721 if ($conf->browser->layout == 'phone') {
722 $urlsource .= '#'.$forname.'_form'; // So we switch to form after a generation
723 }
724 if (empty($noform)) {
725 $out .= '<form action="'.$urlsource.'" id="'.$forname.'_form" method="post">';
726 }
727 $out .= '<input type="hidden" name="action" value="builddoc">';
728 $out .= '<input type="hidden" name="page_y" value="">';
729 $out .= '<input type="hidden" name="token" value="'.newToken().'">';
730
731 $out .= load_fiche_titre($titletoshow, '', '');
732 $out .= '<div class="div-table-responsive-no-min">';
733 $out .= '<table class="liste formdoc noborder centpercent">';
734
735 $out .= '<tr class="liste_titre">';
736 $addcolumforpicto = ($delallowed || $printer || $morepicto);
737 $colspan = (4 + ($addcolumforpicto ? 1 : 0));
738 $colspanmore = 0;
739
740 $out .= '<th colspan="'.$colspan.'" class="formdoc liste_titre maxwidthonsmartphone center">';
741
742 // Model
743 if (!empty($modellist)) {
744 asort($modellist);
745 $out .= '<span class="hideonsmartphone">'.$langs->trans('Model').' </span>';
746 if (is_array($modellist) && count($modellist) == 1) { // If there is only one element
747 $arraykeys = array_keys($modellist);
748 $modelselected = $arraykeys[0];
749 }
750 $morecss = 'minwidth75 maxwidth200';
751 if ($conf->browser->layout == 'phone') {
752 $morecss = 'maxwidth100';
753 }
754 $out .= $form->selectarray('model', $modellist, $modelselected, $showempty, 0, 0, '', 0, 0, 0, '', $morecss, 1, '', 0, 0);
755 // script for select the separator
756 /* TODO This must appear on export feature only
757 $out .= '<label class="forhide" for="delimiter">Delimiter:</label>';
758 $out .= '<input type="radio" class="testinput forhide" name="delimiter" value="," id="comma" checked><label class="forhide" for="comma">,</label>';
759 $out .= '<input type="radio" class="testinput forhide" name="delimiter" value=";" id="semicolon"><label class="forhide" for="semicolon">;</label>';
760
761 $out .= '<script>
762 jQuery(document).ready(function() {
763 $(".selectformat").on("change", function() {
764 var separator;
765 var selected = $(this).val();
766 if (selected == "excel2007" || selected == "tsv") {
767 $("input.testinput").prop("disabled", true);
768 $(".forhide").hide();
769 } else {
770 $("input.testinput").prop("disabled", false);
771 $(".forhide").show();
772 }
773
774 if ($("#semicolon").is(":checked")) {
775 separator = ";";
776 } else {
777 separator = ",";
778 }
779 });
780 if ("' . $conf->global->EXPORT_CSV_SEPARATOR_TO_USE . '" == ";") {
781 $("#semicolon").prop("checked", true);
782 } else {
783 $("#comma").prop("checked", true);
784 }
785 });
786 </script>';
787 */
788 if ($conf->use_javascript_ajax) {
789 $out .= ajax_combobox('model');
790 }
791 $out .= $form->textwithpicto('', $tooltipontemplatecombo, 1, 'help', 'marginrightonly', 0, 3, '', 0);
792 } else {
793 $out .= '<div class="float">'.$langs->trans("Files").'</div>';
794 }
795
796 // Language code (if multilang)
797 if (($allowgenifempty || (is_array($modellist) && count($modellist) > 0)) && getDolGlobalInt('MAIN_MULTILANGS') && !$forcenomultilang && (!empty($modellist) || $showempty)) {
798 include_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
799 $formadmin = new FormAdmin($this->db);
800 $defaultlang = ($codelang && $codelang != 'auto') ? $codelang : $langs->getDefaultLang();
801 $morecss = 'maxwidth150';
802 if ($conf->browser->layout == 'phone') {
803 $morecss = 'maxwidth100';
804 }
805 $out .= $formadmin->select_language($defaultlang, 'lang_id', 0, array(), 0, 0, 0, $morecss);
806 } else {
807 $out .= '&nbsp;';
808 }
809
810 // Button
811 $genbutton = '<input class="button buttongen reposition nomargintop nomarginbottom" id="'.$forname.'_generatebutton" name="'.$forname.'_generatebutton"';
812 $genbutton .= ' type="submit" value="'.$buttonlabel.'"';
813 if (!$allowgenifempty && !is_array($modellist) && empty($modellist)) {
814 $genbutton .= ' disabled';
815 }
816 $genbutton .= '>';
817 if ($allowgenifempty && !is_array($modellist) && empty($modellist) && empty($conf->dol_no_mouse_hover) && $modulepart != 'unpaid') {
818 $langs->load("errors");
819 $genbutton .= ' '.img_warning($langs->transnoentitiesnoconv("WarningNoDocumentModelActivated"));
820 }
821 if (!$allowgenifempty && !is_array($modellist) && empty($modellist) && empty($conf->dol_no_mouse_hover) && $modulepart != 'unpaid') {
822 $genbutton = '';
823 }
824 if (empty($modellist) && !$showempty && $modulepart != 'unpaid') {
825 $genbutton = '';
826 }
827 $out .= $genbutton;
828 $out .= '</th>';
829
830 if (!empty($hookmanager->hooks['formfile'])) {
831 foreach ($hookmanager->hooks['formfile'] as $module) {
832 if (method_exists($module, 'formBuilddocLineOptions')) {
833 $colspanmore++;
834 $out .= '<th></th>';
835 }
836 }
837 }
838 $out .= '</tr>';
839
840 // Execute hooks
841 $parameters = array('colspan' => ($colspan + $colspanmore), 'socid' => (isset($GLOBALS['socid']) ? $GLOBALS['socid'] : ''), 'id' => (isset($GLOBALS['id']) ? $GLOBALS['id'] : ''), 'modulepart' => $modulepart);
842 if (is_object($hookmanager)) {
843 $reshook = $hookmanager->executeHooks('formBuilddocOptions', $parameters, $GLOBALS['object']);
844 $out .= $hookmanager->resPrint;
845 }
846 }
847
848 // Get list of files
849 if (!empty($filedir)) {
850 $link_list = array();
851 if (is_object($object)) {
852 require_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php';
853 $link = new Link($this->db);
854 $sortfield = $sortorder = '';
855 $res = $link->fetchAll($link_list, $object->element, $object->id, $sortfield, $sortorder);
856 }
857
858 $out .= '<!-- html.formfile::showdocuments -->'."\n";
859
860 // Show title of array if not already shown
861 if ((!empty($file_list) || !empty($link_list) || preg_match('/^massfilesarea/', $modulepart))
862 && !$headershown) {
863 $headershown = 1;
864 $out .= '<div class="titre">'.$titletoshow.'</div>'."\n";
865 $out .= '<div class="div-table-responsive-no-min">';
866 $out .= '<table class="noborder centpercent" id="'.$modulepart.'_table">'."\n";
867 }
868
869 // Loop on each file found
870 if (is_array($file_list)) {
871 '@phan-var-force array<array{name:string,path:string,level1name:string,relativename:string,fullname:string,date:string,size:int,perm:int,type:string}> $file_list'; // phan limitations loose typing information with empty() tests, etc. Force again.
872 // Defined relative dir to DOL_DATA_ROOT
873 $relativedir = '';
874 if ($filedir) {
875 $relativedir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT, '/').'/', '', $filedir);
876 $relativedir = preg_replace('/^[\\/]/', '', $relativedir);
877 }
878
879 // Get list of files stored into database for same relative directory
880 if ($relativedir) {
881 completeFileArrayWithDatabaseInfo($file_list, $relativedir);
882
883 //var_dump($sortfield.' - '.$sortorder);
884 if (!empty($sortfield) && !empty($sortorder)) { // If $sortfield is for example 'position_name', we will sort on the property 'position_name' (that is concat of position+name)
885 $file_list = dol_sort_array($file_list, $sortfield, $sortorder);
886 }
887 }
888
889 $i = 0;
890 foreach ($file_list as $file) {
891 $i++;
892
893 // Define relative path for download link (depends on module)
894 $relativepath = (string) $file["name"]; // Cas general
895 if ($modulesubdir) {
896 $relativepath = (string) $modulesubdir."/".$file["name"]; // Cas propal, facture...
897 }
898 if ($modulepart == 'export') {
899 $relativepath = (string) $file["name"]; // Other case
900 }
901
902 $out .= '<tr class="oddeven'.((!$genallowed && $i == 1) ? ' trfirstline' : '').'">';
903
904 $documenturl = DOL_URL_ROOT.'/document.php';
905 if (isset($conf->global->DOL_URL_ROOT_DOCUMENT_PHP)) {
906 $documenturl = getDolGlobalString('DOL_URL_ROOT_DOCUMENT_PHP'); // To use another wrapper
907 }
908
909 // Show file name with link to download
910 $imgpreview = $this->showPreview($file, $modulepart, $relativepath, 0, $param);
911
912 $out .= '<td class="minwidth200 tdoverflowmax300">';
913 if ($imgpreview) {
914 $out .= '<span class="spanoverflow widthcentpercentminusx valignmiddle">';
915 } else {
916 $out .= '<span class="spanoverflow">';
917 }
918 $out .= '<a class="documentdownload paddingright" ';
919 if (getDolGlobalInt('MAIN_DISABLE_FORCE_SAVEAS') == 2) {
920 $out .= 'target="_blank" ';
921 }
922 $out .= 'href="'.$documenturl.'?modulepart='.$modulepart.'&file='.urlencode($relativepath).($param ? '&'.$param : '').'"';
923
924 $mime = dol_mimetype($relativepath, '', 0);
925 if (preg_match('/text/', $mime)) {
926 $out .= ' target="_blank" rel="noopener noreferrer"';
927 }
928 $out .= ' title="'.dol_escape_htmltag($file["name"]).'"';
929 $out .= '>';
930 $out .= img_mime($file["name"], $langs->trans("File").': '.$file["name"]);
931 $out .= dol_trunc($file["name"], 150);
932 $out .= '</a>';
933 $out .= '</span>'."\n";
934 $out .= $imgpreview;
935 $out .= '</td>';
936
937 // Show file size
938 $size = (!empty($file['size']) ? $file['size'] : dol_filesize($filedir."/".$file["name"]));
939 $out .= '<td class="nowraponall right" title="'.dolPrintHTML($size.' '.$langs->trans("Bytes")).'">'.dol_print_size($size, 1, 1).'</td>';
940
941 // Show file date
942 $date = (!empty($file['date']) ? $file['date'] : dol_filemtime($filedir."/".$file["name"]));
943 $out .= '<td class="nowrap right">'.dol_print_date($date, 'dayhour', 'tzuser').'</td>';
944
945 // Show share link
946 $out .= '<td class="nowraponall">';
947 if (!empty($file['share'])) {
948 // Define $urlwithroot
949 $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
950 $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
951 //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current
952
953 //print '<span class="opacitymedium">'.$langs->trans("Hash").' : '.$file['share'].'</span>';
954 $forcedownload = 0;
955 $paramlink = '';
956 if (!empty($file['share'])) {
957 $paramlink .= ($paramlink ? '&' : '').'hashp='.$file['share']; // Hash for public share
958 }
959 if ($forcedownload) {
960 $paramlink .= ($paramlink ? '&' : '').'attachment=1';
961 }
962
963 $fulllink = $urlwithroot.'/document.php'.($paramlink ? '?'.$paramlink : '');
964
965 $out .= '<a href="'.$fulllink.'" target="_blank" rel="noopener">'.img_picto($langs->trans("FileSharedViaALink"), 'globe').'</a> ';
966 $out .= '<input type="text" class="quatrevingtpercentminusx width75 nopadding small" id="downloadlink'.$file['rowid'].'" name="downloadexternallink" title="'.dol_escape_htmltag($langs->trans("FileSharedViaALink")).'" value="'.dol_escape_htmltag($fulllink).'">';
967 $out .= ajax_autoselect('downloadlink'.$file['rowid']);
968 } else {
969 //print '<span class="opacitymedium">'.$langs->trans("FileNotShared").'</span>';
970 }
971 $out .= '</td>';
972
973 // Show picto delete, print...
974 if ($delallowed || $printer || $morepicto) {
975 $out .= '<td class="right nowraponall">';
976 if ($delallowed) {
977 $tmpurlsource = preg_replace('/#[a-zA-Z0-9_]*$/', '', $urlsource);
978 $out .= '<a class="reposition" href="'.$tmpurlsource.((strpos($tmpurlsource, '?') === false) ? '?' : '&').'action='.urlencode($removeaction).'&token='.newToken().'&file='.urlencode($relativepath);
979 $out .= ($param ? '&'.$param : '');
980 //$out.= '&modulepart='.$modulepart; // TODO obsolete ?
981 //$out.= '&urlsource='.urlencode($urlsource); // TODO obsolete ?
982 $out .= '">'.img_picto($langs->trans("Delete"), 'delete').'</a>';
983 }
984 if ($printer) {
985 $out .= '<a class="marginleftonly reposition" href="'.$urlsource.(strpos($urlsource, '?') ? '&' : '?').'action=print_file&token='.newToken().'&printer='.urlencode($modulepart).'&file='.urlencode($relativepath);
986 $out .= ($param ? '&'.$param : '');
987 $out .= '">'.img_picto($langs->trans("PrintFile", $relativepath), 'printer.png').'</a>';
988 }
989 if ($morepicto) {
990 $morepicto = preg_replace('/__FILENAMEURLENCODED__/', urlencode($relativepath), $morepicto);
991 $out .= $morepicto;
992 }
993 $out .= '</td>';
994 }
995
996 if (is_object($hookmanager)) {
997 $addcolumforpicto = ($delallowed || $printer || $morepicto);
998 $colspan = (4 + ($addcolumforpicto ? 1 : 0));
999 $colspanmore = 0;
1000 $parameters = array('colspan' => ($colspan + $colspanmore), 'socid' => (isset($GLOBALS['socid']) ? $GLOBALS['socid'] : ''), 'id' => (isset($GLOBALS['id']) ? $GLOBALS['id'] : ''), 'modulepart' => $modulepart, 'relativepath' => $relativepath);
1001 $res = $hookmanager->executeHooks('formBuilddocLineOptions', $parameters, $file);
1002 if (empty($res)) {
1003 $out .= $hookmanager->resPrint; // Complete line
1004 $out .= '</tr>';
1005 } else {
1006 $out = $hookmanager->resPrint; // Replace all $out
1007 }
1008 }
1009 }
1010
1011 $this->numoffiles++;
1012 }
1013 // Loop on each link found
1014 if (is_array($link_list)) {
1015 $colspan = 2;
1016
1017 foreach ($link_list as $file) {
1018 $out .= '<tr class="oddeven">';
1019 $out .= '<td colspan="'.$colspan.'" class="maxwidhtonsmartphone">';
1020 $out .= '<a data-ajax="false" href="'.$file->url.'" target="_blank" rel="noopener noreferrer">';
1021 $out .= $file->label;
1022 $out .= '</a>';
1023 $out .= '</td>';
1024 $out .= '<td class="right">';
1025 $out .= dol_print_date($file->datea, 'dayhour');
1026 $out .= '</td>';
1027 // for share link of files
1028 $out .= '<td></td>';
1029 if ($delallowed || $printer || $morepicto) {
1030 $out .= '<td></td>';
1031 }
1032 $out .= '</tr>'."\n";
1033 }
1034 $this->numoffiles++;
1035 }
1036
1037 if (count($file_list) == 0 && count($link_list) == 0 && $headershown) {
1038 $out .= '<tr><td colspan="'.(3 + ($addcolumforpicto ? 1 : 0)).'"><span class="opacitymedium">'.$langs->trans("None").'</span></td></tr>'."\n";
1039 }
1040 }
1041
1042 if ($headershown) {
1043 // Affiche pied du tableau
1044 $out .= "</table>\n";
1045 $out .= "</div>\n";
1046 if ($genallowed) {
1047 if (empty($noform)) {
1048 $out .= '</form>'."\n";
1049 }
1050 }
1051 }
1052 $out .= '<!-- End show_document -->'."\n";
1053
1054 $out .= '<script>
1055 jQuery(document).ready(function() {
1056 var selectedValue = $(".selectformat").val();
1057
1058 if (selectedValue === "excel2007" || selectedValue === "tsv") {
1059 $(".forhide").prop("disabled", true).hide();
1060 } else {
1061 $(".forhide").prop("disabled", false).show();
1062 }
1063 });
1064 </script>';
1065 //return ($i?$i:$headershown);
1066 return $out;
1067 }
1068
1082 public function getDocumentsLink($modulepart, $modulesubdir, $filedir, $filter = '', $morecss = 'valignmiddle', $allfiles = 0)
1083 {
1084 global $conf, $langs;
1085
1086 include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
1087
1088 $out = '';
1089 $this->infofiles = array('nboffiles' => 0, 'extensions' => array(), 'files' => array());
1090
1091 $entity = 1; // Without multicompany
1092
1093 // Get object entity
1094 if (isModEnabled('multicompany')) {
1095 $regs = array();
1096 preg_match('/\/([0-9]+)\/[^\/]+\/'.preg_quote($modulesubdir, '/').'$/', $filedir, $regs);
1097 $entity = ((!empty($regs[1]) && $regs[1] > 1) ? $regs[1] : 1); // If entity id not found in $filedir this is entity 1 by default
1098 }
1099
1100 // Get list of files starting with name of ref (Note: files with '^ref\.extension' are generated files, files with '^ref-...' are uploaded files)
1101 if ($allfiles || getDolGlobalString('MAIN_SHOW_ALL_FILES_ON_DOCUMENT_TOOLTIP')) {
1102 $filterforfilesearch = '^'.preg_quote(basename($modulesubdir), '/');
1103 } else {
1104 $filterforfilesearch = '^'.preg_quote(basename($modulesubdir), '/').'\.';
1105 }
1106 $file_list = dol_dir_list($filedir, 'files', 0, $filterforfilesearch, '\.meta$|\.png$'); // We also discard .meta and .png preview
1107
1108 //var_dump($file_list);
1109 // For ajax treatment
1110 $out .= '<!-- html.formfile::getDocumentsLink -->'."\n";
1111 if (!empty($file_list)) {
1112 $out = '<dl class="dropdown inline-block">
1113 <dt><a data-ajax="false" href="#" onClick="return false;">'.img_picto('', 'listlight', '', 0, 0, 0, '', $morecss).'</a></dt>
1114 <dd><div class="multichoicedoc" style="position:absolute;left:100px;" ><ul class="ulselectedfields">';
1115 $tmpout = '';
1116
1117 // Loop on each file found
1118 $found = 0;
1119 $i = 0;
1120 foreach ($file_list as $file) {
1121 $i++;
1122 if ($filter && !preg_match('/'.$filter.'/i', $file["name"])) {
1123 continue; // Discard this. It does not match provided filter.
1124 }
1125
1126 $found++;
1127 // Define relative path for download link (depends on module)
1128 $relativepath = $file["name"]; // Cas general
1129 if ($modulesubdir) {
1130 $relativepath = (string) $modulesubdir."/".$file["name"]; // Cas propal, facture...
1131 }
1132 // Autre cas
1133 if ($modulepart == 'donation') {
1134 $relativepath = (string) get_exdir($modulesubdir, 2, 0, 0, null, 'donation').$file["name"];
1135 }
1136 if ($modulepart == 'export') {
1137 $relativepath = (string) $file["name"];
1138 }
1139
1140 $this->infofiles['nboffiles']++;
1141 $this->infofiles['files'][] = $file['fullname'];
1142 $ext = (string) pathinfo($file['name'], PATHINFO_EXTENSION); // pathinfo returns a string here (cast for static analysis)
1143 if (!array_key_exists($ext, $this->infofiles['extensions'])) {
1144 $this->infofiles['extensions'][$ext] = 1;
1145 } else {
1146 $this->infofiles['extensions'][$ext]++;
1147 }
1148
1149 // Preview
1150 if (!empty($conf->use_javascript_ajax) && ($conf->browser->layout != 'phone')) {
1151 $tmparray = getAdvancedPreviewUrl($modulepart, $relativepath, 1, '&entity='.$entity);
1152 if ($tmparray && $tmparray['url']) {
1153 $tmpout .= '<li><a href="'.$tmparray['url'].'"'.($tmparray['css'] ? ' class="'.$tmparray['css'].'"' : '').($tmparray['mime'] ? ' mime="'.$tmparray['mime'].'"' : '').($tmparray['target'] ? ' target="'.$tmparray['target'].'"' : '').'>';
1154 //$tmpout.= img_picto('','detail');
1155 $tmpout .= '<i class="fa fa-search-plus paddingright" style="color: gray"></i>';
1156 $tmpout .= $langs->trans("Preview").' '.$ext.'</a></li>';
1157 }
1158 }
1159
1160 // Download
1161 $tmpout .= '<li class="nowrap"><a class="pictopreview nowrap" ';
1162 if (getDolGlobalInt('MAIN_DISABLE_FORCE_SAVEAS') == 2) {
1163 $tmpout .= 'target="_blank" ';
1164 }
1165 $tmpout .= 'href="'.DOL_URL_ROOT.'/document.php?modulepart='.$modulepart.'&amp;entity='.$entity.'&amp;file='.urlencode($relativepath).'"';
1166 $mime = dol_mimetype($relativepath, '', 0);
1167 if (preg_match('/text/', $mime)) {
1168 $tmpout .= ' target="_blank" rel="noopener noreferrer"';
1169 }
1170 $tmpout .= '>';
1171 $tmpout .= img_mime($relativepath, $file["name"]);
1172 $tmpout .= $langs->trans("Download").' '.$ext;
1173 $tmpout .= '</a></li>'."\n";
1174 }
1175 $out .= $tmpout;
1176 $out .= '</ul></div></dd>
1177 </dl>';
1178
1179 if (!$found) {
1180 $out = '';
1181 }
1182 } else {
1183 // TODO Add link to regenerate doc ?
1184 //$out.= '<div id="gen_pdf_'.$modulesubdir.'" class="linkobject hideobject">'.img_picto('', 'refresh').'</div>'."\n";
1185 }
1186
1187 return $out;
1188 }
1189
1190
1191 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1225 public function list_of_documents($filearray, $object, $modulepart, $param = '', $forcedownload = 0, $relativepath = '', $permonobject = 1, $useinecm = 0, $textifempty = '', $maxlength = 0, $title = '', $url = '', $showrelpart = 0, $permtoeditline = -1, $upload_dir = '', $sortfield = '', $sortorder = 'ASC', $disablemove = 1, $addfilterfields = 0, $disablecrop = -1, $moreattrondiv = '', $moreoptions = array())
1226 {
1227 // phpcs:enable
1228 global $user, $conf, $langs, $hookmanager, $form;
1229 global $sortfield, $sortorder;
1230 global $dolibarr_main_url_root;
1231
1232 if ($disablecrop == -1) {
1233 $disablecrop = 1;
1234 // Values here must be supported by the photos_resize.php page.
1235 if (in_array($modulepart, array('bank', 'bom', 'expensereport', 'facture', 'facture_fournisseur', 'holiday', 'medias', 'member', 'mrp', 'project', 'product', 'produit', 'propal', 'service', 'societe', 'tax', 'tax-vat', 'ticket', 'user'))) {
1236 $disablecrop = 0;
1237 }
1238 }
1239
1240 // Define relative path used to store the file
1241 if (empty($relativepath)) {
1242 $relativepath = (!empty($object->ref) ? dol_sanitizeFileName($object->ref) : '').'/';
1243 if (!empty($object->element) && $object->element == 'invoice_supplier') {
1244 $relativepath = get_exdir($object->id, 2, 0, 0, $object, 'invoice_supplier').$relativepath; // TODO Call using a defined value for $relativepath
1245 }
1246 if (!empty($object->element) && $object->element == 'project_task') {
1247 $relativepath = 'Call_not_supported_._Call_function_using_a_defined_relative_path_.';
1248 }
1249 }
1250 // For backward compatibility, we detect file stored into an old path
1251 if (getDolGlobalInt('PRODUCT_USE_OLD_PATH_FOR_PHOTO') && isset($filearray[0]) && $filearray[0]['level1name'] == 'photos') {
1252 $relativepath = preg_replace('/^.*\/produit\//', '', $filearray[0]['path']).'/';
1253 }
1254
1255 // Defined relative dir to DOL_DATA_ROOT
1256 $relativedir = '';
1257 if ($upload_dir) {
1258 $relativedir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT, '/').'/', '', $upload_dir);
1259 $relativedir = preg_replace('/^[\\/]/', '', $relativedir);
1260 }
1261 // For example here $upload_dir = '/pathtodocuments/commande/SO2001-123/'
1262 // For example here $upload_dir = '/pathtodocuments/tax/vat/1'
1263 // For example here $upload_dir = '/home/ldestailleur/git/dolibarr_dev/documents/fournisseur/facture/6/1/SI2210-0013' and relativedir='fournisseur/facture/6/1/SI2210-0013'
1264
1265 $hookmanager->initHooks(array('formfile'));
1266 $parameters = array(
1267 'filearray' => $filearray,
1268 'modulepart' => $modulepart,
1269 'param' => $param,
1270 'forcedownload' => $forcedownload,
1271 'relativepath' => $relativepath, // relative filename to module dir
1272 'relativedir' => $relativedir, // relative dirname to DOL_DATA_ROOT
1273 'permtodelete' => $permonobject,
1274 'useinecm' => $useinecm,
1275 'textifempty' => $textifempty,
1276 'maxlength' => $maxlength,
1277 'title' => $title,
1278 'url' => $url
1279 );
1280 $reshook = $hookmanager->executeHooks('showFilesList', $parameters, $object);
1281
1282 if (!empty($reshook)) { // null or '' for bypass
1283 return $reshook;
1284 } else {
1285 if (!is_object($form)) {
1286 include_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php'; // The component may be included into ajax page that does not include the Form class
1287 $form = new Form($this->db);
1288 }
1289
1290 if (!preg_match('/&id=/', $param) && isset($object->id)) {
1291 $param .= '&id='.$object->id;
1292 }
1293 $relativepathwihtoutslashend = preg_replace('/\/$/', '', $relativepath);
1294 if ($relativepathwihtoutslashend) {
1295 $param .= '&file='.urlencode($relativepathwihtoutslashend);
1296 }
1297
1298 if ($permtoeditline < 0) { // Old behaviour for backward compatibility. New feature should call method with value 0 or 1
1299 $permtoeditline = 0;
1300 if (in_array($modulepart, array('product', 'produit', 'service'))) {
1301 if ($user->hasRight('produit', 'creer') && $object->type == Product::TYPE_PRODUCT) {
1302 $permtoeditline = 1;
1303 }
1304 if ($user->hasRight('service', 'creer') && $object->type == Product::TYPE_SERVICE) {
1305 $permtoeditline = 1;
1306 }
1307 }
1308 }
1309 if (!getDolGlobalString('MAIN_UPLOAD_DOC')) {
1310 $permtoeditline = 0;
1311 $permonobject = 0;
1312 }
1313 if (empty($url)) {
1314 $url = $_SERVER["PHP_SELF"];
1315 }
1316
1317
1318 // Show title of list of existing files
1319 $morehtmlright = '';
1320 if (!empty($moreoptions['showhideaddbutton']) && $conf->use_javascript_ajax) {
1321 $morehtmlright .= dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', 'javascript:console.log("open add file form");jQuery(".divattachnewfile").toggle(); if (!jQuery(".divattachnewfile").is(":hidden")) { jQuery("input[type=\'file\']").click(); }', '', $permtoeditline);
1322 }
1323
1324 if ((empty($useinecm) || $useinecm == 3 || $useinecm == 6) && $title != 'none') {
1325 print load_fiche_titre($title ? $title : $langs->trans("AttachedFiles"), $morehtmlright, 'file-upload', 0, '', 'table-list-of-attached-files');
1326 }
1327 if (!empty($moreoptions) && $moreoptions['afteruploadtitle']) {
1328 print '<div class="divattachnewfile'.((!empty($moreoptions['showhideaddbutton']) && $conf->use_javascript_ajax) ? ' hidden' : '').'">'.$moreoptions['afteruploadtitle'].'</div>';
1329 }
1330
1331 // Show the table
1332 print '<!-- html.formfile::list_of_documents -->'."\n";
1333 if (GETPOST('action', 'aZ09') == 'editfile' && $permtoeditline) {
1334 print '<form action="'.$_SERVER["PHP_SELF"].'?'.$param.'" method="POST">';
1335 print '<input type="hidden" name="token" value="'.newToken().'">';
1336 print '<input type="hidden" name="action" value="renamefile">';
1337 print '<input type="hidden" name="id" value="'.(is_object($object) ? $object->id : '').'">';
1338 print '<input type="hidden" name="modulepart" value="'.$modulepart.'">';
1339 }
1340
1341 print '<div class="div-table-responsive-no-min"'.($moreattrondiv ? ' '.$moreattrondiv : '').'>';
1342 print '<table id="tablelines" class="centpercent liste noborder nobottom">'."\n";
1343
1344 if (!empty($addfilterfields)) {
1345 print '<tr class="liste_titre nodrag nodrop">';
1346 print '<td><input type="search_doc_ref" value="'.dol_escape_htmltag(GETPOST('search_doc_ref', 'alpha')).'"></td>';
1347 print '<td></td>';
1348 print '<td></td>';
1349 if (empty($useinecm) || $useinecm == 4 || $useinecm == 5 || $useinecm == 6) {
1350 print '<td></td>';
1351 }
1352 print '<td></td>';
1353 print '<td></td>';
1354 if (empty($disablemove) && count($filearray) > 1) {
1355 print '<td></td>';
1356 }
1357 print "</tr>\n";
1358 }
1359
1360 // Get list of files stored into database for same relative directory
1361 if ($relativedir) {
1362 completeFileArrayWithDatabaseInfo($filearray, $relativedir);
1363
1364 //var_dump($sortfield.' - '.$sortorder);
1365 if ($sortfield && $sortorder) { // If $sortfield is for example 'position_name', we will sort on the property 'position_name' (that is concat of position+name)
1366 $filearray = dol_sort_array($filearray, $sortfield, $sortorder);
1367 }
1368 }
1369
1370 print '<tr class="liste_titre nodrag nodrop">';
1371 //print $url.' sortfield='.$sortfield.' sortorder='.$sortorder;
1372 print_liste_field_titre('Documents2', $url, "name", "", $param, '', $sortfield, $sortorder, 'left ');
1373 print_liste_field_titre('Size', $url, "size", "", $param, '', $sortfield, $sortorder, 'right ');
1374 print_liste_field_titre('Date', $url, "date", "", $param, '', $sortfield, $sortorder, 'center ');
1375 if (empty($useinecm) || $useinecm == 4 || $useinecm == 5 || $useinecm == 6) {
1376 print_liste_field_titre('', $url, "", "", $param, '', $sortfield, $sortorder, 'center '); // Preview
1377 }
1378 // Shared or not - Hash of file
1380 // Action button
1382 if (empty($disablemove) && count($filearray) > 1) {
1384 }
1385 print "</tr>\n";
1386
1387 $nboffiles = count($filearray);
1388 if ($nboffiles > 0) {
1389 include_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
1390 }
1391
1392 $i = 0;
1393 $nboflines = 0;
1394 $lastrowid = 0;
1395 $parametersByDefault = array(
1396 'modulepart' => $modulepart,
1397 'relativepath' => $relativepath,
1398 'permtoedit' => $permtoeditline,
1399 'permonobject' => $permonobject,
1400 );
1401 foreach ($filearray as $key => $file) { // filearray must be only files here
1402 if ($file['name'] != '.' && $file['name'] != '..' && !preg_match('/\.meta$/i', $file['name'])) {
1403 if (array_key_exists('rowid', $filearray[$key]) && $filearray[$key]['rowid'] > 0) {
1404 $lastrowid = $filearray[$key]['rowid'];
1405 }
1406 //var_dump($filearray[$key]);
1407
1408 // get specific parameters from file attributes if set or get default ones
1409 $modulepart = ($file['modulepart'] ?? $parametersByDefault['modulepart']);
1410 $relativepath = ($file['relativepath'] ?? $parametersByDefault['relativepath']);
1411 $permtoeditline = ($file['permtoedit'] ?? $parametersByDefault['permtoedit']);
1412 $permonobject = ($file['permonobject'] ?? $parametersByDefault['permonobject']);
1413
1414 // Note: for supplier invoice, $modulepart may be already 'facture_fournisseur' and $relativepath may be already '6/1/SI2210-0013/'
1415 if (empty($relativepath) || empty($modulepart)) {
1416 $filepath = $file['level1name'].'/'.$file['name'];
1417 } else {
1418 $filepath = $relativepath.$file['name'];
1419 }
1420 if (empty($modulepart)) {
1421 $modulepart = basename(dirname($file['path']));
1422 }
1423 if (empty($relativepath)) {
1424 $relativepath = preg_replace('/\/(.+)/', '', $filepath) . '/';
1425 }
1426
1427 $editline = 0;
1428 $nboflines++;
1429 print '<!-- Line list_of_documents '.$key.' relativepath = '.$relativepath.' -->'."\n";
1430 // Do we have entry into database ?
1431
1432 print '<!-- In database: position='.(array_key_exists('position', $filearray[$key]) ? $filearray[$key]['position'] : 0).' -->'."\n";
1433 print '<tr class="oddeven" id="row-'.((array_key_exists('rowid', $filearray[$key]) && $filearray[$key]['rowid'] > 0) ? $filearray[$key]['rowid'] : 'AFTER'.$lastrowid.'POS'.($i + 1)).'">';
1434
1435
1436 // File name
1437 print '<td class="minwidth200 tdoverflowmax500" title="'.dolPrintHTMLForAttribute($file['name']).'">';
1438
1439 // Show file name with link to download
1440 //print "XX".$file['name']; //$file['name'] must be utf8
1441 print '<a class="paddingright valignmiddle" ';
1442 if (getDolGlobalInt('MAIN_DISABLE_FORCE_SAVEAS') == 2) {
1443 print 'target="_blank" ';
1444 }
1445 print 'href="'.DOL_URL_ROOT.'/document.php?modulepart='.$modulepart;
1446 if ($forcedownload) {
1447 print '&attachment=1';
1448 }
1449 if (!empty($object->entity)) {
1450 print '&entity='.$object->entity;
1451 }
1452 print '&file='.urlencode($filepath);
1453 print '">';
1454 print img_mime($file['name'], $file['name'].' ('.dol_print_size($file['size'], 0, 0).')', 'inline-block valignmiddle paddingright');
1455 if ($showrelpart == 1) {
1456 print $relativepath;
1457 }
1458 //print dol_trunc($file['name'],$maxlength,'middle');
1459
1460 //var_dump(dirname($filepath).' - '.dirname(GETPOST('urlfile', 'alpha')));
1461
1462 if (GETPOST('action', 'aZ09') == 'editfile' && $file['name'] == basename(GETPOST('urlfile', 'alpha')) && dirname($filepath) == dirname(GETPOST('urlfile', 'alpha'))) {
1463 print '</a>';
1464 $section_dir = dirname(GETPOST('urlfile', 'alpha'));
1465 if (!preg_match('/\/$/', $section_dir)) {
1466 $section_dir .= '/';
1467 }
1468 print '<input type="hidden" name="section_dir" value="'.$section_dir.'">';
1469 print '<input type="hidden" name="renamefilefrom" value="'.dol_escape_htmltag($file['name']).'">';
1470 print '<input type="text" name="renamefileto" class="quatrevingtpercent" value="'.dol_escape_htmltag($file['name']).'">';
1471 $editline = 1;
1472 } else {
1473 $filenametoshow = preg_replace('/\.noexe$/', '', $file['name']);
1474 print dol_escape_htmltag(dol_trunc($filenametoshow, 200));
1475 print '</a>';
1476 }
1477 // Preview link
1478 if (!$editline) {
1479 print $this->showPreview($file, $modulepart, $filepath, 0, '&entity='.(empty($object->entity) ? $conf->entity : $object->entity));
1480 }
1481
1482 print "</td>\n";
1483
1484 // Size
1485 $sizetoshow = dol_print_size($file['size'], 1, 1);
1486 $sizetoshowbytes = dol_print_size($file['size'], 0, 1);
1487 print '<td class="right nowraponall">';
1488 if ($sizetoshow == $sizetoshowbytes) {
1489 print $sizetoshow;
1490 } else {
1491 print $form->textwithpicto($sizetoshow, $sizetoshowbytes, -1);
1492 }
1493 print '</td>';
1494
1495 // Date
1496 print '<td class="center nowraponall">'.dol_print_date($file['date'], "dayhour", "tzuser").'</td>';
1497
1498 // Preview
1499 if (empty($useinecm) || $useinecm == 4 || $useinecm == 5 || $useinecm == 6) {
1500 $fileinfo = pathinfo($file['name']);
1501 print '<td class="center">';
1502 if (image_format_supported($file['name']) >= 0) {
1503 if ($useinecm == 5 || $useinecm == 6) {
1504 $smallfile = getImageFileNameForSize($file['name'], ''); // There is no thumb for ECM module and Media filemanager, so we use true image. TODO Change this for better performance.
1505 } else {
1506 $smallfile = getImageFileNameForSize($file['name'], '_small'); // For new thumbs using same ext (in lower case however) than original
1507 }
1508 if (!dol_is_file($file['path'].'/'.$smallfile)) {
1509 $smallfile = getImageFileNameForSize($file['name'], '_small', '.png'); // For backward compatibility of old thumbs that were created with filename in lower case and with .png extension
1510 }
1511 if (!dol_is_file($file['path'].'/'.$smallfile)) {
1512 $smallfile = getImageFileNameForSize($file['name'], ''); // This is in case no _small image exist
1513 }
1514 //print $file['path'].'/'.$smallfile.'<br>';
1515
1516
1517 $urlforhref = getAdvancedPreviewUrl($modulepart, $relativepath.$fileinfo['filename'].'.'.strtolower($fileinfo['extension']), 1, '&entity='.(empty($object->entity) ? $conf->entity : $object->entity));
1518 if (empty($urlforhref)) {
1519 $urlforhref = DOL_URL_ROOT.'/viewimage.php?modulepart='.urlencode($modulepart).'&entity='.(empty($object->entity) ? $conf->entity : $object->entity).'&file='.urlencode($relativepath.$fileinfo['filename'].'.'.strtolower($fileinfo['extension']));
1520 print '<a href="'.$urlforhref.'" class="aphoto" target="_blank" rel="noopener noreferrer">';
1521 } else {
1522 print '<a href="'.$urlforhref['url'].'" class="'.$urlforhref['css'].'" target="'.$urlforhref['target'].'" mime="'.$urlforhref['mime'].'">';
1523 }
1524 print '<img class="photo maxwidth200 shadow valignmiddle"';
1525 if ($useinecm == 4 || $useinecm == 5 || $useinecm == 6) {
1526 print ' height="20"';
1527 } else {
1528 //print ' style="max-height: '.$maxheightmini.'px"';
1529 print ' style="max-height: 24px"';
1530 }
1531 print ' src="'.DOL_URL_ROOT.'/viewimage.php?modulepart='.urlencode($modulepart).'&entity='.(empty($object->entity) ? $conf->entity : $object->entity).'&file='.urlencode($relativepath.$smallfile);
1532 if (!empty($filearray[$key]['date'])) { // We know the date of file, we can use it as cache key so URL will be in browser cache as long as file date is not modified.
1533 print '&cache='.urlencode((string) $filearray[$key]['date']);
1534 }
1535 print '" title="">';
1536 print '</a>';
1537 }
1538 print '</td>';
1539 }
1540
1541 // Shared or not - Hash of file
1542 print '<td class="center">';
1543 if ($relativedir && $filearray[$key]['rowid'] > 0) { // only if we are in a mode where a scan of dir were done and we have id of file in ECM table
1544 if ($editline) {
1545 print '<label for="idshareenabled'.$key.'">'.$langs->trans("FileSharedViaALink").'</label> ';
1546 print '<input class="inline-block" type="checkbox" id="idshareenabled'.$key.'" name="shareenabled"'.($file['share'] ? ' checked="checked"' : '').' /> ';
1547 } else {
1548 if ($file['share']) {
1549 // Define $urlwithroot
1550 $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
1551 $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
1552 //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current
1553
1554 //print '<span class="opacitymedium">'.$langs->trans("Hash").' : '.$file['share'].'</span>';
1555 $forcedownload = 0;
1556 $paramlink = '';
1557 if (!empty($file['share'])) {
1558 $paramlink .= ($paramlink ? '&' : '').'hashp='.$file['share']; // Hash for public share
1559 }
1560 if ($forcedownload) {
1561 $paramlink .= ($paramlink ? '&' : '').'attachment=1';
1562 }
1563
1564 $fulllink = $urlwithroot.'/document.php'.($paramlink ? '?'.$paramlink : '');
1565
1566 print '<a href="'.$fulllink.'" target="_blank" rel="noopener">'.img_picto($langs->trans("FileSharedViaALink"), 'globe').'</a> ';
1567 print '<input type="text" class="quatrevingtpercent minwidth200imp nopadding small" id="downloadlink'.$filearray[$key]['rowid'].'" name="downloadexternallink" title="'.dol_escape_htmltag($langs->trans("FileSharedViaALink")).'" value="'.dol_escape_htmltag($fulllink).'">';
1568 } else {
1569 //print '<span class="opacitymedium">'.$langs->trans("FileNotShared").'</span>';
1570 }
1571 }
1572 }
1573 print '</td>';
1574
1575 // Actions buttons (1 column or 2 if !disablemove)
1576 if (!$editline) {
1577 // Delete or view link
1578 // ($param must start with &)
1579 print '<td class="valignmiddle right actionbuttons nowraponall"><!-- action on files -->';
1580 if ($useinecm == 1 || $useinecm == 5) { // ECM manual tree only
1581 // $section is inside $param
1582 $newparam = preg_replace('/&file=.*$/', '', $param); // We don't need param file=
1583 $backtopage = DOL_URL_ROOT.'/ecm/index.php?&section_dir='.urlencode($relativepath).$newparam;
1584 print '<a class="editfielda editfilelink" href="'.DOL_URL_ROOT.'/ecm/file_card.php?urlfile='.urlencode($file['name']).$param.'&backtopage='.urlencode($backtopage).'" rel="'.urlencode($file['name']).'">'.img_edit('default', 0, 'class="paddingrightonly"').'</a>';
1585 }
1586
1587 if (empty($useinecm) || $useinecm == 2 || $useinecm == 3 || $useinecm == 6) { // 6=Media file manager
1588 $newmodulepart = $modulepart;
1589 if (in_array($modulepart, array('product', 'produit', 'service'))) {
1590 $newmodulepart = 'produit|service';
1591 }
1592 if (image_format_supported($file['name']) > 0) {
1593 if ($permtoeditline) {
1594 $moreparaminurl = '';
1595 if (!empty($object->id) && $object->id > 0) {
1596 $moreparaminurl .= '&id='.$object->id;
1597 } elseif (GETPOST('website', 'alpha')) {
1598 $moreparaminurl .= '&website='.GETPOST('website', 'alpha');
1599 }
1600 // Set the backtourl
1601 if ($modulepart == 'medias' && !GETPOST('website')) {
1602 $moreparaminurl .= '&backtourl='.urlencode(DOL_URL_ROOT.'/ecm/index_medias.php?file_manager=1&modulepart='.$modulepart.'&section_dir='.$relativepath);
1603 }
1604 // Link to convert into webp
1605 if (!preg_match('/\.webp$/i', $file['name'])) {
1606 if ($modulepart == 'medias' && !GETPOST('website')) {
1607 print '<a href="'.DOL_URL_ROOT.'/ecm/index_medias.php?action=confirmconvertimgwebp&token='.newToken().'&section_dir='.urlencode($relativepath).'&filetoregenerate='.urlencode($fileinfo['basename']).'&module='.$modulepart.$param.$moreparaminurl.'" title="'.dol_escape_htmltag($langs->trans("GenerateChosenImgWebp")).'">'.img_picto('', 'images', 'class="flip marginrightonly"').'</a>';
1608 } elseif ($modulepart == 'medias' && GETPOST('website')) {
1609 print '<a href="'.DOL_URL_ROOT.'/website/index.php?action=confirmconvertimgwebp&token='.newToken().'&section_dir='.urlencode($relativepath).'&filetoregenerate='.urlencode($fileinfo['basename']).'&module='.$modulepart.$param.$moreparaminurl.'" title="'.dol_escape_htmltag($langs->trans("GenerateChosenImgWebp")).'">'.img_picto('', 'images', 'class="flip marginrightonly"').'</a>';
1610 }
1611 }
1612 }
1613 }
1614 if (!$disablecrop && image_format_supported($file['name']) > 0) {
1615 if ($permtoeditline) {
1616 // Link to resize
1617 $moreparaminurl = '';
1618 if (!empty($object->id) && $object->id > 0) {
1619 $moreparaminurl .= '&id='.$object->id;
1620 } elseif (GETPOST('website', 'alpha')) {
1621 $moreparaminurl .= '&website='.GETPOST('website', 'alpha');
1622 }
1623 // Set the backtourl
1624 if ($modulepart == 'medias' && !GETPOST('website')) {
1625 $moreparaminurl .= '&backtourl='.urlencode(DOL_URL_ROOT.'/ecm/index_medias.php?file_manager=1&modulepart='.$modulepart.'&section_dir='.$relativepath);
1626 }
1627 //var_dump($moreparaminurl);
1628 print '<a class="editfielda" href="'.DOL_URL_ROOT.'/core/photos_resize.php?modulepart='.urlencode($newmodulepart).$moreparaminurl.'&file='.urlencode($relativepath.$fileinfo['filename'].'.'.strtolower($fileinfo['extension'])).'" title="'.dol_escape_htmltag($langs->trans("ResizeOrCrop")).'">'.img_picto($langs->trans("ResizeOrCrop"), 'resize', 'class="paddingrightonly"').'</a>';
1629 }
1630 }
1631
1632 if ($permtoeditline) {
1633 $paramsectiondir = (in_array($modulepart, array('medias', 'ecm')) ? '&section_dir='.urlencode($relativepath) : '');
1634 print '<a class="editfielda reposition editfilelink" href="'.(($useinecm == 1 || $useinecm == 5) ? '#' : ($url.'?action=editfile&token='.newToken().'&urlfile='.urlencode($filepath).$paramsectiondir.$param)).'" rel="'.$filepath.'">'.img_edit('default', 0, 'class="paddingrightonly"').'</a>';
1635 }
1636 }
1637 // Output link to delete file
1638 if ($permonobject) {
1639 $useajax = 1;
1640 if (!empty($conf->dol_use_jmobile)) {
1641 $useajax = 0;
1642 }
1643 if (empty($conf->use_javascript_ajax)) {
1644 $useajax = 0;
1645 }
1646 if (getDolGlobalString('MAIN_ECM_DISABLE_JS')) {
1647 $useajax = 0;
1648 }
1649 print '<a href="'.((($useinecm && $useinecm != 3 && $useinecm != 6) && $useajax) ? '#' : ($url.'?action=deletefile&token='.newToken().'&urlfile='.urlencode($filepath).$param)).'" class="reposition deletefilelink" rel="'.$filepath.'">'.img_delete().'</a>';
1650 }
1651 print "</td>";
1652
1653 if (empty($disablemove) && count($filearray) > 1) {
1654 if ($nboffiles > 1 && $conf->browser->layout != 'phone') {
1655 print '<td class="linecolmove tdlineupdown center">';
1656 if ($i > 0) {
1657 print '<a class="lineupdown" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=up&rowid='.$object->id.'">'.img_up('default', 0, 'imgupforline').'</a>';
1658 }
1659 if ($i < ($nboffiles - 1)) {
1660 print '<a class="lineupdown" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=down&rowid='.$object->id.'">'.img_down('default', 0, 'imgdownforline').'</a>';
1661 }
1662 print '</td>';
1663 } else {
1664 print '<td'.(($conf->browser->layout != 'phone') ? ' class="linecolmove tdlineupdown center"' : ' class="linecolmove center"').'>';
1665 print '</td>';
1666 }
1667 }
1668 } else {
1669 print '<td class="right">';
1670 print '<input type="hidden" name="ecmfileid" value="'.(empty($filearray[$key]['rowid']) ? '' : $filearray[$key]['rowid']).'">';
1671 print '<input type="submit" class="button button-save smallpaddingimp" name="renamefilesave" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
1672 print '<input type="submit" class="button button-cancel smallpaddingimp" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
1673 print '</td>';
1674 if (empty($disablemove) && count($filearray) > 1) {
1675 print '<td class="right"></td>';
1676 }
1677 }
1678 print "</tr>\n";
1679
1680 $i++;
1681 }
1682 }
1683 if ($nboffiles == 0) {
1684 $colspan = '6';
1685 if (empty($disablemove) && count($filearray) > 1) {
1686 $colspan++; // 6 columns or 7
1687 }
1688 print '<tr class="oddeven"><td colspan="'.$colspan.'">';
1689 if (empty($textifempty)) {
1690 print '<span class="opacitymedium">'.$langs->trans("NoFileFound").'</span>';
1691 } else {
1692 print '<span class="opacitymedium">'.$textifempty.'</span>';
1693 }
1694 print '</td></tr>';
1695 }
1696
1697 print "</table>";
1698 print '</div>';
1699
1700 if ($nboflines > 1 && is_object($object)) {
1701 if (!empty($conf->use_javascript_ajax) && $permtoeditline) {
1702 $table_element_line = 'ecm_files'; // used by ajaxrow.tpl.php
1703 include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php';
1704 }
1705 }
1706
1707 print ajax_autoselect('downloadlink');
1708
1709 if (GETPOST('action', 'aZ09') == 'editfile' && $permtoeditline) {
1710 print '</form>';
1711 }
1712
1713 return $nboffiles;
1714 }
1715 }
1716
1717
1718 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1737 public function list_of_autoecmfiles($upload_dir, $filearray, $modulepart, $param, $forcedownload = 0, $relativepath = '', $permissiontodelete = 1, $useinecm = 0, $textifempty = '', $maxlength = 0, $url = '', $addfilterfields = 0)
1738 {
1739 // phpcs:enable
1740 global $conf, $langs, $hookmanager, $form;
1741 global $sortfield, $sortorder;
1742 global $search_doc_ref;
1743 global $dolibarr_main_url_root;
1744
1745 dol_syslog(get_class($this).'::list_of_autoecmfiles upload_dir='.$upload_dir.' modulepart='.$modulepart);
1746
1747 // Show list of documents
1748 if (empty($useinecm) || $useinecm == 6) {
1749 print load_fiche_titre($langs->trans("AttachedFiles"));
1750 }
1751 if (empty($url)) {
1752 $url = $_SERVER["PHP_SELF"];
1753 }
1754
1755 if (!empty($addfilterfields)) {
1756 print '<form action="'.$_SERVER['PHP_SELF'].'">';
1757 print '<input type="hidden" name="token" value="'.newToken().'">';
1758 print '<input type="hidden" name="module" value="'.$modulepart.'">';
1759 }
1760
1761 print '<div class="div-table-responsive-no-min">';
1762 print '<table width="100%" class="noborder">'."\n";
1763
1764 if (!empty($addfilterfields)) {
1765 print '<tr class="liste_titre nodrag nodrop">';
1766 print '<td class="liste_titre"></td>';
1767 print '<td class="liste_titre"><input type="text" class="maxwidth100onsmartphone" name="search_doc_ref" value="'.dol_escape_htmltag($search_doc_ref).'"></td>';
1768 print '<td class="liste_titre"></td>';
1769 print '<td class="liste_titre"></td>';
1770 // Action column
1771 print '<td class="liste_titre right">';
1772 $searchpicto = $form->showFilterButtons();
1773 print $searchpicto;
1774 print '</td>';
1775 print "</tr>\n";
1776 }
1777
1778 print '<tr class="liste_titre">';
1779 $sortref = "fullname";
1780 if ($modulepart == 'invoice_supplier') {
1781 $sortref = 'level1name';
1782 }
1783 print_liste_field_titre("Ref", $url, $sortref, "", $param, '', $sortfield, $sortorder);
1784 print_liste_field_titre("Documents2", $url, "name", "", $param, '', $sortfield, $sortorder);
1785 print_liste_field_titre("Size", $url, "size", "", $param, '', $sortfield, $sortorder, 'right ');
1786 print_liste_field_titre("Date", $url, "date", "", $param, '', $sortfield, $sortorder, 'center ');
1787 print_liste_field_titre("Shared", $url, 'share', '', $param, '', $sortfield, $sortorder, 'right ');
1788 print '</tr>'."\n";
1789
1790 // To show ref or specific information according to view to show (defined by $module)
1791 $object_instance = null;
1792 if ($modulepart == 'company') {
1793 include_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
1794 $object_instance = new Societe($this->db);
1795 } elseif ($modulepart == 'invoice') {
1796 include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
1797 $object_instance = new Facture($this->db);
1798 } elseif ($modulepart == 'invoice_supplier') {
1799 include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
1800 $object_instance = new FactureFournisseur($this->db);
1801 } elseif ($modulepart == 'propal') {
1802 include_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
1803 $object_instance = new Propal($this->db);
1804 } elseif ($modulepart == 'supplier_proposal') {
1805 include_once DOL_DOCUMENT_ROOT.'/supplier_proposal/class/supplier_proposal.class.php';
1806 $object_instance = new SupplierProposal($this->db);
1807 } elseif ($modulepart == 'order') {
1808 include_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
1809 $object_instance = new Commande($this->db);
1810 } elseif ($modulepart == 'order_supplier') {
1811 include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
1812 $object_instance = new CommandeFournisseur($this->db);
1813 } elseif ($modulepart == 'contract') {
1814 include_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php';
1815 $object_instance = new Contrat($this->db);
1816 } elseif ($modulepart == 'product') {
1817 include_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
1818 $object_instance = new Product($this->db);
1819 } elseif ($modulepart == 'tax') {
1820 include_once DOL_DOCUMENT_ROOT.'/compta/sociales/class/chargesociales.class.php';
1821 $object_instance = new ChargeSociales($this->db);
1822 } elseif ($modulepart == 'tax-vat') {
1823 include_once DOL_DOCUMENT_ROOT.'/compta/tva/class/tva.class.php';
1824 $object_instance = new Tva($this->db);
1825 } elseif ($modulepart == 'salaries') {
1826 include_once DOL_DOCUMENT_ROOT.'/salaries/class/salary.class.php';
1827 $object_instance = new Salary($this->db);
1828 } elseif ($modulepart == 'project') {
1829 include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
1830 $object_instance = new Project($this->db);
1831 } elseif ($modulepart == 'project_task') {
1832 include_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
1833 $object_instance = new Task($this->db);
1834 } elseif ($modulepart == 'fichinter') {
1835 include_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinter.class.php';
1836 $object_instance = new Fichinter($this->db);
1837 } elseif ($modulepart == 'user') {
1838 include_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
1839 $object_instance = new User($this->db);
1840 } elseif ($modulepart == 'expensereport') {
1841 include_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
1842 $object_instance = new ExpenseReport($this->db);
1843 } elseif ($modulepart == 'holiday') {
1844 include_once DOL_DOCUMENT_ROOT.'/holiday/class/holiday.class.php';
1845 $object_instance = new Holiday($this->db);
1846 } elseif ($modulepart == 'recruitment-recruitmentcandidature') {
1847 include_once DOL_DOCUMENT_ROOT.'/recruitment/class/recruitmentcandidature.class.php';
1848 $object_instance = new RecruitmentCandidature($this->db);
1849 } elseif ($modulepart == 'banque') {
1850 include_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
1851 $object_instance = new Account($this->db);
1852 } elseif ($modulepart == 'chequereceipt') {
1853 include_once DOL_DOCUMENT_ROOT.'/compta/paiement/cheque/class/remisecheque.class.php';
1854 $object_instance = new RemiseCheque($this->db);
1855 } elseif ($modulepart == 'mrp-mo') {
1856 include_once DOL_DOCUMENT_ROOT.'/mrp/class/mo.class.php';
1857 $object_instance = new Mo($this->db);
1858 } else {
1859 $parameters = array('modulepart' => $modulepart);
1860 $reshook = $hookmanager->executeHooks('addSectionECMAuto', $parameters);
1861 if ($reshook > 0 && is_array($hookmanager->resArray) && count($hookmanager->resArray) > 0) {
1862 if (array_key_exists('classpath', $hookmanager->resArray) && !empty($hookmanager->resArray['classpath'])) {
1863 dol_include_once($hookmanager->resArray['classpath']);
1864 if (array_key_exists('classname', $hookmanager->resArray) && !empty($hookmanager->resArray['classname'])) {
1865 if (class_exists($hookmanager->resArray['classname'])) {
1866 $tmpclassname = $hookmanager->resArray['classname'];
1867 $object_instance = new $tmpclassname($this->db);
1868 }
1869 }
1870 }
1871 }
1872 }
1873
1874 //var_dump($filearray);
1875 //var_dump($object_instance);
1876
1877 // Get list of files stored into database for same relative directory
1878 $relativepathfromroot = preg_replace('/'.preg_quote(DOL_DATA_ROOT.'/', '/').'/', '', $upload_dir);
1879 if ($relativepathfromroot) {
1880 completeFileArrayWithDatabaseInfo($filearray, $relativepathfromroot.'/%');
1881
1882 //var_dump($sortfield.' - '.$sortorder);
1883 if ($sortfield && $sortorder) { // If $sortfield is for example 'position_name', we will sort on the property 'position_name' (that is concat of position+name)
1884 $filearray = dol_sort_array($filearray, $sortfield, $sortorder, 1);
1885 }
1886 }
1887
1888 //var_dump($filearray);
1889
1890 foreach ($filearray as $key => $file) {
1891 if (!is_dir($file['name'])
1892 && $file['name'] != '.'
1893 && $file['name'] != '..'
1894 && $file['name'] != 'CVS'
1895 && !preg_match('/\.meta$/i', $file['name'])) {
1896 // Define relative path used to store the file
1897 $relativefile = preg_replace('/'.preg_quote($upload_dir.'/', '/').'/', '', $file['fullname']);
1898
1899 $id = 0;
1900 $ref = '';
1901
1902 // To show ref or specific information according to view to show (defined by $modulepart)
1903 // $modulepart can be $object->table_name (that is 'mymodule_myobject') or $object->element.'-'.$module (for compatibility purpose)
1904 $reg = array();
1905 if ($modulepart == 'company' || $modulepart == 'tax' || $modulepart == 'tax-vat' || $modulepart == 'salaries') {
1906 preg_match('/(\d+)\/[^\/]+$/', $relativefile, $reg);
1907 $id = (isset($reg[1]) ? $reg[1] : '');
1908 } elseif ($modulepart == 'invoice_supplier') {
1909 preg_match('/([^\/]+)\/[^\/]+$/', $relativefile, $reg);
1910 $ref = (isset($reg[1]) ? $reg[1] : '');
1911 if (is_numeric($ref)) {
1912 $id = $ref;
1913 $ref = '';
1914 }
1915 } elseif ($modulepart == 'user') {
1916 // $ref may be also id with old supplier invoices
1917 preg_match('/(.*)\/[^\/]+$/', $relativefile, $reg);
1918 $id = (isset($reg[1]) ? $reg[1] : '');
1919 } elseif ($modulepart == 'project_task') {
1920 // $ref of task is the sub-directory of the project
1921 $reg = explode("/", $relativefile);
1922 $ref = (isset($reg[1]) ? $reg[1] : '');
1923 } elseif (in_array($modulepart, array(
1924 'invoice',
1925 'propal',
1926 'supplier_proposal',
1927 'order',
1928 'order_supplier',
1929 'contract',
1930 'product',
1931 'project',
1932 'project_task',
1933 'fichinter',
1934 'expensereport',
1935 'recruitment-recruitmentcandidature',
1936 'mrp-mo',
1937 'banque',
1938 'chequereceipt',
1939 'holiday'))) {
1940 preg_match('/(.*)\/[^\/]+$/', $relativefile, $reg);
1941 $ref = (isset($reg[1]) ? $reg[1] : '');
1942 } else {
1943 $parameters = array('modulepart' => $modulepart, 'fileinfo' => $file);
1944 $reshook = $hookmanager->executeHooks('addSectionECMAuto', $parameters);
1945 if ($reshook > 0 && is_array($hookmanager->resArray) && count($hookmanager->resArray) > 0) {
1946 if (array_key_exists('ref', $hookmanager->resArray) && !empty($hookmanager->resArray['ref'])) {
1947 $ref = $hookmanager->resArray['ref'];
1948 }
1949 if (array_key_exists('id', $hookmanager->resArray) && !empty($hookmanager->resArray['id'])) {
1950 $id = $hookmanager->resArray['id'];
1951 }
1952 }
1953 //print 'Error: Value for modulepart = '.$modulepart.' is not yet implemented in function list_of_autoecmfiles'."\n";
1954 }
1955
1956 if (!$id && !$ref) {
1957 continue;
1958 }
1959
1960 $found = 0;
1961 if (!empty($conf->cache['modulepartobject'][$modulepart.'_'.$id.'_'.$ref])) {
1962 $found = 1;
1963 } else {
1964 //print 'Fetch '.$id." - ".$ref.' class='.get_class($object_instance).'<br>';
1965
1966 $result = 0;
1967 if (is_object($object_instance)) {
1968 $object_instance->id = 0;
1969 $object_instance->ref = '';
1970 if ($id) {
1971 $result = $object_instance->fetch($id);
1972 } else {
1973 if (!($result = $object_instance->fetch(0, $ref))) {
1974 //fetchOneLike looks for objects with wildcards in its reference.
1975 //It is useful for those masks who get underscores instead of their actual symbols (because the _ had replaced all forbidden chars into filename)
1976 // TODO Example when this is needed ?
1977 // This may find when ref is 'A_B' and date was stored as 'A~B' into database, but in which case do we have this ?
1978 // May be we can add hidden option to enable this.
1979 $result = $object_instance->fetchOneLike($ref);
1980 }
1981 }
1982 }
1983
1984 if ($result > 0) { // Save object loaded into a cache
1985 $found = 1;
1986 $conf->cache['modulepartobject'][$modulepart.'_'.$id.'_'.$ref] = clone $object_instance;
1987 }
1988 if ($result == 0) {
1989 $found = 1;
1990 $conf->cache['modulepartobject'][$modulepart.'_'.$id.'_'.$ref] = 'notfound';
1991 unset($filearray[$key]);
1992 }
1993 }
1994
1995 if ($found <= 0 || !is_object($conf->cache['modulepartobject'][$modulepart.'_'.$id.'_'.$ref])) {
1996 continue; // We do not show orphelins files
1997 }
1998
1999 print '<!-- Line list_of_autoecmfiles key='.$key.' -->'."\n";
2000 print '<tr class="oddeven">';
2001 print '<td>';
2002 if ($found > 0 && is_object($conf->cache['modulepartobject'][$modulepart.'_'.$id.'_'.$ref])) {
2003 $tmpobject = $conf->cache['modulepartobject'][$modulepart.'_'.$id.'_'.$ref];
2004 //if (! in_array($tmpobject->element, array('expensereport'))) {
2005 print $tmpobject->getNomUrl(1, 'document');
2006 //} else {
2007 // print $tmpobject->getNomUrl(1);
2008 //}
2009 } else {
2010 print $langs->trans("ObjectDeleted", ($id ? $id : $ref));
2011 }
2012
2013 //$modulesubdir=dol_sanitizeFileName($ref);
2014 //$modulesubdir = dirname($relativefile);
2015
2016 //$filedir=$conf->$modulepart->dir_output . '/' . dol_sanitizeFileName($obj->ref);
2017 //$filedir = $file['path'];
2018 //$urlsource=$_SERVER['PHP_SELF'].'?id='.$obj->rowid;
2019 //print $formfile->getDocumentsLink($modulepart, $filename, $filedir);
2020 print '</td>';
2021
2022 // File
2023 // Check if document source has external module part, if it the case use it for module part on document.php
2024 print '<td>';
2025 //print "XX".$file['name']; //$file['name'] must be utf8
2026 print '<a ';
2027 if (getDolGlobalInt('MAIN_DISABLE_FORCE_SAVEAS') == 2) {
2028 print 'target="_blank" ';
2029 }
2030 print 'href="'.DOL_URL_ROOT.'/document.php?modulepart='.urlencode($modulepart);
2031 if ($forcedownload) {
2032 print '&attachment=1';
2033 }
2034 print '&file='.urlencode($relativefile).'">';
2035 print img_mime($file['name'], $file['name'].' ('.dol_print_size($file['size'], 0, 0).')');
2036 print dol_escape_htmltag(dol_trunc($file['name'], $maxlength, 'middle'));
2037 print '</a>';
2038
2039 //print $this->getDocumentsLink($modulepart, $modulesubdir, $filedir, '^'.preg_quote($file['name'],'/').'$');
2040
2041 print $this->showPreview($file, $modulepart, $file['relativename']);
2042
2043 print "</td>\n";
2044
2045 // Size
2046 $sizetoshow = dol_print_size($file['size'], 1, 1);
2047 $sizetoshowbytes = dol_print_size($file['size'], 0, 1);
2048 print '<td class="right nowraponall">';
2049 if ($sizetoshow == $sizetoshowbytes) {
2050 print $sizetoshow;
2051 } else {
2052 print $form->textwithpicto($sizetoshow, $sizetoshowbytes, -1);
2053 }
2054 print '</td>';
2055
2056 // Date
2057 print '<td class="center">'.dol_print_date($file['date'], "dayhour").'</td>';
2058
2059 // Share link
2060 print '<td class="right">';
2061 if (!empty($file['share'])) {
2062 // Define $urlwithroot
2063 $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
2064 $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
2065 //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current
2066
2067 //print '<span class="opacitymedium">'.$langs->trans("Hash").' : '.$file['share'].'</span>';
2068 $forcedownload = 0;
2069 $paramlink = '';
2070 if (!empty($file['share'])) {
2071 $paramlink .= ($paramlink ? '&' : '').'hashp='.$file['share']; // Hash for public share
2072 }
2073 if ($forcedownload) {
2074 $paramlink .= ($paramlink ? '&' : '').'attachment=1';
2075 }
2076
2077 $fulllink = $urlwithroot.'/document.php'.($paramlink ? '?'.$paramlink : '');
2078
2079 print img_picto($langs->trans("FileSharedViaALink"), 'globe').' ';
2080 print '<input type="text" class="quatrevingtpercent width100 nopadding nopadding small" id="downloadlink" name="downloadexternallink" value="'.dol_escape_htmltag($fulllink).'">';
2081 }
2082 //if (!empty($useinecm) && $useinecm != 6) print '<a data-ajax="false" href="'.DOL_URL_ROOT.'/document.php?modulepart='.$modulepart;
2083 //if ($forcedownload) print '&attachment=1';
2084 //print '&file='.urlencode($relativefile).'">';
2085 //print img_view().'</a> &nbsp; ';
2086 //if ($permissiontodelete) print '<a href="'.$url.'?id='.$object->id.'&section='.$_REQUEST["section"].'&action=delete&token='.newToken().'&urlfile='.urlencode($file['name']).'">'.img_delete().'</a>';
2087 //else print '&nbsp;';
2088 print "</td>";
2089
2090 print "</tr>\n";
2091 }
2092 }
2093
2094 if (count($filearray) == 0) {
2095 print '<tr class="oddeven"><td colspan="5">';
2096 if (empty($textifempty)) {
2097 print '<span class="opacitymedium">'.$langs->trans("NoFileFound").'</span>';
2098 } else {
2099 print '<span class="opacitymedium">'.$textifempty.'</span>';
2100 }
2101 print '</td></tr>';
2102 }
2103 print "</table>";
2104 print '</div>';
2105
2106 if (!empty($addfilterfields)) {
2107 print '</form>';
2108 }
2109 return count($filearray);
2110 // Fin de zone
2111 }
2112
2125 public function listOfLinks($object, $permissiontodelete = 1, $action = null, $selected = null, $param = '', $htmlname = 'formaddlink', $moreoptions = array())
2126 {
2127 global $conf, $langs;
2128 global $sortfield, $sortorder;
2129
2130 $langs->load("link");
2131
2132 require_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php';
2133 $link = new Link($this->db);
2134 $links = array();
2135 if ($sortfield == "name") {
2136 $sortfield = "label";
2137 } elseif ($sortfield == "date") {
2138 $sortfield = "datea";
2139 } else {
2140 $sortfield = '';
2141 }
2142 $res = $link->fetchAll($links, $object->element, $object->id, $sortfield, $sortorder);
2143 $param .= (isset($object->id) ? '&id='.$object->id : '');
2144
2145 $permissiontoedit = $permissiontodelete;
2146
2147 print '<!-- listOfLinks -->'."\n";
2148
2149 $morehtmlright = '';
2150 if (!empty($moreoptions['showhideaddbutton']) && $conf->use_javascript_ajax) {
2151 $morehtmlright .= dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', 'javascript:console.log("open addlink form"); jQuery(".divlinkfile").toggle();', '', $permissiontoedit);
2152 }
2153
2154 // Show list of associated links
2155 print load_fiche_titre($langs->trans("LinkedFiles"), $morehtmlright, 'link', 0, '', 'table-list-of-links');
2156
2157 if (!empty($moreoptions) && $moreoptions['afterlinktitle']) {
2158 print '<div class="divlinkfile'.((!empty($moreoptions['showhideaddbutton']) && $conf->use_javascript_ajax) ? ' hidden' : '').'">'.$moreoptions['afterlinktitle'].'</div>';
2159 }
2160
2161 print '<form action="'.$_SERVER['PHP_SELF'].($param ? '?'.$param : '').'" id="'.$htmlname.'" method="POST">';
2162 print '<input type="hidden" name="token" value="'.newToken().'">';
2163
2164 print '<table class="liste noborder nobottom centpercent">';
2165 print '<tr class="liste_titre">';
2167 $langs->trans("Links"),
2168 $_SERVER['PHP_SELF'],
2169 "name",
2170 "",
2171 $param,
2172 '',
2173 $sortfield,
2174 $sortorder,
2175 ''
2176 );
2178 "",
2179 "",
2180 "",
2181 "",
2182 "",
2183 '',
2184 '',
2185 '',
2186 'right '
2187 );
2189 $langs->trans("Date"),
2190 $_SERVER['PHP_SELF'],
2191 "date",
2192 "",
2193 $param,
2194 '',
2195 $sortfield,
2196 $sortorder,
2197 'center '
2198 );
2200 '',
2201 $_SERVER['PHP_SELF'],
2202 "",
2203 "",
2204 $param,
2205 '',
2206 '',
2207 '',
2208 'center '
2209 );
2210 print_liste_field_titre('', '', '');
2211 print '</tr>';
2212 $nboflinks = count($links);
2213 if ($nboflinks > 0) {
2214 include_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
2215 }
2216 foreach ($links as $link) {
2217 print '<tr class="oddeven">';
2218 //edit mode
2219 if ($action == 'update' && $selected === (int) $link->id && $permissiontoedit) {
2220 print '<td>';
2221 print '<input type="hidden" name="id" value="'.$object->id.'">';
2222 print '<input type="hidden" name="linkid" value="'.$link->id.'">';
2223 print '<input type="hidden" name="action" value="confirm_updateline">';
2224 print $langs->trans('Link').': <input type="text" name="link" value="'.$link->url.'">';
2225 print '</td>';
2226 print '<td>';
2227 print $langs->trans('Label').': <input type="text" name="label" value="'.dol_escape_htmltag($link->label).'">';
2228 print '</td>';
2229 print '<td class="center">'.dol_print_date(dol_now(), "dayhour", "tzuser").'</td>';
2230 print '<td class="right"></td>';
2231 print '<td class="right">';
2232 print '<input type="submit" class="button button-save" name="save" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
2233 print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
2234 print '</td>';
2235 } else {
2236 print '<td>';
2237 print img_picto('', 'globe').' ';
2238 print '<a data-ajax="false" href="'.$link->url.'" target="_blank" rel="noopener noreferrer">';
2239 print dol_escape_htmltag($link->label);
2240 print '</a>';
2241 print '</td>'."\n";
2242 print '<td class="right"></td>';
2243 print '<td class="center">'.dol_print_date($link->datea, "dayhour", "tzuser").'</td>';
2244 print '<td class="center"></td>';
2245 print '<td class="right">';
2246 print '<a href="'.$_SERVER['PHP_SELF'].'?action=update&linkid='.$link->id.$param.'&token='.newToken().'" class="editfilelink editfielda reposition" >'.img_edit().'</a>'; // id= is included into $param
2247 if ($permissiontodelete) {
2248 print ' &nbsp; <a class="deletefilelink reposition" href="'.$_SERVER['PHP_SELF'].'?action=deletelink&token='.newToken().'&linkid='.((int) $link->id).$param.'">'.img_delete().'</a>'; // id= is included into $param
2249 } else {
2250 print '&nbsp;';
2251 }
2252 print '</td>';
2253 }
2254 print "</tr>\n";
2255 }
2256 if ($nboflinks == 0) {
2257 print '<tr class="oddeven"><td colspan="5">';
2258 print '<span class="opacitymedium">'.$langs->trans("NoLinkFound").'</span>';
2259 print '</td></tr>';
2260 }
2261 print "</table>";
2262
2263 print '</form>';
2264
2265 return $nboflinks;
2266 }
2267
2268
2279 public function showPreview($file, $modulepart, $relativepath, $ruleforpicto = 0, $param = '')
2280 {
2281 global $langs, $conf;
2282
2283 $out = '';
2284 if ($conf->browser->layout != 'phone' && !empty($conf->use_javascript_ajax)) {
2285 $urladvancedpreview = getAdvancedPreviewUrl($modulepart, $relativepath, 1, $param); // Return if a file is qualified for preview.
2286 if (count($urladvancedpreview)) {
2287 $out .= '<a class="pictopreview '.$urladvancedpreview['css'].'" href="'.$urladvancedpreview['url'].'"'.(empty($urladvancedpreview['mime']) ? '' : ' mime="'.$urladvancedpreview['mime'].'"').' '.(empty($urladvancedpreview['target']) ? '' : ' target="'.$urladvancedpreview['target'].'"').'>';
2288 //$out.= '<a class="pictopreview">';
2289 if (empty($ruleforpicto)) {
2290 //$out.= img_picto($langs->trans('Preview').' '.$file['name'], 'detail');
2291 $out .= '<span class="fa fa-search-plus pictofixedwidth" style="color: gray"></span>';
2292 } else {
2293 $out .= img_mime($relativepath, $langs->trans('Preview').' '.$file['name'], 'pictofixedwidth');
2294 }
2295 $out .= '</a>';
2296 } else {
2297 if ($ruleforpicto < 0) {
2298 $out .= img_picto('', 'generic', '', 0, 0, 0, '', 'paddingright pictofixedwidth');
2299 }
2300 }
2301 }
2302 return $out;
2303 }
2304}
$id
Definition account.php:39
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:58
ajax_combobox($htmlname, $events=array(), $minLengthToAutocomplete=0, $forcefocus=0, $widthTypeOfAutocomplete='resolve', $idforemptyvalue='-1', $morecss='')
Convert a html select field into an ajax combobox.
Definition ajax.lib.php:457
Class to manage bank accounts.
Class for managing the social charges.
Class to manage predefined suppliers products.
Class to manage customers orders.
Class to manage Trips and Expenses.
Class to manage suppliers invoices.
Class to manage invoices.
Class to generate html code for admin pages.
Class to offer components to list and upload files.
showPreview($file, $modulepart, $relativepath, $ruleforpicto=0, $param='')
Show detail icon with link for preview.
list_of_autoecmfiles($upload_dir, $filearray, $modulepart, $param, $forcedownload=0, $relativepath='', $permissiontodelete=1, $useinecm=0, $textifempty='', $maxlength=0, $url='', $addfilterfields=0)
Show list of documents in a directory of ECM module.
showdocuments($modulepart, $modulesubdir, $filedir, $urlsource, $genallowed, $delallowed=0, $modelselected='', $allowgenifempty=1, $forcenomultilang=0, $iconPDF=0, $notused=0, $noform=0, $param='', $title='', $buttonlabel='', $codelang='', $morepicto='', $object=null, $hideifempty=0, $removeaction='remove_file', $tooltipontemplatecombo='')
Return a string to show the box with list of available documents for object.
list_of_documents($filearray, $object, $modulepart, $param='', $forcedownload=0, $relativepath='', $permonobject=1, $useinecm=0, $textifempty='', $maxlength=0, $title='', $url='', $showrelpart=0, $permtoeditline=-1, $upload_dir='', $sortfield='', $sortorder='ASC', $disablemove=1, $addfilterfields=0, $disablecrop=-1, $moreattrondiv='', $moreoptions=array())
Show list of documents in $filearray (may be they are all in same directory but may not) This also sy...
form_attach_new_file($url, $title='', $addcancel=0, $sectionid=0, $perm=1, $size=50, $object=null, $options='', $useajax=1, $savingdocmask='', $linkfiles=1, $htmlname='formuserfile', $accept='', $sectiondir='', $usewithoutform=0, $capture=0, $disablemulti=0, $nooutput=0)
Show form to upload a new file.
show_documents($modulepart, $modulesubdir, $filedir, $urlsource, $genallowed, $delallowed=0, $modelselected='', $allowgenifempty=1, $forcenomultilang=0, $iconPDF=0, $notused=0, $noform=0, $param='', $title='', $buttonlabel='', $codelang='')
Show the box with list of available documents for object.
getDocumentsLink($modulepart, $modulesubdir, $filedir, $filter='', $morecss='valignmiddle', $allfiles=0)
Show a Document icon with link(s) You may want to call this into a div like this: print '.
__construct($db)
Constructor.
listOfLinks($object, $permissiontodelete=1, $action=null, $selected=null, $param='', $htmlname='formaddlink', $moreoptions=array())
Show array with linked files.
Class to manage generation of HTML components Only common components must be here.
Class of the module paid holiday.
Class for Mo.
Definition mo.class.php:34
static liste_modeles($db, $maxfilenamelength=0)
Return list of active generation modules.
static liste_modeles($db, $maxfilenamelength=0)
Return list of active generation modules.
static liste_modeles($db, $maxfilenamelength=0)
Return list of active generation modules.
static liste_modeles($db, $maxfilenamelength=0)
Return list of active generation modules.
static liste_modeles($db, $maxfilenamelength=0)
Return list of active generation modules.
static liste_modeles($db, $maxfilenamelength=0)
Return list of active generation modules.
static liste_modeles($db, $maxfilenamelength=0)
Return list of active generation modules.
static liste_modeles($db, $maxfilenamelength=0)
Return list of active generation modules.
static liste_modeles($db, $maxfilenamelength=0)
Return list of active generation modules.
static liste_modeles($db, $maxfilenamelength=0)
Return list of active generation modules.
static liste_modeles($db, $maxfilenamelength=0)
Return list of active generation modules.
static liste_modeles($db, $maxfilenamelength=0)
Return list of active generation modules.
static liste_modeles($db, $maxfilenamelength=0)
Return list of active generation modules.
static liste_modeles($db, $maxfilenamelength=0)
Return list of active generation modules.
static liste_modeles($db, $maxfilenamelength=0)
Return list of active generation modules.
static liste_modeles($db, $maxfilenamelength=0)
Return list of active generation modules.
static liste_modeles($db, $maxfilenamelength=0)
Return list of active generation modules.
static liste_modeles($db, $maxfilenamelength=0)
Return list of active generation modules.
static liste_modeles($db, $maxfilenamelength=0)
Return list of active generation modules.
static liste_modeles($db, $maxfilenamelength=0)
Return list of active generation modules.
static liste_modeles($db, $maxfilenamelength=0)
Return list of active generation modules.
static liste_modeles($db, $maxfilenamelength=0)
Return list of active generation modules.
static liste_modeles($db, $maxfilenamelength=0)
Return list of active generation modules.
static liste_modeles($db, $maxfilenamelength=0)
Return list of active generation modules.
static liste_modeles($db, $maxfilenamelength=0)
Return list of active generation modules.
static liste_modeles($db, $maxfilenamelength=0)
Return list of active generation modules.
static liste_modeles($db, $maxfilenamelength=0)
Return list of active generation modules.
Class to manage products or services.
const TYPE_PRODUCT
Regular product.
const TYPE_SERVICE
Service.
Class to manage projects.
Class to manage proposals.
Class for RecruitmentCandidature.
Class to manage cheque delivery receipts.
Class to manage salary payments.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage price ask supplier.
Class to manage tasks.
Class to manage VAT - Value-added tax (also known in French as TVA - Taxe sur la valeur ajoutée)
Definition tva.class.php:38
Class to manage Dolibarr users.
dol_filemtime($pathoffile)
Return time of a file.
dol_filesize($pathoffile)
Return size of a file.
dol_is_file($pathoffile)
Return if path is 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
completeFileArrayWithDatabaseInfo(&$filearray, $relativedir)
Complete $filearray with data from database.
dol_print_size($size, $shortvalue=0, $shortunit=0)
Return string with formatted size.
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
img_delete($titlealt='default', $other='class="pictodelete"', $morecss='')
Show delete logo.
dol_mimetype($file, $default='application/octet-stream', $mode=0)
Return MIME type of a file from its name with extension.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
dolGetButtonTitle($label, $helpText='', $iconClass='fa fa-file', $url='', $id='', $status=1, $params=array())
Function dolGetButtonTitle : this kind of buttons are used in title in list.
img_down($titlealt='default', $selected=0, $moreclass='')
Show down arrow logo.
dol_now($mode='auto')
Return date for now.
img_mime($file, $titlealt='', $morecss='')
Show MIME img of a file.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_escape_js($stringtoescape, $mode=0, $noescapebackslashn=0)
Returns text escaped for inclusion into javascript code.
ajax_autoselect($htmlname, $addlink='', $textonlink='Link')
Make content of an input box selected when we click into input field.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
dol_sort_array(&$array, $index, $order='asc', $natsort=0, $case_sensitive=0, $keepindex=0)
Advanced sort array by the value of a given key, which produces ascending (default) or descending out...
if(!function_exists( 'dol_getprefix')) dol_include_once($relpath, $classname='')
Make an include_once using default root and alternate root if it fails.
newToken()
Return the value of token currently saved into session with name 'newtoken'.
print_liste_field_titre($name, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $tooltip="", $forcenowrapcolumntitle=0)
Show title line of an array.
getImageFileNameForSize($file, $extName, $extImgTarget='')
Return the filename of file to get the thumbs.
getAdvancedPreviewUrl($modulepart, $relativepath, $alldata=0, $param='')
Return URL we can use for advanced preview links.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '…' if string larger than length.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
info_admin($text, $infoonimgalt=0, $nodiv=0, $admin='1', $morecss='hideonsmartphone', $textfordropdown='', $picto='')
Show information in HTML for admin users or standard users.
img_edit($titlealt='default', $float=0, $other='')
Show logo edit/modify fiche.
img_up($titlealt='default', $selected=0, $moreclass='')
Show top arrow logo.
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_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
image_format_supported($file, $acceptsvg=0)
Return if a filename is file name of a supported image format.
getMaxFileSizeArray()
Return the max allowed for file upload.