Merge pull request #301 from mkoch227/attachment-improvements
Attachment improvements, phase onemerge-requests/2/head
commit
25dd548e35
@ -0,0 +1,189 @@
|
||||
<?php
|
||||
/*******************************************************************************
|
||||
* Title: Help Desk Software HESK
|
||||
* Version: 2.6.4 from 22nd June 2015
|
||||
* Author: Klemen Stirn
|
||||
* Website: http://www.hesk.com
|
||||
********************************************************************************
|
||||
* COPYRIGHT AND TRADEMARK NOTICE
|
||||
* Copyright 2005-2015 Klemen Stirn. All Rights Reserved.
|
||||
* HESK is a registered trademark of Klemen Stirn.
|
||||
|
||||
* The HESK may be used and modified free of charge by anyone
|
||||
* AS LONG AS COPYRIGHT NOTICES AND ALL THE COMMENTS REMAIN INTACT.
|
||||
* By using this code you agree to indemnify Klemen Stirn from any
|
||||
* liability that might arise from it's use.
|
||||
|
||||
* Selling the code for this program, in part or full, without prior
|
||||
* written consent is expressly forbidden.
|
||||
|
||||
* Using this code, in part or full, to create derivate work,
|
||||
* new scripts or products is expressly forbidden. Obtain permission
|
||||
* before redistributing this software over the Internet or in
|
||||
* any other medium. In all cases copyright and header must remain intact.
|
||||
* This Copyright is in full effect in any country that has International
|
||||
* Trade Agreements with the United States of America or
|
||||
* with the European Union.
|
||||
|
||||
* Removing any of the copyright notices without purchasing a license
|
||||
* is expressly forbidden. To remove HESK copyright notice you must purchase
|
||||
* a license for this script. For more information on how to obtain
|
||||
* a license please visit the page below:
|
||||
* https://www.hesk.com/buy.php
|
||||
*******************************************************************************/
|
||||
|
||||
define('IN_SCRIPT',1);
|
||||
define('HESK_PATH','./');
|
||||
|
||||
// Get all the required files and functions
|
||||
require(HESK_PATH . 'hesk_settings.inc.php');
|
||||
require(HESK_PATH . 'modsForHesk_settings.inc.php');
|
||||
require(HESK_PATH . 'inc/common.inc.php');
|
||||
hesk_load_database_functions();
|
||||
|
||||
hesk_session_start();
|
||||
|
||||
// Are we in maintenance mode? (check customers only)
|
||||
if ( empty($SESSION['id']) )
|
||||
{
|
||||
hesk_check_maintenance();
|
||||
}
|
||||
|
||||
// Knowledgebase attachments
|
||||
if ( isset($_GET['kb_att']) )
|
||||
{
|
||||
// Attachment ID
|
||||
$att_id = intval( hesk_GET('kb_att') ) or hesk_error($hesklang['id_not_valid']);
|
||||
|
||||
// Connect to database
|
||||
hesk_dbConnect();
|
||||
|
||||
// Get attachment info
|
||||
$res = hesk_dbQuery("SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."kb_attachments` WHERE `att_id`='{$att_id}' LIMIT 1");
|
||||
if (hesk_dbNumRows($res) != 1)
|
||||
{
|
||||
hesk_error($hesklang['id_not_valid'].' (att_id)');
|
||||
}
|
||||
$file = hesk_dbFetchAssoc($res);
|
||||
|
||||
// Is this person allowed access to this attachment?
|
||||
$res = hesk_dbQuery("SELECT `t1`.`type` as `cat_type`, `t2`.`type` as `art_type`
|
||||
FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."kb_articles` AS `t2`
|
||||
JOIN `".hesk_dbEscape($hesk_settings['db_pfix'])."kb_categories` AS `t1`
|
||||
ON `t2`.`catid` = `t1`.`id`
|
||||
WHERE (`t2`.`attachments` LIKE '{$att_id}#%' OR `t2`.`attachments` LIKE '%,{$att_id}#%' )
|
||||
LIMIT 1");
|
||||
|
||||
// If no attachment found, throw an error
|
||||
if (hesk_dbNumRows($res) != 1)
|
||||
{
|
||||
hesk_error($hesklang['id_not_valid'].' (no_art)');
|
||||
}
|
||||
$row = hesk_dbFetchAssoc($res);
|
||||
|
||||
// Private or draft article or category?
|
||||
if ($row['cat_type'] || $row['art_type'])
|
||||
{
|
||||
if ( empty($_SESSION['id']) )
|
||||
{
|
||||
// This is a staff-only attachment
|
||||
hesk_error($hesklang['attpri']);
|
||||
}
|
||||
elseif ($row['art_type'] == 2)
|
||||
{
|
||||
// Need permission to manage KB to access draft attachments
|
||||
require(HESK_PATH . 'inc/admin_functions.inc.php');
|
||||
hesk_checkPermission('can_man_kb');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ticket attachments
|
||||
else
|
||||
{
|
||||
// Attachmend ID and ticket tracking ID
|
||||
$att_id = intval( hesk_GET('att_id', 0) ) or die($hesklang['id_not_valid']);
|
||||
$tic_id = hesk_cleanID() or die("$hesklang[int_error]: $hesklang[no_trackID]");
|
||||
|
||||
// Connect to database
|
||||
hesk_dbConnect();
|
||||
|
||||
// Get attachment info
|
||||
$res = hesk_dbQuery("SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."attachments` WHERE `att_id`='{$att_id}' LIMIT 1");
|
||||
if (hesk_dbNumRows($res) != 1)
|
||||
{
|
||||
hesk_error($hesklang['id_not_valid'].' (att_id)');
|
||||
}
|
||||
$file = hesk_dbFetchAssoc($res);
|
||||
|
||||
// Is ticket ID valid for this attachment?
|
||||
if ($file['ticket_id'] != $tic_id)
|
||||
{
|
||||
hesk_error($hesklang['trackID_not_found']);
|
||||
}
|
||||
|
||||
// Verify email address match if needed
|
||||
if ( empty($_SESSION['id']) )
|
||||
{
|
||||
hesk_verifyEmailMatch($tic_id);
|
||||
|
||||
// Only staff may download attachments to notes
|
||||
if ($file['type'])
|
||||
{
|
||||
hesk_error($hesklang['perm_deny']);
|
||||
}
|
||||
}
|
||||
|
||||
// Update the download count
|
||||
|
||||
}
|
||||
|
||||
// Path of the file on the server
|
||||
$realpath = $hesk_settings['attach_dir'] . '/' . $file['saved_name'];
|
||||
if (isset($_GET['kb_att'])) {
|
||||
$realpath = $modsForHesk_settings['kb_attach_dir'] . '/' . $file['saved_name'];
|
||||
}
|
||||
|
||||
// Perhaps the file has been deleted?
|
||||
if ( ! file_exists($realpath))
|
||||
{
|
||||
hesk_error($hesklang['attdel']);
|
||||
}
|
||||
|
||||
// Update the download count
|
||||
if ( isset($_GET['kb_att']) ) {
|
||||
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."kb_attachments` SET `download_count` = `download_count` + 1 WHERE `att_id` = '{$att_id}'");
|
||||
} else {
|
||||
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."attachments` SET `download_count` = `download_count` + 1 WHERE `att_id` = '{$att_id}'");
|
||||
}
|
||||
|
||||
// Send the file as an attachment to prevent malicious code from executing
|
||||
header("Pragma: "); # To fix a bug in IE when running https
|
||||
header("Cache-Control: "); # To fix a bug in IE when running https
|
||||
header('Content-Description: File Transfer');
|
||||
header('Content-Type: application/octet-stream');
|
||||
header('Content-Length: ' . $file['size']);
|
||||
header('Content-Disposition: attachment; filename=' . $file['real_name']);
|
||||
|
||||
// For larger files use chunks, smaller ones can be read all at once
|
||||
$chunksize = 1048576; // = 1024 * 1024 (1 Mb)
|
||||
if ($file['size'] > $chunksize)
|
||||
{
|
||||
$handle = fopen($realpath, 'rb');
|
||||
$buffer = '';
|
||||
while ( ! feof($handle))
|
||||
{
|
||||
set_time_limit(300);
|
||||
$buffer = fread($handle, $chunksize);
|
||||
echo $buffer;
|
||||
flush();
|
||||
}
|
||||
fclose($handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
readfile($realpath);
|
||||
}
|
||||
|
||||
exit();
|
||||
?>
|
@ -0,0 +1,142 @@
|
||||
<?php
|
||||
/*******************************************************************************
|
||||
* Title: Help Desk Software HESK
|
||||
* Version: 2.6.4 from 22nd June 2015
|
||||
* Author: Klemen Stirn
|
||||
* Website: http://www.hesk.com
|
||||
********************************************************************************
|
||||
* COPYRIGHT AND TRADEMARK NOTICE
|
||||
* Copyright 2005-2015 Klemen Stirn. All Rights Reserved.
|
||||
* HESK is a registered trademark of Klemen Stirn.
|
||||
|
||||
* The HESK may be used and modified free of charge by anyone
|
||||
* AS LONG AS COPYRIGHT NOTICES AND ALL THE COMMENTS REMAIN INTACT.
|
||||
* By using this code you agree to indemnify Klemen Stirn from any
|
||||
* liability that might arise from it's use.
|
||||
|
||||
* Selling the code for this program, in part or full, without prior
|
||||
* written consent is expressly forbidden.
|
||||
|
||||
* Using this code, in part or full, to create derivate work,
|
||||
* new scripts or products is expressly forbidden. Obtain permission
|
||||
* before redistributing this software over the Internet or in
|
||||
* any other medium. In all cases copyright and header must remain intact.
|
||||
* This Copyright is in full effect in any country that has International
|
||||
* Trade Agreements with the United States of America or
|
||||
* with the European Union.
|
||||
|
||||
* Removing any of the copyright notices without purchasing a license
|
||||
* is expressly forbidden. To remove HESK copyright notice you must purchase
|
||||
* a license for this script. For more information on how to obtain
|
||||
* a license please visit the page below:
|
||||
* https://www.hesk.com/buy.php
|
||||
*******************************************************************************/
|
||||
|
||||
/* Check if this is a valid include */
|
||||
if (!defined('IN_SCRIPT')) {die('Invalid attempt');}
|
||||
|
||||
/***************************
|
||||
Function hesk_uploadFiles()
|
||||
***************************/
|
||||
function hesk_uploadFile($i, $isTicket = true)
|
||||
{
|
||||
global $hesk_settings, $hesklang, $trackingID, $hesk_error_buffer, $modsForHesk_settings;
|
||||
|
||||
/* Return if name is empty */
|
||||
if (empty($_FILES['attachment']['name'][$i])) {return '';}
|
||||
|
||||
/* Parse the name */
|
||||
$file_realname = hesk_cleanFileName($_FILES['attachment']['name'][$i]);
|
||||
|
||||
/* Check file extension */
|
||||
$ext = strtolower(strrchr($file_realname, "."));
|
||||
if ( ! in_array($ext,$hesk_settings['attachments']['allowed_types']))
|
||||
{
|
||||
return hesk_fileError(sprintf($hesklang['type_not_allowed'], $ext, $file_realname));
|
||||
}
|
||||
|
||||
/* Check file size */
|
||||
if ($_FILES['attachment']['size'][$i] > $hesk_settings['attachments']['max_size'])
|
||||
{
|
||||
return hesk_fileError(sprintf($hesklang['file_too_large'], $file_realname));
|
||||
}
|
||||
else
|
||||
{
|
||||
$file_size = $_FILES['attachment']['size'][$i];
|
||||
}
|
||||
|
||||
/* Generate a random file name */
|
||||
$useChars='AEUYBDGHJLMNPQRSTVWXZ123456789';
|
||||
$tmp = uniqid();
|
||||
for($j=1;$j<10;$j++)
|
||||
{
|
||||
$tmp .= $useChars{mt_rand(0,29)};
|
||||
}
|
||||
|
||||
if (defined('KB'))
|
||||
{
|
||||
$file_name = substr(md5($tmp . $file_realname), 0, 200) . $ext;
|
||||
}
|
||||
else
|
||||
{
|
||||
$file_name = substr($trackingID . '_' . md5($tmp . $file_realname), 0, 200) . $ext;
|
||||
}
|
||||
|
||||
// Does the temporary file exist? If not, probably server-side configuration limits have been reached
|
||||
// Uncomment this for debugging purposes
|
||||
/*
|
||||
if ( ! file_exists($_FILES['attachment']['tmp_name'][$i]) )
|
||||
{
|
||||
return hesk_fileError($hesklang['fnuscphp']);
|
||||
}
|
||||
*/
|
||||
|
||||
/* If upload was successful let's create the headers */
|
||||
$directory = $hesk_settings['attach_dir'];
|
||||
if (!$isTicket) {
|
||||
$directory = $modsForHesk_settings['kb_attach_dir'];
|
||||
}
|
||||
if ( ! move_uploaded_file($_FILES['attachment']['tmp_name'][$i], dirname(dirname(__FILE__)).'/'.$directory.'/'.$file_name))
|
||||
{
|
||||
return hesk_fileError($hesklang['cannot_move_tmp']);
|
||||
}
|
||||
|
||||
$info = array(
|
||||
'saved_name'=> $file_name,
|
||||
'real_name' => $file_realname,
|
||||
'size' => $file_size
|
||||
);
|
||||
|
||||
return $info;
|
||||
} // End hesk_uploadFile()
|
||||
|
||||
|
||||
function hesk_fileError($error)
|
||||
{
|
||||
global $hesk_settings, $hesklang, $trackingID;
|
||||
global $hesk_error_buffer;
|
||||
|
||||
$hesk_error_buffer['attachments'] = $error;
|
||||
|
||||
return false;
|
||||
} // End hesk_fileError()
|
||||
|
||||
|
||||
function hesk_removeAttachments($attachments, $isTicket)
|
||||
{
|
||||
global $hesk_settings, $hesklang, $modsForHesk_settings;
|
||||
|
||||
$directory = $hesk_settings['attach_dir'];
|
||||
if (!$isTicket) {
|
||||
$directory = $modsForHesk_settings['kb_attach_dir'];
|
||||
}
|
||||
|
||||
$hesk_settings['server_path'] = dirname(dirname(__FILE__)).'/'.$directory.'/';
|
||||
|
||||
foreach ($attachments as $myatt)
|
||||
{
|
||||
hesk_unlink($hesk_settings['server_path'].$myatt['saved_name']);
|
||||
}
|
||||
|
||||
return true;
|
||||
} // End hesk_removeAttachments()
|
@ -0,0 +1,162 @@
|
||||
<?php
|
||||
function mfh_listAttachments($attachments='', $reply=0, $is_staff)
|
||||
{
|
||||
global $hesk_settings, $hesklang, $trackingID, $can_edit, $can_delete;
|
||||
|
||||
/* Attachments disabled or not available */
|
||||
if ( ! $hesk_settings['attachments']['use'] || ! strlen($attachments) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* List attachments */
|
||||
echo '<p><b>'.$hesklang['attachments'].':</b></p><br />';
|
||||
$att=explode(',',substr($attachments, 0, -1));
|
||||
echo '<div class="table-responsive">';
|
||||
echo '<table class="table table-striped attachment-table">';
|
||||
echo '<thead>
|
||||
<tr>
|
||||
<th> </th>
|
||||
<th>' . $hesklang['file_name'] . '</th>';
|
||||
if ($is_staff) {
|
||||
echo '<th>'.$hesklang['download_count'].'</th>';
|
||||
}
|
||||
echo '<th>'.$hesklang['action'].'</th>
|
||||
</tr>
|
||||
</thead>';
|
||||
echo '<tbody>';
|
||||
foreach ($att as $myatt)
|
||||
{
|
||||
|
||||
list($att_id, $att_name) = explode('#', $myatt);
|
||||
$fileparts = pathinfo($att_name);
|
||||
$fontAwesomeIcon = mfh_getFontAwesomeIconForFileExtension($fileparts['extension']);
|
||||
echo '
|
||||
<tr>
|
||||
<td>';
|
||||
//-- File is an image
|
||||
if ($fontAwesomeIcon == 'fa fa-file-image-o') {
|
||||
|
||||
//-- Get the actual image location and display a thumbnail. It will be linked to a modal to view a larger size.
|
||||
$path = mfh_getSavedNameUrlForAttachment($att_id, $is_staff);
|
||||
if ($path == '') {
|
||||
echo '<i class="fa fa-ban fa-4x" data-toggle="tooltip" title="'.$hesklang['attachment_removed'].'"></i>';
|
||||
} else {
|
||||
echo '<span data-toggle="tooltip" title="'.$hesklang['click_to_preview'].'">
|
||||
<img src="'.$path.'" alt="'.$hesklang['image'].'" data-toggle="modal" data-target="#modal-attachment-'.$att_id.'">
|
||||
</span>';
|
||||
echo '<div class="modal fade" id="modal-attachment-'.$att_id.'" tabindex="-1" role="dialog" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title" id="myModalLabel">'.$att_name.'</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<img class="img-responsive" src="'.$path.'" alt="'.$hesklang['image'].'">
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">'.$hesklang['close_modal'].'</button>
|
||||
<a href="../download_attachment.php?att_id='.$att_id.'&track='.$trackingID.'" class="btn btn-success">'.$hesklang['dnl'].'</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>';
|
||||
}
|
||||
} else {
|
||||
//-- Display the FontAwesome icon in the panel's body
|
||||
echo '<i class="'.$fontAwesomeIcon.' fa-4x"></i>';
|
||||
}
|
||||
echo'
|
||||
</td>
|
||||
<td>
|
||||
<p>'.$att_name.'</p>
|
||||
</td>';
|
||||
if ($is_staff) {
|
||||
echo '<td>'.mfh_getNumberOfDownloadsForAttachment($att_id).'</td>';
|
||||
}
|
||||
echo '<td>
|
||||
<div class="btn-group">';
|
||||
/* Can edit and delete tickets? */
|
||||
if ($is_staff && $can_edit && $can_delete)
|
||||
{
|
||||
echo '<a class="btn btn-danger" href="admin_ticket.php?delatt='.$att_id.'&reply='.$reply.'&track='.$trackingID.'&Refresh='.mt_rand(10000,99999).'&token='.hesk_token_echo(0).'" onclick="return hesk_confirmExecute(\''.hesk_makeJsString($hesklang['pda']).'\');" data-toggle="tooltip" data-placement="top" data-original-title="'.$hesklang['delete'].'"><i class="fa fa-times"></i></a> ';
|
||||
}
|
||||
echo '<a class="btn btn-success" href="../download_attachment.php?att_id='.$att_id.'&track='.$trackingID.'"
|
||||
data-toggle="tooltip" data-placement="top" data-original-title="'.$hesklang['dnl'].'">
|
||||
<i class="fa fa-arrow-down"></i>
|
||||
</a>';
|
||||
echo '</div>
|
||||
</td>
|
||||
</tr>
|
||||
';
|
||||
}
|
||||
echo '</tbody></table></div>';
|
||||
|
||||
return true;
|
||||
} // End hesk_listAttachments()
|
||||
|
||||
function mfh_getSavedNameUrlForAttachment($att_id, $is_staff)
|
||||
{
|
||||
global $hesk_settings;
|
||||
|
||||
//-- Call the DB for the attachment
|
||||
$nameRS = hesk_dbQuery("SELECT `saved_name` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."attachments` WHERE `att_id` = ".hesk_dbEscape($att_id));
|
||||
$name = hesk_dbFetchAssoc($nameRS);
|
||||
if ($is_staff) {
|
||||
$realpath = '../'.$hesk_settings['attach_dir'] . '/' . $name['saved_name'];
|
||||
} else {
|
||||
$realpath = $hesk_settings['attach_dir'] . '/' . $name['saved_name'];
|
||||
}
|
||||
|
||||
return !file_exists($realpath) ? '' : $realpath;
|
||||
}
|
||||
|
||||
function mfh_getFontAwesomeIconForFileExtension($fileExtension)
|
||||
{
|
||||
$imageExtensions = array('jpg','jpeg','png','bmp','gif');
|
||||
|
||||
//-- Word, Excel, and PPT file extensions: http://en.wikipedia.org/wiki/List_of_Microsoft_Office_filename_extensions
|
||||
$wordFileExtensions = array('doc','docx','dotm','dot','docm','docb');
|
||||
$excelFileExtensions = array('xls','xlt','xlm','xlsx','xlsm','xltx','xltm');
|
||||
$pptFileExtensions = array('ppt','pot','pps','pptx','pptm','potx','potm','ppsx','ppsm','sldx','sldm');
|
||||
|
||||
//-- File archive extensions: http://en.wikipedia.org/wiki/List_of_archive_formats
|
||||
$archiveFileExtensions = array('tar','gz','zip','rar','7z','bz2','lz','lzma','tgz','tbz2','zipx');
|
||||
|
||||
//-- Audio file extensions: http://en.wikipedia.org/wiki/Audio_file_format#List_of_formats
|
||||
$audioFileExtensions = array('3gp','act','aiff','aac','amr','au','awb','dct','dss','dvf','flac','gsm','iklax','ivs','m4a','m4p','mmf','mp3','mpc','msv','ogg','oga','opus','ra','rm','raw','tta','vox','wav','wma','wv');
|
||||
|
||||
//-- Video file extensions: http://en.wikipedia.org/wiki/Video_file_format#List_of_video_file_formats
|
||||
$videoFileExtensions = array('webm','mkv','flv','drc','mng','avi','mov','qt','wmv','yuv','rm','rmvb','asf','mp4','m4p','m4v','mpg','mp2','mpeg','mpe','mpv','m2v','svi','3gp','3g2','mxf','roq','nsv');
|
||||
|
||||
//-- The only one I know of :D
|
||||
$pdfFileExtensions = array('pdf');
|
||||
|
||||
$textFileExtensions = array('txt');
|
||||
|
||||
$icon = 'fa fa-file-';
|
||||
$fileExtension = strtolower($fileExtension);
|
||||
if (in_array($fileExtension, $imageExtensions)) {
|
||||
$icon.='image-o';
|
||||
} elseif (in_array($fileExtension, $wordFileExtensions)) {
|
||||
$icon.='word-o';
|
||||
} elseif (in_array($fileExtension, $excelFileExtensions)) {
|
||||
$icon.='excel-o';
|
||||
} elseif (in_array($fileExtension, $pptFileExtensions)) {
|
||||
$icon.='powerpoint-o';
|
||||
} elseif (in_array($fileExtension, $archiveFileExtensions)) {
|
||||
$icon.='archive-o';
|
||||
} elseif (in_array($fileExtension, $audioFileExtensions)) {
|
||||
$icon.='audio-o';
|
||||
} elseif (in_array($fileExtension, $videoFileExtensions)) {
|
||||
$icon.='video-o';
|
||||
} elseif (in_array($fileExtension, $pdfFileExtensions)) {
|
||||
$icon.='pdf-o';
|
||||
} elseif (in_array($fileExtension, $textFileExtensions)) {
|
||||
$icon.='text-o';
|
||||
} else {
|
||||
$icon.='o';
|
||||
}
|
||||
return $icon;
|
||||
}
|
Loading…
Reference in New Issue