Merge pull request #301 from mkoch227/attachment-improvements
Attachment improvements, phase one
This commit is contained in:
commit
25dd548e35
2
.gitignore
vendored
2
.gitignore
vendored
@ -11,7 +11,6 @@ docs/docs_style.css
|
||||
docs/index.html
|
||||
docs/quick-guide.html
|
||||
docs/step-by-step-guide.html
|
||||
download_attachment.php
|
||||
file_limits.php
|
||||
footer.txt
|
||||
header.txt
|
||||
@ -147,7 +146,6 @@ img/unlock.png
|
||||
img/vertical.jpg
|
||||
img/view.png
|
||||
inc/assignment_search.inc.php
|
||||
inc/attachments.inc.php
|
||||
inc/calendar/img/cal.gif
|
||||
inc/calendar/img/next_mon.gif
|
||||
inc/calendar/img/next_year.gif
|
||||
|
@ -697,9 +697,9 @@ if ( defined('HESK_DEMO') )
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="s_attach_dir" class="col-sm-3 control-label"><?php echo $hesklang['atf']; ?> <a href="Javascript:void(0)" onclick="Javascript:hesk_window('<?php echo $help_folder; ?>helpdesk.html#62','400','500')"><i class="fa fa-question-circle settingsquestionmark"></i></a></label>
|
||||
<label for="s_attach_dir" class="col-sm-3 control-label"><?php echo $hesklang['ticket_attach_dir']; ?> <a href="Javascript:void(0)" onclick="Javascript:hesk_window('<?php echo $help_folder; ?>helpdesk.html#62','400','500')"><i class="fa fa-question-circle settingsquestionmark"></i></a></label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" class="form-control" placeholder="<?php echo htmlspecialchars($hesklang['atf']); ?>" name="s_attach_dir" size="40" maxlength="255" value="<?php echo $hesk_settings['attach_dir']; ?>" />
|
||||
<input type="text" class="form-control" placeholder="<?php echo htmlspecialchars($hesklang['ticket_attach_dir']); ?>" name="s_attach_dir" size="40" maxlength="255" value="<?php echo $hesk_settings['attach_dir']; ?>" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
@ -1287,6 +1287,21 @@ if ( defined('HESK_DEMO') )
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="kb_attach_dir" class="col-sm-4 control-label">
|
||||
<span class="label label-primary"
|
||||
data-toggle="tooltip"
|
||||
title="<?php echo $hesklang['added_in_mods_for_hesk']; ?>"><?php echo $hesklang['mods_for_hesk_acronym']; ?></span>
|
||||
<?php echo $hesklang['kb_attach_dir']; ?>
|
||||
<i class="fa fa-question-circle settingsquestionmark" data-toggle="htmlpopover"
|
||||
title="<?php echo $hesklang['kb_attach_dir']; ?>"
|
||||
data-content="<?php echo $hesklang['kb_attach_dir_help']; ?>"></i>
|
||||
</label>
|
||||
<div class="col-sm-8">
|
||||
<input type="text" class="form-control" placeholder="<?php echo htmlspecialchars($hesklang['kb_attach_dir']); ?>" name="kb_attach_dir" size="40" maxlength="255" value="<?php echo $modsForHesk_settings['kb_attach_dir']; ?>">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="knowledgebase-visibility-setting" class="col-sm-4 col-xs-12 control-label">
|
||||
<span class="label label-primary"
|
||||
|
@ -518,6 +518,7 @@ $set['request_location'] = empty($_POST['request_location']) ? 0 : 1;
|
||||
$set['category_order_column'] = empty($_POST['category_order_column']) ? 'cat_order' : 'name';
|
||||
$set['rich_text_for_tickets'] = empty($_POST['rich_text_for_tickets']) ? 0 : 1;
|
||||
$set['statuses_order_column'] = empty($_POST['statuses_order_column']) ? 'sort' : 'name';
|
||||
$set['kb_attach_dir'] = hesk_POST('kb_attach_dir', 'attachments');
|
||||
|
||||
if ($set['customer-email-verification-required'])
|
||||
{
|
||||
@ -592,7 +593,10 @@ $modsForHesk_settings[\'category_order_column\'] = \''.$set['category_order_colu
|
||||
$modsForHesk_settings[\'rich_text_for_tickets\'] = '.$set['rich_text_for_tickets'].';
|
||||
|
||||
//-- Column to sort statuses by. Can be either \'sort\' or \'name\'
|
||||
$modsForHesk_settings[\'statuses_order_column\'] = \''.$set['statuses_order_column'].'\';';
|
||||
$modsForHesk_settings[\'statuses_order_column\'] = \''.$set['statuses_order_column'].'\';
|
||||
|
||||
//-- Directory to store knowledgebase articles in.
|
||||
$modsForHesk_settings[\'kb_attach_dir\'] = \''.$set['kb_attach_dir'].'\';';
|
||||
|
||||
// Write the file
|
||||
if ( ! file_put_contents(HESK_PATH . 'modsForHesk_settings.inc.php', $modsForHesk_file_content) )
|
||||
|
@ -42,6 +42,7 @@ require(HESK_PATH . 'modsForHesk_settings.inc.php');
|
||||
require(HESK_PATH . 'inc/common.inc.php');
|
||||
require(HESK_PATH . 'inc/admin_functions.inc.php');
|
||||
require(HESK_PATH . 'inc/status_functions.inc.php');
|
||||
require(HESK_PATH . 'inc/view_attachment_functions.inc.php');
|
||||
hesk_load_database_functions();
|
||||
|
||||
hesk_session_start();
|
||||
@ -1430,7 +1431,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
}
|
||||
}
|
||||
/* Attachments */
|
||||
hesk_listAttachments($ticket['attachments']);
|
||||
mfh_listAttachments($ticket['attachments'], 0, true);
|
||||
|
||||
// Show suggested KB articles
|
||||
if ($hesk_settings['kb_enable'] && $hesk_settings['kb_recommendanswers'] && strlen($ticket['articles']) )
|
||||
@ -1504,154 +1505,6 @@ require_once(HESK_PATH . 'inc/footer.inc.php');
|
||||
|
||||
/*** START FUNCTIONS ***/
|
||||
|
||||
|
||||
function hesk_listAttachments($attachments='', $reply=0, $white=1)
|
||||
{
|
||||
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><th>'.$hesklang['action'].'</th></tr></thead>';
|
||||
echo '<tbody>';
|
||||
foreach ($att as $myatt)
|
||||
{
|
||||
|
||||
list($att_id, $att_name) = explode('#', $myatt);
|
||||
$fileparts = pathinfo($att_name);
|
||||
$fontAwesomeIcon = hesk_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 = hesk_getSavedNameUrlForAttachment($att_id);
|
||||
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>
|
||||
<td>
|
||||
<div class="btn-group">';
|
||||
/* Can edit and delete tickets? */
|
||||
if ($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 hesk_getSavedNameUrlForAttachment($att_id)
|
||||
{
|
||||
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);
|
||||
$realpath = '../'.$hesk_settings['attach_dir'] . '/' . $name['saved_name'];
|
||||
|
||||
return !file_exists($realpath) ? '' : $realpath;
|
||||
}
|
||||
|
||||
function hesk_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;
|
||||
}
|
||||
|
||||
|
||||
function hesk_getAdminButtons($reply=0,$white=1)
|
||||
{
|
||||
global $hesk_settings, $hesklang, $ticket, $reply, $trackingID, $can_edit, $can_archive, $can_delete, $isManager;
|
||||
@ -1851,7 +1704,7 @@ function hesk_printTicketReplies() {
|
||||
} ?></p>
|
||||
</div>
|
||||
<div class="ticketMessageTop pushMargin">
|
||||
<?php hesk_listAttachments($reply['attachments'],$reply['id']);
|
||||
<?php mfh_listAttachments($reply['attachments'],$reply['id'],true);
|
||||
/* Staff rating */
|
||||
if ($hesk_settings['rating'] && $reply['staffid'])
|
||||
{
|
||||
|
@ -37,6 +37,7 @@ 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');
|
||||
require(HESK_PATH . 'inc/admin_functions.inc.php');
|
||||
hesk_load_database_functions();
|
||||
@ -1113,7 +1114,7 @@ function save_article()
|
||||
$attachments = array();
|
||||
for ($i=1;$i<=3;$i++)
|
||||
{
|
||||
$att = hesk_uploadFile($i);
|
||||
$att = hesk_uploadFile($i, false);
|
||||
if ( ! empty($att))
|
||||
{
|
||||
$attachments[$i] = $att;
|
||||
@ -1922,7 +1923,7 @@ function new_article()
|
||||
$attachments = array();
|
||||
for ($i=1;$i<=3;$i++)
|
||||
{
|
||||
$att = hesk_uploadFile($i);
|
||||
$att = hesk_uploadFile($i, false);
|
||||
if ( ! empty($att))
|
||||
{
|
||||
$attachments[$i] = $att;
|
||||
|
189
download_attachment.php
Executable file
189
download_attachment.php
Executable file
@ -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();
|
||||
?>
|
142
inc/attachments.inc.php
Normal file
142
inc/attachments.inc.php
Normal file
@ -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()
|
@ -1973,3 +1973,12 @@ function mfh_getDisplayTextForStatusId($statusId) {
|
||||
return $hesklang[$statusRec['Key']];
|
||||
}
|
||||
}
|
||||
|
||||
function mfh_getNumberOfDownloadsForAttachment($att_id, $table='attachments')
|
||||
{
|
||||
global $hesk_settings;
|
||||
|
||||
$res = hesk_dbQuery('SELECT `download_count` FROM `'.hesk_dbEscape($hesk_settings['db_pfix'].$table)."` WHERE `att_id` = ".intval($att_id));
|
||||
$rec = hesk_dbFetchAssoc($res);
|
||||
return $rec['download_count'];
|
||||
}
|
162
inc/view_attachment_functions.inc.php
Normal file
162
inc/view_attachment_functions.inc.php
Normal file
@ -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;
|
||||
}
|
@ -2,7 +2,6 @@
|
||||
define('IN_SCRIPT', 1);
|
||||
require(HESK_PATH . 'hesk_settings.inc.php');
|
||||
require(HESK_PATH . 'inc/common.inc.php');
|
||||
echo $hesklang['yes'];
|
||||
|
||||
function executeQuery($sql) {
|
||||
global $hesk_last_query;
|
||||
@ -557,6 +556,8 @@ function execute240Scripts() {
|
||||
global $hesk_settings;
|
||||
|
||||
hesk_dbConnect();
|
||||
|
||||
// Setup quick help sections
|
||||
executeQuery("CREATE TABLE `".hesk_dbEscape($hesk_settings['db_pfix'])."quick_help_sections` (
|
||||
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
`location` VARCHAR(100) NOT NULL,
|
||||
@ -572,6 +573,7 @@ function execute240Scripts() {
|
||||
executeQuery("INSERT INTO `hesk_quick_help_sections` (`location`, `show`)
|
||||
VALUES ('knowledgebase', '1')");
|
||||
|
||||
// Setup status improvement tables
|
||||
executeQuery("CREATE TABLE `".hesk_dbEscape($hesk_settings['db_pfix'])."text_to_status_xref` (
|
||||
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
`language` VARCHAR(200) NOT NULL,
|
||||
@ -586,6 +588,12 @@ function execute240Scripts() {
|
||||
WHERE `id`='".intval($myStatus['ID'])."' LIMIT 1");
|
||||
$i += 10;
|
||||
}
|
||||
|
||||
// Process attachment improvement tables
|
||||
executeQuery("ALTER TABLE `".hesk_dbEscape($hesk_settings['db_pfix'])."attachments` ADD COLUMN `download_count` INT NOT NULL DEFAULT 0");
|
||||
executeQuery("ALTER TABLE `".hesk_dbEscape($hesk_settings['db_pfix'])."kb_attachments` ADD COLUMN `download_count` INT NOT NULL DEFAULT 0");
|
||||
|
||||
executeQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."settings` SET `Value` = '2.4.0' WHERE `Key` = 'modsForHeskVersion'");
|
||||
}
|
||||
|
||||
function initializeXrefTable() {
|
||||
@ -607,6 +615,8 @@ function initializeXrefTable() {
|
||||
}
|
||||
|
||||
function execute240FileUpdate() {
|
||||
global $hesk_settings;
|
||||
|
||||
$file = file_get_contents(HESK_PATH . 'modsForHesk_settings.inc.php');
|
||||
|
||||
//-- Only add the additional settings if they aren't already there.
|
||||
@ -624,6 +634,13 @@ $modsForHesk_settings[\'category_order_column\'] = \'cat_order\';';
|
||||
//-- Setting for using rich-text editor for tickets. 0 = Disable, 1 = Enable
|
||||
$modsForHesk_settings[\'rich_text_for_tickets\'] = 0;';
|
||||
}
|
||||
if (strpos($file, '$modsForHesk_settings[\'kb_attach_dir\']') === false)
|
||||
{
|
||||
$file .= '
|
||||
|
||||
//-- Directory to store knowledgebase articles in.
|
||||
$modsForHesk_settings[\'kb_attach_dir\'] = \''.$hesk_settings['attach_dir'].'\';';
|
||||
}
|
||||
|
||||
return file_put_contents(HESK_PATH.'modsForHesk_settings.inc.php', $file);
|
||||
}
|
@ -53,6 +53,11 @@ $hesklang['status_sort'] = 'Status Sorting';
|
||||
$hesklang['status_sort_help'] = 'Determines if statuses shown on the manage statuses page and all dropdowns are sorted by the user-defined order (default), or sorted alphabetically.';
|
||||
$hesklang['cannot_delete_status_tickets'] = 'This status cannot be deleted because there are tickets set to this status.';
|
||||
$hesklang['default_statuses_updated'] = 'Default statuses have been updated!';
|
||||
$hesklang['download_count'] = 'Download Count';
|
||||
$hesklang['kb_attach_dir'] = 'Knowledgebase attachments folder';
|
||||
$hesklang['kb_attach_dir_help'] = 'Name of the folder, where knowledgebase attachments will be stored.<br><br>The folder needs to exist within the main HESK folder and be writable by PHP. On most systems names are CaSe SeNSiTiVe.
|
||||
<br><br>Allowed chars (other will be removed): a-z A-Z 0-9 _ -';
|
||||
$hesklang['ticket_attach_dir'] = 'Ticket attachments folder';
|
||||
|
||||
// ADDED OR MODIFIED IN Mods for HESK 2.3.0
|
||||
$hesklang['sm_icon'] = 'Icon';
|
||||
|
@ -56,3 +56,6 @@ $modsForHesk_settings['rich_text_for_tickets'] = 0;
|
||||
|
||||
//-- Column to sort statuses by. Can be either 'sort' or 'name'
|
||||
$modsForHesk_settings['statuses_order_column'] = 'sort';
|
||||
|
||||
//-- Directory to store knowledgebase articles in.
|
||||
$modsForHesk_settings['kb_attach_dir'] = 'attachments';
|
36
ticket.php
36
ticket.php
@ -40,6 +40,7 @@ define('WYSIWYG',1);
|
||||
/* Get all the required files and functions */
|
||||
require(HESK_PATH . 'hesk_settings.inc.php');
|
||||
require(HESK_PATH . 'inc/common.inc.php');
|
||||
require(HESK_PATH . 'inc/view_attachment_functions.inc.php');
|
||||
|
||||
// Are we in maintenance mode?
|
||||
hesk_check_maintenance();
|
||||
@ -407,7 +408,7 @@ if (!$show['show']) {
|
||||
}
|
||||
}
|
||||
/* Attachments */
|
||||
hesk_listAttachments($ticket['attachments'], $i);
|
||||
mfh_listAttachments($ticket['attachments'], $i, false);
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
@ -726,7 +727,7 @@ function hesk_printCustomerTicketReplies()
|
||||
<div class="message"><?php echo hesk_html_entity_decode($reply['message']); ?></div>
|
||||
</div>
|
||||
<div class="ticketMessageTop">
|
||||
<?php hesk_listAttachments($reply['attachments'],$i);?>
|
||||
<?php mfh_listAttachments($reply['attachments'],$i,false);?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -738,37 +739,6 @@ function hesk_printCustomerTicketReplies()
|
||||
} // End hesk_printCustomerTicketReplies()
|
||||
|
||||
|
||||
function hesk_listAttachments($attachments='', $white=1)
|
||||
{
|
||||
global $hesk_settings, $hesklang, $trackingID;
|
||||
|
||||
/* Attachments disabled or not available */
|
||||
if ( ! $hesk_settings['attachments']['use'] || ! strlen($attachments) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Style and mousover/mousout */
|
||||
$tmp = $white ? 'White' : 'Blue';
|
||||
$style = 'class="option'.$tmp.'OFF" onmouseover="this.className=\'option'.$tmp.'ON\'" onmouseout="this.className=\'option'.$tmp.'OFF\'"';
|
||||
|
||||
/* List attachments */
|
||||
echo '<p><b>'.$hesklang['attachments'].':</b><br />';
|
||||
$att=explode(',',substr($attachments, 0, -1));
|
||||
foreach ($att as $myatt)
|
||||
{
|
||||
list($att_id, $att_name) = explode('#', $myatt);
|
||||
|
||||
echo '
|
||||
<a href="download_attachment.php?att_id='.$att_id.'&track='.$trackingID.$hesk_settings['e_query'].'"><img src="img/clip.png" width="16" height="16" alt="'.$hesklang['dnl'].' '.$att_name.'" title="'.$hesklang['dnl'].' '.$att_name.'" '.$style.' /></a>
|
||||
<a href="download_attachment.php?att_id='.$att_id.'&track='.$trackingID.$hesk_settings['e_query'].'">'.$att_name.'</a><br />
|
||||
';
|
||||
}
|
||||
echo '</p>';
|
||||
|
||||
return true;
|
||||
} // End hesk_listAttachments()
|
||||
|
||||
|
||||
function hesk_getCustomerButtons($white=1)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user