1<?php
2/* Copyright (C) 2008-2020 Laurent Destailleur  <eldy@users.sourceforge.net>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18/**
19 *	\file      	htdocs/ecm/file_card.php
20 *	\ingroup   	ecm
21 *	\brief     	Card of a file for ECM module
22 */
23
24require '../main.inc.php';
25require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
26require_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmdirectory.class.php';
27require_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php';
28require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
29require_once DOL_DOCUMENT_ROOT.'/core/lib/ecm.lib.php';
30require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
31
32// Load translation files required by page
33$langs->loadLangs(array('ecm', 'companies', 'other', 'users', 'orders', 'propal', 'bills', 'contracts', 'categories'));
34
35$action = GETPOST('action', 'aZ09');
36$cancel = GETPOST('cancel', 'alpha');
37$backtopage = GETPOST('backtopage', 'alpha');
38
39if (!$user->rights->ecm->setup) accessforbidden();
40
41// Get parameters
42$socid = GETPOST("socid", "int");
43
44// Security check
45if ($user->socid > 0)
46{
47	$action = '';
48	$socid = $user->socid;
49}
50
51$limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit;
52$sortfield = GETPOST("sortfield", 'alpha');
53$sortorder = GETPOST("sortorder", 'alpha');
54$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
55if (empty($page) || $page == -1) { $page = 0; }     // If $page is not defined, or '' or -1
56$offset = $limit * $page;
57$pageprev = $page - 1;
58$pagenext = $page + 1;
59if (!$sortorder) $sortorder = "ASC";
60if (!$sortfield) $sortfield = "label";
61
62$section = GETPOST("section", 'alpha');
63if (!$section)
64{
65	dol_print_error('', 'Error, section parameter missing');
66	exit;
67}
68$urlfile = (string) dol_sanitizePathName(GETPOST("urlfile"));
69if (!$urlfile)
70{
71	dol_print_error('', "ErrorParamNotDefined");
72	exit;
73}
74
75// Load ecm object
76$ecmdir = new EcmDirectory($db);
77$result = $ecmdir->fetch(GETPOST("section", 'alpha'));
78if (!$result > 0)
79{
80	dol_print_error($db, $ecmdir->error);
81	exit;
82}
83$relativepath = $ecmdir->getRelativePath();
84$upload_dir = $conf->ecm->dir_output.'/'.$relativepath;
85
86$fullpath = $conf->ecm->dir_output.'/'.$relativepath.$urlfile;
87
88$file = new stdClass();
89$file->section_id = $ecmdir->id;
90$file->label = $urlfile;
91
92$relativetodocument = 'ecm/'.$relativepath; // $relativepath is relative to ECM dir, we need relative to document
93$filepath = $relativepath.$file->label;
94$filepathtodocument = $relativetodocument.$file->label;
95
96// Try to load object from index
97$object = new ECMFiles($db);
98$extrafields = new ExtraFields($db);
99// fetch optionals attributes and labels
100$extrafields->fetch_name_optionals_label($object->table_element);
101
102$result = $object->fetch(0, '', $filepathtodocument);
103if ($result < 0)
104{
105	dol_print_error($db, $object->error, $object->errors);
106	exit;
107}
108
109
110
111/*
112 * Actions
113 */
114
115if ($cancel)
116{
117	$action = '';
118	if ($backtopage)
119	{
120		header("Location: ".$backtopage);
121		exit;
122	} else {
123		header('Location: '.$_SERVER["PHP_SELF"].'?urlfile='.urlencode($urlfile).'&section='.urlencode($section).($module ? '&module='.urlencode($module) : ''));
124		exit;
125	}
126}
127
128// Rename file
129if ($action == 'update')
130{
131	$error = 0;
132
133	$oldlabel = GETPOST('urlfile', 'alpha');
134	$newlabel = dol_sanitizeFileName(GETPOST('label', 'alpha'));
135	$shareenabled = GETPOST('shareenabled', 'alpha');
136
137	//$db->begin();
138
139	$olddir = $ecmdir->getRelativePath(0); // Relative to ecm
140	$olddirrelativetodocument = 'ecm/'.$olddir; // Relative to document
141	$newdirrelativetodocument = 'ecm/'.$olddir;
142	$olddir = $conf->ecm->dir_output.'/'.$olddir;
143	$newdir = $olddir;
144
145	$oldfile = $olddir.$oldlabel;
146	$newfile = $newdir.$newlabel;
147	$newfileformove = $newfile;
148	// If old file end with .noexe, new file must also end with .noexe
149	if (preg_match('/\.noexe$/', $oldfile) && !preg_match('/\.noexe$/', $newfileformove)) {
150		$newfileformove .= '.noexe';
151	}
152	//var_dump($oldfile);var_dump($newfile);exit;
153
154	// Now we update index of file
155	$db->begin();
156	//print $oldfile.' - '.$newfile;
157	if ($newlabel != $oldlabel)
158	{
159		$result = dol_move($oldfile, $newfileformove); // This include update of database
160		if (!$result)
161		{
162			$langs->load('errors');
163			setEventMessages($langs->trans('ErrorFailToRenameFile', $oldfile, $newfile), null, 'errors');
164			$error++;
165		}
166
167		// Reload object after the move
168		$result = $object->fetch(0, '', $newdirrelativetodocument.$newlabel);
169		if ($result < 0)
170		{
171			dol_print_error($db, $object->error, $object->errors);
172			exit;
173		}
174	}
175
176	if (!$error)
177	{
178		if ($shareenabled)
179		{
180			require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
181			$object->share = getRandomPassword(true);
182		} else {
183			$object->share = '';
184		}
185
186		if ($object->id > 0)
187		{
188			$ret = $extrafields->setOptionalsFromPost(null, $object);
189			if ($ret < 0) $error++;
190			if (!$error) {
191				// Actions on extra fields
192				$result = $object->insertExtraFields();
193				if ($result < 0) {
194					setEventMessages($object->error, $object->errors, 'errors');
195					$error++;
196				}
197			}
198			// Call update to set the share key
199			$result = $object->update($user);
200			if ($result < 0)
201			{
202				setEventMessages($object->error, $object->errors, 'warnings');
203			}
204		} else {
205			// Call create to insert record
206			$object->entity = $conf->entity;
207			$object->filepath = preg_replace('/[\\/]+$/', '', $newdirrelativetodocument);
208			$object->filename = $newlabel;
209			$object->label = md5_file(dol_osencode($newfileformove)); // hash of file content
210			$object->fullpath_orig = '';
211			$object->gen_or_uploaded = 'unknown';
212			$object->description = ''; // indexed content
213			$object->keyword = ''; // keyword content
214			$result = $object->create($user);
215			if ($result < 0)
216			{
217				setEventMessages($object->error, $object->errors, 'warnings');
218			}
219		}
220	}
221
222	if (!$error)
223	{
224		$db->commit();
225
226		$urlfile = $newlabel;
227		// If old file end with .noexe, new file must also end with .noexe
228		if (preg_match('/\.noexe$/', $newfileformove)) {
229			$urlfile .= '.noexe';
230		}
231
232		header('Location: '.$_SERVER["PHP_SELF"].'?urlfile='.urlencode($urlfile).'&section='.urlencode($section));
233		exit;
234	} else {
235		$db->rollback();
236	}
237}
238
239
240
241/*
242 * View
243 */
244
245$form = new Form($db);
246
247llxHeader();
248
249$head = ecm_file_prepare_head($file);
250
251if ($action == 'edit')
252{
253	print '<form name="update" action="'.$_SERVER["PHP_SELF"].'" method="POST">';
254	print '<input type="hidden" name="token" value="'.newToken().'">';
255	print '<input type="hidden" name="section" value="'.$section.'">';
256	print '<input type="hidden" name="urlfile" value="'.$urlfile.'">';
257	print '<input type="hidden" name="module" value="'.$module.'">';
258	print '<input type="hidden" name="action" value="update">';
259	print '<input type="hidden" name="id" value="'.$object->id.'">';
260}
261
262print dol_get_fiche_head($head, 'card', $langs->trans("File"), -1, 'generic');
263
264
265$s = '';
266$tmpecmdir = new EcmDirectory($db); // Need to create a new one
267$tmpecmdir->fetch($ecmdir->id);
268$result = 1;
269$i = 0;
270while ($tmpecmdir && $result > 0)
271{
272	$tmpecmdir->ref = $tmpecmdir->label;
273	$s = $tmpecmdir->getNomUrl(1).$s;
274	if ($tmpecmdir->fk_parent)
275	{
276		$s = ' -> '.$s;
277		$result = $tmpecmdir->fetch($tmpecmdir->fk_parent);
278	} else {
279		$tmpecmdir = 0;
280	}
281	$i++;
282}
283
284$urlfiletoshow = preg_replace('/\.noexe$/', '', $urlfile);
285
286$s = img_picto('', 'object_dir').' <a href="'.DOL_URL_ROOT.'/ecm/index.php">'.$langs->trans("ECMRoot").'</a> -> '.$s.' -> ';
287if ($action == 'edit') $s .= '<input type="text" name="label" class="quatrevingtpercent" value="'.$urlfiletoshow.'">';
288else $s .= $urlfiletoshow;
289
290$linkback = '';
291if ($backtopage) {
292	$linkback = '<a href="'.$backtopage.'">'.$langs->trans("BackToTree").'</a>';
293}
294
295$object->ref = ''; // Force to hide ref
296dol_banner_tab($object, '', $linkback, 0, '', '', $s);
297
298print '<div class="fichecenter">';
299
300print '<div class="underbanner clearboth"></div>';
301print '<table class="border centpercent tableforfield">';
302print '<tr><td class="titlefield">'.$langs->trans("ECMCreationDate").'</td><td>';
303print dol_print_date(dol_filemtime($fullpath), 'dayhour');
304print '</td></tr>';
305/*print '<tr><td>'.$langs->trans("ECMDirectoryForFiles").'</td><td>';
306print '/ecm/'.$relativepath;
307print '</td></tr>';
308print '<tr><td>'.$langs->trans("ECMNbOfDocs").'</td><td>';
309print count($filearray);
310print '</td></tr>';
311print '<tr><td>'.$langs->trans("TotalSizeOfAttachedFiles").'</td><td>';
312print dol_print_size($totalsize);
313print '</td></tr>';
314*/
315
316// Hash of file content
317print '<tr><td>'.$langs->trans("HashOfFileContent").'</td><td>';
318$object = new EcmFiles($db);
319$object->fetch(0, '', $filepathtodocument);
320if (!empty($object->label))
321{
322	print $object->label;
323} else {
324	print img_warning().' '.$langs->trans("FileNotYetIndexedInDatabase");
325}
326print '</td></tr>';
327
328// Define $urlwithroot
329$urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
330$urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
331//$urlwithroot=DOL_MAIN_URL_ROOT;					// This is to use same domain name than current
332
333// Link for internal download
334print '<tr><td>'.$langs->trans("DirectDownloadInternalLink").'</td><td>';
335$modulepart = 'ecm';
336$forcedownload = 1;
337$rellink = '/document.php?modulepart='.$modulepart;
338if ($forcedownload) $rellink .= '&attachment=1';
339if (!empty($object->entity)) $rellink .= '&entity='.$object->entity;
340$rellink .= '&file='.urlencode($filepath);
341$fulllink = $urlwithroot.$rellink;
342print img_picto('', 'globe').' ';
343if ($action != 'edit') print '<input type="text" class="quatrevingtpercent" id="downloadinternallink" name="downloadinternellink" value="'.dol_escape_htmltag($fulllink).'">';
344else print $fulllink;
345if ($action != 'edit') print ' <a href="'.$fulllink.'">'.$langs->trans("Download").'</a>'; // No target here.
346print '</td></tr>';
347
348// Link for direct external download
349print '<tr><td>';
350if ($action != 'edit') print $langs->trans("DirectDownloadLink");
351else print $langs->trans("FileSharedViaALink");
352print '</td><td>';
353if (!empty($object->share))
354{
355	if ($action != 'edit')
356	{
357		$forcedownload = 0;
358
359		$paramlink = '';
360		if (!empty($object->share)) $paramlink .= ($paramlink ? '&' : '').'hashp='.$object->share; // Hash for public share
361		if ($forcedownload) $paramlink .= ($paramlink ? '&' : '').'attachment=1';
362
363		$fulllink = $urlwithroot.'/document.php'.($paramlink ? '?'.$paramlink : '');
364		//if (! empty($object->ref))       $fulllink.='&hashn='.$object->ref;		// Hash of file path
365		//elseif (! empty($object->label)) $fulllink.='&hashc='.$object->label;		// Hash of file content
366
367		print img_picto('', 'globe').' ';
368		if ($action != 'edit') print '<input type="text" class="quatrevingtpercent" id="downloadlink" name="downloadexternallink" value="'.dol_escape_htmltag($fulllink).'">';
369		else print $fulllink;
370		if ($action != 'edit') print ' <a href="'.$fulllink.'">'.$langs->trans("Download").'</a>'; // No target here
371	} else {
372		print '<input type="checkbox" name="shareenabled"'.($object->share ? ' checked="checked"' : '').' /> ';
373	}
374} else {
375	if ($action != 'edit')
376	{
377		print '<span class="opacitymedium">'.$langs->trans("FileNotShared").'</span>';
378	} else {
379		print '<input type="checkbox" name="shareenabled"'.($object->share ? ' checked="checked"' : '').' /> ';
380	}
381}
382print '</td>';
383print '</tr>';
384print $object->showOptionals($extrafields, ($action == 'edit' ? 'edit' : 'view'));
385print '</table>';
386print '</div>';
387
388print ajax_autoselect('downloadinternallink');
389print ajax_autoselect('downloadlink');
390
391print dol_get_fiche_end();
392
393if ($action == 'edit')
394{
395	print '<div class="center">';
396	print '<input type="submit" class="button button-save" name="submit" value="'.$langs->trans("Save").'">';
397	print ' &nbsp; &nbsp; ';
398	print '<input type="submit" class="button button-cancel" name="cancel" value="'.$langs->trans("Cancel").'">';
399	print '</div>';
400
401	print '</form>';
402}
403
404
405// Confirmation de la suppression d'une ligne categorie
406if ($action == 'delete_file')
407{
408	print $form->formconfirm($_SERVER["PHP_SELF"].'?section='.urlencode($section), $langs->trans('DeleteFile'), $langs->trans('ConfirmDeleteFile', $urlfile), 'confirm_deletefile', '', 1, 1);
409}
410
411if ($action != 'edit')
412{
413	// Actions buttons
414	print '<div class="tabsAction">';
415
416	if ($user->rights->ecm->setup)
417	{
418		print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?action=edit&section='.urlencode($section).'&urlfile='.urlencode($urlfile).'">'.$langs->trans('Edit').'</a>';
419	}
420	/*
421	if ($user->rights->ecm->setup)
422	{
423		print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?action=delete_file&token='.newToken().'&section='.$section.'&urlfile='.urlencode($urlfile).'">'.$langs->trans('Delete').'</a>';
424	}
425	else
426	{
427		print '<a class="butActionRefused classfortooltip" href="#" title="'.$langs->trans("NotAllowed").'">'.$langs->trans('Delete').'</a>';
428	}
429    */
430	print '</div>';
431}
432
433
434// End of page
435llxFooter();
436$db->close();
437