dolibarr 22.0.5
file_card.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2008-2020 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
4 * Copyright (C) 2025 MDW <mdeweerd@users.noreply.github.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
26// Load Dolibarr environment
27require '../main.inc.php';
28require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
29require_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmdirectory.class.php';
30require_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php';
31require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
32require_once DOL_DOCUMENT_ROOT.'/core/lib/ecm.lib.php';
33require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
34
45// Load translation files required by page
46$langs->loadLangs(array('ecm', 'companies', 'other', 'users', 'orders', 'propal', 'bills', 'contracts', 'categories'));
47
48$action = GETPOST('action', 'aZ09');
49$cancel = GETPOST('cancel', 'alpha');
50$backtopage = GETPOST('backtopage', 'alpha');
51
52// Get parameters
53$socid = GETPOSTINT("socid");
54
55// Security check
56if ($user->socid > 0) {
57 $action = '';
58 $socid = $user->socid;
59}
60
61$limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
62$sortfield = GETPOST('sortfield', 'aZ09comma');
63$sortorder = GETPOST('sortorder', 'aZ09comma');
64$page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page");
65if (empty($page) || $page == -1) {
66 $page = 0;
67} // If $page is not defined, or '' or -1
68$offset = $limit * $page;
69$pageprev = $page - 1;
70$pagenext = $page + 1;
71if (!$sortorder) {
72 $sortorder = "ASC";
73}
74if (!$sortfield) {
75 $sortfield = "label";
76}
77
78$section = GETPOST("section", 'alpha');
79if (!$section) {
80 dol_print_error(null, 'Error, section parameter missing');
81 exit;
82}
83$urlfile = (string) dol_sanitizePathName(GETPOST("urlfile"), '_', 0);
84if (!$urlfile) {
85 dol_print_error(null, "ErrorParamNotDefined");
86 exit;
87}
88
89// Load ecm object
90$ecmdir = new EcmDirectory($db);
91$result = $ecmdir->fetch(GETPOSTINT("section"));
92if (!($result > 0)) {
93 dol_print_error($db, $ecmdir->error);
94 exit;
95}
96$relativepath = $ecmdir->getRelativePath();
97$upload_dir = $conf->ecm->dir_output.'/'.$relativepath;
98
99$fullpath = $conf->ecm->dir_output.'/'.$relativepath.$urlfile;
100
101$relativetodocument = 'ecm/'.$relativepath; // $relativepath is relative to ECM dir, we need relative to document
102$filepath = $relativepath.$urlfile;
103$filepathtodocument = $relativetodocument.$urlfile;
104
105// Try to load object from index
106$object = new EcmFiles($db);
107$extrafields = new ExtraFields($db);
108// fetch optionals attributes and labels
109$extrafields->fetch_name_optionals_label($object->table_element);
110
111$result = $object->fetch(0, '', $filepathtodocument);
112if ($result < 0) {
113 dol_print_error($db, $object->error, $object->errors);
114 exit;
115}
116
117// Permissions
118$permissiontoread = $user->hasRight('ecm', 'read');
119$permissiontoadd = $user->hasRight('ecm', 'setup');
120$permissiontoupload = $user->hasRight('ecm', 'upload');
121
122if (!$permissiontoread) {
124}
125
126
127/*
128 * Actions
129 */
130
131if ($cancel) {
132 $action = '';
133 if ($backtopage) {
134 header("Location: ".$backtopage);
135 exit;
136 } else {
137 header('Location: '.$_SERVER["PHP_SELF"].'?urlfile='.urlencode($urlfile).'&section='.urlencode($section).($module ? '&module='.urlencode($module) : ''));
138 exit;
139 }
140}
141
142// Rename file
143if ($action == 'update' && $permissiontoadd) {
144 $error = 0;
145
146 $oldlabel = GETPOST('urlfile', 'alpha');
147 $newlabel = dol_sanitizeFileName(GETPOST('label', 'alpha'), '_', 0);
148 $shareenabled = GETPOST('shareenabled', 'alpha');
149
150 //$db->begin();
151
152 $olddir = $ecmdir->getRelativePath(0); // Relative to ecm
153 $olddirrelativetodocument = 'ecm/'.$olddir; // Relative to document
154 $newdirrelativetodocument = 'ecm/'.$olddir;
155 $olddir = $conf->ecm->dir_output.'/'.$olddir;
156 $newdir = $olddir;
157
158 $oldfile = $olddir.$oldlabel;
159 $newfile = $newdir.$newlabel;
160 $newfileformove = $newfile;
161 // If old file end with .noexe, new file must also end with .noexe
162 if (preg_match('/\.noexe$/', $oldfile) && !preg_match('/\.noexe$/', $newfileformove)) {
163 $newfileformove .= '.noexe';
164 }
165 //var_dump($oldfile);var_dump($newfile);exit;
166
167 // Now we update index of file
168 $db->begin();
169 //print $oldfile.' - '.$newfile;
170 if ($newlabel != $oldlabel) {
171 $result = dol_move($oldfile, $newfileformove); // This include update of database
172 if (!$result) {
173 $langs->load('errors');
174 setEventMessages($langs->trans('ErrorFailToRenameFile', $oldfile, $newfile), null, 'errors');
175 $error++;
176 }
177
178 // Reload object after the move
179 $result = $object->fetch(0, '', $newdirrelativetodocument.$newlabel);
180 if ($result < 0) {
181 dol_print_error($db, $object->error, $object->errors);
182 exit;
183 }
184 }
185
186 if (!$error) {
187 if ($shareenabled) {
188 require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
189 $object->share = getRandomPassword(true);
190 } else {
191 $object->share = '';
192 }
193
194 if ($object->id > 0) {
195 $ret = $extrafields->setOptionalsFromPost(null, $object);
196 if ($ret < 0) {
197 $error++;
198 }
199 if (!$error) {
200 // Actions on extra fields
201 $result = $object->insertExtraFields();
202 if ($result < 0) {
203 setEventMessages($object->error, $object->errors, 'errors');
204 $error++;
205 }
206 }
207 // Call update to set the share key
208 $result = $object->update($user);
209 if ($result < 0) {
210 setEventMessages($object->error, $object->errors, 'warnings');
211 }
212 } else {
213 // Call create to insert record
214 $object->entity = $conf->entity;
215 $object->filepath = preg_replace('/[\\/]+$/', '', $newdirrelativetodocument);
216 $object->filename = $newlabel;
217 $object->label = md5_file(dol_osencode($newfileformove)); // hash of file content
218 $object->fullpath_orig = '';
219 $object->gen_or_uploaded = 'unknown';
220 $object->description = ''; // indexed content
221 $object->keywords = ''; // keyword content
222 $result = $object->create($user);
223 if ($result < 0) {
224 setEventMessages($object->error, $object->errors, 'warnings');
225 }
226 }
227 }
228
229 if (!$error) {
230 $db->commit();
231
232 $urlfile = $newlabel;
233 // If old file end with .noexe, new file must also end with .noexe
234 if (preg_match('/\.noexe$/', $newfileformove)) {
235 $urlfile .= '.noexe';
236 }
237
238 header('Location: '.$_SERVER["PHP_SELF"].'?urlfile='.urlencode($urlfile).'&section='.urlencode($section));
239 exit;
240 } else {
241 $db->rollback();
242 }
243}
244
245
246
247/*
248 * View
249 */
250
251$form = new Form($db);
252
253llxHeader('', '', '', '', 0, 0, '', '', '', 'mod-ecm page-file_card');
254
255$object->section_id = $ecmdir->id;
256$object->label = $urlfile;
257$head = ecm_file_prepare_head($object);
258
259if ($action == 'edit') {
260 print '<form name="update" action="'.$_SERVER["PHP_SELF"].'" method="POST">';
261 print '<input type="hidden" name="token" value="'.newToken().'">';
262 print '<input type="hidden" name="section" value="'.$section.'">';
263 print '<input type="hidden" name="urlfile" value="'.$urlfile.'">';
264 print '<input type="hidden" name="module" value="'.$module.'">';
265 print '<input type="hidden" name="action" value="update">';
266 print '<input type="hidden" name="id" value="'.$object->id.'">';
267}
268
269print dol_get_fiche_head($head, 'card', $langs->trans("File"), -1, 'generic');
270
271
272$s = '';
273$tmpecmdir = new EcmDirectory($db); // Need to create a new one
274$tmpecmdir->fetch($ecmdir->id);
275$result = 1;
276$i = 0;
277while ($tmpecmdir && $result > 0) {
278 $tmpecmdir->ref = $tmpecmdir->label;
279 $s = $tmpecmdir->getNomUrl(1).$s;
280 if ($tmpecmdir->fk_parent) {
281 $s = ' -> '.$s;
282 $result = $tmpecmdir->fetch($tmpecmdir->fk_parent);
283 } else {
284 $tmpecmdir = 0;
285 }
286 $i++;
287}
288
289$urlfiletoshow = preg_replace('/\.noexe$/', '', $urlfile);
290
291$s = img_picto('', 'object_dir').' <a href="'.DOL_URL_ROOT.'/ecm/index.php">'.$langs->trans("ECMRoot").'</a> -> '.$s.' -> ';
292if ($action == 'edit') {
293 $s .= '<input type="text" name="label" class="quatrevingtpercent" value="'.$urlfiletoshow.'">';
294} else {
295 $s .= $urlfiletoshow;
296}
297
298$linkback = '';
299if ($backtopage) {
300 $linkback = '<a href="'.$backtopage.'">'.$langs->trans("BackToTree").'</a>';
301}
302
303$object->ref = ''; // Force to hide ref
304dol_banner_tab($object, '', $linkback, 0, '', '', $s);
305
306print '<div class="fichecenter">';
307
308print '<div class="underbanner clearboth"></div>';
309print '<table class="border centpercent tableforfield">';
310print '<tr><td class="titlefieldcreate">'.$langs->trans("ECMCreationDate").'</td><td>';
311print dol_print_date(dol_filemtime($fullpath), 'dayhour');
312print '</td></tr>';
313/*print '<tr><td>'.$langs->trans("ECMDirectoryForFiles").'</td><td>';
314print '/ecm/'.$relativepath;
315print '</td></tr>';
316print '<tr><td>'.$langs->trans("ECMNbOfDocs").'</td><td>';
317print count($filearray);
318print '</td></tr>';
319print '<tr><td>'.$langs->trans("TotalSizeOfAttachedFiles").'</td><td>';
320print dol_print_size($totalsize);
321print '</td></tr>';
322*/
323
324// Hash of file content
325print '<tr><td>'.$langs->trans("HashOfFileContent").'</td><td>';
326$object = new EcmFiles($db);
327$object->fetch(0, '', $filepathtodocument);
328if (!empty($object->label)) {
329 print $object->label;
330} else {
331 print img_warning().' '.$langs->trans("FileNotYetIndexedInDatabase");
332}
333print '</td></tr>';
334
335// Define $urlwithroot
336$urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
337$urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
338//$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current
339
340// Link for internal download
341print '<tr><td>';
342print $form->textwithpicto($langs->trans("DirectDownloadInternalLink"), $langs->trans("PrivateDownloadLinkDesc"));
343print '</td><td>';
344$modulepart = 'ecm';
345$forcedownload = 1;
346$rellink = '/document.php?modulepart='.$modulepart;
347if ($forcedownload) {
348 $rellink .= '&attachment=1';
349}
350if (!empty($object->entity)) {
351 $rellink .= '&entity='.$object->entity;
352}
353$rellink .= '&file='.urlencode($filepath);
354$fulllink = $urlwithroot.$rellink;
355print img_picto('', 'globe').' ';
356if ($action != 'edit') {
357 print '<input type="text" class="maxquatrevingtpercent widthcentpercentminusxx small" id="downloadinternallink" name="downloadinternellink" value="'.dol_escape_htmltag($fulllink).'">';
358} else {
359 print $fulllink;
360}
361if ($action != 'edit') {
362 print ' <a href="'.$fulllink.'">'.img_picto($langs->trans("Download"), 'download', 'class="opacitymedium paddingrightonly"').'</a>'; // No target here.
363}
364print '</td></tr>';
365
366// Link for direct external download
367print '<tr><td>';
368if ($action != 'edit') {
369 print $form->textwithpicto($langs->trans("DirectDownloadLink"), $langs->trans("PublicDownloadLinkDesc"));
370} else {
371 print $form->textwithpicto($langs->trans("FileSharedViaALink"), $langs->trans("PublicDownloadLinkDesc"));
372}
373print '</td><td>';
374if (!empty($object->share)) {
375 if ($action != 'edit') {
376 $forcedownload = 0;
377
378 $paramlink = '';
379 if (!empty($object->share)) {
380 $paramlink .= ($paramlink ? '&' : '').'hashp='.$object->share; // Hash for public share
381 }
382 if ($forcedownload) {
383 $paramlink .= ($paramlink ? '&' : '').'attachment=1';
384 }
385
386 $fulllink = $urlwithroot.'/document.php'.($paramlink ? '?'.$paramlink : '');
387 //if (!empty($object->ref)) $fulllink.='&hashn='.$object->ref; // Hash of file path
388 //elseif (!empty($object->label)) $fulllink.='&hashc='.$object->label; // Hash of file content
389
390 print img_picto('', 'globe').' ';
391 if ($action != 'edit') {
392 print '<input type="text" class="maxquatrevingtpercent widthcentpercentminusxx nopadding small" id="downloadlink" name="downloadexternallink" value="'.dol_escape_htmltag($fulllink).'">';
393 } else {
394 print $fulllink;
395 }
396 if ($action != 'edit') {
397 print ' <a href="'.$fulllink.'">'.img_picto($langs->trans("Download"), 'download', 'class="opacitymedium paddingrightonly"').'</a>'; // No target here
398 }
399 } else {
400 print '<input type="checkbox" name="shareenabled"'.($object->share ? ' checked="checked"' : '').' /> ';
401 }
402} else {
403 if ($action != 'edit') {
404 print '<span class="opacitymedium">'.$langs->trans("FileNotShared").'</span>';
405 } else {
406 print '<input type="checkbox" name="shareenabled"'.($object->share ? ' checked="checked"' : '').' /> ';
407 }
408}
409print '</td>';
410print '</tr>';
411print $object->showOptionals($extrafields, ($action == 'edit' ? 'edit' : 'view'));
412print '</table>';
413print '</div>';
414
415print ajax_autoselect('downloadinternallink');
416print ajax_autoselect('downloadlink');
417
418print dol_get_fiche_end();
419
420if ($action == 'edit') {
421 print $form->buttonsSaveCancel();
422
423 print '</form>';
424}
425
426
427// Confirm deletion of a file
428if ($action == 'deletefile') {
429 print $form->formconfirm($_SERVER["PHP_SELF"].'?section='.urlencode($section), $langs->trans('DeleteFile'), $langs->trans('ConfirmDeleteFile', $urlfile), 'confirm_deletefile', '', 1, 1);
430}
431
432if ($action != 'edit') {
433 // Actions buttons
434 print '<div class="tabsAction">';
435
436 if ($user->hasRight('ecm', 'setup')) {
437 print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?action=edit&section='.urlencode($section).'&urlfile='.urlencode($urlfile).'">'.$langs->trans('Edit').'</a>';
438 }
439
440 print '</div>';
441}
442
443
444// End of page
445llxFooter();
446$db->close();
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:67
global $dolibarr_main_url_root
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 to manage ECM directories.
Class to manage ECM files.
Class to manage standard extra fields.
Class to manage generation of HTML components Only common components must be here.
ecm_file_prepare_head($object)
Prepare array with list of tabs.
Definition ecm.lib.php:118
dol_filemtime($pathoffile)
Return time of a file.
dol_move($srcfile, $destfile, $newmask='0', $overwriteifexists=1, $testvirus=0, $indexdatabase=1, $moreinfo=array(), $entity=0)
Move a file into another name.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
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)
img_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning logo.
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_osencode($str)
Return a string encoded into OS filesystem encoding.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0, $morecssdiv='')
Show tabs of a record.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
ajax_autoselect($htmlname, $addlink='', $textonlink='Link')
Make content of an input box selected when we click into input field.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0)
Clean a string to use it as a file name.
dol_sanitizePathName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a path name.
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79
getRandomPassword($generic=false, $replaceambiguouschars=null, $length=32)
Return a generated password using default module.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.