dolibarr 24.0.0-beta
upload_page.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2005-2017 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
4 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
5 *
6 * This file is a modified version of datepicker.php from phpBSM to fix some
7 * bugs, to add new features and to dramatically increase speed.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 */
22
28require_once '../main.inc.php';
36require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
37require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
38require_once DOL_DOCUMENT_ROOT.'/ai/class/ai.class.php';
39
40
41if (GETPOST('lang', 'aZ09')) {
42 $langs->setDefaultLang(GETPOST('lang', 'aZ09')); // If language was forced on URL by the main.inc.php
43}
44
45$langs->loadLangs(array("main", "other"));
46
47$action = GETPOST('action', 'aZ09');
48$modulepart = GETPOST('modulepart', 'aZ09');
49
50// users/temp/import
51$upload_dir = $conf->user->dir_temp.'/import';
52dol_mkdir($upload_dir);
53
54$file = GETPOST('file');
55
56$originalfilename = $file;
57$uid = $thiid = $pid = $erid = $salid = 0;
58$reg = array();
59if (preg_match('/-uid([\d+])/', $file, $reg)) {
60 $uid = $reg[1];
61 $originalfilename = preg_replace('/-uid\d+/', '', $originalfilename);
62}
63if (preg_match('/-thiid([\d+])/', $file, $reg)) {
64 $thiid = $reg[1];
65 $originalfilename = preg_replace('/-thiid\d+/', '', $originalfilename);
66}
67if (preg_match('/-pid([\d+])/', $file, $reg)) {
68 $pid = $reg[1];
69 $originalfilename = preg_replace('/-pid\d+/', '', $originalfilename);
70}
71if (preg_match('/-erid([\d+])/', $file, $reg)) {
72 $erid = $reg[1];
73 $originalfilename = preg_replace('/-erid\d+/', '', $originalfilename);
74}
75if (preg_match('/-salid([\d+])/', $file, $reg)) {
76 $salid = $reg[1];
77 $originalfilename = preg_replace('/-salid\d+/', '', $originalfilename);
78}
79$originalfilename = preg_replace('/^upload_page-[a-z_]+-/', '', $originalfilename);
80
81$error = 0;
82
83$ai = new Ai($db);
84
85
86/*
87 * Actions
88 */
89
90if (getDolGlobalString('MAIN_USE_TOP_MENU_IMPORT_FILE') && !is_numeric(getDolGlobalString('MAIN_USE_TOP_MENU_IMPORT_FILE'))) {
91 $urlforuploadpage = getDolGlobalString('MAIN_USE_TOP_MENU_IMPORT_FILE');
92
93 header("Location: ".$urlforuploadpage);
94 exit(1);
95}
96
97if ($action == 'uploadfile') { // Test on permission not required here. Done later
98 if (!$modulepart) { // Should not happen
99 print 'Error, modulepart param is empty';
100 exit(1);
101 }
102
103 // $modulepart can be 'invoice_supplier', ...
104 $arrayobject = getElementProperties($modulepart);
105
106 $module = $arrayobject['module'];
107 $element = $arrayobject['element'];
108 $dir_output = $arrayobject['dir_output'];
109 $dir_temp = $arrayobject['dir_temp'];
110
111 $permlevel1 = 'read';
112 $permlevel2 = '';
113 $fileprefix = 'unknown';
114 if (in_array($modulepart, array('fournisseur', 'invoice_supplier'))) {
115 $permlevel1 = 'facture';
116 $permlevel2 = 'read';
117 $fileprefix = 'upload_page-'.$modulepart.'-uid'.$user->id.'-thiid'.(GETPOSTINT('socid') > 0 ? GETPOSTINT('socid') : 0).'-pid'.(GETPOSTINT('search_prodid') > 0 ? GETPOSTINT('search_prodid') : 0);
118 } elseif ($modulepart == 'expensereport') {
119 $fileprefix = 'upload_page-'.$modulepart.'-uid'.$user->id.'-erid'.(GETPOSTINT('userexpensereportid') > 0 ? GETPOSTINT('userexpensereportid') : 0).'-pid'.(GETPOSTINT('search_prodid') > 0 ? GETPOSTINT('search_prodid') : 0);
120 } elseif ($modulepart == 'salaries') {
121 $fileprefix = 'upload_page-'.$modulepart.'-uid'.$user->id.'-salid'.(GETPOSTINT('usersalaryid') > 0 ? GETPOSTINT('usersalaryid') : 0);
122 }
123
124 if ($permlevel2) {
125 $permissiontoadd = $user->hasRight($module, $permlevel1, $permlevel2); // Used by actions_linkedfiles
126 } else {
127 $permissiontoadd = $user->hasRight($module, $permlevel1); // Used by actions_linkedfiles
128 }
129 $forceFullTextIndexation = '0'; // Used by actions_linkedfiles
130
131
132 if (!empty($_FILES['userfile']['name'])) {
133 $fullnewname = $fileprefix.'-'.$_FILES['userfile']['name'];
134 $_FILES['userfile']['name'] = $fullnewname;
135
136 // $dir_output = output dir of object
137 // $dir_temp = temp dir of object
138 // $upload_dir is "users/temp/import"
139 include DOL_DOCUMENT_ROOT.'/core/actions_linkedfiles.inc.php';
140
141 // TODO Add a js call of ajax service and show instead a message
142 // @phpstan-ignore-next-line $error may have been modified by actions_linkedfiles.inc.php
143 if (!$error) {
144 header("Location: ".DOL_URL_ROOT.'/core/ajax/ajaxuploadpage.php?file='.urlencode($fullnewname));
145 exit;
146 }
147 }
148} else {
149 // Delete the temporary files that are used when uploading files
150 dol_delete_file($upload_dir.'/upload_page-by'.$user->id.'-*');
151}
152
153
154/*
155 * View
156 */
157
158$form = new Form($db);
159
160// Important: Following code is to avoid page request by browser and PHP CPU at each Dolibarr page access.
161/*
162if (GETPOSTINT('cache')) {
163 header('Cache-Control: max-age='.GETPOSTINT('cache').', public');
164 // For a .php, we must set an Expires to avoid to have it forced to an expired value by the web server
165 header('Expires: '.gmdate('D, d M Y H:i:s', dol_now('gmt') + GETPOSTINT('cache')).' GMT');
166 // HTTP/1.0
167 header('Pragma: token=public');
168} else {
169 // HTTP/1.0
170 header('Cache-Control: no-cache');
171}
172*/
173
174$title = $langs->trans("UploadFile");
175$help_url = '';
176
177$arrayofjs = array();
178$arrayofcss = array();
179
180llxHeader('', $title, $help_url, '', 0, 0, $arrayofjs, $arrayofcss, '', 'mod-upload page-card');
181
182print load_fiche_titre('', '', '', 0, '', '', '<h2>'.img_picto('', 'upload').' '.$title.'</h2>');
183
184
185// Instantiate hooks of thirdparty module
186$hookmanager->initHooks(array('uploadform'));
187
188// Define $uploadform
189$uploadform = '';
190
191
192$uploadform = '<div class="display-flex">';
193
194// Form to upload a supplier invoice
195if (isModEnabled('supplier_invoice')) {
196 $langs->load("bills");
197 $uploadform .= '
198 <div id="supplierinvoice" class="flex-item flex-item-uploadfile">'.img_picto('', 'bill', 'class="fa-2x"').'<br>
199 <div>'.$langs->trans("SupplierInvoice").'<br><br>';
200
201 $uploadform .= img_picto('', 'company', 'class="pictofixedwidth"');
202 $uploadform .= $form->select_company(GETPOSTINT('socid'), 'socid', '(statut:=:0)', $langs->transnoentitiesnoconv("Supplier"), 0, 0, array(), 0, 'maxwidth200 disableautoopen');
203
204 $uploadform .= '<br>';
205
206 $prodid = GETPOSTINT('prodid');
207 $prodtext = $langs->trans("RefOrLabel");
208
209 //$uploadform .= $form->select_produits_fournisseurs(0, $prodid, 'prodid', '', '', 0, 1, 2, $prodtext, 0, array(), GETPOSTINT('socid'), '1', 0, 'maxwidth200 disableautoopen', 0, '', null, 1);
210 $uploadform .= img_picto('', 'product', 'class="pictofixedwidth"');
211 $uploadform .= $form->select_produits_fournisseurs(0, $prodid, 'prodid', '', '', array(), 1, 1, 'maxwidth200 disableautoopen', $prodtext, 1);
212
213 $uploadform .= '<br>';
214
215 $uploadform .= '<br>
216 <small class="opacitymedium">'.$langs->trans("OrClickToSelectAFile").'...</small>
217 </div>
218 </div>';
219}
220
221// Form to upload an expense report
222if (isModEnabled('expensereport')) {
223 $langs->load("expensereport");
224 $uploadform .= '
225 <div id="userexpensereport" class="flex-item flex-item-uploadfile">'.img_picto('', 'expensereport', 'class="fa-2x"').'<br>
226 <div>'.$langs->trans("ExpenseReport").'<br><br>';
227
228 $uploadform .= img_picto('', 'user', 'class="pictofixedwidth"');
229 //$uploadform .= '<span class="disableautoopen">';
230 $uploadform .= $form->select_dolusers(GETPOSTINT('userexpensereportid') > 0 ? GETPOSTINT('userexpensereportid') : $user->id, 'userexpensereportid', $langs->transnoentitiesnoconv("User"), null, 0, 'hierarchyme', '', '', 0, 0, '', 0, '', 'maxwidth200 disableautoopen', 1);
231 //$uploadform .= '</span>';
232
233 $uploadform .= '<br>';
234
235 $uploadform .= '<br>
236 <small class="opacitymedium">'.$langs->trans("OrClickToSelectAFile").'...</small>
237 </div>
238 </div>';
239}
240
241
242// Form to upload a salary document
243if (isModEnabled('salaries')) {
244 $langs->load("salaries");
245 $uploadform .= '
246 <div id="userpayroll" class="flex-item flex-item-uploadfile">'.img_picto('', 'salary', 'class="fa-2x"').'<br>
247 <div>'.$langs->trans("UserPaySlip").'<br><br>';
248
249
250 $uploadform .= img_picto('', 'user', 'class="pictofixedwidth"');
251 //$uploadform .= '<span class="disableautoopen">';
252 $uploadform .= $form->select_dolusers(GETPOSTINT('usersalaryid') > 0 ? GETPOSTINT('usersalaryid') : $user->id, 'usersalaryid', $langs->transnoentitiesnoconv("Employee"), null, 0, 'hierarchyme', '', '', 0, 0, '', 0, '', 'maxwidth200 disableautoopen', 1);
253 //$uploadform .= '</span>';
254
255 $uploadform .= '<br>';
256
257 $uploadform .= '<br>
258 <small class="opacitymedium">'.$langs->trans("OrClickToSelectAFile").'...</small>
259 </div>
260 </div>';
261}
262
263
264
265$uploadform .= '</div>';
266
267
268// Execute hook printSearchForm
269$parameters = array('uploadform' => $uploadform);
270$reshook = $hookmanager->executeHooks('printUploadForm', $parameters); // Note that $action and $object may have been modified by some hooks
271if (empty($reshook)) {
272 $uploadform .= $hookmanager->resPrint;
273} else {
274 $uploadform = $hookmanager->resPrint;
275}
276
277$uploadform .= '<br>';
278
279
280if ($action == 'uploadfile') {
281 print $langs->trans("ImportInProcess", $originalfilename).'<br>';
282 print '<br>';
283
284 print $langs->trans("AIProcessingPleaseWait", $ai->getApiService()).'...';
285 print '<br>';
286
287 print '<div class="progress" title="80%">
288 <div class="progress-bar" role="progressbar" style="width: 0%" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
289 </div>';
290
291
292 print '</form>';
293 print "\n<!-- End Form -->\n";
294} else {
295 // Show all forms
296 print "\n";
297 print "<!-- Begin UploadForm -->\n";
298 print '<form id="uploadform" enctype="multipart/form-data" method="POST" action="'.dolBuildUrl($_SERVER["PHP_SELF"]).'">';
299 print '<input type="hidden" name="token" value="'.newToken().'">';
300 print '<input type="hidden" name="action" value="uploadfile">';
301 print '<input type="hidden" name="sendit" value="1">';
302 print '<input type="hidden" name="modulepart" id="modulepart" value="">';
303 print '<input type="hidden" name="overwritefile" value="1">';
304
305 print '<div class="center"><div class="center" style="padding: 10px;">';
306 print '<style>.menu_titre { padding-top: 7px; }</style>';
307 print '<div id="blockupload" class="center">'."\n";
308 //print '<input name="filenamePDF" id="filenamePDF" type="hideobject">';
309 print $uploadform;
310
311
312 $accept = '.pdf,image/*';
313 $disablemulti = 1;
314 $perm = 1;
315 $capture = 1;
316
317 $maxfilesizearray = getMaxFileSizeArray();
318 $max = $maxfilesizearray['max'];
319 $maxmin = $maxfilesizearray['maxmin'];
320 $maxphptoshow = $maxfilesizearray['maxphptoshow'];
321 $maxphptoshowparam = $maxfilesizearray['maxphptoshowparam'];
322 $out = '';
323 if ($maxmin > 0) {
324 $out .= '<input type="hidden" name="MAX_FILE_SIZE" value="'.($maxmin * 1024).'">'; // MAX_FILE_SIZE must precede the field type=file
325 }
326 $out .= '<input class="hideobject" type="file" id="fileInput" value=""';
327 // @phpstan-ignore-next-line
328 $out .= ((getDolGlobalString('MAIN_DISABLE_MULTIPLE_FILEUPLOAD') || $disablemulti) ? ' name="userfile"' : ' name="userfile[]" multiple');
329 // @phpstan-ignore-next-line
330 $out .= (!getDolGlobalString('MAIN_UPLOAD_DOC') || empty($perm) ? ' disabled' : '');
331 // @phpstan-ignore-next-line
332 $out .= (!empty($accept) ? ' accept="'.$accept.'"' : ' accept=""');
333 // @phpstan-ignore-next-line
334 $out .= (!empty($capture) ? ' capture="capture"' : '');
335 $out .= '>';
336
337 print $out;
338
339
340 print "<script>
341 $(document).ready(function() {
342 jQuery('#supplierinvoice:not(.disableautoopen)').on('click', function(event) {
343 console.log('Click on link supplierinvoice to open input file');
344 console.log(event);
345 if (!event.target.closest('.disableautoopen')) {
346 $('#modulepart').val('invoice_supplier');
347 $('#fileInput').click();
348 }
349 });
350
351 jQuery('#userexpensereport:not(.disableautoopen)').on('click', function(event) {
352 console.log('Click on link userexpensereport to open input file');
353 console.log(event);
354 if (!event.target.closest('.disableautoopen')) {
355 $('#modulepart').val('expensereport');
356 $('#fileInput').click();
357 }
358 });
359
360 jQuery('#userpayroll:not(.disableautoopen)').on('click', function(event) {
361 console.log('Click on link userpayroll to open input file');
362 console.log(event);
363 if (!event.target.closest('.disableautoopen')) {
364 $('#modulepart').val('salaries');
365 $('#fileInput').click();
366 }
367 });
368
369 jQuery('#fileInput').on('change', function(event) {
370 console.log(event);
371 console.log('A file was selected, we submit the form');
372 $('#uploadform').submit();
373 });
374 });
375 </script>";
376
377 print '</div>'."\n";
378 print '</div></div>';
379
380 print '</form>';
381 print "\n<!-- End UploadForm -->\n";
382}
383
384
385// End of page
386llxFooter();
387$db->close();
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
Definition wrapper.php:91
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
Definition wrapper.php:73
Class for AI feature.
Definition ai.class.php:36
Class to manage generation of HTML components Only common components must be here.
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $db
API class for accounts.
dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $object=null, $allowdotdot=false, $indexdatabase=1, $nolog=0)
Remove a file or several files with a mask.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='', $morecssonpicto='widthpictotitle')
Load a title with picto.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
getMaxFileSizeArray()
Return the max allowed for file upload.