Spade

Mini Shell

Directory:~$ /home/lmsyaran/www/administrator/components/com_helpdeskpro/Controller/
Upload File

[Home] [System Details] [Kill Me]
Current File:~$ /home/lmsyaran/www/administrator/components/com_helpdeskpro/Controller/Ticket.php

<?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\Controller;

use Joomla\CMS\Mail\MailHelper;
use Joomla\CMS\Captcha\Captcha;
use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Filesystem\File;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\CMS\Router\Route;
use OSL\Container\Container;
use OSL\Controller\Download;
use OSSolution\HelpdeskPro\Site\Helper\Database as
HelpdeskproHelperDatabase;
use OSSolution\HelpdeskPro\Site\Helper\Helper as HelpdeskproHelper;
use OSSolution\HelpdeskPro\Site\Helper\Route as RouteHelper;

defined('_JEXEC') or die;

class Ticket extends Controller
{
	use Download;

	/**
	 * Constructor.
	 *
	 * @param   array  $config  An optional associative array of configuration
settings.
	 *
	 * @see OSFControlleAdmin
	 */
	public function __construct(Container $container, array $config = [])
	{
		parent::__construct($container, $config);

		$this->registerTask('comment_and_close',
'add_comment');
	}

	/**
	 * Display form allows adding a new support ticket
	 */
	public function add()
	{
		$this->input->set('layout', 'form');

		parent::add();
	}

	/**
	 * Override allow add method to control subject support ticket permission
in the frontend
	 *
	 * @param   array  $data
	 *
	 * @return bool
	 */
	protected function allowAdd($data = [])
	{
		if ($this->container->app->isClient('site'))
		{
			return true;
		}

		return parent::allowAdd($data);
	}

	/**
	 * Store a support ticket
	 *
	 * @throws \Exception
	 */
	public function save()
	{
		$this->csrfProtection();

		$config = HelpdeskproHelper::getConfig();
		$app    = $this->container->app;
		$user   = $this->container->user;
		$input  = $this->input;

		if (!$config->enable_captcha || ($user->id &&
$config->enable_captcha == '2'))
		{
			$enableCaptcha = false;
		}
		else
		{
			$enableCaptcha = true;
		}

		if ($enableCaptcha && $app->isClient('site')
&& !$this->validateCaptcha())
		{
			$app->enqueueMessage(Text::_('HD_INVALID_CAPTCHA_ENTERED'),
'warning');
			$input->set('view', 'ticket');
			$input->set('layout', 'form');

			$this->display();

			return;
		}

		$post = $input->post->getData();

		// Perform some basic validation when ticket is submitted from frontend
		if ($app->isClient('site'))
		{
			$errors = [];
			$user   = $this->container->user;

			if (!$user->id &&
!$config->allow_public_user_submit_ticket)
			{
				throw new \Exception(Text::_('HDP_LOGIN_TO_SUBMIT_TICKET'),
403);
			}

			if (!$user->id)
			{
				// Make sure the name and email address is valid
				if (empty($post['name']))
				{
					$errors[] = Text::_('HDP_ENTER_YOUR_NAME');
				}

				$email = $post['email'];
				if (empty($email))
				{
					$errors[] = Text::_('HDP_ENTER_YOUR_EMAIL');
				}

				if ($email && !MailHelper::isEmailAddress($email))
				{
					$errors[] = Text::_('HDP_INVALID_EMAIL_ADDRESS');
				}
			}

			if (empty($post['subject']))
			{
				$errors[] = Text::_('HDP_ENTER_SUBJECT');
			}

			if (empty($post['category_id']))
			{
				$errors[] = Text::_('HDP_SELECT_A_CATEGORY');
			}

			$rowFields =
HelpdeskproHelper::getFields($post['category_id'],
['required = 1']);

			foreach ($rowFields as $field)
			{
				if (empty($post[$field->name]))
				{
					$errors[] = Text::sprintf('HDP_FIELD_NAME_IS_REQUIRED',
$field->title);
				}
			}

			// OK, if error founds, we need to redirect back to submit ticket page
			if (count($errors))
			{
				foreach ($errors as $error)
				{
					$app->enqueueMessage($error, 'error');
				}

				$input->set('view', 'ticket');
				$input->set('layout', 'form');

				$this->display();

				return;
			}

		}

		$input->post->set('message',
ComponentHelper::filterText($post['message']));

		/* @var \OSSolution\HelpdeskPro\Admin\Model\Ticket $model */
		$model = $this->getModel('ticket');

		try
		{
			$model->store($input);
			$msg = Text::_('HDP_TICKET_SUBMITTED');
		}
		catch (\Exception $e)
		{
			$msg = Text::_('HDP_ERROR_SAVING_TICKET');
		}

		if ($app->isClient('administrator'))
		{
			$this->setRedirect('index.php?option=com_helpdeskpro&view=tickets',
$msg);
		}
		else
		{
			$user = $this->container->user;

			if (!$user->id)
			{
				$this->setRedirect(Route::_(RouteHelper::getTicketRoute($input->get('ticket_code'),
false), false), $msg);
			}
			else
			{
				$this->setRedirect(Route::_(RouteHelper::getTicketRoute($input->getInt('id')),
false), $msg);
			}
		}
	}

	/**
	 * Add comment to support ticket
	 *
	 * @throws \Exception
	 */
	public function add_comment()
	{
		$this->csrfProtection();

		/* @var \JApplicationSite $app */
		$app    = $this->container->app;
		$user   = $this->container->user;
		$input  = $this->input;
		$config = HelpdeskproHelper::getConfig();

		if (!$config->allow_public_user_submit_ticket &&
!$user->id)
		{
			if ($app->isClient('administrator'))
			{
				$return =
base64_encode('index.php?option=com_helpdeskpro&view=ticket&id='
. $input->getInt('id'));
			}
			else
			{
				$return =
base64_encode(RouteHelper::getTicketRoute($input->getInt('id')));
			}

			$app->redirect(Route::_('index.php?option=com_users&view=login&return='
. $return), Text::_('HDP_SESSION_EXPIRED'));
		}

		if (!$config->enable_captcha || ($user->id &&
$config->enable_captcha == '2'))
		{
			$enableCaptcha = false;
		}
		else
		{
			$enableCaptcha = true;
		}

		if ($enableCaptcha && $app->isClient('site')
&& !$this->validateCaptcha())
		{
			$app->enqueueMessage(Text::_('HD_INVALID_CAPTCHA_ENTERED'),
'warning');
			$this->input->set('view', 'ticket');
			$this->input->set('layout', 'default');
			$this->input->set('captcha_invalid', 1);
			$this->display();

			return;
		}

		$input->post->set('message',
ComponentHelper::filterText($input->post->getString('message')));
		$model = $this->getModel('ticket');

		$task = $this->getTask();

		if ($task == 'add_comment')
		{
			$closeTicket = false;
		}
		else
		{
			$closeTicket = true;
		}

		/* @var \OSSolution\HelpdeskPro\Admin\Model\Ticket $model */
		try
		{
			$model->addComment($input, $closeTicket);

			if ($closeTicket)
			{
				$msg = Text::_('HDP_COMMENT_ADDED_TICKET_CLOSED');
			}
			else
			{
				$msg = Text::_('HDP_COMMENT_ADDED');
			}
		}
		catch (\Exception $e)
		{
			$msg = Text::_('HDP_ERROR_ADDING_COMMENT');
		}

		$ticketCode = $input->post->getString('ticket_code');
		$ticketId   = $input->post->getInt('id', 0);

		if ($ticketCode)
		{
			$this->setRedirect(Route::_(RouteHelper::getTicketRoute($ticketCode,
false), false), $msg);
		}
		else
		{
			if ($app->isClient('administrator'))
			{
				if ($closeTicket)
				{
					$this->setRedirect('index.php?option=com_helpdeskpro&view=tickets',
$msg);
				}
				else
				{
					$this->setRedirect('index.php?option=com_helpdeskpro&view=ticket&id='
. $ticketId, $msg);
				}
			}
			else
			{
				if ($closeTicket)
				{
					$this->setRedirect(Route::_(RouteHelper::getTicketsRoute(), false),
$msg);
				}
				else
				{
					$this->setRedirect(Route::_(RouteHelper::getTicketRoute($ticketId),
false), $msg);
				}
			}
		}
	}

	/**
	 * Change category for the ticket
	 */
	public function update_category()
	{
		$this->csrfProtection();

		$post  = $this->input->post->getData();
		$model = $this->getModel('ticket');

		/* @var \OSSolution\HelpdeskPro\Admin\Model\Ticket $model */
		try
		{
			$model->updateCategory($post);
			$msg = Text::_('HDP_TICKET_CATEGORY_UPDATED');
		}
		catch (\Exception $e)
		{
			$msg = Text::_('HDP_ERROR_UPDATE_TICKET_CATEGORY');
		}

		if (isset($post['ticket_code']))
		{
			$this->setRedirect(Route::_(RouteHelper::getTicketRoute($post['ticket_code'],
false), false));
		}
		else
		{
			if
($this->container->app->isClient('administrator'))
			{
				$this->setRedirect('index.php?option=com_helpdeskpro&view=ticket&id='
. $post['id'], $msg);
			}
			else
			{
				$this->setRedirect(Route::_(RouteHelper::getTicketRoute($post['id']),
false), $msg);
			}
		}
	}

	/**
	 * Update ticket status
	 *
	 * @throws \Exception
	 */
	public function update_status()
	{
		$this->csrfProtection();

		$app  = $this->container->app;
		$post = $this->input->post->getData();

		/* @var \OSSolution\HelpdeskPro\Admin\Model\Ticket $model */
		$model = $this->getModel('ticket');
		try
		{
			$model->updateStatus($post);
			$msg = Text::_('HDP_TICKET_STATUS_UPDATED');
		}
		catch (\Exception $e)
		{
			$msg = Text::_('HDP_ERROR_UPDATING_TICKET_STATUS');
		}

		if (isset($post['ticket_code']))
		{
			$this->setRedirect(Route::_(RouteHelper::getTicketRoute($post['ticket_code'],
false), false), $msg);
		}
		else
		{
			if ($app->isClient('administrator'))
			{
				$this->setRedirect('index.php?option=com_helpdeskpro&view=ticket&id='
. $post['id'], $msg);
			}
			else
			{
				$this->setRedirect(Route::_(RouteHelper::getTicketRoute($post['id']),
false), $msg);
			}
		}
	}

	/**
	 * Update ticket priority
	 *
	 * @throws \Exception
	 */
	public function update_priority()
	{
		$this->csrfProtection();

		$app  = $this->container->app;
		$post = $this->input->post->getData();

		/* @var \OSSolution\HelpdeskPro\Admin\Model\Ticket $model */
		$model = $this->getModel('ticket');

		try
		{
			$model->updatePriority($post);
			$msg = Text::_('HDP_TICKET_PRIORITY_UPDATED');
		}
		catch (\Exception $e)
		{
			$msg = Text::_('HDP_ERROR_UPDATING_PRIORITY');
		}

		if (isset($post['ticket_code']))
		{
			$this->setRedirect(Route::_(RouteHelper::getTicketRoute($post['ticket_code'],
false), false), $msg);
		}
		else
		{
			if ($app->isClient('administrator'))
			{
				$this->setRedirect('index.php?option=com_helpdeskpro&view=ticket&id='
. $post['id'], $msg);
			}
			else
			{
				$this->setRedirect(Route::_(RouteHelper::getTicketRoute($post['id']),
false), $msg);
			}
		}
	}

	/**
	 * Apply label to a support ticket
	 *
	 * @throws \Exception
	 */
	public function apply_label()
	{
		$this->csrfProtection();

		$post = $this->input->post->getData();

		/* @var \OSSolution\HelpdeskPro\Admin\Model\Ticket $model */
		$model = $this->getModel('ticket');

		try
		{
			$model->applyLabel($post);
			$msg = Text::_('HDP_TICKET_LABEL_UPDATED');
		}
		catch (\Exception $e)
		{
			$msg = Text::_('HDP_ERROR_UPDATING_TICKET_LABEL');
		}

		$this->setRedirect('index.php?option=com_helpdeskpro&view=ticket&id='
. $post['id'], $msg);
	}

	/**
	 * Save rating and close the ticket
	 */
	public function save_rating()
	{
		$this->csrfProtection();

		$post = $this->input->post->getData();

		/* @var \OSSolution\HelpdeskPro\Admin\Model\Ticket $model */
		$model = $this->getModel('ticket');

		try
		{
			$model->saveRating($post);
			$msg = Text::_('HDP_RATING_SAVED');
		}
		catch (\Exception $e)
		{
			$msg = Text::_('HDP_ERROR_SAVING_RATING');
		}

		if (isset($post['ticket_code']))
		{
			$this->setRedirect(Route::_(RouteHelper::getTicketRoute($post['ticket_code'],
false), false), $msg);
		}
		else
		{
			if
($this->container->app->isClient('administrator'))
			{
				$this->setRedirect('index.php?option=com_helpdeskpro&view=ticket&id='
. $post['id'], $msg);
			}
			else
			{
				$this->setRedirect(Route::_(RouteHelper::getTicketRoute($post['id']),
false), $msg);
			}
		}
	}

	/**
	 * Assign ticket to a staff
	 */
	public function assign_ticket()
	{
		$user = $this->container->user;

		if (!$user->authorise('helpdeskpro.assignticket',
'com_helpdeskpro'))
		{
			return;
		}

		$db     = $this->container->db;
		$query  = $db->getQuery(true);
		$userId = $this->input->getInt('user_id', 0);
		$id     = $this->input->getInt('id', 0);

		if ($id)
		{
			//update user id ticket
			$query->update("#__helpdeskpro_tickets")
				->set("staff_id=" . (int) $userId)
				->where("id=" . $id);
			$db->setQuery($query);
			$db->execute();

			// Send notification email to user
			if ($userId)
			{
				$query->clear()
					->select('*')
					->from('#__helpdeskpro_tickets')
					->where('id = ' . (int) $id);
				$db->setQuery($query);
				$row    = $db->loadObject();
				$config = HelpdeskproHelper::getConfig();
				HelpdeskproHelper::sendTicketAssignedEmails($row, $config);
			}
		}
	}

	/**
	 * Update a comment
	 *
	 * @throws \Exception
	 */
	public function update_comment()
	{
		$user      = $this->container->user;
		$messageId = $this->input->getInt('message_id', 0);

		if (HelpdeskproHelper::canUpdateComment($user, $messageId))
		{
			$db         = $this->container->db;
			$query      = $db->getQuery(true);
			$newMessage =
$db->quote($this->input->getHtml('new_message'));
			$query->update('#__helpdeskpro_messages')
				->set('message=' . $newMessage)
				->where('id=' . (int) $messageId);
			$db->setQuery($query);
			$db->execute();
		}

		$this->container->app->close();
	}

	/**
	 * Remove comment from a ticket
	 *
	 * @throws \Exception
	 */
	public function remove_comment()
	{
		$user      = $this->container->user;
		$messageId = $this->input->getInt('message_id', 0);

		if (HelpdeskproHelper::canDeleteComment($user, $messageId))
		{
			$db    = $this->container->db;
			$query = $db->getQuery(true);
			$query->delete('#__helpdeskpro_messages')
				->where('id=' . (int) $messageId);
			$db->setQuery($query);
			$db->execute();
		}

		$this->container->app->close();
	}

	/**
	 * Convert the current open ticket to a knowledge article
	 */
	public function convert_to_kb()
	{
		/* @var \OSSolution\HelpdeskPro\Admin\Model\Ticket $model */
		$model = $this->getModel();

		try
		{
			$model->convertTicketToArticle();
			$this->setMessage(Text::_('HDP_CONVERT_TICKET_SUCCESS'));
		}
		catch (\Exception $e)
		{
			$this->setMessage($e->getMessage(), 'error');
		}

		$this->setRedirect('index.php?option=com_helpdeskpro&view=ticket&id='
. $this->input->getInt('id', 0));
	}

	/**
	 * Export support ticket into a csv file
	 */
	public function export()
	{
		$config = HelpdeskproHelper::getConfig();

		$rowStatuses = HelpdeskproHelperDatabase::getAllStatuses();
		$statusList  = [];

		foreach ($rowStatuses as $status)
		{
			$statusList[$status->id] = $status->title;
		}

		$rowPriorities = HelpdeskproHelperDatabase::getAllPriorities();
		$priorityList  = [];

		foreach ($rowPriorities as $priority)
		{
			$priorityList[$priority->id] = $priority->title;
		}

		$rowFields = HelpdeskproHelper::getAllFields();

		/* @var \OSSolution\HelpdeskPro\Admin\Model\Tickets $model */
		$model = $this->getModel('tickets');
		$rows  = $model->getData();

		if (count($rows))
		{
			$fieldValues = $model->getFieldsData($rowFields);

			$results_arr   = [];
			$results_arr[] = Text::_('HDP_TITLE');
			$results_arr[] = Text::_('HDP_MESSAGE');
			$results_arr[] = Text::_('HDP_CATEGORY');
			$results_arr[] = Text::_('HDP_USER');
			$results_arr[] = Text::_('HDP_EMAIL');
			$results_arr[] = Text::_('HDP_CREATED_DATE');
			$results_arr[] = Text::_('HDP_MODIFIED_DATE');
			$results_arr[] = Text::_('HDP_STATUS');
			$results_arr[] = Text::_('HDP_PRIORITY');
			$results_arr[] = Text::_('HDP_ID');

			for ($i = 0, $n = count($rowFields); $i < $n; $i++)
			{
				$results_arr[] = $rowFields[$i]->title;
			}

			$csv_output = implode(",", $results_arr);

			foreach ($rows as $row)
			{
				$results_arr   = [];
				$results_arr[] = $row->subject;
				$results_arr[] = $row->message;
				$results_arr[] = $row->category_title;

				if ($row->username)
				{
					$results_arr[] = $row->name . '(' . $row->username .
')';
				}
				else
				{
					$results_arr[] = $row->name;
				}

				$results_arr[] = $row->email;
				$results_arr[] = HTMLHelper::_('date', $row->created_date,
$config->date_format);
				$results_arr[] = HTMLHelper::_('date',
$row->modified_date, $config->date_format);
				$results_arr[] = @$statusList[$row->status_id];
				$results_arr[] = @$priorityList[$row->priority_id];
				$results_arr[] = $row->id;

				for ($i = 0, $n = count($rowFields); $i < $n; $i++)
				{
					$fieldId = $rowFields[$i]->id;

					if (!empty($fieldValues[$row->id][$fieldId]))
					{
						$results_arr[] = $fieldValues[$row->id][$fieldId];
					}
					else
					{
						$results_arr[] = "";
					}
				}

				$csv_output .= "\n\"" .
implode("\",\"", $results_arr) . "\"";
			}

			$csv_output .= "\n";

			if (preg_match('Opera(/| )([0-9].[0-9]{1,2})',
$_SERVER['HTTP_USER_AGENT']))
			{
				$UserBrowser = "Opera";
			}
			elseif (preg_match('MSIE ([0-9].[0-9]{1,2})',
$_SERVER['HTTP_USER_AGENT']))
			{
				$UserBrowser = "IE";
			}
			else
			{
				$UserBrowser = '';
			}

			$mime_type = ($UserBrowser == 'IE' || $UserBrowser ==
'Opera') ? 'application/octetstream' :
'application/octet-stream';
			$filename  = "tickets";
			@ob_end_clean();
			ob_start();
			header('Content-Type: ' . $mime_type);
			header('Expires: ' . gmdate('D, d M Y H:i:s') .
' GMT');

			if ($UserBrowser == 'IE')
			{
				header('Content-Disposition: attachment; filename="' .
$filename . '.csv"');
				header('Cache-Control: must-revalidate, post-check=0,
pre-check=0');
				header('Pragma: public');
			}
			else
			{
				header('Content-Disposition: attachment; filename="' .
$filename . '.csv"');
				header('Pragma: no-cache');
			}

			echo $csv_output;
			exit();
		}
	}

	/**
	 * Download a ticket attachment
	 *
	 * @throws \Exception
	 */
	public function download_attachment()
	{
		$fileName         = $this->input->getString('filename',
'');
		$fileName         = basename($fileName);
		$originalFilename =
$this->input->getString('original_filename',
'');
		$originalFilename = File::makeSafe($originalFilename);

		if (file_exists(JPATH_ROOT .
'/media/com_helpdeskpro/attachments/' . $fileName))
		{
			$fileExt = File::getExt($fileName);

			$imageFileTypes = ['gif', 'jpg', 'jpeg',
'png', 'txt', 'csv', 'bmp'];

			if (in_array(strtolower($fileExt), $imageFileTypes))
			{
				$inline = true;
			}
			else
			{
				$inline = false;
			}

			$this->processDownloadFile(JPATH_ROOT .
'/media/com_helpdeskpro/attachments/' . $fileName,
$originalFilename, $inline);
		}
		else
		{
			$this->setRedirect('index.php?option=com_helpdeskpro&view=tickets');
			$this->setMessage(Text::_('HDP_FILE_NOT_EXIST'),
'warning');
		}
	}

	/**
	 * Validate captcha
	 *
	 * @return bool
	 */
	protected function validateCaptcha()
	{
		/* @var $app \JApplicationSite */
		$app = $this->container->get('app');

		$captchaPlugin = $app->getParams()->get('captcha',
$this->container->appConfig->get('captcha'));

		if (!$captchaPlugin)
		{
			// Hardcode to recaptcha, reduce support request
			$captchaPlugin = 'recaptcha';
		}

		$plugin = PluginHelper::getPlugin('captcha', $captchaPlugin);

		$captchaValid = true;

		if ($plugin)
		{
			try
			{
				$captchaValid =
Captcha::getInstance($captchaPlugin)->checkAnswer($this->input->post->get('recaptcha_response_field',
'', 'string'));
			}
			catch (\Exception $e)
			{
				// Captcha is not checked, return false
				$captchaValid = false;
			}
		}

		return $captchaValid;
	}

	/**
	 * Method to upload file uploaded by dropzone JS
	 */
	public function upload()
	{
		if (!\JSession::checkToken('get'))
		{
			return;
		}

		$config = HelpdeskproHelper::getConfig();

		if (!$config->enable_attachment)
		{
			return;
		}

		if (!$this->container->user->id &&
!$config->allow_public_user_submit_ticket)
		{
			return;
		}

		$session = $this->container->session;

		$allowedFileTypes = explode('|',
$config->allowed_file_types);

		for ($i = 0, $n = count($allowedFileTypes); $i < $n; $i++)
		{
			$allowedFileTypes[$i] = trim(strtoupper($allowedFileTypes[$i]));
		}

		$attachmentsPath = JPATH_ROOT .
'/media/com_helpdeskpro/attachments';

		$attachment = $this->input->files->get('file', [],
'raw');

		$name = File::makeSafe($attachment['name']);

		if (empty($name))
		{
			return;
		}

		$fileExt = strtoupper(File::getExt($name));

		if (!in_array($fileExt, $allowedFileTypes))
		{
			return;
		}

		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);

		$uploadedFiles              =
$session->get('hdp_uploaded_files', '');
		$uploadedFilesOriginalNames =
$session->get('hdp_uploaded_files_original_names',
'');

		if ($uploadedFiles)
		{
			$uploadedFiles              = explode('|', $uploadedFiles);
			$uploadedFilesOriginalNames = explode('|',
$uploadedFilesOriginalNames);
		}
		else
		{
			$uploadedFiles              = [];
			$uploadedFilesOriginalNames = [];
		}

		if ($uploaded)
		{
			$uploadedFiles[]              = $fileName;
			$uploadedFilesOriginalNames[] = $name;
		}

		$session->set('hdp_uploaded_files', implode('|',
$uploadedFiles));
		$session->set('hdp_uploaded_files_original_names',
implode('|', $uploadedFilesOriginalNames));
	}
}