Files
Froxlor/lib/Froxlor/System/Cronjob.php
Oskar Eisemuth 4a912e3902 Feature/crontaskid (#1005)
* Add \Froxlor\Cron\TaskId for fixed task id naming

* Replace Cronjob::inserttask numbers with \Froxlor\Cron\TaskId constants

* Use TaskId in Froxlor\Cron\System\TasksCron

* Use TaskId in Froxlor\System\Cronjob,
simplify getOutstandingTasks.
Rename lng['tasks'] cronjob task description.
WARNING: DELETE_DOMAIN_PDNS, DELETE_DOMAIN_SSL now use %domain%

* Remove Froxlor\System\Cronjob type 3 check
2022-01-21 10:03:45 +01:00

343 lines
10 KiB
PHP

<?php
namespace Froxlor\System;
use Froxlor\Settings;
use Froxlor\Database\Database;
use Froxlor\Cron\TaskId;
class Cronjob
{
/**
* Function checkLastGuid
*
* Checks if the system's last guid is not higher than the one saved
* in froxlor's database. If it's higher, froxlor needs to
* set its last guid to this one to avoid conflicts with libnss-users
*
* @return null
*/
public static function checkLastGuid()
{
$mylog = \Froxlor\FroxlorLogger::getInstanceOf();
$group_lines = array();
$group_guids = array();
$update_to_guid = 0;
$froxlor_guid = 0;
$result_stmt = Database::query("SELECT MAX(`guid`) as `fguid` FROM `" . TABLE_PANEL_CUSTOMERS . "`");
$result = $result_stmt->fetch(\PDO::FETCH_ASSOC);
$froxlor_guid = $result['fguid'];
// possibly no customers yet or f*cked up lastguid settings
if ($froxlor_guid < Settings::Get('system.lastguid')) {
$froxlor_guid = Settings::Get('system.lastguid');
}
$g_file = '/etc/group';
if (file_exists($g_file)) {
if (is_readable($g_file)) {
if (true == ($groups = file_get_contents($g_file))) {
$group_lines = explode("\n", $groups);
foreach ($group_lines as $group) {
$group_guids[] = explode(":", $group);
}
foreach ($group_guids as $group) {
/**
* nogroup | nobody have very high guids
* ignore them
*/
if ($group[0] == 'nogroup' || $group[0] == 'nobody') {
continue;
}
$guid = isset($group[2]) ? (int) $group[2] : 0;
if ($guid > $update_to_guid) {
$update_to_guid = $guid;
}
}
// if it's lower, then froxlor's highest guid is the last
if ($update_to_guid < $froxlor_guid) {
$update_to_guid = $froxlor_guid;
} elseif ($update_to_guid == $froxlor_guid) {
// if it's equal, that means we already have a collision
// to ensure it won't happen again, increase the guid by one
$update_to_guid = (int) $update_to_guid ++;
}
// now check if it differs from our settings
if ($update_to_guid != Settings::Get('system.lastguid')) {
$mylog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'Updating froxlor last guid to ' . $update_to_guid);
Settings::Set('system.lastguid', $update_to_guid);
}
} else {
$mylog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'File /etc/group not readable; cannot check for latest guid');
}
} else {
$mylog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'File /etc/group not readable; cannot check for latest guid');
}
} else {
$mylog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'File /etc/group does not exist; cannot check for latest guid');
}
}
/**
* Inserts a task into the PANEL_TASKS-Table
*
* @param
* int Type of task
* @param
* string Parameter 1
* @param
* string Parameter 2
* @param
* string Parameter 3
* @author Florian Lippert <flo@syscp.org>
* @author Froxlor team <team@froxlor.org>
*/
public static function inserttask($type, $param1 = '', $param2 = '', $param3 = '', $param4 = '')
{
// prepare the insert-statement
$ins_stmt = Database::prepare("
INSERT INTO `" . TABLE_PANEL_TASKS . "` SET `type` = :type, `data` = :data
");
if ($type == TaskId::REBUILD_VHOST || $type == TaskId::REBUILD_DNS || $type == TaskId::CREATE_FTP || $type == TaskId::CREATE_QUOTA || $type == TaskId::REBUILD_CRON) {
// 4 = bind -> if bind disabled -> no task
if ($type == TaskId::REBUILD_DNS && Settings::Get('system.bind_enable') == '0') {
return;
}
// 10 = quota -> if quota disabled -> no task
if ($type == TaskId::CREATE_QUOTA && Settings::Get('system.diskquota_enabled') == '0') {
return;
}
// delete previously inserted tasks if they are the same as we only need ONE
$del_stmt = Database::prepare("
DELETE FROM `" . TABLE_PANEL_TASKS . "` WHERE `type` = :type
");
Database::pexecute($del_stmt, array(
'type' => $type
));
// insert the new task
Database::pexecute($ins_stmt, array(
'type' => $type,
'data' => ''
));
} elseif ($type == TaskId::CREATE_HOME && $param1 != '' && $param2 != '' && $param3 != '' && ($param4 == 0 || $param4 == 1)) {
$data = array();
$data['loginname'] = $param1;
$data['uid'] = $param2;
$data['gid'] = $param3;
$data['store_defaultindex'] = $param4;
$data = json_encode($data);
Database::pexecute($ins_stmt, array(
'type' => TaskId::CREATE_HOME,
'data' => $data
));
} elseif ($type == TaskId::DELETE_CUSTOMER_FILES && $param1 != '') {
$data = array();
$data['loginname'] = $param1;
$data = json_encode($data);
Database::pexecute($ins_stmt, array(
'type' => TaskId::DELETE_CUSTOMER_FILES,
'data' => $data
));
} elseif ($type == TaskId::DELETE_EMAIL_DATA && $param1 != '' && $param2 != '') {
$data = array();
$data['loginname'] = $param1;
$data['email'] = $param2;
$data = json_encode($data);
Database::pexecute($ins_stmt, array(
'type' => TaskId::DELETE_EMAIL_DATA,
'data' => $data
));
} elseif ($type == TaskId::DELETE_FTP_DATA && $param1 != '' && $param2 != '') {
$data = array();
$data['loginname'] = $param1;
$data['homedir'] = $param2;
$data = json_encode($data);
Database::pexecute($ins_stmt, array(
'type' => TaskId::DELETE_FTP_DATA,
'data' => $data
));
} elseif ($type == TaskId::DELETE_DOMAIN_PDNS && $param1 != '' && Settings::Get('system.bind_enable') == '1' && Settings::Get('system.dns_server') == 'PowerDNS') {
// -> if bind disabled or dns-server not PowerDNS -> no task
$data = array();
$data['domain'] = $param1;
$data = json_encode($data);
Database::pexecute($ins_stmt, array(
'type' => TaskId::DELETE_DOMAIN_PDNS,
'data' => $data
));
} elseif ($type == TaskId::DELETE_DOMAIN_SSL && $param1 != '') {
$data = array();
$data['domain'] = $param1;
$data = json_encode($data);
Database::pexecute($ins_stmt, array(
'type' => TaskId::DELETE_DOMAIN_SSL,
'data' => $data
));
} elseif ($type == TaskId::CREATE_CUSTOMER_BACKUP && is_array($param1)) {
$data = json_encode($param1);
Database::pexecute($ins_stmt, array(
'type' => TaskId::CREATE_CUSTOMER_BACKUP,
'data' => $data
));
}
}
public static function getCronjobsLastRun()
{
global $lng;
$query = "SELECT `lastrun`, `desc_lng_key` FROM `" . TABLE_PANEL_CRONRUNS . "` WHERE `isactive` = '1' ORDER BY `cronfile` ASC";
$result = Database::query($query);
$cronjobs_last_run = '';
while ($row = $result->fetch(\PDO::FETCH_ASSOC)) {
$lastrun = $lng['cronjobs']['notyetrun'];
if ($row['lastrun'] > 0) {
$lastrun = date('d.m.Y H:i:s', $row['lastrun']);
}
$text = $lng['crondesc'][$row['desc_lng_key']];
$value = $lastrun;
eval("\$cronjobs_last_run .= \"" . \Froxlor\UI\Template::getTemplate("index/overview_item") . "\";");
}
return $cronjobs_last_run;
}
public static function toggleCronStatus($module = null, $isactive = 0)
{
if ($isactive != 1) {
$isactive = 0;
}
$upd_stmt = Database::prepare("
UPDATE `" . TABLE_PANEL_CRONRUNS . "` SET `isactive` = :active WHERE `module` = :module");
Database::pexecute($upd_stmt, array(
'active' => $isactive,
'module' => $module
));
}
public static function getOutstandingTasks()
{
global $lng;
$query = "SELECT * FROM `" . TABLE_PANEL_TASKS . "` ORDER BY `type` ASC";
$result = Database::query($query);
$value = '<ul class="cronjobtask">';
$tasks = '';
while ($row = $result->fetch(\PDO::FETCH_ASSOC)) {
if ($row['data'] != '') {
$row['data'] = json_decode($row['data'], true);
}
$task_id = $row['type'];
if (\Froxlor\Cron\TaskId::isValid($task_id)) {
$task_constname = \Froxlor\Cron\TaskId::convertToConstant($task_id);
$task_desc = isset($lng['tasks'][$task_constname]) ? $lng['tasks'][$task_constname] : $task_constname;
if (is_array($row['data'])) {
// task includes loginname
if (isset($row['data']['loginname'])) {
$loginname = $row['data']['loginname'];
$task_desc = str_replace('%loginname%', $loginname, $task_desc);
}
// task includes domain data
if (isset($row['data']['domain'])) {
$domain = $row['data']['domain'];
$task_desc = str_replace('%domain%', $domain, $task_desc);
}
}
} else {
// unknown
$task_desc = "ERROR: Unknown task type '" . $row['type'] . "'";
}
if ($task_desc != '') {
$tasks .= '<li>' . $task_desc . '</li>';
}
}
if (trim($tasks) == '') {
$value .= '<li>' . $lng['tasks']['noneoutstanding'] . '</li>';
} else {
$value .= $tasks;
}
$value .= '</ul>';
$text = $lng['tasks']['outstanding_tasks'];
eval("\$outstanding_tasks = \"" . \Froxlor\UI\Template::getTemplate("index/overview_item") . "\";");
return $outstanding_tasks;
}
/**
* Cronjob function to end a cronjob in a critical condition
* but not without sending a notification mail to the admin
*
* @param string $message
* @param string $subject
*
* @return void
*/
public static function dieWithMail($message, $subject = "[froxlor] Cronjob error")
{
if (Settings::Get('system.send_cron_errors') == '1') {
$_mail = new Mailer(true);
$_mailerror = false;
$mailerr_msg = "";
try {
$_mail->Subject = $subject;
$_mail->AltBody = $message;
$_mail->MsgHTML(nl2br($message));
$_mail->AddAddress(Settings::Get('panel.adminmail'), Settings::Get('panel.adminmail_defname'));
$_mail->Send();
} catch (\PHPMailer\PHPMailer\Exception $e) {
$mailerr_msg = $e->errorMessage();
$_mailerror = true;
} catch (\Exception $e) {
$mailerr_msg = $e->getMessage();
$_mailerror = true;
}
$_mail->ClearAddresses();
if ($_mailerror) {
echo 'Error sending mail: ' . $mailerr_msg . "\n";
}
}
die($message);
}
public static function updateLastRunOfCron($cronname)
{
$upd_stmt = Database::prepare("
UPDATE `" . TABLE_PANEL_CRONRUNS . "` SET `lastrun` = UNIX_TIMESTAMP() WHERE `cronfile` = :cron;
");
Database::pexecute($upd_stmt, array(
'cron' => $cronname
));
}
}