html.formfile.class.php 81 KB

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