khanat-opennel-code/code/web/private_php/ams/autoload/ticket.php
2015-12-13 21:04:37 +02:00

645 lines
23 KiB
PHP

<?php
/**
* class that handles most ticket related functions.
* the ticket class is used for most ticketing related functions, it also holds some wrapper functions.
* @author Daan Janssens, mentored by Matthew Lagoe
*/
class Ticket{
private $tId; /**< The id of ticket */
private $timestamp; /**< Timestamp of the ticket */
private $title; /**< Title of the ticket */
private $status; /**< Status of the ticket (0 = waiting on user reply, 1 = waiting on support, (2= not used atm), 3 = closed */
private $queue; /**< (not in use atm) */
private $ticket_category; /**< the id of the category belonging to the ticket */
private $author; /**< The ticket_users id */
private $priority; /**< The priority of the ticket where 0 = low, 3= supadupahigh */
////////////////////////////////////////////Functions////////////////////////////////////////////////////
/**
* check if a ticket exists.
* @param $id the id of the ticket to be checked.
* @return true if the ticket exists, else false.
*/
public static function ticketExists($id) {
$dbl = new DBLayer("lib");
//check if ticket exists
if( $dbl->select("`ticket`", array('ticket_id' => $id), "`TId` = :ticket_id")->rowCount() ){
return true;
}else{
return false;
}
}
/**
* return an array of the possible statuses
* @return an array containing the string values that represent the different statuses.
*/
public static function getStatusArray() {
return Array("Waiting on user reply","Waiting on support","Waiting on Dev reply","Closed");
}
/**
* return an array of the possible priorities
* @return an array containing the string values that represent the different priorities.
*/
public static function getPriorityArray() {
return Array("Low","Normal","High","Super Dupa High");
}
/**
* return an entire ticket.
* returns the ticket object and an array of all replies to that ticket.
* @param $id the id of the ticket.
* @param $view_as_admin true if the viewer of the ticket is a mod, else false (depending on this it will also show the hidden comments)
* @return an array containing the 'ticket_obj' and a 'reply_array', which is an array containing all replies to that ticket.
*/
public static function getEntireTicket($id,$view_as_admin) {
$ticket = new Ticket();
$ticket->load_With_TId($id);
$reply_array = Ticket_Reply::getRepliesOfTicket($id, $view_as_admin);
return Array('ticket_obj' => $ticket,'reply_array' => $reply_array);
}
/**
* return all tickets of a specific user.
* an array of all tickets created by a specific user are returned by this function.
* @param $author the id of the user of whom we want all tickets from.
* @return an array containing all ticket objects related to a user.
*/
public static function getTicketsOf($author) {
$dbl = new DBLayer("lib");
$statement = $dbl->execute("SELECT * FROM ticket INNER JOIN ticket_user ON ticket.Author = ticket_user.TUserId and ticket_user.ExternId=:id", array('id' => $author));
$row = $statement->fetchAll();
$result = Array();
foreach($row as $ticket){
$instance = new self();
$instance->setTId($ticket['TId']);
$instance->setTimestamp($ticket['Timestamp']);
$instance->setTitle($ticket['Title']);
$instance->setStatus($ticket['Status']);
$instance->setQueue($ticket['Queue']);
$instance->setTicket_Category($ticket['Ticket_Category']);
$instance->setAuthor($ticket['Author']);
$result[] = $instance;
}
return $result;
}
/**
* function that creates a new ticket.
* A new ticket will be created, in case the extra_info != 0 and the http request came from ingame, then a ticket_info page will be created.
* A log entry will be written, depending on the $real_authors value. In case the for_support_group parameter is set, the ticket will be forwarded immediately.
* Also the mail handler will create a new email that will be sent to the author to notify him that his ticket is freshly created.
* @param $title the title we want to give to the ticket.
* @param $content the content we want to give to the starting post of the ticket.
* @param $category the id of the category that should be related to the ticket.
* @param $author the person who's id will be stored in the database as creator of the ticket.
* @param $real_author should be the same id, or a moderator/admin who creates a ticket for another user (this is used for logging purposes).
* @param $for_support_group in case you directly want to forward the ticket after creating it. (default value = 0 = don't forward)
* @param $extra_info used for creating an ticket_info page related to the ticket, this only happens when the ticket is made ingame.
* @return the created tickets id.
*/
public static function create_Ticket( $title, $content, $category, $author, $real_author, $for_support_group = 0, $extra_info = 0) {
//create the new ticket!
$ticket = new Ticket();
$values = array("Title" => $title, "Timestamp"=>0, "Status"=> 1, "Queue"=> 0, "Ticket_Category" => $category, "Author" => $author, "Priority" => 0);
$ticket->set($values);
$ticket->create();
$ticket_id = $ticket->getTId();
//if ingame then add an extra info
if(Helpers::check_if_game_client() && $extra_info != 0){
$extra_info['Ticket'] = $ticket_id;
Ticket_Info::create_Ticket_Info($extra_info);
}
//write a log entry
if ( $author == $real_author){
Ticket_Log::createLogEntry( $ticket_id, $author, 1);
}else{
Ticket_Log::createLogEntry( $ticket_id, $real_author, 2, $author);
}
Ticket_Reply::createReply($content, $author, $ticket_id, 0, $author);
//forwards the ticket directly after creation to the supposed support group
if($for_support_group){
Ticket::forwardTicket(0, $ticket_id, $for_support_group);
}
//send email that new ticket has been created
Mail_Handler::send_ticketing_mail($ticket->getAuthor(), $ticket, $content, "NEW", $ticket->getForwardedGroupId());
return $ticket_id;
}
/**
* updates the ticket's status.
* A log entry about this will be created only if the newStatus is different from the current status.
* @param $ticket_id the id of the ticket of which we want to change the status.
* @param $newStatus the new status value (integer)
* @param $author the user (id) that performed the update status action
*/
public static function updateTicketStatus( $ticket_id, $newStatus, $author) {
$ticket = new Ticket();
$ticket->load_With_TId($ticket_id);
if ($ticket->getStatus() != $newStatus){
$ticket->setStatus($newStatus);
Ticket_Log::createLogEntry( $ticket_id, $author, 5, $newStatus);
}
$ticket->update();
}
/**
* updates the ticket's status & priority.
* A log entry about this will be created only if the newStatus is different from the current status and also when the newPriority is different from the current priority.
* @todo break this function up into a updateStatus (already exists) and updatePriority function and perhaps write a wrapper function for the combo.
* @param $ticket_id the id of the ticket of which we want to change the status & priority
* @param $newStatus the new status value (integer)
* @param $newPriority the new priority value (integer)
* @param $author the user (id) that performed the update
*/
public static function updateTicketStatusAndPriority( $ticket_id, $newStatus, $newPriority, $author) {
$ticket = new Ticket();
$ticket->load_With_TId($ticket_id);
if ($ticket->getStatus() != $newStatus){
$ticket->setStatus($newStatus);
Ticket_Log::createLogEntry( $ticket_id, $author, 5, $newStatus);
}
if ($ticket->getPriority() != $newPriority){
$ticket->setPriority($newPriority);
Ticket_Log::createLogEntry( $ticket_id, $author, 6, $newPriority);
}
$ticket->update();
}
/**
* return the latest reply of a ticket
* @param $ticket_id the id of the ticket.
* @return a ticket_reply object.
*/
public static function getLatestReply( $ticket_id) {
$dbl = new DBLayer("lib");
$statement = $dbl->execute("SELECT * FROM ticket_reply WHERE Ticket =:id ORDER BY TReplyId DESC LIMIT 1 ", array('id' => $ticket_id));
$reply = new Ticket_Reply();
$reply->set($statement->fetch());
return $reply;
}
/**
* return the attachments list
* @param $ticket_id the id of the ticket.
* @return a ticket_reply object.
*/
public static function getAttachments( $ticket_id) {
$dbl = new DBLayer("lib");
$statement = $dbl->select("`ticket_attachments`",array('ticket_TId' => $ticket_id), "`ticket_TId` =:ticket_TId ORDER BY Timestamp DESC");
$fetchall = $statement->fetchall();
$base = 0;
foreach ($fetchall as &$value) {
$webUser = new WebUsers($value['Uploader']);
$fetchall[$base]['Username'] = $webUser->getUsername();
$bytes = $fetchall[$base]['Filesize'];
$precision = 2;
$units = array('B', 'KB', 'MB', 'GB', 'TB');
$bytes = max($bytes, 0);
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
$pow = min($pow, count($units) - 1);
$bytes /= pow(1024, $pow);
$fetchall[$base]['Filesize'] = round($bytes, $precision) . ' ' . $units[$pow];;
$base++;
}
return $fetchall;
}
/**
* create a new reply for a ticket.
* A reply will only be added if the content isn't empty and if the ticket isn't closed.
* The ticket creator will be notified by email that someone else replied on his ticket.
* @param $content the content of the reply
* @param $author the author of the reply
* @param $ticket_id the id of the ticket to which we want to add the reply.
* @param $hidden boolean that specifies if the reply should only be shown to mods/admins or all users.
*/
public static function createReply($content, $author, $ticket_id, $hidden){
//if not empty
if(! ( Trim ( $content ) === '' )){
$content = filter_var($content, FILTER_SANITIZE_STRING);
$ticket = new Ticket();
$ticket->load_With_TId($ticket_id);
//if status is not closed
if($ticket->getStatus() != 3){
Ticket_Reply::createReply($content, $author, $ticket_id, $hidden, $ticket->getAuthor());
//notify ticket author that a new reply is added!
if($ticket->getAuthor() != $author){
Mail_Handler::send_ticketing_mail($ticket->getAuthor(), $ticket, $content, "REPLY", $ticket->getForwardedGroupId());
}
}else{
//TODO: Show error message that ticket is closed
}
}else{
//TODO: Show error content is empty
}
}
/**
* assign a ticket to a user.
* Checks if the ticket exists, if so then it will try to assign the user to it, a log entry will be written about this.
* @param $user_id the id of user trying to be assigned to the ticket.
* @param $ticket_id the id of the ticket that we try to assign to the user.
* @return SUCCESS_ASSIGNED, TICKET_NOT_EXISTING or ALREADY_ASSIGNED
*/
public static function assignTicket($user_id, $ticket_id){
if(self::ticketExists($ticket_id)){
$returnvalue = Assigned::assignTicket($user_id, $ticket_id);
Ticket_Log::createLogEntry( $ticket_id, $user_id, 7);
return $returnvalue;
}else{
return "TICKET_NOT_EXISTING";
}
}
/**
* unassign a ticket of a user.
* Checks if the ticket exists, if so then it will try to unassign the user of it, a log entry will be written about this.
* @param $user_id the id of user trying to be assigned to the ticket.
* @param $ticket_id the id of the ticket that we try to assign to the user.
* @return SUCCESS_UNASSIGNED, TICKET_NOT_EXISTING or NOT_ASSIGNED
*/
public static function unAssignTicket($user_id, $ticket_id){
if(self::ticketExists($ticket_id)){
$returnvalue = Assigned::unAssignTicket($user_id, $ticket_id);
Ticket_Log::createLogEntry( $ticket_id, $user_id, 9);
return $returnvalue;
}else{
return "TICKET_NOT_EXISTING";
}
}
/**
* forward a ticket to a specific support group.
* Checks if the ticket exists, if so then it will try to forward the ticket to the support group specified, a log entry will be written about this.
* if no log entry should be written then the user_id should be 0, else te $user_id will be used in the log to specify who forwarded it.
* @param $user_id the id of user trying to forward the ticket.
* @param $ticket_id the id of the ticket that we try to forward to a support group.
* @param $group_id the id of the support group.
* @return SUCCESS_FORWARDED, TICKET_NOT_EXISTING or INVALID_SGROUP
*/
public static function forwardTicket($user_id, $ticket_id, $group_id){
if(self::ticketExists($ticket_id)){
if(isset($group_id) && $group_id != ""){
//forward the ticket
$returnvalue = Forwarded::forwardTicket($group_id, $ticket_id);
if($user_id != 0){
//unassign the ticket incase the ticket is assined to yourself
self::unAssignTicket($user_id, $ticket_id);
//make a log entry of this action
Ticket_Log::createLogEntry( $ticket_id, $user_id, 8, $group_id);
}
return $returnvalue;
}else{
return "INVALID_SGROUP";
}
}else{
return "TICKET_NOT_EXISTING";
}
}
////////////////////////////////////////////Methods////////////////////////////////////////////////////
/**
* A constructor.
* Empty constructor
*/
public function __construct() {
}
/**
* sets the object's attributes.
* @param $values should be an array of the form array('TId' => ticket_id, 'Title' => title, 'Status'=> status, 'Timestamp' => ts, 'Queue' => queue,
* 'Ticket_Category' => tc, 'Author' => author, 'Priority' => priority).
*/
public function set($values){
if(isset($values['TId'])){
$this->tId = $values['TId'];
}
$this->title = $values['Title'];
$this->status = $values['Status'];
$this->timestamp = $values['Timestamp'];
$this->queue = $values['Queue'];
$this->ticket_category = $values['Ticket_Category'];
$this->author = $values['Author'];
$this->priority = $values['Priority'];
}
/**
* creates a new 'ticket' entry.
* this method will use the object's attributes for creating a new 'ticket' entry in the database.
*/
public function create(){
$dbl = new DBLayer("lib");
$this->tId = $dbl->executeReturnId("ticket", Array('Title' => $this->title, 'Status' => $this->status, 'Queue' => $this->queue, 'Ticket_Category' => $this->ticket_category, 'Author' => $this->author, 'Priority' => $this->priority), array('Timestamp'=>'now()'));
}
/**
* loads the object's attributes.
* loads the object's attributes by giving a TId (ticket id).
* @param $id the id of the ticket that should be loaded
*/
public function load_With_TId( $id) {
$dbl = new DBLayer("lib");
$statement = $dbl->select("ticket", array('id' => $id), "TId=:id");
$row = $statement->fetch();
$this->tId = $row['TId'];
$this->timestamp = $row['Timestamp'];
$this->title = $row['Title'];
$this->status = $row['Status'];
$this->queue = $row['Queue'];
$this->ticket_category = $row['Ticket_Category'];
$this->author = $row['Author'];
$this->priority = $row['Priority'];
}
/**
* update the objects attributes to the db.
*/
public function update(){
$dbl = new DBLayer("lib");
$dbl->update("ticket", Array('Timestamp' => $this->timestamp, 'Title' => $this->title, 'Status' => $this->status, 'Queue' => $this->queue, 'Ticket_Category' => $this->ticket_category, 'Author' => $this->author, 'Priority' => $this->priority), "TId=$this->tId");
}
/**
* check if a ticket has a ticket_info page or not.
* @return true or false
*/
public function hasInfo(){
return Ticket_Info::TicketHasInfo($this->getTId());
}
////////////////////////////////////////////Getters////////////////////////////////////////////////////
/**
* get tId attribute of the object.
*/
public function getTId(){
return $this->tId;
}
/**
* get timestamp attribute of the object in the format defined in the outputTime function of the Helperclass.
*/
public function getTimestamp(){
return Helpers::outputTime($this->timestamp);
}
/**
* get title attribute of the object.
*/
public function getTitle(){
return $this->title;
}
/**
* get status attribute of the object.
*/
public function getStatus(){
return $this->status;
}
/**
* get status attribute of the object in the form of text (string).
*/
public function getStatusText(){
$statusArray = Ticket::getStatusArray();
return $statusArray[$this->getStatus()];
}
/**
* get category attribute of the object in the form of text (string).
*/
public function getCategoryName(){
$category = Ticket_Category::constr_TCategoryId($this->getTicket_Category());
return $category->getName();
}
/**
* get queue attribute of the object.
*/
public function getQueue(){
return $this->queue;
}
/**
* get ticket_category attribute of the object (int).
*/
public function getTicket_Category(){
return $this->ticket_category;
}
/**
* get author attribute of the object (int).
*/
public function getAuthor(){
return $this->author;
}
/**
* get priority attribute of the object (int).
*/
public function getPriority(){
return $this->priority;
}
/**
* get priority attribute of the object in the form of text (string).
*/
public function getPriorityText(){
$priorityArray = Ticket::getPriorityArray();
return $priorityArray[$this->getPriority()];
}
/**
* get the user assigned to the ticket.
* or return 0 in case not assigned.
*/
public function getAssigned(){
$user_id = Assigned::getUserAssignedToTicket($this->getTId());
if ($user_id == ""){
return 0;
}else{
return $user_id;
}
}
/**
* get the name of the support group to whom the ticket is forwarded
* or return 0 in case not forwarded.
*/
public function getForwardedGroupName(){
$group_id = Forwarded::getSGroupOfTicket($this->getTId());
if ($group_id == ""){
return 0;
}else{
return Support_Group::getGroup($group_id)->getName();
}
}
/**
* get the id of the support group to whom the ticket is forwarded
* or return 0 in case not forwarded.
*/
public function getForwardedGroupId(){
$group_id = Forwarded::getSGroupOfTicket($this->getTId());
if ($group_id == ""){
return 0;
}else{
return $group_id;
}
}
////////////////////////////////////////////Setters////////////////////////////////////////////////////
/**
* set tId attribute of the object.
* @param $id integer id of the ticket
*/
public function setTId($id){
$this->tId = $id;
}
/**
* set timestamp attribute of the object.
* @param $ts timestamp of the ticket
*/
public function setTimestamp($ts){
$this->timestamp = $ts;
}
/**
* set title attribute of the object.
* @param $t title of the ticket
*/
public function setTitle($t){
$this->title = $t;
}
/**
* set status attribute of the object.
* @param $s status of the ticket(int)
*/
public function setStatus($s){
$this->status = $s;
}
/**
* set queue attribute of the object.
* @param $q queue of the ticket
*/
public function setQueue($q){
$this->queue = $q;
}
/**
* set ticket_category attribute of the object.
* @param $tc ticket_category id of the ticket(int)
*/
public function setTicket_Category($tc){
$this->ticket_category = $tc;
}
/**
* set author attribute of the object.
* @param $a author of the ticket
*/
public function setAuthor($a){
$this->author = $a;
}
/**
* set priority attribute of the object.
* @param $p priority of the ticket
*/
public function setPriority($p){
$this->priority = $p;
}
/**
* function that creates a ticket Attachment.
*/
public static function add_Attachment($TId,$filename,$author,$tempFile){
global $FILE_STORAGE_PATH;
$length = mt_rand(20, 25);
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$-_.+!*\'(),';
$randomString = '';
for ($i = 0; $i < $length; $i++) {
$randomString .= $characters[rand(0, strlen($characters) - 1)];
}
$targetFile = $FILE_STORAGE_PATH . $randomString . "/" . $filename;
if(file_exists($targetFile)) { return self::add_Attachment($TId,$filename,$author,$tempFile); }
$ticket = new Ticket();
$ticket->load_With_TId($TId);
//create the attachment!
try {
$dbl = new DBLayer("lib");
$dbl->insert("`ticket_attachments`", Array('ticket_TId' => $TId, 'Filename' => $filename, 'Filesize' => filesize($tempFile), 'Uploader' => $author, 'Path' => $randomString . "/" . $filename));
}
catch (Exception $e) {
return $false;
}
mkdir($FILE_STORAGE_PATH . $randomString);
$return = move_uploaded_file($tempFile,$targetFile);
if ($return == false) {
$dbl->delete("`ticket_attachments`", array('Path' => $randomString . "/" . $filename), "`Path` = :Path");
}
//write a log entry
Ticket_Log::createLogEntry( $TId, $author, 10);
return $return;
}
}