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