Spade
Mini Shell
| Directory:~$ /proc/self/root/home/lmsyaran/public_html/j3/plugins/system/hdpreplyviaemail/ |
| [Home] [System Details] [Kill Me] |
<?php
/**
* @version 4.3.0
* @package Joomla
* @subpackage helpdeskpro Pro
* @author Tuan Pham Ngoc
* @copyright Copyright (C) 2013 - 2021 Ossolution Team
* @license GNU/GPL, see LICENSE.php
*/
use Ddeboer\Imap\Search\Date\Since;
use Ddeboer\Imap\Search\Flag\Unanswered;
use Ddeboer\Imap\SearchExpression;
use Ddeboer\Imap\Server;
use EmailReplyParser\Parser\EmailParser;
use Joomla\CMS\Filesystem\File;
use Joomla\CMS\Plugin\CMSPlugin;
use OSSolution\HelpdeskPro\Site\Helper\Helper as HelpdeskproHelper;
defined('_JEXEC') or die;
class plgSystemHDPReplyViaEmail extends CMSPlugin
{
/**
* Application object.
*
* @var JApplicationCms
*/
protected $app;
/**
* Database object.
*
* @var JDatabaseDriver
*/
protected $db;
/**
* Constructor
*
* @param object &$subject The object to observe
* @param array $config
*/
public function __construct(&$subject, $config = array())
{
if (!file_exists(JPATH_ROOT .
'/components/com_helpdeskpro/helpdeskpro.php'))
{
return;
}
parent::__construct($subject, $config);
}
/**
* Protect access to articles
*
* @return void
* @throws Exception
*/
public function onAfterRoute()
{
if (version_compare(PHP_VERSION, '7.2.0', '<'))
{
$this->app->enqueueMessage('Reply Via Email Only Works With
PHP 7.2.0+');
return;
}
if (!$this->canRun())
{
return;
}
//Store last run time
$db = $this->db;
$this->params->set('last_run', time());
$params = $this->params->toString();
$query = $db->getQuery(true)
->update('#__extensions')
->set('params = ' . $db->quote($params))
->where($db->quoteName('element') . '=' .
$db->quote($this->_name))
->where($db->quoteName('folder') . '=' .
$db->quote('system'));
try
{
// Lock the tables to prevent multiple plugin executions causing a race
condition
$db->lockTable('#__extensions');
}
catch (Exception $e)
{
// If we can't lock the tables it's too risk continuing
execution
return;
}
try
{
// Update the plugin parameters
$result = $db->setQuery($query)->execute();
$this->clearCacheGroups(array('com_plugins'), array(0,
1));
}
catch (Exception $exc)
{
// If we failed to execute
$db->unlockTables();
$result = false;
}
try
{
// Unlock the tables after writing
$db->unlockTables();
}
catch (Exception $e)
{
// If we can't lock the tables assume we have somehow failed
$result = false;
}
// Abort on failure
if (!$result)
{
return;
}
$this->fetNewEmails();
}
/**
* Fetch emails and create ticket
*
* @throws Exception
*/
private function fetNewEmails()
{
require_once JPATH_ROOT .
'/plugins/system/hdpreplyviaemail/lib/vendor/autoload.php';
$host = $this->params->get('host');
$port = $this->params->get('port', 993);
$username = $this->params->get('username');
$password = $this->params->get('password');
$requiredParams = [$host, $username, $password];
// Make sure all required parameters are provided before processing it
further
foreach ($requiredParams as $param)
{
if (!strlen(trim($param)))
{
return;
}
}
// Attempt to connect to the mailbox
try
{
// $server = new Server('mail.joomdonation.com', 993,
'/imap/ssl/novalidate-cert');
$server = new Server($host, $port, $this->buildFlags());
// $connection is instance of \Ddeboer\Imap\Connection
// $connection =
$server->authenticate('tickets@joomdonation.com',
'#$$A%u^tet*d*');
$connection = $server->authenticate($username, $password);
}
catch (Exception $e)
{
$this->logData($e->getMessage());
// Log the error here
return;
}
$mailbox = $connection->getMailbox('INBOX');
// Search for emails from yesterday only
$today = new DateTimeImmutable();
$yesterday = $today->sub(new DateInterval('P10D'));
$date = JFactory::getDate('Now',
JFactory::getConfig()->get('offset'));
$date->modify('-1 day');
$search = new SearchExpression();
$search->addCondition(new Unanswered());
$search->addCondition(new Since($yesterday));
$messages = $mailbox->getMessages($search, \SORTDATE);
// Bootstrap the component
require_once JPATH_ADMINISTRATOR .
'/components/com_helpdeskpro/init.php';
// Get component config data
$config = require JPATH_ADMINISTRATOR .
'/components/com_helpdeskpro/config.php';
// Creating component container
$container =
\OSL\Container\Container::getInstance('com_helpdeskpro',
$config);
$db = $container->db;
$query = $db->getQuery(true);
$config = HelpdeskproHelper::getConfig();
$allowedFileTypes = explode('|',
$config->allowed_file_types);
for ($i = 0, $n = count($allowedFileTypes); $i < $n; $i++)
{
$allowedFileTypes[$i] = trim(strtoupper($allowedFileTypes[$i]));
}
$ticketIdRegex = '/#(\d+)/';
/** @var \OSSolution\HelpdeskPro\Admin\Model\Ticket $model */
$model = $container->factory->createModel('Ticket', [],
'admin');
foreach ($messages as $message)
{
$subject = $message->getSubject();
$body = $message->getBodyText();
$fromName = $message->getFrom()->getName();
$fromEmail = $message->getFrom()->getAddress();
$email = (new EmailParser())->parse($body);
$body = $email->getVisibleText() ?: $body;
if (preg_match($ticketIdRegex, $subject, $matches))
{
$ticketId = (int) $matches[1];
}
else
{
$ticketId = 0;
}
$attachmentsPath = JPATH_ROOT .
'/media/com_helpdeskpro/attachments';
$attachments = [];
foreach ($message->getAttachments() as $attachment)
{
$filename = $attachment->getFilename();
$attachments['original_names'][] = $filename;
$filename = File::makeSafe($filename);
$fileExt =
strtoupper(File::getExt($filename));
if (in_array($fileExt, $allowedFileTypes))
{
if (File::exists($attachmentsPath . '/' . $filename))
{
$filename = File::stripExt($filename) . '_' . uniqid() .
'.' . $fileExt;
}
file_put_contents($attachmentsPath . '/' . $filename,
$attachment->getDecodedContent());
$attachments['names'][] = $filename;
}
}
$data = [];
if ($ticketId)
{
// Add comment
$data['ticket_id'] = $ticketId;
$data['message'] = $body;
// Try to get user id from email
$query->clear()
->select('id')
->from('#__users')
->where('email = ' . $db->quote($fromEmail));
$db->setQuery($query);
$data['user_id'] = (int) $db->loadResult();
$model->addTicketComment($data, $attachments);
}
elseif ($this->params->get('new_ticket_category_id'))
{
// Add a new ticket
$data['name'] = $fromName;
$data['email'] = $fromEmail;
$data['subject'] = $subject;
$data['message'] = $body;
$data['category_id'] =
$this->params->get('new_ticket_category_id');
$model->addNewTicket($data, $attachments);
}
// Mark the message as ANSWERED so that it won't be processed next
time
$message->setFlag('\\ANSWERED');
}
}
/**
* Build the flags used for imap connection from plugin parameters
*
* @return string
*/
private function buildFlags()
{
$encryption = $this->params->get('encryption',
'ssl');
$validateCertificate =
$this->params->get('validate_certificate', 1);
$flags = ['imap'];
if ($encryption)
{
$flags[] = $encryption;
}
if ($validateCertificate)
{
$flags[] = 'validate-cert';
}
else
{
$flags[] = 'novalidate-cert';
}
return '/' . implode('/', $flags);
}
/**
* Clears cache groups. We use it to clear the plugins cache after we
update the last run timestamp.
*
* @param array $clearGroups The cache groups to clean
* @param array $cacheClients The cache clients (site, admin) to
clean
*
* @return void
*
* @since 2.0.4
*/
private function clearCacheGroups(array $clearGroups, array $cacheClients
= array(0, 1))
{
$conf = JFactory::getConfig();
foreach ($clearGroups as $group)
{
foreach ($cacheClients as $client_id)
{
try
{
$options = array(
'defaultgroup' => $group,
'cachebase' => ($client_id) ? JPATH_ADMINISTRATOR .
'/cache' :
$conf->get('cache_path', JPATH_SITE .
'/cache'),
);
$cache = JCache::getInstance('callback', $options);
$cache->clean();
}
catch (Exception $e)
{
// Ignore it
}
}
}
}
/**
* Helper method to write data to a log file, for debuging purpose
*
* @param string $logFile
* @param array $data
* @param string $message
*/
private function logData($data = [], $message = null)
{
$text = '[' . gmdate('m/d/Y g:i A') . '] -
';
foreach ($data as $key => $value)
{
$text .= "$key=$value, ";
}
$text .= $message;
$fp = fopen(__DIR__ . '/logs.txt', 'a');
fwrite($fp, $text . "\n\n");
fclose($fp);
}
/**
* Method to check if the plugin could be run
*
* @return bool
*/
protected function canRun()
{
// If trigger secret_code is set, usually from cron-job request, we will
process email-queues immediately
if (trim($this->params->get('secret_code')))
{
if ($this->params->get('secret_code') ==
$this->app->input->getString('secret_code'))
{
return true;
}
return false;
}
$lastRun = (int) $this->params->get('last_run', 0);
$now = time();
$cacheTime = 1200; // Every 20 minutes
if (($now - $lastRun) < $cacheTime)
{
return false;
}
return true;
}
}