Moved the Agents into their own repo. Kept the agent.pl just for reference
This commit is contained in:
parent
22381be29a
commit
8680a02b13
18132 changed files with 0 additions and 2569420 deletions
|
|
@ -1,58 +0,0 @@
|
|||
<?php
|
||||
|
||||
require 'include/ticket.php';
|
||||
require 'include/TicketSettings.php';
|
||||
|
||||
function exec_ogp_module()
|
||||
{
|
||||
global $db;
|
||||
|
||||
$ticket = new ticket($db);
|
||||
|
||||
$TicketSettings = (new TicketSettings($db))->get('attachment_save_dir');
|
||||
$saveDir = (substr($TicketSettings['attachment_save_dir'], -1) == '/' ? $TicketSettings['attachment_save_dir'] : $TicketSettings['attachment_save_dir'] . '/');
|
||||
|
||||
$isAdmin = $db->isAdmin($_SESSION['user_id']);
|
||||
|
||||
$id = (int)$_GET['id'];
|
||||
$tid = (int)$_GET['tid'];
|
||||
$uid = $_GET['uid'];
|
||||
|
||||
if (empty($id) || empty($tid) || empty($uid)) {
|
||||
print_failure(get_lang('attachment_not_all_parameters_sent'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$ticket->exists($tid, $uid)) {
|
||||
print_failure(get_lang('ticket_not_found'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$isAdmin && !$ticket->authorized($_SESSION['user_id'], $tid, $uid)) {
|
||||
print_failure(get_lang('ticket_cant_read'));
|
||||
return;
|
||||
}
|
||||
|
||||
$attachment = $ticket->getAttachmentById($id, $tid);
|
||||
|
||||
if (!$attachment) {
|
||||
print_failure(get_lang('requested_attachment_missing_db'));
|
||||
return;
|
||||
}
|
||||
|
||||
$onDiskName = $saveDir . $attachment['unique_name'];
|
||||
$originalName = $attachment['original_name'];
|
||||
|
||||
if (!file_exists($onDiskName)) {
|
||||
print_failure(get_lang('requested_attachment_missing'));
|
||||
return;
|
||||
}
|
||||
|
||||
$mime = new finfo(FILEINFO_MIME_TYPE);
|
||||
$encoding = new finfo(FILEINFO_MIME_ENCODING);
|
||||
|
||||
header('Content-Type: '.$mime->file($onDiskName));
|
||||
header('Content-Transfer-Encoding: '.$mime->file($encoding));
|
||||
header('Content-disposition: attachment; filename="'.basename($originalName).'"');
|
||||
readfile($onDiskName);
|
||||
}
|
||||
|
|
@ -1,180 +0,0 @@
|
|||
<?php
|
||||
|
||||
class Attachments
|
||||
{
|
||||
private $db;
|
||||
|
||||
private $filesArray = array();
|
||||
private $path;
|
||||
private $maxAttachments;
|
||||
private $maxSize;
|
||||
private $permittedExtensions = array();
|
||||
|
||||
private $allMimeTypes = array();
|
||||
private $permittedMimeTypes = array();
|
||||
|
||||
private $errors = array();
|
||||
|
||||
public function __construct(OGPDatabase $db, $attachments, $path, $maxAttachments, $maxSize, $permittedExtensions)
|
||||
{
|
||||
$this->db = $db;
|
||||
|
||||
$this->filesArray = $this->normalizeFiles($attachments);
|
||||
$this->path = $path;
|
||||
$this->maxAttachments = $maxAttachments;
|
||||
$this->maxSize = $maxSize;
|
||||
$this->permittedExtensions = $permittedExtensions;
|
||||
|
||||
$this->allMimeTypes = require __DIR__ .'/mime.types.php';
|
||||
$this->createMimeArray();
|
||||
}
|
||||
|
||||
public function validAttachmentCount()
|
||||
{
|
||||
if (!empty($this->filesArray)) {
|
||||
return ($this->maxAttachments == 0 || count($this->filesArray) <= $this->maxAttachments);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function validate()
|
||||
{
|
||||
foreach ($this->filesArray as $i => $file) {
|
||||
switch ($file['error']) {
|
||||
case UPLOAD_ERR_OK:
|
||||
break;
|
||||
case UPLOAD_ERR_INI_SIZE:
|
||||
$this->errors[$i][] = get_lang_f('attachment_err_ini_size', $file['name'], $file['size']);
|
||||
break;
|
||||
case UPLOAD_ERR_PARTIAL:
|
||||
$this->errors[$i][] = get_lang_f('attachment_err_partial', $file['name']);
|
||||
break;
|
||||
case UPLOAD_ERR_NO_TMP_DIR:
|
||||
$this->errors[$i][] = get_lang_f('attachment_err_no_tmp', $file['name']);
|
||||
break;
|
||||
case UPLOAD_ERR_CANT_WRITE:
|
||||
$this->errors[$i][] = get_lang_f('attachment_err_cant_write', $file['name']);
|
||||
break;
|
||||
case UPLOAD_ERR_EXTENSION:
|
||||
$this->errors[$i][] = get_lang_f('attachment_err_extension', $file['name']);
|
||||
break;
|
||||
}
|
||||
|
||||
if ($this->checkSize($file['size'])) {
|
||||
$this->errors[$i][] = get_lang_f('attachment_too_large', $file['name'], $file['size'], $this->maxSize);
|
||||
}
|
||||
|
||||
if (in_array($this->getMimeType($file['tmp_name']), $this->permittedMimeTypes) === false) {
|
||||
$this->errors[$i][] = get_lang_f('attachment_forbidden_type', $file['name']);
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getErrors()
|
||||
{
|
||||
$errors = array();
|
||||
|
||||
foreach ($this->errors as $error) {
|
||||
$errors = array_merge($error, $errors);
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
public function save($tid, $reply_id = null)
|
||||
{
|
||||
$savePath = (substr($this->path, -1) == '/' ? $this->path : $this->path . '/');
|
||||
|
||||
foreach ($this->filesArray as $i => $file) {
|
||||
// Ignore and don't save file which has an error associated with it.
|
||||
if (array_key_exists($i, $this->errors)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$original_name = basename($file['name']);
|
||||
$extension = pathinfo($file['name'], PATHINFO_EXTENSION);
|
||||
|
||||
$unique_name = bin2hex(openssl_random_pseudo_bytes(12)) . ( !$extension ? '' : '.' . $extension );
|
||||
|
||||
move_uploaded_file($file['tmp_name'], $savePath . $unique_name);
|
||||
$this->insertAttachment($tid, $reply_id, $original_name, $unique_name);
|
||||
}
|
||||
}
|
||||
|
||||
private function insertAttachment($tid, $reply_id, $original_name, $unique_name)
|
||||
{
|
||||
$fields = array(
|
||||
'ticket_id' => $tid,
|
||||
'original_name' => $original_name,
|
||||
'unique_name' => $unique_name
|
||||
);
|
||||
|
||||
if (is_numeric($reply_id)) {
|
||||
$fields['reply_id'] = $reply_id;
|
||||
}
|
||||
|
||||
return $this->db->resultInsertId('ticket_attachments', $fields);
|
||||
}
|
||||
|
||||
// Turn the _FILES array into something that's better to work with.
|
||||
private function normalizeFiles($files)
|
||||
{
|
||||
$_files = array();
|
||||
$_files_count = count($files['name']);
|
||||
$_files_keys = array_keys($files);
|
||||
|
||||
for ($i = 0; $i < $_files_count; $i++) {
|
||||
if (empty($files['tmp_name'][$i])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($_files_keys as $key) {
|
||||
$_files[$i][$key] = $files[$key][$i];
|
||||
}
|
||||
}
|
||||
|
||||
return array_values($_files);
|
||||
}
|
||||
|
||||
public function checkPath()
|
||||
{
|
||||
if (empty($this->filesArray)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!is_dir($this->path)) {
|
||||
mkdir($this->path, 0777, true);
|
||||
}
|
||||
|
||||
return is_writable($this->path);
|
||||
}
|
||||
|
||||
// Create an array of mimetypes based on the allowed extensions.
|
||||
private function createMimeArray()
|
||||
{
|
||||
$permittedMimeTypes = [];
|
||||
foreach ($this->allMimeTypes['mimes'] as $ext => $mimes) {
|
||||
if (in_array($ext, $this->permittedExtensions)) {
|
||||
$permittedMimeTypes = array_merge($permittedMimeTypes, $mimes);
|
||||
}
|
||||
}
|
||||
|
||||
$this->permittedMimeTypes = $permittedMimeTypes;
|
||||
}
|
||||
|
||||
private function checkSize($uploadedFileSize)
|
||||
{
|
||||
return ($uploadedFileSize > $this->maxSize);
|
||||
}
|
||||
|
||||
// Don't rely on $_FILES type which can be spoofed. Get the true mimetype via finfo.
|
||||
private function getMimeType($file)
|
||||
{
|
||||
$finfo = new finfo(FILEINFO_MIME_TYPE);
|
||||
$mime = $finfo->file($file);
|
||||
return $mime;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
<?php
|
||||
|
||||
class TicketSettings
|
||||
{
|
||||
private $db;
|
||||
|
||||
public function __construct(OGPDatabase $db)
|
||||
{
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
public function get($setting = '*')
|
||||
{
|
||||
$query = "SELECT setting_name, setting_value FROM OGP_DB_PREFIXticket_settings";
|
||||
|
||||
if (is_array($setting) && !empty($setting)) {
|
||||
$in = '';
|
||||
$query .= ' WHERE setting_name IN (';
|
||||
|
||||
foreach ($setting as $setting_name) {
|
||||
$in .= "'". $setting_name ."', ";
|
||||
}
|
||||
|
||||
$query .= rtrim($in, ', ');
|
||||
$query .= ')';
|
||||
} elseif (!empty($setting) && $setting !== '*') {
|
||||
$query = $query . " WHERE setting_name = '".$setting."'";
|
||||
}
|
||||
|
||||
$result = $this->db->resultQuery($query);
|
||||
return $result ? $this->flatten($result) : false;
|
||||
}
|
||||
|
||||
public function set($settings)
|
||||
{
|
||||
foreach ($settings as $setting_name => $setting_value) {
|
||||
$query = $this->buildQueryString($setting_name, $setting_value);
|
||||
$this->db->query($query);
|
||||
}
|
||||
}
|
||||
|
||||
private function buildQueryString($setting_name, $setting_value)
|
||||
{
|
||||
$setting_name = $this->db->real_escape_string($setting_name);
|
||||
$setting_value = $this->db->real_escape_string($setting_value);
|
||||
|
||||
$queryString = "INSERT INTO OGP_DB_PREFIXticket_settings (setting_name, setting_value)
|
||||
VALUES (
|
||||
'". $setting_name ."', '". $setting_value ."'
|
||||
)
|
||||
|
||||
ON DUPLICATE KEY UPDATE setting_value = '". $setting_value ."'";
|
||||
|
||||
return $queryString;
|
||||
}
|
||||
|
||||
private function flatten($arr)
|
||||
{
|
||||
$newArr = array();
|
||||
|
||||
foreach ($arr as $k) {
|
||||
$newArr[$k['setting_name']] = $k['setting_value'];
|
||||
}
|
||||
|
||||
return $newArr;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,114 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is part of the array_column library
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @copyright Copyright (c) Ben Ramsey (http://benramsey.com)
|
||||
* @license http://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
if (!function_exists('array_column')) {
|
||||
/**
|
||||
* Returns the values from a single column of the input array, identified by
|
||||
* the $columnKey.
|
||||
*
|
||||
* Optionally, you may provide an $indexKey to index the values in the returned
|
||||
* array by the values from the $indexKey column in the input array.
|
||||
*
|
||||
* @param array $input A multi-dimensional array (record set) from which to pull
|
||||
* a column of values.
|
||||
* @param mixed $columnKey The column of values to return. This value may be the
|
||||
* integer key of the column you wish to retrieve, or it
|
||||
* may be the string key name for an associative array.
|
||||
* @param mixed $indexKey (Optional.) The column to use as the index/keys for
|
||||
* the returned array. This value may be the integer key
|
||||
* of the column, or it may be the string key name.
|
||||
* @return array
|
||||
*/
|
||||
function array_column($input = null, $columnKey = null, $indexKey = null)
|
||||
{
|
||||
// Using func_get_args() in order to check for proper number of
|
||||
// parameters and trigger errors exactly as the built-in array_column()
|
||||
// does in PHP 5.5.
|
||||
$argc = func_num_args();
|
||||
$params = func_get_args();
|
||||
|
||||
if ($argc < 2) {
|
||||
trigger_error("array_column() expects at least 2 parameters, {$argc} given", E_USER_WARNING);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!is_array($params[0])) {
|
||||
trigger_error(
|
||||
'array_column() expects parameter 1 to be array, ' . gettype($params[0]) . ' given',
|
||||
E_USER_WARNING
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!is_int($params[1])
|
||||
&& !is_float($params[1])
|
||||
&& !is_string($params[1])
|
||||
&& $params[1] !== null
|
||||
&& !(is_object($params[1]) && method_exists($params[1], '__toString'))
|
||||
) {
|
||||
trigger_error('array_column(): The column key should be either a string or an integer', E_USER_WARNING);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isset($params[2])
|
||||
&& !is_int($params[2])
|
||||
&& !is_float($params[2])
|
||||
&& !is_string($params[2])
|
||||
&& !(is_object($params[2]) && method_exists($params[2], '__toString'))
|
||||
) {
|
||||
trigger_error('array_column(): The index key should be either a string or an integer', E_USER_WARNING);
|
||||
return false;
|
||||
}
|
||||
|
||||
$paramsInput = $params[0];
|
||||
$paramsColumnKey = ($params[1] !== null) ? (string) $params[1] : null;
|
||||
|
||||
$paramsIndexKey = null;
|
||||
if (isset($params[2])) {
|
||||
if (is_float($params[2]) || is_int($params[2])) {
|
||||
$paramsIndexKey = (int) $params[2];
|
||||
} else {
|
||||
$paramsIndexKey = (string) $params[2];
|
||||
}
|
||||
}
|
||||
|
||||
$resultArray = array();
|
||||
|
||||
foreach ($paramsInput as $row) {
|
||||
$key = $value = null;
|
||||
$keySet = $valueSet = false;
|
||||
|
||||
if ($paramsIndexKey !== null && array_key_exists($paramsIndexKey, $row)) {
|
||||
$keySet = true;
|
||||
$key = (string) $row[$paramsIndexKey];
|
||||
}
|
||||
|
||||
if ($paramsColumnKey === null) {
|
||||
$valueSet = true;
|
||||
$value = $row;
|
||||
} elseif (is_array($row) && array_key_exists($paramsColumnKey, $row)) {
|
||||
$valueSet = true;
|
||||
$value = $row[$paramsColumnKey];
|
||||
}
|
||||
|
||||
if ($valueSet) {
|
||||
if ($keySet) {
|
||||
$resultArray[$key] = $value;
|
||||
} else {
|
||||
$resultArray[] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $resultArray;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,209 +0,0 @@
|
|||
<?php
|
||||
|
||||
function ticketHeader($info)
|
||||
{
|
||||
$created = new DateTime($info['created_at']);
|
||||
$updated = new DateTime($info['last_updated']);
|
||||
|
||||
return '<div class="divTable">
|
||||
<div class="divTableBody">
|
||||
<div class="divTableRow">
|
||||
<div class="divTableCell infoblock_ticket">'.get_lang('ticket_id').'</div>
|
||||
<div class="divTableCell contentblock_ticket">#'.$info['tid'].' - '.$info['uid'] .'</div>
|
||||
</div>
|
||||
<div class="divTableRow">
|
||||
<div class="divTableCell infoblock_ticket">'.get_lang('service_id').'</div>
|
||||
<div class="divTableCell contentblock_ticket">'.((int)$info['service_id'] === 0 ? '<i>'.get_lang('ticket_no_service').'</i>' :
|
||||
'<a href="?m=user_games&p=edit&home_id='.(int)$info['service_id'].'">#'.(int)$info['service_id'].'</a>'). '</div>
|
||||
</div>
|
||||
<div class="divTableRow">
|
||||
<div class="divTableCell infoblock_ticket">'.get_lang('ticket_subject').'</div>
|
||||
<div class="divTableCell contentblock_ticket">'.$info['subject'].'</div>
|
||||
</div>
|
||||
<div class="divTableRow">
|
||||
<div class="divTableCell infoblock_ticket">'.get_lang('ticket_submitted').'</div>
|
||||
<div class="divTableCell contentblock_ticket">'.$created->format('jS M Y (H:i)').'</div>
|
||||
</div>
|
||||
<div class="divTableRow">
|
||||
<div class="divTableCell infoblock_ticket">'.get_lang('ticket_updated').'</div>
|
||||
<div class="divTableCell contentblock_ticket">'.$updated->format('jS M Y (H:i)').'</div>
|
||||
</div>
|
||||
<div class="divTableRow">
|
||||
<div class="divTableCell infoblock_ticket">'.get_lang('ticket_status').'</div>
|
||||
<div class="divTableCell contentblock_ticket">'.ticketCodeToName($info['status']).'</div>
|
||||
</div>
|
||||
<div class="divTableRow">
|
||||
<div class="divTableCell infoblock_ticket">'.get_lang('submitter_info').'</div>
|
||||
<div class="divTableCell contentblock_ticket">'.get_lang('username').': <a href="?m=user_admin&p=edit_user&user_id='. $info['user_id'] .'">'. $info['users_login'] .'</a> -
|
||||
'. (!empty($info['users_fname']) ? get_lang('name') . ': ' . htmlentities($info['users_fname']) . (!empty($info['users_lname']) ? ' '.htmlentities($info['users_lname']).' - ' : '') : '') .
|
||||
get_lang('ip') . ': '. inet_ntop($info['user_ip']) .' - '.get_lang('role') .': '. ucfirst($info['users_role']).'
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>';
|
||||
}
|
||||
|
||||
function ticketMessage($messageData, $uid, $loggedInAdmin = false, $ratingsEnabled)
|
||||
{
|
||||
$date = new DateTime($messageData['date']);
|
||||
$tid = $messageData['ticket_id'];
|
||||
$rating = $messageData['rating'];
|
||||
|
||||
$class = 'user';
|
||||
|
||||
if (isset($messageData['is_admin'])) {
|
||||
$class = $messageData['is_admin'] == 1 ? 'admin' : 'user';
|
||||
}
|
||||
|
||||
$replyBox = '<div class="ticket_reply '. $class .'">
|
||||
<div class="date">
|
||||
'.$date->format('jS M Y (H:i)').'
|
||||
</div>
|
||||
<div class="'. $class .'">
|
||||
<span class="name">
|
||||
<a href="?m=user_admin&p=edit_user&user_id='.$messageData['user_id'].'">'. htmlentities($messageData['users_login']) .'</a> ' .
|
||||
(!empty($messageData['users_fname']) ? htmlentities($messageData['users_fname']) . (!empty($messageData['users_lname']) ? ' '.htmlentities($messageData['users_lname']) : '') : '') .'
|
||||
</span>
|
||||
<span class="type">
|
||||
'.ucfirst($messageData['users_role']).'
|
||||
</span>
|
||||
</div>
|
||||
<div class="message">'.nl2br(htmlentities($messageData['message'])).'</div>';
|
||||
|
||||
$replyBox .= '<div class="ticket_footer">';
|
||||
|
||||
$replyBox .= '<div class="footer_row">';
|
||||
|
||||
if ($messageData['users_role'] !== 'admin' || $loggedInAdmin) {
|
||||
$replyBox .= '<div class="left">'.get_lang('ip').': '.inet_ntop($messageData['user_ip']).'</div>';
|
||||
}
|
||||
|
||||
if ($messageData['users_role'] == 'admin' && $ratingsEnabled) {
|
||||
$replyBox .= '<div class="right rateResponse" data-tid="'. $tid .'" data-uid="'. $uid .'" data-reply-id="'. $messageData['reply_id'] .'" data-rating="'. $rating .'"></div>';
|
||||
}
|
||||
|
||||
$replyBox .= '<div class="clear"></div>';
|
||||
$replyBox .= '</div>'; // footer_row
|
||||
|
||||
if (isset($messageData['attachments'])) {
|
||||
$replyBox .= '<div class="footer_row attachmentContainer">';
|
||||
|
||||
$replyBox .= '<div class="left attachmentHeader">'. get_lang('attachments') .'</div>';
|
||||
$replyBox .= '<div class="clear"></div>';
|
||||
$replyBox .= '<div class="left attachmentList">';
|
||||
|
||||
$attachmentList = '';
|
||||
foreach ($messageData['attachments'] as $attachment) {
|
||||
$attachmentList .= '<a href="#" class="downloadAttachmentLink" data-id="'. $attachment['attachment_id'] .'" data-tid="'. $tid .'" data-uid="'. $uid .'">'. htmlentities($attachment['original_name']) .'</a>, ';
|
||||
}
|
||||
|
||||
$replyBox .= rtrim($attachmentList, ', ');
|
||||
$replyBox .= '</div>'; //left
|
||||
$replyBox .= '<div class="clear"></div>';
|
||||
|
||||
$replyBox .= '</div>'; //footer row.
|
||||
}
|
||||
|
||||
$replyBox .= '</div>'; // ticket_footer
|
||||
$replyBox .= '</div>'; // ./div :: ticket_reply $class
|
||||
|
||||
return $replyBox;
|
||||
}
|
||||
|
||||
function ticketErrors($errors = array(), $header = '')
|
||||
{
|
||||
$header = empty($header) ? get_lang('ticket_errors_occured') . ':' : $header;
|
||||
$return = '<div class="ticketErrorHolder">
|
||||
<p class="failure" id="errorHeader">'. $header .'</p>
|
||||
<ul class="ticketErrorList">';
|
||||
foreach ($errors as $error) {
|
||||
$return .= '<li class="ticketError">' . $error . '</li>';
|
||||
}
|
||||
$return .= '</ul>
|
||||
</div>';
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
function ticketCodeToName($code, $css = false)
|
||||
{
|
||||
$codes = array(
|
||||
'ticket_closed',
|
||||
'ticket_open',
|
||||
'ticket_admin_response',
|
||||
'ticket_customer_response',
|
||||
);
|
||||
|
||||
return $css ? $codes[$code] : get_lang($codes[$code]);
|
||||
}
|
||||
|
||||
function attachmentForm()
|
||||
{
|
||||
$html = '
|
||||
<div class="attachment_container">
|
||||
<div class="attachment_header">'. get_lang('attachments') .'</div>
|
||||
|
||||
<div class="attachment_add">
|
||||
<button id="add_file_attachment">'. get_lang('add_file_attachment') .'</button>
|
||||
</div>
|
||||
|
||||
<div class="attachment_inputs">
|
||||
<input type="file" name="ticket_file[]">
|
||||
</div>
|
||||
|
||||
<div class="attachment_info">
|
||||
<div id="file_size_info"></div>
|
||||
<div id="extension_info"></div>
|
||||
</div>
|
||||
</div>
|
||||
';
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
function bytesTo($bytes)
|
||||
{
|
||||
if ($bytes == 0) {
|
||||
return '0.00 B';
|
||||
}
|
||||
|
||||
$s = array('B', 'KB', 'MB', 'GB', 'TB', 'PB');
|
||||
$e = floor(log($bytes, 1024));
|
||||
|
||||
return round($bytes / pow(1024, $e), 2) . $s[$e];
|
||||
}
|
||||
|
||||
function toBytes($from)
|
||||
{
|
||||
$number = substr($from, 0, -2);
|
||||
switch (strtoupper(substr($from, -2))) {
|
||||
case "KB":
|
||||
return $number*1024;
|
||||
case "MB":
|
||||
return $number*pow(1024, 2);
|
||||
case "GB":
|
||||
return $number*pow(1024, 3);
|
||||
case "TB":
|
||||
return $number*pow(1024, 4);
|
||||
case "PB":
|
||||
return $number*pow(1024, 5);
|
||||
default:
|
||||
return $from;
|
||||
}
|
||||
}
|
||||
|
||||
function splitExtensions($extensions, $delimiter = ',')
|
||||
{
|
||||
$extArr = explode($delimiter, $extensions);
|
||||
$extList = '';
|
||||
|
||||
foreach ($extArr as $ext) {
|
||||
if (empty($ext)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$extList .= str_replace(array('.', ' '), '', $ext) . $delimiter . ' ';
|
||||
}
|
||||
|
||||
return rtrim($extList, $delimiter . ' ');
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,282 +0,0 @@
|
|||
<?php
|
||||
|
||||
class Ticket
|
||||
{
|
||||
private $db;
|
||||
|
||||
public function __construct(OGPDatabase $db)
|
||||
{
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
public function tickets($ticketsFor = null, $page = 1, $limit = 10)
|
||||
{
|
||||
$limitStart = ((int)($page - 1) * $limit);
|
||||
|
||||
$query = "SELECT a.tid, a.uid, a.user_id, a.parent_id, a.subject, a.created_at, a.last_updated, a.status, a.assigned_to
|
||||
FROM OGP_DB_PREFIXtickets a ";
|
||||
|
||||
if ($ticketsFor !== null) {
|
||||
$query .= "WHERE a.user_id = ".(int)$ticketsFor." OR a.parent_id = ".(int)$ticketsFor." ";
|
||||
|
||||
if ($this->db->isSubUser($ticketsFor)) {
|
||||
$result = $this->db->resultQuery("SELECT users_parent FROM OGP_DB_PREFIXusers WHERE user_id = ".(int)$ticketsFor);
|
||||
$query .= "OR a.parent_id = ".(int)$result[0]['users_parent']." ";
|
||||
}
|
||||
}
|
||||
|
||||
$query .= "ORDER BY a.last_updated DESC ";
|
||||
$query .= "LIMIT $limitStart, ".(int)$limit;
|
||||
|
||||
return $this->db->resultQuery($query);
|
||||
}
|
||||
|
||||
public function count($ticketsFor = null)
|
||||
{
|
||||
$query = "SELECT COUNT(1) as ticketCount FROM OGP_DB_PREFIXtickets a ";
|
||||
|
||||
if ($ticketsFor !== null) {
|
||||
$query .= "WHERE a.user_id = ".(int)$ticketsFor." OR a.parent_id = ".(int)$ticketsFor." ";
|
||||
|
||||
if ($this->db->isSubUser($ticketsFor)) {
|
||||
$result = $this->db->resultQuery("SELECT users_parent FROM OGP_DB_PREFIXusers WHERE user_id = ".(int)$ticketsFor);
|
||||
$query .= "OR a.parent_id = ".(int)$result[0]['users_parent']." ";
|
||||
}
|
||||
}
|
||||
|
||||
$result = $this->db->resultQuery($query);
|
||||
return (!is_array($result) ? 0 : $result[0]['ticketCount']);
|
||||
}
|
||||
|
||||
public function notificationCount($ticketsFor = null, $status = 0)
|
||||
{
|
||||
$query = "SELECT COUNT(1) as ticketCount FROM OGP_DB_PREFIXtickets a WHERE a.status = ".(int)$status." ";
|
||||
|
||||
if ($ticketsFor !== null) {
|
||||
$query .= "AND (a.user_id = ".(int)$ticketsFor." OR a.parent_id = ".(int)$ticketsFor." ";
|
||||
|
||||
if ($this->db->isSubUser($ticketsFor)) {
|
||||
$result = $this->db->resultQuery("SELECT users_parent FROM OGP_DB_PREFIXusers WHERE user_id = ".(int)$ticketsFor);
|
||||
$query .= "OR a.parent_id = ".(int)$result[0]['users_parent'].")";
|
||||
} else {
|
||||
$query .= ")";
|
||||
}
|
||||
}
|
||||
|
||||
$result = $this->db->resultQuery($query);
|
||||
return (!is_array($result) ? 0 : $result[0]['ticketCount']);
|
||||
}
|
||||
|
||||
public function getTicket($tid, $uid)
|
||||
{
|
||||
$query = "SELECT a.tid, a.uid, a.user_id, a.user_ip, a.subject, a.status, a.service_id, a.created_at, a.last_updated,
|
||||
b.users_login, b.users_fname, b.users_lname, b.users_role, b.users_email
|
||||
FROM OGP_DB_PREFIXtickets a
|
||||
JOIN OGP_DB_PREFIXusers b
|
||||
ON (a.user_id = b.user_id)
|
||||
WHERE tid = $tid
|
||||
AND uid = '".$this->db->real_escape_string($uid)."'";
|
||||
|
||||
$result = $this->db->resultQuery($query);
|
||||
|
||||
if (is_array($result)) {
|
||||
$ticketInfo = $result[0];
|
||||
$ticketInfo['messages'] = $this->ticketMessageArray(
|
||||
$this->getMessages($tid),
|
||||
$this->getAttachments($tid)
|
||||
);
|
||||
|
||||
return $ticketInfo;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private function getMessages($tid)
|
||||
{
|
||||
$query = "SELECT a.reply_id, a.ticket_id, a.user_id, a.user_ip, a.message, a.date, a.rating, a.is_admin,
|
||||
b.user_id, b.users_login, b.users_role, b.users_fname, b.users_lname, b.users_email, b.users_parent
|
||||
FROM OGP_DB_PREFIXticket_messages a
|
||||
JOIN OGP_DB_PREFIXusers b
|
||||
ON (a.user_id = b.user_id)
|
||||
WHERE a.ticket_id = $tid
|
||||
ORDER BY a.reply_id DESC";
|
||||
|
||||
return $this->db->resultQuery($query) ?: array();
|
||||
}
|
||||
|
||||
private function getAttachments($tid)
|
||||
{
|
||||
$query = "SELECT attachment_id, reply_id, original_name, unique_name
|
||||
FROM OGP_DB_PREFIXticket_attachments
|
||||
WHERE ticket_id = $tid
|
||||
ORDER BY reply_id DESC";
|
||||
|
||||
return $this->db->resultQuery($query) ?: array();
|
||||
}
|
||||
|
||||
private function ticketMessageArray($messages, $attachments)
|
||||
{
|
||||
$keys = array_keys($messages);
|
||||
$end = end($keys);
|
||||
|
||||
$count = count(array_filter($attachments, function($f) {
|
||||
return is_null($f['reply_id']);
|
||||
}));
|
||||
|
||||
foreach ($messages as $i => $message) {
|
||||
foreach ($attachments as $k => $v) {
|
||||
|
||||
if ($messages[$i]['reply_id'] == $v['reply_id']) {
|
||||
$messages[$i]['attachments'][] = $v;
|
||||
}
|
||||
|
||||
if (is_null($v['reply_id']) && (!isset($messages[$end]['attachments']) || count($messages[$end]['attachments']) < $count)) {
|
||||
$messages[$end]['attachments'][] = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $messages;
|
||||
}
|
||||
|
||||
public function open($user_id, $user_ip, $subject, $message, $service_id, $is_admin)
|
||||
{
|
||||
$parent_id = $user_id;
|
||||
if ($this->db->isSubUser($user_id)) {
|
||||
$result = $this->db->resultQuery("SELECT users_parent FROM OGP_DB_PREFIXusers WHERE user_id = ".(int)$user_id);
|
||||
$parent_id = (int)$result[0]['users_parent'];
|
||||
}
|
||||
|
||||
$uid = bin2hex(openssl_random_pseudo_bytes(4));
|
||||
|
||||
// $this->db->resultInsertId calls real_escape_string on all the values.
|
||||
$fields = array(
|
||||
'uid' => $uid,
|
||||
'user_id' => $user_id,
|
||||
'parent_id' => $parent_id,
|
||||
'user_ip' => inet_pton($user_ip),
|
||||
'subject' => $subject,
|
||||
'service_id' => ($service_id === 0 ? null : (int)$service_id),
|
||||
'status' => 1
|
||||
);
|
||||
|
||||
$insertId = $this->db->resultInsertId('tickets', $fields);
|
||||
if ($insertId !== false) {
|
||||
$this->message($insertId, $user_id, $user_ip, $message, $is_admin, $uid);
|
||||
$this->updateTimestamp($insertId, $uid);
|
||||
|
||||
return array('uid' => $uid, 'tid' => $insertId);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function message($tid, $user_id, $user_ip, $message, $is_admin, $uid)
|
||||
{
|
||||
$fields = array(
|
||||
'ticket_id' => $tid,
|
||||
'user_id' => $user_id,
|
||||
'user_ip' => inet_pton($user_ip),
|
||||
'message' => $message,
|
||||
'is_admin' => ($is_admin ? '1' : '0')
|
||||
);
|
||||
|
||||
$insertId = $this->db->resultInsertId('ticket_messages', $fields);
|
||||
|
||||
if ($insertId !== false) {
|
||||
$this->updateStatus($tid, $uid, ($is_admin ? 2 : 3));
|
||||
$this->updateTimestamp($tid, $uid);
|
||||
}
|
||||
|
||||
return $insertId;
|
||||
}
|
||||
|
||||
// 0 = closed
|
||||
// 1 = open
|
||||
// 2 = admin response
|
||||
// 3 = customer response
|
||||
public function updateStatus($tid, $uid, $status)
|
||||
{
|
||||
$status = (int)$status;
|
||||
return $this->db->query("UPDATE OGP_DB_PREFIXtickets SET status = $status WHERE tid = $tid AND uid = '$uid'");
|
||||
}
|
||||
|
||||
public function updateTimestamp($tid, $uid)
|
||||
{
|
||||
return $this->db->query("UPDATE OGP_DB_PREFIXtickets SET last_updated = NOW() WHERE tid = $tid AND uid = '$uid'");
|
||||
}
|
||||
|
||||
public function exists($tid, $uid)
|
||||
{
|
||||
$query = "SELECT COUNT(1) AS ticketCount FROM OGP_DB_PREFIXtickets
|
||||
WHERE `tid` = $tid AND
|
||||
`uid` = '".$this->db->real_escape_string($uid)."'";
|
||||
|
||||
$result = $this->db->resultQuery($query);
|
||||
return ($result[0]['ticketCount'] == 0 ? false : true);
|
||||
}
|
||||
|
||||
public function authorized($user_id, $tid, $uid)
|
||||
{
|
||||
$query = "SELECT a.user_id as utid, a.parent_id, b.user_id, b.users_parent
|
||||
FROM OGP_DB_PREFIXtickets a
|
||||
JOIN OGP_DB_PREFIXusers b
|
||||
ON (
|
||||
a.user_id = b.user_id
|
||||
OR a.user_id = b.users_parent
|
||||
OR a.parent_id = b.user_id
|
||||
OR a.parent_id = b.users_parent
|
||||
)
|
||||
WHERE a.tid = ".(int)$tid." AND a.uid = '".$this->db->real_escape_string($uid)."'
|
||||
AND (
|
||||
b.user_id = ".(int)$user_id ."
|
||||
OR b.users_parent = ".(int)$user_id."
|
||||
)";
|
||||
|
||||
$result = $this->db->resultQuery($query);
|
||||
return $result[0] ?: false;
|
||||
}
|
||||
|
||||
public function getServices($user_id, $is_admin)
|
||||
{
|
||||
if ($is_admin) {
|
||||
$homes = $this->db->getHomesFor('admin', $user_id);
|
||||
} else {
|
||||
$homes = $this->db->getHomesFor('user_and_group', $user_id);
|
||||
}
|
||||
|
||||
$return = array(
|
||||
array('home_id' => 0, 'home_name' => '')
|
||||
);
|
||||
|
||||
if (!$homes) {
|
||||
return $return;
|
||||
}
|
||||
|
||||
foreach ($homes as $home) {
|
||||
$return[] = array('home_id' => $home['home_id'], 'home_name' => $home['home_name']);
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
public function setRating($tid, $reply_id, $rating)
|
||||
{
|
||||
$query = "UPDATE OGP_DB_PREFIXticket_messages
|
||||
SET rating = ".(int)$rating."
|
||||
WHERE ticket_id = ".(int)$tid." AND reply_id = ".(int)$reply_id;
|
||||
|
||||
return $this->db->query($query);
|
||||
}
|
||||
|
||||
// Move this to the attachment class...?
|
||||
public function getAttachmentById($attachment_id, $tid)
|
||||
{
|
||||
$query = "SELECT original_name, unique_name FROM OGP_DB_PREFIXticket_attachments
|
||||
WHERE attachment_id = ".(int)$attachment_id." AND ticket_id = ".(int)$tid;
|
||||
|
||||
$result = $this->db->resultQuery($query);
|
||||
return $result[0] ?: false;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
window.getParameterByName = function(name) {
|
||||
url = window.location.href;
|
||||
name = name.replace(/[\[\]]/g, "\\$&");
|
||||
|
||||
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
|
||||
results = regex.exec(url);
|
||||
|
||||
if (!results) return null;
|
||||
if (!results[2]) return '';
|
||||
|
||||
return decodeURIComponent(results[2].replace(/\+/g, ' '));
|
||||
}
|
||||
|
||||
window.getCookie = function(name) {
|
||||
match = document.cookie.match(new RegExp(name + '=([^;]+)'));
|
||||
if (match) return match[1];
|
||||
}
|
||||
|
||||
window.deleteCookie = function(name) {
|
||||
document.cookie = name +'=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;';
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
<?php
|
||||
// variables which are required in both viewticket and submitticket.
|
||||
if (!function_exists('get_lang')) exit;
|
||||
?>
|
||||
<script>
|
||||
var fileInputs, limit = <?php echo $attachmentSettings['attachment_limit']; ?>;
|
||||
var allowedExtensions = <?php echo json_encode(explode(', ', $attachmentSettings['attachment_extensions'])); ?>;
|
||||
var maxFileSize = <?php echo $attachmentSettings['attachment_max_size']; ?>;
|
||||
var maxFileSizeUnits = "<?php echo bytesTo($attachmentSettings['attachment_max_size']); ?>";
|
||||
var fixBeforeSubmitting = "<?php echo get_lang('ticket_fix_before_submitting'); ?>"
|
||||
var fixBeforeReplying = "<?php echo get_lang('ticket_fix_before_replying'); ?>"
|
||||
var problemWithAttachments = "<?php echo get_lang('ticket_problem_with_attachments'); ?>"
|
||||
var invalidExtensionLang = "<?php echo get_lang('ticket_attachment_invalid_extension'); ?>"
|
||||
var invalidSizeLang = "<?php echo get_lang('ticket_attachment_invalid_size'); ?>"
|
||||
var maxFileElements = "<?php echo get_lang('ticket_max_file_elements'); ?>"
|
||||
var multipleFilesSelects = "<?php echo get_lang('ticket_attachment_multiple_files'); ?>"
|
||||
var extensionsLang = "<?php echo get_lang('attachment_allowed_extensions_info'); ?>"
|
||||
|
||||
<?php
|
||||
if ($attachmentSettings['attachment_limit'] == 0) {
|
||||
echo 'var fileSizeInfo = "'. get_lang_f('attachment_size_info', bytesTo($attachmentSettings['attachment_max_size'])) .'"';
|
||||
} else {
|
||||
echo 'var fileSizeInfo = "'. get_lang_f('attachment_file_size_info', $attachmentSettings['attachment_limit'], bytesTo($attachmentSettings['attachment_max_size'])) .'"';
|
||||
}
|
||||
?>
|
||||
</script>
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
$(function() {
|
||||
$(".rateResponse").each(function(){
|
||||
var tid = this.getAttribute('data-tid');
|
||||
var uid = this.getAttribute('data-uid');
|
||||
var reply_id = this.getAttribute('data-reply-id');
|
||||
var rating = this.getAttribute('data-rating');
|
||||
|
||||
var inputs = "";
|
||||
|
||||
for (x = 5; x > 0; --x) {
|
||||
inputs += "<input class='star star-" + x + "' value='" + x + "' data-tid='" + tid + "' data-uid='" + uid + "' id='reply_" + reply_id + " star-" + x + "' type='radio' name='star'" + (x == rating ? " checked" : "") + ">",
|
||||
inputs += "<label class='star star-" + x + "' for='reply_" + reply_id + " star-" + x + "'></label>"
|
||||
}
|
||||
|
||||
this.$html = $([
|
||||
"<div class='stars'>",
|
||||
" <form action=''>",
|
||||
inputs,
|
||||
" </form>",
|
||||
"</div>"
|
||||
].join("\n"));
|
||||
|
||||
$(this).html(this.$html.html());
|
||||
});
|
||||
|
||||
$(".ticket_reply_notice").click(function() {
|
||||
var state = ($("#toggleNoticeIcon").text() == "+" ? "-" : "+");
|
||||
$(".ticket_ReplyBox").slideToggle(function() {
|
||||
$("#toggleNoticeIcon").text(state);
|
||||
});
|
||||
});
|
||||
|
||||
$("input[name=star]").click(function() {
|
||||
var data = {
|
||||
reply_id: this.getAttribute('id').split(/[ ,]+/)[0].replace(/\D/g, ''),
|
||||
tid: this.getAttribute('data-tid'),
|
||||
uid: this.getAttribute('data-uid'),
|
||||
rating: this.getAttribute('value')
|
||||
};
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "home.php?m=tickets&p=rate&type=cleared&data_type=json",
|
||||
data: data,
|
||||
success: function(data) {
|
||||
console.log(data.message);
|
||||
},
|
||||
|
||||
dataType: "json",
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -1,118 +0,0 @@
|
|||
$(function() {
|
||||
var cookie = getCookie('fileErrors');
|
||||
var uid = getParameterByName('uid');
|
||||
var page = getParameterByName('p');
|
||||
|
||||
$("#file_size_info").text(fileSizeInfo);
|
||||
$("#extension_info").text(extensionsLang.replace('%s', allowedExtensions.join(', ')));
|
||||
|
||||
if (typeof cookie !== "undefined" && (uid !== null && uid.length !== 0)) {
|
||||
var decodedCookie = decodeURIComponent(cookie.replace(/\+/g, ' '));
|
||||
var json = JSON.parse(decodedCookie);
|
||||
|
||||
if (json.uid == uid && json.fileErrors[0].length > 0) {
|
||||
$("#jsErrorBox").css("display", "block");
|
||||
$("#errorHeader").text(problemWithAttachments + ':');
|
||||
|
||||
for (var key in json.fileErrors[0]) {
|
||||
$(".ticketErrorList").append('<li class="ticketError">' + json.fileErrors[0][key] + '</li>');
|
||||
}
|
||||
|
||||
deleteCookie('fileErrors');
|
||||
}
|
||||
}
|
||||
|
||||
$("#add_file_attachment").click(function(e) {
|
||||
fileInputs = $(".attachment_inputs :file").length;
|
||||
|
||||
if (limit > 0 && fileInputs >= limit) {
|
||||
$(this).prop('disabled', true);
|
||||
} else {
|
||||
$(".attachment_inputs").append(
|
||||
$("<input/>").attr('type', 'file').attr('name', 'ticket_file[]')
|
||||
);
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
$("#submit").click(function(e) {
|
||||
var errorHeader = (page == 'viewticket' ? fixBeforeReplying : fixBeforeSubmitting);
|
||||
var errorCount = 0;
|
||||
var multiple = false;
|
||||
|
||||
$("#jsErrorBox").css("display", "none");
|
||||
$(".ticketErrorList").empty();
|
||||
$("#errorHeader").text(errorHeader + ':');
|
||||
|
||||
fileInputs = $(".attachment_inputs :file").length;
|
||||
|
||||
if (limit > 0 && fileInputs > limit) {
|
||||
$('.ticketErrorList').append('<li class="ticketError">' + maxFileElements.replace("%1", limit) + '</li>')
|
||||
++errorCount;
|
||||
} else {
|
||||
for (var i = 0; i <= fileInputs-1; ++i) {
|
||||
var fileList = $(".attachment_inputs :file").get(i).files;
|
||||
var fileIndex = fileList[0];
|
||||
|
||||
// Prevent "multiple" from being added to the input element - check we only have one file.
|
||||
if (fileList.length > 1 && !multiple) {
|
||||
$(".ticketErrorList").append('<li class="ticketError">' + multipleFilesSelects + '</li>');
|
||||
multiple = true;
|
||||
++errorCount;
|
||||
}
|
||||
|
||||
if (typeof fileIndex == "undefined") {
|
||||
continue;
|
||||
} else {
|
||||
// Seems hacky due to the requirement of including translations.
|
||||
// Make sure the file extension is allowed and the file size is appropriate.
|
||||
if ($.inArray(fileIndex.name.split('.').pop(), allowedExtensions) == -1) {
|
||||
$(".ticketErrorList").append('<li class="ticketError">' + invalidExtensionLang.replace("%1", fileIndex.name) + '</li>');
|
||||
++errorCount;
|
||||
}
|
||||
|
||||
if (fileIndex.size > maxFileSize) {
|
||||
$(".ticketErrorList").append('<li class="ticketError">' + invalidSizeLang.replace("%1", fileIndex.name).replace("%2", maxFileSizeUnits) + '</li>');
|
||||
++errorCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (errorCount > 0) {
|
||||
$("#jsErrorBox").css("display", "block");
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
$(".downloadAttachmentLink").click(function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
var fileName = $(this).text();
|
||||
var attachmentId = this.getAttribute('data-id');
|
||||
var ticketId = this.getAttribute('data-tid');
|
||||
var uniqueId = this.getAttribute('data-uid');
|
||||
|
||||
var url = "?m=tickets&p=download&id=" + attachmentId + "&tid=" + ticketId + "&uid=" + uniqueId + "&type=cleared";
|
||||
|
||||
var xhttp = new XMLHttpRequest();
|
||||
xhttp.onreadystatechange = function() {
|
||||
if (this.readyState == 4 && this.status == 200) {
|
||||
var downloadUrl = URL.createObjectURL(xhttp.response);
|
||||
var a = document.createElement("a");
|
||||
document.body.appendChild(a);
|
||||
a.style = "display: none";
|
||||
a.href = downloadUrl;
|
||||
a.download = fileName;
|
||||
a.click();
|
||||
}
|
||||
};
|
||||
|
||||
xhttp.open("GET", url, true);
|
||||
xhttp.responseType = "blob";
|
||||
xhttp.send();
|
||||
});
|
||||
|
||||
});
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
$(function() {
|
||||
$("#phpIniButton").click(function(e){
|
||||
var units = ['k', 'm', 'g', 't', 'p'];
|
||||
|
||||
var maxSize = $("#attachment_max_size").val();
|
||||
var limit = parseInt($("#attachment_limit").val());
|
||||
|
||||
var unit = maxSize.slice(-2, -1);
|
||||
var sizeNoUnit = maxSize.slice(0, -2);
|
||||
|
||||
var post_max_size = "";
|
||||
if ($.inArray(unit.toLowerCase(), units) != -1) {
|
||||
post_max_size = (sizeNoUnit * (limit+1)) + unit;
|
||||
}
|
||||
|
||||
var str = "<pre>";
|
||||
str += "file_uploads = On\n";
|
||||
str += "upload_max_filesize = " + sizeNoUnit + unit + "\n";
|
||||
str += "max_file_uploads = " + limit + "\n";
|
||||
|
||||
if (post_max_size.length !== 0) {
|
||||
str += "post_max_size = " + post_max_size + "\n";
|
||||
}
|
||||
|
||||
str += "</pre>";
|
||||
|
||||
$("#guesstimateIniSettings").css("display", "block");
|
||||
$("#guesstimateIniSettings").html(str);
|
||||
|
||||
});
|
||||
});
|
||||
|
|
@ -1,109 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
*
|
||||
* OGP - Open Game Panel
|
||||
* Copyright (C) 2008 - 2017 The OGP Development Team
|
||||
*
|
||||
* http://www.opengamepanel.org/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
$module_title = "Tickets";
|
||||
$module_version = "1.0a";
|
||||
$db_version = 3;
|
||||
$module_required = false;
|
||||
$module_menus = array(
|
||||
array(
|
||||
'name' => 'Support Tickets',
|
||||
'group' => 'user',
|
||||
),
|
||||
|
||||
array(
|
||||
'name' => 'Support Ticket Settings',
|
||||
'group' => 'admin',
|
||||
'subpage' => 'ticket_settings',
|
||||
),
|
||||
);
|
||||
|
||||
$install_queries[0] = array(
|
||||
"DROP TABLE IF EXISTS `".OGP_DB_PREFIX."ticket_replies`",
|
||||
|
||||
"DROP TABLE IF EXISTS `".OGP_DB_PREFIX."ticket_messages`",
|
||||
"DROP TABLE IF EXISTS `".OGP_DB_PREFIX."ticket_attachments`",
|
||||
"DROP TABLE IF EXISTS `".OGP_DB_PREFIX."ticket_settings`",
|
||||
"DROP TABLE IF EXISTS `".OGP_DB_PREFIX."tickets`",
|
||||
|
||||
"CREATE TABLE IF NOT EXISTS `".OGP_DB_PREFIX."tickets` (
|
||||
`tid` int NOT NULL AUTO_INCREMENT,
|
||||
`uid` varchar(32) NOT NULL UNIQUE,
|
||||
`user_id` int NOT NULL,
|
||||
`parent_id` int NOT NULL,
|
||||
`user_ip` varbinary(16) NOT NULL,
|
||||
`subject` varchar(64) NOT NULL,
|
||||
`service_id` int,
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
`last_updated` varchar(22),
|
||||
`status` tinyint NOT NULL,
|
||||
`assigned_to` tinyint,
|
||||
PRIMARY KEY (`tid`)
|
||||
);",
|
||||
|
||||
"CREATE TABLE IF NOT EXISTS `".OGP_DB_PREFIX."ticket_messages` (
|
||||
`reply_id` int NOT NULL AUTO_INCREMENT,
|
||||
`ticket_id` int NOT NULL,
|
||||
`user_id` int NOT NULL,
|
||||
`user_ip` varbinary(16) NOT NULL,
|
||||
`message` TEXT NOT NULL,
|
||||
`date` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
`rating` tinyint DEFAULT '0',
|
||||
`is_admin` int DEFAULT '0',
|
||||
PRIMARY KEY (`reply_id`)
|
||||
);",
|
||||
|
||||
"ALTER TABLE `".OGP_DB_PREFIX."ticket_messages` ADD CONSTRAINT `".OGP_DB_PREFIX."ticket_messages_fk0` FOREIGN KEY (`ticket_id`) REFERENCES `".OGP_DB_PREFIX."tickets`(`tid`);",
|
||||
);
|
||||
|
||||
$install_queries[1] = array(
|
||||
"CREATE TABLE IF NOT EXISTS `".OGP_DB_PREFIX."ticket_attachments` (
|
||||
`attachment_id` int NOT NULL AUTO_INCREMENT,
|
||||
`ticket_id` int NOT NULL,
|
||||
`reply_id` int,
|
||||
`original_name` varchar(255) NOT NULL,
|
||||
`unique_name` varchar(32) NOT NULL UNIQUE,
|
||||
PRIMARY KEY (`attachment_id`)
|
||||
);",
|
||||
);
|
||||
|
||||
$install_queries[2] = array(
|
||||
"CREATE TABLE IF NOT EXISTS `".OGP_DB_PREFIX."ticket_settings` (
|
||||
`id` INT NOT NULL AUTO_INCREMENT,
|
||||
`setting_name` varchar(32) NOT NULL UNIQUE,
|
||||
`setting_value` TEXT NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
);",
|
||||
|
||||
"INSERT INTO `".OGP_DB_PREFIX."ticket_settings` (setting_name, setting_value) VALUES ('ratings_enabled', true) ON DUPLICATE KEY UPDATE `setting_name` = 'ratings_enabled', `setting_value` = true",
|
||||
"INSERT INTO `".OGP_DB_PREFIX."ticket_settings` (setting_name, setting_value) VALUES ('attachments_enabled', true) ON DUPLICATE KEY UPDATE `setting_name` = 'attachments_enabled', `setting_value` = true",
|
||||
"INSERT INTO `".OGP_DB_PREFIX."ticket_settings` (setting_name, setting_value) VALUES ('attachment_max_size', '52428800') ON DUPLICATE KEY UPDATE `setting_name` = 'attachment_max_size', `setting_value` = '52428800'",
|
||||
"INSERT INTO `".OGP_DB_PREFIX."ticket_settings` (setting_name, setting_value) VALUES ('attachment_limit', '5') ON DUPLICATE KEY UPDATE `setting_name` = 'attachment_limit', `setting_value` = '5'",
|
||||
"INSERT INTO `".OGP_DB_PREFIX."ticket_settings` (setting_name, setting_value) VALUES ('attachment_save_dir', '".__DIR__ . '/uploads' ."') ON DUPLICATE KEY UPDATE `setting_name` = 'attachment_save_dir', `setting_value` = '".__DIR__ . '/uploads' ."'",
|
||||
"INSERT INTO `".OGP_DB_PREFIX."ticket_settings` (setting_name, setting_value) VALUES ('attachment_extensions', 'jpg, gif, jpeg, jpg, png, pdf, txt, sql, zip') ON DUPLICATE KEY UPDATE `setting_name` = 'attachment_extensions', `setting_value` = 'jpg, gif, jpeg, jpg, png, pdf, txt, sql, zip'",
|
||||
);
|
||||
|
||||
$install_queries[3] = array(
|
||||
"INSERT INTO `".OGP_DB_PREFIX."ticket_settings` (setting_name, setting_value) VALUES ('notifications_enabled', true) ON DUPLICATE KEY UPDATE `setting_name` = 'notifications_enabled', `setting_value` = true",
|
||||
);
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
<navigation>
|
||||
<page key="default" file="supportTickets.php" access="admin,user,subuser" />
|
||||
<page key="ticket_settings" file="ticketSettings.php" access="admin" />
|
||||
<page key="submitticket" file="submitTicket.php" access="admin,user,subuser" />
|
||||
<page key="viewticket" file="viewTicket.php" access="admin,user,subuser" />
|
||||
<page key="rate" file="rating.php" access="admin,user,subuser" />
|
||||
<page key="download" file="downloadAttachment.php" access="admin,user,subuser" />
|
||||
<page key="notifications" file="notificationCount.php" access="admin,user,subuser" />
|
||||
</navigation>
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
<?php
|
||||
|
||||
require 'include/ticket.php';
|
||||
require 'include/TicketSettings.php';
|
||||
|
||||
function exec_ogp_module()
|
||||
{
|
||||
global $db;
|
||||
|
||||
$ticket = new Ticket($db);
|
||||
$TicketSettings = new TicketSettings($db);
|
||||
$notificationsEnabled = $TicketSettings->get('notifications_enabled');
|
||||
|
||||
if ($notificationsEnabled['notifications_enabled']) {
|
||||
$isAdmin = $db->isAdmin($_SESSION['user_id']);
|
||||
$status = $isAdmin ? 3 : 2;
|
||||
$ticketOwner = (!$isAdmin ? $_SESSION['user_id'] : null);
|
||||
|
||||
echo json_encode(
|
||||
array('notificationCount' => $ticket->notificationCount($ticketOwner, $status)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
<?php
|
||||
|
||||
require 'include/ticket.php';
|
||||
require 'include/TicketSettings.php';
|
||||
|
||||
function exec_ogp_module()
|
||||
{
|
||||
global $db, $view;
|
||||
|
||||
$ticket = new Ticket($db);
|
||||
$TicketSettings = (new TicketSettings($db))->get('ratings_enabled');
|
||||
|
||||
$isAdmin = $db->isAdmin($_SESSION['user_id']);
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$tid = (int)$_POST['tid'];
|
||||
$uid = $_POST['uid'];
|
||||
$reply_id = (int)$_POST['reply_id'];
|
||||
$validRatings = range(1, 5);
|
||||
|
||||
if (is_numeric($_POST['rating']) && in_array($_POST['rating'], $validRatings)) {
|
||||
$rating = (int)$_POST['rating'];
|
||||
} else {
|
||||
$rating = 0;
|
||||
}
|
||||
|
||||
if (!$TicketSettings['ratings_enabled']) {
|
||||
echo json_encode(array('message' => get_lang('ratings_disabled')));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$ticket->exists($tid, $uid)) {
|
||||
echo json_encode(array('message' => get_lang('ticket_not_found')));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$ticket->authorized($_SESSION['user_id'], $tid, $uid)) {
|
||||
echo json_encode(array('message' => get_lang('ticket_cant_read')));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if ($rating == 0) {
|
||||
echo json_encode(array('message' => get_lang('invalid_rating')));
|
||||
return;
|
||||
}
|
||||
|
||||
if ($ticket->setRating($tid, $reply_id, $rating)) {
|
||||
echo json_encode(array('message' => get_lang('successfully_rated_response')));
|
||||
} else {
|
||||
echo json_encode(array('message' => get_lang('failed_rating_response')));
|
||||
}
|
||||
}
|
||||
|
||||
$view->refresh("?m=tickets", 0);
|
||||
}
|
||||
|
|
@ -1,169 +0,0 @@
|
|||
<?php
|
||||
|
||||
require 'include/array_column.php';
|
||||
require 'include/ticket.php';
|
||||
require 'include/Attachments.php';
|
||||
require 'include/TicketSettings.php';
|
||||
|
||||
require 'include/functions.php';
|
||||
|
||||
function exec_ogp_module()
|
||||
{
|
||||
global $db, $view;
|
||||
|
||||
$ticket = new Ticket($db);
|
||||
$TicketSettings = new TicketSettings($db);
|
||||
|
||||
$isAdmin = $db->isAdmin($_SESSION['user_id']);
|
||||
$services = $ticket->getServices($_SESSION['user_id'], $isAdmin);
|
||||
|
||||
$attachmentSettings = $TicketSettings->get(array('attachments_enabled', 'attachment_save_dir', 'attachment_limit', 'attachment_max_size', 'attachment_extensions'));
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$attachments = new Attachments(
|
||||
$db,
|
||||
$_FILES['ticket_file'],
|
||||
$attachmentSettings['attachment_save_dir'],
|
||||
$attachmentSettings['attachment_limit'],
|
||||
$attachmentSettings['attachment_max_size'],
|
||||
explode(', ', $attachmentSettings['attachment_extensions'])
|
||||
);
|
||||
|
||||
$_POST = array_map('trim', $_POST);
|
||||
|
||||
$_SESSION['ticket']['ticket_subject'] = strip_real_escape_string($_POST['ticket_subject']);
|
||||
$_SESSION['ticket']['ticket_service'] = $_POST['ticket_service'];
|
||||
$_SESSION['ticket']['ticket_message'] = strip_real_escape_string($_POST['ticket_message']);
|
||||
|
||||
$errors = array();
|
||||
$fileErrors = array();
|
||||
|
||||
if (empty($_POST['ticket_subject'])) {
|
||||
$errors[] = get_lang('no_ticket_subject');
|
||||
} elseif (strlen($_POST['ticket_subject']) > 64 || strlen($_POST['ticket_subject']) < 4) {
|
||||
$errors[] = get_lang('invalid_ticket_subject_length');
|
||||
}
|
||||
|
||||
if (array_search($_POST['ticket_service'], array_column($services, 'home_id')) === false) {
|
||||
$errors[] = get_lang('invalid_home_selected');
|
||||
}
|
||||
|
||||
if (empty($_POST['ticket_message'])) {
|
||||
$errors[] = get_lang('no_ticket_message');
|
||||
} elseif (strlen($_POST['ticket_message']) < 4) {
|
||||
$errors[] = get_lang('invalid_ticket_message_length');
|
||||
}
|
||||
|
||||
if ($attachments->checkPath() === false && $attachmentSettings['attachments_enabled']) {
|
||||
$fileErrors[] = get_lang('attachment_directory_not_writable');
|
||||
}
|
||||
|
||||
if ($attachments->validAttachmentCount() === false && $attachmentSettings['attachments_enabled']) {
|
||||
$fileErrors[] = get_lang_f('attachment_invalid_file_count', $attachmentSettings['attachment_limit']);
|
||||
}
|
||||
|
||||
if (empty($errors)) {
|
||||
$open = $ticket->open($_SESSION['user_id'], getClientIPAddress(), strip_real_escape_string($_POST['ticket_subject']), strip_real_escape_string($_POST['ticket_message']), $_POST['ticket_service'], $isAdmin);
|
||||
|
||||
if (!$open) {
|
||||
echo ticketErrors(array(get_lang('failed_to_open')));
|
||||
$view->refresh("?m=tickets&p=submitticket", 60);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isset($_SESSION['ticket'])) {
|
||||
unset($_SESSION['ticket']);
|
||||
}
|
||||
|
||||
if ($attachmentSettings['attachments_enabled']) {
|
||||
// Validate the uploaded files if specified path exists and is writable. and if the amount of files is valid.
|
||||
// if any files fail to validate, then only save/move the ones which validated successfully and show an error for the ones which didn't.
|
||||
if (empty($fileErrors)) {
|
||||
$validator = $attachments->validate();
|
||||
$fileErrors[] = $validator->getErrors();
|
||||
$attachments->save($open['tid']);
|
||||
}
|
||||
|
||||
setcookie('fileErrors', json_encode(array('uid' => $open['uid'], 'fileErrors' => $fileErrors)), time() + 86400, '/');
|
||||
}
|
||||
|
||||
//TICKET SUBMITTED, POST ON DISCORD and log
|
||||
//logger
|
||||
//$db->logger( "SUPPORT TICKET SUBMITTED ");
|
||||
$db->logger( "TICKET SUBMITTED by " . $_SESSION['user_id']);
|
||||
|
||||
|
||||
|
||||
//WEBHOOK Discord=======================================================================================
|
||||
|
||||
$webhook = "https://discord.com/api/webhooks/1087807080657854484/yYtW8q63xKj3rTFYrNfW2LJk_GeC_WtuI8eJOyELxWbqTQ-uMzOO2I9qofoJCoHXFhC1";
|
||||
//$webhook = "https://discord.com/api/webhooks/710275918274363412/g5Tr-EUdEnLfFryOlscxJ6FuPiSJuE6EMKRYmh9UGMiqTUxU5-y9CQrBlDJW7znr0Tol";
|
||||
|
||||
$msg = "Server support ticket created:\n"."ServerID: " .$_POST['ticket_service'] ."\n". "Subject: " .$_POST['ticket_subject'];
|
||||
$json_data = array ('content'=>"$msg");
|
||||
$make_json = json_encode($json_data);
|
||||
$ch = curl_init( $webhook );
|
||||
curl_setopt( $ch, CURLOPT_HTTPHEADER, array('Content-type: application/json'));
|
||||
curl_setopt( $ch, CURLOPT_POST, 1);
|
||||
curl_setopt( $ch, CURLOPT_POSTFIELDS, $make_json);
|
||||
curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, 1);
|
||||
curl_setopt( $ch, CURLOPT_HEADER, 0);
|
||||
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
$response = curl_exec( $ch );
|
||||
//If you need to debug, or find out why you can't send message uncomment line below, and execute script.
|
||||
//echo $response;
|
||||
//end WEBHOOK Discord
|
||||
|
||||
|
||||
|
||||
|
||||
$view->refresh("?m=tickets&p=viewticket&tid=".$open['tid']."&uid=".$open['uid'], 0);
|
||||
return;
|
||||
} else {
|
||||
echo ticketErrors($errors);
|
||||
$view->refresh("?m=tickets&p=submitticket", 60);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
echo '<h2>'.get_lang('submit_ticket').'</h2>';
|
||||
|
||||
echo '<div id="jsErrorBox">'. ticketErrors() .'</div>';
|
||||
|
||||
echo '
|
||||
<form method="POST" enctype="multipart/form-data">
|
||||
<div class="ticket_elementDiv">
|
||||
<label>'.get_lang('ticket_subject').'</label>
|
||||
<input type="text" id="ticket_subject" name="ticket_subject" '. (isset($_SESSION['ticket']['ticket_subject']) ? 'value="'.$_SESSION['ticket']['ticket_subject'].'"' : '') .' pattern=".{4,64}" required title="4 to 64 characters" autofocus>
|
||||
</div>
|
||||
<div class="ticket_elementDiv">
|
||||
<label>'.get_lang('ticket_service').'</label>
|
||||
<select name="ticket_service">';
|
||||
|
||||
foreach ($services as $service) {
|
||||
echo '<option value="'.$service['home_id'].'" '.(isset($_SESSION['ticket']['ticket_service']) && $_SESSION['ticket']['ticket_service'] == $service['home_id'] ? 'selected' : '') .'>'.htmlentities($service['home_name']).'</option>';
|
||||
}
|
||||
|
||||
echo '</select>
|
||||
</div>
|
||||
<div class="ticket_elementDiv">
|
||||
<label>'.get_lang('ticket_message').'</label>
|
||||
<textarea rows="12" id="ticket_message" name="ticket_message">'. (isset($_SESSION['ticket']['ticket_message']) ? $_SESSION['ticket']['ticket_message'] : '') .'</textarea>
|
||||
</div>';
|
||||
|
||||
if ($attachmentSettings['attachments_enabled']) {
|
||||
echo attachmentForm();
|
||||
}
|
||||
|
||||
echo '<div class="ticket_buttonDiv">
|
||||
<input type="submit" id="submit" value="'.get_lang('submit_ticket').'" />
|
||||
</div>
|
||||
</form>';
|
||||
|
||||
require 'js/javascript_vars.php';
|
||||
?>
|
||||
|
||||
<script src="modules/tickets/js/helpers.js"></script>
|
||||
<script src="modules/tickets/js/ticket.js"></script>
|
||||
<?php
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
.ticket_elementDiv label, input { float: left }
|
||||
.ticket_elementDiv label, input[type="submit"] { clear: left }
|
||||
.ticket_elementDiv label { font-weight: bold; font-size: 14px; }
|
||||
.ticket_elementDiv input, select, textarea { padding: 10px 10px; width: 90%; margin-bottom: 24px; }
|
||||
.ticket_elementDiv label { width: 70px; }
|
||||
|
||||
.ticket_buttonDiv { float: right; clear: both; }
|
||||
|
||||
.ticketErrorHolder {
|
||||
padding: 6px;
|
||||
background-color: pink;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
}
|
||||
.ticketErrorList li {
|
||||
list-style-type: none;
|
||||
|
||||
}
|
||||
.ticketError {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
#jsErrorBox { display: none; margin-bottom: 24px; }
|
||||
|
||||
.attachment_container { width: 100%; margin-top: 6px; }
|
||||
|
||||
.attachment_header { margin-bottom: 6px; font-weight: bold; font-size: 14px; }
|
||||
|
||||
.attachment_add { float: right; }
|
||||
.attachment_add button { padding: 10px 24px; }
|
||||
|
||||
.attachment_add button:disabled { cursor: not-allowed; }
|
||||
|
||||
.attachment_inputs { float: left; width: 80%; }
|
||||
.attachment_inputs input[type="file"] {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 10px 10px;
|
||||
margin-bottom: 6px;
|
||||
background-color: #f0f4fd;
|
||||
font-size: 16px;
|
||||
color: #526489;
|
||||
}
|
||||
|
||||
.attachment_info { clear: both; margin-bottom: 6px; color: #777; }
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
<?php
|
||||
|
||||
require 'include/ticket.php';
|
||||
require 'include/functions.php';
|
||||
|
||||
function exec_ogp_module()
|
||||
{
|
||||
global $db, $loggedInUserInfo;
|
||||
|
||||
if (isset($_SESSION['ticket'])) {
|
||||
unset($_SESSION['ticket']);
|
||||
}
|
||||
if (isset($_SESSION['ticketReply'])) {
|
||||
unset($_SESSION['ticketReply']);
|
||||
}
|
||||
|
||||
$page = (isset($_GET['page']) && (int)$_GET['page'] > 0) ? (int)$_GET['page'] : 1;
|
||||
$limit = (isset($_GET['limit']) && (int)$_GET['limit'] > 0) ? (int)$_GET['limit'] : 10;
|
||||
|
||||
if (!empty($loggedInUserInfo['users_page_limit']) && empty($_GET['limit'])) {
|
||||
$limit = $loggedInUserInfo['users_page_limit'];
|
||||
}
|
||||
|
||||
$ticket = new Ticket($db);
|
||||
$isAdmin = $db->isAdmin($_SESSION['user_id']);
|
||||
|
||||
$ticketOwner = (!$isAdmin ? $_SESSION['user_id'] : null);
|
||||
$ticketCount = $ticket->count($ticketOwner);
|
||||
$tickets = $ticket->tickets($ticketOwner, $page, $limit);
|
||||
|
||||
echo '<h2>'.get_lang('support_tickets').'</h2>';
|
||||
|
||||
echo '<div class="ticketOptionLinks">
|
||||
<a href="?m=tickets&p=submitticket">'.get_lang('submit_ticket').'</a>
|
||||
</div>';
|
||||
|
||||
if ($tickets !== false && $ticketCount > 0) {
|
||||
echo '<table class="ticketListTable" style="width:100%;">';
|
||||
echo '<tr>';
|
||||
echo '<th>'.get_lang('ticket_subject').'</th>';
|
||||
echo '<th>'.get_lang('ticket_status').'</th>';
|
||||
echo '<th>'.get_lang('ticket_updated').'</th>';
|
||||
echo '</tr>';
|
||||
|
||||
foreach ($tickets as $t) {
|
||||
$date = new DateTime($t['last_updated']);
|
||||
echo '<tr class="ticketRow '.ticketCodeToName($t['status'], true).'">
|
||||
<td><a href="?m=tickets&p=viewticket&tid='.$t['tid'].'&uid='.$t['uid'].'">'. htmlentities($t['subject']) .'</a></td>
|
||||
<td>'. ticketCodeToName($t['status']) .'</td>
|
||||
<td>'. $date->format('jS M Y (H:i)') .'</td>
|
||||
</tr>';
|
||||
}
|
||||
|
||||
echo '</table>';
|
||||
|
||||
echo '<div class="ticketPagination">'.paginationPages($ticketCount, $page, $limit, '?m=tickets&limit='.$limit.'&page=', 3, 'Tickets').'</div>';
|
||||
} else {
|
||||
if ($ticketCount > 0) {
|
||||
echo '<div class="no_tickets">' . get_lang('ticket_invalid_page_num') . '</div>';
|
||||
} else {
|
||||
echo '<div class="no_tickets">' . get_lang('no_tickets_submitted') . '</div>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
<?php
|
||||
|
||||
require 'include/functions.php';
|
||||
|
||||
require 'include/TicketSettings.php';
|
||||
require 'includes/form_table_class.php';
|
||||
|
||||
function exec_ogp_module()
|
||||
{
|
||||
global $db, $view;
|
||||
|
||||
$TicketSettings = new TicketSettings($db);
|
||||
$errors = array();
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$types = array('kb', 'mb', 'gb', 'tb', 'pb');
|
||||
$fields = array();
|
||||
|
||||
$ratings_enabled = (int)$_POST['ratings_enabled'];
|
||||
$attachments_enabled = (int)$_POST['attachments_enabled'];
|
||||
$notifications_enabled = (int)$_POST['notifications_enabled'];
|
||||
$attachment_limit = (int)$_POST['attachment_limit'];
|
||||
$attachment_extensions = trim($_POST['attachment_extensions']);
|
||||
$extensions = splitExtensions($attachment_extensions);
|
||||
|
||||
$fields['ratings_enabled'] = ($ratings_enabled >= 1 ? 1 : 0);
|
||||
$fields['attachments_enabled'] = ($attachments_enabled >= 1 ? 1 : 0);
|
||||
$fields['notifications_enabled'] = ($notifications_enabled >= 1 ? 1 : 0);
|
||||
$fields['attachment_limit'] = $attachment_limit;
|
||||
|
||||
if (!is_numeric(substr($_POST['attachment_max_size'], 0, -2))) {
|
||||
$errors[] = get_lang('invalid_max_size');
|
||||
} elseif (!in_array(strtolower(substr($_POST['attachment_max_size'], -2)), $types)) {
|
||||
$errors[] = get_lang('invalid_unit');
|
||||
} else {
|
||||
$fields['attachment_max_size'] = toBytes($_POST['attachment_max_size']);
|
||||
}
|
||||
|
||||
if (!is_dir($_POST['attachment_save_dir']) && !mkdir($_POST['attachment_save_dir'], 0777, true)) {
|
||||
$errors[] = get_lang('invalid_save_dir');
|
||||
} elseif (!is_writable($_POST['attachment_save_dir'])) {
|
||||
$errors[] = get_lang('invalid_save_dir_not_writable');
|
||||
} else {
|
||||
$fields['attachment_save_dir'] = $_POST['attachment_save_dir'];
|
||||
}
|
||||
|
||||
if (empty($attachment_extensions) || empty($extensions)) {
|
||||
$errors[] = get_lang('invalid_extensions');
|
||||
} else {
|
||||
$fields['attachment_extensions'] = $extensions;
|
||||
}
|
||||
|
||||
$TicketSettings->set($fields);
|
||||
}
|
||||
|
||||
$settings = $TicketSettings->get();
|
||||
|
||||
echo '<h2>'.get_lang('ticket_settings').'</h2>';
|
||||
|
||||
if (!empty($errors)) {
|
||||
echo ticketErrors($errors, get_lang('settings_errors_occured'));
|
||||
}
|
||||
|
||||
$form = new FormTable;
|
||||
$form->start_form('?m=tickets&p=ticket_settings', 'POST');
|
||||
$form->start_table();
|
||||
|
||||
$form->add_field('on_off', 'ratings_enabled', $settings['ratings_enabled']);
|
||||
$form->add_field('on_off', 'attachments_enabled', $settings['attachments_enabled']);
|
||||
$form->add_field('on_off', 'notifications_enabled', $settings['notifications_enabled']);
|
||||
$form->add_field('string', 'attachment_max_size', bytesTo($settings['attachment_max_size']));
|
||||
$form->add_field('string', 'attachment_limit', $settings['attachment_limit']);
|
||||
$form->add_field('string', 'attachment_save_dir', $settings['attachment_save_dir']);
|
||||
$form->add_field('string', 'attachment_extensions', $settings['attachment_extensions']);
|
||||
|
||||
$form->end_table();
|
||||
$form->add_button('submit', 'update_settings', get_lang('update_settings'));
|
||||
$form->end_form();
|
||||
?>
|
||||
<button id="phpIniButton"><?php echo get_lang('show_php_ini'); ?></button>
|
||||
<div id="guesstimateIniSettings"></div>
|
||||
|
||||
<script src="modules/tickets/js/ticket_settings.js"></script>
|
||||
<?php
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
.ticketErrorHolder {
|
||||
padding: 6px;
|
||||
background-color: pink;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.ticketErrorList li {
|
||||
list-style-type: none;
|
||||
|
||||
}
|
||||
|
||||
.ticketError {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
#guesstimateIniSettings {
|
||||
display: none;
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
.no_tickets {
|
||||
padding: 12px;
|
||||
background-color: pink;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.ticketOptionLinks {
|
||||
padding: 4px;
|
||||
border-bottom: 1px solid #e3e3e3;
|
||||
}
|
||||
|
||||
.ticketListTable {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.ticketListTable th {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.ticketPagination {}
|
||||
|
|
@ -1 +0,0 @@
|
|||
Deny from all
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 798 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 660 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 50 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 121 KiB |
|
|
@ -1,5 +0,0 @@
|
|||
By default, ticket attachments will be stored here.
|
||||
|
||||
You should go to the settings and change this so attachments will be saved outside of the www folder.
|
||||
|
||||
If you are unable to do that, then make sure direct access to this folder is blocked.
|
||||
|
|
@ -1,168 +0,0 @@
|
|||
<?php
|
||||
|
||||
require 'include/ticket.php';
|
||||
require 'include/Attachments.php';
|
||||
require 'include/TicketSettings.php';
|
||||
|
||||
require 'include/functions.php';
|
||||
|
||||
function exec_ogp_module()
|
||||
{
|
||||
global $db, $view;
|
||||
|
||||
if (isset($_SESSION['ticket'])) {
|
||||
unset($_SESSION['ticket']);
|
||||
}
|
||||
|
||||
$ticket = new Ticket($db);
|
||||
$TicketSettings = new TicketSettings($db);
|
||||
|
||||
$isAdmin = $db->isAdmin($_SESSION['user_id']);
|
||||
$attachmentSettings = $TicketSettings->get(array('attachments_enabled', 'attachment_save_dir', 'attachment_limit', 'attachment_max_size', 'attachment_extensions', 'ratings_enabled'));
|
||||
|
||||
echo '<h2>'.get_lang('viewing_ticket').'</h2>';
|
||||
|
||||
$tid = (int)$_GET['tid'];
|
||||
$uid = $_GET['uid'];
|
||||
|
||||
$ticketData = $ticket->getTicket($tid, $uid);
|
||||
|
||||
if (!$ticket->exists($tid, $uid)) {
|
||||
print_failure(get_lang('ticket_not_found'));
|
||||
$view->refresh("?m=tickets");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$isAdmin && !$ticket->authorized($_SESSION['user_id'], $tid, $uid)) {
|
||||
print_failure(get_lang('ticket_cant_read'));
|
||||
$view->refresh("?m=tickets");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$ticketData) {
|
||||
print_failure(get_lang('cant_view_ticket'));
|
||||
$view->refresh("?m=tickets");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$attachments = new Attachments(
|
||||
$db,
|
||||
$_FILES['ticket_file'],
|
||||
$attachmentSettings['attachment_save_dir'],
|
||||
$attachmentSettings['attachment_limit'],
|
||||
$attachmentSettings['attachment_max_size'],
|
||||
explode(', ', $attachmentSettings['attachment_extensions'])
|
||||
);
|
||||
|
||||
if (isset($_POST['ticket_close'])) {
|
||||
$ticket->updateStatus($tid, $uid, 0);
|
||||
$view->refresh("?m=tickets&p=viewticket&tid=".$tid."&uid=".$uid, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isset($_POST['ticket_submit_response'])) {
|
||||
$_POST = array_map('trim', $_POST);
|
||||
$_SESSION['ticketReply'] = strip_real_escape_string($_POST['reply_content']);
|
||||
|
||||
$errors = array();
|
||||
$fileErrors = array();
|
||||
|
||||
if (empty($_POST['reply_content'])) {
|
||||
$errors[] = get_lang('no_ticket_reply');
|
||||
} elseif (strlen($_POST['reply_content']) < 4) {
|
||||
$errors[] = get_lang('invalid_ticket_reply_length');
|
||||
}
|
||||
|
||||
if ($attachments->checkPath() === false && $attachmentSettings['attachments_enabled']) {
|
||||
$fileErrors[] = get_lang('attachment_directory_not_writable');
|
||||
}
|
||||
|
||||
if ($attachments->validAttachmentCount() === false && $attachmentSettings['attachments_enabled']) {
|
||||
$fileErrors[] = get_lang_f('attachment_invalid_file_count', $attachmentSettings['attachment_limit']);
|
||||
}
|
||||
|
||||
if (empty($errors)) {
|
||||
$reply = $ticket->message($tid, $_SESSION['user_id'], getClientIPAddress(), strip_real_escape_string($_POST['reply_content']), $isAdmin, $uid);
|
||||
|
||||
if (!$reply) {
|
||||
echo ticketErrors(array(get_lang('failed_to_reply')));
|
||||
$view->refresh("?m=tickets&p=submitticket", 60);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isset($_SESSION['ticketReply'])) {
|
||||
unset($_SESSION['ticketReply']);
|
||||
}
|
||||
|
||||
if ($attachmentSettings['attachments_enabled']) {
|
||||
// Validate the uploaded files if specified path exists and is writable. and if the amount of files is valid.
|
||||
// if any files fail to validate, then only save/move the ones which validated successfully and show an error for the ones which didn't.
|
||||
if (empty($fileErrors)) {
|
||||
$validator = $attachments->validate();
|
||||
$fileErrors[] = $validator->getErrors();
|
||||
$attachments->save($tid, $reply);
|
||||
}
|
||||
|
||||
setcookie('fileErrors', json_encode(array('uid' => $uid, 'fileErrors' => $fileErrors)), time() + 86400, '/');
|
||||
}
|
||||
|
||||
$view->refresh("?m=tickets&p=viewticket&tid=".$tid."&uid=".$uid, 0);
|
||||
return;
|
||||
} else {
|
||||
echo ticketErrors($errors);
|
||||
$view->refresh("?m=tickets&p=viewticket&tid=".$tid."&uid=".$uid, 60);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo '<div id="jsErrorBox">'. ticketErrors() .'</div>';
|
||||
echo ticketHeader($ticketData);
|
||||
|
||||
if ($ticketData['status'] == 0) {
|
||||
echo '<div class="ticket_closed">'.get_lang('ticket_is_closed').'</div>';
|
||||
|
||||
echo '<div class="ticket_reply_notice">';
|
||||
echo '<div class="left" id="toggleNoticeMessage">'.get_lang('reply').'</div>';
|
||||
echo '<div class="right" id="toggleNoticeIcon">+</div>';
|
||||
echo '<div class="clear"></div>';
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
echo '<div class="ticket_ReplyBox status_'.ticketCodeToName($ticketData['status'], true).'">
|
||||
<form method="POST" enctype="multipart/form-data">
|
||||
<textarea name="reply_content" id="messageBox" style="width:100%;" rows="12">'.(isset($_SESSION['ticketReply']) ? $_SESSION['ticketReply'] : '').'</textarea>';
|
||||
|
||||
if ($attachmentSettings['attachments_enabled']) {
|
||||
echo attachmentForm();
|
||||
}
|
||||
|
||||
echo '<input type="submit" id="submit" class="ticket_button" name="ticket_submit_response" value="'. get_lang('ticket_submit_response') . '">
|
||||
'.($ticketData['status'] != 0 ? '<input type="submit" class="ticket_button" name="ticket_close" value="'. get_lang('ticket_close') . '">' : '').'
|
||||
</form>
|
||||
</div>';
|
||||
|
||||
if (!empty($ticketData['messages'])) {
|
||||
echo '<div class="replyContainer">';
|
||||
foreach ($ticketData['messages'] as $message) {
|
||||
echo ticketMessage($message, $uid, $isAdmin, $attachmentSettings['ratings_enabled']);
|
||||
}
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
if (empty($ticketData['messages']) && $ticketData['status'] != 0) {
|
||||
echo '<div class="no_ticket_replies">'.get_lang('no_ticket_replies').'</div>';
|
||||
}
|
||||
|
||||
require 'js/javascript_vars.php';
|
||||
?>
|
||||
<script src="modules/tickets/js/helpers.js"></script>
|
||||
<script src="modules/tickets/js/ticket.js"></script>
|
||||
<script src="modules/tickets/js/rating.js"></script>
|
||||
|
||||
<?php
|
||||
}
|
||||
|
|
@ -1,270 +0,0 @@
|
|||
.divTable{
|
||||
display: table;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.divTableRow {
|
||||
display: table-row;
|
||||
}
|
||||
|
||||
.divTableHeading {
|
||||
background-color: #EEE;
|
||||
display: table-header-group;
|
||||
}
|
||||
|
||||
.divTableCell, .divTableHead {
|
||||
border: 1px solid #e3e3e3;
|
||||
display: table-cell;
|
||||
padding: 3px 10px;
|
||||
}
|
||||
|
||||
.divTableHeading {
|
||||
background-color: #EEE;
|
||||
display: table-header-group;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.divTableFoot {
|
||||
background-color: #EEE;
|
||||
display: table-footer-group;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.divTableBody {
|
||||
display: table-row-group;
|
||||
}
|
||||
|
||||
.infoblock_ticket {
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
.contentblock_ticket {
|
||||
|
||||
}
|
||||
|
||||
.ticket_ReplyBox {
|
||||
margin-top:12px;
|
||||
}
|
||||
|
||||
.ticket_button {
|
||||
margin: 8px 0 4px 0;
|
||||
}
|
||||
|
||||
.ticket_admin_button {
|
||||
margin: 8px 0 4px 0;
|
||||
float: right;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.no_ticket_replies {
|
||||
padding: 12px;
|
||||
background-color: pink;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.ticket_reply {
|
||||
margin: 10px 0;
|
||||
padding: 0;
|
||||
border: 1px solid #efefef;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.ticket_reply.admin {
|
||||
border: 1px solid #cce4fc;
|
||||
}
|
||||
|
||||
.ticket_reply .date {
|
||||
float: right;
|
||||
padding: 8px 10px;
|
||||
font-size: .8em;
|
||||
}
|
||||
|
||||
.ticket_reply .user {
|
||||
padding: 5px 10px;
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
|
||||
.ticket_reply .admin {
|
||||
padding: 5px 10px;
|
||||
background-color: #cce4fc;
|
||||
}
|
||||
|
||||
.ticket_reply .user .name {
|
||||
display: block;
|
||||
font-size: .9em;
|
||||
}
|
||||
|
||||
.ticket_reply .admin .name {
|
||||
display: block;
|
||||
font-size: .9em;
|
||||
}
|
||||
|
||||
.ticket_reply .user .type {
|
||||
display: block;
|
||||
font-weight: 700;
|
||||
font-size: .8em;
|
||||
}
|
||||
|
||||
.ticket_reply .admin .type {
|
||||
display: block;
|
||||
font-weight: 700;
|
||||
font-size: .8em;
|
||||
}
|
||||
|
||||
.ticket_reply .message {
|
||||
padding: 12px 15px;
|
||||
}
|
||||
|
||||
.ticket_footer {
|
||||
border-top:1px solid #eee;
|
||||
padding: 8px 10px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.ticket_footer .left, .ticket_footer .center, .ticket_footer .right {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.ticket_footer .left {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.ticket_footer .right {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.attachmentContainer {
|
||||
border-top: 1px solid #eee;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.attachmentHeader {
|
||||
margin-top: 4px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.attachmentList {
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.ticketErrorHolder {
|
||||
padding: 6px;
|
||||
background-color: pink;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.ticketErrorList li {
|
||||
list-style-type: none;
|
||||
|
||||
}
|
||||
|
||||
.ticketError {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.ticket_closed {
|
||||
padding: 12px;
|
||||
margin: 8px 0;
|
||||
background-color: #fcf8e3;
|
||||
color: #8a6d3b;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.ticket_ReplyBox.status_ticket_closed {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ticket_reply_notice {
|
||||
cursor: pointer;
|
||||
right: 0;
|
||||
text-align: center;
|
||||
background-color: #d9edf7;
|
||||
border-color: #bce8f1;
|
||||
color: #31708f;
|
||||
padding: 12px;
|
||||
font-size: 14px;
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
||||
.ticket_reply_notice .left, .ticket_reply_notice .center, .ticket_reply_notice .right {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.ticket_reply_notice .left {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.ticket_reply_notice .right {
|
||||
font-weight: bold;
|
||||
font-size: 16px;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.clear {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
div.stars {
|
||||
width: 270px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
input.star {
|
||||
display: none;
|
||||
}
|
||||
|
||||
label.star {
|
||||
float: right;
|
||||
color: #444;
|
||||
transition: all .2s;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
input.star:checked ~ label.star:before {
|
||||
content: '\2605';
|
||||
color: #FD4;
|
||||
transition: all .25s;
|
||||
}
|
||||
|
||||
input.star-5:checked ~ label.star:before {
|
||||
|
||||
}
|
||||
|
||||
input.star-1:checked ~ label.star:before {
|
||||
color: #F62;
|
||||
}
|
||||
|
||||
label.star:hover {
|
||||
transform: rotate(-15deg) scale(1.3);
|
||||
}
|
||||
|
||||
label.star:before {
|
||||
content: '\2605';
|
||||
}
|
||||
|
||||
#jsErrorBox { display: none; margin-bottom: 24px; }
|
||||
|
||||
.attachment_container { width: 100%; margin-top: 6px; }
|
||||
|
||||
.attachment_header { margin-bottom: 6px; font-weight: bold; font-size: 14px; }
|
||||
|
||||
.attachment_add { float: right; }
|
||||
.attachment_add button { padding: 10px 24px; }
|
||||
|
||||
.attachment_add button:disabled { cursor: not-allowed; }
|
||||
|
||||
.attachment_inputs { float: left; width: 80%; }
|
||||
.attachment_inputs input[type="file"] {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 10px 10px;
|
||||
margin-bottom: 6px;
|
||||
background-color: #f0f4fd;
|
||||
font-size: 16px;
|
||||
color: #526489;
|
||||
}
|
||||
|
||||
.attachment_info { clear: both; margin-bottom: 6px; color: #777; }
|
||||
Loading…
Add table
Add a link
Reference in a new issue