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