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