Passed
Push — EXTRACT_CLASSES ( 0382f2...c25e41 )
by Rafael
52:18
created

FormFile::showdocuments()   F

Complexity

Conditions 185
Paths > 20000

Size

Total Lines 706
Code Lines 456

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 185
eloc 456
nc 29290218
nop 21
dl 0
loc 706
rs 0
c 0
b 0
f 0

How to fix   Long Method    Complexity    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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