Spade
Mini Shell
| Directory:~$ /home/lmsyaran/www/administrator/components/com_helpdeskpro/Model/ |
| [Home] [System Details] [Kill Me] |
<?php
/**
* @version 4.3.0
* @package Joomla
* @subpackage Helpdesk Pro
* @author Tuan Pham Ngoc
* @copyright Copyright (C) 2013 - 2021 Ossolution Team
* @license GNU/GPL, see LICENSE.php
*/
namespace OSSolution\HelpdeskPro\Admin\Model;
use Joomla\CMS\Application\ApplicationHelper;
use Joomla\CMS\Filesystem\File;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\CMS\Uri\Uri;
use Joomla\CMS\User\User;
use Joomla\CMS\User\UserHelper;
use OSL\Input\Input;
use OSL\Model\AdminModel;
use OSSolution\HelpdeskPro\Site\Helper\Helper as HelpdeskproHelper;
use OSSolution\HelpdeskPro\Site\Helper\Html as HelpdeskproHelperHtml;
defined('_JEXEC') or die;
class Ticket extends AdminModel
{
/**
* Initialize the model, insert extra model state
*/
protected function initialize()
{
$this->state->insert('ticket_code', 'string',
'');
}
/**
* Override getData method to allow getting ticket details from ticket
code
*
* @return object
*/
public function getData()
{
if ($this->state->ticket_code &&
empty($this->state->id))
{
$db = $this->getDbo();
$query = $db->getQuery(true);
$query->select('id')
->from('#__helpdeskpro_tickets')
->where('ticket_code = ' .
$db->quote($this->state->ticket_code));
$db->setQuery($query);
$this->state->set('id', (int) $db->loadResult());
}
return parent::getData();
}
/**
* Override loadData method to allow getting more information about the
ticket
*/
protected function loadData()
{
$fieldSuffix = '';
if ($this->container->app->isClient('site'))
{
$fieldSuffix = HelpdeskproHelper::getFieldSuffix();
}
$db = $this->getDbo();
$query = $db->getQuery(true);
$query->select('a.*, b.username, c.title' . $fieldSuffix .
' AS category_title')
->select('s.title' . $fieldSuffix . ' AS `status`,
p.title' . $fieldSuffix . ' AS `priority`')
->from('#__helpdeskpro_tickets AS a')
->leftJoin('#__users AS b ON a.user_id = b.id')
->leftJoin('#__helpdeskpro_categories AS c ON a.category_id =
c.id')
->leftJoin('#__helpdeskpro_statuses AS s ON a.status_id =
s.id')
->leftJoin('#__helpdeskpro_priorities AS p ON a.priority_id =
p.id')
->where('a.id = ' . $this->state->id);
$db->setQuery($query);
$this->data = $db->loadObject();
if ($this->state->ticket_code)
{
$this->data->is_ticket_code = 1;
}
else
{
$this->data->is_ticket_code = 0;
}
}
/**
* Store the support ticket
*
* @param \OSL\Input\Input $input
*
* @return bool
*/
public function store($input, $ignore = [])
{
jimport('joomla.user.helper');
$db = $this->getDbo();
$query = $db->getQuery(true);
$user = $this->container->user;
if ($user->authorise('core.admin',
'com_helpdeskpro'))
{
$data = $input->post->getData(Input::INPUT_ALLOWRAW);
}
else
{
$data = $input->post->getData(Input::INPUT_ALLOWHTML);
}
// Basic data filtering
$data['subject'] =
trim($input->getString('subject'));
// Special case for message, we need to get it from input instead of from
$input->post
$data['message'] =
trim($input->getHtml('message'));
if (isset($data['name']))
{
$data['name'] = trim($input->getString('name'));
}
if (isset($data['email']))
{
$data['email'] =
trim($input->getString('email'));
}
$config = HelpdeskproHelper::getConfig();
$allowedFileTypes = explode('|',
$config->allowed_file_types);
for ($i = 0, $n = count($allowedFileTypes); $i < $n; $i++)
{
$allowedFileTypes[$i] = trim(strtoupper($allowedFileTypes[$i]));
}
$row = $this->getTable();
$row->bind($data);
if ($user->get('id') &&
!isset($data['name']))
{
$row->name = $user->get('name');
$row->email = $user->get('email');
$row->user_id = $user->get('id');
}
else
{
$query->select('id')
->from('#__users')
->where('email = ' .
$db->quote($data['email']));
$db->setQuery($query);
$row->user_id = $db->loadResult();
$role = HelpdeskproHelper::getUserRole();
if ($role == 'staff')
{
$row->staff_id = $user->id;
}
}
$uploadedFiles = $this->storeAttachment($input, $allowedFileTypes);
if (count($uploadedFiles['names']))
{
$row->attachments = implode('|',
$uploadedFiles['names']);
$row->original_filenames = implode('|',
$uploadedFiles['original_names']);
}
elseif ($attachments =
$this->container->session->get('hdp_uploaded_files'))
{
$row->attachments = $attachments;
$row->original_filenames =
$this->container->session->get('hdp_uploaded_files_original_names');
}
$row->status_id = $config->new_ticket_status_id;
$ticketCode = '';
while (true)
{
$ticketCode = strtolower(UserHelper::genRandomPassword(10));
$query->clear()
->select('COUNT(*)')
->from('#__helpdeskpro_tickets')
->where('ticket_code = ' . $db->quote($ticketCode));
$db->setQuery($query);
$total = $db->loadResult();
if (!$total)
{
break;
}
}
$row->ticket_code = $ticketCode;
$row->created_date = $row->modified_date = gmdate('Y-m-d
H:i:s');
$row->language = $this->container->language->getTag();
$row->store();
// Store ID of the ticket back to input
$input->set('id', $row->id);
//Store custom fields information for this ticket
$this->saveFieldsValue($row, $input);
//Trigger plugins
PluginHelper::importPlugin('helpdeskpro');
$this->container->app->triggerEvent('onAfterStoreTicket',
[$row]);
// Send notification email to admin and confirmation email to
registrants
HelpdeskproHelper::sendNewTicketNotificationEmails($row, $config);
if (!$user->id)
{
$input->set('ticket_code', $ticketCode);
}
}
/**
* Save custom fields value which users entered for the ticket
*
* @param \OSSolution\HelpdeskPro\Admin\Table\Ticket $ticket
* @param \OSL\Input\Input $input
*/
protected function saveFieldsValue($ticket, $input)
{
$fields = HelpdeskproHelper::getFields($ticket->category_id);
/* @var \OSSolution\HelpdeskPro\Admin\Table\Fieldvalue $row */
$row = $this->getTable('Fieldvalue');
foreach ($fields as $field)
{
if ($field->fieldtype == 'Heading' || $field->fieldtype
== 'Message')
{
continue;
}
$row->id = 0;
$row->ticket_id = $ticket->id;
$row->field_id = $field->id;
$fieldValue = trim($input->get($field->name, null,
'raw'));
if (is_array($fieldValue))
{
$fieldValue = implode(',', $fieldValue);
}
$row->field_value = $fieldValue;
$row->store();
}
}
/**
* Update ticket category
*
* @param array $data
*
* @return boolean
*/
public function updateCategory($data)
{
/* @var \OSSolution\HelpdeskPro\Admin\Table\Ticket $row */
$row = $this->getTable();
$row->load($data['id']);
$row->category_id = $data['new_value'];
$row->store();
}
/**
* Update ticket Status
*
* @param array $data
*
* @return boolean
*/
public function updateStatus($data)
{
$config = HelpdeskproHelper::getConfig();
/* @var \OSSolution\HelpdeskPro\Admin\Table\Ticket $row */
$row = $this->getTable();
$row->load($data['id']);
$oldTicketStatus = $row->status_id;
$newTicketStatus = $data['new_value'];
$row->status_id = $data['new_value'];
$row->store();
if ($newTicketStatus == $config->closed_ticket_status)
{
HelpdeskproHelper::sendTicketClosedEmail($row, $config);
}
else
{
HelpdeskproHelper::sendTicketStatusChangeEmail($row, $oldTicketStatus,
$newTicketStatus, $config);
}
}
/**
* Update ticket Status
*
* @param array $data
*
* @return boolean
*/
public function updatePriority($data)
{
/* @var \OSSolution\HelpdeskPro\Admin\Table\Ticket $row */
$row = $this->getTable();
$row->load($data['id']);
$row->priority_id = $data['new_value'];
$row->store();
}
/**
* Update ticket Label
*
* @param array $data
*
* @return boolean
*/
public function applyLabel($data)
{
/* @var \OSSolution\HelpdeskPro\Admin\Table\Ticket $row */
$row = $this->getTable();
$row->load($data['id']);
$row->label_id = $data['new_value'];
$row->store();
}
/**
* Save rating for the ticket
*
* @param $data
*
* @return bool
*/
public function saveRating($data)
{
$config = HelpdeskproHelper::getConfig();
/* @var \OSSolution\HelpdeskPro\Admin\Table\Ticket $row */
$row = $this->getTable();
$row->load($data['id']);
$row->rating = $data['new_value'];
$row->status_id = $config->closed_ticket_status;
// Send ticket closed email
HelpdeskproHelper::sendTicketClosedEmail($row, $config);
$row->store();
}
/**
* Method to add new ticket, call from API
*
* @param array $data
* @param array $attachments
*/
public function addNewTicket($data, $attachments)
{
jimport('joomla.user.helper');
$config = HelpdeskproHelper::getConfig();
$db = $this->getDbo();
$query = $db->getQuery(true);
$row = $this->getTable();
$row->bind($data, ['id']);
$query->select('*')
->from('#__users')
->where('email = ' .
$db->quote($data['email']));
$db->setQuery($query);
$user = $db->loadObject();
if ($user)
{
$row->name = $user->name;
$row->email = $user->email;
$row->user_id = $user->id;
}
if (!empty($attachments['names']))
{
$row->attachments = implode('|',
$attachments['names']);
$row->original_filenames = implode('|',
$attachments['original_names']);
}
$row->status_id = $config->new_ticket_status_id;
$ticketCode = '';
while (true)
{
$ticketCode = strtolower(UserHelper::genRandomPassword(10));
$query->clear()
->select('COUNT(*)')
->from('#__helpdeskpro_tickets')
->where('ticket_code = ' . $db->quote($ticketCode));
$db->setQuery($query);
$total = $db->loadResult();
if (!$total)
{
break;
}
}
$row->ticket_code = $ticketCode;
$row->created_date = $row->modified_date = gmdate('Y-m-d
H:i:s');
$row->language = $this->container->language->getTag();
$row->store();
//Trigger plugins
PluginHelper::importPlugin('helpdeskpro');
$this->container->app->triggerEvent('onAfterStoreTicket',
[$row]);
// Send notification email to admin and confirmation email to
registrants
HelpdeskproHelper::sendNewTicketNotificationEmails($row, $config);
}
/**
* Method to add comment to a ticket by API
*
* @param array $data
* @param array $attachments
*/
public function addTicketComment($data, $attachments)
{
$config = HelpdeskproHelper::getConfig();
/* @var \OSSolution\HelpdeskPro\Admin\Table\Ticket $ticket */
$ticket = $this->getTable();
/* @var \OSSolution\HelpdeskPro\Admin\Table\Message $row */
$row = $this->getTable('Message');
$row->message = $data['message'];
$row->user_id = $data['user_id'];
$row->date_added = gmdate('Y-m-d H:i:s');
$row->ticket_id = $data['ticket_id'];
if (!empty($attachments['names']))
{
$row->attachments = implode('|',
$attachments['names']);
$row->original_filenames = implode('|',
$attachments['original_names']);
}
$row->store();
if (!$ticket->load($data['ticket_id']))
{
// Invalid ticket, do not process it further
return;
}
// Do not allow adding comment to closed ticket
if ($ticket->status_id == $config->closed_ticket_status)
{
return;
}
if ($row->user_id == $ticket->user_id)
{
$isCustomerAddComment = true;
}
else
{
$isCustomerAddComment = false;
}
if ($isCustomerAddComment)
{
$ticket->status_id =
$config->ticket_status_when_customer_add_comment;
}
else
{
$ticket->status_id =
$config->ticket_status_when_admin_add_comment;
}
$ticket->modified_date = gmdate('Y-m-d H:i:s');
$ticket->store();
//Trigger plugins
PluginHelper::importPlugin('helpdeskpro');
$this->container->app->triggerEvent('onAfterStoreComment',
[$row, $ticket]);
//Need to send email to users
if ($isCustomerAddComment)
{
HelpdeskproHelper::sendTicketUpdatedEmailToManagers($row, $ticket,
$config);
}
else
{
HelpdeskproHelper::sendTicketUpdatedEmailToCustomer($row, $ticket,
$config);
}
}
/**
* Add comment to the ticket
*
* @param \OSL\Input\Input $input
* @param bool $closeTicket
*
*/
public function addComment($input, $closeTicket = false)
{
$user = $this->container->user;
$config = HelpdeskproHelper::getConfig();
/* @var \OSSolution\HelpdeskPro\Admin\Table\Ticket $ticket */
$ticket = $this->getTable();
/* @var \OSSolution\HelpdeskPro\Admin\Table\Message $row */
$row = $this->getTable('Message');
$allowedFileTypes = explode('|',
$config->allowed_file_types);
for ($i = 0, $n = count($allowedFileTypes); $i < $n; $i++)
{
$allowedFileTypes[$i] = trim(strtoupper($allowedFileTypes[$i]));
}
$row->message = $input->getHtml('message');
$ticket->load($input->post->getInt('id'));
if ($user->id)
{
$row->user_id = $user->get('id');
}
else
{
if (isset($data['ticket_code']))
{
$row->user_id = $ticket->user_id;
}
}
$row->date_added = gmdate('Y-m-d H:i:s');
$row->ticket_id = $ticket->id;
$uploadedFiles = $this->storeAttachment($input, $allowedFileTypes);
if (count($uploadedFiles['names']))
{
$row->attachments = implode('|',
$uploadedFiles['names']);
$row->original_filenames = implode('|',
$uploadedFiles['original_names']);
}
elseif ($attachments =
$this->container->session->get('hdp_uploaded_files'))
{
$row->attachments = $attachments;
$row->original_filenames =
$this->container->session->get('hdp_uploaded_files_original_names');
}
$row->store();
if ($row->user_id == $ticket->user_id ||
isset($data['ticket_code']))
{
$isCustomerAddComment = true;
}
else
{
$isCustomerAddComment = false;
}
if ($closeTicket)
{
$ticket->status_id = $config->closed_ticket_status;
}
elseif ($isCustomerAddComment)
{
$ticket->status_id =
$config->ticket_status_when_customer_add_comment;
}
else
{
$ticket->status_id =
$config->ticket_status_when_admin_add_comment;
}
$ticket->modified_date = gmdate('Y-m-d H:i:s');
$ticket->store();
//Trigger plugins
PluginHelper::importPlugin('helpdeskpro');
$this->container->app->triggerEvent('onAfterStoreComment',
[$row, $ticket]);
//Need to send email to users
if ($isCustomerAddComment)
{
HelpdeskproHelper::sendTicketUpdatedEmailToManagers($row, $ticket,
$config);
}
else
{
HelpdeskproHelper::sendTicketUpdatedEmailToCustomer($row, $ticket,
$config);
}
if ($closeTicket)
{
HelpdeskproHelper::sendTicketClosedEmail($ticket, $config);
}
}
/**
* Get all comments of the current ticket
*
* @return array
*/
public function getMessages()
{
if ($this->state->id)
{
$db = $this->getDbo();
$query = $db->getQuery(true);
$query->select('a.*, b.name')
->from('#__helpdeskpro_messages AS a')
->leftJoin('#__users AS b ON a.user_id = b.id')
->where('a.ticket_id = ' . $this->state->id)
->order('id DESC');
$db->setQuery($query);
return $db->loadObjectList();
}
return [];
}
/**
* Get all custom fields value for a ticket
*
* @return array
*/
public function getFieldsValue()
{
$fieldValues = [];
if ($this->state->id)
{
$db = $this->getDbo();
$query = $db->getQuery(true);
$query->select('field_id, field_value')
->from('#__helpdeskpro_field_value')
->where('ticket_id = ' . $this->state->id);
$db->setQuery($query);
$rows = $db->loadObjectList();
foreach ($rows as $row)
{
$fieldValues[$row->field_id] = $row->field_value;
}
}
return $fieldValues;
}
/**
* Convert a support ticket to a knowledge base article
*
* @throws \Exception
*/
public function convertTicketToArticle()
{
$item = $this->getData();
$messages = $this->getMessages();
$messages = array_reverse($messages);
if (!$item)
{
throw new \Exception(Text::_('HDP_INVALID_TICKET'));
}
$db = $this->getDbo();
$query = $db->getQuery(true);
$rootUri = Uri::root(true);
$config = HelpdeskproHelper::getConfig();
$user = new User;
$item->date_added = $item->created_date;
array_unshift($messages, $item);
$layoutData = [
'messages' => $messages,
'user' => $user,
'rootUri' => $rootUri,
'config' => $config,
];
$row = $this->getTable('article');
$query->select('id')
->from('#__helpdeskpro_articles')
->where('ticket_id = ' . $item->id);
$db->setQuery($query);
$id = (int) $db->loadResult();
if ($id)
{
$row->load($id);
}
$row->category_id = $item->category_id;
$row->ticket_id = $item->id;
$row->title = '[#' . $item->id . '] - ' .
$item->subject;
$row->alias = ApplicationHelper::stringURLSafe($row->title);
$row->text = '<table
class="adminform">' .
HelpdeskproHelperHtml::loadCommonLayout('common/tmpl/ticket_comments.php',
$layoutData) . '</table>';
$row->published = 1;
$query->clear()
->select('MAX(ordering)')
->from('#__helpdeskpro_articles')
->where('category_id = ' . $row->category_id);
$db->setQuery($query);
$row->ordering = (int) $db->loadResult() + 1;
$row->store();
}
/**
* Delete all the tickets related data before tickets deleted
*
* @param array $cid Ids of deleted record
*/
protected function beforeDelete($cid)
{
$db = $this->getDbo();
$query = $db->getQuery(true);
$attachmentsPath = JPATH_ROOT .
'/media/com_helpdeskpro/attachments/';
$row = $this->getTable();
foreach ($cid as $ticketId)
{
$row->load($ticketId);
// Delete ticket attachments
if ($row->attachments)
{
$files = explode('|', $row->attachments);
foreach ($files as $file)
{
if ($file && File::exists($attachmentsPath . $file))
{
File::delete($attachmentsPath . $file);
}
}
}
// Delete attachments in messages/comments of the ticket
$query->clear()
->select('attachments')
->from('#__helpdeskpro_messages')
->where('ticket_id = ' . $ticketId);
$db->setQuery($query);
$attachments = $db->loadColumn();
foreach ($attachments as $attachment)
{
if ($attachment)
{
$files = explode('|', $attachment);
foreach ($files as $file)
{
if ($file && File::exists($attachmentsPath . $file))
{
File::delete($attachmentsPath . $file);
}
}
}
}
// Delete ticket message
$query->clear()
->delete('#__helpdeskpro_messages')
->where('ticket_id IN (' . implode(',', $cid) .
')');
$db->setQuery($query);
$db->execute();
}
}
/**
* Store attachments which user uploaded
*
* @param \OSL\Input\Input $input
* @param array $allowedFileTypes
*
* @return array
*/
private function storeAttachment($input, $allowedFileTypes)
{
$app = $this->container->app;
$attachmentsPath = JPATH_ROOT .
'/media/com_helpdeskpro/attachments';
$uploadedFiles = [
'names' => [],
'original_names' => [],
];
$attachments = $input->files->get('attachment', [],
'raw');
foreach ($attachments as $attachment)
{
$name = File::makeSafe($attachment['name']);
if (empty($name))
{
continue;
}
$fileExt = strtoupper(File::getExt($name));
if (in_array($fileExt, $allowedFileTypes))
{
if (File::exists($attachmentsPath . '/' . $name))
{
$fileName = File::stripExt($name) . '_' . uniqid() .
'.' . $fileExt;
}
else
{
$fileName = $name;
}
// Fix upload attachments causes by change in Joomla 3.4.4
$uploaded = File::upload($attachment['tmp_name'],
$attachmentsPath . '/' . $fileName, false, true);
if ($uploaded)
{
$uploadedFiles['names'][] = $fileName;
$uploadedFiles['original_names'][] = $name;
}
else
{
$app->enqueueMessage(Text::sprintf('HDP_UPLOAD_FILE_FAILED',
$attachment['name']), 'warning');
}
}
else
{
$app->enqueueMessage(Text::sprintf('HDP_FILETYPE_NOT_ALLOWED',
$attachment['name'], implode(',', $allowedFileTypes)),
'warning');
}
}
return $uploadedFiles;
}
}