Fully responsive globals.php with vertical menu (#2460)
[openemr.git] / interface / super / manage_site_files.php
blobd5009ecb3d35fc9e3038ec6718af018db3b6fd01
1 <?php
2 /**
3 * This module provides for editing site-specific text files and
4 * for uploading site-specific image files.
6 * @package OpenEMR
7 * @link http://www.open-emr.org
8 * @author Rod Roark <rod@sunsetsystems.com>
9 * @author Brady Miller <brady.g.miller@gmail.com>
10 * @copyright Copyright (c) 2010-2016 Rod Roark <rod@sunsetsystems.com>
11 * @copyright Copyright (c) 2018 Brady Miller <brady.g.miller@gmail.com>
12 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
16 require_once('../globals.php');
17 require_once($GLOBALS['srcdir'].'/acl.inc');
18 /* for formData() */
20 if (!acl_check('admin', 'super')) {
21 die(xlt('Not authorized'));
24 $imagedir = "$OE_SITE_DIR/images";
25 $educationdir = "$OE_SITE_DIR/documents/education";
27 if (!empty($_POST['bn_save'])) {
28 //verify csrf
29 if (!verifyCsrfToken($_POST["csrf_token_form"])) {
30 csrfNotVerified();
33 /** This is a feature that allows editing of configuration files. Uncomment this
34 at your own risk, since it is considered a critical security vulnerability if
35 OpenEMR is not configured correctly.
36 // Prepare array of names of editable files, relative to the site directory.
37 $my_files = array(
38 'config.php',
39 'faxcover.txt',
40 'faxtitle.eps',
41 'referral_template.html',
42 'statement.inc.php',
43 'letter_templates/custom_pdf.php',
45 // Append LBF plugin filenames to the array.
46 $lres = sqlStatement('SELECT grp_form_id FROM layout_group_properties ' .
47 "WHERE grp_form_id LIKE 'LBF%' AND grp_group_id = '' AND grp_activity = 1 ORDER BY grp_seq, grp_title");
48 while ($lrow = sqlFetchArray($lres)) {
49 $option_id = $lrow['grp_form_id']; // should start with LBF
50 $my_files[] = "LBF/$option_id.plugin.php";
52 $form_filename = $_REQUEST['form_filename'];
53 // Sanity check to prevent evildoing.
54 if (!in_array($form_filename, $my_files)) {
55 $form_filename = '';
57 $filepath = "$OE_SITE_DIR/$form_filename";
58 if ($form_filename) {
59 // Textareas, at least in Firefox, return a \r\n at the end of each line
60 // even though only \n was originally there. For consistency with
61 // normal OpenEMR usage we translate those back.
62 file_put_contents($filepath, str_replace(
63 "\r\n",
64 "\n",
65 $_POST['form_filedata']
66 ));
67 $form_filename = '';
71 // Handle image uploads.
72 if (is_uploaded_file($_FILES['form_image']['tmp_name']) && $_FILES['form_image']['size']) {
73 $form_dest_filename = $_POST['form_dest_filename'];
74 if ($form_dest_filename == '') {
75 $form_dest_filename = $_FILES['form_image']['name'];
78 $form_dest_filename = basename($form_dest_filename);
79 if ($form_dest_filename == '') {
80 die(xlt('Cannot find a destination filename'));
83 $path_parts = pathinfo($form_dest_filename);
84 if (!in_array(strtolower($path_parts['extension']), array('gif','jpg','jpe','jpeg','png','svg'))) {
85 die(xlt('Only images files are accepted'));
88 $imagepath = "$imagedir/$form_dest_filename";
89 // If the site's image directory does not yet exist, create it.
90 if (!is_dir($imagedir)) {
91 mkdir($imagedir);
94 if (is_file($imagepath)) {
95 unlink($imagepath);
98 $tmp_name = $_FILES['form_image']['tmp_name'];
99 if (!move_uploaded_file($_FILES['form_image']['tmp_name'], $imagepath)) {
100 die(xlt('Unable to create') . " '" . text($imagepath) . "'");
104 // Handle PDF uploads for patient education.
105 if (is_uploaded_file($_FILES['form_education']['tmp_name']) && $_FILES['form_education']['size']) {
106 $form_dest_filename = $_FILES['form_education']['name'];
107 $form_dest_filename = strtolower(basename($form_dest_filename));
108 if (substr($form_dest_filename, -4) != '.pdf') {
109 die(xlt('Filename must end with ".pdf"'));
112 $educationpath = "$educationdir/$form_dest_filename";
113 // If the site's education directory does not yet exist, create it.
114 if (!is_dir($educationdir)) {
115 mkdir($educationdir);
118 if (is_file($educationpath)) {
119 unlink($educationpath);
122 $tmp_name = $_FILES['form_education']['tmp_name'];
123 if (!move_uploaded_file($tmp_name, $educationpath)) {
124 die(text(xl('Unable to create') . " '$educationpath'"));
130 * Thumbnails generator
131 * generating thumbnail image to all images files from documents table
134 if (isset($_POST['generate_thumbnails'])) {
135 //verify csrf
136 if (!verifyCsrfToken($_POST["csrf_token_form"])) {
137 csrfNotVerified();
140 $thumb_generator = new ThumbnailGenerator();
141 $results = $thumb_generator->generate_all();
143 $thumbnail_msg = "<p style='color: green'>" . xlt('Generated thumbnail(s)') . " : " . text($results['sum_success']) . "</p>";
144 $thumbnail_msg .= "<p style='color: red'>" . xlt('Failed to generate') . " : " . text($results['sum_failed']) . "</p>";
145 foreach ($results['failed'] as $key => $file) {
146 $num = $key +1;
147 $thumbnail_msg .= "<p style='color: red; font-size: 11px'> " .text($num) . ". " . text($file) . "</p>";
149 } else {
150 $count_not_generated = ThumbnailGenerator::count_not_generated();
152 $thumbnail_msg = "<p>" . xlt('Files with empty thumbnail') . ": " . text($count_not_generated) . " </p>";
157 * White list files.
158 * Security feature that enable to upload only file with mime-type from white list.
159 * Important to prevention upload of virus script.
160 * Dependence - turn on global setting 'secure_upload'
163 if ($GLOBALS['secure_upload']) {
164 $mime_types = array('image/*', 'text/*', 'audio/*', 'video/*');
166 // Get cURL resource
167 $curl = curl_init();
169 curl_setopt_array($curl, array(
170 CURLOPT_RETURNTRANSFER => 1,
171 CURLOPT_URL => 'https://cdn.rawgit.com/jshttp/mime-db/master/db.json',
172 CURLOPT_CONNECTTIMEOUT => 5,
173 CURLOPT_TIMEOUT => 5
175 // Send the request & save response to $resp
176 $resp = curl_exec($curl);
177 $httpinfo = curl_getinfo($curl);
178 if ($resp && $httpinfo['http_code'] == 200 && $httpinfo['content_type'] == 'application/json;charset=utf-8') {
179 $all_mime_types = json_decode($resp, true);
180 foreach ($all_mime_types as $name => $value) {
181 $mime_types[] = $name;
183 } else {
184 error_log('Get list of mime-type error: "' . curl_error($curl) . '" - Code: ' . curl_errno($curl));
185 $mime_types_list = array(
186 'application/pdf',
187 'image/jpeg',
188 'image/png',
189 'image/gif',
190 'application/msword',
191 'application/vnd.oasis.opendocument.spreadsheet',
192 'text/plain'
194 $mime_types = array_merge($mime_types, $mime_types_list);
197 curl_close($curl);
199 if (isset($_POST['submit_form'])) {
200 //verify csrf
201 if (!verifyCsrfToken($_POST["csrf_token_form"])) {
202 csrfNotVerified();
205 $new_white_list = empty($_POST['white_list']) ? array() : $_POST['white_list'];
207 // truncate white list from list_options table
208 sqlStatement("DELETE FROM `list_options` WHERE `list_id` = 'files_white_list'");
209 foreach ($new_white_list as $mimetype) {
210 sqlStatement("INSERT INTO `list_options` (`list_id`, `option_id`, `title`, `activity`) VALUES ('files_white_list', ?, ?, 1)", array($mimetype, $mimetype));
213 $white_list = $new_white_list;
214 } else {
215 $white_list = array();
216 $lres = sqlStatement("SELECT option_id FROM list_options WHERE list_id = 'files_white_list' AND activity = 1");
217 while ($lrow = sqlFetchArray($lres)) {
218 $white_list[] = $lrow['option_id'];
225 <html>
227 <head>
228 <title><?php echo xlt('File management'); ?></title>
229 <link rel="stylesheet" href='<?php echo $css_header ?>' type='text/css'>
231 <style type="text/css">
232 .dehead { color:#000000; font-family:sans-serif; font-size:10pt; font-weight:bold }
233 .detail { color:#000000; font-family:sans-serif; font-size:10pt; font-weight:normal }
234 #generate_thumb, #file_type_whitelist{
235 width: 95%;
236 margin: 50px auto;
237 border: 2px solid dimgrey;
239 #generate_thumb table{
240 font-size: 14px;
241 text-align: center;
243 #generate_thumb table td{
244 border-right: 1px solid dimgrey;
245 padding: 0 15px;
247 </style>
249 <script type="text/javascript" src="<?php echo $GLOBALS['assets_static_relative'] ?>/jquery/dist/jquery.min.js"></script>
251 <script language="JavaScript">
252 // This is invoked when a filename selection changes in the drop-list.
253 // In this case anything else entered into the form is discarded.
254 function msfFileChanged() {
255 top.restoreSession();
256 document.forms[0].submit();
258 </script>
260 </head>
262 <body class="body_top">
263 <form method='post' action='manage_site_files.php' enctype='multipart/form-data'
264 onsubmit='return top.restoreSession()'>
265 <input type="hidden" name="csrf_token_form" value="<?php echo attr(collectCsrfToken()); ?>" />
267 <center>
270 <table border='1' width='95%'>
272 <?php /** This is a feature that allows editing of configuration files. Uncomment this
273 at your own risk, since it is considered a critical security vulnerability if
274 OpenEMR is not configured correctly. ?>
275 <tr bgcolor='#dddddd' class='dehead'>
276 <td colspan='2' align='center'><?php echo xlt('Edit File in') . " " . text($OE_SITE_DIR); ?></td>
277 </tr>
278 <tr>
279 <td valign='top' class='detail' nowrap>
280 <select name='form_filename' onchange='msfFileChanged()'>
281 <option value=''></option>
282 <?php
283 foreach ($my_files as $filename) {
284 echo " <option value='" . attr($filename) . "'";
285 if ($filename == $form_filename) {
286 echo " selected";
288 echo ">" . text($filename) . "</option>\n";
291 </select>
292 <br />
293 <textarea name='form_filedata' rows='25' style='width:100%'><?php
294 if ($form_filename) {
295 echo text(@file_get_contents($filepath));
297 ?></textarea>
298 </td>
299 </tr>
300 <?php */ ?>
302 <tr bgcolor='#dddddd' class='dehead'>
303 <td colspan='2' align='center'><?php echo text(xl('Upload Image to') . " $imagedir"); ?></td>
304 </tr>
306 <tr>
307 <td valign='top' class='detail' nowrap>
308 <?php echo xlt('Source File'); ?>:
309 <input type="hidden" name="MAX_FILE_SIZE" value="12000000" />
310 <input type="file" name="form_image" size="40" />&nbsp;
311 <?php echo xlt('Destination Filename'); ?>:
312 <select name='form_dest_filename'>
313 <option value=''>(<?php echo xlt('Use source filename'); ?>)</option>
314 <?php
315 // Generate an <option> for each file already in the images directory.
316 $dh = opendir($imagedir);
317 if (!$dh) {
318 die(text(xl('Cannot read directory') . " '$imagedir'"));
321 $imagesslist = array();
322 while (false !== ($sfname = readdir($dh))) {
323 if (substr($sfname, 0, 1) == '.') {
324 continue;
327 if ($sfname == 'CVS') {
328 continue;
331 $imageslist[$sfname] = $sfname;
334 closedir($dh);
335 ksort($imageslist);
336 foreach ($imageslist as $sfname) {
337 echo " <option value='" . attr($sfname) . "'";
338 echo ">" . text($sfname) . "</option>\n";
341 </select>
342 </td>
343 </tr>
345 <tr bgcolor='#dddddd' class='dehead'>
346 <td colspan='2' align='center'><?php echo text(xl('Upload Patient Education PDF to') . " $educationdir"); ?></td>
347 </tr>
348 <tr>
349 <td valign='top' class='detail' nowrap>
350 <?php echo xlt('Source File'); ?>:
351 <input type="file" name="form_education" size="40" />&nbsp;
352 <?php echo xlt('Name must be like codetype_code_language.pdf, for example icd9_274.11_en.pdf'); ?>
353 </td>
354 </tr>
356 </table>
359 <input type='submit' name='bn_save' value='<?php echo xla('Save'); ?>' />
360 </p>
362 </center>
364 </form>
366 <div id="generate_thumb">
367 <table style="width: 100%">
368 <tr>
369 <td class="thumb_title" style="width: 33%">
370 <b><?php echo xlt('Generate Thumbnails')?></b>
371 </td>
372 <td class="thumb_msg" style="width: 50%">
373 <span><?php echo $thumbnail_msg ?></span>
374 </td>
375 <td class="thumb_form" style="width:17%;border-right:none">
376 <form method='post' action='manage_site_files.php#generate_thumb'>
377 <input type="hidden" name="csrf_token_form" value="<?php echo attr(collectCsrfToken()); ?>" />
378 <input style="margin-top: 10px" type="submit" name="generate_thumbnails" value="<?php echo xla('Generate') ?>">
379 </form>
380 </td>
381 </tr>
382 </table>
383 </div>
385 <?php if ($GLOBALS['secure_upload']) { ?>
387 <div id="file_type_whitelist">
388 <h2><?php echo xlt('Create custom white list of MIME content type of a files to secure your documents system');?></h2>
389 <form id="whitelist_form" method="post">
390 <div class="subject-black-list">
391 <div class="top-list">
392 <h2><?php echo xlt('Black list'); ?></h2>
393 <b><?php echo xlt('Filter');?>:</b> <input type="text" id="filter-black-list" >
394 </div>
395 <select multiple="multiple" id='black-list' class="form-control">
396 <?php
397 foreach ($mime_types as $type) {
398 if (!in_array($type, $white_list)) {
399 echo "<option value='" . attr($type) . "'> " . text($type) . "</option>";
403 </select>
404 </div>
406 <div class="subject-info-arrows">
407 <input type="button" id="btnAllRight" value=">>" /><br />
408 <input type="button" id="btnRight" value=">" /><br />
409 <input type="button" id="btnLeft" value="<" /><br />
410 <input type="button" id="btnAllLeft" value="<<" />
411 </div>
413 <div class="subject-white-list">
414 <div class="top-list">
415 <h2><?php echo xlt('White list'); ?></h2>
416 <b><?php echo xlt('Add manually');?>:</b> <input type="text" id="add-manually-input"> <input type="button" id="add-manually" value="+">
417 </div>
418 <select name="white_list[]" multiple="multiple" id='white-list' class="form-control">
419 <?php
420 foreach ($white_list as $type) {
421 echo "<option value='" . attr($type) . "'> " . text($type) . "</option>";
424 </select>
425 </div>
426 <div class="subject-info-save">
427 <input type="button" id="submit-whitelist" value="<?php echo xla('Save'); ?>" />
428 <input type="hidden" name="submit_form" value="1" />
429 <input type="hidden" name="csrf_token_form" value="<?php echo attr(collectCsrfToken()); ?>" />
430 </div>
431 </form>
433 </div>
435 <script>
437 (function () {
438 $('#btnRight').click(function (e) {
439 var selectedOpts = $('#black-list option:selected');
440 if (selectedOpts.length == 0) {
441 e.preventDefault();
444 $('#white-list').append($(selectedOpts).clone());
445 $(selectedOpts).remove();
446 e.preventDefault();
449 $('#btnAllRight').click(function (e) {
450 var selectedOpts = $('#black-list option');
451 if (selectedOpts.length == 0) {
452 e.preventDefault();
455 $('#white-list').append($(selectedOpts).clone());
456 $(selectedOpts).remove();
457 e.preventDefault();
460 $('#btnLeft').click(function (e) {
461 var selectedOpts = $('#white-list option:selected');
462 if (selectedOpts.length == 0) {
463 e.preventDefault();
466 $('#black-list').append($(selectedOpts).clone());
467 $(selectedOpts).remove();
468 e.preventDefault();
471 $('#btnAllLeft').click(function (e) {
472 var selectedOpts = $('#white-list option');
473 if (selectedOpts.length == 0) {
474 e.preventDefault();
477 $('#black-list').append($(selectedOpts).clone());
478 $(selectedOpts).remove();
479 e.preventDefault();
482 var storeElements = [];
484 $('#filter-black-list').on('keyup', function() {
485 var val = this.value.toLowerCase();
487 $('#black-list option').each(function(){
489 if(this.value.toLowerCase().indexOf( val ) == -1){
490 if(storeElements.indexOf(this) == -1){
491 storeElements.unshift(this)
493 $(this).remove();
497 $(storeElements).each(function(key, element){
499 if(element.value.toLowerCase().indexOf( val ) > -1){
501 $('#black-list').prepend(element);
502 storeElements.splice(key, 1)
509 $('#add-manually').on('click', function () {
510 var new_type = $("#add-manually-input").val();
511 if(new_type.length < 1)return;
512 $('#white-list').prepend("<option value="+new_type+">"+new_type+"</option>")
515 $('#submit-whitelist').on('click', function () {
516 $('#white-list option').prop('selected', true);
517 $('#whitelist_form').submit();
520 }(jQuery));
522 </script>
525 <?php } ?>
527 </body>
528 </html>