add new PHPMail Wrapper to avoid multiple setting of properties
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
This commit is contained in:
@@ -50,7 +50,7 @@ abstract class ApiCommand extends ApiParameter
|
|||||||
/**
|
/**
|
||||||
* mail interface
|
* mail interface
|
||||||
*
|
*
|
||||||
* @var \PHPMailer\PHPMailer\PHPMailer
|
* @var \Froxlor\System\Mailer
|
||||||
*/
|
*/
|
||||||
private $mail = null;
|
private $mail = null;
|
||||||
|
|
||||||
@@ -95,13 +95,11 @@ abstract class ApiCommand extends ApiParameter
|
|||||||
*/
|
*/
|
||||||
public function __construct($header = null, $params = null, $userinfo = null)
|
public function __construct($header = null, $params = null, $userinfo = null)
|
||||||
{
|
{
|
||||||
global $version, $dbversion, $branding;
|
|
||||||
|
|
||||||
parent::__construct($params);
|
parent::__construct($params);
|
||||||
|
|
||||||
$this->version = $version;
|
$this->version = \Froxlor\Froxlor::VERSION;
|
||||||
$this->dbversion = $dbversion;
|
$this->dbversion = \Froxlor\Froxlor::DBVERSION;
|
||||||
$this->branding = $branding;
|
$this->branding = \Froxlor\Froxlor::BRANDING;
|
||||||
|
|
||||||
if (! empty($header)) {
|
if (! empty($header)) {
|
||||||
$this->readUserData($header);
|
$this->readUserData($header);
|
||||||
@@ -120,7 +118,11 @@ abstract class ApiCommand extends ApiParameter
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->initLang();
|
$this->initLang();
|
||||||
$this->initMail();
|
|
||||||
|
/**
|
||||||
|
* Initialize the mailingsystem
|
||||||
|
*/
|
||||||
|
$this->mail = new \Froxlor\System\Mailer(true);
|
||||||
|
|
||||||
if ($this->debug) {
|
if ($this->debug) {
|
||||||
$this->logger()->logAction(LOG_ERROR, LOG_DEBUG, "[API] " . get_called_class() . ": " . json_encode($params, JSON_UNESCAPED_SLASHES));
|
$this->logger()->logAction(LOG_ERROR, LOG_DEBUG, "[API] " . get_called_class() . ": " . json_encode($params, JSON_UNESCAPED_SLASHES));
|
||||||
@@ -180,42 +182,6 @@ abstract class ApiCommand extends ApiParameter
|
|||||||
$this->lng = $lng;
|
$this->lng = $lng;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* initialize mail interface so an API wide mail-object is available
|
|
||||||
*
|
|
||||||
* @throws \PHPMailer\PHPMailer\Exception
|
|
||||||
*/
|
|
||||||
private function initMail()
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Initialize the mailingsystem
|
|
||||||
*/
|
|
||||||
$this->mail = new \PHPMailer\PHPMailer\PHPMailer(true);
|
|
||||||
$this->mail->CharSet = "UTF-8";
|
|
||||||
|
|
||||||
if (\Froxlor\Settings::Get('system.mail_use_smtp')) {
|
|
||||||
$this->mail->isSMTP();
|
|
||||||
$this->mail->Host = \Froxlor\Settings::Get('system.mail_smtp_host');
|
|
||||||
$this->mail->SMTPAuth = \Froxlor\Settings::Get('system.mail_smtp_auth') == '1' ? true : false;
|
|
||||||
$this->mail->Username = \Froxlor\Settings::Get('system.mail_smtp_user');
|
|
||||||
$this->mail->Password = \Froxlor\Settings::Get('system.mail_smtp_passwd');
|
|
||||||
if (\Froxlor\Settings::Get('system.mail_smtp_usetls')) {
|
|
||||||
$this->mail->SMTPSecure = 'tls';
|
|
||||||
} else {
|
|
||||||
$this->mail->SMTPAutoTLS = false;
|
|
||||||
}
|
|
||||||
$this->mail->Port = \Froxlor\Settings::Get('system.mail_smtp_port');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (\PHPMailer\PHPMailer\PHPMailer::validateAddress(\Froxlor\Settings::Get('panel.adminmail')) !== false) {
|
|
||||||
// set return-to address and custom sender-name, see #76
|
|
||||||
$this->mail->setFrom(\Froxlor\Settings::Get('panel.adminmail'), \Froxlor\Settings::Get('panel.adminmail_defname'));
|
|
||||||
if (\Froxlor\Settings::Get('panel.adminmail_return') != '') {
|
|
||||||
$this->mail->addReplyTo(\Froxlor\Settings::Get('panel.adminmail_return'), \Froxlor\Settings::Get('panel.adminmail_defname'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns an instance of the wanted ApiCommand (e.g.
|
* returns an instance of the wanted ApiCommand (e.g.
|
||||||
* Customers, Domains, etc);
|
* Customers, Domains, etc);
|
||||||
@@ -279,7 +245,7 @@ abstract class ApiCommand extends ApiParameter
|
|||||||
/**
|
/**
|
||||||
* return mailer instance
|
* return mailer instance
|
||||||
*
|
*
|
||||||
* @return \PHPMailer\PHPMailer\PHPMailer
|
* @return \Froxlor\System\Mailer
|
||||||
*/
|
*/
|
||||||
protected function mailer()
|
protected function mailer()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace Froxlor\Api;
|
namespace Froxlor\Api;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This file is part of the Froxlor project.
|
* This file is part of the Froxlor project.
|
||||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace Froxlor\Api\Commands;
|
namespace Froxlor\Api\Commands;
|
||||||
|
|
||||||
use Froxlor\Database as Database;
|
use Froxlor\Database\Database;
|
||||||
use Froxlor\Settings as Settings;
|
use Froxlor\Settings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This file is part of the Froxlor project.
|
* This file is part of the Froxlor project.
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace Froxlor\Api\Commands;
|
namespace Froxlor\Api\Commands;
|
||||||
|
|
||||||
use Froxlor\Database as Database;
|
use Froxlor\Database\Database;
|
||||||
use Froxlor\Settings as Settings;
|
use Froxlor\Settings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This file is part of the Froxlor project.
|
* This file is part of the Froxlor project.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace Froxlor\Api\Commands;
|
namespace Froxlor\Api\Commands;
|
||||||
|
|
||||||
use Froxlor\Database as Database;
|
use Froxlor\Database\Database;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This file is part of the Froxlor project.
|
* This file is part of the Froxlor project.
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace Froxlor\Api\Commands;
|
namespace Froxlor\Api\Commands;
|
||||||
|
|
||||||
use Froxlor\Database as Database;
|
use Froxlor\Database\Database;
|
||||||
use Froxlor\Settings as Settings;
|
use Froxlor\Settings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This file is part of the Froxlor project.
|
* This file is part of the Froxlor project.
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace Froxlor\Api\Commands;
|
namespace Froxlor\Api\Commands;
|
||||||
|
|
||||||
use Froxlor\Database as Database;
|
use Froxlor\Database\Database;
|
||||||
use Froxlor\Settings as Settings;
|
use Froxlor\Settings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This file is part of the Froxlor project.
|
* This file is part of the Froxlor project.
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace Froxlor\Api\Commands;
|
namespace Froxlor\Api\Commands;
|
||||||
|
|
||||||
use Froxlor\Database as Database;
|
use Froxlor\Database\Database;
|
||||||
use Froxlor\Settings as Settings;
|
use Froxlor\Settings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This file is part of the Froxlor project.
|
* This file is part of the Froxlor project.
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace Froxlor\Api\Commands;
|
namespace Froxlor\Api\Commands;
|
||||||
|
|
||||||
use Froxlor\Database as Database;
|
use Froxlor\Database\Database;
|
||||||
use Froxlor\Settings as Settings;
|
use Froxlor\Settings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This file is part of the Froxlor project.
|
* This file is part of the Froxlor project.
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace Froxlor\Api\Commands;
|
namespace Froxlor\Api\Commands;
|
||||||
|
|
||||||
use Froxlor\Database as Database;
|
use Froxlor\Database\Database;
|
||||||
use Froxlor\Settings as Settings;
|
use Froxlor\Settings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This file is part of the Froxlor project.
|
* This file is part of the Froxlor project.
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace Froxlor\Api\Commands;
|
namespace Froxlor\Api\Commands;
|
||||||
|
|
||||||
use Froxlor\Database as Database;
|
use Froxlor\Database\Database;
|
||||||
use Froxlor\Settings as Settings;
|
use Froxlor\Settings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This file is part of the Froxlor project.
|
* This file is part of the Froxlor project.
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace Froxlor\Api\Commands;
|
namespace Froxlor\Api\Commands;
|
||||||
|
|
||||||
use Froxlor\Database as Database;
|
use Froxlor\Database\Database;
|
||||||
use Froxlor\Settings as Settings;
|
use Froxlor\Settings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This file is part of the Froxlor project.
|
* This file is part of the Froxlor project.
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace Froxlor\Api\Commands;
|
namespace Froxlor\Api\Commands;
|
||||||
|
|
||||||
use Froxlor\Database as Database;
|
use Froxlor\Database\Database;
|
||||||
use Froxlor\Settings as Settings;
|
use Froxlor\Settings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This file is part of the Froxlor project.
|
* This file is part of the Froxlor project.
|
||||||
|
|||||||
@@ -31,30 +31,7 @@ class ReportsCron extends \Froxlor\Cron\FroxlorCron
|
|||||||
/**
|
/**
|
||||||
* Initialize the mailingsystem
|
* Initialize the mailingsystem
|
||||||
*/
|
*/
|
||||||
$mail = new \PHPMailer\PHPMailer\PHPMailer(true);
|
$mail = new \Froxlor\System\Mailer(true);
|
||||||
$mail->CharSet = "UTF-8";
|
|
||||||
|
|
||||||
if (Settings::Get('system.mail_use_smtp')) {
|
|
||||||
$mail->isSMTP();
|
|
||||||
$mail->Host = Settings::Get('system.mail_smtp_host');
|
|
||||||
$mail->SMTPAuth = Settings::Get('system.mail_smtp_auth') == '1' ? true : false;
|
|
||||||
$mail->Username = Settings::Get('system.mail_smtp_user');
|
|
||||||
$mail->Password = Settings::Get('system.mail_smtp_passwd');
|
|
||||||
if (Settings::Get('system.mail_smtp_usetls')) {
|
|
||||||
$mail->SMTPSecure = 'tls';
|
|
||||||
} else {
|
|
||||||
$mail->SMTPAutoTLS = false;
|
|
||||||
}
|
|
||||||
$mail->Port = Settings::Get('system.mail_smtp_port');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (\PHPMailer\PHPMailer\PHPMailer::ValidateAddress(Settings::Get('panel.adminmail')) !== false) {
|
|
||||||
// set return-to address and custom sender-name, see #76
|
|
||||||
$mail->SetFrom(Settings::Get('panel.adminmail'), Settings::Get('panel.adminmail_defname'));
|
|
||||||
if (Settings::Get('panel.adminmail_return') != '') {
|
|
||||||
$mail->AddReplyTo(Settings::Get('panel.adminmail_return'), Settings::Get('panel.adminmail_defname'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((int) Settings::Get('system.report_trafficmax') > 0) {
|
if ((int) Settings::Get('system.report_trafficmax') > 0) {
|
||||||
// Warn the customers at xx% traffic-usage
|
// Warn the customers at xx% traffic-usage
|
||||||
@@ -350,7 +327,7 @@ class ReportsCron extends \Froxlor\Cron\FroxlorCron
|
|||||||
} // trafficmax > 0
|
} // trafficmax > 0
|
||||||
|
|
||||||
// include diskspace-usage report, #466
|
// include diskspace-usage report, #466
|
||||||
include dirname(__FILE__) . '/cron_usage.inc.diskspace.php';
|
self::usageDiskspace();
|
||||||
|
|
||||||
// Another month, reset the reportstatus
|
// Another month, reset the reportstatus
|
||||||
if (date('d') == '01') {
|
if (date('d') == '01') {
|
||||||
@@ -358,4 +335,207 @@ class ReportsCron extends \Froxlor\Cron\FroxlorCron
|
|||||||
Database::query("UPDATE `" . TABLE_PANEL_ADMINS . "` SET `reportsent` = '0';");
|
Database::query("UPDATE `" . TABLE_PANEL_ADMINS . "` SET `reportsent` = '0';");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static function usageDiskspace()
|
||||||
|
{
|
||||||
|
if ((int) Settings::Get('system.report_webmax') > 0) {
|
||||||
|
/**
|
||||||
|
* report about diskusage for customers
|
||||||
|
*/
|
||||||
|
$result_stmt = Database::query("
|
||||||
|
SELECT `c`.`customerid`, `c`.`adminid`, `c`.`name`, `c`.`firstname`,
|
||||||
|
`c`.`company`, `c`.`diskspace`, `c`.`diskspace_used`, `c`.`email`, `c`.`def_language`,
|
||||||
|
`a`.`name` AS `adminname`, `a`.`email` AS `adminmail`
|
||||||
|
FROM `" . TABLE_PANEL_CUSTOMERS . "` AS `c`
|
||||||
|
LEFT JOIN `" . TABLE_PANEL_ADMINS . "` AS `a`
|
||||||
|
ON `a`.`adminid` = `c`.`adminid`
|
||||||
|
WHERE `c`.`diskspace` > '0' AND `c`.`reportsent` <> '2'
|
||||||
|
");
|
||||||
|
|
||||||
|
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||||
|
|
||||||
|
if (isset($row['diskspace']) && $row['diskspace_used'] != null && $row['diskspace_used'] > 0 && (($row['diskspace_used'] * 100) / $row['diskspace']) >= (int) Settings::Get('system.report_webmax')) {
|
||||||
|
|
||||||
|
$rep_userinfo = array(
|
||||||
|
'name' => $row['name'],
|
||||||
|
'firstname' => $row['firstname'],
|
||||||
|
'company' => $row['company']
|
||||||
|
);
|
||||||
|
$replace_arr = array(
|
||||||
|
'SALUTATION' => getCorrectUserSalutation($rep_userinfo),
|
||||||
|
'NAME' => $row['name'], // < keep this for compatibility
|
||||||
|
'DISKAVAILABLE' => round(($row['diskspace'] / 1024), 2), /* traffic is stored in KB, template uses MB */
|
||||||
|
'DISKUSED' => round($row['diskspace_used'] / 1024, 2), /* traffic is stored in KB, template uses MB */
|
||||||
|
'USAGE_PERCENT' => round(($row['diskspace_used'] * 100) / $row['diskspace'], 2),
|
||||||
|
'MAX_PERCENT' => Settings::Get('system.report_webmax')
|
||||||
|
);
|
||||||
|
|
||||||
|
$lngfile_stmt = Database::prepare("
|
||||||
|
SELECT `file` FROM `" . TABLE_PANEL_LANGUAGE . "`
|
||||||
|
WHERE `language` = :deflang
|
||||||
|
");
|
||||||
|
$lngfile = Database::pexecute_first($lngfile_stmt, array(
|
||||||
|
'deflang' => $row['def_language']
|
||||||
|
));
|
||||||
|
|
||||||
|
if ($lngfile !== null) {
|
||||||
|
$langfile = $lngfile['file'];
|
||||||
|
} else {
|
||||||
|
$lngfile = Database::pexecute_first($lngfile_stmt, array(
|
||||||
|
'deflang' => Settings::Get('panel.standardlanguage')
|
||||||
|
));
|
||||||
|
$langfile = $lngfile['file'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// include english language file (fallback)
|
||||||
|
include_once \Froxlor\FileDir::makeCorrectFile(\Froxlor\Froxlor::getInstallDir() . '/lng/english.lng.php');
|
||||||
|
// include admin/customer language file
|
||||||
|
include_once \Froxlor\FileDir::makeCorrectFile(\Froxlor\Froxlor::getInstallDir() . '/' . $langfile);
|
||||||
|
|
||||||
|
// Get mail templates from database; the ones from 'admin' are fetched for fallback
|
||||||
|
$result2_stmt = Database::prepare("
|
||||||
|
SELECT `value` FROM `" . TABLE_PANEL_TEMPLATES . "`
|
||||||
|
WHERE `adminid` = :adminid
|
||||||
|
AND `language` = :lang
|
||||||
|
AND `templategroup` = 'mails' AND `varname` = :varname
|
||||||
|
");
|
||||||
|
$result2_data = array(
|
||||||
|
'adminid' => $row['adminid'],
|
||||||
|
'lang' => $row['def_language'],
|
||||||
|
'varname' => 'diskmaxpercent_subject'
|
||||||
|
);
|
||||||
|
$result2 = Database::pexecute_first($result2_stmt, $result2_data);
|
||||||
|
$mail_subject = html_entity_decode(\Froxlor\PhpHelper::replace_variables((($result2['value'] != '') ? $result2['value'] : $lng['mails']['diskmaxpercent']['subject']), $replace_arr));
|
||||||
|
|
||||||
|
$result2_data['varname'] = 'diskmaxpercent_mailbody';
|
||||||
|
$result2 = Database::pexecute_first($result2_stmt, $result2_data);
|
||||||
|
$mail_body = html_entity_decode(\Froxlor\PhpHelper::replace_variables((($result2['value'] != '') ? $result2['value'] : $lng['mails']['diskmaxpercent']['mailbody']), $replace_arr));
|
||||||
|
|
||||||
|
$_mailerror = false;
|
||||||
|
$mailerr_msg = "";
|
||||||
|
try {
|
||||||
|
$mail->SetFrom($row['adminmail'], $row['adminname']);
|
||||||
|
$mail->Subject = $mail_subject;
|
||||||
|
$mail->AltBody = $mail_body;
|
||||||
|
$mail->MsgHTML(nl2br($mail_body));
|
||||||
|
$mail->AddAddress($row['email'], $row['name']);
|
||||||
|
$mail->Send();
|
||||||
|
} catch (\PHPMailer\PHPMailer\Exception $e) {
|
||||||
|
$mailerr_msg = $e->errorMessage();
|
||||||
|
$_mailerror = true;
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$mailerr_msg = $e->getMessage();
|
||||||
|
$_mailerror = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($_mailerror) {
|
||||||
|
$cronlog->logAction(CRON_ACTION, LOG_ERR, "Error sending mail: " . $mailerr_msg);
|
||||||
|
echo "Error sending mail: " . $mailerr_msg . "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
$mail->ClearAddresses();
|
||||||
|
$upd_stmt = Database::prepare("
|
||||||
|
UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET `reportsent` = '2'
|
||||||
|
WHERE `customerid` = :customerid
|
||||||
|
");
|
||||||
|
Database::pexecute($upd_stmt, array(
|
||||||
|
'customerid' => $row['customerid']
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* report about diskusage for admins/reseller
|
||||||
|
*/
|
||||||
|
$result_stmt = Database::query("
|
||||||
|
SELECT `a`.* FROM `" . TABLE_PANEL_ADMINS . "` `a` WHERE `a`.`reportsent` <> '2'
|
||||||
|
");
|
||||||
|
|
||||||
|
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||||
|
|
||||||
|
if (isset($row['diskspace']) && $row['diskspace_used'] != null && $row['diskspace_used'] > 0 && (($row['diskspace_used'] * 100) / $row['diskspace']) >= (int) Settings::Get('system.report_webmax')) {
|
||||||
|
|
||||||
|
$replace_arr = array(
|
||||||
|
'NAME' => $row['name'],
|
||||||
|
'DISKAVAILABLE' => ($row['diskspace'] / 1024), /* traffic is stored in KB, template uses MB */
|
||||||
|
'DISKUSED' => round($row['diskspace_used'] / 1024, 2), /* traffic is stored in KB, template uses MB */
|
||||||
|
'USAGE_PERCENT' => ($row['diskspace_used'] * 100) / $row['diskspace'],
|
||||||
|
'MAX_PERCENT' => Settings::Get('system.report_webmax')
|
||||||
|
);
|
||||||
|
|
||||||
|
$lngfile_stmt = Database::prepare("
|
||||||
|
SELECT `file` FROM `" . TABLE_PANEL_LANGUAGE . "`
|
||||||
|
WHERE `language` = :deflang
|
||||||
|
");
|
||||||
|
$lngfile = Database::pexecute_first($lngfile_stmt, array(
|
||||||
|
'deflang' => $row['def_language']
|
||||||
|
));
|
||||||
|
|
||||||
|
if ($lngfile !== null) {
|
||||||
|
$langfile = $lngfile['file'];
|
||||||
|
} else {
|
||||||
|
$lngfile = Database::pexecute_first($lngfile_stmt, array(
|
||||||
|
'deflang' => Settings::Get('panel.standardlanguage')
|
||||||
|
));
|
||||||
|
$langfile = $lngfile['file'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// include english language file (fallback)
|
||||||
|
include_once \Froxlor\FileDir::makeCorrectFile(\Froxlor\Froxlor::getInstallDir() . '/lng/english.lng.php');
|
||||||
|
// include admin/customer language file
|
||||||
|
include_once \Froxlor\FileDir::makeCorrectFile(\Froxlor\Froxlor::getInstallDir() . '/' . $langfile);
|
||||||
|
|
||||||
|
// Get mail templates from database; the ones from 'admin' are fetched for fallback
|
||||||
|
$result2_stmt = Database::prepare("
|
||||||
|
SELECT `value` FROM `" . TABLE_PANEL_TEMPLATES . "`
|
||||||
|
WHERE `adminid` = :adminid
|
||||||
|
AND `language` = :lang
|
||||||
|
AND `templategroup` = 'mails' AND `varname` = :varname
|
||||||
|
");
|
||||||
|
$result2_data = array(
|
||||||
|
'adminid' => $row['adminid'],
|
||||||
|
'lang' => $row['def_language'],
|
||||||
|
'varname' => 'diskmaxpercent_subject'
|
||||||
|
);
|
||||||
|
$result2 = Database::pexecute_first($result2_stmt, $result2_data);
|
||||||
|
$mail_subject = html_entity_decode(\Froxlor\PhpHelper::replace_variables((($result2['value'] != '') ? $result2['value'] : $lng['mails']['diskmaxpercent']['subject']), $replace_arr));
|
||||||
|
|
||||||
|
$result2_data['varname'] = 'diskmaxpercent_mailbody';
|
||||||
|
$result2 = Database::pexecute_first($result2_stmt, $result2_data);
|
||||||
|
$mail_body = html_entity_decode(\Froxlor\PhpHelper::replace_variables((($result2['value'] != '') ? $result2['value'] : $lng['mails']['diskmaxpercent']['mailbody']), $replace_arr));
|
||||||
|
|
||||||
|
$_mailerror = false;
|
||||||
|
$mailerr_msg = "";
|
||||||
|
try {
|
||||||
|
$mail->SetFrom($row['email'], $row['name']);
|
||||||
|
$mail->Subject = $mail_subject;
|
||||||
|
$mail->AltBody = $mail_body;
|
||||||
|
$mail->MsgHTML(nl2br($mail_body));
|
||||||
|
$mail->AddAddress($row['email'], $row['name']);
|
||||||
|
$mail->Send();
|
||||||
|
} catch (\PHPMailer\PHPMailer\Exception $e) {
|
||||||
|
$mailerr_msg = $e->errorMessage();
|
||||||
|
$_mailerror = true;
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$mailerr_msg = $e->getMessage();
|
||||||
|
$_mailerror = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($_mailerror) {
|
||||||
|
$cronlog->logAction(CRON_ACTION, LOG_ERR, "Error sending mail: " . $mailerr_msg);
|
||||||
|
echo "Error sending mail: " . $mailerr_msg . "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
$mail->ClearAddresses();
|
||||||
|
$upd_stmt = Database::prepare("
|
||||||
|
UPDATE `" . TABLE_PANEL_ADMINS . "` SET `reportsent` = '2'
|
||||||
|
WHERE `adminid` = :adminid
|
||||||
|
");
|
||||||
|
Database::pexecute($upd_stmt, array(
|
||||||
|
'adminid' => $row['adminid']
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // webmax > 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,219 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
if (! defined('MASTER_CRONJOB'))
|
|
||||||
die('You cannot access this file directly!');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This file is part of the Froxlor project.
|
|
||||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
|
||||||
*
|
|
||||||
* For the full copyright and license information, please view the COPYING
|
|
||||||
* file that was distributed with this source code. You can also view the
|
|
||||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
|
||||||
*
|
|
||||||
* @copyright (c) the authors
|
|
||||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
|
||||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
|
||||||
* @package Cron
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
use Froxlor\Database;
|
|
||||||
use Froxlor\Settings;
|
|
||||||
|
|
||||||
if ((int) Settings::Get('system.report_webmax') > 0) {
|
|
||||||
/**
|
|
||||||
* report about diskusage for customers
|
|
||||||
*/
|
|
||||||
$result_stmt = Database::query("
|
|
||||||
SELECT `c`.`customerid`, `c`.`adminid`, `c`.`name`, `c`.`firstname`,
|
|
||||||
`c`.`company`, `c`.`diskspace`, `c`.`diskspace_used`, `c`.`email`, `c`.`def_language`,
|
|
||||||
`a`.`name` AS `adminname`, `a`.`email` AS `adminmail`
|
|
||||||
FROM `" . TABLE_PANEL_CUSTOMERS . "` AS `c`
|
|
||||||
LEFT JOIN `" . TABLE_PANEL_ADMINS . "` AS `a`
|
|
||||||
ON `a`.`adminid` = `c`.`adminid`
|
|
||||||
WHERE `c`.`diskspace` > '0' AND `c`.`reportsent` <> '2'
|
|
||||||
");
|
|
||||||
|
|
||||||
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
|
||||||
|
|
||||||
if (isset($row['diskspace']) && $row['diskspace_used'] != null && $row['diskspace_used'] > 0 && (($row['diskspace_used'] * 100) / $row['diskspace']) >= (int) Settings::Get('system.report_webmax')) {
|
|
||||||
|
|
||||||
$rep_userinfo = array(
|
|
||||||
'name' => $row['name'],
|
|
||||||
'firstname' => $row['firstname'],
|
|
||||||
'company' => $row['company']
|
|
||||||
);
|
|
||||||
$replace_arr = array(
|
|
||||||
'SALUTATION' => getCorrectUserSalutation($rep_userinfo),
|
|
||||||
'NAME' => $row['name'], // < keep this for compatibility
|
|
||||||
'DISKAVAILABLE' => round(($row['diskspace'] / 1024), 2), /* traffic is stored in KB, template uses MB */
|
|
||||||
'DISKUSED' => round($row['diskspace_used'] / 1024, 2), /* traffic is stored in KB, template uses MB */
|
|
||||||
'USAGE_PERCENT' => round(($row['diskspace_used'] * 100) / $row['diskspace'], 2),
|
|
||||||
'MAX_PERCENT' => Settings::Get('system.report_webmax')
|
|
||||||
);
|
|
||||||
|
|
||||||
$lngfile_stmt = Database::prepare("
|
|
||||||
SELECT `file` FROM `" . TABLE_PANEL_LANGUAGE . "`
|
|
||||||
WHERE `language` = :deflang
|
|
||||||
");
|
|
||||||
$lngfile = Database::pexecute_first($lngfile_stmt, array(
|
|
||||||
'deflang' => $row['def_language']
|
|
||||||
));
|
|
||||||
|
|
||||||
if ($lngfile !== null) {
|
|
||||||
$langfile = $lngfile['file'];
|
|
||||||
} else {
|
|
||||||
$lngfile = Database::pexecute_first($lngfile_stmt, array(
|
|
||||||
'deflang' => Settings::Get('panel.standardlanguage')
|
|
||||||
));
|
|
||||||
$langfile = $lngfile['file'];
|
|
||||||
}
|
|
||||||
|
|
||||||
// include english language file (fallback)
|
|
||||||
include_once \Froxlor\FileDir::makeCorrectFile(\Froxlor\Froxlor::getInstallDir() . '/lng/english.lng.php');
|
|
||||||
// include admin/customer language file
|
|
||||||
include_once \Froxlor\FileDir::makeCorrectFile(\Froxlor\Froxlor::getInstallDir() . '/' . $langfile);
|
|
||||||
|
|
||||||
// Get mail templates from database; the ones from 'admin' are fetched for fallback
|
|
||||||
$result2_stmt = Database::prepare("
|
|
||||||
SELECT `value` FROM `" . TABLE_PANEL_TEMPLATES . "`
|
|
||||||
WHERE `adminid` = :adminid
|
|
||||||
AND `language` = :lang
|
|
||||||
AND `templategroup` = 'mails' AND `varname` = :varname
|
|
||||||
");
|
|
||||||
$result2_data = array(
|
|
||||||
'adminid' => $row['adminid'],
|
|
||||||
'lang' => $row['def_language'],
|
|
||||||
'varname' => 'diskmaxpercent_subject'
|
|
||||||
);
|
|
||||||
$result2 = Database::pexecute_first($result2_stmt, $result2_data);
|
|
||||||
$mail_subject = html_entity_decode(\Froxlor\PhpHelper::replace_variables((($result2['value'] != '') ? $result2['value'] : $lng['mails']['diskmaxpercent']['subject']), $replace_arr));
|
|
||||||
|
|
||||||
$result2_data['varname'] = 'diskmaxpercent_mailbody';
|
|
||||||
$result2 = Database::pexecute_first($result2_stmt, $result2_data);
|
|
||||||
$mail_body = html_entity_decode(\Froxlor\PhpHelper::replace_variables((($result2['value'] != '') ? $result2['value'] : $lng['mails']['diskmaxpercent']['mailbody']), $replace_arr));
|
|
||||||
|
|
||||||
$_mailerror = false;
|
|
||||||
try {
|
|
||||||
$mail->SetFrom($row['adminmail'], $row['adminname']);
|
|
||||||
$mail->Subject = $mail_subject;
|
|
||||||
$mail->AltBody = $mail_body;
|
|
||||||
$mail->MsgHTML(nl2br($mail_body));
|
|
||||||
$mail->AddAddress($row['email'], $row['name']);
|
|
||||||
$mail->Send();
|
|
||||||
} catch (\PHPMailer\PHPMailer\Exception $e) {
|
|
||||||
$mailerr_msg = $e->errorMessage();
|
|
||||||
$_mailerror = true;
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$mailerr_msg = $e->getMessage();
|
|
||||||
$_mailerror = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($_mailerror) {
|
|
||||||
$cronlog->logAction(CRON_ACTION, LOG_ERR, "Error sending mail: " . $mailerr_msg);
|
|
||||||
echo "Error sending mail: " . $mailerr_msg . "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
$mail->ClearAddresses();
|
|
||||||
$upd_stmt = Database::prepare("
|
|
||||||
UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET `reportsent` = '2'
|
|
||||||
WHERE `customerid` = :customerid
|
|
||||||
");
|
|
||||||
Database::pexecute($upd_stmt, array(
|
|
||||||
'customerid' => $row['customerid']
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* report about diskusage for admins/reseller
|
|
||||||
*/
|
|
||||||
$result_stmt = Database::query("
|
|
||||||
SELECT `a`.* FROM `" . TABLE_PANEL_ADMINS . "` `a` WHERE `a`.`reportsent` <> '2'
|
|
||||||
");
|
|
||||||
|
|
||||||
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
|
||||||
|
|
||||||
if (isset($row['diskspace']) && $row['diskspace_used'] != null && $row['diskspace_used'] > 0 && (($row['diskspace_used'] * 100) / $row['diskspace']) >= (int) Settings::Get('system.report_webmax')) {
|
|
||||||
|
|
||||||
$replace_arr = array(
|
|
||||||
'NAME' => $row['name'],
|
|
||||||
'DISKAVAILABLE' => ($row['diskspace'] / 1024), /* traffic is stored in KB, template uses MB */
|
|
||||||
'DISKUSED' => round($row['diskspace_used'] / 1024, 2), /* traffic is stored in KB, template uses MB */
|
|
||||||
'USAGE_PERCENT' => ($row['diskspace_used'] * 100) / $row['diskspace'],
|
|
||||||
'MAX_PERCENT' => Settings::Get('system.report_webmax')
|
|
||||||
);
|
|
||||||
|
|
||||||
$lngfile_stmt = Database::prepare("
|
|
||||||
SELECT `file` FROM `" . TABLE_PANEL_LANGUAGE . "`
|
|
||||||
WHERE `language` = :deflang
|
|
||||||
");
|
|
||||||
$lngfile = Database::pexecute_first($lngfile_stmt, array(
|
|
||||||
'deflang' => $row['def_language']
|
|
||||||
));
|
|
||||||
|
|
||||||
if ($lngfile !== null) {
|
|
||||||
$langfile = $lngfile['file'];
|
|
||||||
} else {
|
|
||||||
$lngfile = Database::pexecute_first($lngfile_stmt, array(
|
|
||||||
'deflang' => Settings::Get('panel.standardlanguage')
|
|
||||||
));
|
|
||||||
$langfile = $lngfile['file'];
|
|
||||||
}
|
|
||||||
|
|
||||||
// include english language file (fallback)
|
|
||||||
include_once \Froxlor\FileDir::makeCorrectFile(\Froxlor\Froxlor::getInstallDir() . '/lng/english.lng.php');
|
|
||||||
// include admin/customer language file
|
|
||||||
include_once \Froxlor\FileDir::makeCorrectFile(\Froxlor\Froxlor::getInstallDir() . '/' . $langfile);
|
|
||||||
|
|
||||||
// Get mail templates from database; the ones from 'admin' are fetched for fallback
|
|
||||||
$result2_stmt = Database::prepare("
|
|
||||||
SELECT `value` FROM `" . TABLE_PANEL_TEMPLATES . "`
|
|
||||||
WHERE `adminid` = :adminid
|
|
||||||
AND `language` = :lang
|
|
||||||
AND `templategroup` = 'mails' AND `varname` = :varname
|
|
||||||
");
|
|
||||||
$result2_data = array(
|
|
||||||
'adminid' => $row['adminid'],
|
|
||||||
'lang' => $row['def_language'],
|
|
||||||
'varname' => 'diskmaxpercent_subject'
|
|
||||||
);
|
|
||||||
$result2 = Database::pexecute_first($result2_stmt, $result2_data);
|
|
||||||
$mail_subject = html_entity_decode(\Froxlor\PhpHelper::replace_variables((($result2['value'] != '') ? $result2['value'] : $lng['mails']['diskmaxpercent']['subject']), $replace_arr));
|
|
||||||
|
|
||||||
$result2_data['varname'] = 'diskmaxpercent_mailbody';
|
|
||||||
$result2 = Database::pexecute_first($result2_stmt, $result2_data);
|
|
||||||
$mail_body = html_entity_decode(\Froxlor\PhpHelper::replace_variables((($result2['value'] != '') ? $result2['value'] : $lng['mails']['diskmaxpercent']['mailbody']), $replace_arr));
|
|
||||||
|
|
||||||
$_mailerror = false;
|
|
||||||
try {
|
|
||||||
$mail->SetFrom($row['email'], $row['name']);
|
|
||||||
$mail->Subject = $mail_subject;
|
|
||||||
$mail->AltBody = $mail_body;
|
|
||||||
$mail->MsgHTML(nl2br($mail_body));
|
|
||||||
$mail->AddAddress($row['email'], $row['name']);
|
|
||||||
$mail->Send();
|
|
||||||
} catch (\PHPMailer\PHPMailer\Exception $e) {
|
|
||||||
$mailerr_msg = $e->errorMessage();
|
|
||||||
$_mailerror = true;
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$mailerr_msg = $e->getMessage();
|
|
||||||
$_mailerror = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($_mailerror) {
|
|
||||||
$cronlog->logAction(CRON_ACTION, LOG_ERR, "Error sending mail: " . $mailerr_msg);
|
|
||||||
echo "Error sending mail: " . $mailerr_msg . "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
$mail->ClearAddresses();
|
|
||||||
$upd_stmt = Database::prepare("
|
|
||||||
UPDATE `" . TABLE_PANEL_ADMINS . "` SET `reportsent` = '2'
|
|
||||||
WHERE `adminid` = :adminid
|
|
||||||
");
|
|
||||||
Database::pexecute($upd_stmt, array(
|
|
||||||
'adminid' => $row['adminid']
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // webmax > 0
|
|
||||||
@@ -320,31 +320,7 @@ class Cronjob
|
|||||||
{
|
{
|
||||||
if (Settings::Get('system.send_cron_errors') == '1') {
|
if (Settings::Get('system.send_cron_errors') == '1') {
|
||||||
|
|
||||||
$_mail = new \PHPMailer\PHPMailer\PHPMailer(true);
|
$_mail = new Mailer(true);
|
||||||
$_mail->CharSet = "UTF-8";
|
|
||||||
|
|
||||||
if (Settings::Get('system.mail_use_smtp')) {
|
|
||||||
$_mail->isSMTP();
|
|
||||||
$_mail->Host = Settings::Get('system.mail_smtp_host');
|
|
||||||
$_mail->SMTPAuth = Settings::Get('system.mail_smtp_auth') == '1' ? true : false;
|
|
||||||
$_mail->Username = Settings::Get('system.mail_smtp_user');
|
|
||||||
$_mail->Password = Settings::Get('system.mail_smtp_passwd');
|
|
||||||
if (Settings::Get('system.mail_smtp_usetls')) {
|
|
||||||
$_mail->SMTPSecure = 'tls';
|
|
||||||
} else {
|
|
||||||
$_mail->SMTPAutoTLS = false;
|
|
||||||
}
|
|
||||||
$_mail->Port = Settings::Get('system.mail_smtp_port');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (\PHPMailer\PHPMailer\PHPMailer::ValidateAddress(Settings::Get('panel.adminmail')) !== false) {
|
|
||||||
// set return-to address and custom sender-name, see #76
|
|
||||||
$_mail->SetFrom(Settings::Get('panel.adminmail'), Settings::Get('panel.adminmail_defname'));
|
|
||||||
if (Settings::Get('panel.adminmail_return') != '') {
|
|
||||||
$_mail->AddReplyTo(Settings::Get('panel.adminmail_return'), Settings::Get('panel.adminmail_defname'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$_mailerror = false;
|
$_mailerror = false;
|
||||||
$mailerr_msg = "";
|
$mailerr_msg = "";
|
||||||
try {
|
try {
|
||||||
|
|||||||
43
lib/Froxlor/System/Mailer.php
Normal file
43
lib/Froxlor/System/Mailer.php
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
namespace Froxlor\System;
|
||||||
|
|
||||||
|
use Froxlor\Settings;
|
||||||
|
|
||||||
|
class Mailer extends \PHPMailer\PHPMailer\PHPMailer
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* class construtor
|
||||||
|
*
|
||||||
|
* @param string $exceptions
|
||||||
|
* whether to throw exceptions or not
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function __construct($exceptions = false)
|
||||||
|
{
|
||||||
|
parent::__construct($exceptions);
|
||||||
|
$this->CharSet = "UTF-8";
|
||||||
|
|
||||||
|
if (Settings::Get('system.mail_use_smtp')) {
|
||||||
|
$this->isSMTP();
|
||||||
|
$this->Host = Settings::Get('system.mail_smtp_host');
|
||||||
|
$this->SMTPAuth = Settings::Get('system.mail_smtp_auth') == '1' ? true : false;
|
||||||
|
$this->Username = Settings::Get('system.mail_smtp_user');
|
||||||
|
$this->Password = Settings::Get('system.mail_smtp_passwd');
|
||||||
|
if (Settings::Get('system.mail_smtp_usetls')) {
|
||||||
|
$this->SMTPSecure = 'tls';
|
||||||
|
} else {
|
||||||
|
$this->SMTPAutoTLS = false;
|
||||||
|
}
|
||||||
|
$this->Port = Settings::Get('system.mail_smtp_port');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self::ValidateAddress(Settings::Get('panel.adminmail')) !== false) {
|
||||||
|
// set return-to address and custom sender-name, see #76
|
||||||
|
$this->SetFrom(Settings::Get('panel.adminmail'), Settings::Get('panel.adminmail_defname'));
|
||||||
|
if (Settings::Get('panel.adminmail_return') != '') {
|
||||||
|
$this->AddReplyTo(Settings::Get('panel.adminmail_return'), Settings::Get('panel.adminmail_defname'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
* @package AJAX
|
* @package AJAX
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
require __DIR__ . '/vendor/autoload.php';
|
require_once dirname(__DIR__) . '/vendor/autoload.php';
|
||||||
|
|
||||||
// Load the user settings
|
// Load the user settings
|
||||||
if (! file_exists('./userdata.inc.php')) {
|
if (! file_exists('./userdata.inc.php')) {
|
||||||
@@ -23,8 +23,6 @@ if (! file_exists('./userdata.inc.php')) {
|
|||||||
}
|
}
|
||||||
require './userdata.inc.php';
|
require './userdata.inc.php';
|
||||||
require './tables.inc.php';
|
require './tables.inc.php';
|
||||||
require './functions/validate/function.validate_ip.php';
|
|
||||||
require './functions/validate/function.validateDomain.php';
|
|
||||||
|
|
||||||
if (isset($_POST['action'])) {
|
if (isset($_POST['action'])) {
|
||||||
$action = $_POST['action'];
|
$action = $_POST['action'];
|
||||||
|
|||||||
25
lib/init.php
25
lib/init.php
@@ -476,27 +476,4 @@ if ($page == '') {
|
|||||||
/**
|
/**
|
||||||
* Initialize the mailingsystem
|
* Initialize the mailingsystem
|
||||||
*/
|
*/
|
||||||
$mail = new \PHPMailer\PHPMailer\PHPMailer(true);
|
$mail = new \Froxlor\System\Mailer(true);
|
||||||
$mail->CharSet = "UTF-8";
|
|
||||||
|
|
||||||
if (Settings::Get('system.mail_use_smtp')) {
|
|
||||||
$mail->isSMTP();
|
|
||||||
$mail->Host = Settings::Get('system.mail_smtp_host');
|
|
||||||
$mail->SMTPAuth = Settings::Get('system.mail_smtp_auth') == '1' ? true : false;
|
|
||||||
$mail->Username = Settings::Get('system.mail_smtp_user');
|
|
||||||
$mail->Password = Settings::Get('system.mail_smtp_passwd');
|
|
||||||
if (Settings::Get('system.mail_smtp_usetls')) {
|
|
||||||
$mail->SMTPSecure = 'tls';
|
|
||||||
} else {
|
|
||||||
$mail->SMTPAutoTLS = false;
|
|
||||||
}
|
|
||||||
$mail->Port = Settings::Get('system.mail_smtp_port');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (\PHPMailer\PHPMailer\PHPMailer::ValidateAddress(Settings::Get('panel.adminmail')) !== false) {
|
|
||||||
// set return-to address and custom sender-name, see #76
|
|
||||||
$mail->SetFrom(Settings::Get('panel.adminmail'), Settings::Get('panel.adminmail_defname'));
|
|
||||||
if (Settings::Get('panel.adminmail_return') != '') {
|
|
||||||
$mail->AddReplyTo(Settings::Get('panel.adminmail_return'), Settings::Get('panel.adminmail_defname'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user