html.formfile.class.php 74 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839
  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. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation; either version 3 of the License, or
  13. * (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  22. */
  23. /**
  24. * \file htdocs/core/class/html.formfile.class.php
  25. * \ingroup core
  26. * \brief File of class to offer components to list and upload files
  27. */
  28. /**
  29. * Class to offer components to list and upload files
  30. */
  31. class FormFile
  32. {
  33. private $db;
  34. /**
  35. * @var string Error code (or message)
  36. */
  37. public $error;
  38. public $numoffiles;
  39. public $infofiles; // Used to return informations by function getDocumentsLink
  40. /**
  41. * Constructor
  42. *
  43. * @param DoliDB $db Database handler
  44. */
  45. function __construct($db)
  46. {
  47. $this->db = $db;
  48. $this->numoffiles=0;
  49. }
  50. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
  51. /**
  52. * Show form to upload a new file.
  53. *
  54. * @param string $url Url
  55. * @param string $title Title zone (Title or '' or 'none')
  56. * @param int $addcancel 1=Add 'Cancel' button
  57. * @param int $sectionid If upload must be done inside a particular ECM section (is sectionid defined, sectiondir must not be)
  58. * @param int $perm Value of permission to allow upload
  59. * @param int $size Length of input file area. Deprecated.
  60. * @param Object $object Object to use (when attachment is done on an element)
  61. * @param string $options Add an option column
  62. * @param integer $useajax Use fileupload ajax (0=never, 1=if enabled, 2=always whatever is option). @deprecated 2 should never be used and if 1 is used, option should no be enabled.
  63. * @param string $savingdocmask Mask to use to define output filename. For example 'XXXXX-__YYYYMMDD__-__file__'
  64. * @param integer $linkfiles 1=Also add form to link files, 0=Do not show form to link files
  65. * @param string $htmlname Name and id of HTML form ('formuserfile' by default, 'formuserfileecm' when used to upload a file in ECM)
  66. * @param string $accept Specifies the types of files accepted (This is not a security check but an user interface facility. eg '.pdf,image/*' or '.png,.jpg' or 'video/*')
  67. * @param string $sectiondir If upload must be done inside a particular directory (is sectiondir defined, sectionid must not be)
  68. * @return int <0 if KO, >0 if OK
  69. */
  70. 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='')
  71. {
  72. // phpcs:enable
  73. global $conf,$langs, $hookmanager;
  74. $hookmanager->initHooks(array('formfile'));
  75. if (! empty($conf->browser->layout) && $conf->browser->layout != 'classic') $useajax=0;
  76. if ((! empty($conf->global->MAIN_USE_JQUERY_FILEUPLOAD) && $useajax) || ($useajax==2))
  77. {
  78. // TODO: Check this works with 2 forms on same page
  79. // TODO: Check this works with GED module, otherwise, force useajax to 0
  80. // TODO: This does not support option savingdocmask
  81. // TODO: This break feature to upload links too
  82. return $this->_formAjaxFileUpload($object);
  83. }
  84. else
  85. {
  86. //If there is no permission and the option to hide unauthorized actions is enabled, then nothing is printed
  87. if (!$perm && !empty($conf->global->MAIN_BUTTON_HIDE_UNAUTHORIZED)) {
  88. return 1;
  89. }
  90. $maxlength=$size;
  91. $out = "\n\n<!-- Start form attach new file -->\n";
  92. if (empty($title)) $title=$langs->trans("AttachANewFile");
  93. if ($title != 'none') $out.=load_fiche_titre($title, null, null);
  94. $out .= '<form name="'.$htmlname.'" id="'.$htmlname.'" action="'.$url.'" enctype="multipart/form-data" method="POST">';
  95. $out .= '<input type="hidden" id="'.$htmlname.'_section_dir" name="section_dir" value="'.$sectiondir.'">';
  96. $out .= '<input type="hidden" id="'.$htmlname.'_section_id" name="section_id" value="'.$sectionid.'">';
  97. $out .= '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
  98. $out .= '<table width="100%" class="nobordernopadding">';
  99. $out .= '<tr>';
  100. if (! empty($options)) $out .= '<td>'.$options.'</td>';
  101. $out .= '<td class="valignmiddle nowrap">';
  102. $max=$conf->global->MAIN_UPLOAD_DOC; // En Kb
  103. $maxphp=@ini_get('upload_max_filesize'); // En inconnu
  104. if (preg_match('/k$/i',$maxphp)) $maxphp=$maxphp*1;
  105. if (preg_match('/m$/i',$maxphp)) $maxphp=$maxphp*1024;
  106. if (preg_match('/g$/i',$maxphp)) $maxphp=$maxphp*1024*1024;
  107. if (preg_match('/t$/i',$maxphp)) $maxphp=$maxphp*1024*1024*1024;
  108. // Now $max and $maxphp are in Kb
  109. $maxmin = $max;
  110. if ($maxphp > 0) $maxmin=min($max,$maxphp);
  111. if ($maxmin > 0)
  112. {
  113. // MAX_FILE_SIZE doit précéder le champ input de type file
  114. $out .= '<input type="hidden" name="max_file_size" value="'.($maxmin*1024).'">';
  115. }
  116. $out .= '<input class="flat minwidth400" type="file"';
  117. $out .= ((! empty($conf->global->MAIN_DISABLE_MULTIPLE_FILEUPLOAD) || $conf->browser->layout != 'classic')?' name="userfile"':' name="userfile[]" multiple');
  118. $out .= (empty($conf->global->MAIN_UPLOAD_DOC) || empty($perm)?' disabled':'');
  119. $out .= (!empty($accept)?' accept="'.$accept.'"':' accept=""');
  120. $out .= '>';
  121. $out .= ' ';
  122. $out .= '<input type="submit" class="button" name="sendit" value="'.$langs->trans("Upload").'"';
  123. $out .= (empty($conf->global->MAIN_UPLOAD_DOC) || empty($perm)?' disabled':'');
  124. $out .= '>';
  125. if ($addcancel)
  126. {
  127. $out .= ' &nbsp; ';
  128. $out .= '<input type="submit" class="button" name="cancel" value="'.$langs->trans("Cancel").'">';
  129. }
  130. if (! empty($conf->global->MAIN_UPLOAD_DOC))
  131. {
  132. if ($perm)
  133. {
  134. $langs->load('other');
  135. $out .= ' ';
  136. $out .= info_admin($langs->trans("ThisLimitIsDefinedInSetup",$max,$maxphp),1);
  137. }
  138. }
  139. else
  140. {
  141. $out .= ' ('.$langs->trans("UploadDisabled").')';
  142. }
  143. $out .= "</td></tr>";
  144. if ($savingdocmask)
  145. {
  146. $out .= '<tr>';
  147. if (! empty($options)) $out .= '<td>'.$options.'</td>';
  148. $out .= '<td valign="middle" class="nowrap">';
  149. $out .= '<input type="checkbox" checked class="savingdocmask" name="savingdocmask" value="'.dol_escape_js($savingdocmask).'"> '.$langs->trans("SaveUploadedFileWithMask", preg_replace('/__file__/',$langs->transnoentitiesnoconv("OriginFileName"),$savingdocmask), $langs->transnoentitiesnoconv("OriginFileName"));
  150. $out .= '</td>';
  151. $out .= '</tr>';
  152. }
  153. $out .= "</table>";
  154. $out .= '</form>';
  155. if (empty($sectionid)) $out .= '<br>';
  156. $out .= "\n<!-- End form attach new file -->\n";
  157. if ($linkfiles)
  158. {
  159. $out .= "\n<!-- Start form link new url -->\n";
  160. $langs->load('link');
  161. $title = $langs->trans("LinkANewFile");
  162. $out .= load_fiche_titre($title, null, null);
  163. $out .= '<form name="'.$htmlname.'_link" id="'.$htmlname.'_link" action="'.$url.'" method="POST">';
  164. $out .= '<input type="hidden" id="'.$htmlname.'_link_section_dir" name="link_section_dir" value="">';
  165. $out .= '<input type="hidden" id="'.$htmlname.'_link_section_id" name="link_section_id" value="'.$sectionid.'">';
  166. $out .= '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
  167. $out .= '<div class="valignmiddle" >';
  168. $out .= '<div class="inline-block" style="padding-right: 10px;">';
  169. if (! empty($conf->global->OPTIMIZEFORTEXTBROWSER)) $out .= '<label for="link">'.$langs->trans("URLToLink") . ':</label> ';
  170. $out .= '<input type="text" name="link" class="flat minwidth400imp" id="link" placeholder="'.dol_escape_htmltag($langs->trans("URLToLink")).'">';
  171. $out .= '</div>';
  172. $out .= '<div class="inline-block" style="padding-right: 10px;">';
  173. if (! empty($conf->global->OPTIMIZEFORTEXTBROWSER)) $out .= '<label for="label">'.$langs->trans("Label") . ':</label> ';
  174. $out .= '<input type="text" class="flat" name="label" id="label" placeholder="'.dol_escape_htmltag($langs->trans("Label")).'">';
  175. $out .= '<input type="hidden" name="objecttype" value="' . $object->element . '">';
  176. $out .= '<input type="hidden" name="objectid" value="' . $object->id . '">';
  177. $out .= '</div>';
  178. $out .= '<div class="inline-block" style="padding-right: 10px;">';
  179. $out .= '<input type="submit" class="button" name="linkit" value="'.$langs->trans("ToLink").'"';
  180. $out .= (empty($conf->global->MAIN_UPLOAD_DOC) || empty($perm)?' disabled':'');
  181. $out .= '>';
  182. $out .= '</div>';
  183. $out .= '</div>';
  184. $out .= '<div class="clearboth"></div>';
  185. $out .= '</form><br>';
  186. $out .= "\n<!-- End form link new url -->\n";
  187. }
  188. $parameters = array('socid'=>(isset($GLOBALS['socid'])?$GLOBALS['socid']:''), 'id'=>(isset($GLOBALS['id'])?$GLOBALS['id']:''), 'url'=>$url, 'perm'=>$perm);
  189. $res = $hookmanager->executeHooks('formattachOptions',$parameters,$object);
  190. if (empty($res))
  191. {
  192. print '<div class="attacharea attacharea'.$htmlname.'">';
  193. print $out;
  194. print '</div>';
  195. }
  196. print $hookmanager->resPrint;
  197. return 1;
  198. }
  199. }
  200. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
  201. /**
  202. * Show the box with list of available documents for object
  203. *
  204. * @param string $modulepart propal, facture, facture_fourn, ...
  205. * @param string $modulesubdir Sub-directory to scan (Example: '0/1/10', 'FA/DD/MM/YY/9999'). Use '' if file is not into subdir of module.
  206. * @param string $filedir Directory to scan
  207. * @param string $urlsource Url of origin page (for return)
  208. * @param int $genallowed Generation is allowed (1/0 or array of formats)
  209. * @param int $delallowed Remove is allowed (1/0)
  210. * @param string $modelselected Model to preselect by default
  211. * @param integer $allowgenifempty Show warning if no model activated
  212. * @param integer $forcenomultilang Do not show language option (even if MAIN_MULTILANGS defined)
  213. * @param int $iconPDF Show only PDF icon with link (1/0)
  214. * @param int $notused Not used
  215. * @param integer $noform Do not output html form tags
  216. * @param string $param More param on http links
  217. * @param string $title Title to show on top of form
  218. * @param string $buttonlabel Label on submit button
  219. * @param string $codelang Default language code to use on lang combo box if multilang is enabled
  220. * @return int <0 if KO, number of shown files if OK
  221. * @deprecated Use print xxx->showdocuments() instead.
  222. */
  223. 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='')
  224. {
  225. // phpcs:enable
  226. $this->numoffiles=0;
  227. print $this->showdocuments($modulepart,$modulesubdir,$filedir,$urlsource,$genallowed,$delallowed,$modelselected,$allowgenifempty,$forcenomultilang,$iconPDF,$notused,$noform,$param,$title,$buttonlabel,$codelang);
  228. return $this->numoffiles;
  229. }
  230. /**
  231. * Return a string to show the box with list of available documents for object.
  232. * This also set the property $this->numoffiles
  233. *
  234. * @param string $modulepart Module the files are related to ('propal', 'facture', 'facture_fourn', 'mymodule', 'mymodule_temp', ...)
  235. * @param string $modulesubdir Existing (so sanitized) sub-directory to scan (Example: '0/1/10', 'FA/DD/MM/YY/9999'). Use '' if file is not into subdir of module.
  236. * @param string $filedir Directory to scan
  237. * @param string $urlsource Url of origin page (for return)
  238. * @param int $genallowed Generation is allowed (1/0 or array list of templates)
  239. * @param int $delallowed Remove is allowed (1/0)
  240. * @param string $modelselected Model to preselect by default
  241. * @param integer $allowgenifempty Allow generation even if list of template ($genallowed) is empty (show however a warning)
  242. * @param integer $forcenomultilang Do not show language option (even if MAIN_MULTILANGS defined)
  243. * @param int $iconPDF Deprecated, see getDocumentsLink
  244. * @param int $notused Not used
  245. * @param integer $noform Do not output html form tags
  246. * @param string $param More param on http links
  247. * @param string $title Title to show on top of form
  248. * @param string $buttonlabel Label on submit button
  249. * @param string $codelang Default language code to use on lang combo box if multilang is enabled
  250. * @param string $morepicto Add more HTML content into cell with picto
  251. * @param Object $object Object when method is called from an object card.
  252. * @param int $hideifempty Hide section of generated files if there is no file
  253. * @return string Output string with HTML array of documents (might be empty string)
  254. */
  255. 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)
  256. {
  257. // Deprecation warning
  258. if (! empty($iconPDF)) {
  259. dol_syslog(__METHOD__ . ": passing iconPDF parameter is deprecated", LOG_WARNING);
  260. }
  261. global $langs, $conf, $user, $hookmanager;
  262. global $form;
  263. if (! is_object($form)) $form=new Form($this->db);
  264. include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
  265. // For backward compatibility
  266. if (! empty($iconPDF)) {
  267. return $this->getDocumentsLink($modulepart, $modulesubdir, $filedir);
  268. }
  269. // Add entity in $param if not already exists
  270. if (!preg_match('/entity\=[0-9]+/', $param)) {
  271. $param.= 'entity='.(!empty($object->entity)?$object->entity:$conf->entity);
  272. }
  273. $printer=0;
  274. if (in_array($modulepart,array('facture','supplier_proposal','propal','proposal','order','commande','expedition', 'commande_fournisseur', 'expensereport','livraison'))) // The direct print feature is implemented only for such elements
  275. {
  276. $printer = (!empty($user->rights->printing->read) && !empty($conf->printing->enabled))?true:false;
  277. }
  278. $hookmanager->initHooks(array('formfile'));
  279. // Get list of files
  280. $file_list=null;
  281. if (! empty($filedir))
  282. {
  283. $file_list=dol_dir_list($filedir,'files',0,'','(\.meta|_preview.*.*\.png)$','date',SORT_DESC);
  284. }
  285. if ($hideifempty && empty($file_list)) return '';
  286. $out='';
  287. $forname='builddoc';
  288. $headershown=0;
  289. $showempty=0;
  290. $i=0;
  291. $out.= "\n".'<!-- Start show_document -->'."\n";
  292. //print 'filedir='.$filedir;
  293. if (preg_match('/massfilesarea_/', $modulepart))
  294. {
  295. $out.='<div id="show_files"><br></div>'."\n";
  296. $title=$langs->trans("MassFilesArea").' <a href="" id="togglemassfilesarea" ref="shown">('.$langs->trans("Hide").')</a>';
  297. $title.='<script type="text/javascript" language="javascript">
  298. jQuery(document).ready(function() {
  299. jQuery(\'#togglemassfilesarea\').click(function() {
  300. if (jQuery(\'#togglemassfilesarea\').attr(\'ref\') == "shown")
  301. {
  302. jQuery(\'#'.$modulepart.'_table\').hide();
  303. jQuery(\'#togglemassfilesarea\').attr("ref", "hidden");
  304. jQuery(\'#togglemassfilesarea\').text("('.dol_escape_js($langs->trans("Show")).')");
  305. }
  306. else
  307. {
  308. jQuery(\'#'.$modulepart.'_table\').show();
  309. jQuery(\'#togglemassfilesarea\').attr("ref","shown");
  310. jQuery(\'#togglemassfilesarea\').text("('.dol_escape_js($langs->trans("Hide")).')");
  311. }
  312. return false;
  313. });
  314. });
  315. </script>';
  316. }
  317. $titletoshow=$langs->trans("Documents");
  318. if (! empty($title)) $titletoshow=$title;
  319. // Show table
  320. if ($genallowed)
  321. {
  322. $modellist=array();
  323. if ($modulepart == 'company')
  324. {
  325. $showempty=1;
  326. if (is_array($genallowed)) $modellist=$genallowed;
  327. else
  328. {
  329. include_once DOL_DOCUMENT_ROOT.'/core/modules/societe/modules_societe.class.php';
  330. $modellist=ModeleThirdPartyDoc::liste_modeles($this->db);
  331. }
  332. }
  333. else if ($modulepart == 'propal')
  334. {
  335. if (is_array($genallowed)) $modellist=$genallowed;
  336. else
  337. {
  338. include_once DOL_DOCUMENT_ROOT.'/core/modules/propale/modules_propale.php';
  339. $modellist=ModelePDFPropales::liste_modeles($this->db);
  340. }
  341. }
  342. else if ($modulepart == 'supplier_proposal')
  343. {
  344. if (is_array($genallowed)) $modellist=$genallowed;
  345. else
  346. {
  347. include_once DOL_DOCUMENT_ROOT.'/core/modules/supplier_proposal/modules_supplier_proposal.php';
  348. $modellist=ModelePDFSupplierProposal::liste_modeles($this->db);
  349. }
  350. }
  351. else if ($modulepart == 'commande')
  352. {
  353. if (is_array($genallowed)) $modellist=$genallowed;
  354. else
  355. {
  356. include_once DOL_DOCUMENT_ROOT.'/core/modules/commande/modules_commande.php';
  357. $modellist=ModelePDFCommandes::liste_modeles($this->db);
  358. }
  359. }
  360. elseif ($modulepart == 'expedition')
  361. {
  362. if (is_array($genallowed)) $modellist=$genallowed;
  363. else
  364. {
  365. include_once DOL_DOCUMENT_ROOT.'/core/modules/expedition/modules_expedition.php';
  366. $modellist=ModelePDFExpedition::liste_modeles($this->db);
  367. }
  368. }
  369. elseif ($modulepart == 'livraison')
  370. {
  371. if (is_array($genallowed)) $modellist=$genallowed;
  372. else
  373. {
  374. include_once DOL_DOCUMENT_ROOT.'/core/modules/livraison/modules_livraison.php';
  375. $modellist=ModelePDFDeliveryOrder::liste_modeles($this->db);
  376. }
  377. }
  378. else if ($modulepart == 'ficheinter')
  379. {
  380. if (is_array($genallowed)) $modellist=$genallowed;
  381. else
  382. {
  383. include_once DOL_DOCUMENT_ROOT.'/core/modules/fichinter/modules_fichinter.php';
  384. $modellist=ModelePDFFicheinter::liste_modeles($this->db);
  385. }
  386. }
  387. elseif ($modulepart == 'facture')
  388. {
  389. if (is_array($genallowed)) $modellist=$genallowed;
  390. else
  391. {
  392. include_once DOL_DOCUMENT_ROOT.'/core/modules/facture/modules_facture.php';
  393. $modellist=ModelePDFFactures::liste_modeles($this->db);
  394. }
  395. }
  396. elseif ($modulepart == 'contract')
  397. {
  398. if (is_array($genallowed)) $modellist=$genallowed;
  399. else
  400. {
  401. include_once DOL_DOCUMENT_ROOT.'/core/modules/contract/modules_contract.php';
  402. $modellist=ModelePDFContract::liste_modeles($this->db);
  403. }
  404. }
  405. elseif ($modulepart == 'project')
  406. {
  407. if (is_array($genallowed)) $modellist=$genallowed;
  408. else
  409. {
  410. include_once DOL_DOCUMENT_ROOT.'/core/modules/project/modules_project.php';
  411. $modellist=ModelePDFProjects::liste_modeles($this->db);
  412. }
  413. }
  414. elseif ($modulepart == 'project_task')
  415. {
  416. if (is_array($genallowed)) $modellist=$genallowed;
  417. else
  418. {
  419. include_once DOL_DOCUMENT_ROOT.'/core/modules/project/task/modules_task.php';
  420. $modellist=ModelePDFTask::liste_modeles($this->db);
  421. }
  422. }
  423. elseif ($modulepart == 'product')
  424. {
  425. if (is_array($genallowed)) $modellist=$genallowed;
  426. else
  427. {
  428. include_once DOL_DOCUMENT_ROOT.'/core/modules/product/modules_product.class.php';
  429. $modellist=ModelePDFProduct::liste_modeles($this->db);
  430. }
  431. }
  432. elseif ($modulepart == 'product_batch')
  433. {
  434. if (is_array($genallowed)) $modellist=$genallowed;
  435. else
  436. {
  437. include_once DOL_DOCUMENT_ROOT.'/core/modules/product_batch/modules_product_batch.class.php';
  438. $modellist=ModelePDFProductBatch::liste_modeles($this->db);
  439. }
  440. }
  441. elseif ($modulepart == 'stock')
  442. {
  443. if (is_array($genallowed)) $modellist=$genallowed;
  444. else
  445. {
  446. include_once DOL_DOCUMENT_ROOT.'/core/modules/stock/modules_stock.php';
  447. $modellist=ModelePDFStock::liste_modeles($this->db);
  448. }
  449. }
  450. elseif ($modulepart == 'movement')
  451. {
  452. if (is_array($genallowed)) $modellist=$genallowed;
  453. else
  454. {
  455. include_once DOL_DOCUMENT_ROOT.'/core/modules/stock/modules_movement.php';
  456. $modellist=ModelePDFMovement::liste_modeles($this->db);
  457. }
  458. }
  459. elseif ($modulepart == 'export')
  460. {
  461. if (is_array($genallowed)) $modellist=$genallowed;
  462. else
  463. {
  464. include_once DOL_DOCUMENT_ROOT.'/core/modules/export/modules_export.php';
  465. $modellist=ModeleExports::liste_modeles($this->db);
  466. }
  467. }
  468. else if ($modulepart == 'commande_fournisseur' || $modulepart == 'supplier_order')
  469. {
  470. if (is_array($genallowed)) $modellist=$genallowed;
  471. else
  472. {
  473. include_once DOL_DOCUMENT_ROOT.'/core/modules/supplier_order/modules_commandefournisseur.php';
  474. $modellist=ModelePDFSuppliersOrders::liste_modeles($this->db);
  475. }
  476. }
  477. else if ($modulepart == 'facture_fournisseur' || $modulepart == 'supplier_invoice')
  478. {
  479. if (is_array($genallowed)) $modellist=$genallowed;
  480. else
  481. {
  482. include_once DOL_DOCUMENT_ROOT.'/core/modules/supplier_invoice/modules_facturefournisseur.php';
  483. $modellist=ModelePDFSuppliersInvoices::liste_modeles($this->db);
  484. }
  485. }
  486. else if ($modulepart == 'supplier_payment')
  487. {
  488. if (is_array($genallowed)) $modellist=$genallowed;
  489. else
  490. {
  491. include_once DOL_DOCUMENT_ROOT.'/core/modules/supplier_payment/modules_supplier_payment.php';
  492. $modellist=ModelePDFSuppliersPayments::liste_modeles($this->db);
  493. }
  494. }
  495. else if ($modulepart == 'remisecheque')
  496. {
  497. if (is_array($genallowed)) $modellist=$genallowed;
  498. else
  499. {
  500. include_once DOL_DOCUMENT_ROOT.'/core/modules/cheque/modules_chequereceipts.php';
  501. $modellist=ModeleChequeReceipts::liste_modeles($this->db);
  502. }
  503. }
  504. elseif ($modulepart == 'donation')
  505. {
  506. if (is_array($genallowed)) $modellist=$genallowed;
  507. else
  508. {
  509. include_once DOL_DOCUMENT_ROOT.'/core/modules/dons/modules_don.php';
  510. $modellist=ModeleDon::liste_modeles($this->db);
  511. }
  512. }
  513. elseif ($modulepart == 'member')
  514. {
  515. if (is_array($genallowed)) $modellist=$genallowed;
  516. else
  517. {
  518. include_once DOL_DOCUMENT_ROOT.'/core/modules/member/modules_cards.php';
  519. $modellist=ModelePDFCards::liste_modeles($this->db);
  520. }
  521. }
  522. elseif ($modulepart == 'agenda' || $modulepart == 'actions')
  523. {
  524. if (is_array($genallowed)) $modellist=$genallowed;
  525. else
  526. {
  527. include_once DOL_DOCUMENT_ROOT.'/core/modules/action/modules_action.php';
  528. $modellist=ModeleAction::liste_modeles($this->db);
  529. }
  530. }
  531. else if ($modulepart == 'expensereport')
  532. {
  533. if (is_array($genallowed)) $modellist=$genallowed;
  534. else
  535. {
  536. include_once DOL_DOCUMENT_ROOT.'/core/modules/expensereport/modules_expensereport.php';
  537. $modellist=ModeleExpenseReport::liste_modeles($this->db);
  538. }
  539. }
  540. else if ($modulepart == 'unpaid')
  541. {
  542. $modellist='';
  543. }
  544. elseif ($modulepart == 'user')
  545. {
  546. if (is_array($genallowed)) $modellist=$genallowed;
  547. else
  548. {
  549. include_once DOL_DOCUMENT_ROOT.'/core/modules/user/modules_user.class.php';
  550. $modellist=ModelePDFUser::liste_modeles($this->db);
  551. }
  552. }
  553. elseif ($modulepart == 'usergroup')
  554. {
  555. if (is_array($genallowed)) $modellist=$genallowed;
  556. else
  557. {
  558. include_once DOL_DOCUMENT_ROOT.'/core/modules/usergroup/modules_usergroup.class.php';
  559. $modellist=ModelePDFUserGroup::liste_modeles($this->db);
  560. }
  561. }
  562. else
  563. {
  564. // For normalized standard modules
  565. $file=dol_buildpath('/core/modules/'.$modulepart.'/modules_'.$modulepart.'.php',0);
  566. if (file_exists($file))
  567. {
  568. $res=include_once $file;
  569. }
  570. // For normalized external modules
  571. else
  572. {
  573. $file=dol_buildpath('/'.$modulepart.'/core/modules/'.$modulepart.'/modules_'.$modulepart.'.php',0);
  574. $res=include_once $file;
  575. }
  576. $class='ModelePDF'.ucfirst($modulepart);
  577. if (class_exists($class))
  578. {
  579. $modellist=call_user_func($class.'::liste_modeles',$this->db);
  580. }
  581. else
  582. {
  583. dol_print_error($this->db,'Bad value for modulepart');
  584. return -1;
  585. }
  586. }
  587. // Set headershown to avoid to have table opened a second time later
  588. $headershown=1;
  589. $buttonlabeltoshow=$buttonlabel;
  590. if (empty($buttonlabel)) $buttonlabel=$langs->trans('Generate');
  591. if ($conf->browser->layout == 'phone') $urlsource.='#'.$forname.'_form'; // So we switch to form after a generation
  592. if (empty($noform)) $out.= '<form action="'.$urlsource.(empty($conf->global->MAIN_JUMP_TAG)?'':'#builddoc').'" id="'.$forname.'_form" method="post">';
  593. $out.= '<input type="hidden" name="action" value="builddoc">';
  594. $out.= '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
  595. $out.= load_fiche_titre($titletoshow, '', '');
  596. $out.= '<div class="div-table-responsive-no-min">';
  597. $out.= '<table class="liste formdoc noborder" summary="listofdocumentstable" width="100%">';
  598. $out.= '<tr class="liste_titre">';
  599. $addcolumforpicto=($delallowed || $printer || $morepicto);
  600. $out.= '<th align="center" colspan="'.(3+($addcolumforpicto?1:0)).'" class="formdoc liste_titre maxwidthonsmartphone">';
  601. // Model
  602. if (! empty($modellist))
  603. {
  604. $out.= '<span class="hideonsmartphone">'.$langs->trans('Model').' </span>';
  605. if (is_array($modellist) && count($modellist) == 1) // If there is only one element
  606. {
  607. $arraykeys=array_keys($modellist);
  608. $modelselected=$arraykeys[0];
  609. }
  610. $out.= $form->selectarray('model', $modellist, $modelselected, $showempty, 0, 0, '', 0, 0, 0, '', 'minwidth100');
  611. if ($conf->use_javascript_ajax)
  612. {
  613. $out.= ajax_combobox('model');
  614. }
  615. }
  616. else
  617. {
  618. $out.= '<div class="float">'.$langs->trans("Files").'</div>';
  619. }
  620. // Language code (if multilang)
  621. if (($allowgenifempty || (is_array($modellist) && count($modellist) > 0)) && $conf->global->MAIN_MULTILANGS && ! $forcenomultilang && (! empty($modellist) || $showempty))
  622. {
  623. include_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
  624. $formadmin=new FormAdmin($this->db);
  625. $defaultlang=$codelang?$codelang:$langs->getDefaultLang();
  626. $morecss='maxwidth150';
  627. if ($conf->browser->layout == 'phone') $morecss='maxwidth100';
  628. $out.= $formadmin->select_language($defaultlang, 'lang_id', 0, 0, 0, 0, 0, $morecss);
  629. }
  630. else
  631. {
  632. $out.= '&nbsp;';
  633. }
  634. // Button
  635. $genbutton = '<input class="button buttongen" id="'.$forname.'_generatebutton" name="'.$forname.'_generatebutton"';
  636. $genbutton.= ' type="submit" value="'.$buttonlabel.'"';
  637. if (! $allowgenifempty && ! is_array($modellist) && empty($modellist)) $genbutton.= ' disabled';
  638. $genbutton.= '>';
  639. if ($allowgenifempty && ! is_array($modellist) && empty($modellist) && empty($conf->dol_no_mouse_hover) && $modulepart != 'unpaid')
  640. {
  641. $langs->load("errors");
  642. $genbutton.= ' '.img_warning($langs->transnoentitiesnoconv("WarningNoDocumentModelActivated"));
  643. }
  644. if (! $allowgenifempty && ! is_array($modellist) && empty($modellist) && empty($conf->dol_no_mouse_hover) && $modulepart != 'unpaid') $genbutton='';
  645. if (empty($modellist) && ! $showempty && $modulepart != 'unpaid') $genbutton='';
  646. $out.= $genbutton;
  647. $out.= '</th>';
  648. if (!empty($hookmanager->hooks['formfile']))
  649. {
  650. foreach($hookmanager->hooks['formfile'] as $module)
  651. {
  652. if (method_exists($module, 'formBuilddocLineOptions')) $out .= '<th></th>';
  653. }
  654. }
  655. $out.= '</tr>';
  656. // Execute hooks
  657. $parameters=array('socid'=>(isset($GLOBALS['socid'])?$GLOBALS['socid']:''),'id'=>(isset($GLOBALS['id'])?$GLOBALS['id']:''),'modulepart'=>$modulepart);
  658. if (is_object($hookmanager))
  659. {
  660. $reshook = $hookmanager->executeHooks('formBuilddocOptions',$parameters,$GLOBALS['object']);
  661. $out.= $hookmanager->resPrint;
  662. }
  663. }
  664. // Get list of files
  665. if (! empty($filedir))
  666. {
  667. $link_list = array();
  668. if (is_object($object))
  669. {
  670. require_once DOL_DOCUMENT_ROOT . '/core/class/link.class.php';
  671. $link = new Link($this->db);
  672. $sortfield = $sortorder = null;
  673. $res = $link->fetchAll($link_list, $object->element, $object->id, $sortfield, $sortorder);
  674. }
  675. $out.= '<!-- html.formfile::showdocuments -->'."\n";
  676. // Show title of array if not already shown
  677. if ((! empty($file_list) || ! empty($link_list) || preg_match('/^massfilesarea/', $modulepart))
  678. && ! $headershown)
  679. {
  680. $headershown=1;
  681. $out.= '<div class="titre">'.$titletoshow.'</div>'."\n";
  682. $out.= '<div class="div-table-responsive-no-min">';
  683. $out.= '<table class="noborder" summary="listofdocumentstable" id="'.$modulepart.'_table" width="100%">'."\n";
  684. }
  685. // Loop on each file found
  686. if (is_array($file_list))
  687. {
  688. foreach($file_list as $file)
  689. {
  690. // Define relative path for download link (depends on module)
  691. $relativepath=$file["name"]; // Cas general
  692. if ($modulesubdir) $relativepath=$modulesubdir."/".$file["name"]; // Cas propal, facture...
  693. if ($modulepart == 'export') $relativepath = $file["name"]; // Other case
  694. $out.= '<tr class="oddeven">';
  695. $documenturl = DOL_URL_ROOT.'/document.php';
  696. if (isset($conf->global->DOL_URL_ROOT_DOCUMENT_PHP)) $documenturl=$conf->global->DOL_URL_ROOT_DOCUMENT_PHP; // To use another wrapper
  697. // Show file name with link to download
  698. $out.= '<td class="minwidth200">';
  699. $out.= '<a class="documentdownload paddingright" href="'.$documenturl.'?modulepart='.$modulepart.'&amp;file='.urlencode($relativepath).($param?'&'.$param:'').'"';
  700. $mime=dol_mimetype($relativepath,'',0);
  701. if (preg_match('/text/',$mime)) $out.= ' target="_blank"';
  702. $out.= ' target="_blank">';
  703. $out.= img_mime($file["name"],$langs->trans("File").': '.$file["name"]);
  704. $out.= dol_trunc($file["name"], 150);
  705. $out.= '</a>'."\n";
  706. $out.= $this->showPreview($file,$modulepart,$relativepath,0,$param);
  707. $out.= '</td>';
  708. // Show file size
  709. $size=(! empty($file['size'])?$file['size']:dol_filesize($filedir."/".$file["name"]));
  710. $out.= '<td align="right" class="nowrap">'.dol_print_size($size,1,1).'</td>';
  711. // Show file date
  712. $date=(! empty($file['date'])?$file['date']:dol_filemtime($filedir."/".$file["name"]));
  713. $out.= '<td align="right" class="nowrap">'.dol_print_date($date, 'dayhour', 'tzuser').'</td>';
  714. if ($delallowed || $printer || $morepicto)
  715. {
  716. $out.= '<td class="right nowraponall">';
  717. if ($delallowed)
  718. {
  719. $tmpurlsource = preg_replace('/#[a-zA-Z0-9_]*$/', '', $urlsource);
  720. $out.= '<a href="'.$tmpurlsource.(strpos($tmpurlsource,'?')?'&amp;':'?').'action=remove_file&amp;file='.urlencode($relativepath);
  721. $out.= ($param?'&amp;'.$param:'');
  722. //$out.= '&modulepart='.$modulepart; // TODO obsolete ?
  723. //$out.= '&urlsource='.urlencode($urlsource); // TODO obsolete ?
  724. $out.= '">'.img_picto($langs->trans("Delete"), 'delete').'</a>';
  725. }
  726. if ($printer)
  727. {
  728. //$out.= '<td align="right">';
  729. $out.= '<a class="paddingleft" href="'.$urlsource.(strpos($urlsource,'?')?'&amp;':'?').'action=print_file&amp;printer='.$modulepart.'&amp;file='.urlencode($relativepath);
  730. $out.= ($param?'&amp;'.$param:'');
  731. $out.= '">'.img_picto($langs->trans("PrintFile", $relativepath),'printer.png').'</a>';
  732. }
  733. if ($morepicto)
  734. {
  735. $morepicto=preg_replace('/__FILENAMEURLENCODED__/',urlencode($relativepath),$morepicto);
  736. $out.=$morepicto;
  737. }
  738. $out.='</td>';
  739. }
  740. if (is_object($hookmanager))
  741. {
  742. $parameters=array('socid'=>(isset($GLOBALS['socid'])?$GLOBALS['socid']:''),'id'=>(isset($GLOBALS['id'])?$GLOBALS['id']:''),'modulepart'=>$modulepart,'relativepath'=>$relativepath);
  743. $res = $hookmanager->executeHooks('formBuilddocLineOptions',$parameters,$file);
  744. if (empty($res))
  745. {
  746. $out.= $hookmanager->resPrint; // Complete line
  747. $out.= '</tr>';
  748. }
  749. else $out = $hookmanager->resPrint; // Replace line
  750. }
  751. }
  752. $this->numoffiles++;
  753. }
  754. // Loop on each link found
  755. if (is_array($link_list))
  756. {
  757. $colspan=2;
  758. foreach($link_list as $file)
  759. {
  760. $out.='<tr class="oddeven">';
  761. $out.='<td colspan="'.$colspan.'" class="maxwidhtonsmartphone">';
  762. $out.='<a data-ajax="false" href="' . $link->url . '" target="_blank">';
  763. $out.=$file->label;
  764. $out.='</a>';
  765. $out.='</td>';
  766. $out.='<td align="right">';
  767. $out.=dol_print_date($file->datea,'dayhour');
  768. $out.='</td>';
  769. if ($delallowed || $printer || $morepicto) $out.='<td></td>';
  770. $out.='</tr>'."\n";
  771. }
  772. $this->numoffiles++;
  773. }
  774. if (count($file_list) == 0 && count($link_list) == 0 && $headershown)
  775. {
  776. $out.='<tr><td colspan="'.(3+($addcolumforpicto?1:0)).'" class="opacitymedium">'.$langs->trans("None").'</td></tr>'."\n";
  777. }
  778. }
  779. if ($headershown)
  780. {
  781. // Affiche pied du tableau
  782. $out.= "</table>\n";
  783. $out.= "</div>\n";
  784. if ($genallowed)
  785. {
  786. if (empty($noform)) $out.= '</form>'."\n";
  787. }
  788. }
  789. $out.= '<!-- End show_document -->'."\n";
  790. //return ($i?$i:$headershown);
  791. return $out;
  792. }
  793. /**
  794. * Show a Document icon with link(s)
  795. * You may want to call this into a div like this:
  796. * print '<div class="inline-block valignmiddle">'.$formfile->getDocumentsLink($element_doc, $filename, $filedir).'</div>';
  797. *
  798. * @param string $modulepart propal, facture, facture_fourn, ...
  799. * @param string $modulesubdir Sub-directory to scan (Example: '0/1/10', 'FA/DD/MM/YY/9999'). Use '' if file is not into subdir of module.
  800. * @param string $filedir Full path to directory to scan
  801. * @param string $filter Filter filenames on this regex string (Example: '\.pdf$')
  802. * @return string Output string with HTML link of documents (might be empty string). This also fill the array ->infofiles
  803. */
  804. function getDocumentsLink($modulepart, $modulesubdir, $filedir, $filter='')
  805. {
  806. global $conf, $langs;
  807. include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
  808. $out='';
  809. $this->infofiles=array('nboffiles'=>0,'extensions'=>array(),'files'=>array());
  810. $entity = 1; // Without multicompany
  811. // Get object entity
  812. if (! empty($conf->multicompany->enabled))
  813. {
  814. preg_match('/\/([0-9]+)\/[^\/]+\/'.preg_quote($modulesubdir,'/').'$/', $filedir, $regs);
  815. $entity = ((! empty($regs[1]) && $regs[1] > 1) ? $regs[1] : 1); // If entity id not found in $filedir this is entity 1 by default
  816. }
  817. // Get list of files starting with name of ref (but not followed by "-" to discard uploaded files and get only generated files)
  818. // @TODO Why not showing by default all files by just removing the '[^\-]+' at end of regex ?
  819. if (! empty($conf->global->MAIN_SHOW_ALL_FILES_ON_DOCUMENT_TOOLTIP))
  820. {
  821. $filterforfilesearch = preg_quote(basename($modulesubdir),'/');
  822. }
  823. else
  824. {
  825. $filterforfilesearch = preg_quote(basename($modulesubdir),'/').'[^\-]+';
  826. }
  827. $file_list=dol_dir_list($filedir, 'files', 0, $filterforfilesearch, '\.meta$|\.png$'); // We also discard .meta and .png preview
  828. //var_dump($file_list);
  829. // For ajax treatment
  830. $out.= '<!-- html.formfile::getDocumentsLink -->'."\n";
  831. if (! empty($file_list))
  832. {
  833. $out='<dl class="dropdown inline-block">
  834. <dt><a data-ajax="false" href="#" onClick="return false;">'.img_picto('', 'listlight', '', 0, 0, 0, '', 'valignmiddle').'</a></dt>
  835. <dd><div class="multichoicedoc" style="position:absolute;left:100px;" ><ul class="ulselectedfields" style="display: none;">';
  836. $tmpout='';
  837. // Loop on each file found
  838. $found=0;
  839. foreach($file_list as $file)
  840. {
  841. $i++;
  842. if ($filter && ! preg_match('/'.$filter.'/i', $file["name"])) continue; // Discard this. It does not match provided filter.
  843. $found++;
  844. // Define relative path for download link (depends on module)
  845. $relativepath=$file["name"]; // Cas general
  846. if ($modulesubdir) $relativepath=$modulesubdir."/".$file["name"]; // Cas propal, facture...
  847. // Autre cas
  848. if ($modulepart == 'donation') {
  849. $relativepath = get_exdir($modulesubdir,2,0,0,null,'donation').$file["name"];
  850. }
  851. if ($modulepart == 'export') {
  852. $relativepath = $file["name"];
  853. }
  854. $this->infofiles['nboffiles']++;
  855. $this->infofiles['files'][]=$file['fullname'];
  856. $ext=pathinfo($file["name"], PATHINFO_EXTENSION);
  857. if (empty($this->infofiles[$ext])) $this->infofiles['extensions'][$ext]=1;
  858. else $this->infofiles['extensions'][$ext]++;
  859. // Preview
  860. if (! empty($conf->use_javascript_ajax) && ($conf->browser->layout != 'phone'))
  861. {
  862. $tmparray = getAdvancedPreviewUrl($modulepart, $relativepath, 1, '&entity='.$entity);
  863. if ($tmparray && $tmparray['url'])
  864. {
  865. $tmpout.= '<li><a href="'.$tmparray['url'].'"'.($tmparray['css']?' class="'.$tmparray['css'].'"':'').($tmparray['mime']?' mime="'.$tmparray['mime'].'"':'').($tmparray['target']?' target="'.$tmparray['target'].'"':'').'>';
  866. //$tmpout.= img_picto('','detail');
  867. $tmpout.= '<i class="fa fa-search-plus paddingright" style="color: gray"></i>';
  868. $tmpout.= $langs->trans("Preview").' '.$ext.'</a></li>';
  869. }
  870. }
  871. // Download
  872. $tmpout.= '<li class="nowrap"><a class="pictopreview nowrap" href="'.DOL_URL_ROOT . '/document.php?modulepart='.$modulepart.'&amp;entity='.$entity.'&amp;file='.urlencode($relativepath).'"';
  873. $mime=dol_mimetype($relativepath,'',0);
  874. if (preg_match('/text/',$mime)) $tmpout.= ' target="_blank"';
  875. $tmpout.= '>';
  876. $tmpout.= img_mime($relativepath, $file["name"]);
  877. $tmpout.= $langs->trans("Download").' '.$ext;
  878. $tmpout.= '</a></li>'."\n";
  879. }
  880. $out.=$tmpout;
  881. $out.='</ul></div></dd>
  882. </dl>';
  883. if (! $found) $out='';
  884. }
  885. else
  886. {
  887. // TODO Add link to regenerate doc ?
  888. //$out.= '<div id="gen_pdf_'.$modulesubdir.'" class="linkobject hideobject">'.img_picto('', 'refresh').'</div>'."\n";
  889. }
  890. return $out;
  891. }
  892. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
  893. /**
  894. * Show list of documents in $filearray (may be they are all in same directory but may not)
  895. * This also sync database if $upload_dir is defined.
  896. *
  897. * @param array $filearray Array of files loaded by dol_dir_list('files') function before calling this.
  898. * @param Object $object Object on which document is linked to.
  899. * @param string $modulepart Value for modulepart used by download or viewimage wrapper.
  900. * @param string $param Parameters on sort links (param must start with &, example &aaa=bbb&ccc=ddd)
  901. * @param int $forcedownload Force to open dialog box "Save As" when clicking on file.
  902. * @param string $relativepath Relative path of docs (autodefined if not provided), relative to module dir, not to MAIN_DATA_ROOT.
  903. * @param int $permonobject Permission on object (so permission to delete or crop document)
  904. * @param int $useinecm Change output for use in ecm module:
  905. * 0: Add a previw link. Show also rename and crop file
  906. * 1: Add link to edit ECM entry
  907. * 2: Add rename and crop file
  908. * @param string $textifempty Text to show if filearray is empty ('NoFileFound' if not defined)
  909. * @param int $maxlength Maximum length of file name shown.
  910. * @param string $title Title before list. Use 'none' to disable title.
  911. * @param string $url Full url to use for click links ('' = autodetect)
  912. * @param int $showrelpart 0=Show only filename (default), 1=Show first level 1 dir
  913. * @param int $permtoeditline Permission to edit document line (You must provide a value, -1 is deprecated and must not be used any more)
  914. * @param string $upload_dir Full path directory so we can know dir relative to MAIN_DATA_ROOT. Fill this to complete file data with database indexes.
  915. * @param string $sortfield Sort field ('name', 'size', 'position', ...)
  916. * @param string $sortorder Sort order ('ASC' or 'DESC')
  917. * @param int $disablemove 1=Disable move button, 0=Position move is possible.
  918. * @param int $addfilterfields Add line with filters
  919. * @return int <0 if KO, nb of files shown if OK
  920. * @see list_of_autoecmfiles
  921. */
  922. 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)
  923. {
  924. // phpcs:enable
  925. global $user, $conf, $langs, $hookmanager;
  926. global $sortfield, $sortorder, $maxheightmini;
  927. global $dolibarr_main_url_root;
  928. global $form;
  929. $disablecrop=1;
  930. if (in_array($modulepart, array('expensereport','holiday','member','project','product','produit','service','societe','tax','ticket','user'))) $disablecrop=0;
  931. // Define relative path used to store the file
  932. if (empty($relativepath))
  933. {
  934. $relativepath=(! empty($object->ref)?dol_sanitizeFileName($object->ref):'').'/';
  935. 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
  936. if ($object->element == 'project_task') $relativepath='Call_not_supported_._Call_function_using_a_defined_relative_path_.';
  937. }
  938. // For backward compatiblity, we detect file stored into an old path
  939. if (! empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO) && $filearray[0]['level1name'] == 'photos')
  940. {
  941. $relativepath=preg_replace('/^.*\/produit\//','',$filearray[0]['path']).'/';
  942. }
  943. // Defined relative dir to DOL_DATA_ROOT
  944. $relativedir = '';
  945. if ($upload_dir)
  946. {
  947. $relativedir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $upload_dir);
  948. $relativedir = preg_replace('/^[\\/]/','',$relativedir);
  949. }
  950. $hookmanager->initHooks(array('formfile'));
  951. $parameters=array(
  952. 'filearray' => $filearray,
  953. 'modulepart'=> $modulepart,
  954. 'param' => $param,
  955. 'forcedownload' => $forcedownload,
  956. 'relativepath' => $relativepath, // relative filename to module dir
  957. 'relativedir' => $relativedir, // relative dirname to DOL_DATA_ROOT
  958. 'permtodelete' => $permonobject,
  959. 'useinecm' => $useinecm,
  960. 'textifempty' => $textifempty,
  961. 'maxlength' => $maxlength,
  962. 'title' => $title,
  963. 'url' => $url
  964. );
  965. $reshook=$hookmanager->executeHooks('showFilesList', $parameters, $object);
  966. if (isset($reshook) && $reshook != '') // null or '' for bypass
  967. {
  968. return $reshook;
  969. }
  970. else
  971. {
  972. if (! is_object($form))
  973. {
  974. 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
  975. $form=new Form($this->db);
  976. }
  977. if (! preg_match('/&id=/', $param) && isset($object->id)) $param.='&id='.$object->id;
  978. $relativepathwihtoutslashend=preg_replace('/\/$/', '', $relativepath);
  979. if ($relativepathwihtoutslashend) $param.= '&file='.urlencode($relativepathwihtoutslashend);
  980. if ($permtoeditline < 0) // Old behaviour for backward compatibility. New feature should call method with value 0 or 1
  981. {
  982. $permtoeditline=0;
  983. if (in_array($modulepart, array('product','produit','service')))
  984. {
  985. if ($user->rights->produit->creer && $object->type == Product::TYPE_PRODUCT) $permtoeditline=1;
  986. if ($user->rights->service->creer && $object->type == Product::TYPE_SERVICE) $permtoeditline=1;
  987. }
  988. }
  989. if (empty($conf->global->MAIN_UPLOAD_DOC))
  990. {
  991. $permtoeditline=0;
  992. $permonobject=0;
  993. }
  994. // Show list of existing files
  995. if (empty($useinecm) && $title != 'none') print load_fiche_titre($title?$title:$langs->trans("AttachedFiles"));
  996. if (empty($url)) $url=$_SERVER["PHP_SELF"];
  997. print '<!-- html.formfile::list_of_documents -->'."\n";
  998. if (GETPOST('action','aZ09') == 'editfile' && $permtoeditline)
  999. {
  1000. print '<form action="'.$_SERVER["PHP_SELF"].'?'.$param.'" method="POST">';
  1001. print '<input type="hidden" name="action" value="renamefile">';
  1002. print '<input type="hidden" name="id" value="'.$object->id.'">';
  1003. print '<input type="hidden" name="modulepart" value="'.$modulepart.'">';
  1004. }
  1005. print '<div class="div-table-responsive-no-min">';
  1006. print '<table width="100%" id="tablelines" class="'.($useinecm?'liste noborder':'liste').'">'."\n";
  1007. if (! empty($addfilterfields))
  1008. {
  1009. print '<tr class="liste_titre nodrag nodrop">';
  1010. print '<td><input type="search_doc_ref" value="'.dol_escape_htmltag(GETPOST('search_doc_ref','alpha')).'"></td>';
  1011. print '<td></td>';
  1012. print '<td></td>';
  1013. if (empty($useinecm)) print '<td></td>';
  1014. print '<td></td>';
  1015. print '<td></td>';
  1016. if (! $disablemove) print '<td></td>';
  1017. print "</tr>\n";
  1018. }
  1019. print '<tr class="liste_titre nodrag nodrop">';
  1020. //print $url.' sortfield='.$sortfield.' sortorder='.$sortorder;
  1021. print_liste_field_titre('Documents2',$url,"name","",$param,'align="left"',$sortfield,$sortorder);
  1022. print_liste_field_titre('Size',$url,"size","",$param,'align="right"',$sortfield,$sortorder);
  1023. print_liste_field_titre('Date',$url,"date","",$param,'align="center"',$sortfield,$sortorder);
  1024. if (empty($useinecm)) print_liste_field_titre('',$url,"","",$param,'align="center"'); // Preview
  1025. print_liste_field_titre('');
  1026. print_liste_field_titre('');
  1027. if (! $disablemove) print_liste_field_titre('');
  1028. print "</tr>\n";
  1029. // Get list of files stored into database for same relative directory
  1030. if ($relativedir)
  1031. {
  1032. completeFileArrayWithDatabaseInfo($filearray, $relativedir);
  1033. //var_dump($sortfield.' - '.$sortorder);
  1034. if ($sortfield && $sortorder) // If $sortfield is for example 'position_name', we will sort on the property 'position_name' (that is concat of position+name)
  1035. {
  1036. $filearray=dol_sort_array($filearray, $sortfield, $sortorder);
  1037. }
  1038. }
  1039. $nboffiles=count($filearray);
  1040. if ($nboffiles > 0) include_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
  1041. $i=0; $nboflines = 0; $lastrowid=0;
  1042. foreach($filearray as $key => $file) // filearray must be only files here
  1043. {
  1044. if ($file['name'] != '.'
  1045. && $file['name'] != '..'
  1046. && ! preg_match('/\.meta$/i',$file['name']))
  1047. {
  1048. if ($filearray[$key]['rowid'] > 0) $lastrowid = $filearray[$key]['rowid'];
  1049. $filepath=$relativepath.$file['name'];
  1050. $editline=0;
  1051. $nboflines++;
  1052. print '<!-- Line list_of_documents '.$key.' relativepath = '.$relativepath.' -->'."\n";
  1053. // Do we have entry into database ?
  1054. print '<!-- In database: position='.$filearray[$key]['position'].' -->'."\n";
  1055. print '<tr class="oddeven" id="row-'.($filearray[$key]['rowid']>0?$filearray[$key]['rowid']:'AFTER'.$lastrowid.'POS'.($i+1)).'">';
  1056. // File name
  1057. print '<td class="minwith200">';
  1058. // Show file name with link to download
  1059. //print "XX".$file['name']; //$file['name'] must be utf8
  1060. print '<a class="paddingright" href="'.DOL_URL_ROOT.'/document.php?modulepart='.$modulepart;
  1061. if ($forcedownload) print '&attachment=1';
  1062. if (! empty($object->entity)) print '&entity='.$object->entity;
  1063. print '&file='.urlencode($filepath);
  1064. print '">';
  1065. print img_mime($file['name'], $file['name'].' ('.dol_print_size($file['size'],0,0).')', 'inline-block valignbottom paddingright');
  1066. if ($showrelpart == 1) print $relativepath;
  1067. //print dol_trunc($file['name'],$maxlength,'middle');
  1068. if (GETPOST('action','aZ09') == 'editfile' && $file['name'] == basename(GETPOST('urlfile','alpha')))
  1069. {
  1070. print '</a>';
  1071. $section_dir=dirname(GETPOST('urlfile','alpha'));
  1072. print '<input type="hidden" name="section_dir" value="'.$section_dir.'">';
  1073. print '<input type="hidden" name="renamefilefrom" value="'.dol_escape_htmltag($file['name']).'">';
  1074. print '<input type="text" name="renamefileto" class="quatrevingtpercent" value="'.dol_escape_htmltag($file['name']).'">';
  1075. $editline=1;
  1076. }
  1077. else
  1078. {
  1079. print dol_trunc($file['name'], 200);
  1080. print '</a>';
  1081. }
  1082. // Preview link
  1083. if (! $editline) print $this->showPreview($file, $modulepart, $filepath);
  1084. // Public share link
  1085. //if (! $editline && ! empty($filearray[$key]['hashp'])) print pictowithlinktodirectdownload;
  1086. print "</td>\n";
  1087. // Size
  1088. $sizetoshow = dol_print_size($file['size'],1,1);
  1089. $sizetoshowbytes = dol_print_size($file['size'],0,1);
  1090. print '<td align="right" width="80px">';
  1091. if ($sizetoshow == $sizetoshowbytes) print $sizetoshow;
  1092. else {
  1093. print $form->textwithpicto($sizetoshow, $sizetoshowbytes, -1);
  1094. }
  1095. print '</td>';
  1096. // Date
  1097. print '<td align="center" width="140px">'.dol_print_date($file['date'],"dayhour","tzuser").'</td>'; // 140px = width for date with PM format
  1098. // Preview
  1099. if (empty($useinecm))
  1100. {
  1101. $fileinfo = pathinfo($file['name']);
  1102. print '<td align="center">';
  1103. if (image_format_supported($file['name']) > 0)
  1104. {
  1105. $minifile=getImageFileNameForSize($file['name'], '_mini'); // For new thumbs using same ext (in lower case howerver) than original
  1106. if (! dol_is_file($file['path'].'/'.$minifile)) $minifile=getImageFileNameForSize($file['name'], '_mini', '.png'); // For backward compatibility of old thumbs that were created with filename in lower case and with .png extension
  1107. //print $file['path'].'/'.$minifile.'<br>';
  1108. $urlforhref=getAdvancedPreviewUrl($modulepart, $relativepath.$fileinfo['filename'].'.'.strtolower($fileinfo['extension']), 1, '&entity='.(!empty($object->entity)?$object->entity:$conf->entity));
  1109. if (empty($urlforhref)) {
  1110. $urlforhref=DOL_URL_ROOT.'/viewimage.php?modulepart='.$modulepart.'&entity='.(!empty($object->entity)?$object->entity:$conf->entity).'&file='.urlencode($relativepath.$fileinfo['filename'].'.'.strtolower($fileinfo['extension']));
  1111. print '<a href="'.$urlforhref.'" class="aphoto" target="_blank">';
  1112. } else {
  1113. print '<a href="'.$urlforhref['url'].'" class="'.$urlforhref['css'].'" target="'.$urlforhref['target'].'" mime="'.$urlforhref['mime'].'">';
  1114. }
  1115. print '<img border="0" height="'.$maxheightmini.'" src="'.DOL_URL_ROOT.'/viewimage.php?modulepart='.$modulepart.'&entity='.(!empty($object->entity)?$object->entity:$conf->entity).'&file='.urlencode($relativepath.$minifile).'" title="">';
  1116. print '</a>';
  1117. }
  1118. else print '&nbsp;';
  1119. print '</td>';
  1120. }
  1121. // 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)
  1122. print '<td align="center">';
  1123. if ($relativedir && $filearray[$key]['rowid'] > 0)
  1124. {
  1125. if ($editline)
  1126. {
  1127. print $langs->trans("FileSharedViaALink").' ';
  1128. print '<input class="inline-block" type="checkbox" name="shareenabled"'.($file['share']?' checked="checked"':'').' /> ';
  1129. }
  1130. else
  1131. {
  1132. if ($file['share'])
  1133. {
  1134. // Define $urlwithroot
  1135. $urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root));
  1136. $urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
  1137. //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current
  1138. //print '<span class="opacitymedium">'.$langs->trans("Hash").' : '.$file['share'].'</span>';
  1139. $forcedownload=0;
  1140. $paramlink='';
  1141. if (! empty($file['share'])) $paramlink.=($paramlink?'&':'').'hashp='.$file['share']; // Hash for public share
  1142. if ($forcedownload) $paramlink.=($paramlink?'&':'').'attachment=1';
  1143. $fulllink=$urlwithroot.'/document.php'.($paramlink?'?'.$paramlink:'');
  1144. print img_picto($langs->trans("FileSharedViaALink"),'object_globe.png').' ';
  1145. print '<input type="text" class="quatrevingtpercent" id="downloadlink" name="downloadexternallink" value="'.dol_escape_htmltag($fulllink).'">';
  1146. }
  1147. else
  1148. {
  1149. //print '<span class="opacitymedium">'.$langs->trans("FileNotShared").'</span>';
  1150. }
  1151. }
  1152. }
  1153. print '</td>';
  1154. // Actions buttons
  1155. if (! $editline)
  1156. {
  1157. // Delete or view link
  1158. // ($param must start with &)
  1159. print '<td class="valignmiddle right actionbuttons"><!-- action on files -->';
  1160. if ($useinecm == 1)
  1161. {
  1162. print '<a href="'.DOL_URL_ROOT.'/ecm/file_card.php?urlfile='.urlencode($file['name']).$param.'" class="editfilelink" rel="'.urlencode($file['name']).'">'.img_edit('default', 0, 'class="paddingrightonly"').'</a>';
  1163. }
  1164. if (! $useinecm || $useinecm == 2)
  1165. {
  1166. $newmodulepart=$modulepart;
  1167. if (in_array($modulepart, array('product','produit','service'))) $newmodulepart='produit|service';
  1168. if (! $disablecrop && image_format_supported($file['name']) > 0)
  1169. {
  1170. if ($permtoeditline)
  1171. {
  1172. // Link to resize
  1173. print '<a href="'.DOL_URL_ROOT.'/core/photos_resize.php?modulepart='.urlencode($newmodulepart).'&id='.$object->id.'&file='.urlencode($relativepath.$fileinfo['filename'].'.'.strtolower($fileinfo['extension'])).'" title="'.dol_escape_htmltag($langs->trans("ResizeOrCrop")).'">'.img_picto($langs->trans("ResizeOrCrop"),'resize','class="paddingrightonly"').'</a>';
  1174. }
  1175. }
  1176. if ($permtoeditline)
  1177. {
  1178. $paramsectiondir=(in_array($modulepart, array('medias','ecm'))?'&section_dir='.urlencode($relativepath):'');
  1179. print '<a href="'.(($useinecm == 1)?'#':($url.'?action=editfile&urlfile='.urlencode($filepath).$paramsectiondir.$param)).'" class="editfilelink" rel="'.$filepath.'">'.img_edit('default',0,'class="paddingrightonly"').'</a>';
  1180. }
  1181. }
  1182. if ($permonobject)
  1183. {
  1184. $useajax=1;
  1185. if (! empty($conf->dol_use_jmobile)) $useajax=0;
  1186. if (empty($conf->use_javascript_ajax)) $useajax=0;
  1187. if (! empty($conf->global->MAIN_ECM_DISABLE_JS)) $useajax=0;
  1188. print '<a href="'.(($useinecm && $useajax)?'#':($url.'?action=delete&urlfile='.urlencode($filepath).$param)).'" class="deletefilelink" rel="'.$filepath.'">'.img_delete().'</a>';
  1189. }
  1190. print "</td>";
  1191. if (empty($disablemove))
  1192. {
  1193. if ($nboffiles > 1 && $conf->browser->layout != 'phone') {
  1194. print '<td align="center" class="linecolmove tdlineupdown">';
  1195. if ($i > 0) {
  1196. print '<a class="lineupdown" href="'.$_SERVER["PHP_SELF"].'?id='.$this->id.'&amp;action=up&amp;rowid='.$line->id.'">'.img_up('default',0,'imgupforline').'</a>';
  1197. }
  1198. if ($i < $nboffiles-1) {
  1199. print '<a class="lineupdown" href="'.$_SERVER["PHP_SELF"].'?id='.$this->id.'&amp;action=down&amp;rowid='.$line->id.'">'.img_down('default',0,'imgdownforline').'</a>';
  1200. }
  1201. print '</td>';
  1202. }
  1203. else {
  1204. print '<td align="center"'.(($conf->browser->layout != 'phone' && empty($disablemove)) ?' class="linecolmove tdlineupdown"':' class="linecolmove"').'>';
  1205. print '</td>';
  1206. }
  1207. }
  1208. }
  1209. else
  1210. {
  1211. print '<td class="right">';
  1212. print '<input type="hidden" name="ecmfileid" value="'.$filearray[$key]['rowid'].'">';
  1213. print '<input type="submit" class="button" name="renamefilesave" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
  1214. print '<input type="submit" class="button" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
  1215. print '</td>';
  1216. if (empty($disablemove)) print '<td class="right"></td>';
  1217. }
  1218. print "</tr>\n";
  1219. $i++;
  1220. }
  1221. }
  1222. if ($nboffiles == 0)
  1223. {
  1224. $colspan=(empty($useinecm)?'6':'6');
  1225. if (empty($disablemove)) $colspan++; // 6 columns or 7
  1226. print '<tr class="oddeven"><td colspan="'.$colspan.'" class="opacitymedium">';
  1227. if (empty($textifempty)) print $langs->trans("NoFileFound");
  1228. else print $textifempty;
  1229. print '</td></tr>';
  1230. }
  1231. print "</table>";
  1232. print '</div>';
  1233. if ($nboflines > 1 && is_object($object)) {
  1234. if (! empty($conf->use_javascript_ajax) && $permtoeditline) {
  1235. $table_element_line = 'ecm_files';
  1236. include DOL_DOCUMENT_ROOT . '/core/tpl/ajaxrow.tpl.php';
  1237. }
  1238. }
  1239. print ajax_autoselect('downloadlink');
  1240. if (GETPOST('action','aZ09') == 'editfile' && $permtoeditline)
  1241. {
  1242. print '</form>';
  1243. }
  1244. return $nboffiles;
  1245. }
  1246. }
  1247. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
  1248. /**
  1249. * Show list of documents in a directory
  1250. *
  1251. * @param string $upload_dir Directory that was scanned
  1252. * @param array $filearray Array of files loaded by dol_dir_list function before calling this function
  1253. * @param string $modulepart Value for modulepart used by download wrapper
  1254. * @param string $param Parameters on sort links
  1255. * @param int $forcedownload Force to open dialog box "Save As" when clicking on file
  1256. * @param string $relativepath Relative path of docs (autodefined if not provided)
  1257. * @param int $permtodelete Permission to delete
  1258. * @param int $useinecm Change output for use in ecm module
  1259. * @param int $textifempty Text to show if filearray is empty
  1260. * @param int $maxlength Maximum length of file name shown
  1261. * @param string $url Full url to use for click links ('' = autodetect)
  1262. * @param int $addfilterfields Add line with filters
  1263. * @return int <0 if KO, nb of files shown if OK
  1264. * @see list_of_documents
  1265. */
  1266. function list_of_autoecmfiles($upload_dir, $filearray, $modulepart, $param, $forcedownload=0, $relativepath='', $permtodelete=1, $useinecm=0, $textifempty='', $maxlength=0, $url='', $addfilterfields=0)
  1267. {
  1268. // phpcs:enable
  1269. global $user, $conf, $langs, $form;
  1270. global $sortfield, $sortorder;
  1271. global $search_doc_ref;
  1272. dol_syslog(get_class($this).'::list_of_autoecmfiles upload_dir='.$upload_dir.' modulepart='.$modulepart);
  1273. // Show list of documents
  1274. if (empty($useinecm)) print load_fiche_titre($langs->trans("AttachedFiles"));
  1275. if (empty($url)) $url=$_SERVER["PHP_SELF"];
  1276. if (! empty($addfilterfields))
  1277. {
  1278. print '<form action="'.$_SERVER['PHP_SELF'].'">';
  1279. print '<input type="hidden" name="module" value="'.$modulepart.'">';
  1280. }
  1281. print '<div class="div-table-responsive-no-min">';
  1282. print '<table width="100%" class="noborder">'."\n";
  1283. if (! empty($addfilterfields))
  1284. {
  1285. print '<tr class="liste_titre nodrag nodrop">';
  1286. print '<td></td>';
  1287. print '<td><input type="text" class="maxwidth100onsmartphone" name="search_doc_ref" value="'.dol_escape_htmltag($search_doc_ref).'"></td>';
  1288. print '<td></td>';
  1289. print '<td></td>';
  1290. // Action column
  1291. print '<td class="liste_titre" align="middle">';
  1292. $searchpicto=$form->showFilterButtons();
  1293. print $searchpicto;
  1294. print '</td>';
  1295. print "</tr>\n";
  1296. }
  1297. print '<tr class="liste_titre">';
  1298. $sortref="fullname";
  1299. if ($modulepart == 'invoice_supplier') $sortref='level1name';
  1300. print_liste_field_titre("Ref",$url,$sortref,"",$param,'align="left"',$sortfield,$sortorder);
  1301. print_liste_field_titre("Documents2",$url,"name","",$param,'align="left"',$sortfield,$sortorder);
  1302. print_liste_field_titre("Size",$url,"size","",$param,'align="right"',$sortfield,$sortorder);
  1303. print_liste_field_titre("Date",$url,"date","",$param,'align="center"',$sortfield,$sortorder);
  1304. print_liste_field_titre('','','');
  1305. print '</tr>'."\n";
  1306. // To show ref or specific information according to view to show (defined by $module)
  1307. if ($modulepart == 'company')
  1308. {
  1309. include_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
  1310. $object_instance=new Societe($this->db);
  1311. }
  1312. else if ($modulepart == 'invoice')
  1313. {
  1314. include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
  1315. $object_instance=new Facture($this->db);
  1316. }
  1317. else if ($modulepart == 'invoice_supplier')
  1318. {
  1319. include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
  1320. $object_instance=new FactureFournisseur($this->db);
  1321. }
  1322. else if ($modulepart == 'propal')
  1323. {
  1324. include_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
  1325. $object_instance=new Propal($this->db);
  1326. }
  1327. else if ($modulepart == 'supplier_proposal')
  1328. {
  1329. include_once DOL_DOCUMENT_ROOT.'/supplier_proposal/class/supplier_proposal.class.php';
  1330. $object_instance=new SupplierProposal($this->db);
  1331. }
  1332. else if ($modulepart == 'order')
  1333. {
  1334. include_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
  1335. $object_instance=new Commande($this->db);
  1336. }
  1337. else if ($modulepart == 'order_supplier')
  1338. {
  1339. include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
  1340. $object_instance=new CommandeFournisseur($this->db);
  1341. }
  1342. else if ($modulepart == 'contract')
  1343. {
  1344. include_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php';
  1345. $object_instance=new Contrat($this->db);
  1346. }
  1347. else if ($modulepart == 'product')
  1348. {
  1349. include_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
  1350. $object_instance=new Product($this->db);
  1351. }
  1352. else if ($modulepart == 'tax')
  1353. {
  1354. include_once DOL_DOCUMENT_ROOT.'/compta/sociales/class/chargesociales.class.php';
  1355. $object_instance=new ChargeSociales($this->db);
  1356. }
  1357. else if ($modulepart == 'project')
  1358. {
  1359. include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
  1360. $object_instance=new Project($this->db);
  1361. }
  1362. else if ($modulepart == 'fichinter')
  1363. {
  1364. include_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinter.class.php';
  1365. $object_instance=new Fichinter($this->db);
  1366. }
  1367. else if ($modulepart == 'user')
  1368. {
  1369. include_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
  1370. $object_instance=new User($this->db);
  1371. }
  1372. else if ($modulepart == 'expensereport')
  1373. {
  1374. include_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
  1375. $object_instance=new ExpenseReport($this->db);
  1376. }
  1377. else if ($modulepart == 'holiday')
  1378. {
  1379. include_once DOL_DOCUMENT_ROOT.'/holiday/class/holiday.class.php';
  1380. $object_instance=new Holiday($this->db);
  1381. }
  1382. foreach($filearray as $key => $file)
  1383. {
  1384. if (!is_dir($file['name'])
  1385. && $file['name'] != '.'
  1386. && $file['name'] != '..'
  1387. && $file['name'] != 'CVS'
  1388. && ! preg_match('/\.meta$/i',$file['name']))
  1389. {
  1390. // Define relative path used to store the file
  1391. $relativefile=preg_replace('/'.preg_quote($upload_dir.'/','/').'/','',$file['fullname']);
  1392. //var_dump($file);
  1393. $id=0; $ref=''; $label='';
  1394. // To show ref or specific information according to view to show (defined by $module)
  1395. if ($modulepart == 'company') { preg_match('/(\d+)\/[^\/]+$/',$relativefile,$reg); $id=(isset($reg[1])?$reg[1]:''); }
  1396. if ($modulepart == 'invoice') { preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg); $ref=(isset($reg[1])?$reg[1]:''); }
  1397. if ($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
  1398. if ($modulepart == 'propal') { preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg); $ref=(isset($reg[1])?$reg[1]:''); }
  1399. if ($modulepart == 'supplier_proposal') { preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg); $ref=(isset($reg[1])?$reg[1]:''); }
  1400. if ($modulepart == 'order') { preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg); $ref=(isset($reg[1])?$reg[1]:''); }
  1401. if ($modulepart == 'order_supplier') { preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg); $ref=(isset($reg[1])?$reg[1]:''); }
  1402. if ($modulepart == 'contract') { preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg); $ref=(isset($reg[1])?$reg[1]:''); }
  1403. if ($modulepart == 'product') { preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg); $ref=(isset($reg[1])?$reg[1]:''); }
  1404. if ($modulepart == 'tax') { preg_match('/(\d+)\/[^\/]+$/',$relativefile,$reg); $id=(isset($reg[1])?$reg[1]:''); }
  1405. if ($modulepart == 'project') { preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg); $ref=(isset($reg[1])?$reg[1]:'');}
  1406. if ($modulepart == 'fichinter') { preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg); $ref=(isset($reg[1])?$reg[1]:'');}
  1407. if ($modulepart == 'user') { preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg); $id=(isset($reg[1])?$reg[1]:'');}
  1408. if ($modulepart == 'expensereport') { preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg); $ref=(isset($reg[1])?$reg[1]:'');}
  1409. if ($modulepart == 'holiday') { preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg); $id=(isset($reg[1])?$reg[1]:'');}
  1410. if (! $id && ! $ref) continue;
  1411. $found=0;
  1412. if (! empty($this->cache_objects[$modulepart.'_'.$id.'_'.$ref]))
  1413. {
  1414. $found=1;
  1415. }
  1416. else
  1417. {
  1418. //print 'Fetch '.$id." - ".$ref.'<br>';
  1419. if ($id) {
  1420. $result = $object_instance->fetch($id);
  1421. } else {
  1422. //fetchOneLike looks for objects with wildcards in its reference.
  1423. //It is useful for those masks who get underscores instead of their actual symbols
  1424. //fetchOneLike requires some info in the object. If it doesn't have it, then 0 is returned
  1425. //that's why we look only look fetchOneLike when fetch returns 0
  1426. if (!$result = $object_instance->fetch('', $ref)) {
  1427. $result = $object_instance->fetchOneLike($ref);
  1428. }
  1429. }
  1430. if ($result > 0) { // Save object into a cache
  1431. $found=1; $this->cache_objects[$modulepart.'_'.$id.'_'.$ref] = clone $object_instance;
  1432. }
  1433. if ($result == 0) { $found=1; $this->cache_objects[$modulepart.'_'.$id.'_'.$ref]='notfound'; unset($filearray[$key]); }
  1434. }
  1435. if (! $found > 0 || ! is_object($this->cache_objects[$modulepart.'_'.$id.'_'.$ref])) continue; // We do not show orphelins files
  1436. print '<!-- Line list_of_autoecmfiles '.$key.' -->'."\n";
  1437. print '<tr class="oddeven">';
  1438. print '<td>';
  1439. if ($found > 0 && is_object($this->cache_objects[$modulepart.'_'.$id.'_'.$ref])) print $this->cache_objects[$modulepart.'_'.$id.'_'.$ref]->getNomUrl(1,'document');
  1440. else print $langs->trans("ObjectDeleted",($id?$id:$ref));
  1441. //$modulesubdir=dol_sanitizeFileName($ref);
  1442. $modulesubdir=dirname($relativefile);
  1443. //$filedir=$conf->$modulepart->dir_output . '/' . dol_sanitizeFileName($obj->ref);
  1444. $filedir=$file['path'];
  1445. //$urlsource=$_SERVER['PHP_SELF'].'?id='.$obj->rowid;
  1446. //print $formfile->getDocumentsLink($modulepart, $filename, $filedir);
  1447. print '</td>';
  1448. // File
  1449. print '<td>';
  1450. //print "XX".$file['name']; //$file['name'] must be utf8
  1451. print '<a href="'.DOL_URL_ROOT.'/document.php?modulepart='.$modulepart;
  1452. if ($forcedownload) print '&attachment=1';
  1453. print '&file='.urlencode($relativefile).'">';
  1454. print img_mime($file['name'],$file['name'].' ('.dol_print_size($file['size'],0,0).')');
  1455. print dol_trunc($file['name'],$maxlength,'middle');
  1456. print '</a>';
  1457. //print $this->getDocumentsLink($modulepart, $modulesubdir, $filedir, '^'.preg_quote($file['name'],'/').'$');
  1458. print $this->showPreview($file, $modulepart, $file['relativename']);
  1459. print "</td>\n";
  1460. print '<td align="right">'.dol_print_size($file['size'],1,1).'</td>';
  1461. print '<td align="center">'.dol_print_date($file['date'],"dayhour").'</td>';
  1462. print '<td align="right">';
  1463. //if (! empty($useinecm)) print '<a data-ajax="false" href="'.DOL_URL_ROOT.'/document.php?modulepart='.$modulepart;
  1464. //if ($forcedownload) print '&attachment=1';
  1465. //print '&file='.urlencode($relativefile).'">';
  1466. //print img_view().'</a> &nbsp; ';
  1467. //if ($permtodelete) print '<a href="'.$url.'?id='.$object->id.'&section='.$_REQUEST["section"].'&action=delete&urlfile='.urlencode($file['name']).'">'.img_delete().'</a>';
  1468. //else print '&nbsp;';
  1469. print "</td></tr>\n";
  1470. }
  1471. }
  1472. if (count($filearray) == 0)
  1473. {
  1474. print '<tr class="oddeven"><td colspan="5">';
  1475. if (empty($textifempty)) print $langs->trans("NoFileFound");
  1476. else print $textifempty;
  1477. print '</td></tr>';
  1478. }
  1479. print "</table>";
  1480. print '</div>';
  1481. if (! empty($addfilterfields)) print '</form>';
  1482. // Fin de zone
  1483. }
  1484. /**
  1485. * Show form to upload a new file with jquery fileupload.
  1486. * This form use the fileupload.php file.
  1487. *
  1488. * @param Object $object Object to use
  1489. * @return void
  1490. */
  1491. private function _formAjaxFileUpload($object)
  1492. {
  1493. global $langs, $conf;
  1494. // PHP post_max_size
  1495. $post_max_size = ini_get('post_max_size');
  1496. $mul_post_max_size = substr($post_max_size, -1);
  1497. $mul_post_max_size = ($mul_post_max_size == 'M' ? 1048576 : ($mul_post_max_size == 'K' ? 1024 : ($mul_post_max_size == 'G' ? 1073741824 : 1)));
  1498. $post_max_size = $mul_post_max_size * (int) $post_max_size;
  1499. // PHP upload_max_filesize
  1500. $upload_max_filesize = ini_get('upload_max_filesize');
  1501. $mul_upload_max_filesize = substr($upload_max_filesize, -1);
  1502. $mul_upload_max_filesize = ($mul_upload_max_filesize == 'M' ? 1048576 : ($mul_upload_max_filesize == 'K' ? 1024 : ($mul_upload_max_filesize == 'G' ? 1073741824 : 1)));
  1503. $upload_max_filesize = $mul_upload_max_filesize * (int) $upload_max_filesize;
  1504. // Max file size
  1505. $max_file_size = (($post_max_size < $upload_max_filesize) ? $post_max_size : $upload_max_filesize);
  1506. // Include main
  1507. include DOL_DOCUMENT_ROOT.'/core/tpl/ajax/fileupload_main.tpl.php';
  1508. // Include template
  1509. include DOL_DOCUMENT_ROOT.'/core/tpl/ajax/fileupload_view.tpl.php';
  1510. }
  1511. /**
  1512. * Show array with linked files
  1513. *
  1514. * @param Object $object Object
  1515. * @param int $permtodelete Deletion is allowed
  1516. * @param string $action Action
  1517. * @param string $selected ???
  1518. * @param string $param More param to add into URL
  1519. * @return int Number of links
  1520. */
  1521. public function listOfLinks($object, $permtodelete=1, $action=null, $selected=null, $param='')
  1522. {
  1523. global $user, $conf, $langs, $user;
  1524. global $sortfield, $sortorder;
  1525. $langs->load("link");
  1526. require_once DOL_DOCUMENT_ROOT . '/core/class/link.class.php';
  1527. $link = new Link($this->db);
  1528. $links = array();
  1529. if ($sortfield == "name") {
  1530. $sortfield = "label";
  1531. } elseif ($sortfield == "date") {
  1532. $sortfield = "datea";
  1533. } else {
  1534. $sortfield = null;
  1535. }
  1536. $res = $link->fetchAll($links, $object->element, $object->id, $sortfield, $sortorder);
  1537. $param .= (isset($object->id)?'&id=' . $object->id : '');
  1538. // Show list of associated links
  1539. print load_fiche_titre($langs->trans("LinkedFiles"));
  1540. print '<form action="' . $_SERVER['PHP_SELF'] . ($param?'?'.$param:'') . '" method="POST">';
  1541. print '<table width="100%" class="liste">';
  1542. print '<tr class="liste_titre">';
  1543. print_liste_field_titre(
  1544. $langs->trans("Links"),
  1545. $_SERVER['PHP_SELF'],
  1546. "name",
  1547. "",
  1548. $param,
  1549. 'align="left"',
  1550. $sortfield,
  1551. $sortorder
  1552. );
  1553. print_liste_field_titre(
  1554. "",
  1555. "",
  1556. "",
  1557. "",
  1558. "",
  1559. 'align="right"'
  1560. );
  1561. print_liste_field_titre(
  1562. $langs->trans("Date"),
  1563. $_SERVER['PHP_SELF'],
  1564. "date",
  1565. "",
  1566. $param,
  1567. 'align="center"',
  1568. $sortfield,
  1569. $sortorder
  1570. );
  1571. print_liste_field_titre(
  1572. '',
  1573. $_SERVER['PHP_SELF'],
  1574. "",
  1575. "",
  1576. $param,
  1577. 'align="center"'
  1578. );
  1579. print_liste_field_titre('','','');
  1580. print '</tr>';
  1581. $nboflinks = count($links);
  1582. if ($nboflinks > 0) include_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
  1583. foreach ($links as $link)
  1584. {
  1585. print '<tr class="oddeven">';
  1586. //edit mode
  1587. if ($action == 'update' && $selected === $link->id)
  1588. {
  1589. print '<td>';
  1590. print '<input type="hidden" name="id" value="' . $object->id . '">';
  1591. print '<input type="hidden" name="linkid" value="' . $link->id . '">';
  1592. print '<input type="hidden" name="action" value="confirm_updateline">';
  1593. print $langs->trans('Link') . ': <input type="text" name="link" value="' . $link->url . '">';
  1594. print '</td>';
  1595. print '<td>';
  1596. print $langs->trans('Label') . ': <input type="text" name="label" value="' . $link->label . '">';
  1597. print '</td>';
  1598. print '<td align="center">' . dol_print_date(dol_now(), "dayhour", "tzuser") . '</td>';
  1599. print '<td align="right"></td>';
  1600. print '<td align="right">';
  1601. print '<input type="submit" name="save" class="button" value="' . dol_escape_htmltag($langs->trans('Save')) . '">';
  1602. print '<input type="submit" name="cancel" class="button" value="' . dol_escape_htmltag($langs->trans('Cancel')) . '">';
  1603. print '</td>';
  1604. }
  1605. else
  1606. {
  1607. print '<td>';
  1608. print img_picto('', 'object_globe').' ';
  1609. print '<a data-ajax="false" href="' . $link->url . '" target="_blank">';
  1610. print $link->label;
  1611. print '</a>';
  1612. print '</td>'."\n";
  1613. print '<td align="right"></td>';
  1614. print '<td align="center">' . dol_print_date($link->datea, "dayhour", "tzuser") . '</td>';
  1615. print '<td align="center"></td>';
  1616. print '<td align="right">';
  1617. print '<a href="' . $_SERVER['PHP_SELF'] . '?action=update&linkid=' . $link->id . $param . '" class="editfilelink" >' . img_edit() . '</a>'; // id= is included into $param
  1618. if ($permtodelete) {
  1619. print ' &nbsp; <a href="'. $_SERVER['PHP_SELF'] .'?action=delete&linkid=' . $link->id . $param . '" class="deletefilelink">' . img_delete() . '</a>'; // id= is included into $param
  1620. } else {
  1621. print '&nbsp;';
  1622. }
  1623. print '</td>';
  1624. }
  1625. print "</tr>\n";
  1626. }
  1627. if ($nboflinks == 0)
  1628. {
  1629. print '<tr class="oddeven"><td colspan="5" class="opacitymedium">';
  1630. print $langs->trans("NoLinkFound");
  1631. print '</td></tr>';
  1632. }
  1633. print "</table>";
  1634. print '</form>';
  1635. return $nboflinks;
  1636. }
  1637. /**
  1638. * Show detail icon with link for preview
  1639. *
  1640. * @param array $file Array with data of file. Example: array('name'=>...)
  1641. * @param string $modulepart propal, facture, facture_fourn, ...
  1642. * @param string $relativepath Relative path of docs
  1643. * @param string $ruleforpicto Rule for picto: 0=Use the generic preview picto, 1=Use the picto of mime type of file)
  1644. * @param string $param More param on http links
  1645. * @return string $out Output string with HTML
  1646. */
  1647. public function showPreview($file, $modulepart, $relativepath, $ruleforpicto=0, $param='')
  1648. {
  1649. global $langs, $conf;
  1650. $out='';
  1651. if ($conf->browser->layout != 'phone' && ! empty($conf->use_javascript_ajax))
  1652. {
  1653. $urladvancedpreview=getAdvancedPreviewUrl($modulepart, $relativepath, 1, $param); // Return if a file is qualified for preview.
  1654. if (count($urladvancedpreview))
  1655. {
  1656. $out.= '<a class="pictopreview '.$urladvancedpreview['css'].'" href="'.$urladvancedpreview['url'].'"'.(empty($urladvancedpreview['mime'])?'':' mime="'.$urladvancedpreview['mime'].'"').' '.(empty($urladvancedpreview['target'])?'':' target="'.$urladvancedpreview['target'].'"').'>';
  1657. //$out.= '<a class="pictopreview">';
  1658. if (empty($ruleforpicto))
  1659. {
  1660. //$out.= img_picto($langs->trans('Preview').' '.$file['name'], 'detail');
  1661. $out.='<span class="fa fa-search-plus" style="color: gray"></span>';
  1662. }
  1663. else $out.= img_mime($relativepath, $langs->trans('Preview').' '.$file['name']);
  1664. $out.= '</a>';
  1665. }
  1666. }
  1667. return $out;
  1668. }
  1669. }