Current Directory: /home/astoriaah/www/administrator/components/com_admintools/Model/Scanner
Viewing File: /home/astoriaah/www/administrator/components/com_admintools/Model/Scanner/Email.php
<?php
/**
* @package admintools
* @copyright Copyright (c)2010-2022 Nicholas K. Dionysopoulos / Akeeba Ltd
* @license GNU General Public License version 3, or later
*/
namespace Akeeba\AdminTools\Admin\Model\Scanner;
use Akeeba\AdminTools\Admin\Model\ScanAlerts;
use Akeeba\AdminTools\Admin\Model\Scanner\Logger\Logger;
use Akeeba\AdminTools\Admin\Model\Scanner\Util\Configuration;
use Akeeba\AdminTools\Admin\Model\Scanner\Util\Session;
use Akeeba\AdminTools\Admin\Model\Scans;
use Exception;
use FOF40\Container\Container;
use Joomla\CMS\Factory;
use Joomla\CMS\Language\Text as JText;
defined('_JEXEC') || die;
/**
* Handles sending a notification email after the PHP File Change Scanner has finished executing
*/
class Email
{
/**
* Scanner configuration
*
* @var Configuration
*/
private $configuration;
/**
* Logger
*
* @var Logger
*/
private $logger;
/**
* Temporary session storage
*
* @var Session
*/
private $session;
/**
* Email constructor.
*
* @param Configuration $configuration Scanner configuration
* @param Session $session Temporary session storage
* @param Logger $logger Logger
*/
public function __construct(Configuration $configuration, Session $session, Logger $logger)
{
$this->configuration = $configuration;
$this->session = $session;
$this->logger = $logger;
}
public function sendEmail()
{
// If no email is set, quit
$email = trim($this->configuration->get('scanemail'));
if (empty($email))
{
$this->logger->debug("No email is set. Scan results will not sent by email.");
return;
}
$container = Container::getInstance('com_admintools');
$this->logger->debug(sprintf("%s: Email address set to %s", __CLASS__, $email));
// Get the ID of the scan
$scanID = $this->session->get('scanID');
$this->logger->debug(sprintf("%s: Latest scan ID is %s", __CLASS__, $scanID));
// Get scan statistics
$this->logger->debug(sprintf("%s: Getting scan statistics", __CLASS__));
/** @var Scans $scanModel */
$scanModel = $container->factory->model('Scans')->tmpInstance();
$scanModel->find($scanID);
// Populate table data for new, modified and suspicious files
$this->logger->debug(sprintf("%s: Populating table", __CLASS__));
$body_new = '';
$body_modified = '';
/** @var ScanAlerts $scanAlertsModel */
$scanAlertsModel = $container->factory->model('ScanAlerts')->tmpInstance();
$totalFiles = $scanAlertsModel
->scan_id($scanID)
->acknowledged(0)
->count();
$segments = (int) ($totalFiles / 100) + 1;
$this->logger->debug(sprintf("%s: Processing file list in $segments segment(s)", __CLASS__));
$modified = 0;
$new = 0;
$suspicious = 0;
for ($i = 0; $i < $segments; $i++)
{
$limitStart = 100 * $i;
$files = $scanAlertsModel->reset()
->scan_id($scanID)
->acknowledged(0)
->limit(100)
->limitstart($limitStart)
->get();
if (!$files->count())
{
continue;
}
/** @var ScanAlerts $file */
foreach ($files as $file)
{
if ($file->threat_score > 0)
{
$suspicious++;
}
$fileRow = "<tr><td>{$file->path}</td><td>{$file->threat_score}</td></tr>\n";
if ($file->newfile)
{
$body_new .= $fileRow;
$new++;
}
else
{
$body_modified .= $fileRow;
$modified++;
}
}
}
// Conditional email sending only when actionable items are found
if ($this->configuration->get('scan_conditional_email'))
{
$this->logger->info("You have enabled conditional email sending. Calculating number of actionable items (number of added, modified and suspicious files)");
$numActionableFiles = $modified + $new + $suspicious;
if ($numActionableFiles < 1)
{
$this->logger->info("No actionable items were detected. An email will NOT be sent this time.");
return;
}
}
$this->logger->debug(sprintf("%s: Preparing email text", __CLASS__));
// Prepare the email body
$body = '<html lang="en"><head>' . JText::_('COM_ADMINTOOLS_SCANS_EMAIL_HEADING') . '<title></title></head><body>';
$body .= '<h1>' . JText::_('COM_ADMINTOOLS_SCANS_EMAIL_HEADING') . "</h1><hr/>\n";
$body .= '<h2>' . JText::_('COM_ADMINTOOLS_SCANS_EMAIL_OVERVIEW') . "</h2>\n";
$body .= "<p>\n";
$body .= '<strong>' . JText::_('COM_ADMINTOOLS_LBL_SCAN_TOTAL') . "</strong>: " . $totalFiles . "<br/>\n";
$body .= '<strong>' . JText::_('COM_ADMINTOOLS_LBL_SCAN_MODIFIED') . "</strong>: " . $modified . "<br/>\n";
$body .= '<strong>' . JText::_('COM_ADMINTOOLS_LBL_SCAN_ADDED') . "</strong>: " . $new . "<br/>\n";
$body .= '<strong>' . JText::_('COM_ADMINTOOLS_LBL_SCAN_SUSPICIOUS') . "</strong>: " . $suspicious . "<br/>\n";
$body .= "</p>\n";
// Add the new files report only if we really have some files
if ($body_new)
{
$body .= '<hr/><h2>' . JText::_('COM_ADMINTOOLS_LBL_SCAN_ADDED') . "</h2>\n";
$body .= "<table width=\"100%\">\n";
$body .= "\t<thead>\n";
$body .= "\t<tr>\n";
$body .= "\t\t<th>" . JText::_('COM_ADMINTOOLS_LBL_SCANALERTS_PATH') . "</th>\n";
$body .= "\t\t<th width=\"50\">" . JText::_('COM_ADMINTOOLS_LBL_SCANALERTS_THREAT_SCORE') . "</th>\n";
$body .= "\t</tr>\n";
$body .= "\t</thead>\n";
$body .= "\t<tbody>\n";
$body .= $body_new;
$body .= "\t</tbody>\n";
$body .= '</table>';
}
// Add the modified files report only if we really have some files
if ($body_modified)
{
$body .= '<hr/><h2>' . JText::_('COM_ADMINTOOLS_LBL_SCAN_MODIFIED') . "</h2>\n";
$body .= "<table width=\"100%\">\n";
$body .= "\t<thead>\n";
$body .= "\t<tr>\n";
$body .= "\t\t<th>" . JText::_('COM_ADMINTOOLS_LBL_SCANALERTS_PATH') . "</th>\n";
$body .= "\t\t<th width=\"50\">" . JText::_('COM_ADMINTOOLS_LBL_SCANALERTS_THREAT_SCORE') . "</th>\n";
$body .= "\t</tr>\n";
$body .= "\t</thead>\n";
$body .= "\t<tbody>\n";
$body .= $body_modified;
$body .= "\t</tbody>\n";
$body .= '</table>';
}
// No added or modified files? Let's print a message for the user
if (!$body_new && !$body_modified)
{
$body .= '<p>' . JText::_('COM_ADMINTOOLS_SCANS_EMAIL_NOTHING_TO_REPORT') . '</p>';
}
unset($body_new);
unset($body_modified);
$body .= '</body></html>';
// Prepare the email subject
$config = $container->platform->getConfig();
$sitename = $config->get('sitename', 'Unknown Site');
$subject = JText::sprintf('COM_ADMINTOOLS_SCANS_EMAIL_SUBJECT', $sitename);
// Send the email
$this->logger->debug(sprintf("%s: Ready to send out emails", __CLASS__));
try
{
$mailer = Factory::getMailer();
$mailer->isHTML(true);
$mailer->addRecipient($email);
$mailer->setSubject($subject);
$mailer->setBody($body);
$mailer->Send();
}
catch (Exception $e)
{
$this->logger->warning(sprintf("Could not set email. Received error from Joomla's Mailer: %s", $e->getMessage()));
}
}
}