diff --git a/.gitignore b/.gitignore
index 7b12609a..e4ef0e68 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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
diff --git a/admin/admin_settings.php b/admin/admin_settings.php
index 5e578079..a9d235b6 100644
--- a/admin/admin_settings.php
+++ b/admin/admin_settings.php
@@ -697,9 +697,9 @@ if ( defined('HESK_DEMO') )
@@ -1287,6 +1287,21 @@ if ( defined('HESK_DEMO') )
?>
+
+
- $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();
+?>
diff --git a/inc/attachments.inc.php b/inc/attachments.inc.php
new file mode 100644
index 00000000..8a56797a
--- /dev/null
+++ b/inc/attachments.inc.php
@@ -0,0 +1,142 @@
+ $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()
diff --git a/inc/common.inc.php b/inc/common.inc.php
index 5a6a7074..1c43e76f 100644
--- a/inc/common.inc.php
+++ b/inc/common.inc.php
@@ -1972,4 +1972,13 @@ function mfh_getDisplayTextForStatusId($statusId) {
// Fallback to the language key
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'];
}
\ No newline at end of file
diff --git a/inc/view_attachment_functions.inc.php b/inc/view_attachment_functions.inc.php
new file mode 100644
index 00000000..39dee973
--- /dev/null
+++ b/inc/view_attachment_functions.inc.php
@@ -0,0 +1,162 @@
+
'.$hesklang['attachments'].':';
+ $att=explode(',',substr($attachments, 0, -1));
+ echo '
';
+ echo '
';
+ echo '
+
+ |
+ ' . $hesklang['file_name'] . ' | ';
+ if ($is_staff) {
+ echo ''.$hesklang['download_count'].' | ';
+ }
+ echo ''.$hesklang['action'].' |
+
+ ';
+ echo '';
+ foreach ($att as $myatt)
+ {
+
+ list($att_id, $att_name) = explode('#', $myatt);
+ $fileparts = pathinfo($att_name);
+ $fontAwesomeIcon = mfh_getFontAwesomeIconForFileExtension($fileparts['extension']);
+ echo '
+
+ ';
+ //-- 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 '';
+ } else {
+ echo '
+
+ ';
+ echo '
+
+
+
+
+
+
+
+
+
+ ';
+ }
+ } else {
+ //-- Display the FontAwesome icon in the panel's body
+ echo '';
+ }
+ echo'
+ |
+
+ '.$att_name.'
+ | ';
+ if ($is_staff) {
+ echo ''.mfh_getNumberOfDownloadsForAttachment($att_id).' | ';
+ }
+ echo '
+ ';
+ /* Can edit and delete tickets? */
+ if ($is_staff && $can_edit && $can_delete)
+ {
+ echo ' ';
+ }
+ echo '
+
+ ';
+ echo '
+ |
+
+ ';
+ }
+ echo '
';
+
+ 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;
+}
\ No newline at end of file
diff --git a/install/mods-for-hesk/sql/installSql.php b/install/mods-for-hesk/sql/installSql.php
index 53405010..76cdb845 100644
--- a/install/mods-for-hesk/sql/installSql.php
+++ b/install/mods-for-hesk/sql/installSql.php
@@ -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);
}
\ No newline at end of file
diff --git a/language/en/text.php b/language/en/text.php
index f193e14c..b225a82f 100644
--- a/language/en/text.php
+++ b/language/en/text.php
@@ -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.
The folder needs to exist within the main HESK folder and be writable by PHP. On most systems names are CaSe SeNSiTiVe.
+
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';
diff --git a/modsForHesk_settings.inc.php b/modsForHesk_settings.inc.php
index ca271ed5..6e152745 100644
--- a/modsForHesk_settings.inc.php
+++ b/modsForHesk_settings.inc.php
@@ -55,4 +55,7 @@ $modsForHesk_settings['category_order_column'] = 'cat_order';
$modsForHesk_settings['rich_text_for_tickets'] = 0;
//-- Column to sort statuses by. Can be either 'sort' or 'name'
-$modsForHesk_settings['statuses_order_column'] = 'sort';
\ No newline at end of file
+$modsForHesk_settings['statuses_order_column'] = 'sort';
+
+//-- Directory to store knowledgebase articles in.
+$modsForHesk_settings['kb_attach_dir'] = 'attachments';
\ No newline at end of file
diff --git a/ticket.php b/ticket.php
index ff9412c4..bc1e34c2 100644
--- a/ticket.php
+++ b/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);
?>
@@ -726,7 +727,7 @@ function hesk_printCustomerTicketReplies()