dolibarr 23.0.3
filemanager.tpl.php
1<?php
2/* Copyright (C) 2017 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
4 * Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
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 * Output code for the filemanager
20 * $module must be defined ('ecm', 'medias', ...)
21 * $formalreadyopen can be set to 1 to avoid to open the <form> to submit files a second time
22 */
40// Protection to avoid direct call of template
41if (empty($conf) || !is_object($conf)) {
42 print "Error, template page filemanager.tpl.php can't be called as URL";
43 exit;
44}
45
46'
47@phan-var-force Website $website
48@phan-var-force string $filepathnoext
49@phan-var-force string $pageid
50@phan-var-force EcmDirectory $ecmdir
51@phan-var-force ?string $module
52@phan-var-force int $section
53';
54
55?>
56
57<!-- BEGIN PHP TEMPLATE core/tpl/filemanager.tpl.php -->
58<!-- Doc of fileTree plugin at https://www.abeautifulsite.net/jquery-file-tree -->
59
60<?php
61
62require_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmdirectory.class.php';
63
64$langs->load("ecm");
65
66if (!isset($module)) {
67 $module = 'ecm';
68}
69
70$permtoadd = 0;
71$permtoupload = 0;
72$showroot = 0;
73$error = 0;
74
75if ($module == 'ecm') {
76 $permtoadd = $user->hasRight("ecm", "setup");
77 $permtoupload = $user->hasRight("ecm", "upload");
78 $showroot = 0;
79}
80if ($module == 'medias') {
81 $permtoadd = ($user->hasRight("mailing", "creer") || $user->hasRight("website", "write"));
82 $permtoupload = ($user->hasRight("mailing", "creer") || $user->hasRight("website", "write"));
83 $showroot = 1;
84}
85
86if (!isset($section)) {
87 $section = 0;
88}
89
90// Confirm remove file (for non javascript users)
91if (($action == 'delete' || $action == 'file_manager_delete') && empty($conf->use_javascript_ajax)) {
92 // TODO Add website, pageid, filemanager if defined
93 print $form->formconfirm($_SERVER["PHP_SELF"].'?section='.$section.'&urlfile='.urlencode(GETPOST("urlfile")), $langs->trans('DeleteFile'), $langs->trans('ConfirmDeleteFile'), 'confirm_deletefile', '', '', 1);
94}
95
96// Start container of all panels
97?>
98<!-- Begin div id="containerlayout" -->
99<div id="containerlayout">
100<div id="ecm-layout-north" class="toolbar largebutton">
101<?php
102
103// Start top panel, toolbar
104print '<div class="inline-block toolbarbutton centpercent">';
105
106// Toolbar
107if ($permtoadd) {
108 $websitekeyandpageid = (!empty($websitekey) ? '&website='.urlencode($websitekey) : '').(!empty($pageid) ? '&pageid='.urlencode((string) $pageid) : '');
109 print '<a id="acreatedir" href="'.DOL_URL_ROOT.'/ecm/dir_add_card.php?action=create&module='.urlencode($module).$websitekeyandpageid.'&backtopage='.urlencode($_SERVER["PHP_SELF"].'?file_manager=1'.$websitekeyandpageid).'" class="inline-block valignmiddle toolbarbutton paddingtop" title="'.dol_escape_htmltag($langs->trans('ECMAddSection')).'">';
110 print img_picto('', 'folder-plus', '', 0, 0, 0, '', 'size15x marginrightonly');
111 print '</a>';
112} else {
113 print '<a id="acreatedir" href="#" class="inline-block valignmiddle toolbarbutton paddingtop" title="'.$langs->trans("NotAllowed").'">';
114 print img_picto('', 'folder-plus', 'disabled', 0, 0, 0, '', 'size15x marginrightonly');
115 print '</a>';
116}
117if ($module == 'ecm') {
118 $tmpurl = ((!empty($conf->use_javascript_ajax) && !getDolGlobalString('MAIN_ECM_DISABLE_JS')) ? '#' : ($_SERVER["PHP_SELF"].'?action=refreshmanual'.($module ? '&amp;module='.$module : '').($section ? '&amp;section='.$section : '')));
119 print '<a id="arefreshbutton" href="'.$tmpurl.'" class="inline-block valignmiddle toolbarbutton paddingtop" title="'.dol_escape_htmltag($langs->trans('ReSyncListOfDir')).'">';
120 print img_picto('', 'refresh', 'id="refreshbutton"', 0, 0, 0, '', 'size15x marginrightonly');
121 print '</a>';
122}
123if ($permtoadd && GETPOSTISSET('website')) { // If on file manager to manage medias of a web site
124 // @phan-suppress-next-line PhanTypeExpectedObjectPropAccess
125 print '<a id="agenerateimgwebp" href="'.$_SERVER["PHP_SELF"].'?action=confirmconvertimgwebp&token='.newToken().'&website='.urlencode($website->ref).'" class="inline-block valignmiddle toolbarbutton paddingtop" title="'.dol_escape_htmltag($langs->trans("GenerateImgWebp")).'">';
126 print img_picto('', 'images', '', 0, 0, 0, '', 'size15x flip marginrightonly');
127 print '</a>';
128} elseif ($permtoadd && $module == 'ecm') { // If on file manager medias in ecm
129 if (getDolGlobalInt('ECM_SHOW_GENERATE_WEBP_BUTTON')) {
130 print '<a id="agenerateimgwebp" href="'.$_SERVER["PHP_SELF"].'?action=confirmconvertimgwebp&token='.newToken().'" class="inline-block valignmiddle toolbarbutton paddingtop" title="'.dol_escape_htmltag($langs->trans("GenerateImgWebp")).'">';
131 print img_picto('', 'images', '', 0, 0, 0, '', 'size15x flip marginrightonly');
132 print '</a>';
133 }
134}
135
136print "<script>
137$('#acreatedir').on('click', function() {
138 try{
139 section_dir = $('.directory.expanded')[$('.directory.expanded').length-1].children[0].rel;
140 section = $('.directory.expanded')[$('.directory.expanded').length-1].children[0].id.split('_')[2];
141 catParent = ";
142if ($module == 'ecm') {
143 print "section;";
144} else {
145 print "section_dir.substring(0, section_dir.length - 1);";
146}
147print "
148 } catch{
149 section_dir = '/';
150 section = 0;
151 catParent = ";
152if ($module == 'ecm') {
153 print "section;";
154} else {
155 print "section_dir;";
156}
157print "
158 }
159 console.log('We click to create a new directory, we set current section_dir='+section_dir+' into href url of button acreatedir');
160 $('#acreatedir').attr('href', $('#acreatedir').attr('href')+'%26section_dir%3D'+encodeURI(section_dir)+'%26section%3D'+encodeURI(section)+'&section_dir='+encodeURI(section_dir)+'&section='+encodeURI(section)+'&catParent='+encodeURI(catParent));
161 console.log($('#acreatedir').attr('href'));
162});
163$('#agenerateimgwebp').on('click', function() {
164 try{
165 section_dir = $('.directory.expanded')[$('.directory.expanded').length-1].children[0].rel;
166 section = $('.directory.expanded')[$('.directory.expanded').length-1].children[0].id.split('_')[2];
167 } catch{
168 section_dir = '/';
169 section = 0;
170 }
171 console.log('We click to generate webp image, we set current section_dir='+section_dir+' into href url of button agenerateimgwebp');
172 $('#agenerateimgwebp').attr('href', $('#agenerateimgwebp').attr('href')+'&section_dir='+encodeURI(section_dir)+'&section='+encodeURI(section));
173 console.log($('#agenerateimgwebp').attr('href'));
174});
175</script>";
176
177// Start "Add new file" area
178$nameforformuserfile = 'formuserfileecm';
179
180print '<div class="inline-block valignmiddle floatright">';
181
182// Zone to attach a new file
183if ((!empty($conf->use_javascript_ajax) && !getDolGlobalString('MAIN_ECM_DISABLE_JS')) || !empty($section)) {
184 if ((empty($section) || $section == -1) && ($module != 'medias')) {
185 ?>
186 <script>
187 jQuery(document).ready(function() {
188 jQuery('#<?php echo $nameforformuserfile ?>').hide();
189 });
190 </script>
191 <?php
192 }
193
194 $sectiondir = GETPOST('file', 'alpha') ? GETPOST('file', 'alpha') : GETPOST('section_dir', 'alpha');
195
196 print '<!-- Start form to attach new file in filemanager.tpl.php sectionid='.$section.' sectiondir='.$sectiondir.' -->'."\n";
197 include_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
198 $formfile = new FormFile($db);
199 print $formfile->form_attach_new_file($_SERVER["PHP_SELF"], 'none', 0, ($section ? $section : -1), $permtoupload, 48, null, '', 0, '', 0, $nameforformuserfile, '', $sectiondir, empty($formalreadyopen) ? 0 : $formalreadyopen, 0, 0, 1);
200} else {
201 print '&nbsp;';
202}
203
204print '</div>';
205// End "Add new file" area
206
207
208print '</div>';
209// End top panel, toolbar
210
211?>
212</div>
213<div id="ecm-layout-west" class="inline-block">
214<?php
215// Start left area
216
217
218// Ask confirmation of deletion of directory
219if ($action == 'delete_section') {
220 print $form->formconfirm($_SERVER["PHP_SELF"].'?section='.$section, $langs->trans('DeleteSection'), $langs->trans('ConfirmDeleteSection', $ecmdir->label), 'confirm_deletesection', '', '', 1);
221}
222// End confirm
223
224// Ask confirmation to build webp images
225if ($action == 'confirmconvertimgwebp') {
226 $langs->load("ecm");
227
228 $section_dir = GETPOST('section_dir', 'alpha');
229 $section = GETPOST('section', 'alpha');
230 $file = GETPOST('filetoregenerate', 'alpha');
231 $form = new Form($db);
232 $formquestion = array();
233 $formquestion['section_dir'] = array('type' => 'hidden', 'value' => $section_dir, 'name' => 'section_dir');
234 $formquestion['section'] = array('type' => 'hidden', 'value' => $section, 'name' => 'section');
235 $formquestion['filetoregenerate'] = array('type' => 'hidden', 'value' => $file, 'name' => 'filetoregenerate');
236 if ($module == 'medias') {
237 $formquestion['website'] = array('type' => 'hidden', 'value' => $website->ref, 'name' => 'website'); // @phan-suppress-current-line PhanTypeExpectedObjectPropAccess
238 }
239 $param = '';
240 if (!empty($sortfield)) {
241 $param .= '&sortfield='.urlencode($sortfield);
242 }
243 if (!empty($sortorder)) {
244 $param .= '&sortorder='.urlencode($sortorder);
245 }
246 print $form->formconfirm($_SERVER["PHP_SELF"].($param ? '?'.$param : ''), empty($file) ? $langs->trans('ConfirmImgWebpCreation') : $langs->trans('ConfirmChosenImgWebpCreation'), empty($file) ? $langs->trans('ConfirmGenerateImgWebp') : $langs->trans('ConfirmGenerateChosenImgWebp', basename($file)), 'convertimgwebp', $formquestion, "yes", 1);
247 $action = 'file_manager';
248}
249
250// Duplicate images into .webp
251if ($action == 'convertimgwebp' && $permtoadd) {
252 $file = GETPOST('filetoregenerate', 'alpha');
253
254 if ($module == 'medias') {
255 $imagefolder = $conf->website->dir_output.'/'.$websitekey.'/medias/'.dol_sanitizePathName(GETPOST('section_dir', 'alpha'));
256 } else {
257 $imagefolder = $conf->ecm->dir_output.'/'.dol_sanitizePathName(GETPOST('section_dir', 'alpha'));
258 }
259
260 include_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
261
262 if (!empty($file)) {
263 $filelist = array();
264 $filelist[]["fullname"] = dol_osencode($imagefolder.'/'.$file); // get $imagefolder.'/'.$file infos
265 } else {
266 $regeximgext = getListOfPossibleImageExt();
267
268 $filelist = dol_dir_list($imagefolder, "files", 0, $regeximgext);
269 }
270
271 $nbconverted = 0;
272
273 foreach ($filelist as $filename) {
274 $filepath = $filename['fullname'];
275 if (!(substr_compare($filepath, 'webp', -strlen('webp')) === 0)) {
276 if (!empty($file) || !dol_is_file($filepathnoext.'.webp')) { // If file does not exists yet
277 if (image_format_supported($filepath) == 1) {
278 $filepathnoext = preg_replace("/\.[a-z0-9]+$/i", "", $filepath);
279 $result = dol_imageResizeOrCrop($filepath, 0, 0, 0, 0, 0, $filepathnoext.'.webp', 90);
280 if (!dol_is_file($result)) {
281 $error++;
282 setEventMessages($result, null, 'errors');
283 } else {
284 $nbconverted++;
285 }
286 }
287 }
288 }
289 if ($error) {
290 break;
291 }
292 }
293 if (!$error) {
294 if (!empty($file)) {
295 setEventMessages($langs->trans('SucessConvertChosenImgWebp'), null);
296 } else {
297 setEventMessages($langs->trans('SucessConvertImgWebp'), null);
298 }
299 }
300 $action = 'file_manager';
301}
302
303// List of directories
304if (empty($action) || $action == 'editfile' || $action == 'file_manager' || preg_match('/refresh/i', $action) || $action == 'delete') {
305 $langs->load("ecm");
306
307 print '<table class="liste centpercent noborder">'."\n";
308
309 print '<!-- Title for manual directories -->'."\n";
310 print '<tr class="liste_titre">'."\n";
311 print '<th class="liste_titre left">';
312 print '<span style="padding-left: 5px; padding-right: 5px;">'.$langs->trans("ECMSections").'</span>';
313 print '</th></tr>';
314
315 $showonrightsize = '';
316
317 // Manual section
318 $htmltooltip = $langs->trans("ECMAreaDesc2a");
319 $htmltooltip .= '<br>'.$langs->trans("ECMAreaDesc2b");
320
321 if (!empty($conf->use_javascript_ajax) && !getDolGlobalString('MAIN_ECM_DISABLE_JS')) {
322 // Show the link to "Root"
323 if ($showroot) {
324 print '<tr class="oddeven nohover"><td><div style="padding-left: 5px; padding-right: 5px;"><a href="'.$_SERVER["PHP_SELF"].'?file_manager=1'.(!empty($websitekey) ? '&website='.urlencode($websitekey) : '').'&pageid='.urlencode((string) $pageid).'">';
325 if ($module == 'medias') {
326 print $langs->trans("RootOfMedias");
327 } else {
328 print $langs->trans("Root");
329 }
330 print '</a></div></td></tr>';
331 }
332
333 print '<tr class="oddeven nohover"><td>';
334
335 // Show filemanager tree (will be filled by a call of ajax /ecm/tpl/enablefiletreeajax.tpl.php, later, that executes ajaxdirtree.php)
336 print '<div id="filetree" class="ecmfiletree"></div>';
337
338 if ($action == 'deletefile') {
339 print $form->formconfirm('eeeee', $langs->trans('DeleteFile'), $langs->trans('ConfirmDeleteFile'), 'confirm_deletefile', '', '', 'deletefile');
340 }
341
342 print '</td></tr>';
343 } else {
344 // Show filtree when ajax is disabled (rare)
345 print '<tr><td style="padding-left: 20px">';
346
347 $_POST['modulepart'] = $module;
348 $_POST['openeddir'] = GETPOST('openeddir');
349 $_POST['dir'] = empty($_POST['dir']) ? '/' : GETPOST('dir');
350
351 // Show filemanager tree (will be filled by direct include of ajaxdirtree.php in mode noajax, this will return all dir - all levels - to show)
352 print '<div id="filetree" class="ecmfiletree">';
353
354 // Variables that may be defined:
355 // $_GET['modulepart'], $_GET['openeddir'], $_GET['sortfield'], $_GET['sortorder']
356 // $_POST['dir']
357 $mode = 'noajax';
358 if (empty($url)) {
359 $url = DOL_URL_ROOT.'/ecm/index.php';
360 }
361 include DOL_DOCUMENT_ROOT.'/core/ajax/ajaxdirtree.php';
362
363 print '</div>';
364 print '</td></tr>';
365 }
366
367
368 print "</table>";
369}
370
371
372// End left panel
373?>
374</div>
375<div id="ecm-layout-center" class="inline-block">
376<div class="pane-in ecm-in-layout-center">
377<div id="ecmfileview" class="ecmfileview">
378<?php
379// Start right panel - List of content of a directory
380
381$mode = 'noajax';
382if (empty($url)) { // autoset $url but it is better to have it defined before (for example by ecm/index.php, ecm/index_medias.php, website/index.php)
383 if (!empty($module) && $module == 'medias' && !GETPOST('website')) {
384 $url = DOL_URL_ROOT.'/ecm/index_medias.php';
385 } elseif (GETPOSTISSET('website')) {
386 $url = DOL_URL_ROOT.'/website/index.php';
387 } else {
388 $url = DOL_URL_ROOT.'/ecm/index.php';
389 }
390}
391include DOL_DOCUMENT_ROOT.'/core/ajax/ajaxdirpreview.php'; // Show content of a directory on right side
392
393
394// End right panel
395?>
396</div>
397</div>
398
399</div>
400</div> <!-- End div id="containerlayout" -->
401<?php
402
403
404if (!empty($conf->use_javascript_ajax) && !getDolGlobalString('MAIN_ECM_DISABLE_JS')) { // Show filtree when ajax is enabled
405 //var_dump($modulepart);
406 // Variables that may be defined:
407 // $_GET['modulepart'], $_GET['openeddir'], $_GET['sortfield'], $_GET['sortorder']
408 // $_POST['dir']
409 // $_POST['section_dir'], $_POST['section_id'], $_POST['token'], $_POST['max_file_size'], $_POST['sendit']
410 if (GETPOST('section_dir', 'alpha')) {
411 $preopened = GETPOST('section_dir', 'alpha');
412 }
413
414 include DOL_DOCUMENT_ROOT.'/ecm/tpl/enablefiletreeajax.tpl.php';
415}
416
417?>
418<!-- END PHP TEMPLATE core/tpl/filemanager.tpl.php -->
Class to offer components to list and upload files.
Class to manage generation of HTML components Only common components must be here.
dol_is_file($pathoffile)
Return if path is a file.
dol_dir_list($utf8_path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0, $nbsecondsold=0)
Scan a directory and return a list of files/directories.
Definition files.lib.php:64
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)
dol_osencode($str)
Return a string encoded into OS filesystem encoding.
dol_sanitizePathName($str, $newstr='_', $unaccent=0, $allowdash=0)
Clean a string to use it as a path name.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
newToken()
Return the value of token currently saved into session with name 'newtoken'.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
getListOfPossibleImageExt($acceptsvg=0)
Return if a filename is file name of a supported image format.
dol_imageResizeOrCrop($file, $mode, $newWidth, $newHeight, $src_x=0, $src_y=0, $filetowrite='', $newquality=0)
Resize or crop an image file (Supported extensions are gif, jpg, png, bmp and webp)
image_format_supported($file, $acceptsvg=0)
Return if a filename is file name of a supported image format.